[7735] in linux-scsi channel archive

home help back first fref pref prev next nref lref last post

SCSI Queueing...

daemon@ATHENA.MIT.EDU (Eric Youngdale)
Mon Dec 20 11:14:49 1999

Message-ID: <002801bf4b07$78712b00$6366420c@zydeco>
From: "Eric Youngdale" <eric@andante.org>
To: "Juergen Fischer" <Juergen_Fischer@t-online.de>,
	<Arnd Bergmann@lml.valinux.com>
Cc: <linux-scsi@vger.rutgers.edu>
Date:   Mon, 20 Dec 1999 16:29:16 -0000
MIME-Version: 1.0
Content-Type: multipart/mixed;
	boundary="----=_NextPart_000_001F_01BF4B07.5BCBCB40"

This is a multi-part message in MIME format.

------=_NextPart_000_001F_01BF4B07.5BCBCB40
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit


 I have a set of patches.  I have verified that everything compiles, but I
have no way at the moment of testing to make sure I haven't broken anything.
Anyways, with that caveat aside, I believe this should correct the following
problems:

    1) Incorrect sg segment count.  The problem was that I botched something
when I did a merge as the code for segment counting, and I assumed that I
could use the segment counting in ll_rw_blk to save some work.  It turns out
we cannot - we should just use our own functions, and then everything should
be OK.

 2) I fixed most obvious part of the > 16 disks problem in a cleaner way.

 3) The problem of being unable to write a cdrom was kind of interesting.
The whole story was evident from the logs that were sent.  Essentially what
is happening is that a command is failing with DID_ERROR, but the HA isn't
automatically requesting it (for one reason or another), and the error
handler thread got invoked.  The error handler got the sense data, and
decided that everything was OK, and then dropped down and tried calling
scsi_done() to report the completion of the command.  Right at the start of
scsi_done(), we attempt to remove the timer from the command - if this
fails, it is assumed that the command timed out, that the error handler is
running, and hence scsi_done does nothing on the assumption that the error
handler thread is taking care of it.  Which it was, kind of.  The "fix"
isn't the cleanest thing, but it was the most obvious - just add a timer
back to the command before we call scsi_done().  Maybe I will think of a
more elegant fix in the next day or so, so this one is more of a workaround.

-Eric




------=_NextPart_000_001F_01BF4B07.5BCBCB40
Content-Type: application/octet-stream;
	name="Fixes.dat"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="Fixes.dat"

Index: hosts.h=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/hosts.h,v=0A=
retrieving revision 1.1.1.2=0A=
diff -u -r1.1.1.2 hosts.h=0A=
--- hosts.h	1999/12/18 23:33:45	1.1.1.2=0A=
+++ hosts.h	1999/12/19 21:35:15=0A=
@@ -437,6 +437,8 @@=0A=
     struct module * module;	  /* Used for loadable modules */=0A=
     unsigned char scsi_type;=0A=
     unsigned char major;=0A=
+    unsigned char min_major;      /* Minimum major in range. */ =0A=
+    unsigned char max_major;      /* Maximum major in range. */=0A=
     unsigned char nr_dev;	  /* Number currently attached */=0A=
     unsigned char dev_noticed;	  /* Number of devices detected. */=0A=
     unsigned char dev_max;	  /* Current size of arrays */=0A=
@@ -447,7 +449,8 @@=0A=
     void (*finish)(void);	  /* Perform initialization after attachment =
*/=0A=
     int (*attach)(Scsi_Device *); /* Attach devices to arrays */=0A=
     void (*detach)(Scsi_Device *);=0A=
-    int (*init_command)(Scsi_Cmnd *);     /* Used by new queueing code. =
*/=0A=
+    int (*init_command)(Scsi_Cmnd *);     /* Used by new queueing code. =0A=
+                                           Selects command for blkdevs =
*/=0A=
 };=0A=
 =0A=
 extern struct Scsi_Device_Template sd_template;=0A=
Index: scsi.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/scsi.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 scsi.c=0A=
--- scsi.c	1999/12/18 22:54:31	1.2=0A=
+++ scsi.c	1999/12/20 06:01:09=0A=
@@ -1575,6 +1575,9 @@=0A=
 	 * Since serial_number is now 0, the error handler cound detect this=0A=
 	 * situation and avoid to call the the low level driver abort routine.=0A=
 	 * (DB)=0A=
