--- dist/linux-2.0/drivers/scsi/scsi.c Sun May 18 23:27:47 1997 +++ linux-2.0/drivers/scsi/scsi.c Sun May 18 23:36:50 1997 @@ -659,6 +659,8 @@ SDpnt->manufacturer = SCSI_MAN_SONY; else if (!strncmp (scsi_result + 8, "PIONEER", 7)) SDpnt->manufacturer = SCSI_MAN_PIONEER; + else if (!strncmp (scsi_result + 8, "HP", 2)) + SDpnt->manufacturer = SCSI_MAN_HP; else SDpnt->manufacturer = SCSI_MAN_UNKNOWN; diff -ur dist/linux-2.0/drivers/scsi/scsi.h linux-2.0/drivers/scsi/scsi.h --- dist/linux-2.0/drivers/scsi/scsi.h Thu Jul 4 00:42:26 1996 +++ linux-2.0/drivers/scsi/scsi.h Sun May 18 23:36:50 1997 @@ -132,6 +132,7 @@ #define SCSI_MAN_NEC_OLDCDR 3 #define SCSI_MAN_SONY 4 #define SCSI_MAN_PIONEER 5 +#define SCSI_MAN_HP 6 /* * As the scsi do command functions are intelligent, and may need to diff -ur dist/linux-2.0/drivers/scsi/sr.c linux-2.0/drivers/scsi/sr.c --- dist/linux-2.0/drivers/scsi/sr.c Sun May 18 23:27:47 1997 +++ linux-2.0/drivers/scsi/sr.c Sun May 18 23:36:50 1997 @@ -384,6 +384,10 @@ * - SONY: Same as Nec. * * - PIONEER: works with SONY code (may be others too ?) + * + * 19960531 + * + * - HP: Untested. */ void sr_photocd(struct inode *inode) @@ -450,11 +454,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: @@ -491,12 +490,8 @@ 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); @@ -514,7 +509,7 @@ #ifdef DEBUG printk(KERN_DEBUG "sr_photocd: get_density: 0x%x\n",rec[4]); #endif - + /* ...and only if necessary a set_density */ if ((rec[4] != 0x81 && is_xa) || (rec[4] != 0 && !is_xa)) { #ifdef DEBUG @@ -570,19 +565,69 @@ } 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 - break; - + memset(buf,0,40); + *((unsigned long*)buf) = 0x0; /* we send nothing... */ + *((unsigned long*)buf+1) = 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, buf); + 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; + } + memset(buf,0,40); + *((unsigned long*)buf) = 0x0; /* we send nothing... */ + *((unsigned long*)buf+1) = 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, buf); + 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: sector = 0; 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;