diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 194 |
1 files changed, 110 insertions, 84 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 0bfeb0c79d6e..3f630e4080d4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -55,7 +55,7 @@ static DEFINE_MUTEX(idecd_ref_mutex); -static void ide_cd_release(struct kref *); +static void ide_cd_release(struct device *); static struct cdrom_info *ide_cd_get(struct gendisk *disk) { @@ -67,7 +67,7 @@ static struct cdrom_info *ide_cd_get(struct gendisk *disk) if (ide_device_get(cd->drive)) cd = NULL; else - kref_get(&cd->kref); + get_device(&cd->dev); } mutex_unlock(&idecd_ref_mutex); @@ -79,7 +79,7 @@ static void ide_cd_put(struct cdrom_info *cd) ide_drive_t *drive = cd->drive; mutex_lock(&idecd_ref_mutex); - kref_put(&cd->kref, ide_cd_release); + put_device(&cd->dev); ide_device_put(drive); mutex_unlock(&idecd_ref_mutex); } @@ -100,8 +100,7 @@ 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); + ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) return 0; @@ -151,13 +150,12 @@ 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); + ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", + 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]); + ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", + failed_command->cmd[0]); if (!cdrom_log_sense(drive, failed_command, sense)) return; @@ -194,6 +192,14 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, bio_sectors = max(bio_sectors(failed_command->bio), 4U); sector &= ~(bio_sectors - 1); + /* + * The SCSI specification allows for the value + * returned by READ CAPACITY to be up to 75 2K + * sectors past the last readable block. + * Therefore, if we hit a medium error within the + * last 75 2K sectors, we decrease the saved size + * value. + */ if (sector < get_capacity(info->disk) && drive->probed_capacity - sector < 4 * 75) set_capacity(info->disk, sector); @@ -207,9 +213,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, struct request *failed_command) { struct cdrom_info *info = drive->driver_data; - struct request *rq = &info->request_sense_request; + struct request *rq = &drive->request_sense_rq; - ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__); + ide_debug_log(IDE_DBG_SENSE, "enter"); if (sense == NULL) sense = &info->sense_data; @@ -231,10 +237,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, rq->buffer = (void *) failed_command; if (failed_command) - ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n", - failed_command->cmd[0]); + ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x", + failed_command->cmd[0]); - ide_do_drive_cmd(drive, rq); + drive->hwif->rq = NULL; + + elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); } static void cdrom_end_request(ide_drive_t *drive, int uptodate) @@ -242,9 +250,8 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) struct request *rq = drive->hwif->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); + ide_debug_log(IDE_DBG_FUNC, "cmd: 0x%x, uptodate: 0x%x, nsectors: %d", + rq->cmd[0], uptodate, nsectors); if (blk_sense_request(rq) && uptodate) { /* @@ -265,8 +272,8 @@ static void cdrom_end_request(ide_drive_t *drive, int uptodate) * now end the failed request */ if (blk_fs_request(failed)) { - if (ide_end_dequeued_request(drive, failed, 0, - failed->hard_nr_sectors)) + if (ide_end_rq(drive, failed, -EIO, + failed->hard_nr_sectors << 9)) BUG(); } else { if (blk_end_request(failed, -EIO, @@ -285,10 +292,13 @@ 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_debug_log(IDE_DBG_FUNC, "uptodate: 0x%x, nsectors: %d", + uptodate, nsectors); + + if (blk_fs_request(rq) == 0 && uptodate <= 0 && rq->errors == 0) + rq->errors = -EIO; - ide_end_request(drive, uptodate, nsectors); + ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9); } static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st) @@ -328,9 +338,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) return 1; } - ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, " - "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n", - __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err); + ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, " + "rq->cmd_type: 0x%x, err: 0x%x", + stat, good_stat, rq->cmd[0], rq->cmd_type, + err); if (blk_sense_request(rq)) { /* @@ -520,8 +531,7 @@ 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); + ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); /* * ireason == 0: the drive wants to receive data from us @@ -562,7 +572,7 @@ 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); + ide_debug_log(IDE_DBG_FUNC, "len: %d", len); if ((len % SECTOR_SIZE) == 0) return 0; @@ -584,8 +594,7 @@ static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) 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); + ide_debug_log(IDE_DBG_RQ, "rq->cmd_flags: 0x%x", rq->cmd_flags); if (rq_data_dir(rq) == READ) { unsigned short sectors_per_frame = @@ -629,7 +638,7 @@ static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive, static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if (rq->buffer != bio_data(rq->bio)) { sector_t n = @@ -648,8 +657,7 @@ static void ide_cd_restore_request(ide_drive_t *drive, 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, rq->cmd[0]: 0x%x\n", - __func__, rq->cmd[0]); + ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); /* * Some of the trailing request sense fields are optional, @@ -676,9 +684,9 @@ 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, cmd[0]: 0x%x, write: 0x%x, " - "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write, - timeout, cmd_flags); + ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " + "cmd_flags: 0x%x", + cmd[0], write, timeout, cmd_flags); /* start of retry loop */ do { @@ -762,8 +770,8 @@ 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); + ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x", + rq->cmd[0], write); /* check for errors */ dma = drive->dma; @@ -785,10 +793,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) if (dma_error) return ide_error(drive, "dma error", stat); if (blk_fs_request(rq)) { - ide_end_request(drive, 1, rq->nr_sectors); + ide_complete_rq(drive, 0, rq->nr_sectors + ? (rq->nr_sectors << 9) : ide_rq_bytes(rq)); return ide_stopped; } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) { - ide_end_request(drive, 1, 1); + ide_complete_rq(drive, 0, 512); return ide_stopped; } goto end_request; @@ -800,8 +809,8 @@ 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); + ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d", + stat, thislen); /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { @@ -866,8 +875,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); + ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, " + "ireason: 0x%x", + rq->cmd_type, ireason); /* transfer data */ while (thislen > 0) { @@ -949,7 +959,8 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) expiry = ide_cd_expiry; } - ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry); + hwif->expiry = expiry; + ide_set_handler(drive, cdrom_newpc_intr, timeout); return ide_started; end_request: @@ -978,9 +989,9 @@ 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, rq->cmd[0]: 0x%x, write: 0x%x, " - "secs_per_frame: %u\n", - __func__, rq->cmd[0], write, sectors_per_frame); + ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, write: 0x%x, " + "secs_per_frame: %u", + rq->cmd[0], write, sectors_per_frame); if (write) { /* disk has become write protected */ @@ -1016,9 +1027,8 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) { - ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, " - "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0], - rq->cmd_type); + ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", + rq->cmd[0], rq->cmd_type); if (blk_pc_request(rq)) rq->cmd_flags |= REQ_QUIET; @@ -1057,10 +1067,13 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, sector_t block) { - ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, " - "rq->cmd_type: 0x%x, block: %llu\n", - __func__, rq->cmd[0], rq->cmd_type, - (unsigned long long)block); + struct ide_cmd cmd; + + ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu", + rq->cmd[0], (unsigned long long)block); + + if (drive->debug_mask & IDE_DBG_RQ) + blk_dump_rq_flags(rq, "ide_cd_do_request"); if (blk_fs_request(rq)) { if (cdrom_start_rw(drive, rq) == ide_stopped) @@ -1084,7 +1097,14 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, return ide_stopped; } - return ide_issue_pc(drive); + memset(&cmd, 0, sizeof(cmd)); + + if (rq_data_dir(rq)) + cmd.tf_flags |= IDE_TFLAG_WRITE; + + cmd.rq = rq; + + return ide_issue_pc(drive, &cmd); } /* @@ -1109,7 +1129,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1137,7 +1157,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); memset(cmd, 0, BLK_MAX_CDB); cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1169,8 +1189,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = blocklen >> SECTOR_BITS; - ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n", - __func__, *capacity, *sectors_per_frame); + ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu", + *capacity, *sectors_per_frame); return 0; } @@ -1181,7 +1201,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); memset(cmd, 0, BLK_MAX_CDB); @@ -1211,7 +1231,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if (toc == NULL) { /* try to allocate space */ @@ -1373,7 +1393,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; @@ -1393,7 +1413,7 @@ 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]); @@ -1403,8 +1423,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]); } - ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n", - __func__, curspeed, maxspeed); + ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u", + curspeed, maxspeed); cd->current_speed = (curspeed + (176/2)) / 176; cd->max_speed = (maxspeed + (176/2)) / 176; @@ -1438,7 +1458,7 @@ 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); + ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots); devinfo->ops = &ide_cdrom_dops; devinfo->speed = info->current_speed; @@ -1461,9 +1481,8 @@ 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); + ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx", + 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 | @@ -1744,7 +1763,7 @@ static int ide_cdrom_setup(ide_drive_t *drive) char *fw_rev = (char *)&id[ATA_ID_FW_REV]; int nslots; - ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__); + ide_debug_log(IDE_DBG_PROBE, "enter"); blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn); blk_queue_dma_alignment(drive->queue, 31); @@ -1787,23 +1806,25 @@ 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_debug_log(IDE_DBG_FUNC, "enter"); ide_proc_unregister_driver(drive, info->driver); - + device_del(&info->dev); del_gendisk(info->disk); - ide_cd_put(info); + mutex_lock(&idecd_ref_mutex); + put_device(&info->dev); + mutex_unlock(&idecd_ref_mutex); } -static void ide_cd_release(struct kref *kref) +static void ide_cd_release(struct device *dev) { - struct cdrom_info *info = to_ide_drv(kref, cdrom_info); + struct cdrom_info *info = to_ide_drv(dev, 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__); + ide_debug_log(IDE_DBG_FUNC, "enter"); kfree(info->toc); if (devinfo->handle == drive) @@ -1827,7 +1848,6 @@ static struct ide_driver ide_cdrom_driver = { .remove = ide_cd_remove, .version = IDECD_VERSION, .do_request = ide_cd_do_request, - .end_request = ide_end_request, #ifdef CONFIG_IDE_PROC_FS .proc_entries = ide_cd_proc_entries, .proc_devsets = ide_cd_proc_devsets, @@ -1962,9 +1982,8 @@ 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); + ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x", + drive->driver_req, drive->media); if (!strstr("ide-cdrom", drive->driver_req)) goto failed; @@ -1997,7 +2016,12 @@ static int ide_cd_probe(ide_drive_t *drive) ide_init_disk(g, drive); - kref_init(&info->kref); + info->dev.parent = &drive->gendev; + info->dev.release = ide_cd_release; + dev_set_name(&info->dev, dev_name(&drive->gendev)); + + if (device_register(&info->dev)) + goto out_free_disk; info->drive = drive; info->driver = &ide_cdrom_driver; @@ -2011,7 +2035,7 @@ 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_cd_release(&info->kref); + put_device(&info->dev); goto failed; } @@ -2021,6 +2045,8 @@ static int ide_cd_probe(ide_drive_t *drive) add_disk(g); return 0; +out_free_disk: + put_disk(g); out_free_cd: kfree(info); failed: |