+         *=0A=
+         * FIXME(eric) - I believe that this test is now redundant, due =
to=0A=
+         * the test of the return status of del_timer().=0A=
 	 */=0A=
 	if (SCpnt->state =3D=3D SCSI_STATE_TIMEOUT) {=0A=
 		SCSI_LOG_MLCOMPLETE(1, printk("Ignoring completion of %p due to =
timeout status", SCpnt));=0A=
Index: scsi_error.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/scsi_error.c,v=0A=
retrieving revision 1.3=0A=
diff -u -r1.3 scsi_error.c=0A=
--- scsi_error.c	1999/12/18 23:02:22	1.3=0A=
+++ scsi_error.c	1999/12/20 05:35:26=0A=
@@ -1778,6 +1778,17 @@=0A=
 	for (SCpnt =3D SCdone; SCpnt !=3D NULL; SCpnt =3D SCdone) {=0A=
 		SCdone =3D SCpnt->bh_next;=0A=
 		SCpnt->bh_next =3D NULL;=0A=
+                /*=0A=
+                 * Oh, this is a vile hack.  scsi_done() expects a timer=0A=
+                 * to be running on the command.  If there isn't, it =
assumes=0A=
+                 * that the command has actually timed out, and a timer=0A=
+                 * handler is running.  That may well be how we got into=0A=
+                 * this fix, but right now things are stable.  We add=0A=
+                 * a timer back again so that we can report completion.=0A=
+                 * scsi_done() will immediately remove said timer from=0A=
+                 * the command, and then process it.=0A=
+                 */=0A=
+		scsi_add_timer(SCpnt, 100, scsi_eh_times_out);=0A=
 		scsi_done(SCpnt);=0A=
 	}=0A=
 =0A=
Index: scsi_lib.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/scsi_lib.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 scsi_lib.c=0A=
--- scsi_lib.c	1999/12/18 22:54:32	1.2=0A=
+++ scsi_lib.c	1999/12/18 23:24:03=0A=
@@ -607,6 +607,22 @@=0A=
 		if (spnt->blk && spnt->major =3D=3D major) {=0A=
 			return spnt;=0A=
 		}=0A=
+		/*=0A=
+		 * I am still not entirely satisfied with this solution,=0A=
+		 * but it is good enough for now.  Disks have a number of=0A=
+		 * major numbers associated with them, the primary=0A=
+		 * 8, which we test above, and a secondary range of 7=0A=
+		 * different consecutive major numbers.   If this ever=0A=
+		 * becomes insufficient, then we could add another function=0A=
+		 * to the structure, and generalize this completely.=0A=
+		 */=0A=
+		if( spnt->min_major !=3D 0 =0A=
+		    && spnt->max_major !=3D 0=0A=
+		    && major >=3D spnt->min_major=0A=
+		    && major <=3D spnt->max_major )=0A=
+		{=0A=
+			return spnt;=0A=
+		}=0A=
 	}=0A=
 	return NULL;=0A=
 }=0A=
Index: scsi_merge.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/scsi_merge.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 scsi_merge.c=0A=
--- scsi_merge.c	1999/12/18 22:54:32	1.2=0A=
+++ scsi_merge.c	1999/12/20 05:24:51=0A=
@@ -765,7 +765,8 @@=0A=
 	if( scsi_dma_free_sectors > 30 ) {=0A=
 		for (this_count =3D 0, bh =3D SCpnt->request.bh;=0A=
 		     bh; bh =3D bh->b_reqnext) {=0A=
-			if( scsi_dma_free_sectors < 30 || this_count =3D=3D sectors )=0A=
+			if( scsi_dma_free_sectors - this_count < 30 =0A=
+			    || this_count =3D=3D sectors )=0A=
 			{=0A=
 				break;=0A=
 			}=0A=
@@ -831,24 +832,11 @@=0A=
  * We always force "_VALID" to 1.  Eventually clean this up=0A=
  * and get rid of the extra argument.=0A=
  */=0A=
-#if 0=0A=
-/* Old definitions */=0A=
-INITIO(scsi_init_io_, 0, 0, 0)=0A=
-INITIO(scsi_init_io_d, 0, 0, 1)=0A=
-INITIO(scsi_init_io_c, 0, 1, 0)=0A=
-INITIO(scsi_init_io_dc, 0, 1, 1)=0A=
-=0A=
-/* Newer redundant definitions. */=0A=
-INITIO(scsi_init_io_, 1, 0, 0)=0A=
-INITIO(scsi_init_io_d, 1, 0, 1)=0A=
-INITIO(scsi_init_io_c, 1, 1, 0)=0A=
-INITIO(scsi_init_io_dc, 1, 1, 1)=0A=
-#endif=0A=
-=0A=
 INITIO(scsi_init_io_v, 1, 0, 0)=0A=
 INITIO(scsi_init_io_vd, 1, 0, 1)=0A=
 INITIO(scsi_init_io_vc, 1, 1, 0)=0A=
 INITIO(scsi_init_io_vdc, 1, 1, 1)=0A=
+=0A=
 /*=0A=
  * Function:    initialize_merge_fn()=0A=
  *=0A=
@@ -881,21 +869,12 @@=0A=
 	 * If this host has an unlimited tablesize, then don't bother with a=0A=
 	 * merge manager.  The whole point of the operation is to make sure=0A=
 	 * that requests don't grow too large, and this host isn't picky.=0A=
-	 */=0A=
-	if (SHpnt->sg_tablesize =3D=3D SG_ALL) {=0A=
-		if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
-			SDpnt->scsi_init_io_fn =3D scsi_init_io_v;=0A=
-		} else if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma !=3D 0) {=0A=
-			SDpnt->scsi_init_io_fn =3D scsi_init_io_vd;=0A=
-		} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma =3D=3D 0) {=0A=
-			SDpnt->scsi_init_io_fn =3D scsi_init_io_vc;=0A=
-		} else if (CLUSTERABLE_DEVICE(SHpnt, SDpnt) && =
SHpnt->unchecked_isa_dma !=3D 0) {=0A=
-			SDpnt->scsi_init_io_fn =3D scsi_init_io_vdc;=0A=
-		}=0A=
-		return;=0A=
-	}=0A=
-	/*=0A=
-	 * Now pick out the correct function.=0A=
+	 *=0A=
+	 * Note that ll_rw_blk.c is effectively maintaining a segment=0A=
+	 * count which is only valid if clustering is used, and it obviously=0A=
+	 * doesn't handle the DMA case.   In the end, it=0A=
+	 * is simply easier to do it ourselves with our own functions=0A=
+	 * rather than rely upon the default behavior of ll_rw_blk.=0A=
 	 */=0A=
 	if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
 		q->merge_fn =3D scsi_merge_fn_;=0A=
