/* * ATAPI CD-ROM driver. * * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * * See Documentation/cdrom/ide-cd for usage information. * * Suggestions are welcome. Patches that work are more welcome though. ;-) * * Documentation: * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. * * For historical changelog please see: * 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>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched/task_stack.h>#include <linux/delay.h>#include <linux/timer.h>#include <linux/seq_file.h>#include <linux/slab.h>#include <linux/interrupt.h>#include <linux/errno.h>#include <linux/cdrom.h>#include <linux/ide.h>#include <linux/completion.h>#include <linux/mutex.h>#include <linux/bcd.h> /* For SCSI -> ATAPI command conversion */#include <scsi/scsi.h> #include <linux/io.h>#include <asm/byteorder.h>#include <linux/uaccess.h>#include <asm/unaligned.h> #include "ide-cd.h" static DEFINE_MUTEX(ide_cd_mutex);static DEFINE_MUTEX(idecd_ref_mutex); static void ide_cd_release(struct device *); static struct cdrom_info *ide_cd_get(struct gendisk *disk){ struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); cd = ide_drv_g(disk, cdrom_info); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; else get_device(&cd->dev); } mutex_unlock(&idecd_ref_mutex); return cd;} static void ide_cd_put(struct cdrom_info *cd){ ide_drive_t *drive = cd->drive; mutex_lock(&idecd_ref_mutex); put_device(&cd->dev); ide_device_put(drive); mutex_unlock(&idecd_ref_mutex);} /* * Generic packet command support and error handling routines. */ /* Mark that we've seen a media change and invalidate our internal buffers. */static void cdrom_saw_media_change(ide_drive_t *drive){ drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;} static int cdrom_log_sense(ide_drive_t *drive, struct request *rq){ struct request_sense *sense = &drive->sense_data; int log = 0; if (!sense || !rq || (rq->rq_flags & RQF_QUIET)) return 0; ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); switch (sense->sense_key) { case NO_SENSE: case RECOVERED_ERROR: break; case NOT_READY: /* * don't care about tray state messages for e.g. capacity * commands or in-progress or becoming ready */ if (sense->asc == 0x3a || sense->asc == 0x04) break; log = 1; break; case ILLEGAL_REQUEST: /* * don't log START_STOP unit with LoEj set, since we cannot * reliably check if drive can auto-close */ if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) break; log = 1; break; case UNIT_ATTENTION: /* * Make good and sure we've seen this potential media change. * Some drives (i.e. Creative) fail to present the correct sense * key in the error register. */ cdrom_saw_media_change(drive); break; default: log = 1; break; } return log;} static void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *failed_command){ struct request_sense *sense = &drive->sense_data; struct cdrom_info *info = drive->driver_data; unsigned long sector; unsigned long bio_sectors; 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, "failed cmd: 0x%x", failed_command->cmd[0]); if (!cdrom_log_sense(drive, failed_command)) return; /* * If a read toc is executed for a CD-R or CD-RW medium where the first * toc has not been recorded yet, it will fail with 05/24/00 (which is a * confusing error) */ if (failed_command && scsi_req(failed_command)->cmd[0] == GPCMD_READ_TOC_PMA_ATIP) if (sense->sense_key == 0x05 && sense->asc == 0x24) return; /* current error */ if (sense->error_code == 0x70) { switch (sense->sense_key) { case MEDIUM_ERROR: case VOLUME_OVERFLOW: case ILLEGAL_REQUEST: if (!sense->valid) break; if (failed_command == NULL || blk_rq_is_passthrough(failed_command)) break; sector = (sense->information[0] << 24) | (sense->information[1] << 16) | (sense->information[2] << 8) | (sense->information[3]); if (queue_logical_block_size(drive->queue) == 2048) /* device sector size is 2K */ sector <<= 2; 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); } } ide_cd_log_error(drive->name, failed_command, sense);} static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq){ /* * For ATA_PRIV_SENSE, "rq->special" points to the original * failed request. Also, the sense data should be read * directly from rq which might be different from the original * sense buffer if it got copied during mapping. */ struct request *failed = (struct request *)rq->special; void *sense = bio_data(rq->bio); if (failed) { /* * Sense is always read into drive->sense_data, copy back to the * original request. */ memcpy(scsi_req(failed)->sense, sense, 18); scsi_req(failed)->sense_len = scsi_req(rq)->sense_len; cdrom_analyze_sense_data(drive, failed); if (ide_end_rq(drive, failed, BLK_STS_IOERR, blk_rq_bytes(failed))) BUG(); } else cdrom_analyze_sense_data(drive, NULL);} /* * Allow the drive 5 seconds to recover; some devices will return NOT_READY * while flushing data from cache. * * returns: 0 failed (write timeout expired) * 1 success */static int ide_cd_breathe(ide_drive_t *drive, struct request *rq){ struct cdrom_info *info = drive->driver_data; if (!scsi_req(rq)->result) info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; scsi_req(rq)->result = 1; if (time_after(jiffies, info->write_timeout)) return 0; else { /* * take a breather */ blk_delay_queue(drive->queue, 1); return 1; }} /** * Returns: * 0: if the request should be continued. * 1: if the request will be going through error recovery. * 2: if the request should be ended. */static int cdrom_decode_status(ide_drive_t *drive, u8 stat){ ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; int err, sense_key, do_end_request = 0; /* get the IDE error register */ err = ide_read_error(drive); sense_key = err >> 4; ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " "stat 0x%x", rq->cmd[0], rq->cmd_type, err, stat); if (ata_sense_request(rq)) { /* * We got an error trying to get sense info from the drive * (probably while trying to recover from a former error). * Just give up. */ rq->rq_flags |= RQF_FAILED; return 2; } /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ if (blk_rq_is_scsi(rq) && !scsi_req(rq)->result) scsi_req(rq)->result = SAM_STAT_CHECK_CONDITION; if (blk_noretry_request(rq)) do_end_request = 1; switch (sense_key) { case NOT_READY: if (req_op(rq) == REQ_OP_WRITE) { if (ide_cd_breathe(drive, rq)) return 1; } else { cdrom_saw_media_change(drive); if (!blk_rq_is_passthrough(rq) && !(rq->rq_flags & RQF_QUIET)) printk(KERN_ERR PFX "%s: tray open\n", drive->name); } do_end_request = 1; break; case UNIT_ATTENTION: cdrom_saw_media_change(drive); if (blk_rq_is_passthrough(rq)) return 0; /* * Arrange to retry the request but be sure to give up if we've * retried too many times. */ if (++scsi_req(rq)->result > ERROR_MAX) do_end_request = 1; break; case ILLEGAL_REQUEST: /* * Don't print error message for this condition -- SFF8090i * indicates that 5/24/00 is the correct response to a request * to close the tray if the drive doesn't have that capability. * * cdrom_log_sense() knows this! */ if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT) break; /* fall-through */ case DATA_PROTECT: /* * No point in retrying after an illegal request or data * protect error. */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "command error", stat); do_end_request = 1; break; case MEDIUM_ERROR: /* * No point in re-trying a zillion times on a bad sector. * If we got here the error is not correctable. */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "media error " "(bad sector)", stat); do_end_request = 1; break; case BLANK_CHECK: /* disk appears blank? */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "media error (blank)", stat); do_end_request = 1; break; default: if (blk_rq_is_passthrough(rq)) break; if (err & ~ATA_ABORTED) { /* go to the default handler for other errors */ ide_error(drive, "cdrom_decode_status", stat); return 1; } else if (++scsi_req(rq)->result > ERROR_MAX) /* we've racked up too many retries, abort */ do_end_request = 1; } if (blk_rq_is_passthrough(rq)) { rq->rq_flags |= RQF_FAILED; 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) goto end_request; /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) return ide_queue_sense_rq(drive, NULL) ? 2 : 1; return 1; end_request: if (stat & ATA_ERR) { hwif->rq = NULL; return ide_queue_sense_rq(drive, rq) ? 2 : 1; } else return 2;} static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd){ struct request *rq = cmd->rq; ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. */ if (scsi_req(rq)->cmd[0] == GPCMD_REQUEST_SENSE && cmd->nleft > 0 && cmd->nleft <= 5) cmd->nleft = 0;} int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, int write, void *buffer, unsigned *bufflen, struct request_sense *sense, int timeout, req_flags_t rq_flags){ struct cdrom_info *info = drive->driver_data; int retries = 10; bool failed; ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " "rq_flags: 0x%x", cmd[0], write, timeout, rq_flags); /* start of retry loop */ do { struct request *rq; int error; bool delay = false; rq = blk_get_request(drive->queue, write ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, __GFP_RECLAIM); memcpy(scsi_req(rq)->cmd, cmd, BLK_MAX_CDB); ide_req(rq)->type = ATA_PRIV_PC; rq->rq_flags |= rq_flags; rq->timeout = timeout; if (buffer) { error = blk_rq_map_kern(drive->queue, rq, buffer, *bufflen, GFP_NOIO); if (error) { blk_put_request(rq); return error; } } blk_execute_rq(drive->queue, info->disk, rq, 0); error = scsi_req(rq)->result ? -EIO : 0; if (buffer) *bufflen = scsi_req(rq)->resid_len; if (sense) memcpy(sense, scsi_req(rq)->sense, sizeof(*sense)); /* * FIXME: we should probably abort/retry or something in case of * failure. */ failed = (rq->rq_flags & RQF_FAILED) != 0; if (failed) { /* * The request failed. Retry if it was due to a unit * attention status (usually means media was changed). */ struct request_sense *reqbuf = scsi_req(rq)->sense; if (reqbuf->sense_key == UNIT_ATTENTION) cdrom_saw_media_change(drive); else if (reqbuf->sense_key == NOT_READY && reqbuf->asc == 4 && reqbuf->ascq != 4) { /* * The drive is in the process of loading * a disk. Retry, but wait a little to give * the drive time to complete the load. */ delay = true; } else { /* otherwise, don't retry */ retries = 0; } --retries; } blk_put_request(rq); if (delay) ssleep(2); } while (failed && retries >= 0); /* return an error if the command failed */ return failed ? -EIO : 0;} /* * returns true if rq has been completedLines 1–500 of 1823. Load more
/* * ATAPI CD-ROM driver. * * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * * See Documentation/cdrom/ide-cd for usage information. * * Suggestions are welcome. Patches that work are more welcome though. ;-) * * Documentation: * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards. * * For historical changelog please see: * 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> #include <linux/types.h> #include <linux/kernel.h> #include <linux/sched/task_stack.h> #include <linux/delay.h> #include <linux/timer.h> #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/errno.h> #include <linux/cdrom.h> #include <linux/ide.h> #include <linux/completion.h> #include <linux/mutex.h> #include <linux/bcd.h> /* For SCSI -> ATAPI command conversion */ #include <scsi/scsi.h> #include <linux/io.h> #include <asm/byteorder.h> #include <linux/uaccess.h> #include <asm/unaligned.h> #include "ide-cd.h" static DEFINE_MUTEX(ide_cd_mutex); static DEFINE_MUTEX(idecd_ref_mutex); static void ide_cd_release(struct device *); static struct cdrom_info *ide_cd_get(struct gendisk *disk) { struct cdrom_info *cd = NULL; mutex_lock(&idecd_ref_mutex); cd = ide_drv_g(disk, cdrom_info); if (cd) { if (ide_device_get(cd->drive)) cd = NULL; else get_device(&cd->dev); } mutex_unlock(&idecd_ref_mutex); return cd; } static void ide_cd_put(struct cdrom_info *cd) { ide_drive_t *drive = cd->drive; mutex_lock(&idecd_ref_mutex); put_device(&cd->dev); ide_device_put(drive); mutex_unlock(&idecd_ref_mutex); } /* * Generic packet command support and error handling routines. */ /* Mark that we've seen a media change and invalidate our internal buffers. */ static void cdrom_saw_media_change(ide_drive_t *drive) { drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED; drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; } static int cdrom_log_sense(ide_drive_t *drive, struct request *rq) { struct request_sense *sense = &drive->sense_data; int log = 0; if (!sense || !rq || (rq->rq_flags & RQF_QUIET)) return 0; ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); switch (sense->sense_key) { case NO_SENSE: case RECOVERED_ERROR: break; case NOT_READY: /* * don't care about tray state messages for e.g. capacity * commands or in-progress or becoming ready */ if (sense->asc == 0x3a || sense->asc == 0x04) break; log = 1; break; case ILLEGAL_REQUEST: /* * don't log START_STOP unit with LoEj set, since we cannot * reliably check if drive can auto-close */ if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24) break; log = 1; break; case UNIT_ATTENTION: /* * Make good and sure we've seen this potential media change. * Some drives (i.e. Creative) fail to present the correct sense * key in the error register. */ cdrom_saw_media_change(drive); break; default: log = 1; break; } return log; } static void cdrom_analyze_sense_data(ide_drive_t *drive, struct request *failed_command) { struct request_sense *sense = &drive->sense_data; struct cdrom_info *info = drive->driver_data; unsigned long sector; unsigned long bio_sectors; 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, "failed cmd: 0x%x", failed_command->cmd[0]); if (!cdrom_log_sense(drive, failed_command)) return; /* * If a read toc is executed for a CD-R or CD-RW medium where the first * toc has not been recorded yet, it will fail with 05/24/00 (which is a * confusing error) */ if (failed_command && scsi_req(failed_command)->cmd[0] == GPCMD_READ_TOC_PMA_ATIP) if (sense->sense_key == 0x05 && sense->asc == 0x24) return; /* current error */ if (sense->error_code == 0x70) { switch (sense->sense_key) { case MEDIUM_ERROR: case VOLUME_OVERFLOW: case ILLEGAL_REQUEST: if (!sense->valid) break; if (failed_command == NULL || blk_rq_is_passthrough(failed_command)) break; sector = (sense->information[0] << 24) | (sense->information[1] << 16) | (sense->information[2] << 8) | (sense->information[3]); if (queue_logical_block_size(drive->queue) == 2048) /* device sector size is 2K */ sector <<= 2; 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); } } ide_cd_log_error(drive->name, failed_command, sense); } static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) { /* * For ATA_PRIV_SENSE, "rq->special" points to the original * failed request. Also, the sense data should be read * directly from rq which might be different from the original * sense buffer if it got copied during mapping. */ struct request *failed = (struct request *)rq->special; void *sense = bio_data(rq->bio); if (failed) { /* * Sense is always read into drive->sense_data, copy back to the * original request. */ memcpy(scsi_req(failed)->sense, sense, 18); scsi_req(failed)->sense_len = scsi_req(rq)->sense_len; cdrom_analyze_sense_data(drive, failed); if (ide_end_rq(drive, failed, BLK_STS_IOERR, blk_rq_bytes(failed))) BUG(); } else cdrom_analyze_sense_data(drive, NULL); } /* * Allow the drive 5 seconds to recover; some devices will return NOT_READY * while flushing data from cache. * * returns: 0 failed (write timeout expired) * 1 success */ static int ide_cd_breathe(ide_drive_t *drive, struct request *rq) { struct cdrom_info *info = drive->driver_data; if (!scsi_req(rq)->result) info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY; scsi_req(rq)->result = 1; if (time_after(jiffies, info->write_timeout)) return 0; else { /* * take a breather */ blk_delay_queue(drive->queue, 1); return 1; } } /** * Returns: * 0: if the request should be continued. * 1: if the request will be going through error recovery. * 2: if the request should be ended. */ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) { ide_hwif_t *hwif = drive->hwif; struct request *rq = hwif->rq; int err, sense_key, do_end_request = 0; /* get the IDE error register */ err = ide_read_error(drive); sense_key = err >> 4; ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, " "stat 0x%x", rq->cmd[0], rq->cmd_type, err, stat); if (ata_sense_request(rq)) { /* * We got an error trying to get sense info from the drive * (probably while trying to recover from a former error). * Just give up. */ rq->rq_flags |= RQF_FAILED; return 2; } /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ if (blk_rq_is_scsi(rq) && !scsi_req(rq)->result) scsi_req(rq)->result = SAM_STAT_CHECK_CONDITION; if (blk_noretry_request(rq)) do_end_request = 1; switch (sense_key) { case NOT_READY: if (req_op(rq) == REQ_OP_WRITE) { if (ide_cd_breathe(drive, rq)) return 1; } else { cdrom_saw_media_change(drive); if (!blk_rq_is_passthrough(rq) && !(rq->rq_flags & RQF_QUIET)) printk(KERN_ERR PFX "%s: tray open\n", drive->name); } do_end_request = 1; break; case UNIT_ATTENTION: cdrom_saw_media_change(drive); if (blk_rq_is_passthrough(rq)) return 0; /* * Arrange to retry the request but be sure to give up if we've * retried too many times. */ if (++scsi_req(rq)->result > ERROR_MAX) do_end_request = 1; break; case ILLEGAL_REQUEST: /* * Don't print error message for this condition -- SFF8090i * indicates that 5/24/00 is the correct response to a request * to close the tray if the drive doesn't have that capability. * * cdrom_log_sense() knows this! */ if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT) break; /* fall-through */ case DATA_PROTECT: /* * No point in retrying after an illegal request or data * protect error. */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "command error", stat); do_end_request = 1; break; case MEDIUM_ERROR: /* * No point in re-trying a zillion times on a bad sector. * If we got here the error is not correctable. */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "media error " "(bad sector)", stat); do_end_request = 1; break; case BLANK_CHECK: /* disk appears blank? */ if (!(rq->rq_flags & RQF_QUIET)) ide_dump_status(drive, "media error (blank)", stat); do_end_request = 1; break; default: if (blk_rq_is_passthrough(rq)) break; if (err & ~ATA_ABORTED) { /* go to the default handler for other errors */ ide_error(drive, "cdrom_decode_status", stat); return 1; } else if (++scsi_req(rq)->result > ERROR_MAX) /* we've racked up too many retries, abort */ do_end_request = 1; } if (blk_rq_is_passthrough(rq)) { rq->rq_flags |= RQF_FAILED; 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) goto end_request; /* if we got a CHECK_CONDITION status, queue a request sense command */ if (stat & ATA_ERR) return ide_queue_sense_rq(drive, NULL) ? 2 : 1; return 1; end_request: if (stat & ATA_ERR) { hwif->rq = NULL; return ide_queue_sense_rq(drive, rq) ? 2 : 1; } else return 2; } static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) { struct request *rq = cmd->rq; ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]); /* * Some of the trailing request sense fields are optional, * and some drives don't send them. Sigh. */ if (scsi_req(rq)->cmd[0] == GPCMD_REQUEST_SENSE && cmd->nleft > 0 && cmd->nleft <= 5) cmd->nleft = 0; } int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, int write, void *buffer, unsigned *bufflen, struct request_sense *sense, int timeout, req_flags_t rq_flags) { struct cdrom_info *info = drive->driver_data; int retries = 10; bool failed; ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, " "rq_flags: 0x%x", cmd[0], write, timeout, rq_flags); /* start of retry loop */ do { struct request *rq; int error; bool delay = false; rq = blk_get_request(drive->queue, write ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, __GFP_RECLAIM); memcpy(scsi_req(rq)->cmd, cmd, BLK_MAX_CDB); ide_req(rq)->type = ATA_PRIV_PC; rq->rq_flags |= rq_flags; rq->timeout = timeout; if (buffer) { error = blk_rq_map_kern(drive->queue, rq, buffer, *bufflen, GFP_NOIO); if (error) { blk_put_request(rq); return error; } } blk_execute_rq(drive->queue, info->disk, rq, 0); error = scsi_req(rq)->result ? -EIO : 0; if (buffer) *bufflen = scsi_req(rq)->resid_len; if (sense) memcpy(sense, scsi_req(rq)->sense, sizeof(*sense)); /* * FIXME: we should probably abort/retry or something in case of * failure. */ failed = (rq->rq_flags & RQF_FAILED) != 0; if (failed) { /* * The request failed. Retry if it was due to a unit * attention status (usually means media was changed). */ struct request_sense *reqbuf = scsi_req(rq)->sense; if (reqbuf->sense_key == UNIT_ATTENTION) cdrom_saw_media_change(drive); else if (reqbuf->sense_key == NOT_READY && reqbuf->asc == 4 && reqbuf->ascq != 4) { /* * The drive is in the process of loading * a disk. Retry, but wait a little to give * the drive time to complete the load. */ delay = true; } else { /* otherwise, don't retry */ retries = 0; } --retries; } blk_put_request(rq); if (delay) ssleep(2); } while (failed && retries >= 0); /* return an error if the command failed */ return failed ? -EIO : 0; } /* * returns true if rq has been completed