lkml.org 
[lkml]   [1998]   [Mar]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[patch] ide-cd update

The following patch should go into 2.1.90 (or .91 if I've missed it).
It fixes a bug that showed up when I switched to egcs, and adds support
for the CDROM_SELECT_SPEED ioctl to ide-cd. I also update the ide-cd docs
so people won't have to pester me about the Panasonic 24 speed drives.
It works for me, so I wan't to get this into the kernel to make sure it
works for everybody else. Simply doing a 'cat /proc/sys/dev/cdrom/info'
will show you the current speed of your cdrom drive...

-Erik

--
Erik B. Andersen Web: http://www.inconnect.com/~andersen/
email: andersee@debian.org
--This message was written using 73% post-consumer electrons--

[------patch ide-cd-update---------]

diff -u --recursive --new-file linux-2.1.89.virgin/Documentation/cdrom/ide-cd linux/Documentation/cdrom/ide-cd
--- linux-2.1.89.virgin/Documentation/cdrom/ide-cd Sat Feb 28 09:19:36 1998
+++ linux/Documentation/cdrom/ide-cd Thu Mar 12 17:42:37 1998
@@ -224,10 +224,8 @@
- If the autoprobing is not finding your drive, you can tell the
driver to assume that one exists by using a lilo option of the
form `hdX=cdrom', where X is the drive letter corresponding to
- where your drive is installed (see section 2). This is required
- for CDROM drives such as the Pioneer DR-A24X, which do not properly
- identify themselves as ATAPI CDROM drives. Note that if you
- do this and you see a boot message like
+ where your drive is installed. Note that if you do this and you
+ see a boot message like

hdX: ATAPI cdrom (?)

@@ -281,7 +279,16 @@
there are hardware problems with the interrupt setup; they
apparently don't use interrupts.

-
+ - If you own a Pioneer DR-A24X, you _will_ get nasty error messages
+ on boot such as "irq timeout: status=0x50 { DriveReady SeekComplete }"
+ The Pioneer DR-A24X cdrom drives are fairly popular these days.
+ Unfortunatly, these drives seem to become very confused when we perform
+ the standard Linux ATA disk drive probe. If you own one of these drives,
+ you can bypass the ATA probing which confuses these cdrom drives, by
+ adding `append="hdX=noprobe hdX=cdrom"' to your lilo.conf file and runing
+ lilo (again where X is the drive letter corresponding to where your drive
+ is installed.)
+
c. System hangups.

- If the system locks up when you try to access the cdrom, the most
diff -u --recursive --new-file linux-2.1.89.virgin/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- linux-2.1.89.virgin/drivers/block/ide-cd.c Sat Feb 28 09:20:16 1998
+++ linux/drivers/block/ide-cd.c Fri Mar 13 08:35:03 1998
@@ -26,7 +26,6 @@
* (If you are using a cd changer, you may get errors in the kernel
* logs that are completly expected. Don't complain to me about this,
* unless you have a patch to fix it. I am working on it...)
- * -Implement ide_cdrom_select_speed using the generic cdrom interface
* -Fix ide_cdrom_reset so that it works (it does nothing right now)
* -Query the drive to find what features are available before trying to
* use them (like trying to close the tray in drives that can't).
@@ -189,10 +188,19 @@
* malloc'ed but never free'd when closing the device.
* -- Cleaned up the global namespace a bit by making more
* functions static that should already have been.
+ * 4.11 Mar 12, 1998 -- Added support for the CDROM_SELECT_SPEED ioctl
+ * based on a patch for 2.0.33 by Jelle Foks
+ * <jelle@scintilla.utwente.nl>, a patch for 2.0.33
+ * by Toni Giorgino <toni@pcape2.pi.infn.it>, the SCSI
+ * version, and my own efforts. -erik
+ * -- Fixed a stupid bug which egcs was kind enough to
+ * inform me of where "Illegal mode for this track"
+ * was never returned due to a comparison on data
+ * types of limited range.
*
*************************************************************************/

-#define IDECD_VERSION "4.10"
+#define IDECD_VERSION "4.11"

#include <linux/module.h>
#include <linux/types.h>
@@ -271,8 +279,7 @@

printk (" Error code: 0x%02x\n", reqbuf->error_code);

- if (reqbuf->sense_key >= 0 &&
- reqbuf->sense_key < ARY_LEN (sense_key_texts))
+ if ( reqbuf->sense_key < ARY_LEN (sense_key_texts))
s = sense_key_texts[reqbuf->sense_key];
else
s = "(bad sense key)";
@@ -285,7 +292,7 @@
s = buf;
} else {
int lo, hi;
- int key = (reqbuf->asc << 8);
+ unsigned short key = (reqbuf->asc << 8);
if ( ! (reqbuf->ascq >= 0x80 && reqbuf->ascq <= 0xdd) )
key |= reqbuf->ascq;

@@ -496,7 +503,7 @@
} else if (sense_key == UNIT_ATTENTION) {
/* Check for media change. */
cdrom_saw_media_change (drive);
- printk ("%s: media changed\n", drive->name);
+ /*printk("%s: media changed\n",drive->name);*/
return 0;
} else {
/* Otherwise, print an error. */
@@ -1518,7 +1525,6 @@
return cdrom_queue_packet_command (drive, &pc);
}

-
static int
cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
struct atapi_request_sense *reqbuf)
@@ -1721,7 +1727,6 @@
return cdrom_queue_packet_command (drive, &pc);
}

-
static int
cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,
struct atapi_request_sense *reqbuf)
@@ -1742,6 +1747,43 @@
}


+/* Note that this takes speed in kbytes/second, so don't try requesting
+ silly speeds like 2 here. Common speeds include:
+ 176 kbytes/second -- 1x
+ 353 kbytes/second -- 2x
+ 387 kbytes/second -- 2.2x
+ 528 kbytes/second -- 3x
+ 706 kbytes/second -- 4x
+ 1400 kbytes/second -- 8x
+ 2800 kbytes/second -- 16x
+ ATAPI drives are free to select the speed you request or any slower
+ rate :-( Requesting too fast a speed will _not_ produce an error. */
+static int
+cdrom_select_speed (ide_drive_t *drive, int speed,
+ struct atapi_request_sense *reqbuf)
+{
+ struct packet_command pc;
+ memset (&pc, 0, sizeof (pc));
+ pc.sense_data = reqbuf;
+
+ if (speed < 1)
+ speed = 0xffff; /* set to max */
+ else
+ speed *= 177; /* Nx to kbytes/s */
+
+ pc.c[0] = SET_CD_SPEED;
+ /* Read Drive speed in kbytes/second MSB */
+ pc.c[2] = (speed >> 8) & 0xff;
+ /* Read Drive speed in kbytes/second LSB */
+ pc.c[3] = speed & 0xff;
+ /* Write Drive speed in kbytes/second MSB */
+ //pc.c[4] = (speed >> 8) & 0xff;
+ /* Write Drive speed in kbytes/second LSB */
+ //pc.c[5] = speed & 0xff;
+
+ return cdrom_queue_packet_command (drive, &pc);
+}
+
static int
cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
struct atapi_request_sense *reqbuf)
@@ -2429,6 +2471,44 @@
return cdrom_lockdoor (drive, lock, NULL);
}

+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;
+ ide_drive_t *drive = (ide_drive_t*) cdi->handle;
+ struct atapi_request_sense reqbuf;
+ stat=cdrom_select_speed (drive, speed, &reqbuf);
+ if (stat<0)
+ return stat;
+
+ /* Now that that is 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;
+ }
+ cdi->speed = CDROM_STATE_FLAGS (drive)->current_speed;
+ return 0;
+}
+

static
int ide_cdrom_select_disc (struct cdrom_device_info *cdi, int slot)
@@ -2668,14 +2748,14 @@
ide_cdrom_check_media_change_real, /* media_changed */
ide_cdrom_tray_move, /* tray_move */
ide_cdrom_lock_door, /* lock_door */
- NULL, /* select_speed */
+ ide_cdrom_select_speed, /* select_speed */
ide_cdrom_select_disc, /* select_disc */
ide_cdrom_get_last_session, /* get_last_session */
ide_cdrom_get_mcn, /* get_mcn */
ide_cdrom_reset, /* reset */
ide_cdrom_audio_ioctl, /* audio_ioctl */
ide_cdrom_dev_ioctl, /* dev_ioctl */
- CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK
+ CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED
| CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN
| CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET
| CDC_IOCTLS | CDC_DRIVE_STATUS, /* capability */
@@ -2691,7 +2771,7 @@
devinfo->dev = MKDEV (HWIF(drive)->major, minor);
devinfo->ops = &ide_cdrom_dops;
devinfo->mask = 0;
- *(int *)&devinfo->speed = CDROM_CONFIG_FLAGS (drive)->max_speed;
+ *(int *)&devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed;
*(int *)&devinfo->capacity = nslots;
devinfo->handle = (void *) drive;
strcpy(devinfo->name, drive->name);
@@ -2750,11 +2830,15 @@

/* 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;
+ 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;
+ 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 CDROM",
diff -u --recursive --new-file linux-2.1.89.virgin/drivers/block/ide-cd.h linux/drivers/block/ide-cd.h
--- linux-2.1.89.virgin/drivers/block/ide-cd.h Wed Dec 17 12:11:51 1997
+++ linux/drivers/block/ide-cd.h Fri Mar 13 07:57:58 1998
@@ -71,7 +71,7 @@
#define MODE_SENSE_10 0x5a
#define MODE_SELECT_10 0x55
#define READ_CD 0xbe
-
+#define SET_CD_SPEED 0xbb
#define LOAD_UNLOAD 0xa6
#define MECHANISM_STATUS 0xbd

@@ -431,7 +431,7 @@
with additions from Tables 141 and 142 of the ATAPI 2.6 draft standard. */

struct {
- short asc_ascq;
+ unsigned short asc_ascq;
char *text;
} sense_data_texts[] = {
{ 0x0000, "No additional sense information" },

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.044 / U:0.160 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site