diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 122 |
1 files changed, 60 insertions, 62 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 68e7f19dc036..d99847157186 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -188,16 +188,6 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
188 | ide_cd_log_error(drive->name, failed_command, sense); | 188 | ide_cd_log_error(drive->name, failed_command, sense); |
189 | } | 189 | } |
190 | 190 | ||
191 | /* Initialize a ide-cd packet command request */ | ||
192 | void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) | ||
193 | { | ||
194 | struct cdrom_info *cd = drive->driver_data; | ||
195 | |||
196 | ide_init_drive_cmd(rq); | ||
197 | rq->cmd_type = REQ_TYPE_ATA_PC; | ||
198 | rq->rq_disk = cd->disk; | ||
199 | } | ||
200 | |||
201 | static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | 191 | static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, |
202 | struct request *failed_command) | 192 | struct request *failed_command) |
203 | { | 193 | { |
@@ -208,7 +198,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
208 | sense = &info->sense_data; | 198 | sense = &info->sense_data; |
209 | 199 | ||
210 | /* stuff the sense request in front of our current request */ | 200 | /* stuff the sense request in front of our current request */ |
211 | ide_cd_init_rq(drive, rq); | 201 | blk_rq_init(NULL, rq); |
202 | rq->cmd_type = REQ_TYPE_ATA_PC; | ||
203 | rq->rq_disk = info->disk; | ||
212 | 204 | ||
213 | rq->data = sense; | 205 | rq->data = sense; |
214 | rq->cmd[0] = GPCMD_REQUEST_SENSE; | 206 | rq->cmd[0] = GPCMD_REQUEST_SENSE; |
@@ -216,11 +208,12 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, | |||
216 | rq->data_len = 18; | 208 | rq->data_len = 18; |
217 | 209 | ||
218 | rq->cmd_type = REQ_TYPE_SENSE; | 210 | rq->cmd_type = REQ_TYPE_SENSE; |
211 | rq->cmd_flags |= REQ_PREEMPT; | ||
219 | 212 | ||
220 | /* NOTE! Save the failed command in "rq->buffer" */ | 213 | /* NOTE! Save the failed command in "rq->buffer" */ |
221 | rq->buffer = (void *) failed_command; | 214 | rq->buffer = (void *) failed_command; |
222 | 215 | ||
223 | (void) ide_do_drive_cmd(drive, rq, ide_preempt); | 216 | ide_do_drive_cmd(drive, rq); |
224 | } | 217 | } |
225 | 218 | ||
226 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) | 219 | static void cdrom_end_request(ide_drive_t *drive, int uptodate) |
@@ -537,8 +530,8 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive, | |||
537 | info->dma = !hwif->dma_ops->dma_setup(drive); | 530 | info->dma = !hwif->dma_ops->dma_setup(drive); |
538 | 531 | ||
539 | /* set up the controller registers */ | 532 | /* set up the controller registers */ |
540 | ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | | 533 | ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL, |
541 | IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma); | 534 | xferlen, info->dma); |
542 | 535 | ||
543 | if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { | 536 | if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { |
544 | /* waiting for CDB interrupt, not DMA yet. */ | 537 | /* waiting for CDB interrupt, not DMA yet. */ |
@@ -838,34 +831,54 @@ static void ide_cd_request_sense_fixup(struct request *rq) | |||
838 | } | 831 | } |
839 | } | 832 | } |
840 | 833 | ||
841 | int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) | 834 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, |
835 | int write, void *buffer, unsigned *bufflen, | ||
836 | struct request_sense *sense, int timeout, | ||
837 | unsigned int cmd_flags) | ||
842 | { | 838 | { |
843 | struct request_sense sense; | 839 | struct cdrom_info *info = drive->driver_data; |
840 | struct request_sense local_sense; | ||
844 | int retries = 10; | 841 | int retries = 10; |
845 | unsigned int flags = rq->cmd_flags; | 842 | unsigned int flags = 0; |
846 | 843 | ||
847 | if (rq->sense == NULL) | 844 | if (!sense) |
848 | rq->sense = &sense; | 845 | sense = &local_sense; |
849 | 846 | ||
850 | /* start of retry loop */ | 847 | /* start of retry loop */ |
851 | do { | 848 | do { |
849 | struct request *rq; | ||
852 | int error; | 850 | int error; |
853 | unsigned long time = jiffies; | ||
854 | rq->cmd_flags = flags; | ||
855 | 851 | ||
856 | error = ide_do_drive_cmd(drive, rq, ide_wait); | 852 | rq = blk_get_request(drive->queue, write, __GFP_WAIT); |
857 | time = jiffies - time; | 853 | |
854 | memcpy(rq->cmd, cmd, BLK_MAX_CDB); | ||
855 | rq->cmd_type = REQ_TYPE_ATA_PC; | ||
856 | rq->sense = sense; | ||
857 | rq->cmd_flags |= cmd_flags; | ||
858 | rq->timeout = timeout; | ||
859 | if (buffer) { | ||
860 | rq->data = buffer; | ||
861 | rq->data_len = *bufflen; | ||
862 | } | ||
863 | |||
864 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); | ||
865 | |||
866 | if (buffer) | ||
867 | *bufflen = rq->data_len; | ||
868 | |||
869 | flags = rq->cmd_flags; | ||
870 | blk_put_request(rq); | ||
858 | 871 | ||
859 | /* | 872 | /* |
860 | * FIXME: we should probably abort/retry or something in case of | 873 | * FIXME: we should probably abort/retry or something in case of |
861 | * failure. | 874 | * failure. |
862 | */ | 875 | */ |
863 | if (rq->cmd_flags & REQ_FAILED) { | 876 | if (flags & REQ_FAILED) { |
864 | /* | 877 | /* |
865 | * The request failed. Retry if it was due to a unit | 878 | * The request failed. Retry if it was due to a unit |
866 | * attention status (usually means media was changed). | 879 | * attention status (usually means media was changed). |
867 | */ | 880 | */ |
868 | struct request_sense *reqbuf = rq->sense; | 881 | struct request_sense *reqbuf = sense; |
869 | 882 | ||
870 | if (reqbuf->sense_key == UNIT_ATTENTION) | 883 | if (reqbuf->sense_key == UNIT_ATTENTION) |
871 | cdrom_saw_media_change(drive); | 884 | cdrom_saw_media_change(drive); |
@@ -885,10 +898,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) | |||
885 | } | 898 | } |
886 | 899 | ||
887 | /* end of retry loop */ | 900 | /* end of retry loop */ |
888 | } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0); | 901 | } while ((flags & REQ_FAILED) && retries >= 0); |
889 | 902 | ||
890 | /* return an error if the command failed */ | 903 | /* return an error if the command failed */ |
891 | return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; | 904 | return (flags & REQ_FAILED) ? -EIO : 0; |
892 | } | 905 | } |
893 | 906 | ||
894 | /* | 907 | /* |
@@ -1268,23 +1281,20 @@ static void msf_from_bcd(struct atapi_msf *msf) | |||
1268 | 1281 | ||
1269 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) | 1282 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) |
1270 | { | 1283 | { |
1271 | struct request req; | ||
1272 | struct cdrom_info *info = drive->driver_data; | 1284 | struct cdrom_info *info = drive->driver_data; |
1273 | struct cdrom_device_info *cdi = &info->devinfo; | 1285 | struct cdrom_device_info *cdi = &info->devinfo; |
1286 | unsigned char cmd[BLK_MAX_CDB]; | ||
1274 | 1287 | ||
1275 | ide_cd_init_rq(drive, &req); | 1288 | memset(cmd, 0, BLK_MAX_CDB); |
1276 | 1289 | cmd[0] = GPCMD_TEST_UNIT_READY; | |
1277 | req.sense = sense; | ||
1278 | req.cmd[0] = GPCMD_TEST_UNIT_READY; | ||
1279 | req.cmd_flags |= REQ_QUIET; | ||
1280 | 1290 | ||
1281 | /* | 1291 | /* |
1282 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs | 1292 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs |
1283 | * instead of supporting the LOAD_UNLOAD opcode. | 1293 | * instead of supporting the LOAD_UNLOAD opcode. |
1284 | */ | 1294 | */ |
1285 | req.cmd[7] = cdi->sanyo_slot % 3; | 1295 | cmd[7] = cdi->sanyo_slot % 3; |
1286 | 1296 | ||
1287 | return ide_cd_queue_pc(drive, &req); | 1297 | return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET); |
1288 | } | 1298 | } |
1289 | 1299 | ||
1290 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | 1300 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, |
@@ -1297,17 +1307,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
1297 | } capbuf; | 1307 | } capbuf; |
1298 | 1308 | ||
1299 | int stat; | 1309 | int stat; |
1300 | struct request req; | 1310 | unsigned char cmd[BLK_MAX_CDB]; |
1301 | 1311 | unsigned len = sizeof(capbuf); | |
1302 | ide_cd_init_rq(drive, &req); | ||
1303 | 1312 | ||
1304 | req.sense = sense; | 1313 | memset(cmd, 0, BLK_MAX_CDB); |
1305 | req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; | 1314 | cmd[0] = GPCMD_READ_CDVD_CAPACITY; |
1306 | req.data = (char *)&capbuf; | ||
1307 | req.data_len = sizeof(capbuf); | ||
1308 | req.cmd_flags |= REQ_QUIET; | ||
1309 | 1315 | ||
1310 | stat = ide_cd_queue_pc(drive, &req); | 1316 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, |
1317 | REQ_QUIET); | ||
1311 | if (stat == 0) { | 1318 | if (stat == 0) { |
1312 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 1319 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
1313 | *sectors_per_frame = | 1320 | *sectors_per_frame = |
@@ -1321,24 +1328,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, | |||
1321 | int format, char *buf, int buflen, | 1328 | int format, char *buf, int buflen, |
1322 | struct request_sense *sense) | 1329 | struct request_sense *sense) |
1323 | { | 1330 | { |
1324 | struct request req; | 1331 | unsigned char cmd[BLK_MAX_CDB]; |
1325 | 1332 | ||
1326 | ide_cd_init_rq(drive, &req); | 1333 | memset(cmd, 0, BLK_MAX_CDB); |
1327 | 1334 | ||
1328 | req.sense = sense; | 1335 | cmd[0] = GPCMD_READ_TOC_PMA_ATIP; |
1329 | req.data = buf; | 1336 | cmd[6] = trackno; |
1330 | req.data_len = buflen; | 1337 | cmd[7] = (buflen >> 8); |
1331 | req.cmd_flags |= REQ_QUIET; | 1338 | cmd[8] = (buflen & 0xff); |
1332 | req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; | 1339 | cmd[9] = (format << 6); |
1333 | req.cmd[6] = trackno; | ||
1334 | req.cmd[7] = (buflen >> 8); | ||
1335 | req.cmd[8] = (buflen & 0xff); | ||
1336 | req.cmd[9] = (format << 6); | ||
1337 | 1340 | ||
1338 | if (msf_flag) | 1341 | if (msf_flag) |
1339 | req.cmd[1] = 2; | 1342 | cmd[1] = 2; |
1340 | 1343 | ||
1341 | return ide_cd_queue_pc(drive, &req); | 1344 | return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET); |
1342 | } | 1345 | } |
1343 | 1346 | ||
1344 | /* Try to read the entire TOC for the disk into our internal buffer. */ | 1347 | /* Try to read the entire TOC for the disk into our internal buffer. */ |
@@ -2103,11 +2106,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
2103 | goto failed; | 2106 | goto failed; |
2104 | } | 2107 | } |
2105 | } | 2108 | } |
2106 | if (drive->scsi) { | ||
2107 | printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi " | ||
2108 | "emulation.\n", drive->name); | ||
2109 | goto failed; | ||
2110 | } | ||
2111 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); | 2109 | info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL); |
2112 | if (info == NULL) { | 2110 | if (info == NULL) { |
2113 | printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", | 2111 | printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", |