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