[7742] in linux-scsi channel archive

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

SCSI queueing status.

daemon@ATHENA.MIT.EDU (Eric Youngdale)
Thu Dec 23 00:58:11 1999

Message-ID: <003c01bf4cdd$f9407e20$7f66420c@zydeco>
From: "Eric Youngdale" <eric@andante.org>
To: <linux-scsi@vger.rutgers.edu>
Cc: "Peter Rival" <frival@zk3.dec.com>,
	"Christoph Rohland" <hans-christoph.rohland@sap.com>,
	<frankeh@us.ibm.com>, "Tim Waugh" <twaugh@redhat.com>
Date:   Thu, 23 Dec 1999 00:37:30 -0000
MIME-Version: 1.0
Content-Type: multipart/mixed;
	boundary="----=_NextPart_000_0030_01BF4CDD.E4FC8120"

This is a multi-part message in MIME format.

------=_NextPart_000_0030_01BF4CDD.E4FC8120
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit


I have figured out a couple more of the open issues.  I *believe* that this
may correct all of the outstanding issues as of last night (details below),
that is of course assuming that the patches themselves don't break anything.
Also, I am flying a little blind here, as I cannot test live kernels until I
get back home from Christmas, so I don't want to forward patches to Linus
until I get good feedback from a number of people.

    I am enclosing cumulative diffs against 2.3.34.

 1) The problem with HIGHMEM is that in ll_rw_blk.c we are automatically
getting a bounce buffer, but from this it is impossible to do queue
management to combine requests.  I simply added some code to dereference the
thing.  The fix is a bit of a hack, but I don't completely understand
HIGHMEM anyways, so this will do for now, I guess.

 2) Some people were reporting problems scanning the bus with ppa and imm
host adapters.  The problem here was that I was incrementing the host usage
count too soon, and thus hosts that could only queue a single command would
deadlock attempting to scan the bus. I think I have fixed this - it was a
relic of the old way of doing things (and a maintainence problem as well) to
bump the usage count in two separate functions.  I moved this over so that
it is all done in the same place now.  There is a danger that I missed
something here, and thus there is a slight possibility that usage counts
will get out of synch and the system will wedge.

 3) The problem involving > 16 disks was a weird one.  The symptom was that
ext2 didn't recognize the superblock, and as a result it went onto the next
filesystem - iso9660 in this case.  There were spew messages on the console
complaining about the fact that the disk drive didn't support multi-session.
There were actually two bugs - the first one I had fixed some time ago.  I
am not 100% certain that I have fixed the second bug, but I believe the
underlying problem was caused by the incorrect usage of the MINOR() macro in
sd.c.  Whether or not this fully corrects the problem, the second thing was
a real bug.

    4) I fixed a bug in a previous patch which would have probably led to
spurious messages about running low on DMA memory.

-Eric





------=_NextPart_000_0030_01BF4CDD.E4FC8120
Content-Type: application/octet-stream;
	name="linux34.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="linux34.diff"

Index: linux/drivers/scsi/hosts.h=0A=
diff -c linux/drivers/scsi/hosts.h:1.1.1.2 linux/drivers/scsi/hosts.h:1.2=0A=
*** linux/drivers/scsi/hosts.h:1.1.1.2	Sat Dec 18 18:33:45 1999=0A=
--- linux/drivers/scsi/hosts.h	Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 437,442 ****=0A=
--- 437,444 ----=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=
***************=0A=
*** 447,453 ****=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=
  };=0A=
  =0A=
  extern struct Scsi_Device_Template sd_template;=0A=
--- 449,456 ----=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=
!                                            Selects command for blkdevs =
*/=0A=
  };=0A=
  =0A=
  extern struct Scsi_Device_Template sd_template;=0A=
Index: linux/drivers/scsi/scsi.c=0A=
diff -c linux/drivers/scsi/scsi.c:1.1.1.4 linux/drivers/scsi/scsi.c:1.3=0A=
*** linux/drivers/scsi/scsi.c:1.1.1.4	Wed Dec 22 10:28:43 1999=0A=
--- linux/drivers/scsi/scsi.c	Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 1470,1478 ****=0A=
  	 */=0A=
  =0A=
  =0A=
- 	host->host_busy++;=0A=
- 	device->device_busy++;=0A=
- =0A=
  	/*=0A=
  	 * Our own function scsi_done (which marks the host as not busy, =
disables=0A=
  	 * the timeout counter, etc) will be called by us or by the=0A=
--- 1470,1475 ----=0A=
***************=0A=
*** 1575,1580 ****=0A=
--- 1572,1580 ----=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: linux/drivers/scsi/scsi_error.c=0A=
diff -c linux/drivers/scsi/scsi_error.c:1.1.1.4 =
linux/drivers/scsi/scsi_error.c:1.4=0A=
*** linux/drivers/scsi/scsi_error.c:1.1.1.4	Wed Dec 22 10:28:44 1999=0A=
--- linux/drivers/scsi/scsi_error.c	Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 1778,1783 ****=0A=
--- 1778,1794 ----=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=
***************=0A=
*** 1809,1815 ****=0A=
--- 1820,1833 ----=0A=
  	int rtn;=0A=
  	DECLARE_MUTEX_LOCKED(sem);=0A=
  =0A=
+         /*=0A=
+          * We only listen to signals if the HA was loaded as a module.=0A=
+          * If the HA was compiled into the kernel, then we don't listen=0A=
+          * to any signals.=0A=
+          */=0A=
+         if( host->loaded_as_module ) {=0A=
  	siginitsetinv(&current->blocked, SHUTDOWN_SIGS);=0A=
+         }=0A=
  =0A=
  	lock_kernel();=0A=
  =0A=
***************=0A=
*** 1844,1853 ****=0A=
--- 1862,1875 ----=0A=
  		 * trying to unload a module.=0A=
  		 */=0A=
  		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler sleeping\n"));=0A=
+                 if( host->loaded_as_module ) {=0A=
  		down_interruptible(&sem);=0A=
  =0A=
  		if (signal_pending(current))=0A=
  			break;=0A=
+                 } else {=0A=
+                         down(&sem);=0A=
+                 }=0A=
  =0A=
  		SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler waking up\n"));=0A=
  =0A=
Index: linux/drivers/scsi/scsi_lib.c=0A=
diff -c linux/drivers/scsi/scsi_lib.c:1.1.1.3 =
linux/drivers/scsi/scsi_lib.c:1.3=0A=
*** linux/drivers/scsi/scsi_lib.c:1.1.1.3	Wed Dec 22 10:28:45 1999=0A=
--- linux/drivers/scsi/scsi_lib.c	Wed Dec 22 02:41:24 1999=0A=
***************=0A=
*** 607,612 ****=0A=
--- 607,628 ----=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=
***************=0A=
*** 742,750 ****=0A=
  			if (!SCpnt) {=0A=
  				break;=0A=
  			}=0A=
