cd.c revision 1.109
1/*	$NetBSD: cd.c,v 1.109 1998/01/12 09:49:11 thorpej Exp $	*/
2
3/*
4 * Copyright (c) 1994, 1995, 1997 Charles M. 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 M. 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 "rnd.h"
50
51#include <sys/types.h>
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/kernel.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#include <sys/proc.h>
67#include <sys/conf.h>
68#if NRND > 0
69#include <sys/rnd.h>
70#endif
71
72#include <dev/scsipi/scsipi_all.h>
73#include <dev/scsipi/scsipi_cd.h>
74#include <dev/scsipi/scsipi_disk.h>	/* rw_big and start_stop come */
75					/* from there */
76#include <dev/scsipi/scsi_disk.h>	/* rw comes from there */
77#include <dev/scsipi/scsipiconf.h>
78#include <dev/scsipi/cd_link.h>
79
80#include "cd.h"				/* NCD_SCSI and NCD_ATAPI come */
81					/* from here */
82
83#define	CDUNIT(z)			DISKUNIT(z)
84#define	CDPART(z)			DISKPART(z)
85#define	MAKECDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
86
87#define MAXTRACK	99
88#define CD_BLOCK_OFFSET	150
89#define CD_FRAMES	75
90#define CD_SECS		60
91
92struct cd_toc {
93	struct ioc_toc_header header;
94	struct cd_toc_entry entries[MAXTRACK+1]; /* One extra for the */
95						 /* leadout */
96};
97
98int	cdlock __P((struct cd_softc *));
99void	cdunlock __P((struct cd_softc *));
100void	cdstart __P((void *));
101void	cdminphys __P((struct buf *));
102void	cdgetdefaultlabel __P((struct cd_softc *, struct disklabel *));
103void	cdgetdisklabel __P((struct cd_softc *));
104void	cddone __P((struct scsipi_xfer *));
105u_long	cd_size __P((struct cd_softc *, int));
106void	lba2msf __P((u_long, u_char *, u_char *, u_char *));
107u_long	msf2lba __P((u_char, u_char, u_char));
108int	cd_play __P((struct cd_softc *, int, int));
109int	cd_play_tracks __P((struct cd_softc *, int, int, int, int));
110int	cd_play_msf __P((struct cd_softc *, int, int, int, int, int, int));
111int	cd_pause __P((struct cd_softc *, int));
112int	cd_reset __P((struct cd_softc *));
113int	cd_read_subchannel __P((struct cd_softc *, int, int, int,
114	    struct cd_sub_channel_info *, int));
115int	cd_read_toc __P((struct cd_softc *, int, int, void *, int));
116int	cd_get_parms __P((struct cd_softc *, int));
117int	cd_load_toc __P((struct cd_softc *, struct cd_toc *));
118
119struct dkdriver cddkdriver = { cdstrategy };
120
121struct scsipi_device cd_switch = {
122	NULL,			/* use default error handler */
123	cdstart,		/* we have a queue, which is started by this */
124	NULL,			/* we do not have an async handler */
125	cddone,			/* deal with stats at interrupt time */
126};
127
128extern struct cfdriver cd_cd;
129
130/*
131 * The routine called by the low level scsi routine when it discovers
132 * A device suitable for this driver
133 */
134void
135cdattach(parent, cd, sc_link, ops)
136	struct device *parent;
137	struct cd_softc *cd;
138	struct scsipi_link *sc_link;
139	const struct cd_ops *ops;
140{
141	SC_DEBUG(sc_link, SDEV_DB2, ("cdattach: "));
142
143	/*
144	 * Store information needed to contact our base driver
145	 */
146	cd->sc_link = sc_link;
147	cd->sc_ops = ops;
148	sc_link->device = &cd_switch;
149	sc_link->device_softc = cd;
150	if (sc_link->openings > CDOUTSTANDING)
151		sc_link->openings = CDOUTSTANDING;
152
153	/*
154	 * Initialize and attach the disk structure.
155	 */
156  	cd->sc_dk.dk_driver = &cddkdriver;
157	cd->sc_dk.dk_name = cd->sc_dev.dv_xname;
158	disk_attach(&cd->sc_dk);
159
160#if !defined(i386)
161	dk_establish(&cd->sc_dk, &cd->sc_dev);		/* XXX */
162#endif
163
164	printf("\n");
165
166#if NRND > 0
167	rnd_attach_source(&cd->rnd_source, cd->sc_dev.dv_xname, RND_TYPE_DISK);
168#endif
169}
170
171/*
172 * Wait interruptibly for an exclusive lock.
173 *
174 * XXX
175 * Several drivers do this; it should be abstracted and made MP-safe.
176 */
177int
178cdlock(cd)
179	struct cd_softc *cd;
180{
181	int error;
182
183	while ((cd->flags & CDF_LOCKED) != 0) {
184		cd->flags |= CDF_WANTED;
185		if ((error = tsleep(cd, PRIBIO | PCATCH, "cdlck", 0)) != 0)
186			return (error);
187	}
188	cd->flags |= CDF_LOCKED;
189	return (0);
190}
191
192/*
193 * Unlock and wake up any waiters.
194 */
195void
196cdunlock(cd)
197	struct cd_softc *cd;
198{
199
200	cd->flags &= ~CDF_LOCKED;
201	if ((cd->flags & CDF_WANTED) != 0) {
202		cd->flags &= ~CDF_WANTED;
203		wakeup(cd);
204	}
205}
206
207/*
208 * open the device. Make sure the partition info is a up-to-date as can be.
209 */
210int
211cdopen(dev, flag, fmt, p)
212	dev_t dev;
213	int flag, fmt;
214	struct proc *p;
215{
216	struct cd_softc *cd;
217	struct scsipi_link *sc_link;
218	int unit, part;
219	int error;
220
221	unit = CDUNIT(dev);
222	if (unit >= cd_cd.cd_ndevs)
223		return (ENXIO);
224	cd = cd_cd.cd_devs[unit];
225	if (cd == NULL)
226		return (ENXIO);
227
228	sc_link = cd->sc_link;
229
230	SC_DEBUG(sc_link, SDEV_DB1,
231	    ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
232	    cd_cd.cd_ndevs, CDPART(dev)));
233
234	if ((error = cdlock(cd)) != 0)
235		return (error);
236
237	if (cd->sc_dk.dk_openmask != 0) {
238		/*
239		 * If any partition is open, but the disk has been invalidated,
240		 * disallow further opens.
241		 */
242		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
243			error = EIO;
244			goto bad3;
245		}
246	} else {
247		/* Check that it is still responding and ok. */
248		error = scsipi_test_unit_ready(sc_link,
249		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE |
250		    SCSI_IGNORE_NOT_READY);
251		SC_DEBUG(sc_link, SDEV_DB1,
252		    ("cdopen: scsipi_test_unit_ready, error=%d\n", error));
253		if (error)
254			goto bad3;
255
256		/* Start the pack spinning if necessary. */
257		error = scsipi_start(sc_link, SSS_START,
258		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE |
259		    SCSI_SILENT);
260		SC_DEBUG(sc_link, SDEV_DB1,
261		    ("cdopen: scsipi_start, error=%d\n", error));
262		if (error)
263			goto bad3;
264
265		sc_link->flags |= SDEV_OPEN;
266
267		/* Lock the pack in. */
268		error = scsipi_prevent(sc_link, PR_PREVENT,
269		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
270		SC_DEBUG(sc_link, SDEV_DB1,
271		    ("cdopen: scsipi_prevent, error=%d\n", error));
272		if (error)
273			goto bad;
274
275		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
276			sc_link->flags |= SDEV_MEDIA_LOADED;
277
278			/* Load the physical device parameters. */
279			if (cd_get_parms(cd, 0) != 0) {
280				error = ENXIO;
281				goto bad2;
282			}
283			SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded "));
284
285			/* Fabricate a disk label. */
286			cdgetdisklabel(cd);
287			SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated "));
288		}
289	}
290
291	part = CDPART(dev);
292
293	/* Check that the partition exists. */
294	if (part != RAW_PART &&
295	    (part >= cd->sc_dk.dk_label->d_npartitions ||
296	    cd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
297		error = ENXIO;
298		goto bad;
299	}
300
301	/* Insure only one open at a time. */
302	switch (fmt) {
303	case S_IFCHR:
304		cd->sc_dk.dk_copenmask |= (1 << part);
305		break;
306	case S_IFBLK:
307		cd->sc_dk.dk_bopenmask |= (1 << part);
308		break;
309	}
310	cd->sc_dk.dk_openmask =
311	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
312
313	SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
314	cdunlock(cd);
315	return (0);
316
317bad2:
318	sc_link->flags &= ~SDEV_MEDIA_LOADED;
319
320bad:
321	if (cd->sc_dk.dk_openmask == 0) {
322		scsipi_prevent(sc_link, PR_ALLOW,
323		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
324		sc_link->flags &= ~SDEV_OPEN;
325	}
326
327bad3:
328	cdunlock(cd);
329	return (error);
330}
331
332/*
333 * close the device.. only called if we are the LAST
334 * occurence of an open device
335 */
336int
337cdclose(dev, flag, fmt, p)
338	dev_t dev;
339	int flag, fmt;
340	struct proc *p;
341{
342	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
343	int part = CDPART(dev);
344	int error;
345
346	if ((error = cdlock(cd)) != 0)
347		return (error);
348
349	switch (fmt) {
350	case S_IFCHR:
351		cd->sc_dk.dk_copenmask &= ~(1 << part);
352		break;
353	case S_IFBLK:
354		cd->sc_dk.dk_bopenmask &= ~(1 << part);
355		break;
356	}
357	cd->sc_dk.dk_openmask =
358	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
359
360	if (cd->sc_dk.dk_openmask == 0) {
361		/* XXXX Must wait for I/O to complete! */
362
363		scsipi_prevent(cd->sc_link, PR_ALLOW,
364		    SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
365		cd->sc_link->flags &= ~SDEV_OPEN;
366	}
367
368	cdunlock(cd);
369	return (0);
370}
371
372/*
373 * Actually translate the requested transfer into one the physical driver can
374 * understand.  The transfer is described by a buf and will include only one
375 * physical transfer.
376 */
377void
378cdstrategy(bp)
379	struct buf *bp;
380{
381	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
382	int opri;
383
384	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdstrategy "));
385	SC_DEBUG(cd->sc_link, SDEV_DB1,
386	    ("%ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
387	/*
388	 * The transfer must be a whole number of blocks.
389	 */
390	if ((bp->b_bcount % cd->sc_dk.dk_label->d_secsize) != 0) {
391		bp->b_error = EINVAL;
392		goto bad;
393	}
394	/*
395	 * If the device has been made invalid, error out
396	 * maybe the media changed
397	 */
398	if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
399		bp->b_error = EIO;
400		goto bad;
401	}
402	/*
403	 * If it's a null transfer, return immediately
404	 */
405	if (bp->b_bcount == 0)
406		goto done;
407
408	/*
409	 * Do bounds checking, adjust transfer. if error, process.
410	 * If end of partition, just return.
411	 */
412	if (CDPART(bp->b_dev) != RAW_PART &&
413	    bounds_check_with_label(bp, cd->sc_dk.dk_label,
414	    (cd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0)
415		goto done;
416
417	opri = splbio();
418
419	/*
420	 * Place it in the queue of disk activities for this disk
421	 */
422	disksort(&cd->buf_queue, bp);
423
424	/*
425	 * Tell the device to get going on the transfer if it's
426	 * not doing anything, otherwise just wait for completion
427	 */
428	cdstart(cd);
429
430	splx(opri);
431	return;
432
433bad:
434	bp->b_flags |= B_ERROR;
435done:
436	/*
437	 * Correctly set the buf to indicate a completed xfer
438	 */
439	bp->b_resid = bp->b_bcount;
440	biodone(bp);
441}
442
443/*
444 * cdstart looks to see if there is a buf waiting for the device
445 * and that the device is not already busy. If both are true,
446 * It deques the buf and creates a scsi command to perform the
447 * transfer in the buf. The transfer request will call scsipi_done
448 * on completion, which will in turn call this routine again
449 * so that the next queued transfer is performed.
450 * The bufs are queued by the strategy routine (cdstrategy)
451 *
452 * This routine is also called after other non-queued requests
453 * have been made of the scsi driver, to ensure that the queue
454 * continues to be drained.
455 *
456 * must be called at the correct (highish) spl level
457 * cdstart() is called at splbio from cdstrategy and scsipi_done
458 */
459void
460cdstart(v)
461	register void *v;
462{
463	register struct cd_softc *cd = v;
464	register struct scsipi_link *sc_link = cd->sc_link;
465	struct disklabel *lp = cd->sc_dk.dk_label;
466	struct buf *bp = 0;
467	struct buf *dp;
468	struct scsipi_rw_big cmd_big;
469#if NCD_SCSI > 0
470	struct scsi_rw cmd_small;
471#endif
472	struct scsipi_generic *cmdp;
473	int blkno, nblks, cmdlen;
474	struct partition *p;
475
476	SC_DEBUG(sc_link, SDEV_DB2, ("cdstart "));
477	/*
478	 * Check if the device has room for another command
479	 */
480	while (sc_link->openings > 0) {
481		/*
482		 * there is excess capacity, but a special waits
483		 * It'll need the adapter as soon as we clear out of the
484		 * way and let it run (user level wait).
485		 */
486		if (sc_link->flags & SDEV_WAITING) {
487			sc_link->flags &= ~SDEV_WAITING;
488			wakeup((caddr_t)sc_link);
489			return;
490		}
491
492		/*
493		 * See if there is a buf with work for us to do..
494		 */
495		dp = &cd->buf_queue;
496		if ((bp = dp->b_actf) == NULL)	/* yes, an assign */
497			return;
498		dp->b_actf = bp->b_actf;
499
500		/*
501		 * If the deivce has become invalid, abort all the
502		 * reads and writes until all files have been closed and
503		 * re-opened
504		 */
505		if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
506			bp->b_error = EIO;
507			bp->b_flags |= B_ERROR;
508			bp->b_resid = bp->b_bcount;
509			biodone(bp);
510			continue;
511		}
512
513		/*
514		 * We have a buf, now we should make a command
515		 *
516		 * First, translate the block to absolute and put it in terms
517		 * of the logical blocksize of the device.
518		 */
519		blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
520		if (CDPART(bp->b_dev) != RAW_PART) {
521			p = &lp->d_partitions[CDPART(bp->b_dev)];
522			blkno += p->p_offset;
523		}
524		nblks = howmany(bp->b_bcount, lp->d_secsize);
525
526#if NCD_SCSI > 0
527		/*
528		 *  Fill out the scsi command.  If the transfer will
529		 *  fit in a "small" cdb, use it.
530		 */
531		if (((blkno & 0x1fffff) == blkno) &&
532		    ((nblks & 0xff) == nblks) && sc_link->type == BUS_SCSI) {
533			/*
534			 * We can fit in a small cdb.
535			 */
536			bzero(&cmd_small, sizeof(cmd_small));
537			cmd_small.opcode = (bp->b_flags & B_READ) ?
538			    SCSI_READ_COMMAND : SCSI_WRITE_COMMAND;
539			_lto3b(blkno, cmd_small.addr);
540			cmd_small.length = nblks & 0xff;
541			cmdlen = sizeof(cmd_small);
542			cmdp = (struct scsipi_generic *)&cmd_small;
543		} else
544#endif
545		{
546			/*
547			 * Need a large cdb.
548			 */
549			bzero(&cmd_big, sizeof(cmd_big));
550			cmd_big.opcode = (bp->b_flags & B_READ) ?
551			    READ_BIG : WRITE_BIG;
552			_lto4b(blkno, cmd_big.addr);
553			_lto2b(nblks, cmd_big.length);
554			cmdlen = sizeof(cmd_big);
555			cmdp = (struct scsipi_generic *)&cmd_big;
556		}
557
558		/* Instrumentation. */
559		disk_busy(&cd->sc_dk);
560
561		/*
562		 * Call the routine that chats with the adapter.
563		 * Note: we cannot sleep as we may be an interrupt
564		 */
565		if (scsipi_command(sc_link, cmdp, cmdlen, (u_char *)bp->b_data,
566		    bp->b_bcount, CDRETRIES, 30000, bp, SCSI_NOSLEEP |
567		    ((bp->b_flags & B_READ) ? SCSI_DATA_IN : SCSI_DATA_OUT))) {
568			disk_unbusy(&cd->sc_dk, 0);
569			printf("%s: not queued", cd->sc_dev.dv_xname);
570		}
571	}
572}
573
574void
575cddone(xs)
576	struct scsipi_xfer *xs;
577{
578	struct cd_softc *cd = xs->sc_link->device_softc;
579
580	if (xs->bp != NULL) {
581		disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid);
582#if NRND > 0
583		rnd_add_uint32(&cd->rnd_source, xs->bp->b_blkno);
584#endif
585	}
586}
587
588void
589cdminphys(bp)
590	struct buf *bp;
591{
592	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
593	long max;
594
595	/*
596	 * If the device is ancient, we want to make sure that
597	 * the transfer fits into a 6-byte cdb.
598	 *
599	 * XXX Note that the SCSI-I spec says that 256-block transfers
600	 * are allowed in a 6-byte read/write, and are specified
601	 * by settng the "length" to 0.  However, we're conservative
602	 * here, allowing only 255-block transfers in case an
603	 * ancient device gets confused by length == 0.  A length of 0
604	 * in a 10-byte read/write actually means 0 blocks.
605	 */
606	if (cd->flags & CDF_ANCIENT) {
607		max = cd->sc_dk.dk_label->d_secsize * 0xff;
608
609		if (bp->b_bcount > max)
610			bp->b_bcount = max;
611	}
612
613	(*cd->sc_link->adapter->scsipi_minphys)(bp);
614}
615
616int
617cdread(dev, uio, ioflag)
618	dev_t dev;
619	struct uio *uio;
620	int ioflag;
621{
622
623	return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
624}
625
626int
627cdwrite(dev, uio, ioflag)
628	dev_t dev;
629	struct uio *uio;
630	int ioflag;
631{
632
633	return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
634}
635
636/*
637 * conversion between minute-seconde-frame and logical block adress
638 * adresses format
639 */
640void
641lba2msf (lba, m, s, f)
642	u_long lba;
643	u_char *m, *s, *f;
644{
645	u_long tmp;
646
647	tmp = lba + CD_BLOCK_OFFSET;	/* offset of first logical frame */
648	tmp &= 0xffffff;		/* negative lbas use only 24 bits */
649	*m = tmp / (CD_SECS * CD_FRAMES);
650	tmp %= (CD_SECS * CD_FRAMES);
651	*s = tmp / CD_FRAMES;
652	*f = tmp % CD_FRAMES;
653}
654
655u_long
656msf2lba (m, s, f)
657	u_char m, s, f;
658{
659
660	return ((((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET);
661}
662
663
664/*
665 * Perform special action on behalf of the user.
666 * Knows about the internals of this device
667 */
668int
669cdioctl(dev, cmd, addr, flag, p)
670	dev_t dev;
671	u_long cmd;
672	caddr_t addr;
673	int flag;
674	struct proc *p;
675{
676	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
677	int error;
678
679	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdioctl 0x%lx ", cmd));
680
681	/*
682	 * If the device is not valid.. abandon ship
683	 */
684	if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0)
685		return (EIO);
686
687	switch (cmd) {
688	case DIOCGDINFO:
689		*(struct disklabel *)addr = *(cd->sc_dk.dk_label);
690		return (0);
691
692	case DIOCGPART:
693		((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label;
694		((struct partinfo *)addr)->part =
695		    &cd->sc_dk.dk_label->d_partitions[CDPART(dev)];
696		return (0);
697
698	case DIOCWDINFO:
699	case DIOCSDINFO:
700		if ((flag & FWRITE) == 0)
701			return (EBADF);
702
703		if ((error = cdlock(cd)) != 0)
704			return (error);
705		cd->flags |= CDF_LABELLING;
706
707		error = setdisklabel(cd->sc_dk.dk_label,
708		    (struct disklabel *)addr, /*cd->sc_dk.dk_openmask : */0,
709		    cd->sc_dk.dk_cpulabel);
710		if (error == 0) {
711			/* XXX ? */
712		}
713
714		cd->flags &= ~CDF_LABELLING;
715		cdunlock(cd);
716		return (error);
717
718	case DIOCWLABEL:
719		return (EBADF);
720
721	case DIOCGDEFLABEL:
722		cdgetdefaultlabel(cd, (struct disklabel *)addr);
723		return (0);
724
725	case CDIOCPLAYTRACKS: {
726		struct ioc_play_track *args = (struct ioc_play_track *)addr;
727
728		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd)) != 0)
729			return (error);
730		return (cd_play_tracks(cd, args->start_track,
731		    args->start_index, args->end_track, args->end_index));
732	}
733	case CDIOCPLAYMSF: {
734		struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
735
736		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd)) != 0)
737			return (error);
738		return (cd_play_msf(cd, args->start_m, args->start_s,
739		    args->start_f, args->end_m, args->end_s, args->end_f));
740	}
741	case CDIOCPLAYBLOCKS: {
742		struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
743
744		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd)) != 0)
745			return (error);
746		return (cd_play(cd, args->blk, args->len));
747	}
748	case CDIOCREADSUBCHANNEL: {
749		struct ioc_read_subchannel *args =
750		    (struct ioc_read_subchannel *)addr;
751		struct cd_sub_channel_info data;
752		int len = args->data_len;
753
754		if (len > sizeof(data) ||
755		    len < sizeof(struct cd_sub_channel_header))
756			return (EINVAL);
757		error = cd_read_subchannel(cd, args->address_format,
758		    args->data_format, args->track, &data, len);
759		if (error)
760			return (error);
761		len = min(len, _2btol(data.header.data_len) +
762		    sizeof(struct cd_sub_channel_header));
763		return (copyout(&data, args->data, len));
764	}
765	case CDIOREADTOCHEADER: {
766		struct ioc_toc_header th;
767
768		if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th))) != 0)
769			return (error);
770		if (cd->sc_link->quirks & ADEV_LITTLETOC) {
771#if BYTE_ORDER == BIG_ENDIAN
772			bswap((u_int8_t *)&th.len, sizeof(th.len));
773#endif
774		} else
775			th.len = ntohs(th.len);
776		bcopy(&th, addr, sizeof(th));
777		return (0);
778	}
779	case CDIOREADTOCENTRYS: {
780		struct cd_toc toc;
781		struct ioc_read_toc_entry *te =
782		    (struct ioc_read_toc_entry *)addr;
783		struct ioc_toc_header *th;
784		struct cd_toc_entry *cte;
785		int len = te->data_len;
786		int ntracks;
787
788		th = &toc.header;
789
790		if (len > sizeof(toc.entries) ||
791		    len < sizeof(struct cd_toc_entry))
792			return (EINVAL);
793		error = cd_read_toc(cd, te->address_format, te->starting_track,
794		    &toc, len + sizeof(struct ioc_toc_header));
795		if (error)
796			return (error);
797		if (te->address_format == CD_LBA_FORMAT)
798			for (ntracks =
799			    th->ending_track - th->starting_track + 1;
800			    ntracks >= 0; ntracks--) {
801				cte = &toc.entries[ntracks];
802				cte->addr_type = CD_LBA_FORMAT;
803				if (cd->sc_link->quirks & ADEV_LITTLETOC) {
804#if BYTE_ORDER == BIG_ENDIAN
805					bswap((u_int8_t*)&cte->addr,
806					    sizeof(cte->addr));
807#endif
808				} else
809					cte->addr.lba = ntohl(cte->addr.lba);
810			}
811		if (cd->sc_link->quirks & ADEV_LITTLETOC) {
812#if BYTE_ORDER == BIG_ENDIAN
813			bswap((u_int8_t*)&th->len, sizeof(th->len));
814#endif
815		} else
816			th->len = ntohs(th->len);
817		len = min(len, th->len - (sizeof(th->starting_track) +
818		    sizeof(th->ending_track)));
819		return (copyout(toc.entries, te->data, len));
820	}
821	case CDIOCSETPATCH: {
822		struct ioc_patch *arg = (struct ioc_patch *)addr;
823
824		return ((*cd->sc_ops->cdo_setchan)(cd, arg->patch[0],
825		    arg->patch[1], arg->patch[2], arg->patch[3]));
826	}
827	case CDIOCGETVOL: {
828		struct ioc_vol *arg = (struct ioc_vol *)addr;
829
830		return ((*cd->sc_ops->cdo_getvol)(cd, arg));
831	}
832	case CDIOCSETVOL: {
833		struct ioc_vol *arg = (struct ioc_vol *)addr;
834
835		return ((*cd->sc_ops->cdo_setvol)(cd, arg));
836	}
837
838	case CDIOCSETMONO:
839		return ((*cd->sc_ops->cdo_setchan)(cd, BOTH_CHANNEL,
840		    BOTH_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL));
841
842	case CDIOCSETSTEREO:
843		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
844		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL));
845
846	case CDIOCSETMUTE:
847		return ((*cd->sc_ops->cdo_setchan)(cd, MUTE_CHANNEL,
848		    MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL));
849
850	case CDIOCSETLEFT:
851		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
852		    LEFT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL));
853
854	case CDIOCSETRIGHT:
855		return ((*cd->sc_ops->cdo_setchan)(cd, RIGHT_CHANNEL,
856		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL));
857
858	case CDIOCRESUME:
859		return (cd_pause(cd, PA_RESUME));
860	case CDIOCPAUSE:
861		return (cd_pause(cd, PA_PAUSE));
862	case CDIOCSTART:
863		return (scsipi_start(cd->sc_link, SSS_START, 0));
864	case CDIOCSTOP:
865		return (scsipi_start(cd->sc_link, SSS_STOP, 0));
866	case CDIOCEJECT: /* FALLTHROUGH */
867	case DIOCEJECT:
868		return (scsipi_start(cd->sc_link, SSS_STOP|SSS_LOEJ, 0));
869	case CDIOCALLOW:
870		return (scsipi_prevent(cd->sc_link, PR_ALLOW, 0));
871	case CDIOCPREVENT:
872		return (scsipi_prevent(cd->sc_link, PR_PREVENT, 0));
873	case DIOCLOCK:
874		return (scsipi_prevent(cd->sc_link,
875		    (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0));
876	case CDIOCSETDEBUG:
877		cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2);
878		return (0);
879	case CDIOCCLRDEBUG:
880		cd->sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2);
881		return (0);
882	case CDIOCRESET:
883		return (cd_reset(cd));
884
885	default:
886		if (CDPART(dev) != RAW_PART)
887			return (ENOTTY);
888		return (scsipi_do_ioctl(cd->sc_link, dev, cmd, addr, flag, p));
889	}
890
891#ifdef DIAGNOSTIC
892	panic("cdioctl: impossible");
893#endif
894}
895
896void
897cdgetdefaultlabel(cd, lp)
898	struct cd_softc *cd;
899	struct disklabel *lp;
900{
901
902	bzero(lp, sizeof(struct disklabel));
903
904	lp->d_secsize = cd->params.blksize;
905	lp->d_ntracks = 1;
906	lp->d_nsectors = 100;
907	lp->d_ncylinders = (cd->params.disksize / 100) + 1;
908	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
909
910	strncpy(lp->d_typename, "SCSI CD-ROM", 16);
911	lp->d_type = DTYPE_SCSI;
912	strncpy(lp->d_packname, "fictitious", 16);
913	lp->d_secperunit = cd->params.disksize;
914	lp->d_rpm = 300;
915	lp->d_interleave = 1;
916	lp->d_flags = D_REMOVABLE;
917
918	lp->d_partitions[0].p_offset = 0;
919	lp->d_partitions[0].p_size =
920	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
921	lp->d_partitions[0].p_fstype = FS_ISO9660;
922	lp->d_partitions[RAW_PART].p_offset = 0;
923	lp->d_partitions[RAW_PART].p_size =
924	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
925	lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
926	lp->d_npartitions = RAW_PART + 1;
927
928	lp->d_magic = DISKMAGIC;
929	lp->d_magic2 = DISKMAGIC;
930	lp->d_checksum = dkcksum(lp);
931}
932
933/*
934 * Load the label information on the named device
935 * Actually fabricate a disklabel
936 *
937 * EVENTUALLY take information about different
938 * data tracks from the TOC and put it in the disklabel
939 */
940void
941cdgetdisklabel(cd)
942	struct cd_softc *cd;
943{
944	struct disklabel *lp = cd->sc_dk.dk_label;
945
946	bzero(cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
947
948	cdgetdefaultlabel(cd, lp);
949}
950
951/*
952 * Find out from the device what it's capacity is
953 */
954u_long
955cd_size(cd, flags)
956	struct cd_softc *cd;
957	int flags;
958{
959	struct scsipi_read_cd_cap_data rdcap;
960	struct scsipi_read_cd_capacity scsipi_cmd;
961	int blksize;
962	u_long size;
963
964	if (cd->sc_link->quirks & ADEV_NOCAPACITY) {
965		/*
966		 * the drive doesn't support the READ_CD_CAPACITY command
967		 * use a fake size
968		 */
969		cd->params.blksize = 2048;
970		cd->params.disksize = 400000;
971		return (400000);
972	}
973
974	/*
975	 * make up a scsi command and ask the scsi driver to do
976	 * it for you.
977	 */
978	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
979	scsipi_cmd.opcode = READ_CD_CAPACITY;
980
981	/*
982	 * If the command works, interpret the result as a 4 byte
983	 * number of blocks and a blocksize
984	 */
985	if (scsipi_command(cd->sc_link,
986	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
987	    (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 20000, NULL,
988	    flags | SCSI_DATA_IN) != 0)
989		return (0);
990
991	blksize = _4btol(rdcap.length);
992	if ((blksize < 512) || ((blksize & 511) != 0))
993		blksize = 2048;	/* some drives lie ! */
994	cd->params.blksize = blksize;
995
996	size = _4btol(rdcap.addr) + 1;
997	if (size < 100)
998		size = 400000;	/* ditto */
999	cd->params.disksize = size;
1000
1001	SC_DEBUG(cd->sc_link, SDEV_DB2, ("cd_size: %d %ld\n", blksize, size));
1002	return (size);
1003}
1004
1005/*
1006 * Get scsi driver to send a "start playing" command
1007 */
1008int
1009cd_play(cd, blkno, nblks)
1010	struct cd_softc *cd;
1011	int blkno, nblks;
1012{
1013	struct scsipi_play scsipi_cmd;
1014
1015	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1016	scsipi_cmd.opcode = PLAY;
1017	_lto4b(blkno, scsipi_cmd.blk_addr);
1018	_lto2b(nblks, scsipi_cmd.xfer_len);
1019	return (scsipi_command(cd->sc_link,
1020	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1021	    0, 0, CDRETRIES, 200000, NULL, 0));
1022}
1023
1024/*
1025 * Get scsi driver to send a "start playing" command
1026 */
1027int
1028cd_play_tracks(cd, strack, sindex, etrack, eindex)
1029	struct cd_softc *cd;
1030	int strack, sindex, etrack, eindex;
1031{
1032	struct cd_toc toc;
1033	int error;
1034
1035	if (!etrack)
1036		return (EIO);
1037	if (strack > etrack)
1038		return (EINVAL);
1039
1040	if ((error = cd_load_toc(cd, &toc)) != 0)
1041		return (error);
1042
1043	if (++etrack > (toc.header.ending_track+1))
1044		etrack = toc.header.ending_track+1;
1045
1046	strack -= toc.header.starting_track;
1047	etrack -= toc.header.starting_track;
1048	if (strack < 0)
1049		return (EINVAL);
1050
1051	return (cd_play_msf(cd, toc.entries[strack].addr.msf.minute,
1052	    toc.entries[strack].addr.msf.second,
1053	    toc.entries[strack].addr.msf.frame,
1054	    toc.entries[etrack].addr.msf.minute,
1055	    toc.entries[etrack].addr.msf.second,
1056	    toc.entries[etrack].addr.msf.frame));
1057}
1058
1059/*
1060 * Get scsi driver to send a "play msf" command
1061 */
1062int
1063cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
1064	struct cd_softc *cd;
1065	int startm, starts, startf, endm, ends, endf;
1066{
1067	struct scsipi_play_msf scsipi_cmd;
1068
1069	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1070	scsipi_cmd.opcode = PLAY_MSF;
1071	scsipi_cmd.start_m = startm;
1072	scsipi_cmd.start_s = starts;
1073	scsipi_cmd.start_f = startf;
1074	scsipi_cmd.end_m = endm;
1075	scsipi_cmd.end_s = ends;
1076	scsipi_cmd.end_f = endf;
1077	return (scsipi_command(cd->sc_link,
1078	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1079	    0, 0, CDRETRIES, 2000, NULL, 0));
1080}
1081
1082/*
1083 * Get scsi driver to send a "start up" command
1084 */
1085int
1086cd_pause(cd, go)
1087	struct cd_softc *cd;
1088	int go;
1089{
1090	struct scsipi_pause scsipi_cmd;
1091
1092	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1093	scsipi_cmd.opcode = PAUSE;
1094	scsipi_cmd.resume = go & 0xff;
1095	return (scsipi_command(cd->sc_link,
1096	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1097	    0, 0, CDRETRIES, 2000, NULL, 0));
1098}
1099
1100/*
1101 * Get scsi driver to send a "RESET" command
1102 */
1103int
1104cd_reset(cd)
1105	struct cd_softc *cd;
1106{
1107
1108	return (scsipi_command(cd->sc_link, 0, 0, 0, 0,
1109	    CDRETRIES, 2000, NULL, SCSI_RESET));
1110}
1111
1112/*
1113 * Read subchannel
1114 */
1115int
1116cd_read_subchannel(cd, mode, format, track, data, len)
1117	struct cd_softc *cd;
1118	int mode, format, track, len;
1119	struct cd_sub_channel_info *data;
1120{
1121	struct scsipi_read_subchannel scsipi_cmd;
1122
1123	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1124	scsipi_cmd.opcode = READ_SUBCHANNEL;
1125	if (mode == CD_MSF_FORMAT)
1126		scsipi_cmd.byte2 |= CD_MSF;
1127	scsipi_cmd.byte3 = SRS_SUBQ;
1128	scsipi_cmd.subchan_format = format;
1129	scsipi_cmd.track = track;
1130	_lto2b(len, scsipi_cmd.data_len);
1131	return (scsipi_command(cd->sc_link,
1132	    (struct scsipi_generic *)&scsipi_cmd,
1133	    sizeof(struct scsipi_read_subchannel), (u_char *)data, len,
1134	    CDRETRIES, 5000, NULL, SCSI_DATA_IN|SCSI_SILENT));
1135}
1136
1137/*
1138 * Read table of contents
1139 */
1140int
1141cd_read_toc(cd, mode, start, data, len)
1142	struct cd_softc *cd;
1143	int mode, start, len;
1144	void *data;
1145{
1146	struct scsipi_read_toc scsipi_cmd;
1147	int ntoc;
1148
1149	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1150#if 0
1151	if (len != sizeof(struct ioc_toc_header))
1152		ntoc = ((len) - sizeof(struct ioc_toc_header)) /
1153		    sizeof(struct cd_toc_entry);
1154	else
1155#endif
1156	ntoc = len;
1157	scsipi_cmd.opcode = READ_TOC;
1158	if (mode == CD_MSF_FORMAT)
1159		scsipi_cmd.byte2 |= CD_MSF;
1160	scsipi_cmd.from_track = start;
1161	_lto2b(ntoc, scsipi_cmd.data_len);
1162	return (scsipi_command(cd->sc_link,
1163	    (struct scsipi_generic *)&scsipi_cmd,
1164	    sizeof(struct scsipi_read_toc), (u_char *)data, len, CDRETRIES,
1165	    5000, NULL, SCSI_DATA_IN));
1166}
1167
1168int
1169cd_load_toc(cd, toc)
1170	struct cd_softc *cd;
1171	struct cd_toc *toc;
1172{
1173	int ntracks, len, error;
1174
1175	if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header))) != 0)
1176		return (error);
1177
1178	ntracks = toc->header.ending_track - toc->header.starting_track + 1;
1179	len = (ntracks + 1) * sizeof(struct cd_toc_entry) +
1180	    sizeof(toc->header);
1181	if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len)) != 0)
1182		return (error);
1183	return (0);
1184}
1185
1186/*
1187 * Get the scsi driver to send a full inquiry to the device and use the
1188 * results to fill out the disk parameter structure.
1189 */
1190int
1191cd_get_parms(cd, flags)
1192	struct cd_softc *cd;
1193	int flags;
1194{
1195
1196	/*
1197	 * give a number of sectors so that sec * trks * cyls
1198	 * is <= disk_size
1199	 */
1200	if (cd_size(cd, flags) == 0)
1201		return (ENXIO);
1202	return (0);
1203}
1204
1205int
1206cdsize(dev)
1207	dev_t dev;
1208{
1209
1210	/* CD-ROMs are read-only. */
1211	return (-1);
1212}
1213
1214int
1215cddump(dev, blkno, va, size)
1216	dev_t dev;
1217	daddr_t blkno;
1218	caddr_t va;
1219	size_t size;
1220{
1221
1222	/* Not implemented. */
1223	return (ENXIO);
1224}
1225