Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.33 471 lines 12 kB view raw
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 31 if (!cdi->use_count) 32 drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; 33} 34 35/* 36 * add logic to try GET_EVENT command first to check for media and tray 37 * status. this should be supported by newer cd-r/w and all DVD etc 38 * drives 39 */ 40int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr) 41{ 42 ide_drive_t *drive = cdi->handle; 43 struct media_event_desc med; 44 struct request_sense sense; 45 int stat; 46 47 if (slot_nr != CDSL_CURRENT) 48 return -EINVAL; 49 50 stat = cdrom_check_status(drive, &sense); 51 if (!stat || sense.sense_key == UNIT_ATTENTION) 52 return CDS_DISC_OK; 53 54 if (!cdrom_get_media_event(cdi, &med)) { 55 if (med.media_present) 56 return CDS_DISC_OK; 57 else if (med.door_open) 58 return CDS_TRAY_OPEN; 59 else 60 return CDS_NO_DISC; 61 } 62 63 if (sense.sense_key == NOT_READY && sense.asc == 0x04 64 && sense.ascq == 0x04) 65 return CDS_DISC_OK; 66 67 /* 68 * If not using Mt Fuji extended media tray reports, 69 * just return TRAY_OPEN since ATAPI doesn't provide 70 * any other way to detect this... 71 */ 72 if (sense.sense_key == NOT_READY) { 73 if (sense.asc == 0x3a && sense.ascq == 1) 74 return CDS_NO_DISC; 75 else 76 return CDS_TRAY_OPEN; 77 } 78 return CDS_DRIVE_NOT_READY; 79} 80 81int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi, 82 int slot_nr) 83{ 84 ide_drive_t *drive = cdi->handle; 85 int retval; 86 87 if (slot_nr == CDSL_CURRENT) { 88 (void) cdrom_check_status(drive, NULL); 89 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0; 90 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; 91 return retval; 92 } else { 93 return -EINVAL; 94 } 95} 96 97/* Eject the disk if EJECTFLAG is 0. 98 If EJECTFLAG is 1, try to reload the disk. */ 99static 100int cdrom_eject(ide_drive_t *drive, int ejectflag, 101 struct request_sense *sense) 102{ 103 struct cdrom_info *cd = drive->driver_data; 104 struct cdrom_device_info *cdi = &cd->devinfo; 105 char loej = 0x02; 106 unsigned char cmd[BLK_MAX_CDB]; 107 108 if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag) 109 return -EDRIVE_CANT_DO_THIS; 110 111 /* reload fails on some drives, if the tray is locked */ 112 if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag) 113 return 0; 114 115 /* only tell drive to close tray if open, if it can do that */ 116 if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) 117 loej = 0; 118 119 memset(cmd, 0, BLK_MAX_CDB); 120 121 cmd[0] = GPCMD_START_STOP_UNIT; 122 cmd[4] = loej | (ejectflag != 0); 123 124 return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, 0); 125} 126 127/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ 128static 129int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, 130 struct request_sense *sense) 131{ 132 struct request_sense my_sense; 133 int stat; 134 135 if (sense == NULL) 136 sense = &my_sense; 137 138 /* If the drive cannot lock the door, just pretend. */ 139 if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) { 140 stat = 0; 141 } else { 142 unsigned char cmd[BLK_MAX_CDB]; 143 144 memset(cmd, 0, BLK_MAX_CDB); 145 146 cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; 147 cmd[4] = lockflag ? 1 : 0; 148 149 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, 150 sense, 0, 0); 151 } 152 153 /* If we got an illegal field error, the drive 154 probably cannot lock the door. */ 155 if (stat != 0 && 156 sense->sense_key == ILLEGAL_REQUEST && 157 (sense->asc == 0x24 || sense->asc == 0x20)) { 158 printk(KERN_ERR "%s: door locking not supported\n", 159 drive->name); 160 drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING; 161 stat = 0; 162 } 163 164 /* no medium, that's alright. */ 165 if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a) 166 stat = 0; 167 168 if (stat == 0) { 169 if (lockflag) 170 drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED; 171 else 172 drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED; 173 } 174 175 return stat; 176} 177 178int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position) 179{ 180 ide_drive_t *drive = cdi->handle; 181 struct request_sense sense; 182 183 if (position) { 184 int stat = ide_cd_lockdoor(drive, 0, &sense); 185 186 if (stat) 187 return stat; 188 } 189 190 return cdrom_eject(drive, !position, &sense); 191} 192 193int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock) 194{ 195 ide_drive_t *drive = cdi->handle; 196 197 return ide_cd_lockdoor(drive, lock, NULL); 198} 199 200/* 201 * ATAPI devices are free to select the speed you request or any slower 202 * rate. :-( Requesting too fast a speed will _not_ produce an error. 203 */ 204int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed) 205{ 206 ide_drive_t *drive = cdi->handle; 207 struct cdrom_info *cd = drive->driver_data; 208 struct request_sense sense; 209 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; 210 int stat; 211 unsigned char cmd[BLK_MAX_CDB]; 212 213 if (speed == 0) 214 speed = 0xffff; /* set to max */ 215 else 216 speed *= 177; /* Nx to kbytes/s */ 217 218 memset(cmd, 0, BLK_MAX_CDB); 219 220 cmd[0] = GPCMD_SET_SPEED; 221 /* Read Drive speed in kbytes/second MSB/LSB */ 222 cmd[2] = (speed >> 8) & 0xff; 223 cmd[3] = speed & 0xff; 224 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != 225 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { 226 /* Write Drive speed in kbytes/second MSB/LSB */ 227 cmd[4] = (speed >> 8) & 0xff; 228 cmd[5] = speed & 0xff; 229 } 230 231 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0); 232 233 if (!ide_cdrom_get_capabilities(drive, buf)) { 234 ide_cdrom_update_speed(drive, buf); 235 cdi->speed = cd->current_speed; 236 } 237 238 return 0; 239} 240 241int ide_cdrom_get_last_session(struct cdrom_device_info *cdi, 242 struct cdrom_multisession *ms_info) 243{ 244 struct atapi_toc *toc; 245 ide_drive_t *drive = cdi->handle; 246 struct cdrom_info *info = drive->driver_data; 247 struct request_sense sense; 248 int ret; 249 250 if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) { 251 ret = ide_cd_read_toc(drive, &sense); 252 if (ret) 253 return ret; 254 } 255 256 toc = info->toc; 257 ms_info->addr.lba = toc->last_session_lba; 258 ms_info->xa_flag = toc->xa_flag; 259 260 return 0; 261} 262 263int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, 264 struct cdrom_mcn *mcn_info) 265{ 266 ide_drive_t *drive = cdi->handle; 267 int stat, mcnlen; 268 char buf[24]; 269 unsigned char cmd[BLK_MAX_CDB]; 270 unsigned len = sizeof(buf); 271 272 memset(cmd, 0, BLK_MAX_CDB); 273 274 cmd[0] = GPCMD_READ_SUBCHANNEL; 275 cmd[1] = 2; /* MSF addressing */ 276 cmd[2] = 0x40; /* request subQ data */ 277 cmd[3] = 2; /* format */ 278 cmd[8] = len; 279 280 stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0); 281 if (stat) 282 return stat; 283 284 mcnlen = sizeof(mcn_info->medium_catalog_number) - 1; 285 memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen); 286 mcn_info->medium_catalog_number[mcnlen] = '\0'; 287 288 return 0; 289} 290 291int ide_cdrom_reset(struct cdrom_device_info *cdi) 292{ 293 ide_drive_t *drive = cdi->handle; 294 struct cdrom_info *cd = drive->driver_data; 295 struct request_sense sense; 296 struct request *rq; 297 int ret; 298 299 rq = blk_get_request(drive->queue, READ, __GFP_WAIT); 300 rq->cmd_type = REQ_TYPE_SPECIAL; 301 rq->cmd_flags = REQ_QUIET; 302 ret = blk_execute_rq(drive->queue, cd->disk, rq, 0); 303 blk_put_request(rq); 304 /* 305 * A reset will unlock the door. If it was previously locked, 306 * lock it again. 307 */ 308 if (drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) 309 (void)ide_cd_lockdoor(drive, 1, &sense); 310 311 return ret; 312} 313 314static int ide_cd_get_toc_entry(ide_drive_t *drive, int track, 315 struct atapi_toc_entry **ent) 316{ 317 struct cdrom_info *info = drive->driver_data; 318 struct atapi_toc *toc = info->toc; 319 int ntracks; 320 321 /* 322 * don't serve cached data, if the toc isn't valid 323 */ 324 if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0) 325 return -EINVAL; 326 327 /* Check validity of requested track number. */ 328 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; 329 330 if (toc->hdr.first_track == CDROM_LEADOUT) 331 ntracks = 0; 332 333 if (track == CDROM_LEADOUT) 334 *ent = &toc->ent[ntracks]; 335 else if (track < toc->hdr.first_track || track > toc->hdr.last_track) 336 return -EINVAL; 337 else 338 *ent = &toc->ent[track - toc->hdr.first_track]; 339 340 return 0; 341} 342 343static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) 344{ 345 struct cdrom_ti *ti = arg; 346 struct atapi_toc_entry *first_toc, *last_toc; 347 unsigned long lba_start, lba_end; 348 int stat; 349 struct request_sense sense; 350 unsigned char cmd[BLK_MAX_CDB]; 351 352 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc); 353 if (stat) 354 return stat; 355 356 stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc); 357 if (stat) 358 return stat; 359 360 if (ti->cdti_trk1 != CDROM_LEADOUT) 361 ++last_toc; 362 lba_start = first_toc->addr.lba; 363 lba_end = last_toc->addr.lba; 364 365 if (lba_end <= lba_start) 366 return -EINVAL; 367 368 memset(cmd, 0, BLK_MAX_CDB); 369 370 cmd[0] = GPCMD_PLAY_AUDIO_MSF; 371 lba_to_msf(lba_start, &cmd[3], &cmd[4], &cmd[5]); 372 lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]); 373 374 return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0); 375} 376 377static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) 378{ 379 struct cdrom_info *cd = drive->driver_data; 380 struct cdrom_tochdr *tochdr = arg; 381 struct atapi_toc *toc; 382 int stat; 383 384 /* Make sure our saved TOC is valid. */ 385 stat = ide_cd_read_toc(drive, NULL); 386 if (stat) 387 return stat; 388 389 toc = cd->toc; 390 tochdr->cdth_trk0 = toc->hdr.first_track; 391 tochdr->cdth_trk1 = toc->hdr.last_track; 392 393 return 0; 394} 395 396static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg) 397{ 398 struct cdrom_tocentry *tocentry = arg; 399 struct atapi_toc_entry *toce; 400 int stat; 401 402 stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce); 403 if (stat) 404 return stat; 405 406 tocentry->cdte_ctrl = toce->control; 407 tocentry->cdte_adr = toce->adr; 408 if (tocentry->cdte_format == CDROM_MSF) { 409 lba_to_msf(toce->addr.lba, 410 &tocentry->cdte_addr.msf.minute, 411 &tocentry->cdte_addr.msf.second, 412 &tocentry->cdte_addr.msf.frame); 413 } else 414 tocentry->cdte_addr.lba = toce->addr.lba; 415 416 return 0; 417} 418 419int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, 420 unsigned int cmd, void *arg) 421{ 422 ide_drive_t *drive = cdi->handle; 423 424 switch (cmd) { 425 /* 426 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since 427 * atapi doesn't support it 428 */ 429 case CDROMPLAYTRKIND: 430 return ide_cd_fake_play_trkind(drive, arg); 431 case CDROMREADTOCHDR: 432 return ide_cd_read_tochdr(drive, arg); 433 case CDROMREADTOCENTRY: 434 return ide_cd_read_tocentry(drive, arg); 435 default: 436 return -EINVAL; 437 } 438} 439 440/* the generic packet interface to cdrom.c */ 441int ide_cdrom_packet(struct cdrom_device_info *cdi, 442 struct packet_command *cgc) 443{ 444 ide_drive_t *drive = cdi->handle; 445 unsigned int flags = 0; 446 unsigned len = cgc->buflen; 447 448 if (cgc->timeout <= 0) 449 cgc->timeout = ATAPI_WAIT_PC; 450 451 /* here we queue the commands from the uniform CD-ROM 452 layer. the packet must be complete, as we do not 453 touch it at all. */ 454 455 if (cgc->data_direction == CGC_DATA_WRITE) 456 flags |= REQ_RW; 457 458 if (cgc->sense) 459 memset(cgc->sense, 0, sizeof(struct request_sense)); 460 461 if (cgc->quiet) 462 flags |= REQ_QUIET; 463 464 cgc->stat = ide_cd_queue_pc(drive, cgc->cmd, 465 cgc->data_direction == CGC_DATA_WRITE, 466 cgc->buffer, &len, 467 cgc->sense, cgc->timeout, flags); 468 if (!cgc->stat) 469 cgc->buflen -= len; 470 return cgc->stat; 471}