Linux Audio

Check our new training course

Open-source upstreaming

Need help get the support for your hardware in upstream Linux?
Loading...
Note: File does not exist in v6.8.
  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 */
 21int 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 */
 29void 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 */
 42int 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 */
 90unsigned 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. */
108static
109int 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. */
136static
137int 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
182int 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
196int 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 */
207int 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
243int 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
264int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
265		      struct cdrom_mcn *mcn_info)
266{
267	ide_drive_t *drive = cdi->handle;
268	int stat, mcnlen;
269	char buf[24];
270	unsigned char cmd[BLK_MAX_CDB];
271	unsigned len = sizeof(buf);
272
273	memset(cmd, 0, BLK_MAX_CDB);
274
275	cmd[0] = GPCMD_READ_SUBCHANNEL;
276	cmd[1] = 2;		/* MSF addressing */
277	cmd[2] = 0x40;	/* request subQ data */
278	cmd[3] = 2;		/* format */
279	cmd[8] = len;
280
281	stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0);
282	if (stat)
283		return stat;
284
285	mcnlen = sizeof(mcn_info->medium_catalog_number) - 1;
286	memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen);
287	mcn_info->medium_catalog_number[mcnlen] = '\0';
288
289	return 0;
290}
291
292int ide_cdrom_reset(struct cdrom_device_info *cdi)
293{
294	ide_drive_t *drive = cdi->handle;
295	struct cdrom_info *cd = drive->driver_data;
296	struct request *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
315static int ide_cd_get_toc_entry(ide_drive_t *drive, int track,
316				struct atapi_toc_entry **ent)
317{
318	struct cdrom_info *info = drive->driver_data;
319	struct atapi_toc *toc = info->toc;
320	int ntracks;
321
322	/*
323	 * don't serve cached data, if the toc isn't valid
324	 */
325	if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0)
326		return -EINVAL;
327
328	/* Check validity of requested track number. */
329	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
330
331	if (toc->hdr.first_track == CDROM_LEADOUT)
332		ntracks = 0;
333
334	if (track == CDROM_LEADOUT)
335		*ent = &toc->ent[ntracks];
336	else if (track < toc->hdr.first_track || track > toc->hdr.last_track)
337		return -EINVAL;
338	else
339		*ent = &toc->ent[track - toc->hdr.first_track];
340
341	return 0;
342}
343
344static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
345{
346	struct cdrom_ti *ti = arg;
347	struct atapi_toc_entry *first_toc, *last_toc;
348	unsigned long lba_start, lba_end;
349	int stat;
350	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
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);
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	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}