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