ide-cd_ioctl.c revision 5b03a1b140e13a28ff6be1526892a9dc538ddef6
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/gfp.h> 12#include <linux/ide.h> 13#include <scsi/scsi.h> 14 15#include "ide-cd.h" 16 17/**************************************************************************** 18 * Other driver requests (open, close, check media change). 19 */ 20int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose) 21{ 22 return 0; 23} 24 25/* 26 * Close down the device. Invalidate all cached blocks. 27 */ 28void ide_cdrom_release_real(struct cdrom_device_info *cdi) 29{ 30 ide_drive_t *drive = cdi->handle; 31 32 if (!cdi->use_count) 33 drive->atapi_flags &= ~IDE_AFLAG_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 82unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi, 83 unsigned int clearing, int slot_nr) 84{ 85 ide_drive_t *drive = cdi->handle; 86 int retval; 87 88 if (slot_nr == CDSL_CURRENT) { 89 (void) cdrom_check_status(drive, NULL); 90 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; 91 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 92 return retval ? DISK_EVENT_MEDIA_CHANGE : 0; 93 } else { 94 return 0; 95 } 96} 97 98/* Eject the disk if EJECTFLAG is 0. 99 If EJECTFLAG is 1, try to reload the disk. */ 100static 101int cdrom_eject(ide_drive_t *drive, int ejectflag, 102 struct request_sense *sense) 103{ 104 struct cdrom_info *cd = drive->driver_data; 105 struct cdrom_device_info *cdi = &cd->devinfo; 106 char loej = 0x02; 107 unsigned char cmd[BLK_MAX_CDB]; 108 109 if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag) 110 return -EDRIVE_CANT_DO_THIS; 111 112 /* reload fails on some drives, if the tray is locked */ 113 if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag) 114 return 0; 115 116 /* only tell drive to close tray if open, if it can do that */ 117 if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) 118 loej = 0; 119 120 memset(cmd, 0, BLK_MAX_CDB); 121 122 cmd[0] = GPCMD_START_STOP_UNIT; 123 cmd[4] = loej | (ejectflag != 0); 124 125 return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, 0); 126} 127 128/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ 129static 130int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, 131 struct request_sense *sense) 132{ 133 struct request_sense my_sense; 134 int stat; 135 136 if (sense == NULL) 137 sense = &my_sense; 138 139 /* If the drive cannot lock the door, just pretend. */ 140 if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) { 141 stat = 0; 142 } else { 143 unsigned char cmd[BLK_MAX_CDB]; 144 145 memset(cmd, 0, BLK_MAX_CDB); 146 147 cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; 148 cmd[4] = lockflag ? 1 : 0; 149 150 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, 151 sense, 0, 0); 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 drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; 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 drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED; 172 else 173 drive->atapi_flags &= ~IDE_AFLAG_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_sense sense; 210 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; 211 int stat; 212 unsigned char cmd[BLK_MAX_CDB]; 213 214 if (speed == 0) 215 speed = 0xffff; /* set to max */ 216 else 217 speed *= 177; /* Nx to kbytes/s */ 218 219 memset(cmd, 0, BLK_MAX_CDB); 220 221 cmd[0] = GPCMD_SET_SPEED; 222 /* Read Drive speed in kbytes/second MSB/LSB */ 223 cmd[2] = (speed >> 8) & 0xff; 224 cmd[3] = speed & 0xff; 225 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != 226 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { 227 /* Write Drive speed in kbytes/second MSB/LSB */ 228 cmd[4] = (speed >> 8) & 0xff; 229 cmd[5] = speed & 0xff; 230 } 231 232 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0); 233 234 if (!ide_cdrom_get_capabilities(drive, buf)) { 235 ide_cdrom_update_speed(drive, buf); 236 cdi->speed = cd->current_speed; 237 } 238 239 return 0; 240} 241 242int ide_cdrom_get_last_session(struct cdrom_device_info *cdi, 243 struct cdrom_multisession *ms_info) 244{ 245 struct atapi_toc *toc; 246 ide_drive_t *drive = cdi->handle; 247 struct cdrom_info *info = drive->driver_data; 248 struct request_sense sense; 249 int ret; 250 251 if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) { 252 ret = ide_cd_read_toc(drive, &sense); 253 if (ret) 254 return ret; 255 } 256 257 toc = info->toc; 258 ms_info->addr.lba = toc->last_session_lba; 259 ms_info->xa_flag = toc->xa_flag; 260 261 return 0; 262} 263 264int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, 265 struct cdrom_mcn *mcn_info) 266{ 267 ide_drive_t *drive = cdi->handle; 268 int stat, mcnlen; 269 char buf[24]; 270 unsigned char cmd[BLK_MAX_CDB]; 271 unsigned len = sizeof(buf); 272 273 memset(cmd, 0, BLK_MAX_CDB); 274 275 cmd[0] = GPCMD_READ_SUBCHANNEL; 276 cmd[1] = 2; /* MSF addressing */ 277 cmd[2] = 0x40; /* request subQ data */ 278 cmd[3] = 2; /* format */ 279 cmd[8] = len; 280 281 stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0); 282 if (stat) 283 return stat; 284 285 mcnlen = sizeof(mcn_info->medium_catalog_number) - 1; 286 memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen); 287 mcn_info->medium_catalog_number[mcnlen] = '\0'; 288 289 return 0; 290} 291 292int ide_cdrom_reset(struct cdrom_device_info *cdi) 293{ 294 ide_drive_t *drive = cdi->handle; 295 struct cdrom_info *cd = drive->driver_data; 296 struct request_sense sense; 297 struct request *rq; 298 int ret; 299 300 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 301 rq->cmd_type = REQ_TYPE_SPECIAL; 302 rq->cmd_flags = REQ_QUIET; 303 ret = blk_execute_rq(drive->queue, cd->disk, rq, 0); 304 blk_put_request(rq); 305 /* 306 * A reset will unlock the door. If it was previously locked, 307 * lock it again. 308 */ 309 if (drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) 310 (void)ide_cd_lockdoor(drive, 1, &sense); 311 312 return ret; 313} 314 315static int ide_cd_get_toc_entry(ide_drive_t *drive, int track, 316 struct atapi_toc_entry **ent) 317{ 318 struct cdrom_info *info = drive->driver_data; 319 struct atapi_toc *toc = info->toc; 320 int ntracks; 321 322 /* 323 * don't serve cached data, if the toc isn't valid 324 */ 325 if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0) 326 return -EINVAL; 327 328 /* Check validity of requested track number. */ 329 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; 330 331 if (toc->hdr.first_track == CDROM_LEADOUT) 332 ntracks = 0; 333 334 if (track == CDROM_LEADOUT) 335 *ent = &toc->ent[ntracks]; 336 else if (track < toc->hdr.first_track || track > toc->hdr.last_track) 337 return -EINVAL; 338 else 339 *ent = &toc->ent[track - toc->hdr.first_track]; 340 341 return 0; 342} 343 344static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) 345{ 346 struct cdrom_ti *ti = arg; 347 struct atapi_toc_entry *first_toc, *last_toc; 348 unsigned long lba_start, lba_end; 349 int stat; 350 struct request_sense sense; 351 unsigned char cmd[BLK_MAX_CDB]; 352 353 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc); 354 if (stat) 355 return stat; 356 357 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc); 358 if (stat) 359 return stat; 360 361 if (ti->cdti_trk1 != CDROM_LEADOUT) 362 ++last_toc; 363 lba_start = first_toc->addr.lba; 364 lba_end = last_toc->addr.lba; 365 366 if (lba_end <= lba_start) 367 return -EINVAL; 368 369 memset(cmd, 0, BLK_MAX_CDB); 370 371 cmd[0] = GPCMD_PLAY_AUDIO_MSF; 372 lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]); 373 lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]); 374 375 return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0); 376} 377 378static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) 379{ 380 struct cdrom_info *cd = drive->driver_data; 381 struct cdrom_tochdr *tochdr = arg; 382 struct atapi_toc *toc; 383 int stat; 384 385 /* Make sure our saved TOC is valid. */ 386 stat = ide_cd_read_toc(drive, NULL); 387 if (stat) 388 return stat; 389 390 toc = cd->toc; 391 tochdr->cdth_trk0 = toc->hdr.first_track; 392 tochdr->cdth_trk1 = toc->hdr.last_track; 393 394 return 0; 395} 396 397static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg) 398{ 399 struct cdrom_tocentry *tocentry = arg; 400 struct atapi_toc_entry *toce; 401 int stat; 402 403 stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce); 404 if (stat) 405 return stat; 406 407 tocentry->cdte_ctrl = toce->control; 408 tocentry->cdte_adr = toce->adr; 409 if (tocentry->cdte_format == CDROM_MSF) { 410 lba_to_msf(toce->addr.lba, 411 &tocentry->cdte_addr.msf.minute, 412 &tocentry->cdte_addr.msf.second, 413 &tocentry->cdte_addr.msf.frame); 414 } else 415 tocentry->cdte_addr.lba = toce->addr.lba; 416 417 return 0; 418} 419 420int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, 421 unsigned int cmd, void *arg) 422{ 423 ide_drive_t *drive = cdi->handle; 424 425 switch (cmd) { 426 /* 427 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since 428 * atapi doesn't support it 429 */ 430 case CDROMPLAYTRKIND: 431 return ide_cd_fake_play_trkind(drive, arg); 432 case CDROMREADTOCHDR: 433 return ide_cd_read_tochdr(drive, arg); 434 case CDROMREADTOCENTRY: 435 return ide_cd_read_tocentry(drive, arg); 436 default: 437 return -EINVAL; 438 } 439} 440 441/* the generic packet interface to cdrom.c */ 442int ide_cdrom_packet(struct cdrom_device_info *cdi, 443 struct packet_command *cgc) 444{ 445 ide_drive_t *drive = cdi->handle; 446 unsigned int flags = 0; 447 unsigned len = cgc->buflen; 448 449 if (cgc->timeout <= 0) 450 cgc->timeout = ATAPI_WAIT_PC; 451 452 /* here we queue the commands from the uniform CD-ROM 453 layer. the packet must be complete, as we do not 454 touch it at all. */ 455 456 if (cgc->data_direction == CGC_DATA_WRITE) 457 flags |= REQ_WRITE; 458 459 if (cgc->sense) 460 memset(cgc->sense, 0, sizeof(struct request_sense)); 461 462 if (cgc->quiet) 463 flags |= REQ_QUIET; 464 465 cgc->stat = ide_cd_queue_pc(drive, cgc->cmd, 466 cgc->data_direction == CGC_DATA_WRITE, 467 cgc->buffer, &len, 468 cgc->sense, cgc->timeout, flags); 469 if (!cgc->stat) 470 cgc->buflen -= len; 471 return cgc->stat; 472} 473