diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ff8815937d32..792a3cf73d6e 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -839,34 +839,54 @@ static void ide_cd_request_sense_fixup(struct request *rq) | |||
839 | } | 839 | } |
840 | } | 840 | } |
841 | 841 | ||
842 | int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) | 842 | int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd, |
843 | int write, void *buffer, unsigned *bufflen, | ||
844 | struct request_sense *sense, int timeout, | ||
845 | unsigned int cmd_flags) | ||
843 | { | 846 | { |
844 | struct request_sense sense; | 847 | struct cdrom_info *info = drive->driver_data; |
848 | struct request_sense local_sense; | ||
845 | int retries = 10; | 849 | int retries = 10; |
846 | unsigned int flags = rq->cmd_flags; | 850 | unsigned int flags = 0; |
847 | 851 | ||
848 | if (rq->sense == NULL) | 852 | if (!sense) |
849 | rq->sense = &sense; | 853 | sense = &local_sense; |
850 | 854 | ||
851 | /* start of retry loop */ | 855 | /* start of retry loop */ |
852 | do { | 856 | do { |
857 | struct request *rq; | ||
853 | int error; | 858 | int error; |
854 | unsigned long time = jiffies; | ||
855 | rq->cmd_flags = flags; | ||
856 | 859 | ||
857 | error = ide_do_drive_cmd(drive, rq, ide_wait); | 860 | rq = blk_get_request(drive->queue, write, __GFP_WAIT); |
858 | time = jiffies - time; | 861 | |
862 | memcpy(rq->cmd, cmd, BLK_MAX_CDB); | ||
863 | rq->cmd_type = REQ_TYPE_ATA_PC; | ||
864 | rq->sense = sense; | ||
865 | rq->cmd_flags |= cmd_flags; | ||
866 | rq->timeout = timeout; | ||
867 | if (buffer) { | ||
868 | rq->data = buffer; | ||
869 | rq->data_len = *bufflen; | ||
870 | } | ||
871 | |||
872 | error = blk_execute_rq(drive->queue, info->disk, rq, 0); | ||
873 | |||
874 | if (buffer) | ||
875 | *bufflen = rq->data_len; | ||
876 | |||
877 | flags = rq->cmd_flags; | ||
878 | blk_put_request(rq); | ||
859 | 879 | ||
860 | /* | 880 | /* |
861 | * FIXME: we should probably abort/retry or something in case of | 881 | * FIXME: we should probably abort/retry or something in case of |
862 | * failure. | 882 | * failure. |
863 | */ | 883 | */ |
864 | if (rq->cmd_flags & REQ_FAILED) { | 884 | if (flags & REQ_FAILED) { |
865 | /* | 885 | /* |
866 | * The request failed. Retry if it was due to a unit | 886 | * The request failed. Retry if it was due to a unit |
867 | * attention status (usually means media was changed). | 887 | * attention status (usually means media was changed). |
868 | */ | 888 | */ |
869 | struct request_sense *reqbuf = rq->sense; | 889 | struct request_sense *reqbuf = sense; |
870 | 890 | ||
871 | if (reqbuf->sense_key == UNIT_ATTENTION) | 891 | if (reqbuf->sense_key == UNIT_ATTENTION) |
872 | cdrom_saw_media_change(drive); | 892 | cdrom_saw_media_change(drive); |
@@ -886,10 +906,10 @@ int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) | |||
886 | } | 906 | } |
887 | 907 | ||
888 | /* end of retry loop */ | 908 | /* end of retry loop */ |
889 | } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0); | 909 | } while ((flags & REQ_FAILED) && retries >= 0); |
890 | 910 | ||
891 | /* return an error if the command failed */ | 911 | /* return an error if the command failed */ |
892 | return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; | 912 | return (flags & REQ_FAILED) ? -EIO : 0; |
893 | } | 913 | } |
894 | 914 | ||
895 | /* | 915 | /* |
@@ -1269,23 +1289,20 @@ static void msf_from_bcd(struct atapi_msf *msf) | |||
1269 | 1289 | ||
1270 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) | 1290 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) |
1271 | { | 1291 | { |
1272 | struct request req; | ||
1273 | struct cdrom_info *info = drive->driver_data; | 1292 | struct cdrom_info *info = drive->driver_data; |
1274 | struct cdrom_device_info *cdi = &info->devinfo; | 1293 | struct cdrom_device_info *cdi = &info->devinfo; |
1294 | unsigned char cmd[BLK_MAX_CDB]; | ||
1275 | 1295 | ||
1276 | ide_cd_init_rq(drive, &req); | 1296 | memset(cmd, 0, BLK_MAX_CDB); |
1277 | 1297 | cmd[0] = GPCMD_TEST_UNIT_READY; | |
1278 | req.sense = sense; | ||
1279 | req.cmd[0] = GPCMD_TEST_UNIT_READY; | ||
1280 | req.cmd_flags |= REQ_QUIET; | ||
1281 | 1298 | ||
1282 | /* | 1299 | /* |
1283 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs | 1300 | * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs |
1284 | * instead of supporting the LOAD_UNLOAD opcode. | 1301 | * instead of supporting the LOAD_UNLOAD opcode. |
1285 | */ | 1302 | */ |
1286 | req.cmd[7] = cdi->sanyo_slot % 3; | 1303 | cmd[7] = cdi->sanyo_slot % 3; |
1287 | 1304 | ||
1288 | return ide_cd_queue_pc(drive, &req); | 1305 | return ide_cd_queue_pc(drive, cmd, 0, NULL, 0, sense, 0, REQ_QUIET); |
1289 | } | 1306 | } |
1290 | 1307 | ||
1291 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | 1308 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, |
@@ -1298,17 +1315,14 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
1298 | } capbuf; | 1315 | } capbuf; |
1299 | 1316 | ||
1300 | int stat; | 1317 | int stat; |
1301 | struct request req; | 1318 | unsigned char cmd[BLK_MAX_CDB]; |
1302 | 1319 | unsigned len = sizeof(capbuf); | |
1303 | ide_cd_init_rq(drive, &req); | ||
1304 | 1320 | ||
1305 | req.sense = sense; | 1321 | memset(cmd, 0, BLK_MAX_CDB); |
1306 | req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; | 1322 | cmd[0] = GPCMD_READ_CDVD_CAPACITY; |
1307 | req.data = (char *)&capbuf; | ||
1308 | req.data_len = sizeof(capbuf); | ||
1309 | req.cmd_flags |= REQ_QUIET; | ||
1310 | 1323 | ||
1311 | stat = ide_cd_queue_pc(drive, &req); | 1324 | stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0, |
1325 | REQ_QUIET); | ||
1312 | if (stat == 0) { | 1326 | if (stat == 0) { |
1313 | *capacity = 1 + be32_to_cpu(capbuf.lba); | 1327 | *capacity = 1 + be32_to_cpu(capbuf.lba); |
1314 | *sectors_per_frame = | 1328 | *sectors_per_frame = |
@@ -1322,24 +1336,20 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, | |||
1322 | int format, char *buf, int buflen, | 1336 | int format, char *buf, int buflen, |
1323 | struct request_sense *sense) | 1337 | struct request_sense *sense) |
1324 | { | 1338 | { |
1325 | struct request req; | 1339 | unsigned char cmd[BLK_MAX_CDB]; |
1326 | 1340 | ||
1327 | ide_cd_init_rq(drive, &req); | 1341 | memset(cmd, 0, BLK_MAX_CDB); |
1328 | 1342 | ||
1329 | req.sense = sense; | 1343 | cmd[0] = GPCMD_READ_TOC_PMA_ATIP; |
1330 | req.data = buf; | 1344 | cmd[6] = trackno; |
1331 | req.data_len = buflen; | 1345 | cmd[7] = (buflen >> 8); |
1332 | req.cmd_flags |= REQ_QUIET; | 1346 | cmd[8] = (buflen & 0xff); |
1333 | req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; | 1347 | cmd[9] = (format << 6); |
1334 | req.cmd[6] = trackno; | ||
1335 | req.cmd[7] = (buflen >> 8); | ||
1336 | req.cmd[8] = (buflen & 0xff); | ||
1337 | req.cmd[9] = (format << 6); | ||
1338 | 1348 | ||
1339 | if (msf_flag) | 1349 | if (msf_flag) |
1340 | req.cmd[1] = 2; | 1350 | cmd[1] = 2; |
1341 | 1351 | ||
1342 | return ide_cd_queue_pc(drive, &req); | 1352 | return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET); |
1343 | } | 1353 | } |
1344 | 1354 | ||
1345 | /* Try to read the entire TOC for the disk into our internal buffer. */ | 1355 | /* Try to read the entire TOC for the disk into our internal buffer. */ |