patch-2.4.0-prerelease linux/drivers/scsi/sr_ioctl.c
Next file: linux/drivers/scsi/sr_vendor.c
Previous file: linux/drivers/scsi/sr.h
Back to the patch index
Back to the overall index
- Lines: 150
- Date:
Fri Dec 29 14:07:22 2000
- Orig file:
v2.4.0-test12/linux/drivers/scsi/sr_ioctl.c
- Orig date:
Sun Nov 19 18:44:14 2000
diff -u --recursive --new-file v2.4.0-test12/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
@@ -30,11 +30,52 @@
/* In fact, it is very slow if it has to spin up first */
#define IOCTL_TIMEOUT 30*HZ
+/* ATAPI drives don't have a SCMD_PLAYAUDIO_TI command. When these drives
+ are emulating a SCSI device via the idescsi module, they need to have
+ CDROMPLAYTRKIND commands translated into CDROMPLAYMSF commands for them */
+
+static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti)
+{
+ struct cdrom_tocentry trk0_te, trk1_te;
+ struct cdrom_tochdr tochdr;
+ u_char sr_cmd[10];
+ int ntracks, ret;
+
+ if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr)))
+ return ret;
+
+ ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1;
+
+ if (ti->cdti_trk1 == ntracks)
+ ti->cdti_trk1 = CDROM_LEADOUT;
+ else
+ ti->cdti_trk1 ++;
+
+ trk0_te.cdte_track = ti->cdti_trk0;
+ trk0_te.cdte_format = CDROM_MSF;
+ trk1_te.cdte_track = ti->cdti_trk1;
+ trk1_te.cdte_format = CDROM_MSF;
+
+ if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk0_te)))
+ return ret;
+ if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk1_te)))
+ return ret;
+
+ sr_cmd[0] = GPCMD_PLAY_AUDIO_MSF;
+ sr_cmd[3] = trk0_te.cdte_addr.msf.minute;
+ sr_cmd[4] = trk0_te.cdte_addr.msf.second;
+ sr_cmd[5] = trk0_te.cdte_addr.msf.frame;
+ sr_cmd[6] = trk1_te.cdte_addr.msf.minute;
+ sr_cmd[7] = trk1_te.cdte_addr.msf.second;
+ sr_cmd[8] = trk1_te.cdte_addr.msf.frame;
+ return sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
+}
+
/* We do our own retries because we want to know what the specific
error code is. Normally the UNIT_ATTENTION code will automatically
clear after one error */
-int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflength, int quiet, int readwrite)
+int sr_do_ioctl(int target, unsigned char *sr_cmd, void *buffer, unsigned buflength, int quiet, int readwrite, struct request_sense *sense)
{
Scsi_Request *SRpnt;
Scsi_Device *SDev;
@@ -132,7 +173,10 @@
err = -EIO;
}
}
- result = SRpnt->sr_result;
+
+ if (sense)
+ memcpy(sense, SRpnt->sr_sense_buffer, sizeof(*sense));
+
/* Wake up a process waiting for device */
scsi_release_request(SRpnt);
SRpnt = NULL;
@@ -149,7 +193,7 @@
sr_cmd[0] = GPCMD_TEST_UNIT_READY;
sr_cmd[1] = ((scsi_CDs[minor].device->lun) << 5);
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
- return sr_do_ioctl(minor, sr_cmd, NULL, 0, 1, SCSI_DATA_NONE);
+ return sr_do_ioctl(minor, sr_cmd, NULL, 0, 1, SCSI_DATA_NONE, NULL);
}
int sr_tray_move(struct cdrom_device_info *cdi, int pos)
@@ -161,7 +205,7 @@
sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
sr_cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ;
- return sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE);
+ return sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
}
int sr_lock_door(struct cdrom_device_info *cdi, int lock)
@@ -238,7 +282,7 @@
sr_cmd[8] = 24;
sr_cmd[9] = 0;
- result = sr_do_ioctl(MINOR(cdi->dev), sr_cmd, buffer, 24, 0, SCSI_DATA_READ);
+ result = sr_do_ioctl(MINOR(cdi->dev), sr_cmd, buffer, 24, 0, SCSI_DATA_READ, NULL);
memcpy(mcn->medium_catalog_number, buffer + 9, 13);
mcn->medium_catalog_number[13] = 0;
@@ -267,7 +311,7 @@
sr_cmd[2] = (speed >> 8) & 0xff; /* MSB for speed (in kbytes/sec) */
sr_cmd[3] = speed & 0xff; /* LSB */
- if (sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE))
+ if (sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL))
return -EIO;
return 0;
}
@@ -296,7 +340,7 @@
sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
sr_cmd[8] = 12; /* LSB of length */
- result = sr_do_ioctl(target, sr_cmd, buffer, 12, 1, SCSI_DATA_READ);
+ result = sr_do_ioctl(target, sr_cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);
tochdr->cdth_trk0 = buffer[2];
tochdr->cdth_trk1 = buffer[3];
@@ -315,7 +359,7 @@
sr_cmd[6] = tocentry->cdte_track;
sr_cmd[8] = 12; /* LSB of length */
- result = sr_do_ioctl(target, sr_cmd, buffer, 12, 0, SCSI_DATA_READ);
+ result = sr_do_ioctl(target, sr_cmd, buffer, 12, 0, SCSI_DATA_READ, NULL);
tocentry->cdte_ctrl = buffer[5] & 0xf;
tocentry->cdte_adr = buffer[5] >> 4;
@@ -341,7 +385,10 @@
sr_cmd[7] = ti->cdti_trk1;
sr_cmd[8] = ti->cdti_ind1;
- result = sr_do_ioctl(target, sr_cmd, NULL, 255, 0, SCSI_DATA_NONE);
+ result = sr_do_ioctl(target, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);
+ if (result == -EDRIVE_CANT_DO_THIS)
+ result = sr_fake_playtrkind(cdi, ti);
+
break;
}
@@ -402,7 +449,7 @@
cmd[9] = 0x10;
break;
}
- return sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ);
+ return sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
}
/*
@@ -440,7 +487,7 @@
cmd[4] = (unsigned char) (lba >> 8) & 0xff;
cmd[5] = (unsigned char) lba & 0xff;
cmd[8] = 1;
- rc = sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ);
+ rc = sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);
return rc;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)