- 			SHpnt->host_busy++;=0A=
- 			SDpnt->device_busy++;=0A=
  		}=0A=
  =0A=
  		/*=0A=
  		 * FIXME(eric)=0A=
--- 758,771 ----=0A=
  			if (!SCpnt) {=0A=
  				break;=0A=
  			}=0A=
  		}=0A=
+ =0A=
+ 		/*=0A=
+ 		 * Now bump the usage count for both the host and the=0A=
+ 		 * device.=0A=
+ 		 */=0A=
+ 		SHpnt->host_busy++;=0A=
+ 		SDpnt->device_busy++;=0A=
  =0A=
  		/*=0A=
  		 * FIXME(eric)=0A=
Index: linux/drivers/scsi/scsi_merge.c=0A=
diff -c linux/drivers/scsi/scsi_merge.c:1.1.1.3 =
linux/drivers/scsi/scsi_merge.c:1.3=0A=
*** linux/drivers/scsi/scsi_merge.c:1.1.1.3	Wed Dec 22 10:28:45 1999=0A=
--- linux/drivers/scsi/scsi_merge.c	Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 290,295 ****=0A=
--- 290,319 ----=0A=
  =0A=
  	count =3D bh->b_size >> 9;=0A=
  	sector =3D bh->b_rsector;=0A=
+ #if CONFIG_HIGHMEM=0A=
+ 	/*=0A=
+ 	 * This is a temporary hack for the time being.=0A=
+ 	 * In some cases, the ll_rw_blk layer is creating=0A=
+ 	 * bounce buffers for us - this implies that we don't=0A=
+ 	 * need to down here, but queue management becomes quite=0A=
+ 	 * difficult otherwise.  When the ll_rw_blk layer gets=0A=
+ 	 * cleaned up to handle bounce buffers better, then=0A=
+ 	 * this hack can be cleaned up.=0A=
+ 	 */=0A=
+ 	if( sector =3D=3D -1 )=0A=
+ 	{=0A=
+ 		struct buffer_head * bh_new;=0A=
+ 		bh_new =3D (struct buffer_head *) bh->b_dev_id;=0A=
+ 		if( bh_new !=3D NULL )=0A=
+ 		{=0A=
+ 			sector =3D bh_new->b_rsector;=0A=
+ 		}=0A=
+ 		if( sector =3D=3D -1 )=0A=
+ 		{=0A=
+ 			panic("Unable to merge ambiguous block request");=0A=
+ 		}=0A=
+ 	}=0A=
+ #endif=0A=
  =0A=
  	/*=0A=
  	 * We come in here in one of two cases.   The first is that we=0A=
***************=0A=
*** 765,771 ****=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=
  			{=0A=
  				break;=0A=
  			}=0A=
--- 789,796 ----=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 - this_count < 30 =0A=
! 			    || this_count =3D=3D sectors )=0A=
  			{=0A=
  				break;=0A=
  			}=0A=
***************=0A=
*** 831,854 ****=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=
   * Function:    initialize_merge_fn()=0A=
   *=0A=
--- 856,866 ----=0A=
   * We always force "_VALID" to 1.  Eventually clean this up=0A=
   * and get rid of the extra argument.=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=
***************=0A=
*** 881,901 ****=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=
  	if (!CLUSTERABLE_DEVICE(SHpnt, SDpnt) && SHpnt->unchecked_isa_dma =
=3D=3D 0) {=0A=
  		q->merge_fn =3D scsi_merge_fn_;=0A=
--- 893,904 ----=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=
! 	 * 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: linux/drivers/scsi/sd.c=0A=
diff -c linux/drivers/scsi/sd.c:1.1.1.3 linux/drivers/scsi/sd.c:1.4=0A=
*** linux/drivers/scsi/sd.c:1.1.1.3	Wed Dec 22 10:28:46 1999=0A=
--- linux/drivers/scsi/sd.c	Wed Dec 22 18:37:56 1999=0A=
***************=0A=
*** 202,207 ****=0A=
--- 202,212 ----=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=
***************=0A=
*** 229,235 ****=0A=
  	Scsi_Disk *dpnt;=0A=
  	char nbuff[6];=0A=
  =0A=
! 	devm =3D MINOR(SCpnt->request.rq_dev);=0A=
  	dev =3D DEVICE_NR(SCpnt->request.rq_dev);=0A=
  =0A=
  	block =3D SCpnt->request.sector;=0A=
--- 234,240 ----=0A=
  	Scsi_Disk *dpnt;=0A=
  	char nbuff[6];=0A=
  =0A=
! 	devm =3D SD_PARTITION(SCpnt->request.rq_dev);=0A=
  	dev =3D DEVICE_NR(SCpnt->request.rq_dev);=0A=
  =0A=
  	block =3D SCpnt->request.sector;=0A=
***************=0A=
*** 561,567 ****=0A=
  			default:=0A=
  				break;=0A=
  			}=0A=
! 			error_sector -=3D sd[MINOR(SCpnt->request.rq_dev)].start_sect;=0A=
  			error_sector &=3D ~(block_sectors - 1);=0A=
  			good_sectors =3D error_sector - SCpnt->request.sector;=0A=
  			if (good_sectors < 0 || good_sectors >=3D this_count)=0A=
--- 566,572 ----=0A=
  			default:=0A=
  				break;=0A=
  			}=0A=
! 			error_sector -=3D =
sd[SD_PARTITION(SCpnt->request.rq_dev)].start_sect;=0A=
  			error_sector &=3D ~(block_sectors - 1);=0A=
  			good_sectors =3D error_sector - SCpnt->request.sector;=0A=
  			if (good_sectors < 0 || good_sectors >=3D this_count)=0A=
Index: linux/drivers/scsi/sg.c=0A=
diff -c linux/drivers/scsi/sg.c:1.1.1.4 linux/drivers/scsi/sg.c:1.3=0A=
*** linux/drivers/scsi/sg.c:1.1.1.4	Wed Dec 22 10:28:46 1999=0A=
--- linux/drivers/scsi/sg.c	Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 101,110 ****=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=
  =0A=
  =0A=
  typedef struct sg_scatter_hold  /* holding area for scsi scatter =
gather info */=0A=
--- 101,117 ----=0A=
  static void sg_detach(Scsi_Device *);=0A=
  =0A=
  =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: linux/drivers/scsi/st.c=0A=
diff -c linux/drivers/scsi/st.c:1.1.1.3 linux/drivers/scsi/st.c:1.3=0A=
*** linux/drivers/scsi/st.c:1.1.1.3	Wed Dec 22 10:28:48 1999=0A=
--- linux/drivers/scsi/st.c	Wed Dec 22 02:41:25 1999=0A=
***************=0A=
*** 147,156 ****=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=
  static int st_compression(Scsi_Tape *, int);=0A=
  =0A=
--- 147,162 ----=0A=
  static void st_detach(Scsi_Device *);=0A=
  =0A=
  struct Scsi_Device_Template st_template =3D=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_0030_01BF4CDD.E4FC8120--


-
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