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