ide-cd_ioctl.c revision b348487f0dc06f09a4c0d9e353eaa66e70230c7d
1/* 2 * cdrom.c IOCTLs handling for ide-cd driver. 3 * 4 * Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov> 5 * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> 6 * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de> 7 */ 8 9#include <linux/kernel.h> 10#include <linux/cdrom.h> 11#include <linux/ide.h> 12#include <scsi/scsi.h> 13 14#include "ide-cd.h" 15 16/**************************************************************************** 17 * Other driver requests (open, close, check media change). 18 */ 19int 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 */ 27void 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 */ 41int 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 82int 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. */ 101static 102int 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. */ 131static 132int 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 179int 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 194int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock) 195{ 196 ide_drive_t *drive = cdi->handle; 197 198 return ide_cd_lockdoor(drive, lock, NULL); 199} 200 201/* 202 * ATAPI devices are free to select the speed you request or any slower 203 * rate. :-( Requesting too fast a speed will _not_ produce an error. 204 */ 205int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed) 206{ 207 ide_drive_t *drive = cdi->handle; 208 struct cdrom_info *cd = drive->driver_data; 209 struct request rq; 210 struct request_sense sense; 211 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; 212 int stat; 213 214 ide_cd_init_rq(drive, &rq); 215 216 rq.sense = &sense; 217 218 if (speed == 0) 219 speed = 0xffff; /* set to max */ 220 else 221 speed *= 177; /* Nx to kbytes/s */ 222 223 rq.cmd[0] = GPCMD_SET_SPEED; 224 /* Read Drive speed in kbytes/second MSB/LSB */ 225 rq.cmd[2] = (speed >> 8) & 0xff; 226 rq.cmd[3] = speed & 0xff; 227 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != 228 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { 229 /* Write Drive speed in kbytes/second MSB/LSB */ 230 rq.cmd[4] = (speed >> 8) & 0xff; 231 rq.cmd[5] = speed & 0xff; 232 } 233 234 stat = ide_cd_queue_pc(drive, &rq); 235 236 if (!ide_cdrom_get_capabilities(drive, buf)) { 237 ide_cdrom_update_speed(drive, buf); 238 cdi->speed = cd->current_speed; 239 } 240 241 return 0; 242} 243 244int ide_cdrom_get_last_session(struct cdrom_device_info *cdi, 245 struct cdrom_multisession *ms_info) 246{ 247 struct atapi_toc *toc; 248 ide_drive_t *drive = cdi->handle; 249 struct cdrom_info *info = drive->driver_data; 250 struct request_sense sense; 251 int ret; 252 253 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || !info->toc) { 254 ret = ide_cd_read_toc(drive, &sense); 255 if (ret) 256 return ret; 257 } 258 259 toc = info->toc; 260 ms_info->addr.lba = toc->last_session_lba; 261 ms_info->xa_flag = toc->xa_flag; 262 263 return 0; 264} 265 266int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, 267 struct cdrom_mcn *mcn_info) 268{ 269 ide_drive_t *drive = cdi->handle; 270 int stat, mcnlen; 271 struct request rq; 272 char buf[24]; 273 274 ide_cd_init_rq(drive, &rq); 275 276 rq.data = buf; 277 rq.data_len = sizeof(buf); 278 279 rq.cmd[0] = GPCMD_READ_SUBCHANNEL; 280 rq.cmd[1] = 2; /* MSF addressing */ 281 rq.cmd[2] = 0x40; /* request subQ data */ 282 rq.cmd[3] = 2; /* format */ 283 rq.cmd[8] = sizeof(buf); 284 285 stat = ide_cd_queue_pc(drive, &rq); 286 if (stat) 287 return stat; 288 289 mcnlen = sizeof(mcn_info->medium_catalog_number) - 1; 290 memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen); 291 mcn_info->medium_catalog_number[mcnlen] = '\0'; 292 293 return 0; 294} 295 296int ide_cdrom_reset(struct cdrom_device_info *cdi) 297{ 298 ide_drive_t *drive = cdi->handle; 299 struct cdrom_info *cd = drive->driver_data; 300 struct request_sense sense; 301 struct request req; 302 int ret; 303 304 ide_cd_init_rq(drive, &req); 305 req.cmd_type = REQ_TYPE_SPECIAL; 306 req.cmd_flags = REQ_QUIET; 307 ret = ide_do_drive_cmd(drive, &req, ide_wait); 308 309 /* 310 * A reset will unlock the door. If it was previously locked, 311 * lock it again. 312 */ 313 if (cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) 314 (void)ide_cd_lockdoor(drive, 1, &sense); 315 316 return ret; 317} 318 319static int ide_cd_get_toc_entry(ide_drive_t *drive, int track, 320 struct atapi_toc_entry **ent) 321{ 322 struct cdrom_info *info = drive->driver_data; 323 struct atapi_toc *toc = info->toc; 324 int ntracks; 325 326 /* 327 * don't serve cached data, if the toc isn't valid 328 */ 329 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0) 330 return -EINVAL; 331 332 /* Check validity of requested track number. */ 333 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; 334 335 if (toc->hdr.first_track == CDROM_LEADOUT) 336 ntracks = 0; 337 338 if (track == CDROM_LEADOUT) 339 *ent = &toc->ent[ntracks]; 340 else if (track < toc->hdr.first_track || track > toc->hdr.last_track) 341 return -EINVAL; 342 else 343 *ent = &toc->ent[track - toc->hdr.first_track]; 344 345 return 0; 346} 347 348static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) 349{ 350 struct cdrom_ti *ti = arg; 351 struct atapi_toc_entry *first_toc, *last_toc; 352 unsigned long lba_start, lba_end; 353 int stat; 354 struct request rq; 355 struct request_sense sense; 356 357 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc); 358 if (stat) 359 return stat; 360 361 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc); 362 if (stat) 363 return stat; 364 365 if (ti->cdti_trk1 != CDROM_LEADOUT) 366 ++last_toc; 367 lba_start = first_toc->addr.lba; 368 lba_end = last_toc->addr.lba; 369 370 if (lba_end <= lba_start) 371 return -EINVAL; 372 373 ide_cd_init_rq(drive, &rq); 374 375 rq.sense = &sense; 376 rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF; 377 lba_to_msf(lba_start, &rq.cmd[3], &rq.cmd[4], &rq.cmd[5]); 378 lba_to_msf(lba_end - 1, &rq.cmd[6], &rq.cmd[7], &rq.cmd[8]); 379 380 return ide_cd_queue_pc(drive, &rq); 381} 382 383static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) 384{ 385 struct cdrom_info *cd = drive->driver_data; 386 struct cdrom_tochdr *tochdr = arg; 387 struct atapi_toc *toc; 388 int stat; 389 390 /* Make sure our saved TOC is valid. */ 391 stat = ide_cd_read_toc(drive, NULL); 392 if (stat) 393 return stat; 394 395 toc = cd->toc; 396 tochdr->cdth_trk0 = toc->hdr.first_track; 397 tochdr->cdth_trk1 = toc->hdr.last_track; 398 399 return 0; 400} 401 402static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg) 403{ 404 struct cdrom_tocentry *tocentry = arg; 405 struct atapi_toc_entry *toce; 406 int stat; 407 408 stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce); 409 if (stat) 410 return stat; 411 412 tocentry->cdte_ctrl = toce->control; 413 tocentry->cdte_adr = toce->adr; 414 if (tocentry->cdte_format == CDROM_MSF) { 415 lba_to_msf(toce->addr.lba, 416 &tocentry->cdte_addr.msf.minute, 417 &tocentry->cdte_addr.msf.second, 418 &tocentry->cdte_addr.msf.frame); 419 } else 420 tocentry->cdte_addr.lba = toce->addr.lba; 421 422 return 0; 423} 424 425int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, 426 unsigned int cmd, void *arg) 427{ 428 ide_drive_t *drive = cdi->handle; 429 430 switch (cmd) { 431 /* 432 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since 433 * atapi doesn't support it 434 */ 435 case CDROMPLAYTRKIND: 436 return ide_cd_fake_play_trkind(drive, arg); 437 case CDROMREADTOCHDR: 438 return ide_cd_read_tochdr(drive, arg); 439 case CDROMREADTOCENTRY: 440 return ide_cd_read_tocentry(drive, arg); 441 default: 442 return -EINVAL; 443 } 444} 445 446/* the generic packet interface to cdrom.c */ 447int 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 461 if (cgc->data_direction == CGC_DATA_WRITE) 462 req.cmd_flags |= REQ_RW; 463 464 memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); 465 if (cgc->sense) 466 memset(cgc->sense, 0, sizeof(struct request_sense)); 467 req.data = cgc->buffer; 468 req.data_len = cgc->buflen; 469 req.timeout = cgc->timeout; 470 471 if (cgc->quiet) 472 req.cmd_flags |= REQ_QUIET; 473 474 req.sense = cgc->sense; 475 cgc->stat = ide_cd_queue_pc(drive, &req); 476 if (!cgc->stat) 477 cgc->buflen -= req.data_len; 478 return cgc->stat; 479} 480