.. | .. |
---|
9 | 9 | * May be copied or modified under the terms of the GNU General Public |
---|
10 | 10 | * License. See linux/COPYING for more information. |
---|
11 | 11 | * |
---|
12 | | - * See Documentation/cdrom/ide-cd for usage information. |
---|
| 12 | + * See Documentation/cdrom/ide-cd.rst for usage information. |
---|
13 | 13 | * |
---|
14 | 14 | * Suggestions are welcome. Patches that work are more welcome though. ;-) |
---|
15 | 15 | * |
---|
.. | .. |
---|
25 | 25 | |
---|
26 | 26 | #define IDECD_VERSION "5.00" |
---|
27 | 27 | |
---|
| 28 | +#include <linux/compat.h> |
---|
28 | 29 | #include <linux/module.h> |
---|
29 | 30 | #include <linux/types.h> |
---|
30 | 31 | #include <linux/kernel.h> |
---|
.. | .. |
---|
211 | 212 | static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) |
---|
212 | 213 | { |
---|
213 | 214 | /* |
---|
214 | | - * For ATA_PRIV_SENSE, "rq->special" points to the original |
---|
| 215 | + * For ATA_PRIV_SENSE, "ide_req(rq)->special" points to the original |
---|
215 | 216 | * failed request. Also, the sense data should be read |
---|
216 | 217 | * directly from rq which might be different from the original |
---|
217 | 218 | * sense buffer if it got copied during mapping. |
---|
218 | 219 | */ |
---|
219 | | - struct request *failed = (struct request *)rq->special; |
---|
| 220 | + struct request *failed = ide_req(rq)->special; |
---|
220 | 221 | void *sense = bio_data(rq->bio); |
---|
221 | 222 | |
---|
222 | 223 | if (failed) { |
---|
.. | .. |
---|
258 | 259 | /* |
---|
259 | 260 | * take a breather |
---|
260 | 261 | */ |
---|
261 | | - blk_delay_queue(drive->queue, 1); |
---|
| 262 | + blk_mq_requeue_request(rq, false); |
---|
| 263 | + blk_mq_delay_kick_requeue_list(drive->queue, 1); |
---|
262 | 264 | return 1; |
---|
263 | 265 | } |
---|
| 266 | +} |
---|
| 267 | + |
---|
| 268 | +static void ide_cd_free_sense(ide_drive_t *drive) |
---|
| 269 | +{ |
---|
| 270 | + if (!drive->sense_rq) |
---|
| 271 | + return; |
---|
| 272 | + |
---|
| 273 | + blk_mq_free_request(drive->sense_rq); |
---|
| 274 | + drive->sense_rq = NULL; |
---|
| 275 | + drive->sense_rq_armed = false; |
---|
264 | 276 | } |
---|
265 | 277 | |
---|
266 | 278 | /** |
---|
.. | .. |
---|
338 | 350 | */ |
---|
339 | 351 | if (scsi_req(rq)->cmd[0] == GPCMD_START_STOP_UNIT) |
---|
340 | 352 | break; |
---|
341 | | - /* fall-through */ |
---|
| 353 | + fallthrough; |
---|
342 | 354 | case DATA_PROTECT: |
---|
343 | 355 | /* |
---|
344 | 356 | * No point in retrying after an illegal request or data |
---|
.. | .. |
---|
516 | 528 | return false; |
---|
517 | 529 | } |
---|
518 | 530 | |
---|
| 531 | +/* standard prep_rq that builds 10 byte cmds */ |
---|
| 532 | +static bool ide_cdrom_prep_fs(struct request_queue *q, struct request *rq) |
---|
| 533 | +{ |
---|
| 534 | + int hard_sect = queue_logical_block_size(q); |
---|
| 535 | + long block = (long)blk_rq_pos(rq) / (hard_sect >> 9); |
---|
| 536 | + unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); |
---|
| 537 | + struct scsi_request *req = scsi_req(rq); |
---|
| 538 | + |
---|
| 539 | + if (rq_data_dir(rq) == READ) |
---|
| 540 | + req->cmd[0] = GPCMD_READ_10; |
---|
| 541 | + else |
---|
| 542 | + req->cmd[0] = GPCMD_WRITE_10; |
---|
| 543 | + |
---|
| 544 | + /* |
---|
| 545 | + * fill in lba |
---|
| 546 | + */ |
---|
| 547 | + req->cmd[2] = (block >> 24) & 0xff; |
---|
| 548 | + req->cmd[3] = (block >> 16) & 0xff; |
---|
| 549 | + req->cmd[4] = (block >> 8) & 0xff; |
---|
| 550 | + req->cmd[5] = block & 0xff; |
---|
| 551 | + |
---|
| 552 | + /* |
---|
| 553 | + * and transfer length |
---|
| 554 | + */ |
---|
| 555 | + req->cmd[7] = (blocks >> 8) & 0xff; |
---|
| 556 | + req->cmd[8] = blocks & 0xff; |
---|
| 557 | + req->cmd_len = 10; |
---|
| 558 | + return true; |
---|
| 559 | +} |
---|
| 560 | + |
---|
| 561 | +/* |
---|
| 562 | + * Most of the SCSI commands are supported directly by ATAPI devices. |
---|
| 563 | + * This transform handles the few exceptions. |
---|
| 564 | + */ |
---|
| 565 | +static bool ide_cdrom_prep_pc(struct request *rq) |
---|
| 566 | +{ |
---|
| 567 | + u8 *c = scsi_req(rq)->cmd; |
---|
| 568 | + |
---|
| 569 | + /* transform 6-byte read/write commands to the 10-byte version */ |
---|
| 570 | + if (c[0] == READ_6 || c[0] == WRITE_6) { |
---|
| 571 | + c[8] = c[4]; |
---|
| 572 | + c[5] = c[3]; |
---|
| 573 | + c[4] = c[2]; |
---|
| 574 | + c[3] = c[1] & 0x1f; |
---|
| 575 | + c[2] = 0; |
---|
| 576 | + c[1] &= 0xe0; |
---|
| 577 | + c[0] += (READ_10 - READ_6); |
---|
| 578 | + scsi_req(rq)->cmd_len = 10; |
---|
| 579 | + return true; |
---|
| 580 | + } |
---|
| 581 | + |
---|
| 582 | + /* |
---|
| 583 | + * it's silly to pretend we understand 6-byte sense commands, just |
---|
| 584 | + * reject with ILLEGAL_REQUEST and the caller should take the |
---|
| 585 | + * appropriate action |
---|
| 586 | + */ |
---|
| 587 | + if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { |
---|
| 588 | + scsi_req(rq)->result = ILLEGAL_REQUEST; |
---|
| 589 | + return false; |
---|
| 590 | + } |
---|
| 591 | + |
---|
| 592 | + return true; |
---|
| 593 | +} |
---|
| 594 | + |
---|
| 595 | +static bool ide_cdrom_prep_rq(ide_drive_t *drive, struct request *rq) |
---|
| 596 | +{ |
---|
| 597 | + if (!blk_rq_is_passthrough(rq)) { |
---|
| 598 | + scsi_req_init(scsi_req(rq)); |
---|
| 599 | + |
---|
| 600 | + return ide_cdrom_prep_fs(drive->queue, rq); |
---|
| 601 | + } else if (blk_rq_is_scsi(rq)) |
---|
| 602 | + return ide_cdrom_prep_pc(rq); |
---|
| 603 | + |
---|
| 604 | + return true; |
---|
| 605 | +} |
---|
| 606 | + |
---|
519 | 607 | static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) |
---|
520 | 608 | { |
---|
521 | 609 | ide_hwif_t *hwif = drive->hwif; |
---|
.. | .. |
---|
662 | 750 | case REQ_OP_DRV_IN: |
---|
663 | 751 | case REQ_OP_DRV_OUT: |
---|
664 | 752 | expiry = ide_cd_expiry; |
---|
665 | | - /*FALLTHRU*/ |
---|
| 753 | + fallthrough; |
---|
666 | 754 | default: |
---|
667 | 755 | timeout = ATAPI_WAIT_PC; |
---|
668 | 756 | break; |
---|
.. | .. |
---|
675 | 763 | out_end: |
---|
676 | 764 | if (blk_rq_is_scsi(rq) && rc == 0) { |
---|
677 | 765 | scsi_req(rq)->resid_len = 0; |
---|
678 | | - blk_end_request_all(rq, BLK_STS_OK); |
---|
| 766 | + blk_mq_end_request(rq, BLK_STS_OK); |
---|
679 | 767 | hwif->rq = NULL; |
---|
680 | 768 | } else { |
---|
681 | 769 | if (sense && uptodate) |
---|
.. | .. |
---|
705 | 793 | if (sense && rc == 2) |
---|
706 | 794 | ide_error(drive, "request sense failure", stat); |
---|
707 | 795 | } |
---|
| 796 | + |
---|
| 797 | + ide_cd_free_sense(drive); |
---|
708 | 798 | return ide_stopped; |
---|
709 | 799 | } |
---|
710 | 800 | |
---|
.. | .. |
---|
729 | 819 | * We may be retrying this request after an error. Fix up any |
---|
730 | 820 | * weirdness which might be present in the request packet. |
---|
731 | 821 | */ |
---|
732 | | - q->prep_rq_fn(q, rq); |
---|
| 822 | + ide_cdrom_prep_rq(drive, rq); |
---|
733 | 823 | } |
---|
734 | 824 | |
---|
735 | 825 | /* fs requests *must* be hardware frame aligned */ |
---|
.. | .. |
---|
944 | 1034 | return 0; |
---|
945 | 1035 | } |
---|
946 | 1036 | |
---|
947 | | -static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, |
---|
948 | | - int format, char *buf, int buflen) |
---|
| 1037 | +static int ide_cdrom_read_tocentry(ide_drive_t *drive, int trackno, |
---|
| 1038 | + int msf_flag, int format, char *buf, int buflen) |
---|
949 | 1039 | { |
---|
950 | 1040 | unsigned char cmd[BLK_MAX_CDB]; |
---|
951 | 1041 | |
---|
.. | .. |
---|
1014 | 1104 | sectors_per_frame << SECTOR_SHIFT); |
---|
1015 | 1105 | |
---|
1016 | 1106 | /* first read just the header, so we know how long the TOC is */ |
---|
1017 | | - stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, |
---|
| 1107 | + stat = ide_cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr, |
---|
1018 | 1108 | sizeof(struct atapi_toc_header)); |
---|
1019 | 1109 | if (stat) |
---|
1020 | 1110 | return stat; |
---|
.. | .. |
---|
1031 | 1121 | ntracks = MAX_TRACKS; |
---|
1032 | 1122 | |
---|
1033 | 1123 | /* now read the whole schmeer */ |
---|
1034 | | - stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, |
---|
| 1124 | + stat = ide_cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0, |
---|
1035 | 1125 | (char *)&toc->hdr, |
---|
1036 | 1126 | sizeof(struct atapi_toc_header) + |
---|
1037 | 1127 | (ntracks + 1) * |
---|
.. | .. |
---|
1051 | 1141 | * Heiko Eißfeldt. |
---|
1052 | 1142 | */ |
---|
1053 | 1143 | ntracks = 0; |
---|
1054 | | - stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, |
---|
| 1144 | + stat = ide_cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0, |
---|
1055 | 1145 | (char *)&toc->hdr, |
---|
1056 | 1146 | sizeof(struct atapi_toc_header) + |
---|
1057 | 1147 | (ntracks + 1) * |
---|
.. | .. |
---|
1091 | 1181 | |
---|
1092 | 1182 | if (toc->hdr.first_track != CDROM_LEADOUT) { |
---|
1093 | 1183 | /* read the multisession information */ |
---|
1094 | | - stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp, |
---|
| 1184 | + stat = ide_cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp, |
---|
1095 | 1185 | sizeof(ms_tmp)); |
---|
1096 | 1186 | if (stat) |
---|
1097 | 1187 | return stat; |
---|
.. | .. |
---|
1105 | 1195 | |
---|
1106 | 1196 | if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) { |
---|
1107 | 1197 | /* re-read multisession information using MSF format */ |
---|
1108 | | - stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, |
---|
| 1198 | + stat = ide_cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp, |
---|
1109 | 1199 | sizeof(ms_tmp)); |
---|
1110 | 1200 | if (stat) |
---|
1111 | 1201 | return stat; |
---|
.. | .. |
---|
1215 | 1305 | if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT) |
---|
1216 | 1306 | devinfo->mask |= CDC_SELECT_SPEED; |
---|
1217 | 1307 | |
---|
1218 | | - devinfo->disk = info->disk; |
---|
1219 | | - return register_cdrom(devinfo); |
---|
| 1308 | + return register_cdrom(info->disk, devinfo); |
---|
1220 | 1309 | } |
---|
1221 | 1310 | |
---|
1222 | 1311 | static int ide_cdrom_probe_capabilities(ide_drive_t *drive) |
---|
.. | .. |
---|
1321 | 1410 | be16_to_cpup((__be16 *)&buf[8 + 12])); |
---|
1322 | 1411 | |
---|
1323 | 1412 | return nslots; |
---|
1324 | | -} |
---|
1325 | | - |
---|
1326 | | -/* standard prep_rq_fn that builds 10 byte cmds */ |
---|
1327 | | -static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq) |
---|
1328 | | -{ |
---|
1329 | | - int hard_sect = queue_logical_block_size(q); |
---|
1330 | | - long block = (long)blk_rq_pos(rq) / (hard_sect >> 9); |
---|
1331 | | - unsigned long blocks = blk_rq_sectors(rq) / (hard_sect >> 9); |
---|
1332 | | - struct scsi_request *req = scsi_req(rq); |
---|
1333 | | - |
---|
1334 | | - q->initialize_rq_fn(rq); |
---|
1335 | | - |
---|
1336 | | - if (rq_data_dir(rq) == READ) |
---|
1337 | | - req->cmd[0] = GPCMD_READ_10; |
---|
1338 | | - else |
---|
1339 | | - req->cmd[0] = GPCMD_WRITE_10; |
---|
1340 | | - |
---|
1341 | | - /* |
---|
1342 | | - * fill in lba |
---|
1343 | | - */ |
---|
1344 | | - req->cmd[2] = (block >> 24) & 0xff; |
---|
1345 | | - req->cmd[3] = (block >> 16) & 0xff; |
---|
1346 | | - req->cmd[4] = (block >> 8) & 0xff; |
---|
1347 | | - req->cmd[5] = block & 0xff; |
---|
1348 | | - |
---|
1349 | | - /* |
---|
1350 | | - * and transfer length |
---|
1351 | | - */ |
---|
1352 | | - req->cmd[7] = (blocks >> 8) & 0xff; |
---|
1353 | | - req->cmd[8] = blocks & 0xff; |
---|
1354 | | - req->cmd_len = 10; |
---|
1355 | | - return BLKPREP_OK; |
---|
1356 | | -} |
---|
1357 | | - |
---|
1358 | | -/* |
---|
1359 | | - * Most of the SCSI commands are supported directly by ATAPI devices. |
---|
1360 | | - * This transform handles the few exceptions. |
---|
1361 | | - */ |
---|
1362 | | -static int ide_cdrom_prep_pc(struct request *rq) |
---|
1363 | | -{ |
---|
1364 | | - u8 *c = scsi_req(rq)->cmd; |
---|
1365 | | - |
---|
1366 | | - /* transform 6-byte read/write commands to the 10-byte version */ |
---|
1367 | | - if (c[0] == READ_6 || c[0] == WRITE_6) { |
---|
1368 | | - c[8] = c[4]; |
---|
1369 | | - c[5] = c[3]; |
---|
1370 | | - c[4] = c[2]; |
---|
1371 | | - c[3] = c[1] & 0x1f; |
---|
1372 | | - c[2] = 0; |
---|
1373 | | - c[1] &= 0xe0; |
---|
1374 | | - c[0] += (READ_10 - READ_6); |
---|
1375 | | - scsi_req(rq)->cmd_len = 10; |
---|
1376 | | - return BLKPREP_OK; |
---|
1377 | | - } |
---|
1378 | | - |
---|
1379 | | - /* |
---|
1380 | | - * it's silly to pretend we understand 6-byte sense commands, just |
---|
1381 | | - * reject with ILLEGAL_REQUEST and the caller should take the |
---|
1382 | | - * appropriate action |
---|
1383 | | - */ |
---|
1384 | | - if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { |
---|
1385 | | - scsi_req(rq)->result = ILLEGAL_REQUEST; |
---|
1386 | | - return BLKPREP_KILL; |
---|
1387 | | - } |
---|
1388 | | - |
---|
1389 | | - return BLKPREP_OK; |
---|
1390 | | -} |
---|
1391 | | - |
---|
1392 | | -static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) |
---|
1393 | | -{ |
---|
1394 | | - if (!blk_rq_is_passthrough(rq)) |
---|
1395 | | - return ide_cdrom_prep_fs(q, rq); |
---|
1396 | | - else if (blk_rq_is_scsi(rq)) |
---|
1397 | | - return ide_cdrom_prep_pc(rq); |
---|
1398 | | - |
---|
1399 | | - return 0; |
---|
1400 | 1413 | } |
---|
1401 | 1414 | |
---|
1402 | 1415 | struct cd_list_entry { |
---|
.. | .. |
---|
1508 | 1521 | |
---|
1509 | 1522 | ide_debug_log(IDE_DBG_PROBE, "enter"); |
---|
1510 | 1523 | |
---|
1511 | | - blk_queue_prep_rq(q, ide_cdrom_prep_fn); |
---|
| 1524 | + drive->prep_rq = ide_cdrom_prep_rq; |
---|
1512 | 1525 | blk_queue_dma_alignment(q, 31); |
---|
1513 | 1526 | blk_queue_update_dma_pad(q, 15); |
---|
1514 | 1527 | |
---|
.. | .. |
---|
1569 | 1582 | if (devinfo->handle == drive) |
---|
1570 | 1583 | unregister_cdrom(devinfo); |
---|
1571 | 1584 | drive->driver_data = NULL; |
---|
1572 | | - blk_queue_prep_rq(drive->queue, NULL); |
---|
| 1585 | + drive->prep_rq = NULL; |
---|
1573 | 1586 | g->private_data = NULL; |
---|
1574 | 1587 | put_disk(g); |
---|
1575 | 1588 | kfree(info); |
---|
.. | .. |
---|
1598 | 1611 | struct cdrom_info *info; |
---|
1599 | 1612 | int rc = -ENXIO; |
---|
1600 | 1613 | |
---|
1601 | | - check_disk_change(bdev); |
---|
| 1614 | + if (bdev_check_media_change(bdev)) { |
---|
| 1615 | + info = ide_drv_g(bdev->bd_disk, cdrom_info); |
---|
| 1616 | + |
---|
| 1617 | + ide_cd_read_toc(info->drive); |
---|
| 1618 | + } |
---|
1602 | 1619 | |
---|
1603 | 1620 | mutex_lock(&ide_cd_mutex); |
---|
1604 | 1621 | info = ide_cd_get(bdev->bd_disk); |
---|
.. | .. |
---|
1697 | 1714 | return ret; |
---|
1698 | 1715 | } |
---|
1699 | 1716 | |
---|
| 1717 | +static int idecd_locked_compat_ioctl(struct block_device *bdev, fmode_t mode, |
---|
| 1718 | + unsigned int cmd, unsigned long arg) |
---|
| 1719 | +{ |
---|
| 1720 | + struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); |
---|
| 1721 | + void __user *argp = compat_ptr(arg); |
---|
| 1722 | + int err; |
---|
| 1723 | + |
---|
| 1724 | + switch (cmd) { |
---|
| 1725 | + case CDROMSETSPINDOWN: |
---|
| 1726 | + return idecd_set_spindown(&info->devinfo, (unsigned long)argp); |
---|
| 1727 | + case CDROMGETSPINDOWN: |
---|
| 1728 | + return idecd_get_spindown(&info->devinfo, (unsigned long)argp); |
---|
| 1729 | + default: |
---|
| 1730 | + break; |
---|
| 1731 | + } |
---|
| 1732 | + |
---|
| 1733 | + err = generic_ide_ioctl(info->drive, bdev, cmd, arg); |
---|
| 1734 | + if (err == -EINVAL) |
---|
| 1735 | + err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, |
---|
| 1736 | + (unsigned long)argp); |
---|
| 1737 | + |
---|
| 1738 | + return err; |
---|
| 1739 | +} |
---|
| 1740 | + |
---|
| 1741 | +static int idecd_compat_ioctl(struct block_device *bdev, fmode_t mode, |
---|
| 1742 | + unsigned int cmd, unsigned long arg) |
---|
| 1743 | +{ |
---|
| 1744 | + int ret; |
---|
| 1745 | + |
---|
| 1746 | + mutex_lock(&ide_cd_mutex); |
---|
| 1747 | + ret = idecd_locked_compat_ioctl(bdev, mode, cmd, arg); |
---|
| 1748 | + mutex_unlock(&ide_cd_mutex); |
---|
| 1749 | + |
---|
| 1750 | + return ret; |
---|
| 1751 | +} |
---|
1700 | 1752 | |
---|
1701 | 1753 | static unsigned int idecd_check_events(struct gendisk *disk, |
---|
1702 | 1754 | unsigned int clearing) |
---|
.. | .. |
---|
1705 | 1757 | return cdrom_check_events(&info->devinfo, clearing); |
---|
1706 | 1758 | } |
---|
1707 | 1759 | |
---|
1708 | | -static int idecd_revalidate_disk(struct gendisk *disk) |
---|
1709 | | -{ |
---|
1710 | | - struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
---|
1711 | | - |
---|
1712 | | - ide_cd_read_toc(info->drive); |
---|
1713 | | - |
---|
1714 | | - return 0; |
---|
1715 | | -} |
---|
1716 | | - |
---|
1717 | 1760 | static const struct block_device_operations idecd_ops = { |
---|
1718 | 1761 | .owner = THIS_MODULE, |
---|
1719 | 1762 | .open = idecd_open, |
---|
1720 | 1763 | .release = idecd_release, |
---|
1721 | 1764 | .ioctl = idecd_ioctl, |
---|
| 1765 | + .compat_ioctl = IS_ENABLED(CONFIG_COMPAT) ? |
---|
| 1766 | + idecd_compat_ioctl : NULL, |
---|
1722 | 1767 | .check_events = idecd_check_events, |
---|
1723 | | - .revalidate_disk = idecd_revalidate_disk |
---|
1724 | 1768 | }; |
---|
1725 | 1769 | |
---|
1726 | 1770 | /* module options */ |
---|
.. | .. |
---|
1784 | 1828 | ide_cd_read_toc(drive); |
---|
1785 | 1829 | g->fops = &idecd_ops; |
---|
1786 | 1830 | g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE; |
---|
1787 | | - device_add_disk(&drive->gendev, g); |
---|
| 1831 | + g->events = DISK_EVENT_MEDIA_CHANGE; |
---|
| 1832 | + device_add_disk(&drive->gendev, g, NULL); |
---|
1788 | 1833 | return 0; |
---|
1789 | 1834 | |
---|
1790 | 1835 | out_free_disk: |
---|