root/drivers/ide/ide-cd_ioctl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ide_cdrom_open_real
  2. ide_cdrom_release_real
  3. ide_cdrom_drive_status
  4. ide_cdrom_check_events_real
  5. cdrom_eject
  6. ide_cd_lockdoor
  7. ide_cdrom_tray_move
  8. ide_cdrom_lock_door
  9. ide_cdrom_select_speed
  10. ide_cdrom_get_last_session
  11. ide_cdrom_get_mcn
  12. ide_cdrom_reset
  13. ide_cd_get_toc_entry
  14. ide_cd_fake_play_trkind
  15. ide_cd_read_tochdr
  16. ide_cd_read_tocentry
  17. ide_cdrom_audio_ioctl
  18. ide_cdrom_packet

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * cdrom.c IOCTLs handling for ide-cd driver.
   4  *
   5  * Copyright (C) 1994-1996  Scott Snyder <snyder@fnald0.fnal.gov>
   6  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
   7  * Copyright (C) 1998-2000  Jens Axboe <axboe@suse.de>
   8  */
   9 
  10 #include <linux/kernel.h>
  11 #include <linux/cdrom.h>
  12 #include <linux/gfp.h>
  13 #include <linux/ide.h>
  14 #include <scsi/scsi.h>
  15 
  16 #include "ide-cd.h"
  17 
  18 /****************************************************************************
  19  * Other driver requests (open, close, check media change).
  20  */
  21 int ide_cdrom_open_real(struct cdrom_device_info *cdi, int purpose)
  22 {
  23         return 0;
  24 }
  25 
  26 /*
  27  * Close down the device.  Invalidate all cached blocks.
  28  */
  29 void ide_cdrom_release_real(struct cdrom_device_info *cdi)
  30 {
  31         ide_drive_t *drive = cdi->handle;
  32 
  33         if (!cdi->use_count)
  34                 drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
  35 }
  36 
  37 /*
  38  * add logic to try GET_EVENT command first to check for media and tray
  39  * status. this should be supported by newer cd-r/w and all DVD etc
  40  * drives
  41  */
  42 int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr)
  43 {
  44         ide_drive_t *drive = cdi->handle;
  45         struct media_event_desc med;
  46         struct scsi_sense_hdr sshdr;
  47         int stat;
  48 
  49         if (slot_nr != CDSL_CURRENT)
  50                 return -EINVAL;
  51 
  52         stat = cdrom_check_status(drive, &sshdr);
  53         if (!stat || sshdr.sense_key == UNIT_ATTENTION)
  54                 return CDS_DISC_OK;
  55 
  56         if (!cdrom_get_media_event(cdi, &med)) {
  57                 if (med.media_present)
  58                         return CDS_DISC_OK;
  59                 else if (med.door_open)
  60                         return CDS_TRAY_OPEN;
  61                 else
  62                         return CDS_NO_DISC;
  63         }
  64 
  65         if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04
  66                         && sshdr.ascq == 0x04)
  67                 return CDS_DISC_OK;
  68 
  69         /*
  70          * If not using Mt Fuji extended media tray reports,
  71          * just return TRAY_OPEN since ATAPI doesn't provide
  72          * any other way to detect this...
  73          */
  74         if (sshdr.sense_key == NOT_READY) {
  75                 if (sshdr.asc == 0x3a && sshdr.ascq == 1)
  76                         return CDS_NO_DISC;
  77                 else
  78                         return CDS_TRAY_OPEN;
  79         }
  80         return CDS_DRIVE_NOT_READY;
  81 }
  82 
  83 /*
  84  * ide-cd always generates media changed event if media is missing, which
  85  * makes it impossible to use for proper event reporting, so
  86  * DISK_EVENT_FLAG_UEVENT is cleared in disk->event_flags
  87  * and the following function is used only to trigger
  88  * revalidation and never propagated to userland.
  89  */
  90 unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
  91                                          unsigned int clearing, int slot_nr)
  92 {
  93         ide_drive_t *drive = cdi->handle;
  94         int retval;
  95 
  96         if (slot_nr == CDSL_CURRENT) {
  97                 (void) cdrom_check_status(drive, NULL);
  98                 retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
  99                 drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
 100                 return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
 101         } else {
 102                 return 0;
 103         }
 104 }
 105 
 106 /* Eject the disk if EJECTFLAG is 0.
 107    If EJECTFLAG is 1, try to reload the disk. */
 108 static
 109 int cdrom_eject(ide_drive_t *drive, int ejectflag)
 110 {
 111         struct cdrom_info *cd = drive->driver_data;
 112         struct cdrom_device_info *cdi = &cd->devinfo;
 113         char loej = 0x02;
 114         unsigned char cmd[BLK_MAX_CDB];
 115 
 116         if ((drive->atapi_flags & IDE_AFLAG_NO_EJECT) && !ejectflag)
 117                 return -EDRIVE_CANT_DO_THIS;
 118 
 119         /* reload fails on some drives, if the tray is locked */
 120         if ((drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED) && ejectflag)
 121                 return 0;
 122 
 123         /* only tell drive to close tray if open, if it can do that */
 124         if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
 125                 loej = 0;
 126 
 127         memset(cmd, 0, BLK_MAX_CDB);
 128 
 129         cmd[0] = GPCMD_START_STOP_UNIT;
 130         cmd[4] = loej | (ejectflag != 0);
 131 
 132         return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, NULL, 0, 0);
 133 }
 134 
 135 /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
 136 static
 137 int ide_cd_lockdoor(ide_drive_t *drive, int lockflag)
 138 {
 139         struct scsi_sense_hdr sshdr;
 140         int stat;
 141 
 142         /* If the drive cannot lock the door, just pretend. */
 143         if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
 144                 stat = 0;
 145         } else {
 146                 unsigned char cmd[BLK_MAX_CDB];
 147 
 148                 memset(cmd, 0, BLK_MAX_CDB);
 149 
 150                 cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
 151                 cmd[4] = lockflag ? 1 : 0;
 152 
 153                 stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL,
 154                                        &sshdr, 0, 0);
 155         }
 156 
 157         /* If we got an illegal field error, the drive
 158            probably cannot lock the door. */
 159         if (stat != 0 &&
 160             sshdr.sense_key == ILLEGAL_REQUEST &&
 161             (sshdr.asc == 0x24 || sshdr.asc == 0x20)) {
 162                 printk(KERN_ERR "%s: door locking not supported\n",
 163                         drive->name);
 164                 drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
 165                 stat = 0;
 166         }
 167 
 168         /* no medium, that's alright. */
 169         if (stat != 0 && sshdr.sense_key == NOT_READY && sshdr.asc == 0x3a)
 170                 stat = 0;
 171 
 172         if (stat == 0) {
 173                 if (lockflag)
 174                         drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED;
 175                 else
 176                         drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED;
 177         }
 178 
 179         return stat;
 180 }
 181 
 182 int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
 183 {
 184         ide_drive_t *drive = cdi->handle;
 185 
 186         if (position) {
 187                 int stat = ide_cd_lockdoor(drive, 0);
 188 
 189                 if (stat)
 190                         return stat;
 191         }
 192 
 193         return cdrom_eject(drive, !position);
 194 }
 195 
 196 int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock)
 197 {
 198         ide_drive_t *drive = cdi->handle;
 199 
 200         return ide_cd_lockdoor(drive, lock);
 201 }
 202 
 203 /*
 204  * ATAPI devices are free to select the speed you request or any slower
 205  * rate. :-(  Requesting too fast a speed will _not_ produce an error.
 206  */
 207 int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
 208 {
 209         ide_drive_t *drive = cdi->handle;
 210         struct cdrom_info *cd = drive->driver_data;
 211         u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
 212         int stat;
 213         unsigned char cmd[BLK_MAX_CDB];
 214 
 215         if (speed == 0)
 216                 speed = 0xffff; /* set to max */
 217         else
 218                 speed *= 177;   /* Nx to kbytes/s */
 219 
 220         memset(cmd, 0, BLK_MAX_CDB);
 221 
 222         cmd[0] = GPCMD_SET_SPEED;
 223         /* Read Drive speed in kbytes/second MSB/LSB */
 224         cmd[2] = (speed >> 8) & 0xff;
 225         cmd[3] = speed & 0xff;
 226         if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
 227             (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
 228                 /* Write Drive speed in kbytes/second MSB/LSB */
 229                 cmd[4] = (speed >> 8) & 0xff;
 230                 cmd[5] = speed & 0xff;
 231         }
 232 
 233         stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, NULL, 0, 0);
 234 
 235         if (!ide_cdrom_get_capabilities(drive, buf)) {
 236                 ide_cdrom_update_speed(drive, buf);
 237                 cdi->speed = cd->current_speed;
 238         }
 239 
 240         return 0;
 241 }
 242 
 243 int ide_cdrom_get_last_session(struct cdrom_device_info *cdi,
 244                                struct cdrom_multisession *ms_info)
 245 {
 246         struct atapi_toc *toc;
 247         ide_drive_t *drive = cdi->handle;
 248         struct cdrom_info *info = drive->driver_data;
 249         int ret;
 250 
 251         if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) {
 252                 ret = ide_cd_read_toc(drive);
 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 
 264 int 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 
 292 int 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 *rq;
 297         int ret;
 298 
 299         rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, 0);
 300         ide_req(rq)->type = ATA_PRIV_MISC;
 301         rq->rq_flags = RQF_QUIET;
 302         blk_execute_rq(drive->queue, cd->disk, rq, 0);
 303         ret = scsi_req(rq)->result ? -EIO : 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);
 311 
 312         return ret;
 313 }
 314 
 315 static 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 
 344 static 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         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, NULL, 0, 0);
 375 }
 376 
 377 static 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);
 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 
 396 static 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 
 419 int 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 */
 441 int ide_cdrom_packet(struct cdrom_device_info *cdi,
 442                             struct packet_command *cgc)
 443 {
 444         ide_drive_t *drive = cdi->handle;
 445         req_flags_t 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->sshdr)
 456                 memset(cgc->sshdr, 0, sizeof(*cgc->sshdr));
 457 
 458         if (cgc->quiet)
 459                 flags |= RQF_QUIET;
 460 
 461         cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
 462                                     cgc->data_direction == CGC_DATA_WRITE,
 463                                     cgc->buffer, &len,
 464                                     cgc->sshdr, cgc->timeout, flags);
 465         if (!cgc->stat)
 466                 cgc->buflen -= len;
 467         return cgc->stat;
 468 }

/* [<][>][^][v][top][bottom][index][help] */