#define IDECD_VERSION "4.61"
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
* we cannot reliably check if drive can auto-close
*/
if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
- break;
- log = 1;
+ log = 0;
break;
case UNIT_ATTENTION:
/*
struct request *failed_command,
struct request_sense *sense)
{
- unsigned long sector;
- unsigned long bio_sectors;
- unsigned long valid;
- struct cdrom_info *info = drive->driver_data;
-
if (!cdrom_log_sense(drive, failed_command, sense))
return;
if (sense->sense_key == 0x05 && sense->asc == 0x24)
return;
- if (sense->error_code == 0x70) { /* Current Error */
- switch(sense->sense_key) {
- case MEDIUM_ERROR:
- case VOLUME_OVERFLOW:
- case ILLEGAL_REQUEST:
- if (!sense->valid)
- break;
- if (failed_command == NULL ||
- !blk_fs_request(failed_command))
- break;
- sector = (sense->information[0] << 24) |
- (sense->information[1] << 16) |
- (sense->information[2] << 8) |
- (sense->information[3]);
-
- bio_sectors = bio_sectors(failed_command->bio);
- if (bio_sectors < 4)
- bio_sectors = 4;
- if (drive->queue->hardsect_size == 2048)
- sector <<= 2; /* Device sector size is 2K */
- sector &= ~(bio_sectors -1);
- valid = (sector - failed_command->sector) << 9;
-
- if (valid < 0)
- valid = 0;
- if (sector < get_capacity(info->disk) &&
- drive->probed_capacity - sector < 4 * 75) {
- set_capacity(info->disk, sector);
- }
- }
- }
#if VERBOSE_IDE_CD_ERRORS
{
int i;
sense = failed->sense;
failed->sense_len = rq->sense_len;
}
- cdrom_analyze_sense_data(drive, failed, sense);
+
/*
* now end failed request
*/
- if (blk_fs_request(failed)) {
- if (ide_end_dequeued_request(drive, failed, 0,
- failed->hard_nr_sectors))
- BUG();
- } else {
- spin_lock_irqsave(&ide_lock, flags);
- end_that_request_chunk(failed, 0,
- failed->data_len);
- end_that_request_last(failed, 0);
- spin_unlock_irqrestore(&ide_lock, flags);
- }
- } else
- cdrom_analyze_sense_data(drive, NULL, sense);
+ spin_lock_irqsave(&ide_lock, flags);
+ end_that_request_chunk(failed, 0, failed->data_len);
+ end_that_request_last(failed, 0);
+ spin_unlock_irqrestore(&ide_lock, flags);
+ }
+
+ cdrom_analyze_sense_data(drive, failed, sense);
}
if (!rq->current_nr_sectors && blk_fs_request(rq))
ide_end_request(drive, uptodate, nsectors);
}
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
-{
- if (stat & 0x80)
- return;
- ide_dump_status(drive, msg, stat);
-}
-
/* Returns 0 if the request should be continued.
Returns 1 if the request was ended. */
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal
request or data protect error.*/
- ide_dump_status_no_sense (drive, "command error", stat);
+ ide_dump_status (drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/* No point in re-trying a zillion times on a bad
* sector... If we got here the error is not correctable */
- ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
+ ide_dump_status (drive, "media error (bad sector)", stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* Disk appears blank ?? */
- ide_dump_status_no_sense (drive, "media error (blank)", stat);
+ ide_dump_status (drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler
do_end_request = 1;
}
- /* End a request through request sense analysis when we have
- sense data. We need this in order to perform end of media
- processing */
-
- if (do_end_request) {
- if (stat & ERR_STAT) {
- unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
- blkdev_dequeue_request(rq);
- HWGROUP(drive)->rq = NULL;
- spin_unlock_irqrestore(&ide_lock, flags);
-
- cdrom_queue_request_sense(drive, rq->sense, rq);
- } else
- cdrom_end_request(drive, 0);
- } else {
- /* If we got a CHECK_CONDITION status,
- queue a request sense command. */
- if (stat & ERR_STAT)
- cdrom_queue_request_sense(drive, NULL, NULL);
- }
+ if (do_end_request)
+ cdrom_end_request(drive, 0);
+
+ /* If we got a CHECK_CONDITION status,
+ queue a request sense command. */
+ if ((stat & ERR_STAT) != 0)
+ cdrom_queue_request_sense(drive, NULL, NULL);
} else {
blk_dump_rq_flags(rq, "ide-cd: bad rq");
cdrom_end_request(drive, 0);
} else {
confused:
printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
- "appears confused (ireason = 0x%02x). "
- "Trying to recover by ending request.\n",
+ "appears confused (ireason = 0x%02x)\n",
drive->name, ireason);
rq->flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
- return ide_stopped;
}
/* Now we wait for another interrupt. */
}
-static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
+static
+int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
{
struct request_sense sense;
int retries = 10;
}
}
- BUG_ON(HWGROUP(drive)->handler != NULL);
+ if (HWGROUP(drive)->handler != NULL)
+ BUG();
ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
return ide_started;
toc->capacity = 0x1fffff;
set_capacity(info->disk, toc->capacity * sectors_per_frame);
- /* Save a private copy of te TOC capacity for error handling */
- drive->probed_capacity = toc->capacity * sectors_per_frame;
-
blk_queue_hardsect_size(drive->queue,
sectors_per_frame << SECTOR_BITS);
if (!stat && (last_written > toc->capacity)) {
toc->capacity = last_written;
set_capacity(info->disk, toc->capacity * sectors_per_frame);
- drive->probed_capacity = toc->capacity * sectors_per_frame;
}
/* Remember that we've read this stuff. */
* any other way to detect this...
*/
if (sense.sense_key == NOT_READY) {
- if (sense.asc == 0x3a && sense.ascq == 1)
- return CDS_NO_DISC;
- else
- return CDS_TRAY_OPEN;
+ if (sense.asc == 0x3a) {
+ if (sense.ascq == 1)
+ return CDS_NO_DISC;
+ else if (sense.ascq == 0 || sense.ascq == 2)
+ return CDS_TRAY_OPEN;
+ }
}
+
return CDS_DRIVE_NOT_READY;
}
drive->driver_data = info;
g->minors = 1;
+ snprintf(g->devfs_name, sizeof(g->devfs_name),
+ "%s/cd", drive->devfs_name);
g->driverfs_dev = &drive->gendev;
g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
if (ide_cdrom_setup(drive)) {