patch-2.1.4 linux/drivers/scsi/sr.c
Next file: linux/drivers/scsi/sr_ioctl.c
Previous file: linux/drivers/scsi/sg.c
Back to the patch index
Back to the overall index
- Lines: 219
- Date:
Mon Oct 14 09:07:16 1996
- Orig file:
v2.1.3/linux/drivers/scsi/sr.c
- Orig date:
Thu Sep 26 15:28:30 1996
diff -u --recursive --new-file v2.1.3/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
@@ -384,12 +384,18 @@
* - SONY: Same as Nec.
*
* - PIONEER: works with SONY code (may be others too ?)
+ *
+ * 19961011
+ *
+ * - HP: reportedly working.
*/
void sr_photocd(struct inode *inode)
{
unsigned long sector,min,sec,frame;
unsigned char buf[40]; /* the buffer for the ioctl */
+ Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf;
+#define CLEAR_CMD_BUFFER memset (buf, 0, sizeof buf);
unsigned char *cmd; /* the scsi-command */
unsigned char *send; /* the data we send to the drive ... */
unsigned char *rec; /* ... and get back */
@@ -419,7 +425,7 @@
sector = 0;
is_xa = 0;
no_multi = 0;
- cmd = rec = &buf[8];
+ cmd = rec = sic->data;
switch(scsi_CDs[MINOR(inode->i_rdev)].device->manufacturer) {
@@ -427,14 +433,14 @@
#ifdef DEBUG
printk(KERN_DEBUG "sr_photocd: use NEC code\n");
#endif
- memset(buf,0,40);
- *((unsigned int*)buf) = 0x0; /* we send nothing... */
- *((unsigned int*)buf+1) = 0x16; /* and receive 0x16 bytes */
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0x0; /* we send nothing... */
+ sic->outlen = 0x16; /* and receive 0x16 bytes */
cmd[0] = 0xde;
cmd[1] = 0x03;
cmd[2] = 0xb0;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
+ SCSI_IOCTL_SEND_COMMAND, sic);
if (rc != 0) {
if (rc != 0x28000002) /* drop "not ready" */
printk(KERN_WARNING"sr_photocd: ioctl error (NEC): 0x%x\n",rc);
@@ -450,11 +456,6 @@
frame = (unsigned long) rec[17]/16*10 + (unsigned long) rec[17]%16;
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
is_xa = (rec[14] == 0xb0);
-#ifdef DEBUG
- if (sector) {
- printk(KERN_DEBUG "sr_photocd: multisession CD detected. start: %lu\n",sector);
- }
-#endif
break;
case SCSI_MAN_TOSHIBA:
@@ -464,13 +465,13 @@
/* we request some disc information (is it a XA-CD ?,
* where starts the last session ?) */
- memset(buf,0,40);
- *((unsigned int*)buf) = (unsigned int) 0;
- *((unsigned int*)buf+1) = (unsigned int) 4; /* receive 4 bytes */
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0; /* we send nothing... */
+ sic->outlen = 4; /* and receive 4 bytes */
cmd[0] = (unsigned char) 0x00c7;
cmd[1] = (unsigned char) 3;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
+ SCSI_IOCTL_SEND_COMMAND, sic);
if (rc != 0) {
if (rc == 0x28000002) {
/* Got a "not ready" - error. No chance to find out if this is
@@ -491,22 +492,18 @@
sec = (unsigned long) rec[2]/16*10 + (unsigned long) rec[2]%16;
frame = (unsigned long) rec[3]/16*10 + (unsigned long) rec[3]%16;
sector = min*CD_SECS*CD_FRAMES + sec*CD_FRAMES + frame;
- if (sector) {
+ if (sector)
sector -= CD_BLOCK_OFFSET;
-#ifdef DEBUG
- printk(KERN_DEBUG "sr_photocd: multisession CD detected: start: %lu\n",sector);
-#endif
- }
/* now we do a get_density... */
- memset(buf,0,40);
- *((unsigned int*)buf) = (unsigned int) 0;
- *((unsigned int*)buf+1) = (unsigned int) 12;
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0; /* we send nothing... */
+ sic->outlen = 12; /* and receive 12 bytes */
cmd[0] = (unsigned char) MODE_SENSE;
cmd[2] = (unsigned char) 1;
cmd[4] = (unsigned char) 12;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
+ SCSI_IOCTL_SEND_COMMAND, sic);
if (rc != 0) {
printk(KERN_WARNING "sr_photocd: ioctl error (TOSHIBA #2): 0x%x\n",rc);
break;
@@ -520,9 +517,9 @@
#ifdef DEBUG
printk(KERN_DEBUG "sr_photocd: doing set_density\n");
#endif
- memset(buf,0,40);
- *((unsigned int*)buf) = (unsigned int) 12; /* send 12 bytes */
- *((unsigned int*)buf+1) = (unsigned int) 0;
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 12; /* we send 12 bytes... */
+ sic->outlen = 0; /* and receive nothing */
cmd[0] = (unsigned char) MODE_SELECT;
cmd[1] = (unsigned char) (1 << 4);
cmd[4] = (unsigned char) 12;
@@ -533,7 +530,7 @@
(unsigned char) 0x81 : (unsigned char) 0;
send[10] = (unsigned char) 0x08;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
+ SCSI_IOCTL_SEND_COMMAND, sic);
if (rc != 0) {
printk(KERN_WARNING "sr_photocd: ioctl error (TOSHIBA #3): 0x%x\n",rc);
}
@@ -550,14 +547,15 @@
printk(KERN_DEBUG "sr_photocd: use SONY/PIONEER/MATSHITA code\n");
#endif
get_sectorsize(MINOR(inode->i_rdev)); /* spinup (avoid timeout) */
- memset(buf,0,40);
- *((unsigned int*)buf) = 0x0; /* we send nothing... */
- *((unsigned int*)buf+1) = 0x0c; /* and receive 0x0c bytes */
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0x0; /* we send nothing... */
+ sic->outlen = 0x0c; /* and receive 0x0c bytes */
+
cmd[0] = READ_TOC;
cmd[8] = 0x0c;
cmd[9] = 0x40;
rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
- SCSI_IOCTL_SEND_COMMAND, buf);
+ SCSI_IOCTL_SEND_COMMAND, sic);
if (rc != 0) {
if (rc != 0x28000002) /* drop "not ready" */
@@ -571,12 +569,56 @@
}
sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24);
is_xa = !!sector;
+ break;
+ case SCSI_MAN_HP:
+#define DEBUG
#ifdef DEBUG
- if (sector)
- printk (KERN_DEBUG "sr_photocd: multisession CD detected. start: %lu\n",sector);
+ printk(KERN_DEBUG "sr_photocd: use HP code\n");
#endif
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0x0; /* we send nothing... */
+ sic->outlen = 0x4; /* and receive 4 bytes */
+ cmd[0] = 0x43; /* Read TOC */
+ cmd[8] = 0x04;
+ cmd[9] = 0x40;
+ rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
+ SCSI_IOCTL_SEND_COMMAND, sic);
+ if (rc != 0) {
+ if (rc != 0x28000002) /* drop "not ready" */
+ printk(KERN_WARNING "sr_photocd: ioctl error (HP-1): 0x%x\n",rc);
break;
+ }
+ if ((rc = rec[2]) == 0) {
+ printk (KERN_WARNING "sr_photocd: (HP) No finished session");
+ break;
+ }
+ CLEAR_CMD_BUFFER;
+ sic->inlen = 0x0; /* we send nothing... */
+ sic->outlen = 0x0c; /* and receive 0x0c bytes */
+ cmd[0] = 0x43; /* Read TOC */
+ cmd[6] = rc & 0x7f; /* number of last session */
+ cmd[8] = 0x0c;
+ cmd[9] = 0x40;
+ rc = kernel_scsi_ioctl(scsi_CDs[MINOR(inode->i_rdev)].device,
+ SCSI_IOCTL_SEND_COMMAND, sic);
+ if (rc != 0) {
+ if (rc != 0x28000002) /* drop "not ready" */
+ printk(KERN_WARNING "sr_photocd: ioctl error (HP-2): 0x%x\n",rc);
+ break;
+ }
+#undef STRICT_HP
+#ifdef STRICT_HP
+ sector = rec[11] + (rec[10] << 8) + (rec[9] << 16);
+ /* HP documentation states that Logical Start Address is
+ returned as three (!) bytes, and that rec[8] is
+ reserved. This is strange, because a LBA usually is
+ 4 bytes long. */
+#else
+ sector = rec[11] + (rec[10] << 8) + (rec[9] << 16) + (rec[8] << 24);
+#endif
+ is_xa = !!sector;
+ break;
case SCSI_MAN_NEC_OLDCDR:
case SCSI_MAN_UNKNOWN:
default:
@@ -584,6 +626,12 @@
no_multi = 1;
break; }
+#ifdef DEBUG
+ if (sector)
+ printk (KERN_DEBUG "sr_photocd: multisession CD detected. start: %lu\n",sector);
+#endif
+#undef DEBUG
+
scsi_CDs[MINOR(inode->i_rdev)].mpcd_sector = sector;
if (is_xa)
scsi_CDs[MINOR(inode->i_rdev)].xa_flags |= 0x01;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov