patch-2.1.62 linux/drivers/scsi/sr.c

Next file: linux/drivers/scsi/sr.h
Previous file: linux/drivers/scsi/scsi.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.61/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
@@ -45,6 +45,8 @@
 #include <scsi/scsi_ioctl.h>   /* For the door lock/unlock commands */
 #include "constants.h"
 
+MODULE_PARM(xa_test,"i"); /* see sr_ioctl.c */
+
 #define MAX_RETRIES 3
 #define SR_TIMEOUT (30 * HZ)
 
@@ -67,12 +69,15 @@
 
 static int sr_open(struct cdrom_device_info*, int);
 void get_sectorsize(int);
+void get_capabilities(int);
 
 void requeue_sr_request (Scsi_Cmnd * SCpnt);
 static int sr_media_change(struct cdrom_device_info*, int);
 
 static void sr_release(struct cdrom_device_info *cdi)
 {
+	if (scsi_CDs[MINOR(cdi->dev)].sector_size > 2048)
+		sr_set_blocklength(MINOR(cdi->dev),2048);
 	sync_dev(cdi->dev);
 	scsi_CDs[MINOR(cdi->dev)].device->access_count--;
 	if (scsi_CDs[MINOR(cdi->dev)].device->host->hostt->module)
@@ -89,14 +94,14 @@
         sr_media_change,              /* media changed */
         sr_tray_move,                 /* tray move */
         sr_lock_door,                 /* lock door */
-        NULL,                         /* select speed */
+        sr_select_speed,              /* select speed */
         NULL,                         /* select disc */
         sr_get_last_session,          /* get last session */
         sr_get_mcn,                   /* get universal product code */
         sr_reset,                     /* hard reset */
         sr_audio_ioctl,               /* audio ioctl */
         sr_dev_ioctl,                 /* device-specific ioctl */
-        CDC_CLOSE_TRAY | CDC_OPEN_TRAY| CDC_LOCK |
+        CDC_CLOSE_TRAY | CDC_OPEN_TRAY| CDC_LOCK | CDC_SELECT_SPEED |
         CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO,
         0
 };
@@ -139,10 +144,9 @@
         /* If the disk changed, the capacity will now be different,
          * so we force a re-read of this information */
         if (retval) {
-#ifdef CONFIG_BLK_DEV_SR_VENDOR
+		/* check multisession offset etc */
                 sr_cd_check(cdi);
-#endif
-
+		
                  /* 
                   * If the disk changed, the capacity will now be different,
                   * so we force a re-read of this information 
@@ -311,7 +315,8 @@
 		}
 
 		if (SCpnt->sense_buffer[2] == ILLEGAL_REQUEST) {
-			printk("CD-ROM error: ");
+			printk("sr%d: CD-ROM error: ",
+                               DEVICE_NR(SCpnt->request.rq_dev));
 			print_sense("sr", SCpnt);
 			printk("command was: ");
 			print_command(SCpnt->cmnd);
@@ -329,7 +334,8 @@
 		}
 
 		if (SCpnt->sense_buffer[2] == NOT_READY) {
-			printk(KERN_INFO "CD-ROM not ready.  Make sure you have a disc in the drive.\n");
+			printk(KERN_INFO "sr%d: CD-ROM not ready.  Make sure you have a disc in the drive.\n",
+                               DEVICE_NR(SCpnt->request.rq_dev));
 			SCpnt = end_scsi_request(SCpnt, 0, this_count);
 			requeue_sr_request(SCpnt); /* Do next request */
 			return;
@@ -358,7 +364,7 @@
 		    requeue_sr_request(SCpnt);
 		    return;
 		}
-    }
+        }
 
 	/* We only get this far if we have an error we have not recognized */
 	if(result) {
@@ -443,6 +449,17 @@
  	    SDev->was_reset = 0;
 	}
 
+	/* we do lazy blocksize switching (when reading XA sectors,
+	 * see CDROMREADMODE2 ioctl) */
+	if (scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].sector_size > 2048) {
+	    if (!in_interrupt())
+		sr_set_blocklength(DEVICE_NR(CURRENT->rq_dev),2048);
+#if 1
+            else
+                printk("sr: can't switch blocksize: in interrupt\n");
+#endif
+	}
+
 	if (flag++ == 0)
 	    SCpnt = allocate_device(&CURRENT,
 				    scsi_CDs[DEVICE_NR(CURRENT->rq_dev)].device, 0);
@@ -649,7 +666,7 @@
 		     * ensure that all scsi operations are able to do at least a non-scatter/gather
 		     * operation */
 		    if(sgpnt[count].address == NULL){ /* Out of dma memory */
-			printk("Warning: Running low on SCSI DMA buffers");
+			printk("Warning: Running low on SCSI DMA buffers\n");
 			/* Try switching back to a non scatter-gather operation. */
 			while(--count >= 0){
 			    if(sgpnt[count].alt_address)
@@ -805,17 +822,7 @@
     SDp->scsi_request_fn = do_sr_request;
     scsi_CDs[i].device = SDp;
 
-    scsi_CDs[i].cdi.ops        = &sr_dops;
-    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.speed      = 1;
-    scsi_CDs[i].cdi.capacity   = 1;
-    register_cdrom(&scsi_CDs[i].cdi, "sr");
-
-#ifdef CONFIG_BLK_DEV_SR_VENDOR
     sr_vendor_init(i);
-#endif
 
     sr_template.nr_dev++;
     if(sr_template.nr_dev > sr_template.dev_max)
@@ -902,7 +909,7 @@
 		case 512:
 			break;
 		default:
-			printk ("scd%d : unsupported sector size %d.\n",
+			printk ("sr%d: unsupported sector size %d.\n",
 				i, scsi_CDs[i].sector_size);
 			scsi_CDs[i].capacity = 0;
 			scsi_CDs[i].needs_sector_size = 1;
@@ -919,6 +926,58 @@
     scsi_free(buffer, 512);
 }
 
+void get_capabilities(int i){
+    unsigned char cmd[6];
+    unsigned char *buffer;
+    int           rc,n;
+
+    static char *loadmech[] = {
+        "caddy",
+        "tray",
+        "pop-up",
+        "",
+        "changer",
+        "changer",
+        "",
+        ""
+    };          
+
+    buffer = (unsigned char *) scsi_malloc(512);
+    cmd[0] = MODE_SENSE;
+    cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
+    cmd[2] = 0x2a;
+    cmd[4] = 128;
+    cmd[3] = cmd[5] = 0;
+    rc = sr_do_ioctl(i, cmd, buffer, 128, 1);
+    
+    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 */
+        printk("sr%i: scsi3-mmc drive: %dx/%dx %s%s%s%s%s\n",i,
+               ((buffer[n+14] << 8) + buffer[n+15])/176,
+               scsi_CDs[i].cdi.speed,
+               buffer[n+3]&0x01 ? "writer " : "",   /* CD Writer */
+               buffer[n+2]&0x02 ? "cd/rw " : "",    /* can read rewriteable */
+               buffer[n+4]&0x20 ? "xa/form2 " : "", /* can read xa/from2 */
+               buffer[n+5]&0x01 ? "cdda " : "",     /* can read audio data */
+               loadmech[buffer[n+6]>>5]);
+	if ((buffer[n+6] >> 5) == 0)
+		/* caddy drives can't close tray... */
+        	scsi_CDs[i].cdi.mask |= CDC_CLOSE_TRAY;
+    }
+    scsi_free(buffer, 512);
+}
+
 static int sr_registered = 0;
 
 static int sr_init()
@@ -984,7 +1043,16 @@
 	scsi_CDs[i].use = 1;
 	scsi_CDs[i].ten = 1;
 	scsi_CDs[i].remap = 1;
+      	scsi_CDs[i].readcd_known = 0;
+      	scsi_CDs[i].readcd_cdda  = 0;
 	sr_sizes[i] = scsi_CDs[i].capacity >> (BLOCK_SIZE_BITS - 9);
+
+	scsi_CDs[i].cdi.ops        = &sr_dops;
+	scsi_CDs[i].cdi.handle     = &scsi_CDs[i];
+	scsi_CDs[i].cdi.dev        = MKDEV(MAJOR_NR,i);
+	scsi_CDs[i].cdi.mask       = 0;
+	get_capabilities(i);
+	register_cdrom(&scsi_CDs[i].cdi, "sr");
     }
 
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov