patch-2.2.15 linux/drivers/block/ide-cd.c
Next file: linux/drivers/block/ide-disk.c
Previous file: linux/drivers/block/ida_cmd.h
Back to the patch index
Back to the overall index
- Lines: 147
- Date:
Fri Apr 21 12:45:50 2000
- Orig file:
v2.2.14/drivers/block/ide-cd.c
- Orig date:
Tue Jan 4 21:18:44 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
@@ -313,6 +313,10 @@
failed_command->c[0] == SCMD_READ_SUBCHANNEL)
return;
}
+
+ if (failed_command && (failed_command->c[0] == TEST_UNIT_READY))
+ return;
+
if (reqbuf->error_code == 0x70 && reqbuf->sense_key == 0x02
&& ((reqbuf->asc == 0x3a && reqbuf->ascq == 0x00) ||
(reqbuf->asc == 0x04 && reqbuf->ascq == 0x01)))
@@ -2567,14 +2571,51 @@
return cdrom_lockdoor (drive, lock, NULL);
}
+/*
+ * the buffer struct used by ide_cdrom_get_capabilities()
+ */
+struct get_capabilities_buf {
+ char pad[8];
+ struct atapi_capabilities_page cap; /* this is 4 bytes short of ATAPI standard */
+ char extra_cap[4]; /* Acer 50X needs the regulation size buffer */
+};
+
+static
+int ide_cdrom_get_capabilities (ide_drive_t *drive, struct get_capabilities_buf *buf)
+{
+ int stat, attempts = 3, buflen = sizeof(*buf);
+
+ /*
+ * Most drives don't care about the buffer size; they return as much info as there's room for.
+ * But some older drives (?) had trouble with the standard size, preferring 4 bytes less.
+ * And the modern Acer 50X rejects anything smaller than the standard size.
+ */
+ if (!(drive->id && !strcmp(drive->id->model,"ATAPI CD ROM DRIVE 50X MAX")))
+ buflen -= sizeof(buf->extra_cap); /* for all drives except Acer 50X */
+
+ do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
+ stat = cdrom_mode_sense (drive, PAGE_CAPABILITIES, 0, (char *)buf, buflen, NULL);
+ if (stat == 0) {
+ /*
+ * The ACER/AOpen 24X cdrom has the speed fields byte-swapped from the standard.
+ */
+ if (!(drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4))) {
+ buf->cap.curspeed = ntohs(buf->cap.curspeed);
+ buf->cap.maxspeed = ntohs(buf->cap.maxspeed);
+ }
+ CDROM_STATE_FLAGS (drive)->current_speed = (((unsigned int)buf->cap.curspeed) + (176/2)) / 176;
+ CDROM_CONFIG_FLAGS(drive)->max_speed = (((unsigned int)buf->cap.maxspeed) + (176/2)) / 176;
+ return 0;
+ }
+ } while (--attempts);
+ return stat;
+}
+
static
int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
{
- int stat, attempts = 3;
- struct {
- char pad[8];
- struct atapi_capabilities_page cap;
- } buf;
+ int stat;
+ struct get_capabilities_buf buf;
ide_drive_t *drive = (ide_drive_t*) cdi->handle;
struct atapi_request_sense reqbuf;
stat=cdrom_select_speed (drive, speed, &reqbuf);
@@ -2582,25 +2623,9 @@
return stat;
/* Now with that done, update the speed fields */
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
- if (attempts-- <= 0)
- return 0;
- stat = cdrom_mode_sense (drive, PAGE_CAPABILITIES, 0,
- (char *)&buf, sizeof (buf), NULL);
- } while (stat);
-
- /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
- if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (((unsigned int)buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (((unsigned int)buf.cap.maxspeed) + (176/2)) / 176;
- } else {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (ntohs(buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (ntohs(buf.cap.maxspeed) + (176/2)) / 176;
- }
+ if (ide_cdrom_get_capabilities(drive,&buf))
+ return 0;
+
cdi->speed = CDROM_STATE_FLAGS (drive)->current_speed;
return 0;
}
@@ -2894,11 +2919,8 @@
static
int ide_cdrom_probe_capabilities (ide_drive_t *drive)
{
- int stat, nslots = 0, attempts = 3;
- struct {
- char pad[8];
- struct atapi_capabilities_page cap;
- } buf;
+ int stat, nslots = 0;
+ struct get_capabilities_buf buf;
if (CDROM_CONFIG_FLAGS (drive)->nec260) {
CDROM_CONFIG_FLAGS (drive)->no_eject = 0;
@@ -2906,13 +2928,8 @@
return nslots;
}
- do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
- if (attempts-- <= 0)
- return 0;
- stat = cdrom_mode_sense (drive, PAGE_CAPABILITIES, 0,
- (char *)&buf, sizeof (buf), NULL);
- } while (stat);
-
+ if (ide_cdrom_get_capabilities(drive,&buf))
+ return 0;
if (buf.cap.lock == 0)
CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
if (buf.cap.eject)
@@ -2953,19 +2970,6 @@
CDROM_CONFIG_FLAGS (drive)->supp_disc_present = 1;
nslots = mechbuf.nslots;
}
- }
-
- /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
- if (drive->id && !drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (((unsigned int)buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (((unsigned int)buf.cap.maxspeed) + (176/2)) / 176;
- } else {
- CDROM_STATE_FLAGS (drive)->current_speed =
- (ntohs(buf.cap.curspeed) + (176/2)) / 176;
- CDROM_CONFIG_FLAGS (drive)->max_speed =
- (ntohs(buf.cap.maxspeed) + (176/2)) / 176;
}
printk ("%s: ATAPI %dX %s",
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)