diff options
author | Borislav Petkov <bbpetkov@yahoo.de> | 2008-02-01 17:09:29 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-02-01 17:09:29 -0500 |
commit | f9afd18b5827be93fd9fb3cc84ab9bba38b00db8 (patch) | |
tree | 5bf5a34a970720f6e3856e0a1c2bbf7015520a2f /drivers/ide | |
parent | d554336514a63342c2e4b06b4287ad93c112b00f (diff) |
ide-cd: move the remaining cdrom.c ioctl handling code to ide-cd_ioctl.c
There should be no functional changes from this.
Signed-off-by: Borislav Petkov <bbpetkov@yahoo.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-cd.c | 217 | ||||
-rw-r--r-- | drivers/ide/ide-cd.h | 8 | ||||
-rw-r--r-- | drivers/ide/ide-cd_ioctl.c | 210 |
3 files changed, 218 insertions, 217 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 | \ |
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 5343063e83f6..58ae663425a8 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h | |||
@@ -151,12 +151,17 @@ void ide_cd_log_error(const char *, struct request *, struct request_sense *); | |||
151 | /* ide-cd.c functions used by ide-cd_ioctl.c */ | 151 | /* ide-cd.c functions used by ide-cd_ioctl.c */ |
152 | void ide_cd_init_rq(ide_drive_t *, struct request *); | 152 | void ide_cd_init_rq(ide_drive_t *, struct request *); |
153 | int ide_cd_queue_pc(ide_drive_t *, struct request *); | 153 | int ide_cd_queue_pc(ide_drive_t *, struct request *); |
154 | int ide_cd_lockdoor(ide_drive_t *, int, struct request_sense *); | ||
155 | int ide_cd_read_toc(ide_drive_t *, struct request_sense *); | 154 | int ide_cd_read_toc(ide_drive_t *, struct request_sense *); |
156 | int ide_cdrom_get_capabilities(ide_drive_t *, u8 *); | 155 | int ide_cdrom_get_capabilities(ide_drive_t *, u8 *); |
157 | void ide_cdrom_update_speed(ide_drive_t *, u8 *); | 156 | void ide_cdrom_update_speed(ide_drive_t *, u8 *); |
157 | int cdrom_check_status(ide_drive_t *, struct request_sense *); | ||
158 | 158 | ||
159 | /* ide-cd_ioctl.c */ | 159 | /* ide-cd_ioctl.c */ |
160 | int ide_cdrom_open_real(struct cdrom_device_info *, int); | ||
161 | void ide_cdrom_release_real(struct cdrom_device_info *); | ||
162 | int ide_cdrom_drive_status(struct cdrom_device_info *, int); | ||
163 | int ide_cdrom_check_media_change_real(struct cdrom_device_info *, int); | ||
164 | int ide_cdrom_tray_move(struct cdrom_device_info *, int); | ||
160 | int ide_cdrom_lock_door(struct cdrom_device_info *, int); | 165 | int ide_cdrom_lock_door(struct cdrom_device_info *, int); |
161 | int ide_cdrom_select_speed(struct cdrom_device_info *, int); | 166 | int ide_cdrom_select_speed(struct cdrom_device_info *, int); |
162 | int ide_cdrom_get_last_session(struct cdrom_device_info *, | 167 | int ide_cdrom_get_last_session(struct cdrom_device_info *, |
@@ -164,5 +169,6 @@ int ide_cdrom_get_last_session(struct cdrom_device_info *, | |||
164 | int ide_cdrom_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *); | 169 | int ide_cdrom_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *); |
165 | int ide_cdrom_reset(struct cdrom_device_info *cdi); | 170 | int ide_cdrom_reset(struct cdrom_device_info *cdi); |
166 | int ide_cdrom_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); | 171 | int ide_cdrom_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); |
172 | int ide_cdrom_packet(struct cdrom_device_info *, struct packet_command *); | ||
167 | 173 | ||
168 | #endif /* _IDE_CD_H */ | 174 | #endif /* _IDE_CD_H */ |
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index ec698c44e8bf..b68284de4e85 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c | |||
@@ -9,9 +9,188 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/cdrom.h> | 10 | #include <linux/cdrom.h> |
11 | #include <linux/ide.h> | 11 | #include <linux/ide.h> |
12 | #include <scsi/scsi.h> | ||
12 | 13 | ||
13 | #include "ide-cd.h" | 14 | #include "ide-cd.h" |
14 | 15 | ||
16 | /**************************************************************************** | ||
17 | * Other driver requests (open, close, check media change). | ||
18 | */ | ||
19 | int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose) | ||
20 | { | ||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | /* | ||
25 | * Close down the device. Invalidate all cached blocks. | ||
26 | */ | ||
27 | void ide_cdrom_release_real(struct cdrom_device_info *cdi) | ||
28 | { | ||
29 | ide_drive_t *drive = cdi->handle; | ||
30 | struct cdrom_info *cd = drive->driver_data; | ||
31 | |||
32 | if (!cdi->use_count) | ||
33 | cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * add logic to try GET_EVENT command first to check for media and tray | ||
38 | * status. this should be supported by newer cd-r/w and all DVD etc | ||
39 | * drives | ||
40 | */ | ||
41 | int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr) | ||
42 | { | ||
43 | ide_drive_t *drive = cdi->handle; | ||
44 | struct media_event_desc med; | ||
45 | struct request_sense sense; | ||
46 | int stat; | ||
47 | |||
48 | if (slot_nr != CDSL_CURRENT) | ||
49 | return -EINVAL; | ||
50 | |||
51 | stat = cdrom_check_status(drive, &sense); | ||
52 | if (!stat || sense.sense_key == UNIT_ATTENTION) | ||
53 | return CDS_DISC_OK; | ||
54 | |||
55 | if (!cdrom_get_media_event(cdi, &med)) { | ||
56 | if (med.media_present) | ||
57 | return CDS_DISC_OK; | ||
58 | else if (med.door_open) | ||
59 | return CDS_TRAY_OPEN; | ||
60 | else | ||
61 | return CDS_NO_DISC; | ||
62 | } | ||
63 | |||
64 | if (sense.sense_key == NOT_READY && sense.asc == 0x04 | ||
65 | && sense.ascq == 0x04) | ||
66 | return CDS_DISC_OK; | ||
67 | |||
68 | /* | ||
69 | * If not using Mt Fuji extended media tray reports, | ||
70 | * just return TRAY_OPEN since ATAPI doesn't provide | ||
71 | * any other way to detect this... | ||
72 | */ | ||
73 | if (sense.sense_key == NOT_READY) { | ||
74 | if (sense.asc == 0x3a && sense.ascq == 1) | ||
75 | return CDS_NO_DISC; | ||
76 | else | ||
77 | return CDS_TRAY_OPEN; | ||
78 | } | ||
79 | return CDS_DRIVE_NOT_READY; | ||
80 | } | ||
81 | |||
82 | int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, | ||
83 | int slot_nr) | ||
84 | { | ||
85 | ide_drive_t *drive = cdi->handle; | ||
86 | struct cdrom_info *cd = drive->driver_data; | ||
87 | int retval; | ||
88 | |||
89 | if (slot_nr == CDSL_CURRENT) { | ||
90 | (void) cdrom_check_status(drive, NULL); | ||
91 | retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0; | ||
92 | cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED; | ||
93 | return retval; | ||
94 | } else { | ||
95 | return -EINVAL; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | /* Eject the disk if EJECTFLAG is 0. | ||
100 | If EJECTFLAG is 1, try to reload the disk. */ | ||
101 | static | ||
102 | int cdrom_eject(ide_drive_t *drive, int ejectflag, | ||
103 | struct request_sense *sense) | ||
104 | { | ||
105 | struct cdrom_info *cd = drive->driver_data; | ||
106 | struct cdrom_device_info *cdi = &cd->devinfo; | ||
107 | struct request req; | ||
108 | char loej = 0x02; | ||
109 | |||
110 | if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag) | ||
111 | return -EDRIVE_CANT_DO_THIS; | ||
112 | |||
113 | /* reload fails on some drives, if the tray is locked */ | ||
114 | if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag) | ||
115 | return 0; | ||
116 | |||
117 | ide_cd_init_rq(drive, &req); | ||
118 | |||
119 | /* only tell drive to close tray if open, if it can do that */ | ||
120 | if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) | ||
121 | loej = 0; | ||
122 | |||
123 | req.sense = sense; | ||
124 | req.cmd[0] = GPCMD_START_STOP_UNIT; | ||
125 | req.cmd[4] = loej | (ejectflag != 0); | ||
126 | |||
127 | return ide_cd_queue_pc(drive, &req); | ||
128 | } | ||
129 | |||
130 | /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ | ||
131 | static | ||
132 | int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, | ||
133 | struct request_sense *sense) | ||
134 | { | ||
135 | struct cdrom_info *cd = drive->driver_data; | ||
136 | struct request_sense my_sense; | ||
137 | struct request req; | ||
138 | int stat; | ||
139 | |||
140 | if (sense == NULL) | ||
141 | sense = &my_sense; | ||
142 | |||
143 | /* If the drive cannot lock the door, just pretend. */ | ||
144 | if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { | ||
145 | stat = 0; | ||
146 | } else { | ||
147 | ide_cd_init_rq(drive, &req); | ||
148 | req.sense = sense; | ||
149 | req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; | ||
150 | req.cmd[4] = lockflag ? 1 : 0; | ||
151 | stat = ide_cd_queue_pc(drive, &req); | ||
152 | } | ||
153 | |||
154 | /* If we got an illegal field error, the drive | ||
155 | probably cannot lock the door. */ | ||
156 | if (stat != 0 && | ||
157 | sense->sense_key == ILLEGAL_REQUEST && | ||
158 | (sense->asc == 0x24 || sense->asc == 0x20)) { | ||
159 | printk(KERN_ERR "%s: door locking not supported\n", | ||
160 | drive->name); | ||
161 | cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK; | ||
162 | stat = 0; | ||
163 | } | ||
164 | |||
165 | /* no medium, that's alright. */ | ||
166 | if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a) | ||
167 | stat = 0; | ||
168 | |||
169 | if (stat == 0) { | ||
170 | if (lockflag) | ||
171 | cd->cd_flags |= IDE_CD_FLAG_DOOR_LOCKED; | ||
172 | else | ||
173 | cd->cd_flags &= ~IDE_CD_FLAG_DOOR_LOCKED; | ||
174 | } | ||
175 | |||
176 | return stat; | ||
177 | } | ||
178 | |||
179 | int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position) | ||
180 | { | ||
181 | ide_drive_t *drive = cdi->handle; | ||
182 | struct request_sense sense; | ||
183 | |||
184 | if (position) { | ||
185 | int stat = ide_cd_lockdoor(drive, 0, &sense); | ||
186 | |||
187 | if (stat) | ||
188 | return stat; | ||
189 | } | ||
190 | |||
191 | return cdrom_eject(drive, !position, &sense); | ||
192 | } | ||
193 | |||
15 | int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock) | 194 | int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock) |
16 | { | 195 | { |
17 | ide_drive_t *drive = cdi->handle; | 196 | ide_drive_t *drive = cdi->handle; |
@@ -263,3 +442,34 @@ int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, | |||
263 | return -EINVAL; | 442 | return -EINVAL; |
264 | } | 443 | } |
265 | } | 444 | } |
445 | |||
446 | /* the generic packet interface to cdrom.c */ | ||
447 | int ide_cdrom_packet(struct cdrom_device_info *cdi, | ||
448 | struct packet_command *cgc) | ||
449 | { | ||
450 | struct request req; | ||
451 | ide_drive_t *drive = cdi->handle; | ||
452 | |||
453 | if (cgc->timeout <= 0) | ||
454 | cgc->timeout = ATAPI_WAIT_PC; | ||
455 | |||
456 | /* here we queue the commands from the uniform CD-ROM | ||
457 | layer. the packet must be complete, as we do not | ||
458 | touch it at all. */ | ||
459 | ide_cd_init_rq(drive, &req); | ||
460 | memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); | ||
461 | if (cgc->sense) | ||
462 | memset(cgc->sense, 0, sizeof(struct request_sense)); | ||
463 | req.data = cgc->buffer; | ||
464 | req.data_len = cgc->buflen; | ||
465 | req.timeout = cgc->timeout; | ||
466 | |||
467 | if (cgc->quiet) | ||
468 | req.cmd_flags |= REQ_QUIET; | ||
469 | |||
470 | req.sense = cgc->sense; | ||
471 | cgc->stat = ide_cd_queue_pc(drive, &req); | ||
472 | if (!cgc->stat) | ||
473 | cgc->buflen -= req.data_len; | ||
474 | return cgc->stat; | ||
475 | } | ||