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

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 [email protected]
 
-   Last modified: Thu Dec 16 23:08:29 1999 by [email protected]
+   Last modified: Tue Jan  4 21:43:17 2000 by [email protected]
    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, [email protected]
TCL-scripts by Sam Shen (who was at: [email protected])