xref: /netbsd-src/sys/dev/scsipi/cd.c (revision 6ea46cb5e46c49111a6ecf3bcbe3c7e2730fe9f6)
1 /*	$NetBSD: cd.c,v 1.34 1994/08/11 23:51:26 mycroft Exp $	*/
2 
3 /*
4  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Charles Hannum.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Originally written by Julian Elischer (julian@tfs.com)
34  * for TRW Financial Systems for use under the MACH(2.5) operating system.
35  *
36  * TRW Financial Systems, in accordance with their agreement with Carnegie
37  * Mellon University, makes this software available to CMU to distribute
38  * or use in any manner that they see fit as long as this message is kept with
39  * the software. For this reason TFS also grants any other persons or
40  * organisations permission to use or modify this software.
41  *
42  * TFS supplies this software to be publicly redistributed
43  * on the understanding that TFS is not responsible for the correct
44  * functioning of this software in any circumstances.
45  *
46  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
47  */
48 
49 #include <sys/types.h>
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/dkbad.h>
54 #include <sys/conf.h>
55 #include <sys/file.h>
56 #include <sys/stat.h>
57 #include <sys/ioctl.h>
58 #include <sys/buf.h>
59 #include <sys/uio.h>
60 #include <sys/malloc.h>
61 #include <sys/errno.h>
62 #include <sys/device.h>
63 #include <sys/disklabel.h>
64 #include <sys/disk.h>
65 #include <sys/cdio.h>
66 
67 #include <scsi/scsi_all.h>
68 #include <scsi/scsi_cd.h>
69 #include <scsi/scsi_disk.h>	/* rw_big and start_stop come from there */
70 #include <scsi/scsiconf.h>
71 
72 #ifdef	DDB
73 int	Debugger();
74 #else	/* DDB */
75 #define Debugger()
76 #endif	/* DDB */
77 
78 #define	CDOUTSTANDING	2
79 #define	CDRETRIES	1
80 
81 #define	MAKECDDEV(maj, unit, part) \
82     (makedev((maj), ((unit) * MAXPARTITIONS) + (part)))
83 #define CDPART(z)	(minor(z) % MAXPARTITIONS)
84 #define CDUNIT(z)	(minor(z) / MAXPARTITIONS)
85 #ifndef RAW_PART
86 #define	RAW_PART	3
87 #endif
88 
89 struct cd_data {
90 	struct device sc_dev;
91 	struct dkdevice sc_dk;
92 
93 	struct scsi_link *sc_link;	/* address of scsi low level switch */
94 	u_int32 ad_info;	/* info about the adapter */
95 	u_int32 cmdscount;	/* cmds allowed outstanding by board */
96 	struct cd_parms {
97 		u_int32 blksize;
98 		u_long disksize;	/* total number sectors */
99 	} params;
100 	int partflags[MAXPARTITIONS];	/* per partition flags */
101 #define CDOPEN	0x01
102 	u_int32 openparts;	/* one bit for each open partition */
103 	u_int32 xfer_block_wait;
104 	struct buf buf_queue;
105 };
106 
107 void cdattach __P((struct device *, struct device *, void *));
108 
109 struct cfdriver cdcd = {
110 	NULL, "cd", scsi_targmatch, cdattach, DV_DISK, sizeof(struct cd_data)
111 };
112 
113 int cdgetdisklabel __P((struct cd_data *));
114 int cd_get_parms __P((struct cd_data *, int));
115 void cdstrategy __P((struct buf *));
116 void cdstart __P((int));
117 
118 struct dkdriver cddkdriver = { cdstrategy };
119 
120 struct scsi_device cd_switch = {
121 	NULL,			/* use default error handler */
122 	cdstart,		/* we have a queue, which is started by this */
123 	NULL,			/* we do not have an async handler */
124 	NULL,			/* use default 'done' routine */
125 	"cd",			/* we are to be refered to by this name */
126 	0			/* no device specific flags */
127 };
128 
129 #define CD_STOP		0
130 #define CD_START	1
131 #define CD_EJECT	-2
132 
133 /*
134  * The routine called by the low level scsi routine when it discovers
135  * A device suitable for this driver
136  */
137 void
138 cdattach(parent, self, aux)
139 	struct device *parent, *self;
140 	void *aux;
141 {
142 	struct cd_data *cd = (void *)self;
143 	struct cd_parms *dp = &cd->params;
144 	struct scsi_link *sc_link = aux;
145 
146 	SC_DEBUG(sc_link, SDEV_DB2, ("cdattach: "));
147 
148 	/*
149 	 * Store information needed to contact our base driver
150 	 */
151 	cd->sc_link = sc_link;
152 	sc_link->device = &cd_switch;
153 	sc_link->dev_unit = cd->sc_dev.dv_unit;
154 
155 	cd->sc_dk.dk_driver = &cddkdriver;
156 #if !defined(i386) || defined(NEWCONFIG)
157 	dk_establish(&cd->sc_dk, &cd->sc_dev);
158 #endif
159 
160 	if (cd->sc_link->adapter->adapter_info) {
161 		cd->ad_info = ((*(cd->sc_link->adapter->adapter_info)) (sc_link->adapter_softc));
162 		cd->cmdscount = cd->ad_info & AD_INF_MAX_CMDS;
163 		if (cd->cmdscount > CDOUTSTANDING)
164 			cd->cmdscount = CDOUTSTANDING;
165 	} else {
166 		cd->ad_info = 1;
167 		cd->cmdscount = 1;
168 	}
169 	sc_link->opennings = cd->cmdscount;
170 
171 	/*
172 	 * Use the subdriver to request information regarding
173 	 * the drive. We cannot use interrupts yet, so the
174 	 * request must specify this.
175 	 */
176 	cd_get_parms(cd, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT);
177 	if (dp->disksize)
178 		printf(": cd present, %d x %d byte records\n",
179 		    cd->params.disksize, cd->params.blksize);
180 	else
181 		printf(": drive empty\n");
182 }
183 
184 /*
185  * open the device. Make sure the partition info is a up-to-date as can be.
186  */
187 int
188 cdopen(dev)
189 	dev_t dev;
190 {
191 	int error = 0;
192 	int unit, part;
193 	struct cd_data *cd;
194 	struct scsi_link *sc_link;
195 
196 	unit = CDUNIT(dev);
197 	part = CDPART(dev);
198 
199 	if (unit >= cdcd.cd_ndevs)
200 		return ENXIO;
201 	cd = cdcd.cd_devs[unit];
202 	if (!cd)
203 		return ENXIO;
204 
205 	sc_link = cd->sc_link;
206 
207 	SC_DEBUG(sc_link, SDEV_DB1,
208 	    ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
209 	    cdcd.cd_ndevs, part));
210 
211 	/*
212 	 * If it's been invalidated, and not everybody has closed it then
213 	 * forbid re-entry.  (may have changed media)
214 	 */
215 	if (!(sc_link->flags & SDEV_MEDIA_LOADED) && cd->openparts)
216 		return ENXIO;
217 
218 	/*
219 	 * Check that it is still responding and ok.
220 	 * if the media has been changed this will result in a
221 	 * "unit attention" error which the error code will
222 	 * disregard because the SDEV_MEDIA_LOADED flag is not yet set
223 	 */
224 	scsi_test_unit_ready(sc_link, SCSI_SILENT);
225 
226 	/*
227 	 * In case it is a funny one, tell it to start
228 	 * not needed for some drives
229 	 */
230 	scsi_start(sc_link, SSS_START, SCSI_ERR_OK | SCSI_SILENT);
231 
232 	/*
233 	 * Next time actually take notice of error returns
234 	 */
235 	sc_link->flags |= SDEV_OPEN;	/* unit attn errors are now errors */
236 	if (scsi_test_unit_ready(sc_link, 0) != 0) {
237 		SC_DEBUG(sc_link, SDEV_DB3, ("device not responding\n"));
238 		error = ENXIO;
239 		goto bad;
240 	}
241 	SC_DEBUG(sc_link, SDEV_DB3, ("device ok\n"));
242 
243 	/* Lock the pack in. */
244 	scsi_prevent(sc_link, PR_PREVENT, SCSI_ERR_OK | SCSI_SILENT);
245 
246 	/*
247 	 * Load the physical device parameters
248 	 */
249 	if (cd_get_parms(cd, 0)) {
250 		error = ENXIO;
251 		goto bad;
252 	}
253 	SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
254 
255 	/*
256 	 * Make up some partition information
257 	 */
258 	cdgetdisklabel(cd);
259 	SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated "));
260 
261 	/*
262 	 * Check the partition is legal
263 	 */
264 	if (part >= cd->sc_dk.dk_label.d_npartitions && part != RAW_PART) {
265 		error = ENXIO;
266 		goto bad;
267 	}
268 	SC_DEBUG(sc_link, SDEV_DB3, ("partition ok"));
269 
270 	/*
271 	 *  Check that the partition exists
272 	 */
273 	if (cd->sc_dk.dk_label.d_partitions[part].p_fstype == FS_UNUSED &&
274 	    part != RAW_PART) {
275 		error = ENXIO;
276 		goto bad;
277 	}
278 	cd->partflags[part] |= CDOPEN;
279 	cd->openparts |= (1 << part);
280 	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
281 	sc_link->flags |= SDEV_MEDIA_LOADED;
282 	return 0;
283 
284 bad:
285 	if (!cd->openparts) {
286 		scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
287 		sc_link->flags &= ~SDEV_OPEN;
288 	}
289 	return error;
290 }
291 
292 /*
293  * close the device.. only called if we are the LAST
294  * occurence of an open device
295  */
296 int
297 cdclose(dev)
298 	dev_t dev;
299 {
300 	int unit, part;
301 	struct cd_data *cd;
302 
303 	unit = CDUNIT(dev);
304 	part = CDPART(dev);
305 	cd = cdcd.cd_devs[unit];
306 	cd->partflags[part] &= ~CDOPEN;
307 	cd->openparts &= ~(1 << part);
308 	if (!cd->openparts) {
309 		scsi_prevent(cd->sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT);
310 		cd->sc_link->flags &= ~SDEV_OPEN;
311 	}
312 	return 0;
313 }
314 
315 /*
316  * trim the size of the transfer if needed,
317  * called by physio
318  * basically the smaller of our max and the scsi driver's
319  * minphys (note we have no max ourselves)
320  *
321  * Trim buffer length if buffer-size is bigger than page size
322  */
323 void
324 cdminphys(bp)
325 	struct buf *bp;
326 {
327 	register struct cd_data *cd = cdcd.cd_devs[CDUNIT(bp->b_dev)];
328 
329 	(cd->sc_link->adapter->scsi_minphys) (bp);
330 }
331 
332 /*
333  * Actually translate the requested transfer into one the physical driver can
334  * understand.  The transfer is described by a buf and will include only one
335  * physical transfer.
336  */
337 void
338 cdstrategy(bp)
339 	struct buf *bp;
340 {
341 	struct buf *dp;
342 	int opri;
343 	struct cd_data *cd;
344 	int unit;
345 
346 	unit = CDUNIT(bp->b_dev);
347 	cd = cdcd.cd_devs[unit];
348 	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdstrategy "));
349 	SC_DEBUG(cd->sc_link, SDEV_DB1,
350 	    ("%d bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
351 	cdminphys(bp);
352 	/*
353 	 * If the device has been made invalid, error out
354 	 * maybe the media changed
355 	 */
356 	if (!(cd->sc_link->flags & SDEV_MEDIA_LOADED)) {
357 		bp->b_error = EIO;
358 		goto bad;
359 	}
360 	/*
361 	 * can't ever write to a CD
362 	 */
363 	if ((bp->b_flags & B_READ) == 0) {
364 		bp->b_error = EROFS;
365 		goto bad;
366 	}
367 	/*
368 	 * If it's a null transfer, return immediately
369 	 */
370 	if (bp->b_bcount == 0)
371 		goto done;
372 	/*
373 	 * Decide which unit and partition we are talking about
374 	 */
375 	if (CDPART(bp->b_dev) != RAW_PART) {
376 		/*
377 		 * do bounds checking, adjust transfer. if error, process.
378 		 * if end of partition, just return
379 		 */
380 		if (bounds_check_with_label(bp, &cd->sc_dk.dk_label, 1) <= 0)
381 			goto done;
382 		/* otherwise, process transfer request */
383 	}
384 	opri = splbio();
385 	dp = &cd->buf_queue;
386 
387 	/*
388 	 * Place it in the queue of disk activities for this disk
389 	 */
390 	disksort(dp, bp);
391 
392 	/*
393 	 * Tell the device to get going on the transfer if it's
394 	 * not doing anything, otherwise just wait for completion
395 	 */
396 	cdstart(unit);
397 
398 	splx(opri);
399 	return;
400 
401 bad:
402 	bp->b_flags |= B_ERROR;
403 done:
404 
405 	/*
406 	 * Correctly set the buf to indicate a completed xfer
407 	 */
408 	bp->b_resid = bp->b_bcount;
409 	biodone(bp);
410 }
411 
412 /*
413  * cdstart looks to see if there is a buf waiting for the device
414  * and that the device is not already busy. If both are true,
415  * It deques the buf and creates a scsi command to perform the
416  * transfer in the buf. The transfer request will call scsi_done
417  * on completion, which will in turn call this routine again
418  * so that the next queued transfer is performed.
419  * The bufs are queued by the strategy routine (cdstrategy)
420  *
421  * This routine is also called after other non-queued requests
422  * have been made of the scsi driver, to ensure that the queue
423  * continues to be drained.
424  *
425  * must be called at the correct (highish) spl level
426  * cdstart() is called at splbio from cdstrategy and scsi_done
427  */
428 void
429 cdstart(unit)
430 	int unit;
431 {
432 	register struct cd_data *cd = cdcd.cd_devs[unit];
433 	register struct scsi_link *sc_link = cd->sc_link;
434 	struct buf *bp = 0;
435 	struct buf *dp;
436 	struct scsi_rw_big cmd;
437 	int blkno, nblks;
438 	struct partition *p;
439 
440 	SC_DEBUG(sc_link, SDEV_DB2, ("cdstart "));
441 	/*
442 	 * See if there is a buf to do and we are not already
443 	 * doing one
444 	 */
445 	while (sc_link->opennings) {
446 		/*
447 		 * there is excess capacity, but a special waits
448 		 * It'll need the adapter as soon as we clear out of the
449 		 * way and let it run (user level wait).
450 		 */
451 		if (sc_link->flags & SDEV_WAITING) {
452 			sc_link->flags &= ~SDEV_WAITING;
453 			wakeup((caddr_t)sc_link);
454 			return;
455 		}
456 
457 		/*
458 		 * See if there is a buf with work for us to do..
459 		 */
460 		dp = &cd->buf_queue;
461 		if ((bp = dp->b_actf) == NULL)	/* yes, an assign */
462 			return;
463 		dp->b_actf = bp->b_actf;
464 
465 		/*
466 		 * If the deivce has become invalid, abort all the
467 		 * reads and writes until all files have been closed and
468 		 * re-openned
469 		 */
470 		if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
471 			bp->b_error = EIO;
472 			bp->b_flags |= B_ERROR;
473 			biodone(bp);
474 			continue;
475 		}
476 
477 		/*
478 		 * We have a buf, now we should make a command
479 		 *
480 		 * First, translate the block to absolute and put it in terms
481 		 * of the logical blocksize of the device.  Really a bit silly
482 		 * until we have real partitions, but.
483 		 */
484 		blkno = bp->b_blkno / (cd->params.blksize / DEV_BSIZE);
485 		if (CDPART(bp->b_dev) != RAW_PART) {
486 			p = &cd->sc_dk.dk_label.d_partitions[CDPART(bp->b_dev)];
487 			blkno += p->p_offset;
488 		}
489 		nblks = (bp->b_bcount + (cd->params.blksize - 1)) /
490 		    cd->params.blksize;
491 
492 		/*
493 		 *  Fill out the scsi command
494 		 */
495 		bzero(&cmd, sizeof(cmd));
496 		cmd.op_code = (bp->b_flags & B_READ) ? READ_BIG : WRITE_BIG;
497 		cmd.addr_3 = (blkno & 0xff000000) >> 24;
498 		cmd.addr_2 = (blkno & 0xff0000) >> 16;
499 		cmd.addr_1 = (blkno & 0xff00) >> 8;
500 		cmd.addr_0 = blkno & 0xff;
501 		cmd.length2 = (nblks & 0xff00) >> 8;
502 		cmd.length1 = (nblks & 0xff);
503 
504 		/*
505 		 * Call the routine that chats with the adapter.
506 		 * Note: we cannot sleep as we may be an interrupt
507 		 */
508 		if (scsi_scsi_cmd(sc_link, (struct scsi_generic *) &cmd,
509 		    sizeof(cmd), (u_char *) bp->b_data, bp->b_bcount,
510 		    CDRETRIES, 30000, bp, SCSI_NOSLEEP |
511 		    ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))
512 		    != SUCCESSFULLY_QUEUED)
513 			printf("%s: not queued", cd->sc_dev.dv_xname);
514 	}
515 }
516 
517 /*
518  * Perform special action on behalf of the user.
519  * Knows about the internals of this device
520  */
521 int
522 cdioctl(dev, cmd, addr, flag)
523 	dev_t dev;
524 	int cmd;
525 	caddr_t addr;
526 	int flag;
527 {
528 	int error;
529 	int unit, part;
530 	register struct cd_data *cd;
531 
532 	/*
533 	 * Find the device that the user is talking about
534 	 */
535 	unit = CDUNIT(dev);
536 	part = CDPART(dev);
537 	cd = cdcd.cd_devs[unit];
538 	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdioctl 0x%x ", cmd));
539 
540 	/*
541 	 * If the device is not valid.. abandon ship
542 	 */
543 	if (!(cd->sc_link->flags & SDEV_MEDIA_LOADED))
544 		return EIO;
545 
546 	switch (cmd) {
547 	case DIOCSBAD:
548 		return EINVAL;
549 
550 	case DIOCGDINFO:
551 		*(struct disklabel *) addr = cd->sc_dk.dk_label;
552 		return 0;
553 
554 	case DIOCGPART:
555 		((struct partinfo *) addr)->disklab = &cd->sc_dk.dk_label;
556 		((struct partinfo *) addr)->part =
557 		    &cd->sc_dk.dk_label.d_partitions[CDPART(dev)];
558 		return 0;
559 
560 		/*
561 		 * a bit silly, but someone might want to test something on a
562 		 * section of cdrom.
563 		 */
564 	case DIOCWDINFO:
565 	case DIOCSDINFO:
566 		if ((flag & FWRITE) == 0)
567 			return EBADF;
568 		error = setdisklabel(&cd->sc_dk.dk_label,
569 		    (struct disklabel *) addr, 0, 0);
570 		return error;
571 
572 	case DIOCWLABEL:
573 		return EBADF;
574 
575 	case CDIOCPLAYTRACKS: {
576 		struct ioc_play_track *args = (struct ioc_play_track *) addr;
577 		struct cd_mode_data data;
578 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
579 			return error;
580 		data.page.audio.flags &= ~CD_PA_SOTC;
581 		data.page.audio.flags |= CD_PA_IMMED;
582 		if (error = cd_set_mode(cd, &data))
583 			return error;
584 		return cd_play_tracks(cd, args->start_track, args->start_index,
585 		    args->end_track, args->end_index);
586 	}
587 	case CDIOCPLAYMSF: {
588 		struct ioc_play_msf *args
589 		= (struct ioc_play_msf *) addr;
590 		struct cd_mode_data data;
591 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
592 			return error;
593 		data.page.audio.flags &= ~CD_PA_SOTC;
594 		data.page.audio.flags |= CD_PA_IMMED;
595 		if (error = cd_set_mode(cd, &data))
596 			return error;
597 		return cd_play_msf(cd, args->start_m, args->start_s,
598 		    args->start_f, args->end_m, args->end_s, args->end_f);
599 	}
600 	case CDIOCPLAYBLOCKS: {
601 		struct ioc_play_blocks *args
602 		= (struct ioc_play_blocks *) addr;
603 		struct cd_mode_data data;
604 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
605 			return error;
606 		data.page.audio.flags &= ~CD_PA_SOTC;
607 		data.page.audio.flags |= CD_PA_IMMED;
608 		if (error = cd_set_mode(cd, &data))
609 			return error;
610 		return cd_play(cd, args->blk, args->len);
611 	}
612 	case CDIOCREADSUBCHANNEL: {
613 		struct ioc_read_subchannel *args
614 		= (struct ioc_read_subchannel *) addr;
615 		struct cd_sub_channel_info data;
616 		u_int32 len = args->data_len;
617 		if (len > sizeof(data) ||
618 		    len < sizeof(struct cd_sub_channel_header))
619 			return EINVAL;
620 		if (error = cd_read_subchannel(cd, args->address_format,
621 		    args->data_format, args->track, &data, len))
622 			return error;
623 		len = min(len, ((data.header.data_len[0] << 8) +
624 		    data.header.data_len[1] +
625 		    sizeof(struct cd_sub_channel_header)));
626 		return copyout(&data, args->data, len);
627 	}
628 	case CDIOREADTOCHEADER: {
629 		struct ioc_toc_header th;
630 		if (error = cd_read_toc(cd, 0, 0, &th, sizeof(th)))
631 			return error;
632 		th.len = ntohs(th.len);
633 		bcopy(&th, addr, sizeof(th));
634 		return 0;
635 	}
636 	case CDIOREADTOCENTRYS: {
637 		struct cd_toc {
638 			struct ioc_toc_header header;
639 			struct cd_toc_entry entries[65];
640 		} data;
641 		struct ioc_read_toc_entry *te =
642 		(struct ioc_read_toc_entry *) addr;
643 		struct ioc_toc_header *th;
644 		u_int32 len = te->data_len;
645 		th = &data.header;
646 
647 		if (len > sizeof(data.entries) ||
648 		    len < sizeof(struct cd_toc_entry))
649 			return EINVAL;
650 		if (error = cd_read_toc(cd, te->address_format,
651 		    te->starting_track, (struct cd_toc_entry *) &data,
652 		    len + sizeof(struct ioc_toc_header)))
653 			return error;
654 		len = min(len, ntohs(th->len) - (sizeof(th->starting_track) +
655 		    sizeof(th->ending_track)));
656 		return copyout(data.entries, te->data, len);
657 	}
658 	case CDIOCSETPATCH: {
659 		struct ioc_patch *arg = (struct ioc_patch *) addr;
660 		struct cd_mode_data data;
661 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
662 			return error;
663 		data.page.audio.port[LEFT_PORT].channels = arg->patch[0];
664 		data.page.audio.port[RIGHT_PORT].channels = arg->patch[1];
665 		data.page.audio.port[2].channels = arg->patch[2];
666 		data.page.audio.port[3].channels = arg->patch[3];
667 		return cd_set_mode(cd, &data);
668 	}
669 	case CDIOCGETVOL: {
670 		struct ioc_vol *arg = (struct ioc_vol *) addr;
671 		struct cd_mode_data data;
672 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
673 			return error;
674 		arg->vol[LEFT_PORT] = data.page.audio.port[LEFT_PORT].volume;
675 		arg->vol[RIGHT_PORT] = data.page.audio.port[RIGHT_PORT].volume;
676 		arg->vol[2] = data.page.audio.port[2].volume;
677 		arg->vol[3] = data.page.audio.port[3].volume;
678 		return 0;
679 	}
680 	case CDIOCSETVOL: {
681 		struct ioc_vol *arg = (struct ioc_vol *) addr;
682 		struct cd_mode_data data;
683 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
684 			return error;
685 		data.page.audio.port[LEFT_PORT].channels = CHANNEL_0;
686 		data.page.audio.port[LEFT_PORT].volume = arg->vol[LEFT_PORT];
687 		data.page.audio.port[RIGHT_PORT].channels = CHANNEL_1;
688 		data.page.audio.port[RIGHT_PORT].volume = arg->vol[RIGHT_PORT];
689 		data.page.audio.port[2].volume = arg->vol[2];
690 		data.page.audio.port[3].volume = arg->vol[3];
691 		return cd_set_mode(cd, &data);
692 	}
693 	case CDIOCSETMONO: {
694 		struct ioc_vol *arg = (struct ioc_vol *) addr;
695 		struct cd_mode_data data;
696 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
697 			return error;
698 		data.page.audio.port[LEFT_PORT].channels =
699 		    LEFT_CHANNEL | RIGHT_CHANNEL | 4 | 8;
700 		data.page.audio.port[RIGHT_PORT].channels =
701 		    LEFT_CHANNEL | RIGHT_CHANNEL;
702 		data.page.audio.port[2].channels = 0;
703 		data.page.audio.port[3].channels = 0;
704 		return cd_set_mode(cd, &data);
705 	}
706 	case CDIOCSETSTEREO: {
707 		struct ioc_vol *arg = (struct ioc_vol *) addr;
708 		struct cd_mode_data data;
709 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
710 			return error;
711 		data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
712 		data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
713 		data.page.audio.port[2].channels = 0;
714 		data.page.audio.port[3].channels = 0;
715 		return cd_set_mode(cd, &data);
716 	}
717 	case CDIOCSETMUTE: {
718 		struct ioc_vol *arg = (struct ioc_vol *) addr;
719 		struct cd_mode_data data;
720 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
721 			return error;
722 		data.page.audio.port[LEFT_PORT].channels = 0;
723 		data.page.audio.port[RIGHT_PORT].channels = 0;
724 		data.page.audio.port[2].channels = 0;
725 		data.page.audio.port[3].channels = 0;
726 		return cd_set_mode(cd, &data);
727 	}
728 	case CDIOCSETLEFT: {
729 		struct ioc_vol *arg = (struct ioc_vol *) addr;
730 		struct cd_mode_data data;
731 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
732 			return error;
733 		data.page.audio.port[LEFT_PORT].channels = LEFT_CHANNEL;
734 		data.page.audio.port[RIGHT_PORT].channels = LEFT_CHANNEL;
735 		data.page.audio.port[2].channels = 0;
736 		data.page.audio.port[3].channels = 0;
737 		return cd_set_mode(cd, &data);
738 	}
739 	case CDIOCSETRIGHT: {
740 		struct ioc_vol *arg = (struct ioc_vol *) addr;
741 		struct cd_mode_data data;
742 		if (error = cd_get_mode(cd, &data, AUDIO_PAGE))
743 			return error;
744 		data.page.audio.port[LEFT_PORT].channels = RIGHT_CHANNEL;
745 		data.page.audio.port[RIGHT_PORT].channels = RIGHT_CHANNEL;
746 		data.page.audio.port[2].channels = 0;
747 		data.page.audio.port[3].channels = 0;
748 		return cd_set_mode(cd, &data);
749 	}
750 	case CDIOCRESUME:
751 		return cd_pause(cd, 1);
752 	case CDIOCPAUSE:
753 		return cd_pause(cd, 0);
754 	case CDIOCSTART:
755 		return scsi_start(cd->sc_link, SSS_START, 0);
756 	case CDIOCSTOP:
757 		return scsi_start(cd->sc_link, SSS_STOP, 0);
758 	case CDIOCEJECT:
759 		return scsi_start(cd->sc_link, SSS_LOEJ, 0);
760 	case CDIOCALLOW:
761 		return scsi_prevent(cd->sc_link, PR_ALLOW, 0);
762 	case CDIOCPREVENT:
763 		return scsi_prevent(cd->sc_link, PR_PREVENT, 0);
764 	case CDIOCSETDEBUG:
765 		cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2);
766 		return 0;
767 	case CDIOCCLRDEBUG:
768 		cd->sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2);
769 		return 0;
770 	case CDIOCRESET:
771 		return cd_reset(cd);
772 	default:
773 		if (part != RAW_PART)
774 			return ENOTTY;
775 		return scsi_do_ioctl(cd->sc_link, cmd, addr, flag);
776 	}
777 #ifdef DIAGNOSTIC
778 	panic("cdioctl: impossible");
779 #endif
780 }
781 
782 /*
783  * Load the label information on the named device
784  * Actually fabricate a disklabel
785  *
786  * EVENTUALLY take information about different
787  * data tracks from the TOC and put it in the disklabel
788  */
789 int
790 cdgetdisklabel(cd)
791 	struct cd_data *cd;
792 {
793 	char *errstring;
794 
795 	bzero(&cd->sc_dk.dk_label, sizeof(struct disklabel));
796 	bzero(&cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
797 	/*
798 	 * make partition 0 the whole disk
799 	 * remember that comparisons with the partition are done
800 	 * assuming the blocks are 512 bytes so fudge it.
801 	 */
802 	cd->sc_dk.dk_label.d_partitions[0].p_offset = 0;
803 	cd->sc_dk.dk_label.d_partitions[0].p_size =
804 	    cd->params.disksize * (cd->params.blksize / DEV_BSIZE);
805 	cd->sc_dk.dk_label.d_partitions[0].p_fstype = FS_ISO9660;
806 	cd->sc_dk.dk_label.d_npartitions = 1;
807 
808 	cd->sc_dk.dk_label.d_secsize = cd->params.blksize;
809 	cd->sc_dk.dk_label.d_ntracks = 1;
810 	cd->sc_dk.dk_label.d_nsectors = 100;
811 	cd->sc_dk.dk_label.d_ncylinders = (cd->params.disksize / 100) + 1;
812 	cd->sc_dk.dk_label.d_secpercyl = 100;
813 
814 	strncpy(cd->sc_dk.dk_label.d_typename, "scsi cd_rom", 16);
815 	strncpy(cd->sc_dk.dk_label.d_packname, "ficticious", 16);
816 	cd->sc_dk.dk_label.d_secperunit = cd->params.disksize;
817 	cd->sc_dk.dk_label.d_rpm = 300;
818 	cd->sc_dk.dk_label.d_interleave = 1;
819 	cd->sc_dk.dk_label.d_flags = D_REMOVABLE;
820 	cd->sc_dk.dk_label.d_magic = DISKMAGIC;
821 	cd->sc_dk.dk_label.d_magic2 = DISKMAGIC;
822 	cd->sc_dk.dk_label.d_checksum = dkcksum(&cd->sc_dk.dk_label);
823 
824 	/*
825 	 * Signal to other users and routines that we now have a
826 	 * disklabel that represents the media (maybe)
827 	 */
828 	return 0;
829 }
830 
831 /*
832  * Find out from the device what it's capacity is
833  */
834 u_int32
835 cd_size(cd, flags)
836 	struct cd_data *cd;
837 	int flags;
838 {
839 	struct scsi_read_cd_cap_data rdcap;
840 	struct scsi_read_cd_capacity scsi_cmd;
841 	u_int32 size, blksize;
842 	int error;
843 
844 	/*
845 	 * make up a scsi command and ask the scsi driver to do
846 	 * it for you.
847 	 */
848 	bzero(&scsi_cmd, sizeof(scsi_cmd));
849 	scsi_cmd.op_code = READ_CD_CAPACITY;
850 
851 	/*
852 	 * If the command works, interpret the result as a 4 byte
853 	 * number of blocks and a blocksize
854 	 */
855 	error = scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
856 	    sizeof(scsi_cmd), (u_char *) &rdcap, sizeof(rdcap), CDRETRIES,
857 	    20000, NULL, SCSI_DATA_IN | flags);
858 	if (error == EBUSY) {
859 		if (!(flags & SCSI_SILENT))
860 			printf("%s: waiting for drive to spin up\n",
861 			    cd->sc_dev.dv_xname);
862 		if (flags & SCSI_NOSLEEP)
863 			delay(2000000);
864 		else
865 			tsleep(cd, PRIBIO + 1, "cd_size", 2 * hz);
866 		error = scsi_scsi_cmd(cd->sc_link,
867 		    (struct scsi_generic *) &scsi_cmd, sizeof(scsi_cmd),
868 		    (u_char *) &rdcap, sizeof(rdcap), CDRETRIES, 20000, NULL,
869 		    SCSI_DATA_IN | flags);
870 	}
871 
872 	if (error) {
873 		if (!(flags & SCSI_SILENT))
874 			printf("%s: could not get size\n",
875 			    cd->sc_dev.dv_xname);
876 		return 0;
877 	}
878 
879 	blksize = (rdcap.length_3 << 24) + (rdcap.length_2 << 16) +
880 	    (rdcap.length_1 << 8) + rdcap.length_0;
881 	if (blksize < 512)
882 		blksize = 2048;	/* some drives lie ! */
883 	cd->params.blksize = blksize;
884 
885 	size = (rdcap.addr_3 << 24) + (rdcap.addr_2 << 16) +
886 	    (rdcap.addr_1 << 8) + rdcap.addr_0 + 1;
887 	if (size < 100)
888 		size = 400000;	/* ditto */
889 	cd->params.disksize = size;
890 
891 	return size;
892 }
893 
894 /*
895  * Get the requested page into the buffer given
896  */
897 int
898 cd_get_mode(cd, data, page)
899 	struct cd_data *cd;
900 	struct cd_mode_data *data;
901 	int page;
902 {
903 	struct scsi_mode_sense scsi_cmd;
904 	int error;
905 
906 	bzero(&scsi_cmd, sizeof(scsi_cmd));
907 	bzero(data, sizeof(*data));
908 	scsi_cmd.op_code = MODE_SENSE;
909 	scsi_cmd.page = page;
910 	scsi_cmd.length = sizeof(*data) & 0xff;
911 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
912 	    sizeof(scsi_cmd), (u_char *) data, sizeof(*data), CDRETRIES, 20000,
913 	    NULL, SCSI_DATA_IN);
914 }
915 
916 /*
917  * Get the requested page into the buffer given
918  */
919 int
920 cd_set_mode(cd, data)
921 	struct cd_data *cd;
922 	struct cd_mode_data *data;
923 {
924 	struct scsi_mode_select scsi_cmd;
925 
926 	bzero(&scsi_cmd, sizeof(scsi_cmd));
927 	scsi_cmd.op_code = MODE_SELECT;
928 	scsi_cmd.byte2 |= SMS_PF;
929 	scsi_cmd.length = sizeof(*data) & 0xff;
930 	data->header.data_length = 0;
931 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
932 	    sizeof(scsi_cmd), (u_char *) data, sizeof(*data), CDRETRIES, 20000,
933 	    NULL, SCSI_DATA_OUT);
934 }
935 
936 /*
937  * Get scsi driver to send a "start playing" command
938  */
939 int
940 cd_play(cd, blkno, nblks)
941 	struct cd_data *cd;
942 	int blkno, nblks;
943 {
944 	struct scsi_play scsi_cmd;
945 
946 	bzero(&scsi_cmd, sizeof(scsi_cmd));
947 	scsi_cmd.op_code = PLAY;
948 	scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
949 	scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
950 	scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
951 	scsi_cmd.blk_addr[3] = blkno & 0xff;
952 	scsi_cmd.xfer_len[0] = (nblks >> 8) & 0xff;
953 	scsi_cmd.xfer_len[1] = nblks & 0xff;
954 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
955 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 200000, NULL, 0);
956 }
957 
958 /*
959  * Get scsi driver to send a "start playing" command
960  */
961 int
962 cd_play_big(cd, blkno, nblks)
963 	struct cd_data *cd;
964 	int blkno, nblks;
965 {
966 	struct scsi_play_big scsi_cmd;
967 
968 	bzero(&scsi_cmd, sizeof(scsi_cmd));
969 	scsi_cmd.op_code = PLAY_BIG;
970 	scsi_cmd.blk_addr[0] = (blkno >> 24) & 0xff;
971 	scsi_cmd.blk_addr[1] = (blkno >> 16) & 0xff;
972 	scsi_cmd.blk_addr[2] = (blkno >> 8) & 0xff;
973 	scsi_cmd.blk_addr[3] = blkno & 0xff;
974 	scsi_cmd.xfer_len[0] = (nblks >> 24) & 0xff;
975 	scsi_cmd.xfer_len[1] = (nblks >> 16) & 0xff;
976 	scsi_cmd.xfer_len[2] = (nblks >> 8) & 0xff;
977 	scsi_cmd.xfer_len[3] = nblks & 0xff;
978 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
979 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
980 }
981 
982 /*
983  * Get scsi driver to send a "start playing" command
984  */
985 int
986 cd_play_tracks(cd, strack, sindex, etrack, eindex)
987 	struct cd_data *cd;
988 	int strack, sindex, etrack, eindex;
989 {
990 	struct scsi_play_track scsi_cmd;
991 
992 	bzero(&scsi_cmd, sizeof(scsi_cmd));
993 	scsi_cmd.op_code = PLAY_TRACK;
994 	scsi_cmd.start_track = strack;
995 	scsi_cmd.start_index = sindex;
996 	scsi_cmd.end_track = etrack;
997 	scsi_cmd.end_index = eindex;
998 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
999 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 20000, NULL, 0);
1000 }
1001 
1002 /*
1003  * Get scsi driver to send a "play msf" command
1004  */
1005 int
1006 cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
1007 	struct cd_data *cd;
1008 	int startm, starts, startf, endm, ends, endf;
1009 {
1010 	struct scsi_play_msf scsi_cmd;
1011 
1012 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1013 	scsi_cmd.op_code = PLAY_MSF;
1014 	scsi_cmd.start_m = startm;
1015 	scsi_cmd.start_s = starts;
1016 	scsi_cmd.start_f = startf;
1017 	scsi_cmd.end_m = endm;
1018 	scsi_cmd.end_s = ends;
1019 	scsi_cmd.end_f = endf;
1020 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
1021 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
1022 }
1023 
1024 /*
1025  * Get scsi driver to send a "start up" command
1026  */
1027 int
1028 cd_pause(cd, go)
1029 	struct cd_data *cd;
1030 	int go;
1031 {
1032 	struct scsi_pause scsi_cmd;
1033 
1034 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1035 	scsi_cmd.op_code = PAUSE;
1036 	scsi_cmd.resume = go;
1037 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
1038 	    sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
1039 }
1040 
1041 /*
1042  * Get scsi driver to send a "RESET" command
1043  */
1044 int
1045 cd_reset(cd)
1046 	struct cd_data *cd;
1047 {
1048 
1049 	return scsi_scsi_cmd(cd->sc_link, 0, 0, 0, 0, CDRETRIES, 2000, NULL,
1050 	    SCSI_RESET);
1051 }
1052 
1053 /*
1054  * Read subchannel
1055  */
1056 int
1057 cd_read_subchannel(cd, mode, format, track, data, len)
1058 	struct cd_data *cd;
1059 	int mode, format, len;
1060 	struct cd_sub_channel_info *data;
1061 {
1062 	struct scsi_read_subchannel scsi_cmd;
1063 
1064 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1065 	scsi_cmd.op_code = READ_SUBCHANNEL;
1066 	if (mode == CD_MSF_FORMAT)
1067 		scsi_cmd.byte2 |= CD_MSF;
1068 	scsi_cmd.byte3 = SRS_SUBQ;
1069 	scsi_cmd.subchan_format = format;
1070 	scsi_cmd.track = track;
1071 	scsi_cmd.data_len[0] = (len) >> 8;
1072 	scsi_cmd.data_len[1] = (len) & 0xff;
1073 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
1074 	    sizeof(struct scsi_read_subchannel), (u_char *) data, len,
1075 	    CDRETRIES, 5000, NULL, SCSI_DATA_IN);
1076 }
1077 
1078 /*
1079  * Read table of contents
1080  */
1081 int
1082 cd_read_toc(cd, mode, start, data, len)
1083 	struct cd_data *cd;
1084 	int mode, start, len;
1085 	struct cd_toc_entry *data;
1086 {
1087 	struct scsi_read_toc scsi_cmd;
1088 	int ntoc;
1089 
1090 	bzero(&scsi_cmd, sizeof(scsi_cmd));
1091 	/*if (len!=sizeof(struct ioc_toc_header))
1092 	 * ntoc=((len)-sizeof(struct ioc_toc_header))/sizeof(struct cd_toc_entry);
1093 	 * else */
1094 	ntoc = len;
1095 	scsi_cmd.op_code = READ_TOC;
1096 	if (mode == CD_MSF_FORMAT)
1097 		scsi_cmd.byte2 |= CD_MSF;
1098 	scsi_cmd.from_track = start;
1099 	scsi_cmd.data_len[0] = (ntoc) >> 8;
1100 	scsi_cmd.data_len[1] = (ntoc) & 0xff;
1101 	return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *) &scsi_cmd,
1102 	    sizeof(struct scsi_read_toc), (u_char *) data, len, CDRETRIES,
1103 	    5000, NULL, SCSI_DATA_IN);
1104 }
1105 
1106 #define b2tol(a)	(((unsigned)(a##_1) << 8) + (unsigned)a##_0)
1107 
1108 /*
1109  * Get the scsi driver to send a full inquiry to the device and use the
1110  * results to fill out the disk parameter structure.
1111  */
1112 int
1113 cd_get_parms(cd, flags)
1114 	struct cd_data *cd;
1115 	int flags;
1116 {
1117 
1118 	/*
1119 	 * First check if we have it all loaded
1120 	 */
1121 	if (cd->sc_link->flags & SDEV_MEDIA_LOADED)
1122 		return 0;
1123 
1124 	/*
1125 	 * give a number of sectors so that sec * trks * cyls
1126 	 * is <= disk_size
1127 	 */
1128 	if (!cd_size(cd, flags))
1129 		return ENXIO;
1130 
1131 	cd->sc_link->flags |= SDEV_MEDIA_LOADED;
1132 	return 0;
1133 }
1134 
1135 int
1136 cdsize(dev)
1137 	dev_t dev;
1138 {
1139 
1140 	return -1;
1141 }
1142 
1143 int
1144 cddump()
1145 {
1146 
1147 	/* Not implemented. */
1148 	return EINVAL;
1149 }
1150