diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 337 |
1 files changed, 221 insertions, 116 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 49a8c589e34..3308b1cd3a3 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -23,6 +23,9 @@ * Documentation/ide/ChangeLog.ide-cd.1994-2004 */ +#define DRV_NAME "ide-cd" +#define PFX DRV_NAME ": " + #define IDECD_VERSION "5.00" #include <linux/module.h> @@ -50,12 +53,15 @@ #include "ide-cd.h" -static DEFINE_MUTEX(idecd_ref_mutex); +#define IDECD_DEBUG_LOG 1 -#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) +#if IDECD_DEBUG_LOG +#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args) +#else +#define ide_debug_log(lvl, fmt, args...) do {} while (0) +#endif -#define ide_cd_g(disk) \ - container_of((disk)->private_data, struct cdrom_info, driver) +static DEFINE_MUTEX(idecd_ref_mutex); static void ide_cd_release(struct kref *); @@ -64,7 +70,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); - cd = ide_cd_g(disk); + cd = ide_drv_g(disk, cdrom_info); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; @@ -102,6 +108,9 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, { int log = 0; + ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__, + sense->sense_key); + if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -150,6 +159,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, unsigned long bio_sectors; struct cdrom_info *info = drive->driver_data; + ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, " + "sense_key: 0x%x\n", __func__, sense->error_code, + sense->sense_key); + + if (failed_command) + ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n", + __func__, failed_command->cmd[0]); + if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -200,6 +217,8 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct cdrom_info *info = drive->driver_data; struct request *rq = &info->request_sense_request; + ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); + if (sense == NULL) sense = &info->sense_data; @@ -219,6 +238,10 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, /* NOTE! Save the failed command in "rq->buffer" */ rq->buffer = (void *) failed_command; + if (failed_command) + ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", + failed_command->cmd[0]); + ide_do_drive_cmd(drive, rq); } @@ -227,6 +250,10 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *rq = HWGROUP(drive)->rq; int nsectors = rq->hard_cur_sectors; + ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, " + "nsectors: %d\n", __func__, rq->cmd[0], uptodate, + nsectors); + if (blk_sense_request(rq) && uptodate) { /* * For REQ_TYPE_SENSE, "rq->buffer" points to the original @@ -269,6 +296,9 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) if (!nsectors) nsectors = 1; + ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n", + __func__, uptodate, nsectors); + ide_end_request(drive, uptodate, nsectors); } @@ -304,11 +334,15 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) sense_key = err >> 4; if (rq == NULL) { - printk(KERN_ERR "%s: missing rq in %s\n", + printk(KERN_ERR PFX "%s: missing rq in %s\n", drive->name, __func__); return 1; } + ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " + "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat, + good_stat, rq->cmd_type, err); + if (blk_sense_request(rq)) { /* * We got an error trying to get sense info from the drive @@ -374,7 +408,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) cdrom_saw_media_change(drive); /* fail the request */ - printk(KERN_ERR "%s: tray open\n", drive->name); + printk(KERN_ERR PFX "%s: tray open\n", + drive->name); do_end_request = 1; } else { struct cdrom_info *info = drive->driver_data; @@ -436,7 +471,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) ide_dump_status_no_sense(drive, "media error (blank)", stat); do_end_request = 1; - } else if ((err & ~ABRT_ERR) != 0) { + } else if ((err & ~ATA_ABORTED) != 0) { /* go to the default handler for other errors */ ide_error(drive, "cdrom_decode_status", stat); return 1; @@ -457,10 +492,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) * If we got a CHECK_CONDITION status, queue * a request sense command. */ - if (stat & ERR_STAT) + if (stat & ATA_ERR) cdrom_queue_request_sense(drive, NULL, NULL); } else { - blk_dump_rq_flags(rq, "ide-cd: bad rq"); + blk_dump_rq_flags(rq, PFX "bad rq"); cdrom_end_request(drive, 0); } @@ -468,7 +503,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) return 1; end_request: - if (stat & ERR_STAT) { + if (stat & ATA_ERR) { unsigned long flags; spin_lock_irqsave(&ide_lock, flags); @@ -488,6 +523,9 @@ static int cdrom_timer_expiry(ide_drive_t *drive) struct request *rq = HWGROUP(drive)->rq; unsigned long wait = 0; + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd[0]: 0x%x\n", __func__, + rq->cmd[0]); + /* * Some commands are *slow* and normally take a long time to complete. * Usually we can use the ATAPI "disconnect" to bypass this, but not all @@ -504,7 +542,7 @@ static int cdrom_timer_expiry(ide_drive_t *drive) break; default: if (!(rq->cmd_flags & REQ_QUIET)) - printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", + printk(KERN_INFO PFX "cmd 0x%x timed out\n", rq->cmd[0]); wait = 0; break; @@ -524,24 +562,25 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, int xferlen, ide_handler_t *handler) { - struct cdrom_info *info = drive->driver_data; ide_hwif_t *hwif = drive->hwif; + ide_debug_log(IDE_DBG_PC, "Call %s, xferlen: %d\n", __func__, xferlen); + /* FIXME: for Virtual DMA we must check harder */ - if (info->dma) - info->dma = !hwif->dma_ops->dma_setup(drive); + if (drive->dma) + drive->dma = !hwif->dma_ops->dma_setup(drive); /* set up the controller registers */ ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, - xferlen, info->dma); + xferlen, drive->dma); if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* waiting for CDB interrupt, not DMA yet. */ - if (info->dma) + if (drive->dma) drive->waiting_for_dma = 0; /* packet command */ - ide_execute_command(drive, WIN_PACKETCMD, handler, + ide_execute_command(drive, ATA_CMD_PACKET, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); return ide_started; } else { @@ -564,9 +603,10 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, { ide_hwif_t *hwif = drive->hwif; int cmd_len; - struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; + ide_debug_log(IDE_DBG_PC, "Call %s\n", __func__); + if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) { /* * Here we should have been called after receiving an interrupt @@ -574,16 +614,16 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, */ /* check for errors */ - if (cdrom_decode_status(drive, DRQ_STAT, NULL)) + if (cdrom_decode_status(drive, ATA_DRQ, NULL)) return ide_stopped; /* ok, next interrupt will be DMA interrupt */ - if (info->dma) + if (drive->dma) drive->waiting_for_dma = 1; } else { /* otherwise, we must wait for DRQ to get set */ - if (ide_wait_stat(&startstop, drive, DRQ_STAT, - BUSY_STAT, WAIT_READY)) + if (ide_wait_stat(&startstop, drive, ATA_DRQ, + ATA_BUSY, WAIT_READY)) return startstop; } @@ -599,7 +639,7 @@ static ide_startstop_t cdrom_transfer_packet_command(ide_drive_t *drive, hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len); /* start the DMA if need be */ - if (info->dma) + if (drive->dma) hwif->dma_ops->dma_start(drive); return ide_started; @@ -615,6 +655,9 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, { ide_hwif_t *hwif = drive->hwif; + ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n", + __func__, ireason, rw); + /* * ireason == 0: the drive wants to receive data from us * ireason == 2: the drive is expecting to transfer data to us @@ -624,7 +667,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, else if (ireason == (rw << 1)) { /* whoops... */ - printk(KERN_ERR "%s: %s: wrong transfer direction!\n", + printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", drive->name, __func__); ide_pad_transfer(drive, rw, len); @@ -637,7 +680,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, return 0; } else { /* drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", + printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", drive->name, __func__, ireason); } @@ -654,17 +697,19 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, */ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) { + ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len); + if ((len % SECTOR_SIZE) == 0) return 0; - printk(KERN_ERR "%s: %s: Bad transfer size %d\n", - drive->name, __func__, len); + printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name, + __func__, len); if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES) - printk(KERN_ERR " This drive is not supported by " - "this version of the driver\n"); + printk(KERN_ERR PFX "This drive is not supported by this " + "version of the driver\n"); else { - printk(KERN_ERR " Trying to limit transfer sizes\n"); + printk(KERN_ERR PFX "Trying to limit transfer sizes\n"); drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES; } @@ -676,6 +721,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, struct request *rq) { + ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__, + rq->cmd_flags); + if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; @@ -695,7 +743,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, /* sanity check... */ if (rq->current_nr_sectors != bio_cur_sectors(rq->bio)) { - printk(KERN_ERR "%s: %s: buffer botch (%u)\n", + printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n", drive->name, __func__, rq->current_nr_sectors); cdrom_end_request(drive, 0); @@ -704,11 +752,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, rq->current_nr_sectors += nskip; } } -#if 0 - else - /* the immediate bit */ - rq->cmd[1] = 1 << 3; -#endif + /* set up the command */ rq->timeout = ATAPI_WAIT_PC; @@ -739,6 +783,8 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) int stat; static int retry = 10; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (cdrom_decode_status(drive, 0, &stat)) return ide_stopped; @@ -746,7 +792,7 @@ static ide_startstop_t cdrom_seek_intr(ide_drive_t *drive) if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (--retry == 0) - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; } return ide_stopped; } @@ -755,6 +801,8 @@ static void ide_cd_prepare_seek_request(ide_drive_t *drive, struct request *rq) { sector_t frame = rq->sector; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS); memset(rq->cmd, 0, BLK_MAX_CDB); @@ -775,8 +823,11 @@ static ide_startstop_t cdrom_start_seek_continuation(ide_drive_t *drive) * Fix up a possibly partially-processed request so that we can start it over * entirely, or even put it back on the request queue. */ -static void restore_request(struct request *rq) +static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) { + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (rq->buffer != bio_data(rq->bio)) { sector_t n = (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE; @@ -795,8 +846,11 @@ static void restore_request(struct request *rq) /* * All other packet commands. */ -static void ide_cd_request_sense_fixup(struct request *rq) +static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq) { + + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. @@ -822,6 +876,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, if (!sense) sense = &local_sense; + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, " + "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, + timeout, cmd_flags); + /* start of retry loop */ do { struct request *rq; @@ -895,7 +953,6 @@ static int cdrom_newpc_intr_dummy_cb(struct request *rq) static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; - struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc; ide_expiry_t *expiry = NULL; @@ -905,13 +962,16 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) u16 len; u8 ireason; + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n", + __func__, rq->cmd[0], write); + /* check for errors */ - dma = info->dma; + dma = drive->dma; if (dma) { - info->dma = 0; + drive->dma = 0; dma_error = hwif->dma_ops->dma_end(drive); if (dma_error) { - printk(KERN_ERR "%s: DMA %s error\n", drive->name, + printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, write ? "write" : "read"); ide_dma_off(drive); } @@ -937,8 +997,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (thislen > len) thislen = len; + ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n", + __func__, stat, thislen); + /* If DRQ is clear, the command has completed. */ - if ((stat & DRQ_STAT) == 0) { + if ((stat & ATA_DRQ) == 0) { if (blk_fs_request(rq)) { /* * If we're not done reading/writing, complain. @@ -946,7 +1009,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ uptodate = 1; if (rq->current_nr_sectors > 0) { - printk(KERN_ERR "%s: %s: data underrun " + printk(KERN_ERR PFX "%s: %s: data underrun " "(%d blocks)\n", drive->name, __func__, rq->current_nr_sectors); @@ -957,7 +1020,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) cdrom_end_request(drive, uptodate); return ide_stopped; } else if (!blk_pc_request(rq)) { - ide_cd_request_sense_fixup(rq); + ide_cd_request_sense_fixup(drive, rq); /* complain if we still have data left to transfer */ uptodate = rq->data_len ? 0 : 1; } @@ -1000,6 +1063,9 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) xferfunc = hwif->tp_ops->input_data; } + ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, " + "ireason: 0x%x\n", __func__, rq->cmd_type, ireason); + /* transfer data */ while (thislen > 0) { u8 *ptr = blk_fs_request(rq) ? NULL : rq->data; @@ -1024,7 +1090,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) */ ide_pad_transfer(drive, 0, thislen); else { - printk(KERN_ERR "%s: confused, missing data\n", + printk(KERN_ERR PFX "%s: confused, missing data\n", drive->name); blk_dump_rq_flags(rq, rq_data_dir(rq) ? "cdrom_newpc_intr, write" @@ -1111,9 +1177,12 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; + ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n", + __func__, write, sectors_per_frame); + if (write) { /* disk has become write protected */ - if (cd->disk->policy) { + if (get_disk_ro(cd->disk)) { cdrom_end_request(drive, 0); return ide_stopped; } @@ -1122,7 +1191,7 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) * We may be retrying this request after an error. Fix up any * weirdness which might be present in the request packet. */ - restore_request(rq); + ide_cd_restore_request(drive, rq); } /* use DMA, if possible / writes *must* be hardware frame aligned */ @@ -1132,9 +1201,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) cdrom_end_request(drive, 0); return ide_stopped; } - cd->dma = 0; + drive->dma = 0; } else - cd->dma = drive->using_dma; + drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); if (write) cd->devinfo.media_written = 1; @@ -1151,28 +1220,29 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive) static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - struct cdrom_info *info = drive->driver_data; + + ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__, + rq->cmd_type); if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; else rq->cmd_flags &= ~REQ_FAILED; - info->dma = 0; + drive->dma = 0; /* sg request */ if (rq->bio || ((rq->cmd_type == REQ_TYPE_ATA_PC) && rq->data_len)) { struct request_queue *q = drive->queue; unsigned int alignment; - unsigned long addr; - unsigned long stack_mask = ~(THREAD_SIZE - 1); + char *buf; if (rq->bio) - addr = (unsigned long)bio_data(rq->bio); + buf = bio_data(rq->bio); else - addr = (unsigned long)rq->data; + buf = rq->data; - info->dma = drive->using_dma; + drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA); /* * check if dma is safe @@ -1181,12 +1251,9 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) * separate masks. */ alignment = queue_dma_alignment(q) | q->dma_pad_mask; - if (addr & alignment || rq->data_len & alignment) - info->dma = 0; - - if (!((addr & stack_mask) ^ - ((unsigned long)current->stack & stack_mask))) - info->dma = 0; + if ((unsigned long)buf & alignment || rq->data_len & alignment + || object_is_on_stack(buf)) + drive->dma = 0; } } @@ -1200,19 +1267,22 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, ide_handler_t *fn; int xferlen; + ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n", + __func__, rq->cmd_type, (unsigned long long)block); + if (blk_fs_request(rq)) { if (drive->atapi_flags & IDE_AFLAG_SEEKING) { ide_hwif_t *hwif = drive->hwif; unsigned long elapsed = jiffies - info->start_seek; int stat = hwif->tp_ops->read_status(hwif); - if ((stat & SEEK_STAT) != SEEK_STAT) { + if ((stat & ATA_DSC) != ATA_DSC) { if (elapsed < IDECD_SEEK_TIMEOUT) { ide_stall_queue(drive, IDECD_SEEK_TIMER); return ide_stopped; } - printk(KERN_ERR "%s: DSC timeout\n", + printk(KERN_ERR PFX "%s: DSC timeout\n", drive->name); } drive->atapi_flags &= ~IDE_AFLAG_SEEKING; @@ -1220,11 +1290,11 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, if (rq_data_dir(rq) == READ && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && - drive->dsc_overlap) { + (drive->dev_flags & IDE_DFLAG_DSC_OVERLAP)) { xferlen = 0; fn = cdrom_start_seek_continuation; - info->dma = 0; + drive->dma = 0; info->start_seek = jiffies; ide_cd_prepare_seek_request(drive, rq); @@ -1253,7 +1323,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cdrom_end_request(drive, 1); return ide_stopped; } else { - blk_dump_rq_flags(rq, "ide-cd bad flags"); + blk_dump_rq_flags(rq, DRV_NAME " bad flags"); cdrom_end_request(drive, 0); return ide_stopped; } @@ -1283,6 +1353,8 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_device_info *cdi = &info->devinfo; unsigned char cmd[BLK_MAX_CDB]; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1309,6 +1381,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, unsigned len = sizeof(capbuf); u32 blocklen; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1328,10 +1402,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, case 4096: break; default: - printk(KERN_ERR "%s: weird block size %u\n", - drive->name, blocklen); - printk(KERN_ERR "%s: default to 2kb block size\n", - drive->name); + printk(KERN_ERR PFX "%s: weird block size %u\n", + drive->name, blocklen); + printk(KERN_ERR PFX "%s: default to 2kb block size\n", + drive->name); blocklen = 2048; break; } @@ -1347,6 +1421,8 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { unsigned char cmd[BLK_MAX_CDB]; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_TOC_PMA_ATIP; @@ -1375,11 +1451,13 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) long last_written; unsigned long sectors_per_frame = SECTORS_PER_FRAME; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (toc == NULL) { /* try to allocate space */ toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL); if (toc == NULL) { - printk(KERN_ERR "%s: No cdrom TOC buffer!\n", + printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n", drive->name); return -ENOMEM; } @@ -1535,6 +1613,8 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1553,6 +1633,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]); @@ -1593,6 +1675,8 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *devinfo = &info->devinfo; + ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots); + devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; devinfo->capacity = nslots; @@ -1614,13 +1698,17 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) mechtype_t mechtype; int nslots = 1; + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, " + "drive->atapi_flags: 0x%lx\n", __func__, drive->media, + drive->atapi_flags); + cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | CDC_MO_DRIVE | CDC_RAM); if (drive->media == ide_optical) { cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); - printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", + printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n", drive->name); return nslots; } @@ -1661,7 +1749,9 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) cdi->mask &= ~CDC_PLAY_AUDIO; mechtype = buf[8 + 6] >> 5; - if (mechtype == mechtype_caddy || mechtype == mechtype_popup) + if (mechtype == mechtype_caddy || + mechtype == mechtype_popup || + (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE)) cdi->mask |= CDC_CLOSE_TRAY; if (cdi->sanyo_slot > 0) { @@ -1676,7 +1766,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) ide_cdrom_update_speed(drive, buf); - printk(KERN_INFO "%s: ATAPI", drive->name); + printk(KERN_INFO PFX "%s: ATAPI", drive->name); /* don't print speed if the drive reported 0 */ if (cd->max_speed) @@ -1699,7 +1789,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive) else printk(KERN_CONT " drive"); - printk(KERN_CONT ", %dkB Cache\n", be16_to_cpup((__be16 *)&buf[8 + 12])); + printk(KERN_CONT ", %dkB Cache\n", + be16_to_cpup((__be16 *)&buf[8 + 12])); return nslots; } @@ -1811,13 +1902,12 @@ static ide_proc_entry_t idecd_proc[] = { { NULL, 0, NULL, NULL } }; -static void ide_cdrom_add_settings(ide_drive_t *drive) -{ - ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, - &drive->dsc_overlap, NULL); -} -#else -static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; } +ide_devset_rw_flag(dsc_overlap, IDE_DFLAG_DSC_OVERLAP); + +static const struct ide_proc_devset idecd_settings[] = { + IDE_PROC_DEVSET(dsc_overlap, 0, 1), + { 0 }, +}; #endif static const struct cd_list_entry ide_cd_quirks_list[] = { @@ -1859,17 +1949,19 @@ static const struct cd_list_entry ide_cd_quirks_list[] = { { "MATSHITADVD-ROM SR-8176", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, { "MATSHITADVD-ROM SR-8174", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, { "Optiarc DVD RW AD-5200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, + { "Optiarc DVD RW AD-7200A", NULL, IDE_AFLAG_PLAY_AUDIO_OK }, + { "Optiarc DVD RW AD-7543A", NULL, IDE_AFLAG_NO_AUTOCLOSE }, { NULL, NULL, 0 } }; -static unsigned int ide_cd_flags(struct hd_driveid *id) +static unsigned int ide_cd_flags(u16 *id) { const struct cd_list_entry *cle = ide_cd_quirks_list; while (cle->id_model) { - if (strcmp(cle->id_model, id->model) == 0 && + if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 && (cle->id_firmware == NULL || - strstr(id->fw_rev, cle->id_firmware))) + strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware))) return cle->cd_flags; cle++; } @@ -1881,9 +1973,12 @@ static int ide_cdrom_setup(ide_drive_t *drive) { struct cdrom_info *cd = drive->driver_data; struct cdrom_device_info *cdi = &cd->devinfo; - struct hd_driveid *id = drive->id; + u16 *id = drive->id; + char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; + ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); + blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); blk_queue_update_dma_pad(drive->queue, 15); @@ -1891,20 +1986,15 @@ static int ide_cdrom_setup(ide_drive_t *drive) if (!drive->queue->unplug_delay) drive->queue->unplug_delay = 1; - drive->special.all = 0; - drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT | ide_cd_flags(id); - if ((id->config & 0x0060) == 0x20) - drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT; - if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) && - id->fw_rev[4] == '1' && id->fw_rev[6] <= '2') + fw_rev[4] == '1' && fw_rev[6] <= '2') drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD | IDE_AFLAG_TOCADDR_AS_BCD); else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) && - id->fw_rev[4] == '1' && id->fw_rev[6] <= '2') + fw_rev[4] == '1' && fw_rev[6] <= '2') drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD; else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD) /* 3 => use CD in slot 0 */ @@ -1915,15 +2005,19 @@ static int ide_cdrom_setup(ide_drive_t *drive) /* set correct block size */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); - drive->dsc_overlap = (drive->next != drive); + if (drive->next != drive) + drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP; + else + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; if (ide_cdrom_register(drive, nslots)) { - printk(KERN_ERR "%s: %s failed to register device with the" + printk(KERN_ERR PFX "%s: %s failed to register device with the" " cdrom driver.\n", drive->name, __func__); cd->devinfo.handle = NULL; return 1; } - ide_cdrom_add_settings(drive); + + ide_proc_register_driver(drive, cd->driver); return 0; } @@ -1931,6 +2025,8 @@ static void ide_cd_remove(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + ide_proc_unregister_driver(drive, info->driver); del_gendisk(info->disk); @@ -1940,15 +2036,17 @@ static void ide_cd_remove(ide_drive_t *drive) static void ide_cd_release(struct kref *kref) { - struct cdrom_info *info = to_ide_cd(kref); + struct cdrom_info *info = to_ide_drv(kref, cdrom_info); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; struct gendisk *g = info->disk; + ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + kfree(info->toc); if (devinfo->handle == drive) unregister_cdrom(devinfo); - drive->dsc_overlap = 0; + drive->dev_flags &= ~IDE_DFLAG_DSC_OVERLAP; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; @@ -1967,13 +2065,12 @@ static ide_driver_t ide_cdrom_driver = { .probe = ide_cd_probe, .remove = ide_cd_remove, .version = IDECD_VERSION, - .media = ide_cdrom, - .supports_dsc_overlap = 1, .do_request = ide_cd_do_request, .end_request = ide_end_request, .error = __ide_error, #ifdef CONFIG_IDE_PROC_FS .proc = idecd_proc, + .settings = idecd_settings, #endif }; @@ -1998,7 +2095,7 @@ static int idecd_open(struct inode *inode, struct file *file) static int idecd_release(struct inode *inode, struct file *file) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); cdrom_release(&info->devinfo, file); @@ -2050,7 +2147,7 @@ static int idecd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct block_device *bdev = inode->i_bdev; - struct cdrom_info *info = ide_cd_g(bdev->bd_disk); + struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); int err; switch (cmd) { @@ -2071,13 +2168,13 @@ static int idecd_ioctl(struct inode *inode, struct file *file, static int idecd_media_changed(struct gendisk *disk) { - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); return cdrom_media_changed(&info->devinfo); } static int idecd_revalidate_disk(struct gendisk *disk) { - struct cdrom_info *info = ide_cd_g(disk); + struct cdrom_info *info = ide_drv_g(disk, cdrom_info); struct request_sense sense; ide_cd_read_toc(info->drive, &sense); @@ -2096,8 +2193,11 @@ static struct block_device_operations idecd_ops = { /* module options */ static char *ignore; - module_param(ignore, charp, 0400); + +static unsigned long debug_mask; +module_param(debug_mask, ulong, 0644); + MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); static int ide_cd_probe(ide_drive_t *drive) @@ -2106,23 +2206,30 @@ static int ide_cd_probe(ide_drive_t *drive) struct gendisk *g; struct request_sense sense; + ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, " + "drive->media: 0x%x\n", __func__, drive->driver_req, + drive->media); + if (!strstr("ide-cdrom", drive->driver_req)) goto failed; - if (!drive->present) - goto failed; + if (drive->media != ide_cdrom && drive->media != ide_optical) goto failed; + /* skip drives that we were told to ignore */ if (ignore != NULL) { if (strstr(ignore, drive->name)) { - printk(KERN_INFO "ide-cd: ignoring drive %s\n", + printk(KERN_INFO PFX "ignoring drive %s\n", drive->name); goto failed; } } + + drive->debug_mask = debug_mask; + info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); if (info == NULL) { - printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", + printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n", drive->name); goto failed; } @@ -2133,8 +2240,6 @@ static int ide_cd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - ide_proc_register_driver(drive, &ide_cdrom_driver); - kref_init(&info->kref); info->drive = drive; @@ -2149,7 +2254,6 @@ static int ide_cd_probe(ide_drive_t *drive) g->driverfs_dev = &drive->gendev; g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { - ide_proc_unregister_driver(drive, &ide_cdrom_driver); ide_cd_release(&info->kref); goto failed; } @@ -2173,6 +2277,7 @@ static void __exit ide_cdrom_exit(void) static int __init ide_cdrom_init(void) { + printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n"); return driver_register(&ide_cdrom_driver.gen_driver); } |