Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }