/*
* ide_error() takes action based on the error returned by the drive.
*/
-static ide_startstop_t ide_cdrom_error (ide_drive_t *drive, const char *msg, byte stat)
+ide_startstop_t ide_cdrom_error (ide_drive_t *drive, const char *msg, byte stat)
{
struct request *rq;
byte err;
return ide_stopped;
}
-static ide_startstop_t ide_cdrom_abort (ide_drive_t *drive, const char *msg)
+ide_startstop_t ide_cdrom_abort (ide_drive_t *drive, const char *msg)
{
struct request *rq;
{
ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data;
- ide_hwif_t *hwif = drive->hwif;
/* Wait for the controller to be idle. */
if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
return startstop;
- if (info->dma)
- info->dma = !hwif->ide_dma_setup(drive);
+ if (info->dma) {
+ if (info->cmd == READ) {
+ info->dma = !HWIF(drive)->ide_dma_read(drive);
+ } else if (info->cmd == WRITE) {
+ info->dma = !HWIF(drive)->ide_dma_write(drive);
+ } else {
+ printk(KERN_WARNING "ide-cd: DMA set, but not allowed\n");
+ }
+ }
/* Set up the controller registers. */
/* FIXME: for Virtual DMA we must check harder */
ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
return ide_started;
} else {
- unsigned long flags;
-
/* packet command */
+ unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
- hwif->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
+ HWIF(drive)->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags);
-
return (*handler) (drive);
}
}
struct request *rq,
ide_handler_t *handler)
{
- ide_hwif_t *hwif = drive->hwif;
int cmd_len;
struct cdrom_info *info = drive->driver_data;
ide_startstop_t startstop;
/* Start the DMA if need be */
if (info->dma)
- hwif->ide_dma_start(drive);
+ (void) HWIF(drive)->ide_dma_begin(drive);
return ide_started;
}
}
-static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
+/* Sleep for TIME jiffies.
+ Not to be called from an interrupt handler. */
+static
+void cdrom_sleep (int time)
+{
+ int sleep = time;
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+ sleep = schedule_timeout(sleep);
+ } while (sleep);
+}
+
+static
+int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
{
struct request_sense sense;
int retries = 10;
/* The drive is in the process of loading
a disk. Retry, but wait a little to give
the drive time to complete the load. */
- msleep(2000);
+ cdrom_sleep(2 * HZ);
} else {
/* Otherwise, don't retry. */
retries = 0;
info->dma = drive->using_dma ? 1 : 0;
info->cmd = WRITE;
- info->devinfo.media_written = 1;
-
/* Start sending the write request to the drive. */
return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
}
}
CDROM_CONFIG_FLAGS(drive)->seeking = 0;
}
- if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
+ if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
action = cdrom_start_seek(drive, block);
} else {
if (rq_data_dir(rq) == READ)
/* Read the multisession information. */
if (toc->hdr.first_track != CDROM_LEADOUT) {
/* Read the multisession information. */
- stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
+ stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
if (stat) return stat;
-
- toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
} else {
+ ms_tmp.ent.addr.msf.minute = 0;
+ ms_tmp.ent.addr.msf.second = 2;
+ ms_tmp.ent.addr.msf.frame = 0;
ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
- toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
}
#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
- /* Re-read multisession information using MSF format */
- stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
- sizeof(ms_tmp), sense);
- if (stat)
- return stat;
-
+ if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd)
msf_from_bcd (&ms_tmp.ent.addr.msf);
- toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
- ms_tmp.ent.addr.msf.second,
- ms_tmp.ent.addr.msf.frame);
- }
#endif /* not STANDARD_ATAPI */
+ toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.minute,
+ ms_tmp.ent.addr.msf.second,
+ ms_tmp.ent.addr.msf.frame);
+
toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
/* Now try to get the total cdrom capacity. */
* 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 == 0 || sense.ascq == 1)
+ return CDS_NO_DISC;
+ else if (sense.ascq == 2)
+ return CDS_TRAY_OPEN;
+ }
}
return CDS_DRIVE_NOT_READY;
CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
if (cap.cd_r_write)
CDROM_CONFIG_FLAGS(drive)->cd_r = 1;
- if (cap.cd_rw_write) {
+ if (cap.cd_rw_write)
CDROM_CONFIG_FLAGS(drive)->cd_rw = 1;
- CDROM_CONFIG_FLAGS(drive)->ram = 1;
- }
if (cap.test_write)
CDROM_CONFIG_FLAGS(drive)->test_write = 1;
if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
+#ifdef CONFIG_BLK_DEV_IDEDMA
if (drive->using_dma)
- ide_dma_verbose(drive);
-
+ (void) HWIF(drive)->ide_dma_verbose(drive);
+#endif /* CONFIG_BLK_DEV_IDEDMA */
printk("\n");
return nslots;
};
/* options */
-static char *ignore = NULL;
+char *ignore = NULL;
-module_param(ignore, charp, 0400);
+MODULE_PARM(ignore, "s");
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
static int ide_cdrom_attach (ide_drive_t *drive)