Linux Audio

Check our new training course

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 request_sense sense;
 47	int stat;
 48
 49	if (slot_nr != CDSL_CURRENT)
 50		return -EINVAL;
 51
 52	stat = cdrom_check_status(drive, &sense);
 53	if (!stat || sense.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 (sense.sense_key == NOT_READY && sense.asc == 0x04
 66			&& sense.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 (sense.sense_key == NOT_READY) {
 75		if (sense.asc == 0x3a && sense.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 disk->events
 86 * is cleared to 0 and the following function is used only to trigger
 87 * revalidation and never propagated to userland.
 88 */
 89unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi,
 90					 unsigned int clearing, int slot_nr)
 91{
 92	ide_drive_t *drive = cdi->handle;
 93	int retval;
 94
 95	if (slot_nr == CDSL_CURRENT) {
 96		(void) cdrom_check_status(drive, NULL);
 97		retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
 98		drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
 99		return retval ? DISK_EVENT_MEDIA_CHANGE : 0;
100	} else {
101		return 0;
102	}
103}
104
105/* Eject the disk if EJECTFLAG is 0.
106   If EJECTFLAG is 1, try to reload the disk. */
107static
108int cdrom_eject(ide_drive_t *drive, int ejectflag,
109		struct request_sense *sense)
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, sense, 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		    struct request_sense *sense)
139{
140	struct request_sense my_sense;
141	int stat;
142
143	if (sense == NULL)
144		sense = &my_sense;
145
146	/* If the drive cannot lock the door, just pretend. */
147	if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
148		stat = 0;
149	} else {
150		unsigned char cmd[BLK_MAX_CDB];
151
152		memset(cmd, 0, BLK_MAX_CDB);
153
154		cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
155		cmd[4] = lockflag ? 1 : 0;
156
157		stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL,
158				       sense, 0, 0);
159	}
160
161	/* If we got an illegal field error, the drive
162	   probably cannot lock the door. */
163	if (stat != 0 &&
164	    sense->sense_key == ILLEGAL_REQUEST &&
165	    (sense->asc == 0x24 || sense->asc == 0x20)) {
166		printk(KERN_ERR "%s: door locking not supported\n",
167			drive->name);
168		drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
169		stat = 0;
170	}
171
172	/* no medium, that's alright. */
173	if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
174		stat = 0;
175
176	if (stat == 0) {
177		if (lockflag)
178			drive->atapi_flags |= IDE_AFLAG_DOOR_LOCKED;
179		else
180			drive->atapi_flags &= ~IDE_AFLAG_DOOR_LOCKED;
181	}
182
183	return stat;
184}
185
186int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
187{
188	ide_drive_t *drive = cdi->handle;
189	struct request_sense sense;
190
191	if (position) {
192		int stat = ide_cd_lockdoor(drive, 0, &sense);
193
194		if (stat)
195			return stat;
196	}
197
198	return cdrom_eject(drive, !position, &sense);
199}
200
201int ide_cdrom_lock_door(struct cdrom_device_info *cdi, int lock)
202{
203	ide_drive_t *drive = cdi->handle;
204
205	return ide_cd_lockdoor(drive, lock, NULL);
206}
207
208/*
209 * ATAPI devices are free to select the speed you request or any slower
210 * rate. :-(  Requesting too fast a speed will _not_ produce an error.
211 */
212int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
213{
214	ide_drive_t *drive = cdi->handle;
215	struct cdrom_info *cd = drive->driver_data;
216	struct request_sense sense;
217	u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
218	int stat;
219	unsigned char cmd[BLK_MAX_CDB];
220
221	if (speed == 0)
222		speed = 0xffff; /* set to max */
223	else
224		speed *= 177;   /* Nx to kbytes/s */
225
226	memset(cmd, 0, BLK_MAX_CDB);
227
228	cmd[0] = GPCMD_SET_SPEED;
229	/* Read Drive speed in kbytes/second MSB/LSB */
230	cmd[2] = (speed >> 8) & 0xff;
231	cmd[3] = speed & 0xff;
232	if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
233	    (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
234		/* Write Drive speed in kbytes/second MSB/LSB */
235		cmd[4] = (speed >> 8) & 0xff;
236		cmd[5] = speed & 0xff;
237	}
238
239	stat = ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
240
241	if (!ide_cdrom_get_capabilities(drive, buf)) {
242		ide_cdrom_update_speed(drive, buf);
243		cdi->speed = cd->current_speed;
244	}
245
246	return 0;
247}
248
249int ide_cdrom_get_last_session(struct cdrom_device_info *cdi,
250			       struct cdrom_multisession *ms_info)
251{
252	struct atapi_toc *toc;
253	ide_drive_t *drive = cdi->handle;
254	struct cdrom_info *info = drive->driver_data;
255	struct request_sense sense;
256	int ret;
257
258	if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0 || !info->toc) {
259		ret = ide_cd_read_toc(drive, &sense);
260		if (ret)
261			return ret;
262	}
263
264	toc = info->toc;
265	ms_info->addr.lba = toc->last_session_lba;
266	ms_info->xa_flag = toc->xa_flag;
267
268	return 0;
269}
270
271int ide_cdrom_get_mcn(struct cdrom_device_info *cdi,
272		      struct cdrom_mcn *mcn_info)
273{
274	ide_drive_t *drive = cdi->handle;
275	int stat, mcnlen;
276	char buf[24];
277	unsigned char cmd[BLK_MAX_CDB];
278	unsigned len = sizeof(buf);
279
280	memset(cmd, 0, BLK_MAX_CDB);
281
282	cmd[0] = GPCMD_READ_SUBCHANNEL;
283	cmd[1] = 2;		/* MSF addressing */
284	cmd[2] = 0x40;	/* request subQ data */
285	cmd[3] = 2;		/* format */
286	cmd[8] = len;
287
288	stat = ide_cd_queue_pc(drive, cmd, 0, buf, &len, NULL, 0, 0);
289	if (stat)
290		return stat;
291
292	mcnlen = sizeof(mcn_info->medium_catalog_number) - 1;
293	memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen);
294	mcn_info->medium_catalog_number[mcnlen] = '\0';
295
296	return 0;
297}
298
299int ide_cdrom_reset(struct cdrom_device_info *cdi)
300{
301	ide_drive_t *drive = cdi->handle;
302	struct cdrom_info *cd = drive->driver_data;
303	struct request_sense sense;
304	struct request *rq;
305	int ret;
306
307	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
308	ide_req(rq)->type = ATA_PRIV_MISC;
309	rq->rq_flags = RQF_QUIET;
310	blk_execute_rq(drive->queue, cd->disk, rq, 0);
311	ret = scsi_req(rq)->result ? -EIO : 0;
312	blk_put_request(rq);
313	/*
314	 * A reset will unlock the door. If it was previously locked,
315	 * lock it again.
316	 */
317	if (drive->atapi_flags & IDE_AFLAG_DOOR_LOCKED)
318		(void)ide_cd_lockdoor(drive, 1, &sense);
319
320	return ret;
321}
322
323static int ide_cd_get_toc_entry(ide_drive_t *drive, int track,
324				struct atapi_toc_entry **ent)
325{
326	struct cdrom_info *info = drive->driver_data;
327	struct atapi_toc *toc = info->toc;
328	int ntracks;
329
330	/*
331	 * don't serve cached data, if the toc isn't valid
332	 */
333	if ((drive->atapi_flags & IDE_AFLAG_TOC_VALID) == 0)
334		return -EINVAL;
335
336	/* Check validity of requested track number. */
337	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
338
339	if (toc->hdr.first_track == CDROM_LEADOUT)
340		ntracks = 0;
341
342	if (track == CDROM_LEADOUT)
343		*ent = &toc->ent[ntracks];
344	else if (track < toc->hdr.first_track || track > toc->hdr.last_track)
345		return -EINVAL;
346	else
347		*ent = &toc->ent[track - toc->hdr.first_track];
348
349	return 0;
350}
351
352static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg)
353{
354	struct cdrom_ti *ti = arg;
355	struct atapi_toc_entry *first_toc, *last_toc;
356	unsigned long lba_start, lba_end;
357	int stat;
358	struct request_sense sense;
359	unsigned char cmd[BLK_MAX_CDB];
360
361	stat = ide_cd_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
362	if (stat)
363		return stat;
364
365	stat = ide_cd_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
366	if (stat)
367		return stat;
368
369	if (ti->cdti_trk1 != CDROM_LEADOUT)
370		++last_toc;
371	lba_start = first_toc->addr.lba;
372	lba_end   = last_toc->addr.lba;
373
374	if (lba_end <= lba_start)
375		return -EINVAL;
376
377	memset(cmd, 0, BLK_MAX_CDB);
378
379	cmd[0] = GPCMD_PLAY_AUDIO_MSF;
380	lba_to_msf(lba_start,   &cmd[3], &cmd[4], &cmd[5]);
381	lba_to_msf(lba_end - 1, &cmd[6], &cmd[7], &cmd[8]);
382
383	return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, &sense, 0, 0);
384}
385
386static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg)
387{
388	struct cdrom_info *cd = drive->driver_data;
389	struct cdrom_tochdr *tochdr = arg;
390	struct atapi_toc *toc;
391	int stat;
392
393	/* Make sure our saved TOC is valid. */
394	stat = ide_cd_read_toc(drive, NULL);
395	if (stat)
396		return stat;
397
398	toc = cd->toc;
399	tochdr->cdth_trk0 = toc->hdr.first_track;
400	tochdr->cdth_trk1 = toc->hdr.last_track;
401
402	return 0;
403}
404
405static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg)
406{
407	struct cdrom_tocentry *tocentry = arg;
408	struct atapi_toc_entry *toce;
409	int stat;
410
411	stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, &toce);
412	if (stat)
413		return stat;
414
415	tocentry->cdte_ctrl = toce->control;
416	tocentry->cdte_adr  = toce->adr;
417	if (tocentry->cdte_format == CDROM_MSF) {
418		lba_to_msf(toce->addr.lba,
419			   &tocentry->cdte_addr.msf.minute,
420			   &tocentry->cdte_addr.msf.second,
421			   &tocentry->cdte_addr.msf.frame);
422	} else
423		tocentry->cdte_addr.lba = toce->addr.lba;
424
425	return 0;
426}
427
428int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi,
429			  unsigned int cmd, void *arg)
430{
431	ide_drive_t *drive = cdi->handle;
432
433	switch (cmd) {
434	/*
435	 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
436	 * atapi doesn't support it
437	 */
438	case CDROMPLAYTRKIND:
439		return ide_cd_fake_play_trkind(drive, arg);
440	case CDROMREADTOCHDR:
441		return ide_cd_read_tochdr(drive, arg);
442	case CDROMREADTOCENTRY:
443		return ide_cd_read_tocentry(drive, arg);
444	default:
445		return -EINVAL;
446	}
447}
448
449/* the generic packet interface to cdrom.c */
450int ide_cdrom_packet(struct cdrom_device_info *cdi,
451			    struct packet_command *cgc)
452{
453	ide_drive_t *drive = cdi->handle;
454	req_flags_t flags = 0;
455	unsigned len = cgc->buflen;
456
457	if (cgc->timeout <= 0)
458		cgc->timeout = ATAPI_WAIT_PC;
459
460	/* here we queue the commands from the uniform CD-ROM
461	   layer. the packet must be complete, as we do not
462	   touch it at all. */
463
464	if (cgc->sense)
465		memset(cgc->sense, 0, sizeof(struct request_sense));
466
467	if (cgc->quiet)
468		flags |= RQF_QUIET;
469
470	cgc->stat = ide_cd_queue_pc(drive, cgc->cmd,
471				    cgc->data_direction == CGC_DATA_WRITE,
472				    cgc->buffer, &len,
473				    cgc->sense, cgc->timeout, flags);
474	if (!cgc->stat)
475		cgc->buflen -= len;
476	return cgc->stat;
477}