diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 217 |
1 files changed, 1 insertions, 216 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index accf0d41d758..c9316859195e 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1381,7 +1381,7 @@ void msf_from_bcd (struct atapi_msf *msf) | |||
1381 | msf->frame = BCD2BIN(msf->frame); | 1381 | msf->frame = BCD2BIN(msf->frame); |
1382 | } | 1382 | } |
1383 | 1383 | ||
1384 | static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) | 1384 | int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) |
1385 | { | 1385 | { |
1386 | struct request req; | 1386 | struct request req; |
1387 | struct cdrom_info *info = drive->driver_data; | 1387 | struct cdrom_info *info = drive->driver_data; |
@@ -1402,85 +1402,6 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) | |||
1402 | return ide_cd_queue_pc(drive, &req); | 1402 | return ide_cd_queue_pc(drive, &req); |
1403 | } | 1403 | } |
1404 | 1404 | ||
1405 | /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ | ||
1406 | int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | ||
1407 | struct request_sense *sense) | ||
1408 | { | ||
1409 | struct cdrom_info *cd = drive->driver_data; | ||
1410 | struct request_sense my_sense; | ||
1411 | struct request req; | ||
1412 | int stat; | ||
1413 | |||
1414 | if (sense == NULL) | ||
1415 | sense = &my_sense; | ||
1416 | |||
1417 | /* If the drive cannot lock the door, just pretend. */ | ||
1418 | if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { | ||
1419 | stat = 0; | ||
1420 | } else { | ||
1421 | ide_cd_init_rq(drive, &req); | ||
1422 | req.sense = sense; | ||
1423 | req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; | ||
1424 | req.cmd[4] = lockflag ? 1 : 0; | ||
1425 | stat = ide_cd_queue_pc(drive, &req); | ||
1426 | } | ||
1427 | |||
1428 | /* If we got an illegal field error, the drive | ||
1429 | probably cannot lock the door. */ | ||
1430 | if (stat != 0 && | ||
1431 | sense->sense_key == ILLEGAL_REQUEST && | ||
1432 | (sense->asc == 0x24 || sense->asc == 0x20)) { | ||
1433 | printk (KERN_ERR "%s: door locking not supported\n", | ||
1434 | drive->name); | ||
1435 | cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK; | ||
1436 | stat = 0; | ||
1437 | } | ||
1438 | |||
1439 | /* no medium, that's alright. */ | ||
1440 | if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a) | ||
1441 | stat = 0; | ||
1442 | |||
1443 | if (stat == 0) { | ||
1444 | if (lockflag) | ||
1445 | cd->cd_flags |= IDE_CD_FLAG_DOOR_LOCKED; | ||
1446 | else | ||
1447 | cd->cd_flags &= ~IDE_CD_FLAG_DOOR_LOCKED; | ||
1448 | } | ||
1449 | |||
1450 | return stat; | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | /* Eject the disk if EJECTFLAG is 0. | ||
1455 | If EJECTFLAG is 1, try to reload the disk. */ | ||
1456 | static int cdrom_eject(ide_drive_t *drive, int ejectflag, | ||
1457 | struct request_sense *sense) | ||
1458 | { | ||
1459 | struct cdrom_info *cd = drive->driver_data; | ||
1460 | struct cdrom_device_info *cdi = &cd->devinfo; | ||
1461 | struct request req; | ||
1462 | char loej = 0x02; | ||
1463 | |||
1464 | if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag) | ||
1465 | return -EDRIVE_CANT_DO_THIS; | ||
1466 | |||
1467 | /* reload fails on some drives, if the tray is locked */ | ||
1468 | if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag) | ||
1469 | return 0; | ||
1470 | |||
1471 | ide_cd_init_rq(drive, &req); | ||
1472 | |||
1473 | /* only tell drive to close tray if open, if it can do that */ | ||
1474 | if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) | ||
1475 | loej = 0; | ||
1476 | |||
1477 | req.sense = sense; | ||
1478 | req.cmd[0] = GPCMD_START_STOP_UNIT; | ||
1479 | req.cmd[4] = loej | (ejectflag != 0); | ||
1480 | |||
1481 | return ide_cd_queue_pc(drive, &req); | ||
1482 | } | ||
1483 | |||
1484 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | 1405 | static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, |
1485 | unsigned long *sectors_per_frame, | 1406 | unsigned long *sectors_per_frame, |
1486 | struct request_sense *sense) | 1407 | struct request_sense *sense) |
@@ -1696,53 +1617,6 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) | |||
1696 | return 0; | 1617 | return 0; |
1697 | } | 1618 | } |
1698 | 1619 | ||
1699 | /* the generic packet interface to cdrom.c */ | ||
1700 | static int ide_cdrom_packet(struct cdrom_device_info *cdi, | ||
1701 | struct packet_command *cgc) | ||
1702 | { | ||
1703 | struct request req; | ||
1704 | ide_drive_t *drive = cdi->handle; | ||
1705 | |||
1706 | if (cgc->timeout <= 0) | ||
1707 | cgc->timeout = ATAPI_WAIT_PC; | ||
1708 | |||
1709 | /* here we queue the commands from the uniform CD-ROM | ||
1710 | layer. the packet must be complete, as we do not | ||
1711 | touch it at all. */ | ||
1712 | ide_cd_init_rq(drive, &req); | ||
1713 | memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); | ||
1714 | if (cgc->sense) | ||
1715 | memset(cgc->sense, 0, sizeof(struct request_sense)); | ||
1716 | req.data = cgc->buffer; | ||
1717 | req.data_len = cgc->buflen; | ||
1718 | req.timeout = cgc->timeout; | ||
1719 | |||
1720 | if (cgc->quiet) | ||
1721 | req.cmd_flags |= REQ_QUIET; | ||
1722 | |||
1723 | req.sense = cgc->sense; | ||
1724 | cgc->stat = ide_cd_queue_pc(drive, &req); | ||
1725 | if (!cgc->stat) | ||
1726 | cgc->buflen -= req.data_len; | ||
1727 | return cgc->stat; | ||
1728 | } | ||
1729 | |||
1730 | static | ||
1731 | int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position) | ||
1732 | { | ||
1733 | ide_drive_t *drive = cdi->handle; | ||
1734 | struct request_sense sense; | ||
1735 | |||
1736 | if (position) { | ||
1737 | int stat = ide_cd_lockdoor(drive, 0, &sense); | ||
1738 | |||
1739 | if (stat) | ||
1740 | return stat; | ||
1741 | } | ||
1742 | |||
1743 | return cdrom_eject(drive, !position, &sense); | ||
1744 | } | ||
1745 | |||
1746 | int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) | 1620 | int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) |
1747 | { | 1621 | { |
1748 | struct cdrom_info *info = drive->driver_data; | 1622 | struct cdrom_info *info = drive->driver_data; |
@@ -1782,95 +1656,6 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) | |||
1782 | cd->max_speed = (maxspeed + (176/2)) / 176; | 1656 | cd->max_speed = (maxspeed + (176/2)) / 176; |
1783 | } | 1657 | } |
1784 | 1658 | ||
1785 | /* | ||
1786 | * add logic to try GET_EVENT command first to check for media and tray | ||
1787 | * status. this should be supported by newer cd-r/w and all DVD etc | ||
1788 | * drives | ||
1789 | */ | ||
1790 | static | ||
1791 | int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr) | ||
1792 | { | ||
1793 | ide_drive_t *drive = cdi->handle; | ||
1794 | struct media_event_desc med; | ||
1795 | struct request_sense sense; | ||
1796 | int stat; | ||
1797 | |||
1798 | if (slot_nr != CDSL_CURRENT) | ||
1799 | return -EINVAL; | ||
1800 | |||
1801 | stat = cdrom_check_status(drive, &sense); | ||
1802 | if (!stat || sense.sense_key == UNIT_ATTENTION) | ||
1803 | return CDS_DISC_OK; | ||
1804 | |||
1805 | if (!cdrom_get_media_event(cdi, &med)) { | ||
1806 | if (med.media_present) | ||
1807 | return CDS_DISC_OK; | ||
1808 | else if (med.door_open) | ||
1809 | return CDS_TRAY_OPEN; | ||
1810 | else | ||
1811 | return CDS_NO_DISC; | ||
1812 | } | ||
1813 | |||
1814 | if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04) | ||
1815 | return CDS_DISC_OK; | ||
1816 | |||
1817 | /* | ||
1818 | * If not using Mt Fuji extended media tray reports, | ||
1819 | * just return TRAY_OPEN since ATAPI doesn't provide | ||
1820 | * any other way to detect this... | ||
1821 | */ | ||
1822 | if (sense.sense_key == NOT_READY) { | ||
1823 | if (sense.asc == 0x3a && sense.ascq == 1) | ||
1824 | return CDS_NO_DISC; | ||
1825 | else | ||
1826 | return CDS_TRAY_OPEN; | ||
1827 | } | ||
1828 | return CDS_DRIVE_NOT_READY; | ||
1829 | } | ||
1830 | |||
1831 | /**************************************************************************** | ||
1832 | * Other driver requests (open, close, check media change). | ||
1833 | */ | ||
1834 | |||
1835 | static | ||
1836 | int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi, | ||
1837 | int slot_nr) | ||
1838 | { | ||
1839 | ide_drive_t *drive = cdi->handle; | ||
1840 | struct cdrom_info *cd = drive->driver_data; | ||
1841 | int retval; | ||
1842 | |||
1843 | if (slot_nr == CDSL_CURRENT) { | ||
1844 | (void) cdrom_check_status(drive, NULL); | ||
1845 | retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0; | ||
1846 | cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED; | ||
1847 | return retval; | ||
1848 | } else { | ||
1849 | return -EINVAL; | ||
1850 | } | ||
1851 | } | ||
1852 | |||
1853 | |||
1854 | static | ||
1855 | int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose) | ||
1856 | { | ||
1857 | return 0; | ||
1858 | } | ||
1859 | |||
1860 | /* | ||
1861 | * Close down the device. Invalidate all cached blocks. | ||
1862 | */ | ||
1863 | |||
1864 | static | ||
1865 | void ide_cdrom_release_real (struct cdrom_device_info *cdi) | ||
1866 | { | ||
1867 | ide_drive_t *drive = cdi->handle; | ||
1868 | struct cdrom_info *cd = drive->driver_data; | ||
1869 | |||
1870 | if (!cdi->use_count) | ||
1871 | cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; | ||
1872 | } | ||
1873 | |||
1874 | #define IDE_CD_CAPABILITIES \ | 1659 | #define IDE_CD_CAPABILITIES \ |
1875 | (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \ | 1660 | (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \ |
1876 | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \ | 1661 | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \ |