patch-1.3.28 linux/drivers/block/ide-cd.c
Next file: linux/drivers/block/ide.c
Previous file: linux/drivers/block/hd.c
Back to the patch index
Back to the overall index
- Lines: 252
- Date:
Mon Sep 18 08:54:07 1995
- Orig file:
v1.3.27/linux/drivers/block/ide-cd.c
- Orig date:
Sun Sep 3 16:12:48 1995
diff -u --recursive --new-file v1.3.27/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
@@ -41,7 +41,7 @@
* PLAYAUDIO12 is broken on the Aztech; work around it.
* 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c
* (my apologies to Scott, but now ide-cd.c is independent)
- * 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl (UNTESTED).
+ * 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl.
* Implement CDROMREADAUDIO ioctl (UNTESTED).
* Use input_ide_data() and output_ide_data().
* Add door locking.
@@ -63,11 +63,16 @@
* 3.01 Sep 2, 1995 -- Fix ordering of reenabling interrupts in
* cdrom_queue_request.
* Another try at using ide_[input,output]_data.
+ * 3.02 Sep 16, 1995 -- Stick total disk capacity in partition table as well.
+ * Make VERBOSE_IDE_CD_ERRORS dump failed command again.
+ * Dump out more information for ILLEGAL REQUEST errs.
+ * Fix handling of errors occuring before the
+ * packet command is transferred.
+ * Fix transfers with odd bytelengths.
*
- * NOTE: I've tried to implement support for multisession CDs and
- * direct audio reads in this version, but i haven't been able to fully
- * test them due to a lack of the proper hardware. I'd appreciate hearing
- * if the multisession stuff works; i'd also be interested in hearing
+ * NOTE: I've tried to implement support for direct audio reads
+ * in this version, but i haven't been able to fully test it
+ * due to a lack of the proper hardware. I'd be interested in hearing
* if you get anything other than a `Parameter not supported'
* (asc=0x26, ascq=1) error when trying to do a direct audio read.
*
@@ -185,15 +190,18 @@
* Routines to read and write data from/to the drive, using
* the routines input_ide_data() and output_ide_data() from ide.c.
*
- * All transfer lengths should be multiples of 16-bit shorts.
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd bytecount is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
*/
static inline
void cdrom_in_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
{
+ ++bytecount;
ide_input_data (drive, buffer, bytecount / 4);
- if ((bytecount & 0x03 >= 2))
+ if ((bytecount & 0x03) >= 2)
{
insw (IDE_DATA_REG, buffer + (bytecount & ~0x03), 1);
}
@@ -203,8 +211,9 @@
static inline
void cdrom_out_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
{
+ ++bytecount;
ide_output_data (drive, buffer, bytecount / 4);
- if ((bytecount & 0x03 >= 2))
+ if ((bytecount & 0x03) >= 2)
{
outsw (IDE_DATA_REG, buffer + (bytecount & ~0x03), 1);
}
@@ -380,7 +389,7 @@
printk ("ATAPI device %s:\n", drive->name);
- printk (" Error code: %x\n", reqbuf->error_code);
+ printk (" Error code: 0x%02x\n", reqbuf->error_code);
if (reqbuf->sense_key >= 0 &&
reqbuf->sense_key < ARY_LEN (sense_key_texts))
@@ -388,10 +397,10 @@
else
s = "(bad sense key)";
- printk (" Sense key: %x - %s\n", reqbuf->sense_key, s);
+ printk (" Sense key: 0x%02x - %s\n", reqbuf->sense_key, s);
if (reqbuf->asc == 0x40) {
- sprintf (buf, "Diagnostic failure on component %x", reqbuf->ascq);
+ sprintf (buf, "Diagnostic failure on component 0x%02x", reqbuf->ascq);
s = buf;
}
@@ -425,7 +434,7 @@
s = "(reserved error code)";
}
- printk (" Additional sense data: %x, %x - %s\n",
+ printk (" Additional sense data: 0x%02x, 0x%02x - %s\n",
reqbuf->asc, reqbuf->ascq, s);
if (failed_command != NULL) {
@@ -434,6 +443,24 @@
printk ("%02x ", failed_command->c[i]);
printk ("\n");
}
+
+ if (reqbuf->sense_key == ILLEGAL_REQUEST &&
+ (reqbuf->sense_key_specific[0] & 0x80) != 0)
+ {
+ printk (" Error in %s byte %d",
+ (reqbuf->sense_key_specific[0] & 0x40) != 0
+ ? "command packet"
+ : "command data",
+ (reqbuf->sense_key_specific[1] << 8) +
+ reqbuf->sense_key_specific[2]);
+
+ if ((reqbuf->sense_key_specific[0] & 0x40) != 0)
+ {
+ printk (" bit %d", reqbuf->sense_key_specific[0] & 0x07);
+ }
+
+ printk ("\n");
+ }
}
#else
@@ -446,7 +473,7 @@
reqbuf->asc == 0x3a)))
return;
- printk ("%s: code: %x key: %x asc: %x ascq: %x\n",
+ printk ("%s: code: 0x%02x key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
drive->name,
reqbuf->error_code, reqbuf->sense_key, reqbuf->asc, reqbuf->ascq);
#endif
@@ -470,7 +497,8 @@
static void cdrom_queue_request_sense (ide_drive_t *drive,
struct semaphore *sem,
- struct atapi_request_sense *reqbuf)
+ struct atapi_request_sense *reqbuf,
+ struct packet_command *failed_command)
{
struct request *rq;
struct packet_command *pc;
@@ -516,12 +544,11 @@
pc->c[4] = len;
pc->buffer = (char *)reqbuf;
pc->buflen = len;
- pc->sense_data = reqbuf; /* The only reason to set this here is so
- that cdrom_end_request can find the correct
- buffer for dumps to the syslog. */
+ pc->sense_data = (struct atapi_request_sense *)failed_command;
rq = &HWIF(drive)->request_sense_request;
- rq->dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS);
+ rq->rq_status = RQ_ACTIVE;
+ rq->rq_dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS);
rq->cmd = REQUEST_SENSE_COMMAND;
rq->errors = 0;
rq->sector = 0;
@@ -560,7 +587,9 @@
if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate)
{
struct packet_command *pc = (struct packet_command *)rq->buffer;
- cdrom_analyze_sense_data (drive, pc->sense_data, NULL);
+ cdrom_analyze_sense_data (drive,
+ (struct atapi_request_sense *)(pc->buffer - pc->c[4]),
+ (struct packet_command *)pc->sense_data);
}
ide_end_request (uptodate, HWGROUP(drive));
@@ -666,7 +695,7 @@
cdrom_end_request (1, drive);
if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense (drive, sem, pc->sense_data);
+ cdrom_queue_request_sense (drive, sem, pc->sense_data, pc);
}
else
@@ -719,7 +748,7 @@
/* If we got a CHECK_CONDITION status, queue a request sense
command. */
if ((stat & ERR_STAT) != 0)
- cdrom_queue_request_sense (drive, NULL, NULL);
+ cdrom_queue_request_sense (drive, NULL, NULL, NULL);
}
}
@@ -768,9 +797,12 @@
/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
The device registers must have already been prepared
- by cdrom_start_packet_command. */
+ by cdrom_start_packet_command.
+ HANDLER is the interrupt handler to call when the command completes
+ or there's data ready. */
static int cdrom_transfer_packet_command (ide_drive_t *drive,
- char *cmd_buf, int cmd_len)
+ char *cmd_buf, int cmd_len,
+ ide_handler_t *handler)
{
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt)
{
@@ -787,6 +819,9 @@
if (ide_wait_stat (drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1;
}
+ /* Arm the interrupt handler. */
+ ide_set_handler (drive, handler);
+
/* Send the command to the device. */
cdrom_out_bytes (drive, cmd_buf, cmd_len);
@@ -1140,11 +1175,9 @@
pc.c[5] = conv.b.b0;
}
- /* Set up to receive the data-ready interrupt from the drive. */
- ide_set_handler (drive, &cdrom_read_intr);
-
/* Send the command to the drive and return. */
- (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c));
+ (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c),
+ &cdrom_read_intr);
}
@@ -1304,11 +1337,8 @@
struct request *rq = HWGROUP(drive)->rq;
struct packet_command *pc = (struct packet_command *)rq->buffer;
- /* Set up a handler for the data-ready interrupt. */
- ide_set_handler (drive, &cdrom_pc_intr);
-
/* Send the command to the drive and return. */
- cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c));
+ cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c), &cdrom_pc_intr);
}
@@ -1347,7 +1377,8 @@
int major = HWIF(drive)->major;
struct semaphore sem = MUTEX_LOCKED;
- req->dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS);
+ req->rq_dev = MKDEV (major, (drive->select.b.unit) << PARTN_BITS);
+ req->rq_status = RQ_ACTIVE;
req->sem = &sem;
req->errors = 0;
req->next = NULL;
@@ -1782,6 +1813,7 @@
HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS]
= toc->capacity * SECTORS_PER_FRAME;
+ drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
/* Remember that we've read this stuff. */
CDROM_STATE_FLAGS (drive)->toc_valid = 1;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this