aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-cd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r--drivers/ide/ide-cd.c271
1 files changed, 7 insertions, 264 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index b82cabfda63e..1032bec54ee6 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -206,7 +206,7 @@ void cdrom_analyze_sense_data(ide_drive_t *drive,
206/* 206/*
207 * Initialize a ide-cd packet command request 207 * Initialize a ide-cd packet command request
208 */ 208 */
209static void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) 209void ide_cd_init_rq(ide_drive_t *drive, struct request *rq)
210{ 210{
211 struct cdrom_info *cd = drive->driver_data; 211 struct cdrom_info *cd = drive->driver_data;
212 212
@@ -1168,7 +1168,7 @@ static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1168 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation); 1168 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
1169} 1169}
1170 1170
1171static int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) 1171int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq)
1172{ 1172{
1173 struct request_sense sense; 1173 struct request_sense sense;
1174 int retries = 10; 1174 int retries = 10;
@@ -1685,8 +1685,8 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1685} 1685}
1686 1686
1687/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ 1687/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
1688static int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, 1688int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
1689 struct request_sense *sense) 1689 struct request_sense *sense)
1690{ 1690{
1691 struct cdrom_info *cd = drive->driver_data; 1691 struct cdrom_info *cd = drive->driver_data;
1692 struct request_sense my_sense; 1692 struct request_sense my_sense;
@@ -1817,9 +1817,8 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
1817 return ide_cd_queue_pc(drive, &req); 1817 return ide_cd_queue_pc(drive, &req);
1818} 1818}
1819 1819
1820
1821/* Try to read the entire TOC for the disk into our internal buffer. */ 1820/* Try to read the entire TOC for the disk into our internal buffer. */
1822static int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) 1821int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1823{ 1822{
1824 int stat, ntracks, i; 1823 int stat, ntracks, i;
1825 struct cdrom_info *info = drive->driver_data; 1824 struct cdrom_info *info = drive->driver_data;
@@ -1979,112 +1978,6 @@ static int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
1979 return 0; 1978 return 0;
1980} 1979}
1981 1980
1982static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
1983{
1984 struct cdrom_info *cd = drive->driver_data;
1985 struct cdrom_tochdr *tochdr = arg;
1986 struct atapi_toc *toc;
1987 int stat;
1988
1989 /* Make sure our saved TOC is valid. */
1990 stat = ide_cd_read_toc(drive, NULL);
1991 if (stat)
1992 return stat;
1993
1994 toc = cd->toc;
1995 tochdr->cdth_trk0 = toc->hdr.first_track;
1996 tochdr->cdth_trk1 = toc->hdr.last_track;
1997
1998 return 0;
1999}
2000
2001static int ide_cd_get_toc_entry(ide_drive_t *drive, int track,
2002 struct atapi_toc_entry **ent)
2003{
2004 struct cdrom_info *info = drive->driver_data;
2005 struct atapi_toc *toc = info->toc;
2006 int ntracks;
2007
2008 /*
2009 * don't serve cached data, if the toc isn't valid
2010 */
2011 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0)
2012 return -EINVAL;
2013
2014 /* Check validity of requested track number. */
2015 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2016
2017 if (toc->hdr.first_track == CDROM_LEADOUT)
2018 ntracks = 0;
2019
2020 if (track == CDROM_LEADOUT)
2021 *ent = &toc->ent[ntracks];
2022 else if (track < toc->hdr.first_track || track > toc->hdr.last_track)
2023 return -EINVAL;
2024 else
2025 *ent = &toc->ent[track - toc->hdr.first_track];
2026
2027 return 0;
2028}
2029
2030static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg)
2031{
2032 struct cdrom_tocentry *tocentry = arg;
2033 struct atapi_toc_entry *toce;
2034 int stat;
2035
2036 stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce);
2037 if (stat)
2038 return stat;
2039
2040 tocentry->cdte_ctrl = toce->control;
2041 tocentry->cdte_adr = toce->adr;
2042 if (tocentry->cdte_format == CDROM_MSF) {
2043 lba_to_msf(toce->addr.lba,
2044 &tocentry->cdte_addr.msf.minute,
2045 &tocentry->cdte_addr.msf.second,
2046 &tocentry->cdte_addr.msf.frame);
2047 } else
2048 tocentry->cdte_addr.lba = toce->addr.lba;
2049
2050 return 0;
2051}
2052
2053static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
2054{
2055 struct cdrom_ti *ti = arg;
2056 struct atapi_toc_entry *first_toc, *last_toc;
2057 unsigned long lba_start, lba_end;
2058 int stat;
2059 struct request rq;
2060 struct request_sense sense;
2061
2062 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
2063 if (stat)
2064 return stat;
2065
2066 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
2067 if (stat)
2068 return stat;
2069
2070 if (ti->cdti_trk1 != CDROM_LEADOUT)
2071 ++last_toc;
2072 lba_start = first_toc->addr.lba;
2073 lba_end = last_toc->addr.lba;
2074
2075 if (lba_end <= lba_start)
2076 return -EINVAL;
2077
2078 ide_cd_init_rq(drive, &rq);
2079
2080 rq.sense = &sense;
2081 rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2082 lba_to_msf(lba_start, &rq.cmd[3], &rq.cmd[4], &rq.cmd[5]);
2083 lba_to_msf(lba_end - 1, &rq.cmd[6], &rq.cmd[7], &rq.cmd[8]);
2084
2085 return ide_cd_queue_pc(drive, &rq);
2086}
2087
2088/* the generic packet interface to cdrom.c */ 1981/* the generic packet interface to cdrom.c */
2089static int ide_cdrom_packet(struct cdrom_device_info *cdi, 1982static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2090 struct packet_command *cgc) 1983 struct packet_command *cgc)
@@ -2116,52 +2009,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2116 return cgc->stat; 2009 return cgc->stat;
2117} 2010}
2118 2011
2119static int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi,
2120 unsigned int cmd, void *arg)
2121{
2122 ide_drive_t *drive = cdi->handle;
2123
2124 switch (cmd) {
2125 /*
2126 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
2127 * atapi doesn't support it
2128 */
2129 case CDROMPLAYTRKIND:
2130 return ide_cd_fake_play_trkind(drive, arg);
2131 case CDROMREADTOCHDR:
2132 return ide_cd_read_tochdr(drive, arg);
2133 case CDROMREADTOCENTRY:
2134 return ide_cd_read_tocentry(drive, arg);
2135 default:
2136 return -EINVAL;
2137 }
2138}
2139
2140static
2141int ide_cdrom_reset (struct cdrom_device_info *cdi)
2142{
2143 ide_drive_t *drive = cdi->handle;
2144 struct cdrom_info *cd = drive->driver_data;
2145 struct request_sense sense;
2146 struct request req;
2147 int ret;
2148
2149 ide_cd_init_rq(drive, &req);
2150 req.cmd_type = REQ_TYPE_SPECIAL;
2151 req.cmd_flags = REQ_QUIET;
2152 ret = ide_do_drive_cmd(drive, &req, ide_wait);
2153
2154 /*
2155 * A reset will unlock the door. If it was previously locked,
2156 * lock it again.
2157 */
2158 if (cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED)
2159 (void)ide_cd_lockdoor(drive, 1, &sense);
2160
2161 return ret;
2162}
2163
2164
2165static 2012static
2166int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position) 2013int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2167{ 2014{
@@ -2178,15 +2025,7 @@ int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2178 return cdrom_eject(drive, !position, &sense); 2025 return cdrom_eject(drive, !position, &sense);
2179} 2026}
2180 2027
2181static 2028int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
2182int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2183{
2184 ide_drive_t *drive = cdi->handle;
2185
2186 return ide_cd_lockdoor(drive, lock, NULL);
2187}
2188
2189static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
2190{ 2029{
2191 struct cdrom_info *info = drive->driver_data; 2030 struct cdrom_info *info = drive->driver_data;
2192 struct cdrom_device_info *cdi = &info->devinfo; 2031 struct cdrom_device_info *cdi = &info->devinfo;
@@ -2205,7 +2044,7 @@ static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
2205 return stat; 2044 return stat;
2206} 2045}
2207 2046
2208static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) 2047void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
2209{ 2048{
2210 struct cdrom_info *cd = drive->driver_data; 2049 struct cdrom_info *cd = drive->driver_data;
2211 u16 curspeed, maxspeed; 2050 u16 curspeed, maxspeed;
@@ -2226,49 +2065,6 @@ static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
2226} 2065}
2227 2066
2228/* 2067/*
2229 * ATAPI devices are free to select the speed you request or any slower
2230 * rate. :-( Requesting too fast a speed will _not_ produce an error.
2231 */
2232static int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
2233{
2234 ide_drive_t *drive = cdi->handle;
2235 struct cdrom_info *cd = drive->driver_data;
2236 struct request rq;
2237 struct request_sense sense;
2238 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
2239 int stat;
2240
2241 ide_cd_init_rq(drive, &rq);
2242
2243 rq.sense = &sense;
2244
2245 if (speed == 0)
2246 speed = 0xffff; /* set to max */
2247 else
2248 speed *= 177; /* Nx to kbytes/s */
2249
2250 rq.cmd[0] = GPCMD_SET_SPEED;
2251 /* Read Drive speed in kbytes/second MSB/LSB */
2252 rq.cmd[2] = (speed >> 8) & 0xff;
2253 rq.cmd[3] = speed & 0xff;
2254 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
2255 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
2256 /* Write Drive speed in kbytes/second MSB/LSB */
2257 rq.cmd[4] = (speed >> 8) & 0xff;
2258 rq.cmd[5] = speed & 0xff;
2259 }
2260
2261 stat = ide_cd_queue_pc(drive, &rq);
2262
2263 if (!ide_cdrom_get_capabilities(drive, buf)) {
2264 ide_cdrom_update_speed(drive, buf);
2265 cdi->speed = cd->current_speed;
2266 }
2267
2268 return 0;
2269}
2270
2271/*
2272 * add logic to try GET_EVENT command first to check for media and tray 2068 * add logic to try GET_EVENT command first to check for media and tray
2273 * status. this should be supported by newer cd-r/w and all DVD etc 2069 * status. this should be supported by newer cd-r/w and all DVD etc
2274 * drives 2070 * drives
@@ -2314,59 +2110,6 @@ int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2314 return CDS_DRIVE_NOT_READY; 2110 return CDS_DRIVE_NOT_READY;
2315} 2111}
2316 2112
2317static
2318int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2319 struct cdrom_multisession *ms_info)
2320{
2321 struct atapi_toc *toc;
2322 ide_drive_t *drive = cdi->handle;
2323 struct cdrom_info *info = drive->driver_data;
2324 struct request_sense sense;
2325 int ret;
2326
2327 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || !info->toc) {
2328 ret = ide_cd_read_toc(drive, &sense);
2329 if (ret)
2330 return ret;
2331 }
2332
2333 toc = info->toc;
2334 ms_info->addr.lba = toc->last_session_lba;
2335 ms_info->xa_flag = toc->xa_flag;
2336
2337 return 0;
2338}
2339
2340static int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
2341 struct cdrom_mcn *mcn_info)
2342{
2343 ide_drive_t *drive = cdi->handle;
2344 int stat, mcnlen;
2345 struct request rq;
2346 char buf[24];
2347
2348 ide_cd_init_rq(drive, &rq);
2349
2350 rq.data = buf;
2351 rq.data_len = sizeof(buf);
2352
2353 rq.cmd[0] = GPCMD_READ_SUBCHANNEL;
2354 rq.cmd[1] = 2; /* MSF addressing */
2355 rq.cmd[2] = 0x40; /* request subQ data */
2356 rq.cmd[3] = 2; /* format */
2357 rq.cmd[8] = sizeof(buf);
2358
2359 stat = ide_cd_queue_pc(drive, &rq);
2360 if (stat)
2361 return stat;
2362
2363 mcnlen = sizeof(mcn_info->medium_catalog_number) - 1;
2364 memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen);
2365 mcn_info->medium_catalog_number[mcnlen] = '\0';
2366
2367 return 0;
2368}
2369
2370/**************************************************************************** 2113/****************************************************************************
2371 * Other driver requests (open, close, check media change). 2114 * Other driver requests (open, close, check media change).
2372 */ 2115 */