Index: sd.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/sd.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 sd.c=0A=
--- sd.c	1999/12/18 22:54:32	1.2=0A=
+++ sd.c	1999/12/18 23:21:22=0A=
@@ -202,6 +202,11 @@=0A=
 	tag:"sd",=0A=
 	scsi_type:TYPE_DISK,=0A=
 	major:SCSI_DISK0_MAJOR,=0A=
+        /*=0A=
+         * Secondary range of majors that this driver handles.=0A=
+         */=0A=
+	min_major:SCSI_DISK1_MAJOR,=0A=
+	max_major:SCSI_DISK7_MAJOR,=0A=
 	blk:1,=0A=
 	detect:sd_detect,=0A=
 	init:sd_init,=0A=
Index: sg.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/sg.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 sg.c=0A=
--- sg.c	1999/12/18 22:54:33	1.2=0A=
+++ sg.c	1999/12/18 23:09:20=0A=
@@ -101,10 +101,17 @@=0A=
 static void sg_detach(Scsi_Device *);=0A=
 =0A=
 =0A=
-struct Scsi_Device_Template sg_template =3D {NULL, NULL, "sg", NULL, =
0xff,=0A=
-                                           SCSI_GENERIC_MAJOR, 0, 0, 0, =
0,=0A=
-                                           sg_detect, sg_init,=0A=
-                                           sg_finish, sg_attach, =
sg_detach};=0A=
+struct Scsi_Device_Template sg_template =3D =0A=
+{=0A=
+	tag:"sg", =0A=
+	scsi_type:0xff,=0A=
+	major:SCSI_GENERIC_MAJOR, =0A=
+	detect:sg_detect, =0A=
+	init:sg_init,=0A=
+	finish:sg_finish, =0A=
+	attach:sg_attach, =0A=
+	detach:sg_detach=0A=
+};=0A=
 =0A=
 =0A=
 typedef struct sg_scatter_hold  /* holding area for scsi scatter gather =
info */=0A=
Index: st.c=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /home/eric/CVSROOT/scsi/st.c,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 st.c=0A=
--- st.c	1999/12/18 22:54:33	1.2=0A=
+++ st.c	1999/12/18 23:10:25=0A=
@@ -147,10 +147,16 @@=0A=
 static void st_detach(Scsi_Device *);=0A=
 =0A=
 struct Scsi_Device_Template st_template =3D=0A=
-{NULL, "tape", "st", NULL, TYPE_TAPE,=0A=
- SCSI_TAPE_MAJOR, 0, 0, 0, 0,=0A=
- st_detect, st_init,=0A=
- NULL, st_attach, st_detach};=0A=
+{=0A=
+	name:"tape", =0A=
+	tag:"st", =0A=
+	scsi_type:TYPE_TAPE,=0A=
+	major:SCSI_TAPE_MAJOR, =0A=
+	detect:st_detect, =0A=
+	init:st_init,=0A=
+	attach:st_attach, =0A=
+	detach:st_detach=0A=
+};=0A=
 =0A=
 static int st_compression(Scsi_Tape *, int);=0A=
 =0A=

------=_NextPart_000_001F_01BF4B07.5BCBCB40--


-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.rutgers.edu

home help back first fref pref prev next nref lref last post