patch-2.3.36 linux/drivers/scsi/st.c
Next file: linux/drivers/scsi/st.h
Previous file: linux/drivers/scsi/scsi_merge.c
Back to the patch index
Back to the overall index
- Lines: 265
- Date:
Tue Jan 4 13:01:53 2000
- Orig file:
v2.3.35/linux/drivers/scsi/st.c
- Orig date:
Wed Dec 29 13:13:19 1999
diff -u --recursive --new-file v2.3.35/linux/drivers/scsi/st.c linux/drivers/scsi/st.c
@@ -8,10 +8,10 @@
order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer,
Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale.
- Copyright 1992 - 1999 Kai Makisara
+ Copyright 1992 - 2000 Kai Makisara
email Kai.Makisara@metla.fi
- Last modified: Thu Dec 16 23:08:29 1999 by makisara@kai.makisara.local
+ Last modified: Tue Jan 4 21:43:17 2000 by makisara@kai.makisara.local
Some small formal changes - aeb, 950809
*/
@@ -2915,7 +2915,7 @@
static ST_buffer *
new_tape_buffer(int from_initialization, int need_dma)
{
- int i, priority, b_size, got = 0, segs = 0;
+ int i, priority, b_size, order, got = 0, segs = 0;
ST_buffer *tb;
if (st_nbr_buffers >= st_template.dev_max)
@@ -2927,20 +2927,20 @@
priority = GFP_KERNEL;
i = sizeof(ST_buffer) + (st_max_sg_segs - 1) * sizeof(struct scatterlist);
- tb = (ST_buffer *) scsi_init_malloc(i, priority);
+ tb = (ST_buffer *) kmalloc(i, priority);
if (tb) {
- tb->this_size = i;
if (need_dma)
priority |= GFP_DMA;
/* Try to allocate the first segment up to ST_FIRST_ORDER and the
others big enough to reach the goal */
- for (b_size = PAGE_SIZE << ST_FIRST_ORDER;
- b_size / 2 >= st_buffer_size && b_size > PAGE_SIZE;)
- b_size /= 2;
- for (; b_size >= PAGE_SIZE; b_size /= 2) {
+ for (b_size = PAGE_SIZE, order=0;
+ b_size < st_buffer_size && order < ST_FIRST_ORDER;
+ order++, b_size *= 2)
+ ;
+ for ( ; b_size >= PAGE_SIZE; order--, b_size /= 2) {
tb->sg[0].address =
- (unsigned char *) scsi_init_malloc(b_size, priority);
+ (unsigned char *) __get_free_pages(priority, order);
if (tb->sg[0].address != NULL) {
tb->sg[0].alt_address = NULL;
tb->sg[0].length = b_size;
@@ -2948,30 +2948,33 @@
}
}
if (tb->sg[segs].address == NULL) {
- scsi_init_free((char *) tb, tb->this_size);
+ kfree(tb);
tb = NULL;
} else { /* Got something, continue */
- for (b_size = PAGE_SIZE;
+ for (b_size = PAGE_SIZE, order=0;
st_buffer_size >
- tb->sg[0].length + (ST_FIRST_SG - 1) * b_size;)
- b_size *= 2;
-
+ tb->sg[0].length + (ST_FIRST_SG - 1) * b_size;
+ order++, b_size *= 2)
+ ;
for (segs = 1, got = tb->sg[0].length;
- got < st_buffer_size && segs < ST_FIRST_SG;) {
+ got < st_buffer_size && segs < ST_FIRST_SG;) {
tb->sg[segs].address =
- (unsigned char *) scsi_init_malloc(b_size, priority);
+ (unsigned char *) __get_free_pages(priority,
+ order);
if (tb->sg[segs].address == NULL) {
if (st_buffer_size - got <=
(ST_FIRST_SG - segs) * b_size / 2) {
b_size /= 2; /* Large enough for the
rest of the buffers */
+ order--;
continue;
}
- for (i = 0; i < segs - 1; i++)
- scsi_init_free(tb->sg[i].address,
- tb->sg[i].length);
- scsi_init_free((char *) tb, tb->this_size);
+ tb->sg_segs = segs;
+ tb->orig_sg_segs = 0;
+ DEB(tb->buffer_size = got);
+ normalize_buffer(tb);
+ kfree(tb);
tb = NULL;
break;
}
@@ -3011,7 +3014,7 @@
/* Try to allocate a temporary enlarged tape buffer */
static int enlarge_buffer(ST_buffer * STbuffer, int new_size, int need_dma)
{
- int segs, nbr, max_segs, b_size, priority, got;
+ int segs, nbr, max_segs, b_size, priority, order, got;
normalize_buffer(STbuffer);
@@ -3025,20 +3028,23 @@
priority = GFP_KERNEL;
if (need_dma)
priority |= GFP_DMA;
- for (b_size = PAGE_SIZE; b_size * nbr < new_size - STbuffer->buffer_size;)
- b_size *= 2;
+ for (b_size = PAGE_SIZE, order=0;
+ b_size * nbr < new_size - STbuffer->buffer_size;
+ order++, b_size *= 2);
for (segs = STbuffer->sg_segs, got = STbuffer->buffer_size;
segs < max_segs && got < new_size;) {
STbuffer->sg[segs].address =
- (unsigned char *) scsi_init_malloc(b_size, priority);
+ (unsigned char *) __get_free_pages(priority, order);
if (STbuffer->sg[segs].address == NULL) {
if (new_size - got <= (max_segs - segs) * b_size / 2) {
b_size /= 2; /* Large enough for the rest of the buffers */
+ order--;
continue;
}
printk(KERN_NOTICE "st: failed to enlarge buffer to %d bytes.\n",
new_size);
+ DEB(STbuffer->buffer_size = got);
normalize_buffer(STbuffer);
return FALSE;
}
@@ -3060,16 +3066,20 @@
/* Release the extra buffer */
static void normalize_buffer(ST_buffer * STbuffer)
{
- int i;
+ int i, order, b_size;
for (i = STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) {
- scsi_init_free(STbuffer->sg[i].address, STbuffer->sg[i].length);
+ for (b_size=PAGE_SIZE, order=0; b_size < STbuffer->sg[i].length;
+ order++, b_size *= 2)
+ ;
+ free_pages((unsigned long)(STbuffer->sg[i].address), order);
STbuffer->buffer_size -= STbuffer->sg[i].length;
}
DEB(
if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs)
printk(ST_DEB_MSG "st: Buffer at %p normalized to %d bytes (segs %d).\n",
- STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs);
+ STbuffer->sg[0].address, STbuffer->buffer_size,
+ STbuffer->sg_segs);
) /* end DEB */
STbuffer->sg_segs = STbuffer->orig_sg_segs;
}
@@ -3320,7 +3330,7 @@
/* Driver initialization (not __init because may be called later) */
static int st_init()
{
- int i;
+ int i, j;
Scsi_Tape *STp;
int target_nbr;
@@ -3346,8 +3356,8 @@
if (st_template.dev_max > 128 / ST_NBR_MODES)
printk(KERN_INFO "st: Only %d tapes accessible.\n", 128 / ST_NBR_MODES);
scsi_tapes =
- (Scsi_Tape *) scsi_init_malloc(st_template.dev_max * sizeof(Scsi_Tape),
- GFP_ATOMIC);
+ (Scsi_Tape *) kmalloc(st_template.dev_max * sizeof(Scsi_Tape),
+ GFP_ATOMIC);
if (scsi_tapes == NULL) {
printk(KERN_ERR "Unable to allocate descriptors for SCSI tapes.\n");
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
@@ -3361,21 +3371,30 @@
for (i = 0; i < st_template.dev_max; ++i) {
STp = &(scsi_tapes[i]);
STp->capacity = 0xfffff;
- STp->mt_status = (struct mtget *) scsi_init_malloc(sizeof(struct mtget),
- GFP_ATOMIC);
+ STp->mt_status = (struct mtget *) kmalloc(sizeof(struct mtget),
+ GFP_ATOMIC);
+ if (STp->mt_status == NULL) {
+ for (j=0; j < i; j++)
+ kfree(scsi_tapes[j].mt_status);
+ kfree(scsi_tapes);
+ unregister_chrdev(SCSI_TAPE_MAJOR, "st");
+ return 1;
+ }
/* Initialize status */
memset((void *) scsi_tapes[i].mt_status, 0, sizeof(struct mtget));
}
/* Allocate the buffers */
st_buffers =
- (ST_buffer **) scsi_init_malloc(st_template.dev_max * sizeof(ST_buffer *),
- GFP_ATOMIC);
+ (ST_buffer **) kmalloc(st_template.dev_max * sizeof(ST_buffer *),
+ GFP_ATOMIC);
if (st_buffers == NULL) {
printk(KERN_ERR "Unable to allocate tape buffer pointers.\n");
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
- scsi_init_free((char *) scsi_tapes,
- st_template.dev_max * sizeof(Scsi_Tape));
+ for (i=0; i < st_template.dev_max; i++)
+ kfree(scsi_tapes[i].mt_status);
+ kfree(scsi_tapes);
+ unregister_chrdev(SCSI_TAPE_MAJOR, "st");
return 1;
}
target_nbr = st_template.dev_noticed;
@@ -3420,42 +3439,32 @@
int __init init_module(void)
{
- int result;
-
validate_options();
st_template.module = &__this_module;
- result = scsi_register_module(MODULE_SCSI_DEV, &st_template);
- if (result)
- return result;
-
- return 0;
+ return scsi_register_module(MODULE_SCSI_DEV, &st_template);
}
void cleanup_module(void)
{
- int i, j;
+ int i;
scsi_unregister_module(MODULE_SCSI_DEV, &st_template);
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
st_registered--;
if (scsi_tapes != NULL) {
- scsi_init_free((char *) scsi_tapes,
- st_template.dev_max * sizeof(Scsi_Tape));
-
+ for (i=0; i < st_template.dev_max; ++i)
+ kfree(scsi_tapes[i].mt_status);
+ kfree(scsi_tapes);
if (st_buffers != NULL) {
- for (i = 0; i < st_nbr_buffers; i++)
- {
+ for (i = 0; i < st_nbr_buffers; i++) {
if (st_buffers[i] != NULL) {
- for (j = 0; j < st_buffers[i]->sg_segs; j++)
- scsi_init_free((char *) st_buffers[i]->sg[j].address,
- st_buffers[i]->sg[j].length);
- scsi_init_free((char *) st_buffers[i],
- st_buffers[i]->this_size);
+ st_buffers[i]->orig_sg_segs = 0;
+ normalize_buffer(st_buffers[i]);
+ kfree(st_buffers[i]);
}
}
- scsi_init_free((char *) st_buffers,
- st_template.dev_max * sizeof(ST_buffer *));
+ kfree(st_buffers);
}
}
st_template.dev_max = 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)