[3032] in linux-scsi channel archive

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

Re: new scsi code

daemon@ATHENA.MIT.EDU (Gerd Knorr)
Mon Jan 5 12:57:56 1998

Date: 	Mon, 5 Jan 1998 17:43:48 +0100 (MET)
From: Gerd Knorr <kraxel@goldbach.isdn.cs.tu-berlin.de>
To: Eric Youngdale <eric@andante.jic.com>
cc: linux-scsi@vger.rutgers.edu
In-Reply-To: <Pine.LNX.3.95.980105080903.412O-100000@andante.jic.com>


> 	I don't read linux-kernel.  I do read linux-scsi.  Far too much
> noise on the kernel group (I used to spent all my free time deleting mail
> and not accomplishing anything). 

I gate linux-kernel to a local newsgroup, a good solution for this
Problem. 

> To: Andrew Sapozhnikov <sapa@hq.icb.chel.su>
> CC: Gerd Knorr <kraxel@goldbach.isdn.cs.tu-berlin.de>
> 
> 	If you use the old error handling code, does the problem go away,
> or does it persist?  If you are using the old error handling code, do you
> still get the "interrupt received but no mail" message?

I tracked the problem down in the meantime. scsi_check_sense() returns
FAILED for a ILLEGAL REQUEST.  Result is that scsi_unjam_host() gets
called and takes the device offline...

If scsi_check_sense() returns SUCCESS, the error is handled one layer up
and everything is fine :-)


Below a patch for 2.1.x, it modifies scsi_check_sense() and has a few
changes for the scsi cdrom driver: some for the new scsi code, some to
make multisession handling for cdrom writers work (I hope).

That's the code I'm running currently, so far without problems.

  Gerd

------------------------------- cut here -------------------------------
Common subdirectories: kernel/2.1.77/drivers/scsi/aic7xxx and linux/drivers/scsi/aic7xxx
diff -u kernel/2.1.77/drivers/scsi/scsi_error.c linux/drivers/scsi/scsi_error.c
--- kernel/2.1.77/drivers/scsi/scsi_error.c	Wed Dec 24 11:34:05 1997
+++ linux/drivers/scsi/scsi_error.c	Sun Dec 28 14:49:11 1997
@@ -1088,10 +1088,12 @@
     case MEDIUM_ERROR:
 	return FAILED;
 
+    case ILLEGAL_REQUEST:
+	return SUCCESS;
+
     case BLANK_CHECK:
     case DATA_PROTECT:
     case HARDWARE_ERROR:
-    case ILLEGAL_REQUEST:
     default:
 	return FAILED;
     }
diff -u kernel/2.1.77/drivers/scsi/scsi_syms.c linux/drivers/scsi/scsi_syms.c
--- kernel/2.1.77/drivers/scsi/scsi_syms.c	Sat Jan  3 13:24:28 1998
+++ linux/drivers/scsi/scsi_syms.c	Sat Jan  3 13:24:00 1998
@@ -53,6 +53,7 @@
 EXPORT_SYMBOL(scsi_init_malloc);
 EXPORT_SYMBOL(scsi_init_free);
 EXPORT_SYMBOL(scsi_ioctl);
+EXPORT_SYMBOL(scsi_sleep);
 EXPORT_SYMBOL(print_command);
 EXPORT_SYMBOL(print_sense);
 EXPORT_SYMBOL(print_msg);
diff -u kernel/2.1.77/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- kernel/2.1.77/drivers/scsi/sr.c	Wed Dec 24 11:34:05 1997
+++ linux/drivers/scsi/sr.c	Sun Dec 28 13:40:20 1997
@@ -854,8 +854,6 @@
     SDp->scsi_request_fn = do_sr_request;
     scsi_CDs[i].device = SDp;
 
-    sr_vendor_init(i);
-
     sr_template.nr_dev++;
     if(sr_template.nr_dev > sr_template.dev_max)
 	panic ("scsi_devices corrupt (sr)");
@@ -986,13 +984,11 @@
     if (-EINVAL == rc) {
         /* failed, drive has'nt this mode page */
         scsi_CDs[i].cdi.speed      = 1;
-        scsi_CDs[i].cdi.capacity   = 1;
         /* disable speed select, drive probably can't do this either */
         scsi_CDs[i].cdi.mask      |= CDC_SELECT_SPEED;
     } else {
         n = buffer[3]+4;
         scsi_CDs[i].cdi.speed    = ((buffer[n+8] << 8) + buffer[n+9])/176;
-        scsi_CDs[i].cdi.capacity = 1;
       	scsi_CDs[i].readcd_known = 1;
         scsi_CDs[i].readcd_cdda  = buffer[n+5] & 0x01;
         /* print some capability bits */
@@ -1085,7 +1081,9 @@
 	scsi_CDs[i].cdi.handle     = &scsi_CDs[i];
 	scsi_CDs[i].cdi.dev        = MKDEV(MAJOR_NR,i);
 	scsi_CDs[i].cdi.mask       = 0;
+        scsi_CDs[i].cdi.capacity   = 1;
 	get_capabilities(i);
+	sr_vendor_init(i);
 
 	sprintf(name, "sr%d", i);
 	strcpy(scsi_CDs[i].cdi.name, name);
diff -u kernel/2.1.77/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- kernel/2.1.77/drivers/scsi/sr_ioctl.c	Wed Dec 24 11:34:05 1997
+++ linux/drivers/scsi/sr_ioctl.c	Sun Dec 28 14:50:09 1997
@@ -30,7 +30,7 @@
 #define IOCTL_RETRIES 3
 /* The CDROM is fairly slow, so we need a little extra time */
 /* In fact, it is very slow if it has to spin up first */
-#define IOCTL_TIMEOUT 3000
+#define IOCTL_TIMEOUT 30*HZ
 
 static void sr_ioctl_done(Scsi_Cmnd * SCpnt)
 {
@@ -51,11 +51,15 @@
 int sr_do_ioctl(int target, unsigned char * sr_cmd, void * buffer, unsigned buflength, int quiet)
 {
     Scsi_Cmnd * SCpnt;
+    Scsi_Device * SDev;
     int result, err = 0, retries = 0;
 
+    SDev  = scsi_CDs[target].device;
     SCpnt = scsi_allocate_device(NULL, scsi_CDs[target].device, 1);
 
 retry:
+    if( !scsi_block_when_processing_errors(SDev) )
+        return -ENODEV;
     {
 	struct semaphore sem = MUTEX_LOCKED;
 	SCpnt->request.sem = &sem;
@@ -69,7 +73,7 @@
     result = SCpnt->result;
     
     /* Minimal error checking.  Ignore cases we know about, and report the rest. */
-    if(driver_byte(result) != 0)
+    if(driver_byte(result) != 0) {
 	switch(SCpnt->sense_buffer[2] & 0xf) {
 	case UNIT_ATTENTION:
 	    scsi_CDs[target].device->changed = 1;
@@ -86,9 +90,7 @@
                     printk(KERN_INFO "sr%d: CDROM not ready yet.\n", target);
 		if (retries++ < 10) {
 		    /* sleep 2 sec and try again */
-                    current->state = TASK_INTERRUPTIBLE;
-                    current->timeout = jiffies + 200;
-                    schedule ();
+		    scsi_sleep(2*HZ);
                     goto retry;
 		} else {
 		    /* 20 secs are enouth? */
@@ -123,7 +125,8 @@
 	    print_command(sr_cmd);
 	    print_sense("sr", SCpnt);
             err = -EIO;
-	};
+	}
+    }
     
     result = SCpnt->result;
     /* Wake up a process waiting for device*/
@@ -279,23 +282,10 @@
 int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void* arg)
 {
     u_char  sr_cmd[10];    
-    Scsi_Device * SDev;
     int result, target;
     
     target = MINOR(cdi->dev);
     
-    SDev = scsi_CDs[target].device;
-    /*
-     * If we are in the middle of error recovery, don't let anyone
-     * else try and use this device.  Also, if error recovery fails, it
-     * may try and take the device offline, in which case all further
-     * access to the device is prohibited.
-     */
-    if( !scsi_block_when_processing_errors(SDev) )
-      {
-        return -ENODEV;
-      }
-
     switch (cmd) 
     {
 	/* Sun-compatible */
@@ -718,22 +708,9 @@
                  unsigned int cmd, unsigned long arg)
 {
     int target, err;
-    Scsi_Device * SDev;
     
     target = MINOR(cdi->dev);
     
-    SDev = scsi_CDs[target].device;
-    /*
-     * If we are in the middle of error recovery, don't let anyone
-     * else try and use this device.  Also, if error recovery fails, it
-     * may try and take the device offline, in which case all further
-     * access to the device is prohibited.
-     */
-    if( !scsi_block_when_processing_errors(SDev) )
-      {
-        return -ENODEV;
-      }
-
     switch (cmd) {
     case CDROMREADMODE1:
     case CDROMREADMODE2:
diff -u kernel/2.1.77/drivers/scsi/sr_vendor.c linux/drivers/scsi/sr_vendor.c
--- kernel/2.1.77/drivers/scsi/sr_vendor.c	Wed Dec  3 17:43:24 1997
+++ linux/drivers/scsi/sr_vendor.c	Wed Dec  3 14:40:47 1997
@@ -56,8 +56,7 @@
 
 #define VENDOR_NEC             2
 #define VENDOR_TOSHIBA         3
-#define VENDOR_HP_4020         4   /* HP 4xxx writers, others too ?? */
-#define VENDOR_HP_6020         5   /* HP 6020 writers */
+#define VENDOR_WRITER          4   /* pre-scsi3 writers */
 
 #define VENDOR_ID (scsi_CDs[minor].vendor)
 
@@ -72,13 +71,12 @@
 
 	/* default */
 	VENDOR_ID = VENDOR_SCSI3;
+	if (scsi_CDs[minor].readcd_known)
+		/* this is true for scsi3/mmc drives - no more checks */
+		return;
 
-	if ((!strncmp(vendor,"HP",2) || !strncmp(vendor,"PHILIPS",7)) &&
-	    scsi_CDs[minor].device->type == TYPE_WORM) {
-		if (!strncmp(model,"CD-Writer 6020",14))
-                    VENDOR_ID = VENDOR_HP_6020;
-                else
-                    VENDOR_ID = VENDOR_HP_4020;
+	if (scsi_CDs[minor].device->type == TYPE_WORM) {
+		VENDOR_ID = VENDOR_WRITER;
 
 	} else if (!strncmp (vendor, "NEC", 3)) {
 		VENDOR_ID = VENDOR_NEC;
@@ -233,16 +231,13 @@
 			sector -= CD_MSF_OFFSET;
 		break;
 
-	case VENDOR_HP_4020:
-		/* Fallthrough */
-	case VENDOR_HP_6020:
+	case VENDOR_WRITER:
+		memset(cmd,0,12);
 		cmd[0] = READ_TOC;
 		cmd[1] = (scsi_CDs[minor].device->lun << 5);
-		cmd[8] = (VENDOR_ID == VENDOR_HP_4020) ?
-			0x04 : 0x0c;
+		cmd[8] = 0x04;
 		cmd[9] = 0x40;
-		rc = sr_do_ioctl(minor, cmd, buffer,
-		    (VENDOR_ID == VENDOR_HP_4020) ? 0x04 : 0x0c, 0);
+		rc = sr_do_ioctl(minor, cmd, buffer, 0x04, 0);
 		if (rc != 0) {
 			break;
 		}
@@ -252,16 +247,14 @@
 			break;
 		}
 
- 		if (VENDOR_ID == VENDOR_HP_4020) {
- 		    cmd[0] = READ_TOC; /* Read TOC */
- 		    cmd[1] = (scsi_CDs[minor].device->lun << 5);
- 		    cmd[6] = rc & 0x7f;  /* number of last session */
- 		    cmd[8] = 0x0c;
- 		    cmd[9] = 0x40;
- 		    rc = sr_do_ioctl(minor, cmd, buffer, 12, 0);	
- 		    if (rc != 0) {
- 			    break;
- 		    }
+		cmd[0] = READ_TOC; /* Read TOC */
+		cmd[1] = (scsi_CDs[minor].device->lun << 5);
+		cmd[6] = rc & 0x7f;  /* number of last session */
+		cmd[8] = 0x0c;
+		cmd[9] = 0x40;
+		rc = sr_do_ioctl(minor, cmd, buffer, 12, 0);	
+		if (rc != 0) {
+			break;
 		}
 
 		sector = buffer[11] + (buffer[10] << 8) +



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