cd.c revision 1.218
1/*	$NetBSD: cd.c,v 1.218 2005/02/01 00:19:34 reinoud Exp $	*/
2
3/*-
4 * Copyright (c) 1998, 2001, 2003, 2004 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 <sys/cdefs.h>
57__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.218 2005/02/01 00:19:34 reinoud Exp $");
58
59#include "rnd.h"
60
61#include <sys/param.h>
62#include <sys/systm.h>
63#include <sys/kernel.h>
64#include <sys/file.h>
65#include <sys/stat.h>
66#include <sys/ioctl.h>
67#include <sys/buf.h>
68#include <sys/bufq.h>
69#include <sys/uio.h>
70#include <sys/malloc.h>
71#include <sys/errno.h>
72#include <sys/device.h>
73#include <sys/disklabel.h>
74#include <sys/disk.h>
75#include <sys/cdio.h>
76#include <sys/dvdio.h>
77#include <sys/scsiio.h>
78#include <sys/proc.h>
79#include <sys/conf.h>
80#include <sys/vnode.h>
81#if NRND > 0
82#include <sys/rnd.h>
83#endif
84
85#include <dev/scsipi/scsipi_all.h>
86#include <dev/scsipi/scsipi_cd.h>
87#include <dev/scsipi/scsipi_disk.h>	/* rw_big and start_stop come */
88#include <dev/scsipi/scsi_all.h>
89					/* from there */
90#include <dev/scsipi/scsi_disk.h>	/* rw comes from there */
91#include <dev/scsipi/scsipiconf.h>
92#include <dev/scsipi/scsipi_base.h>
93#include <dev/scsipi/cdvar.h>
94
95#define	CDUNIT(z)			DISKUNIT(z)
96#define	CDPART(z)			DISKPART(z)
97#define	CDMINOR(unit, part)		DISKMINOR(unit, part)
98#define	MAKECDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
99
100#define MAXTRACK	99
101#define CD_BLOCK_OFFSET	150
102#define CD_FRAMES	75
103#define CD_SECS		60
104
105struct cd_toc {
106	struct ioc_toc_header header;
107	struct cd_toc_entry entries[MAXTRACK+1]; /* One extra for the */
108						 /* leadout */
109};
110
111static void	cdstart(struct scsipi_periph *);
112static void	cdrestart(void *);
113static void	cdminphys(struct buf *);
114static void	cdgetdefaultlabel(struct cd_softc *, struct disklabel *);
115static void	cdgetdisklabel(struct cd_softc *);
116static void	cddone(struct scsipi_xfer *, int);
117static void	cdbounce(struct buf *);
118static int	cd_interpret_sense(struct scsipi_xfer *);
119static u_long	cd_size(struct cd_softc *, int);
120static int	cd_play(struct cd_softc *, int, int);
121static int	cd_play_tracks(struct cd_softc *, int, int, int, int);
122static int	cd_play_msf(struct cd_softc *, int, int, int, int, int, int);
123static int	cd_pause(struct cd_softc *, int);
124static int	cd_reset(struct cd_softc *);
125static int	cd_read_subchannel(struct cd_softc *, int, int, int,
126		    struct cd_sub_channel_info *, int, int);
127static int	cd_read_toc_f0(struct cd_softc *, int, int, void *, int, int, int);
128static int	cd_get_parms(struct cd_softc *, int);
129static int	cd_load_toc(struct cd_softc *, struct cd_toc *, int);
130static int	cdreadmsaddr(struct cd_softc *, int *);
131
132static int	dvd_auth(struct cd_softc *, dvd_authinfo *);
133static int	dvd_read_physical(struct cd_softc *, dvd_struct *);
134static int	dvd_read_copyright(struct cd_softc *, dvd_struct *);
135static int	dvd_read_disckey(struct cd_softc *, dvd_struct *);
136static int	dvd_read_bca(struct cd_softc *, dvd_struct *);
137static int	dvd_read_manufact(struct cd_softc *, dvd_struct *);
138static int	dvd_read_struct(struct cd_softc *, dvd_struct *);
139
140static int	cd_mode_sense(struct cd_softc *, u_int8_t, void *, size_t, int,
141		    int, int *);
142static int	cd_mode_select(struct cd_softc *, u_int8_t, void *, size_t,
143		    int, int);
144static int	cd_setchan(struct cd_softc *, int, int, int, int, int);
145static int	cd_getvol(struct cd_softc *, struct ioc_vol *, int);
146static int	cd_setvol(struct cd_softc *, const struct ioc_vol *, int);
147static int	cd_set_pa_immed(struct cd_softc *, int);
148static int	cd_load_unload(struct cd_softc *, struct ioc_load_unload *);
149static int	cd_setblksize(struct cd_softc *);
150
151static int	cdmatch(struct device *, struct cfdata *, void *);
152static void	cdattach(struct device *, struct device *, void *);
153static int	cdactivate(struct device *, enum devact);
154static int	cddetach(struct device *, int);
155
156CFATTACH_DECL(cd, sizeof(struct cd_softc), cdmatch, cdattach, cddetach,
157    cdactivate);
158
159extern struct cfdriver cd_cd;
160
161static const struct scsipi_inquiry_pattern cd_patterns[] = {
162	{T_CDROM, T_REMOV,
163	 "",         "",                 ""},
164	{T_WORM, T_REMOV,
165	 "",         "",                 ""},
166#if 0
167	{T_CDROM, T_REMOV, /* more luns */
168	 "PIONEER ", "CD-ROM DRM-600  ", ""},
169#endif
170	{T_DIRECT, T_REMOV,
171	 "NEC                 CD-ROM DRIVE:260", "", ""},
172};
173
174static dev_type_open(cdopen);
175static dev_type_close(cdclose);
176static dev_type_read(cdread);
177static dev_type_write(cdwrite);
178static dev_type_ioctl(cdioctl);
179static dev_type_strategy(cdstrategy);
180static dev_type_dump(cddump);
181static dev_type_size(cdsize);
182
183const struct bdevsw cd_bdevsw = {
184	cdopen, cdclose, cdstrategy, cdioctl, cddump, cdsize, D_DISK
185};
186
187const struct cdevsw cd_cdevsw = {
188	cdopen, cdclose, cdread, cdwrite, cdioctl,
189	nostop, notty, nopoll, nommap, nokqfilter, D_DISK
190};
191
192static struct dkdriver cddkdriver = { cdstrategy };
193
194static const struct scsipi_periphsw cd_switch = {
195	cd_interpret_sense,	/* use our error handler first */
196	cdstart,		/* we have a queue, which is started by this */
197	NULL,			/* we do not have an async handler */
198	cddone,			/* deal with stats at interrupt time */
199};
200
201/*
202 * The routine called by the low level scsi routine when it discovers
203 * A device suitable for this driver
204 */
205static int
206cdmatch(struct device *parent, struct cfdata *match, void *aux)
207{
208	struct scsipibus_attach_args *sa = aux;
209	int priority;
210
211	(void)scsipi_inqmatch(&sa->sa_inqbuf,
212	    (caddr_t)cd_patterns, sizeof(cd_patterns) / sizeof(cd_patterns[0]),
213	    sizeof(cd_patterns[0]), &priority);
214
215	return (priority);
216}
217
218static void
219cdattach(struct device *parent, struct device *self, void *aux)
220{
221	struct cd_softc *cd = (void *)self;
222	struct scsipibus_attach_args *sa = aux;
223	struct scsipi_periph *periph = sa->sa_periph;
224
225	SC_DEBUG(periph, SCSIPI_DB2, ("cdattach: "));
226
227	lockinit(&cd->sc_lock, PRIBIO | PCATCH, "cdlock", 0, 0);
228
229	if (scsipi_periph_bustype(sa->sa_periph) == SCSIPI_BUSTYPE_SCSI &&
230	    periph->periph_version == 0)
231		cd->flags |= CDF_ANCIENT;
232
233	bufq_alloc(&cd->buf_queue, BUFQ_DISKSORT|BUFQ_SORT_RAWBLOCK);
234
235	callout_init(&cd->sc_callout);
236
237	/*
238	 * Store information needed to contact our base driver
239	 */
240	cd->sc_periph = periph;
241
242	periph->periph_dev = &cd->sc_dev;
243	periph->periph_switch = &cd_switch;
244
245	/*
246	 * Increase our openings to the maximum-per-periph
247	 * supported by the adapter.  This will either be
248	 * clamped down or grown by the adapter if necessary.
249	 */
250	periph->periph_openings =
251	    SCSIPI_CHAN_MAX_PERIPH(periph->periph_channel);
252	periph->periph_flags |= PERIPH_GROW_OPENINGS;
253
254	/*
255	 * Initialize and attach the disk structure.
256	 */
257  	cd->sc_dk.dk_driver = &cddkdriver;
258	cd->sc_dk.dk_name = cd->sc_dev.dv_xname;
259	disk_attach(&cd->sc_dk);
260
261	printf("\n");
262
263#if NRND > 0
264	rnd_attach_source(&cd->rnd_source, cd->sc_dev.dv_xname,
265			  RND_TYPE_DISK, 0);
266#endif
267}
268
269static int
270cdactivate(struct device *self, enum devact act)
271{
272	int rv = 0;
273
274	switch (act) {
275	case DVACT_ACTIVATE:
276		rv = EOPNOTSUPP;
277		break;
278
279	case DVACT_DEACTIVATE:
280		/*
281		 * Nothing to do; we key off the device's DVF_ACTIVE.
282		 */
283		break;
284	}
285	return (rv);
286}
287
288static int
289cddetach(struct device *self, int flags)
290{
291	struct cd_softc *cd = (struct cd_softc *) self;
292	struct buf *bp;
293	int s, bmaj, cmaj, i, mn;
294
295	/* locate the major number */
296	bmaj = bdevsw_lookup_major(&cd_bdevsw);
297	cmaj = cdevsw_lookup_major(&cd_cdevsw);
298
299	/* Nuke the vnodes for any open instances */
300	for (i = 0; i < MAXPARTITIONS; i++) {
301		mn = CDMINOR(self->dv_unit, i);
302		vdevgone(bmaj, mn, mn, VBLK);
303		vdevgone(cmaj, mn, mn, VCHR);
304	}
305
306	/* kill any pending restart */
307	callout_stop(&cd->sc_callout);
308
309	s = splbio();
310
311	/* Kill off any queued buffers. */
312	while ((bp = BUFQ_GET(&cd->buf_queue)) != NULL) {
313		bp->b_error = EIO;
314		bp->b_flags |= B_ERROR;
315		bp->b_resid = bp->b_bcount;
316		biodone(bp);
317	}
318
319	bufq_free(&cd->buf_queue);
320
321	/* Kill off any pending commands. */
322	scsipi_kill_pending(cd->sc_periph);
323
324	splx(s);
325
326	lockmgr(&cd->sc_lock, LK_DRAIN, 0);
327
328	/* Detach from the disk list. */
329	disk_detach(&cd->sc_dk);
330
331#if 0
332	/* Get rid of the shutdown hook. */
333	if (cd->sc_sdhook != NULL)
334		shutdownhook_disestablish(cd->sc_sdhook);
335#endif
336
337#if NRND > 0
338	/* Unhook the entropy source. */
339	rnd_detach_source(&cd->rnd_source);
340#endif
341
342	return (0);
343}
344
345/*
346 * open the device. Make sure the partition info is a up-to-date as can be.
347 */
348static int
349cdopen(dev_t dev, int flag, int fmt, struct proc *p)
350{
351	struct cd_softc *cd;
352	struct scsipi_periph *periph;
353	struct scsipi_adapter *adapt;
354	int unit, part;
355	int error;
356
357	unit = CDUNIT(dev);
358	if (unit >= cd_cd.cd_ndevs)
359		return (ENXIO);
360	cd = cd_cd.cd_devs[unit];
361	if (cd == NULL)
362		return (ENXIO);
363
364	periph = cd->sc_periph;
365	adapt = periph->periph_channel->chan_adapter;
366	part = CDPART(dev);
367
368	SC_DEBUG(periph, SCSIPI_DB1,
369	    ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
370	    cd_cd.cd_ndevs, CDPART(dev)));
371
372	/*
373	 * If this is the first open of this device, add a reference
374	 * to the adapter.
375	 */
376	if (cd->sc_dk.dk_openmask == 0 &&
377	    (error = scsipi_adapter_addref(adapt)) != 0)
378		return (error);
379
380	if ((error = lockmgr(&cd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
381		goto bad4;
382
383	if ((periph->periph_flags & PERIPH_OPEN) != 0) {
384		/*
385		 * If any partition is open, but the disk has been invalidated,
386		 * disallow further opens.
387		 */
388		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0 &&
389			(part != RAW_PART || fmt != S_IFCHR )) {
390			error = EIO;
391			goto bad3;
392		}
393	} else {
394		int silent;
395
396		if (part == RAW_PART && fmt == S_IFCHR)
397			silent = XS_CTL_SILENT;
398		else
399			silent = 0;
400
401		/* Check that it is still responding and ok. */
402		error = scsipi_test_unit_ready(periph,
403		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
404		    silent);
405
406		/*
407		 * Start the pack spinning if necessary. Always allow the
408		 * raw parition to be opened, for raw IOCTLs. Data transfers
409		 * will check for SDEV_MEDIA_LOADED.
410		 */
411		if (error == EIO) {
412			int error2;
413
414			error2 = scsipi_start(periph, SSS_START, silent);
415			switch (error2) {
416			case 0:
417				error = 0;
418				break;
419			case EIO:
420			case EINVAL:
421				break;
422			default:
423				error = error2;
424				break;
425			}
426		}
427		if (error) {
428			if (silent)
429				goto out;
430			goto bad3;
431		}
432
433		periph->periph_flags |= PERIPH_OPEN;
434
435		/* Lock the pack in. */
436		error = scsipi_prevent(periph, PR_PREVENT,
437		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE);
438		SC_DEBUG(periph, SCSIPI_DB1,
439		    ("cdopen: scsipi_prevent, error=%d\n", error));
440		if (error)
441			goto bad;
442
443		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
444			periph->periph_flags |= PERIPH_MEDIA_LOADED;
445
446			/* Load the physical device parameters. */
447			if (cd_get_parms(cd, 0) != 0) {
448				error = ENXIO;
449				goto bad2;
450			}
451			SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
452
453			/* Fabricate a disk label. */
454			cdgetdisklabel(cd);
455			SC_DEBUG(periph, SCSIPI_DB3, ("Disklabel fabricated "));
456		}
457	}
458
459	/* Check that the partition exists. */
460	if (part != RAW_PART &&
461	    (part >= cd->sc_dk.dk_label->d_npartitions ||
462	    cd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
463		error = ENXIO;
464		goto bad;
465	}
466
467out:	/* Insure only one open at a time. */
468	switch (fmt) {
469	case S_IFCHR:
470		cd->sc_dk.dk_copenmask |= (1 << part);
471		break;
472	case S_IFBLK:
473		cd->sc_dk.dk_bopenmask |= (1 << part);
474		break;
475	}
476	cd->sc_dk.dk_openmask =
477	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
478
479	SC_DEBUG(periph, SCSIPI_DB3, ("open complete\n"));
480	lockmgr(&cd->sc_lock, LK_RELEASE, NULL);
481	return (0);
482
483bad2:
484	periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
485
486bad:
487	if (cd->sc_dk.dk_openmask == 0) {
488		scsipi_prevent(periph, PR_ALLOW,
489		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE);
490		periph->periph_flags &= ~PERIPH_OPEN;
491	}
492
493bad3:
494	lockmgr(&cd->sc_lock, LK_RELEASE, NULL);
495bad4:
496	if (cd->sc_dk.dk_openmask == 0)
497		scsipi_adapter_delref(adapt);
498	return (error);
499}
500
501/*
502 * close the device.. only called if we are the LAST
503 * occurence of an open device
504 */
505static int
506cdclose(dev_t dev, int flag, int fmt, struct proc *p)
507{
508	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
509	struct scsipi_periph *periph = cd->sc_periph;
510	struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
511	int part = CDPART(dev);
512	int error;
513
514	if ((error = lockmgr(&cd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
515		return (error);
516
517	switch (fmt) {
518	case S_IFCHR:
519		cd->sc_dk.dk_copenmask &= ~(1 << part);
520		break;
521	case S_IFBLK:
522		cd->sc_dk.dk_bopenmask &= ~(1 << part);
523		break;
524	}
525	cd->sc_dk.dk_openmask =
526	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
527
528	if (cd->sc_dk.dk_openmask == 0) {
529		scsipi_wait_drain(periph);
530
531		scsipi_prevent(periph, PR_ALLOW,
532		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
533		    XS_CTL_IGNORE_NOT_READY);
534		periph->periph_flags &= ~PERIPH_OPEN;
535
536		scsipi_wait_drain(periph);
537
538		scsipi_adapter_delref(adapt);
539	}
540
541	lockmgr(&cd->sc_lock, LK_RELEASE, NULL);
542	return (0);
543}
544
545/*
546 * Actually translate the requested transfer into one the physical driver can
547 * understand.  The transfer is described by a buf and will include only one
548 * physical transfer.
549 */
550static void
551cdstrategy(struct buf *bp)
552{
553	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
554	struct disklabel *lp;
555	struct scsipi_periph *periph = cd->sc_periph;
556	daddr_t blkno;
557	int s;
558
559	SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdstrategy "));
560	SC_DEBUG(cd->sc_periph, SCSIPI_DB1,
561	    ("%d bytes @ blk %" PRId64 "\n", bp->b_bcount, bp->b_blkno));
562	/*
563	 * If the device has been made invalid, error out
564	 * maybe the media changed
565	 */
566	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
567		if (periph->periph_flags & PERIPH_OPEN)
568			bp->b_error = EIO;
569		else
570			bp->b_error = ENODEV;
571		goto bad;
572	}
573
574	lp = cd->sc_dk.dk_label;
575
576	/*
577	 * The transfer must be a whole number of blocks, offset must not
578	 * be negative.
579	 */
580	if ((bp->b_bcount % lp->d_secsize) != 0 ||
581	    bp->b_blkno < 0 ) {
582		bp->b_error = EINVAL;
583		goto bad;
584	}
585	/*
586	 * If it's a null transfer, return immediately
587	 */
588	if (bp->b_bcount == 0)
589		goto done;
590
591	/*
592	 * Do bounds checking, adjust transfer. if error, process.
593	 * If end of partition, just return.
594	 */
595	if (CDPART(bp->b_dev) == RAW_PART) {
596		if (bounds_check_with_mediasize(bp, DEV_BSIZE,
597		    cd->params.disksize512) <= 0)
598			goto done;
599	} else {
600		if (bounds_check_with_label(&cd->sc_dk, bp,
601		    (cd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0)
602			goto done;
603	}
604
605	/*
606	 * Now convert the block number to absolute and put it in
607	 * terms of the device's logical block size.
608	 */
609	blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
610	if (CDPART(bp->b_dev) != RAW_PART)
611		blkno += lp->d_partitions[CDPART(bp->b_dev)].p_offset;
612
613	bp->b_rawblkno = blkno;
614
615	/*
616	 * If the disklabel sector size does not match the device
617	 * sector size we may need to do some extra work.
618	 */
619	if (lp->d_secsize != cd->params.blksize) {
620
621		/*
622		 * If the xfer is not a multiple of the device block size
623		 * or it is not block aligned, we need to bounce it.
624		 */
625		if ((bp->b_bcount % cd->params.blksize) != 0 ||
626			((blkno * lp->d_secsize) % cd->params.blksize) != 0) {
627			struct buf *nbp;
628			void *bounce = NULL;
629			long count;
630
631			if ((bp->b_flags & B_READ) == 0) {
632
633				/* XXXX We don't support bouncing writes. */
634				bp->b_error = EACCES;
635				goto bad;
636			}
637			count = ((blkno * lp->d_secsize) % cd->params.blksize);
638			/* XXX Store starting offset in bp->b_rawblkno */
639			bp->b_rawblkno = count;
640
641			count += bp->b_bcount;
642			count = roundup(count, cd->params.blksize);
643
644			blkno = ((blkno * lp->d_secsize) / cd->params.blksize);
645			s = splbio();
646			nbp = pool_get(&bufpool, PR_NOWAIT);
647			splx(s);
648			if (!nbp) {
649				/* No memory -- fail the iop. */
650				bp->b_error = ENOMEM;
651				goto bad;
652			}
653			bounce = malloc(count, M_DEVBUF, M_NOWAIT);
654			if (!bounce) {
655				/* No memory -- fail the iop. */
656				s = splbio();
657				pool_put(&bufpool, nbp);
658				splx(s);
659				bp->b_error = ENOMEM;
660				goto bad;
661			}
662
663			/* Set up the IOP to the bounce buffer. */
664			BUF_INIT(nbp);
665			nbp->b_error = 0;
666			nbp->b_proc = bp->b_proc;
667			nbp->b_vp = NULLVP;
668
669			nbp->b_bcount = count;
670			nbp->b_bufsize = count;
671			nbp->b_data = bounce;
672
673			nbp->b_rawblkno = blkno;
674
675			/* We need to do a read-modify-write operation */
676			nbp->b_flags = bp->b_flags | B_READ | B_CALL;
677			nbp->b_iodone = cdbounce;
678
679			/* Put ptr to orig buf in b_private and use new buf */
680			nbp->b_private = bp;
681
682			BIO_COPYPRIO(nbp, bp);
683
684			bp = nbp;
685
686		} else {
687			/* Xfer is aligned -- just adjust the start block */
688			bp->b_rawblkno = (blkno * lp->d_secsize) /
689				cd->params.blksize;
690		}
691	}
692	s = splbio();
693
694	/*
695	 * Place it in the queue of disk activities for this disk.
696	 *
697	 * XXX Only do disksort() if the current operating mode does not
698	 * XXX include tagged queueing.
699	 */
700	BUFQ_PUT(&cd->buf_queue, bp);
701
702	/*
703	 * Tell the device to get going on the transfer if it's
704	 * not doing anything, otherwise just wait for completion
705	 */
706	cdstart(cd->sc_periph);
707
708	splx(s);
709	return;
710
711bad:
712	bp->b_flags |= B_ERROR;
713done:
714	/*
715	 * Correctly set the buf to indicate a completed xfer
716	 */
717	bp->b_resid = bp->b_bcount;
718	biodone(bp);
719}
720
721/*
722 * cdstart looks to see if there is a buf waiting for the device
723 * and that the device is not already busy. If both are true,
724 * It deques the buf and creates a scsi command to perform the
725 * transfer in the buf. The transfer request will call scsipi_done
726 * on completion, which will in turn call this routine again
727 * so that the next queued transfer is performed.
728 * The bufs are queued by the strategy routine (cdstrategy)
729 *
730 * This routine is also called after other non-queued requests
731 * have been made of the scsi driver, to ensure that the queue
732 * continues to be drained.
733 *
734 * must be called at the correct (highish) spl level
735 * cdstart() is called at splbio from cdstrategy, cdrestart and scsipi_done
736 */
737static void
738cdstart(struct scsipi_periph *periph)
739{
740	struct cd_softc *cd = (void *)periph->periph_dev;
741	struct buf *bp = 0;
742	struct scsipi_rw_10 cmd_big;
743	struct scsi_rw_6 cmd_small;
744	struct scsipi_generic *cmdp;
745	struct scsipi_xfer *xs;
746	int flags, nblks, cmdlen, error;
747
748	SC_DEBUG(periph, SCSIPI_DB2, ("cdstart "));
749	/*
750	 * Check if the device has room for another command
751	 */
752	while (periph->periph_active < periph->periph_openings) {
753		/*
754		 * there is excess capacity, but a special waits
755		 * It'll need the adapter as soon as we clear out of the
756		 * way and let it run (user level wait).
757		 */
758		if (periph->periph_flags & PERIPH_WAITING) {
759			periph->periph_flags &= ~PERIPH_WAITING;
760			wakeup((caddr_t)periph);
761			return;
762		}
763
764		/*
765		 * If the device has become invalid, abort all the
766		 * reads and writes until all files have been closed and
767		 * re-opened
768		 */
769		if (__predict_false(
770		    (periph->periph_flags & PERIPH_MEDIA_LOADED) == 0)) {
771			if ((bp = BUFQ_GET(&cd->buf_queue)) != NULL) {
772				bp->b_error = EIO;
773				bp->b_flags |= B_ERROR;
774				bp->b_resid = bp->b_bcount;
775				biodone(bp);
776				continue;
777			} else {
778				return;
779			}
780		}
781
782		/*
783		 * See if there is a buf with work for us to do..
784		 */
785		if ((bp = BUFQ_PEEK(&cd->buf_queue)) == NULL)
786			return;
787
788		/*
789		 * We have a buf, now we should make a command.
790		 */
791
792		nblks = howmany(bp->b_bcount, cd->params.blksize);
793
794		/*
795		 *  Fill out the scsi command.  If the transfer will
796		 *  fit in a "small" cdb, use it.
797		 */
798		if (((bp->b_rawblkno & 0x1fffff) == bp->b_rawblkno) &&
799		    ((nblks & 0xff) == nblks) &&
800		    !(periph->periph_quirks & PQUIRK_ONLYBIG)) {
801			/*
802			 * We can fit in a small cdb.
803			 */
804			memset(&cmd_small, 0, sizeof(cmd_small));
805			cmd_small.opcode = (bp->b_flags & B_READ) ?
806			    SCSI_READ_6_COMMAND : SCSI_WRITE_6_COMMAND;
807			_lto3b(bp->b_rawblkno, cmd_small.addr);
808			cmd_small.length = nblks & 0xff;
809			cmdlen = sizeof(cmd_small);
810			cmdp = (struct scsipi_generic *)&cmd_small;
811		} else {
812			/*
813			 * Need a large cdb.
814			 */
815			memset(&cmd_big, 0, sizeof(cmd_big));
816			cmd_big.opcode = (bp->b_flags & B_READ) ?
817			    READ_10 : WRITE_10;
818			_lto4b(bp->b_rawblkno, cmd_big.addr);
819			_lto2b(nblks, cmd_big.length);
820			cmdlen = sizeof(cmd_big);
821			cmdp = (struct scsipi_generic *)&cmd_big;
822		}
823
824		/* Instrumentation. */
825		disk_busy(&cd->sc_dk);
826
827		/*
828		 * Figure out what flags to use.
829		 */
830		flags = XS_CTL_NOSLEEP|XS_CTL_ASYNC|XS_CTL_SIMPLE_TAG;
831		if (bp->b_flags & B_READ)
832			flags |= XS_CTL_DATA_IN;
833		else
834			flags |= XS_CTL_DATA_OUT;
835
836		/*
837		 * Call the routine that chats with the adapter.
838		 * Note: we cannot sleep as we may be an interrupt
839		 */
840		xs = scsipi_make_xs(periph, cmdp, cmdlen,
841		    (u_char *)bp->b_data, bp->b_bcount,
842		    CDRETRIES, 30000, bp, flags);
843		if (__predict_false(xs == NULL)) {
844			/*
845			 * out of memory. Keep this buffer in the queue, and
846			 * retry later.
847			 */
848			callout_reset(&cd->sc_callout, hz / 2, cdrestart,
849			    periph);
850			return;
851		}
852		/*
853		 * need to dequeue the buffer before queuing the command,
854		 * because cdstart may be called recursively from the
855		 * HBA driver
856		 */
857#ifdef DIAGNOSTIC
858		if (BUFQ_GET(&cd->buf_queue) != bp)
859			panic("cdstart(): dequeued wrong buf");
860#else
861		BUFQ_GET(&cd->buf_queue);
862#endif
863		error = scsipi_execute_xs(xs);
864		/* with a scsipi_xfer preallocated, scsipi_command can't fail */
865		KASSERT(error == 0);
866	}
867}
868
869static void
870cdrestart(void *v)
871{
872	int s = splbio();
873	cdstart((struct scsipi_periph *)v);
874	splx(s);
875}
876
877static void
878cddone(struct scsipi_xfer *xs, int error)
879{
880	struct cd_softc *cd = (void *)xs->xs_periph->periph_dev;
881	struct buf *bp = xs->bp;
882
883	if (bp) {
884		bp->b_error = error;
885		bp->b_resid = xs->resid;
886		if (error)
887			bp->b_flags |= B_ERROR;
888
889		disk_unbusy(&cd->sc_dk, bp->b_bcount - bp->b_resid,
890		    (bp->b_flags & B_READ));
891#if NRND > 0
892		rnd_add_uint32(&cd->rnd_source, bp->b_rawblkno);
893#endif
894
895		biodone(bp);
896	}
897}
898
899static void
900cdbounce(struct buf *bp)
901{
902	struct buf *obp = (struct buf *)bp->b_private;
903
904	if (bp->b_flags & B_ERROR) {
905		/* EEK propagate the error and free the memory */
906		goto done;
907	}
908	if (obp->b_flags & B_READ) {
909		/* Copy data to the final destination and free the buf. */
910		memcpy(obp->b_data, bp->b_data+obp->b_rawblkno,
911			obp->b_bcount);
912	} else {
913		/*
914		 * XXXX This is a CD-ROM -- READ ONLY -- why do we bother with
915		 * XXXX any of this write stuff?
916		 */
917		if (bp->b_flags & B_READ) {
918			struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
919			struct buf *nbp;
920			int s;
921
922			/* Read part of RMW complete. */
923			memcpy(bp->b_data+obp->b_rawblkno, obp->b_data,
924				obp->b_bcount);
925
926			s = splbio();
927
928			/* We need to alloc a new buf. */
929			nbp = pool_get(&bufpool, PR_NOWAIT);
930			if (!nbp) {
931				splx(s);
932				/* No buf available. */
933				bp->b_flags |= B_ERROR;
934				bp->b_error = ENOMEM;
935				bp->b_resid = bp->b_bcount;
936			}
937
938			/* Set up the IOP to the bounce buffer. */
939			BUF_INIT(nbp);
940			nbp->b_error = 0;
941			nbp->b_proc = bp->b_proc;
942			nbp->b_vp = NULLVP;
943
944			nbp->b_bcount = bp->b_bcount;
945			nbp->b_bufsize = bp->b_bufsize;
946			nbp->b_data = bp->b_data;
947
948			nbp->b_rawblkno = bp->b_rawblkno;
949
950			/* We need to do a read-modify-write operation */
951			nbp->b_flags = obp->b_flags | B_CALL;
952			nbp->b_iodone = cdbounce;
953
954			/* Put ptr to orig buf in b_private and use new buf */
955			nbp->b_private = obp;
956
957			/*
958			 * Place it in the queue of disk activities for this
959			 * disk.
960			 *
961			 * XXX Only do disksort() if the current operating mode
962			 * XXX does not include tagged queueing.
963			 */
964			BUFQ_PUT(&cd->buf_queue, nbp);
965
966			/*
967			 * Tell the device to get going on the transfer if it's
968			 * not doing anything, otherwise just wait for
969			 * completion
970			 */
971			cdstart(cd->sc_periph);
972
973			splx(s);
974			return;
975
976		}
977	}
978done:
979	obp->b_flags |= (bp->b_flags&(B_EINTR|B_ERROR));
980	obp->b_error = bp->b_error;
981	obp->b_resid = bp->b_resid;
982	free(bp->b_data, M_DEVBUF);
983	biodone(obp);
984}
985
986static int
987cd_interpret_sense(struct scsipi_xfer *xs)
988{
989	struct scsipi_periph *periph = xs->xs_periph;
990	struct scsipi_sense_data *sense = &xs->sense.scsi_sense;
991	int retval = EJUSTRETURN;
992
993	/*
994	 * If it isn't a extended or extended/deferred error, let
995	 * the generic code handle it.
996	 */
997	if ((sense->error_code & SSD_ERRCODE) != 0x70 &&
998	    (sense->error_code & SSD_ERRCODE) != 0x71) {	/* DEFERRED */
999		return (retval);
1000	}
1001
1002	/*
1003	 * If we got a "Unit not ready" (SKEY_NOT_READY) and "Logical Unit
1004	 * Is In The Process of Becoming Ready" (Sense code 0x04,0x01), then
1005	 * wait a bit for the drive to spin up
1006	 */
1007
1008	if ((sense->flags & SSD_KEY) == SKEY_NOT_READY &&
1009	    sense->add_sense_code == 0x4 &&
1010	    sense->add_sense_code_qual == 0x01)	{
1011		/*
1012		 * Sleep for 5 seconds to wait for the drive to spin up
1013		 */
1014
1015		SC_DEBUG(periph, SCSIPI_DB1, ("Waiting 5 sec for CD "
1016						"spinup\n"));
1017		if (!callout_pending(&periph->periph_callout))
1018			scsipi_periph_freeze(periph, 1);
1019		callout_reset(&periph->periph_callout,
1020		    5 * hz, scsipi_periph_timed_thaw, periph);
1021		retval = ERESTART;
1022	}
1023	return (retval);
1024}
1025
1026static void
1027cdminphys(struct buf *bp)
1028{
1029	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
1030	long max;
1031
1032	/*
1033	 * If the device is ancient, we want to make sure that
1034	 * the transfer fits into a 6-byte cdb.
1035	 *
1036	 * XXX Note that the SCSI-I spec says that 256-block transfers
1037	 * are allowed in a 6-byte read/write, and are specified
1038	 * by settng the "length" to 0.  However, we're conservative
1039	 * here, allowing only 255-block transfers in case an
1040	 * ancient device gets confused by length == 0.  A length of 0
1041	 * in a 10-byte read/write actually means 0 blocks.
1042	 */
1043	if (cd->flags & CDF_ANCIENT) {
1044		max = cd->sc_dk.dk_label->d_secsize * 0xff;
1045
1046		if (bp->b_bcount > max)
1047			bp->b_bcount = max;
1048	}
1049
1050	(*cd->sc_periph->periph_channel->chan_adapter->adapt_minphys)(bp);
1051}
1052
1053static int
1054cdread(dev_t dev, struct uio *uio, int ioflag)
1055{
1056
1057	return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
1058}
1059
1060static int
1061cdwrite(dev_t dev, struct uio *uio, int ioflag)
1062{
1063
1064	return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
1065}
1066
1067#if 0	/* XXX Not used */
1068/*
1069 * conversion between minute-seconde-frame and logical block address
1070 * addresses format
1071 */
1072static void
1073lba2msf(u_long lba, u_char *m, u_char *s, u_char *f)
1074{
1075	u_long tmp;
1076
1077	tmp = lba + CD_BLOCK_OFFSET;	/* offset of first logical frame */
1078	tmp &= 0xffffff;		/* negative lbas use only 24 bits */
1079	*m = tmp / (CD_SECS * CD_FRAMES);
1080	tmp %= (CD_SECS * CD_FRAMES);
1081	*s = tmp / CD_FRAMES;
1082	*f = tmp % CD_FRAMES;
1083}
1084
1085static u_long
1086msf2lba(u_char m, u_char s, u_char f)
1087{
1088
1089	return ((((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET);
1090}
1091#endif /* XXX Not used */
1092
1093static int
1094cdreadmsaddr(struct cd_softc *cd, int *addr)
1095{
1096	struct scsipi_periph *periph = cd->sc_periph;
1097	int error;
1098	struct cd_toc toc;
1099	struct cd_toc_entry *cte;
1100
1101	error = cd_read_toc_f0(cd, 0, 0, &toc,
1102	    sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
1103	    XS_CTL_DATA_ONSTACK,
1104	    0x40 /* control word for "get MS info" */);
1105
1106	if (error)
1107		return (error);
1108
1109	cte = &toc.entries[0];
1110	if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1111		cte->addr.lba = le32toh(cte->addr.lba);
1112		toc.header.len = le16toh(toc.header.len);
1113	} else {
1114		cte->addr.lba = be32toh(cte->addr.lba);
1115		toc.header.len = be16toh(toc.header.len);
1116	}
1117
1118	*addr = (toc.header.len >= 10 && cte->track > 1) ?
1119		cte->addr.lba : 0;
1120	return 0;
1121}
1122
1123/*
1124 * Perform special action on behalf of the user.
1125 * Knows about the internals of this device
1126 */
1127static int
1128cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
1129{
1130	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
1131	struct scsipi_periph *periph = cd->sc_periph;
1132	int part = CDPART(dev);
1133	int error = 0;
1134#ifdef __HAVE_OLD_DISKLABEL
1135	struct disklabel *newlabel = NULL;
1136#endif
1137
1138	SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdioctl 0x%lx ", cmd));
1139
1140	/*
1141	 * If the device is not valid, some IOCTLs can still be
1142	 * handled on the raw partition. Check this here.
1143	 */
1144	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
1145		switch (cmd) {
1146		case DIOCWLABEL:
1147		case DIOCLOCK:
1148		case ODIOCEJECT:
1149		case DIOCEJECT:
1150		case SCIOCIDENTIFY:
1151		case OSCIOCIDENTIFY:
1152		case SCIOCCOMMAND:
1153		case SCIOCDEBUG:
1154		case CDIOCGETVOL:
1155		case CDIOCSETVOL:
1156		case CDIOCSETMONO:
1157		case CDIOCSETSTEREO:
1158		case CDIOCSETMUTE:
1159		case CDIOCSETLEFT:
1160		case CDIOCSETRIGHT:
1161		case CDIOCCLOSE:
1162		case CDIOCEJECT:
1163		case CDIOCALLOW:
1164		case CDIOCPREVENT:
1165		case CDIOCSETDEBUG:
1166		case CDIOCCLRDEBUG:
1167		case CDIOCRESET:
1168		case SCIOCRESET:
1169		case CDIOCLOADUNLOAD:
1170		case DVD_AUTH:
1171		case DVD_READ_STRUCT:
1172			if (part == RAW_PART)
1173				break;
1174		/* FALLTHROUGH */
1175		default:
1176			if ((periph->periph_flags & PERIPH_OPEN) == 0)
1177				return (ENODEV);
1178			else
1179				return (EIO);
1180		}
1181	}
1182
1183	switch (cmd) {
1184	case DIOCGDINFO:
1185		*(struct disklabel *)addr = *(cd->sc_dk.dk_label);
1186		return (0);
1187#ifdef __HAVE_OLD_DISKLABEL
1188	case ODIOCGDINFO:
1189		newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
1190		if (newlabel == NULL)
1191			return (EIO);
1192		memcpy(newlabel, cd->sc_dk.dk_label, sizeof (*newlabel));
1193		if (newlabel->d_npartitions > OLDMAXPARTITIONS)
1194			error = ENOTTY;
1195		else
1196			memcpy(addr, newlabel, sizeof (struct olddisklabel));
1197		free(newlabel, M_TEMP);
1198		return error;
1199#endif
1200
1201	case DIOCGPART:
1202		((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label;
1203		((struct partinfo *)addr)->part =
1204		    &cd->sc_dk.dk_label->d_partitions[part];
1205		return (0);
1206
1207	case DIOCWDINFO:
1208	case DIOCSDINFO:
1209#ifdef __HAVE_OLD_DISKLABEL
1210	case ODIOCWDINFO:
1211	case ODIOCSDINFO:
1212#endif
1213	{
1214		struct disklabel *lp;
1215
1216		if ((flag & FWRITE) == 0)
1217			return (EBADF);
1218
1219#ifdef __HAVE_OLD_DISKLABEL
1220		if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
1221			newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
1222			if (newlabel == NULL)
1223				return (EIO);
1224			memset(newlabel, 0, sizeof newlabel);
1225			memcpy(newlabel, addr, sizeof (struct olddisklabel));
1226			lp = newlabel;
1227		} else
1228#endif
1229		lp = (struct disklabel *)addr;
1230
1231		if ((error = lockmgr(&cd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
1232			goto bad;
1233		cd->flags |= CDF_LABELLING;
1234
1235		error = setdisklabel(cd->sc_dk.dk_label,
1236		    lp, /*cd->sc_dk.dk_openmask : */0,
1237		    cd->sc_dk.dk_cpulabel);
1238		if (error == 0) {
1239			/* XXX ? */
1240		}
1241
1242		cd->flags &= ~CDF_LABELLING;
1243		lockmgr(&cd->sc_lock, LK_RELEASE, NULL);
1244bad:
1245#ifdef __HAVE_OLD_DISKLABEL
1246		if (newlabel != NULL)
1247			free(newlabel, M_TEMP);
1248#endif
1249		return (error);
1250	}
1251
1252	case DIOCWLABEL:
1253		return (EBADF);
1254
1255	case DIOCGDEFLABEL:
1256		cdgetdefaultlabel(cd, (struct disklabel *)addr);
1257		return (0);
1258
1259#ifdef __HAVE_OLD_DISKLABEL
1260	case ODIOCGDEFLABEL:
1261		newlabel = malloc(sizeof (*newlabel), M_TEMP, M_WAITOK);
1262		if (newlabel == NULL)
1263			return (EIO);
1264		cdgetdefaultlabel(cd, newlabel);
1265		if (newlabel->d_npartitions > OLDMAXPARTITIONS)
1266			error = ENOTTY;
1267		else
1268			memcpy(addr, newlabel, sizeof (struct olddisklabel));
1269		free(newlabel, M_TEMP);
1270		return error;
1271#endif
1272
1273	case CDIOCPLAYTRACKS: {
1274		struct ioc_play_track *args = (struct ioc_play_track *)addr;
1275
1276		if ((error = cd_set_pa_immed(cd, 0)) != 0)
1277			return (error);
1278		return (cd_play_tracks(cd, args->start_track,
1279		    args->start_index, args->end_track, args->end_index));
1280	}
1281	case CDIOCPLAYMSF: {
1282		struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
1283
1284		if ((error = cd_set_pa_immed(cd, 0)) != 0)
1285			return (error);
1286		return (cd_play_msf(cd, args->start_m, args->start_s,
1287		    args->start_f, args->end_m, args->end_s, args->end_f));
1288	}
1289	case CDIOCPLAYBLOCKS: {
1290		struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
1291
1292		if ((error = cd_set_pa_immed(cd, 0)) != 0)
1293			return (error);
1294		return (cd_play(cd, args->blk, args->len));
1295	}
1296	case CDIOCREADSUBCHANNEL: {
1297		struct ioc_read_subchannel *args =
1298		    (struct ioc_read_subchannel *)addr;
1299		struct cd_sub_channel_info data;
1300		u_int len = args->data_len;
1301
1302		if (len > sizeof(data) ||
1303		    len < sizeof(struct cd_sub_channel_header))
1304			return (EINVAL);
1305		error = cd_read_subchannel(cd, args->address_format,
1306		    args->data_format, args->track, &data, len,
1307		    XS_CTL_DATA_ONSTACK);
1308		if (error)
1309			return (error);
1310		len = min(len, _2btol(data.header.data_len) +
1311		    sizeof(struct cd_sub_channel_header));
1312		return (copyout(&data, args->data, len));
1313	}
1314	case CDIOREADTOCHEADER: {
1315		struct ioc_toc_header th;
1316
1317		if ((error = cd_read_toc_f0(cd, 0, 0, &th, sizeof(th),
1318		    XS_CTL_DATA_ONSTACK, 0)) != 0)
1319			return (error);
1320		if (cd->sc_periph->periph_quirks & PQUIRK_LITTLETOC)
1321			th.len = le16toh(th.len);
1322		else
1323			th.len = be16toh(th.len);
1324		memcpy(addr, &th, sizeof(th));
1325		return (0);
1326	}
1327	case CDIOREADTOCENTRYS: {
1328		struct cd_toc toc;
1329		struct ioc_read_toc_entry *te =
1330		    (struct ioc_read_toc_entry *)addr;
1331		struct ioc_toc_header *th;
1332		struct cd_toc_entry *cte;
1333		u_int len = te->data_len;
1334		int ntracks;
1335
1336		th = &toc.header;
1337
1338		if (len > sizeof(toc.entries) ||
1339		    len < sizeof(struct cd_toc_entry))
1340			return (EINVAL);
1341		error = cd_read_toc_f0(cd, te->address_format, te->starting_track,
1342		    &toc, len + sizeof(struct ioc_toc_header),
1343		    XS_CTL_DATA_ONSTACK, 0);
1344		if (error)
1345			return (error);
1346		if (te->address_format == CD_LBA_FORMAT)
1347			for (ntracks =
1348			    th->ending_track - th->starting_track + 1;
1349			    ntracks >= 0; ntracks--) {
1350				cte = &toc.entries[ntracks];
1351				cte->addr_type = CD_LBA_FORMAT;
1352				if (periph->periph_quirks & PQUIRK_LITTLETOC)
1353					cte->addr.lba = le32toh(cte->addr.lba);
1354				else
1355					cte->addr.lba = be32toh(cte->addr.lba);
1356			}
1357		if (periph->periph_quirks & PQUIRK_LITTLETOC)
1358			th->len = le16toh(th->len);
1359		else
1360			th->len = be16toh(th->len);
1361		len = min(len, th->len - (sizeof(th->starting_track) +
1362		    sizeof(th->ending_track)));
1363		return (copyout(toc.entries, te->data, len));
1364	}
1365	case CDIOREADMSADDR: {
1366		int sessno = *(int*)addr;
1367
1368		if (sessno != 0)
1369			return (EINVAL);
1370
1371		return (cdreadmsaddr(cd, (int*)addr));
1372	}
1373	case CDIOCSETPATCH: {
1374		struct ioc_patch *arg = (struct ioc_patch *)addr;
1375
1376		return (cd_setchan(cd, arg->patch[0], arg->patch[1],
1377		    arg->patch[2], arg->patch[3], 0));
1378	}
1379	case CDIOCGETVOL: {
1380		struct ioc_vol *arg = (struct ioc_vol *)addr;
1381
1382		return (cd_getvol(cd, arg, 0));
1383	}
1384	case CDIOCSETVOL: {
1385		struct ioc_vol *arg = (struct ioc_vol *)addr;
1386
1387		return (cd_setvol(cd, arg, 0));
1388	}
1389
1390	case CDIOCSETMONO:
1391		return (cd_setchan(cd, BOTH_CHANNEL, BOTH_CHANNEL,
1392		    MUTE_CHANNEL, MUTE_CHANNEL, 0));
1393
1394	case CDIOCSETSTEREO:
1395		return (cd_setchan(cd, LEFT_CHANNEL, RIGHT_CHANNEL,
1396		    MUTE_CHANNEL, MUTE_CHANNEL, 0));
1397
1398	case CDIOCSETMUTE:
1399		return (cd_setchan(cd, MUTE_CHANNEL, MUTE_CHANNEL,
1400		    MUTE_CHANNEL, MUTE_CHANNEL, 0));
1401
1402	case CDIOCSETLEFT:
1403		return (cd_setchan(cd, LEFT_CHANNEL, LEFT_CHANNEL,
1404		    MUTE_CHANNEL, MUTE_CHANNEL, 0));
1405
1406	case CDIOCSETRIGHT:
1407		return (cd_setchan(cd, RIGHT_CHANNEL, RIGHT_CHANNEL,
1408		    MUTE_CHANNEL, MUTE_CHANNEL, 0));
1409
1410	case CDIOCRESUME:
1411		return (cd_pause(cd, PA_RESUME));
1412	case CDIOCPAUSE:
1413		return (cd_pause(cd, PA_PAUSE));
1414	case CDIOCSTART:
1415		return (scsipi_start(periph, SSS_START, 0));
1416	case CDIOCSTOP:
1417		return (scsipi_start(periph, SSS_STOP, 0));
1418	case CDIOCCLOSE:
1419		return (scsipi_start(periph, SSS_START|SSS_LOEJ,
1420		    XS_CTL_IGNORE_NOT_READY | XS_CTL_IGNORE_MEDIA_CHANGE));
1421	case DIOCEJECT:
1422		if (*(int *)addr == 0) {
1423			/*
1424			 * Don't force eject: check that we are the only
1425			 * partition open. If so, unlock it.
1426			 */
1427			if ((cd->sc_dk.dk_openmask & ~(1 << part)) == 0 &&
1428			    cd->sc_dk.dk_bopenmask + cd->sc_dk.dk_copenmask ==
1429			    cd->sc_dk.dk_openmask) {
1430				error = scsipi_prevent(periph, PR_ALLOW,
1431				    XS_CTL_IGNORE_NOT_READY);
1432				if (error)
1433					return (error);
1434			} else {
1435				return (EBUSY);
1436			}
1437		}
1438		/* FALLTHROUGH */
1439	case CDIOCEJECT: /* FALLTHROUGH */
1440	case ODIOCEJECT:
1441		return (scsipi_start(periph, SSS_STOP|SSS_LOEJ, 0));
1442	case CDIOCALLOW:
1443		return (scsipi_prevent(periph, PR_ALLOW, 0));
1444	case CDIOCPREVENT:
1445		return (scsipi_prevent(periph, PR_PREVENT, 0));
1446	case DIOCLOCK:
1447		return (scsipi_prevent(periph,
1448		    (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0));
1449	case CDIOCSETDEBUG:
1450		cd->sc_periph->periph_dbflags |= (SCSIPI_DB1 | SCSIPI_DB2);
1451		return (0);
1452	case CDIOCCLRDEBUG:
1453		cd->sc_periph->periph_dbflags &= ~(SCSIPI_DB1 | SCSIPI_DB2);
1454		return (0);
1455	case CDIOCRESET:
1456	case SCIOCRESET:
1457		return (cd_reset(cd));
1458	case CDIOCLOADUNLOAD:
1459		return (cd_load_unload(cd, (struct ioc_load_unload *)addr));
1460	case DVD_AUTH:
1461		return (dvd_auth(cd, (dvd_authinfo *)addr));
1462	case DVD_READ_STRUCT:
1463		return (dvd_read_struct(cd, (dvd_struct *)addr));
1464
1465	default:
1466		if (part != RAW_PART)
1467			return (ENOTTY);
1468		return (scsipi_do_ioctl(periph, dev, cmd, addr, flag, p));
1469	}
1470
1471#ifdef DIAGNOSTIC
1472	panic("cdioctl: impossible");
1473#endif
1474}
1475
1476static void
1477cdgetdefaultlabel(struct cd_softc *cd, struct disklabel *lp)
1478{
1479	int lastsession;
1480
1481	memset(lp, 0, sizeof(struct disklabel));
1482
1483	lp->d_secsize = cd->params.blksize;
1484	lp->d_ntracks = 1;
1485	lp->d_nsectors = 100;
1486	lp->d_ncylinders = (cd->params.disksize / 100) + 1;
1487	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1488
1489	switch (scsipi_periph_bustype(cd->sc_periph)) {
1490	case SCSIPI_BUSTYPE_SCSI:
1491		lp->d_type = DTYPE_SCSI;
1492		break;
1493	case SCSIPI_BUSTYPE_ATAPI:
1494		lp->d_type = DTYPE_ATAPI;
1495		break;
1496	}
1497	/*
1498	 * XXX
1499	 * We could probe the mode pages to figure out what kind of disc it is.
1500	 * Is this worthwhile?
1501	 */
1502	strncpy(lp->d_typename, "mydisc", 16);
1503	strncpy(lp->d_packname, "fictitious", 16);
1504	lp->d_secperunit = cd->params.disksize;
1505	lp->d_rpm = 300;
1506	lp->d_interleave = 1;
1507	lp->d_flags = D_REMOVABLE;
1508
1509	if (cdreadmsaddr(cd, &lastsession) != 0)
1510		lastsession = 0;
1511
1512	lp->d_partitions[0].p_offset = 0;
1513#ifdef notyet /* have to fix bounds_check_with_label() first */
1514	lp->d_partitions[0].p_size = lp->d_secperunit;
1515#else
1516	lp->d_partitions[0].p_size =
1517	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1518#endif
1519	lp->d_partitions[0].p_cdsession = lastsession;
1520	lp->d_partitions[0].p_fstype = FS_ISO9660;
1521	lp->d_partitions[RAW_PART].p_offset = 0;
1522#ifdef notyet
1523	lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
1524#else
1525	lp->d_partitions[RAW_PART].p_size =
1526	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1527#endif
1528	lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
1529	lp->d_npartitions = RAW_PART + 1;
1530
1531	lp->d_magic = DISKMAGIC;
1532	lp->d_magic2 = DISKMAGIC;
1533	lp->d_checksum = dkcksum(lp);
1534}
1535
1536/*
1537 * Load the label information on the named device
1538 * Actually fabricate a disklabel
1539 *
1540 * EVENTUALLY take information about different
1541 * data tracks from the TOC and put it in the disklabel
1542 */
1543static void
1544cdgetdisklabel(struct cd_softc *cd)
1545{
1546	struct disklabel *lp = cd->sc_dk.dk_label;
1547	const char *errstring;
1548
1549	memset(cd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
1550
1551	cdgetdefaultlabel(cd, lp);
1552
1553	/*
1554	 * Call the generic disklabel extraction routine
1555	 */
1556	errstring = readdisklabel(MAKECDDEV(0, cd->sc_dev.dv_unit, RAW_PART),
1557	    cdstrategy, lp, cd->sc_dk.dk_cpulabel);
1558	if (errstring) {
1559		printf("%s: %s\n", cd->sc_dev.dv_xname, errstring);
1560		goto error;
1561	}
1562	return;
1563
1564error:
1565	/* Reset to default label -- should print a warning */
1566	memset(cd->sc_dk.dk_cpulabel, 0, sizeof(struct cpu_disklabel));
1567
1568	cdgetdefaultlabel(cd, lp);
1569}
1570
1571/*
1572 * Find out from the device what it's capacity is
1573 */
1574static u_long
1575cd_size(struct cd_softc *cd, int flags)
1576{
1577	struct scsipi_read_cd_capacity cmd;
1578	struct scsipi_read_cd_cap_data data;
1579	int blksize;
1580	u_long size;
1581
1582	if (cd->sc_periph->periph_quirks & PQUIRK_NOCAPACITY) {
1583		/*
1584		 * the drive doesn't support the READ_CD_CAPACITY command
1585		 * use a fake size
1586		 */
1587		cd->params.blksize = 2048;
1588		cd->params.disksize = 400000;
1589		cd->params.disksize512 = 1600000;
1590		return (400000);
1591	}
1592
1593	/*
1594	 * make up a scsi command and ask the scsi driver to do
1595	 * it for you.
1596	 */
1597	memset(&cmd, 0, sizeof(cmd));
1598	cmd.opcode = READ_CD_CAPACITY;
1599
1600	/*
1601	 * If the command works, interpret the result as a 4 byte
1602	 * number of blocks and a blocksize
1603	 */
1604	if (scsipi_command(cd->sc_periph, (void *)&cmd, sizeof(cmd),
1605	    (void *)&data, sizeof(data), CDRETRIES, 30000, NULL,
1606	    flags | XS_CTL_DATA_IN | XS_CTL_DATA_ONSTACK) != 0)
1607		return (0);
1608
1609	blksize = _4btol(data.length);
1610	if ((blksize < 512) || ((blksize & 511) != 0))
1611		blksize = 2048;	/* some drives lie ! */
1612	if (blksize != 2048) {
1613		if (cd_setblksize(cd) == 0)
1614			blksize = 2048;
1615	}
1616	cd->params.blksize = blksize;
1617
1618	size = _4btol(data.addr) + 1;
1619	if (size < 100)
1620		size = 400000;	/* ditto */
1621	cd->params.disksize = size;
1622	cd->params.disksize512 = ((u_int64_t)cd->params.disksize * blksize) / DEV_BSIZE;
1623
1624	SC_DEBUG(cd->sc_periph, SCSIPI_DB2,
1625	    ("cd_size: %d %ld\n", blksize, size));
1626	return (size);
1627}
1628
1629/*
1630 * Get scsi driver to send a "start playing" command
1631 */
1632static int
1633cd_play(struct cd_softc *cd, int blkno, int nblks)
1634{
1635	struct scsipi_play cmd;
1636
1637	memset(&cmd, 0, sizeof(cmd));
1638	cmd.opcode = PLAY;
1639	_lto4b(blkno, cmd.blk_addr);
1640	_lto2b(nblks, cmd.xfer_len);
1641
1642	return (scsipi_command(cd->sc_periph, (void *)&cmd, sizeof(cmd), 0, 0,
1643	    CDRETRIES, 30000, NULL, 0));
1644}
1645
1646/*
1647 * Get scsi driver to send a "start playing" command
1648 */
1649static int
1650cd_play_tracks(struct cd_softc *cd, int strack, int sindex, int etrack,
1651    int eindex)
1652{
1653	struct cd_toc toc;
1654	int error;
1655
1656	if (!etrack)
1657		return (EIO);
1658	if (strack > etrack)
1659		return (EINVAL);
1660
1661	if ((error = cd_load_toc(cd, &toc, XS_CTL_DATA_ONSTACK)) != 0)
1662		return (error);
1663
1664	if (++etrack > (toc.header.ending_track+1))
1665		etrack = toc.header.ending_track+1;
1666
1667	strack -= toc.header.starting_track;
1668	etrack -= toc.header.starting_track;
1669	if (strack < 0)
1670		return (EINVAL);
1671
1672	return (cd_play_msf(cd, toc.entries[strack].addr.msf.minute,
1673	    toc.entries[strack].addr.msf.second,
1674	    toc.entries[strack].addr.msf.frame,
1675	    toc.entries[etrack].addr.msf.minute,
1676	    toc.entries[etrack].addr.msf.second,
1677	    toc.entries[etrack].addr.msf.frame));
1678}
1679
1680/*
1681 * Get scsi driver to send a "play msf" command
1682 */
1683static int
1684cd_play_msf(struct cd_softc *cd, int startm, int starts, int startf, int endm,
1685    int ends, int endf)
1686{
1687	struct scsipi_play_msf cmd;
1688
1689	memset(&cmd, 0, sizeof(cmd));
1690	cmd.opcode = PLAY_MSF;
1691	cmd.start_m = startm;
1692	cmd.start_s = starts;
1693	cmd.start_f = startf;
1694	cmd.end_m = endm;
1695	cmd.end_s = ends;
1696	cmd.end_f = endf;
1697
1698	return (scsipi_command(cd->sc_periph, (void *)&cmd, sizeof(cmd), 0, 0,
1699	    CDRETRIES, 30000, NULL, 0));
1700}
1701
1702/*
1703 * Get scsi driver to send a "start up" command
1704 */
1705static int
1706cd_pause(struct cd_softc *cd, int go)
1707{
1708	struct scsipi_pause cmd;
1709
1710	memset(&cmd, 0, sizeof(cmd));
1711	cmd.opcode = PAUSE;
1712	cmd.resume = go & 0xff;
1713
1714	return (scsipi_command(cd->sc_periph, (void *)&cmd, sizeof(cmd), 0, 0,
1715	    CDRETRIES, 30000, NULL, 0));
1716}
1717
1718/*
1719 * Get scsi driver to send a "RESET" command
1720 */
1721static int
1722cd_reset(struct cd_softc *cd)
1723{
1724
1725	return (scsipi_command(cd->sc_periph, 0, 0, 0, 0,
1726	    CDRETRIES, 30000, NULL, XS_CTL_RESET));
1727}
1728
1729/*
1730 * Read subchannel
1731 */
1732static int
1733cd_read_subchannel(struct cd_softc *cd, int mode, int format, int track,
1734    struct cd_sub_channel_info *data, int len, int flags)
1735{
1736	struct scsipi_read_subchannel cmd;
1737
1738	memset(&cmd, 0, sizeof(cmd));
1739	cmd.opcode = READ_SUBCHANNEL;
1740	if (mode == CD_MSF_FORMAT)
1741		cmd.byte2 |= CD_MSF;
1742	cmd.byte3 = SRS_SUBQ;
1743	cmd.subchan_format = format;
1744	cmd.track = track;
1745	_lto2b(len, cmd.data_len);
1746
1747	return (scsipi_command(cd->sc_periph,
1748	    (void *)&cmd, sizeof(struct scsipi_read_subchannel),
1749	    (void *)data, len,
1750	    CDRETRIES, 30000, NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT));
1751}
1752
1753/*
1754 * Read table of contents
1755 */
1756static int
1757cd_read_toc_f0(struct cd_softc *cd, int mode, int start, void *data, int len,
1758    int flags, int control)
1759{
1760	struct scsipi_read_toc cmd;
1761	int ntoc;
1762
1763	memset(&cmd, 0, sizeof(cmd));
1764#if 0
1765	if (len != sizeof(struct ioc_toc_header))
1766		ntoc = ((len) - sizeof(struct ioc_toc_header)) /
1767		    sizeof(struct cd_toc_entry);
1768	else
1769#endif
1770	ntoc = len;
1771	cmd.opcode = READ_TOC;
1772	if (mode == CD_MSF_FORMAT)
1773		cmd.addr_mode |= CD_MSF;
1774	cmd.resp_format = 0;
1775	cmd.from_track = start;
1776	_lto2b(ntoc, cmd.data_len);
1777	cmd.control = control;
1778
1779	return (scsipi_command(cd->sc_periph,
1780	    (void *)&cmd, sizeof(cmd), (void *)data, len, CDRETRIES,
1781	    30000, NULL, flags | XS_CTL_DATA_IN));
1782}
1783
1784static int
1785cd_load_toc(struct cd_softc *cd, struct cd_toc *toc, int flags)
1786{
1787	int ntracks, len, error;
1788
1789	if ((error = cd_read_toc_f0(cd, 0, 0, toc, sizeof(toc->header),
1790	    flags, 0)) != 0)
1791		return (error);
1792
1793	ntracks = toc->header.ending_track - toc->header.starting_track + 1;
1794	len = (ntracks + 1) * sizeof(struct cd_toc_entry) +
1795	    sizeof(toc->header);
1796	if ((error = cd_read_toc_f0(cd, CD_MSF_FORMAT, 0, toc, len,
1797	    flags, 0)) != 0)
1798		return (error);
1799	return (0);
1800}
1801
1802/*
1803 * Get the scsi driver to send a full inquiry to the device and use the
1804 * results to fill out the disk parameter structure.
1805 */
1806static int
1807cd_get_parms(struct cd_softc *cd, int flags)
1808{
1809
1810	/*
1811	 * give a number of sectors so that sec * trks * cyls
1812	 * is <= disk_size
1813	 */
1814	if (cd_size(cd, flags) == 0)
1815		return (ENXIO);
1816	return (0);
1817}
1818
1819static int
1820cdsize(dev_t dev)
1821{
1822
1823	/* CD-ROMs are read-only. */
1824	return (-1);
1825}
1826
1827static int
1828cddump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
1829{
1830
1831	/* Not implemented. */
1832	return (ENXIO);
1833}
1834
1835#define	dvd_copy_key(dst, src)		memcpy((dst), (src), sizeof(dvd_key))
1836#define	dvd_copy_challenge(dst, src)	memcpy((dst), (src), sizeof(dvd_challenge))
1837
1838static int
1839dvd_auth(struct cd_softc *cd, dvd_authinfo *a)
1840{
1841	struct scsipi_generic cmd;
1842	u_int8_t buf[20];
1843	int error;
1844
1845	memset(cmd.bytes, 0, 15);
1846	memset(buf, 0, sizeof(buf));
1847
1848	switch (a->type) {
1849	case DVD_LU_SEND_AGID:
1850		cmd.opcode = GPCMD_REPORT_KEY;
1851		cmd.bytes[8] = 8;
1852		cmd.bytes[9] = 0 | (0 << 6);
1853		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
1854		    CDRETRIES, 30000, NULL,
1855		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1856		if (error)
1857			return (error);
1858		a->lsa.agid = buf[7] >> 6;
1859		return (0);
1860
1861	case DVD_LU_SEND_CHALLENGE:
1862		cmd.opcode = GPCMD_REPORT_KEY;
1863		cmd.bytes[8] = 16;
1864		cmd.bytes[9] = 1 | (a->lsc.agid << 6);
1865		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
1866		    CDRETRIES, 30000, NULL,
1867		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1868		if (error)
1869			return (error);
1870		dvd_copy_challenge(a->lsc.chal, &buf[4]);
1871		return (0);
1872
1873	case DVD_LU_SEND_KEY1:
1874		cmd.opcode = GPCMD_REPORT_KEY;
1875		cmd.bytes[8] = 12;
1876		cmd.bytes[9] = 2 | (a->lsk.agid << 6);
1877		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
1878		    CDRETRIES, 30000, NULL,
1879		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1880		if (error)
1881			return (error);
1882		dvd_copy_key(a->lsk.key, &buf[4]);
1883		return (0);
1884
1885	case DVD_LU_SEND_TITLE_KEY:
1886		cmd.opcode = GPCMD_REPORT_KEY;
1887		_lto4b(a->lstk.lba, &cmd.bytes[1]);
1888		cmd.bytes[8] = 12;
1889		cmd.bytes[9] = 4 | (a->lstk.agid << 6);
1890		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
1891		    CDRETRIES, 30000, NULL,
1892		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1893		if (error)
1894			return (error);
1895		a->lstk.cpm = (buf[4] >> 7) & 1;
1896		a->lstk.cp_sec = (buf[4] >> 6) & 1;
1897		a->lstk.cgms = (buf[4] >> 4) & 3;
1898		dvd_copy_key(a->lstk.title_key, &buf[5]);
1899		return (0);
1900
1901	case DVD_LU_SEND_ASF:
1902		cmd.opcode = GPCMD_REPORT_KEY;
1903		cmd.bytes[8] = 8;
1904		cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
1905		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
1906		    CDRETRIES, 30000, NULL,
1907		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1908		if (error)
1909			return (error);
1910		a->lsasf.asf = buf[7] & 1;
1911		return (0);
1912
1913	case DVD_HOST_SEND_CHALLENGE:
1914		cmd.opcode = GPCMD_SEND_KEY;
1915		cmd.bytes[8] = 16;
1916		cmd.bytes[9] = 1 | (a->hsc.agid << 6);
1917		buf[1] = 14;
1918		dvd_copy_challenge(&buf[4], a->hsc.chal);
1919		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
1920		    CDRETRIES, 30000, NULL,
1921		    XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
1922		if (error)
1923			return (error);
1924		a->type = DVD_LU_SEND_KEY1;
1925		return (0);
1926
1927	case DVD_HOST_SEND_KEY2:
1928		cmd.opcode = GPCMD_SEND_KEY;
1929		cmd.bytes[8] = 12;
1930		cmd.bytes[9] = 3 | (a->hsk.agid << 6);
1931		buf[1] = 10;
1932		dvd_copy_key(&buf[4], a->hsk.key);
1933		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 12,
1934		    CDRETRIES, 30000, NULL,
1935		    XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
1936		if (error) {
1937			a->type = DVD_AUTH_FAILURE;
1938			return (error);
1939		}
1940		a->type = DVD_AUTH_ESTABLISHED;
1941		return (0);
1942
1943	case DVD_INVALIDATE_AGID:
1944		cmd.opcode = GPCMD_REPORT_KEY;
1945		cmd.bytes[9] = 0x3f | (a->lsa.agid << 6);
1946		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 16,
1947		    CDRETRIES, 30000, NULL, 0);
1948		if (error)
1949			return (error);
1950		return (0);
1951
1952	case DVD_LU_SEND_RPC_STATE:
1953		cmd.opcode = GPCMD_REPORT_KEY;
1954		cmd.bytes[8] = 8;
1955		cmd.bytes[9] = 8 | (0 << 6);
1956		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
1957		    CDRETRIES, 30000, NULL,
1958		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1959		if (error)
1960			return (error);
1961		a->lrpcs.type = (buf[4] >> 6) & 3;
1962		a->lrpcs.vra = (buf[4] >> 3) & 7;
1963		a->lrpcs.ucca = (buf[4]) & 7;
1964		a->lrpcs.region_mask = buf[5];
1965		a->lrpcs.rpc_scheme = buf[6];
1966		return (0);
1967
1968	case DVD_HOST_SEND_RPC_STATE:
1969		cmd.opcode = GPCMD_SEND_KEY;
1970		cmd.bytes[8] = 8;
1971		cmd.bytes[9] = 6 | (0 << 6);
1972		buf[1] = 6;
1973		buf[4] = a->hrpcs.pdrc;
1974		error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 8,
1975		    CDRETRIES, 30000, NULL,
1976		    XS_CTL_DATA_OUT|XS_CTL_DATA_ONSTACK);
1977		if (error)
1978			return (error);
1979		return (0);
1980
1981	default:
1982		return (ENOTTY);
1983	}
1984}
1985
1986static int
1987dvd_read_physical(struct cd_softc *cd, dvd_struct *s)
1988{
1989	struct scsipi_generic cmd;
1990	u_int8_t buf[4 + 4 * 20], *bufp;
1991	int error;
1992	struct dvd_layer *layer;
1993	int i;
1994
1995	memset(cmd.bytes, 0, 15);
1996	memset(buf, 0, sizeof(buf));
1997	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1998	cmd.bytes[6] = s->type;
1999	_lto2b(sizeof(buf), &cmd.bytes[7]);
2000
2001	cmd.bytes[5] = s->physical.layer_num;
2002	error = scsipi_command(cd->sc_periph, &cmd, 12, buf, sizeof(buf),
2003	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
2004	if (error)
2005		return (error);
2006	for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4;
2007	     i++, bufp += 20, layer++) {
2008		memset(layer, 0, sizeof(*layer));
2009                layer->book_version = bufp[0] & 0xf;
2010                layer->book_type = bufp[0] >> 4;
2011                layer->min_rate = bufp[1] & 0xf;
2012                layer->disc_size = bufp[1] >> 4;
2013                layer->layer_type = bufp[2] & 0xf;
2014                layer->track_path = (bufp[2] >> 4) & 1;
2015                layer->nlayers = (bufp[2] >> 5) & 3;
2016                layer->track_density = bufp[3] & 0xf;
2017                layer->linear_density = bufp[3] >> 4;
2018                layer->start_sector = _4btol(&bufp[4]);
2019                layer->end_sector = _4btol(&bufp[8]);
2020                layer->end_sector_l0 = _4btol(&bufp[12]);
2021                layer->bca = bufp[16] >> 7;
2022	}
2023	return (0);
2024}
2025
2026static int
2027dvd_read_copyright(struct cd_softc *cd, dvd_struct *s)
2028{
2029	struct scsipi_generic cmd;
2030	u_int8_t buf[8];
2031	int error;
2032
2033	memset(cmd.bytes, 0, 15);
2034	memset(buf, 0, sizeof(buf));
2035	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
2036	cmd.bytes[6] = s->type;
2037	_lto2b(sizeof(buf), &cmd.bytes[7]);
2038
2039	cmd.bytes[5] = s->copyright.layer_num;
2040	error = scsipi_command(cd->sc_periph, &cmd, 12, buf, sizeof(buf),
2041	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
2042	if (error)
2043		return (error);
2044	s->copyright.cpst = buf[4];
2045	s->copyright.rmi = buf[5];
2046	return (0);
2047}
2048
2049static int
2050dvd_read_disckey(struct cd_softc *cd, dvd_struct *s)
2051{
2052	struct scsipi_generic cmd;
2053	u_int8_t *buf;
2054	int error;
2055
2056	buf = malloc(4 + 2048, M_TEMP, M_WAITOK|M_ZERO);
2057	if (buf == NULL)
2058		return EIO;
2059	memset(cmd.bytes, 0, 15);
2060	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
2061	cmd.bytes[6] = s->type;
2062	_lto2b(4 + 2048, &cmd.bytes[7]);
2063
2064	cmd.bytes[9] = s->disckey.agid << 6;
2065	error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 4 + 2048,
2066	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
2067	if (error == 0)
2068		memcpy(s->disckey.value, &buf[4], 2048);
2069	free(buf, M_TEMP);
2070	return error;
2071}
2072
2073static int
2074dvd_read_bca(struct cd_softc *cd, dvd_struct *s)
2075{
2076	struct scsipi_generic cmd;
2077	u_int8_t buf[4 + 188];
2078	int error;
2079
2080	memset(cmd.bytes, 0, 15);
2081	memset(buf, 0, sizeof(buf));
2082	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
2083	cmd.bytes[6] = s->type;
2084	_lto2b(sizeof(buf), &cmd.bytes[7]);
2085
2086	error = scsipi_command(cd->sc_periph, &cmd, 12, buf, sizeof(buf),
2087	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
2088	if (error)
2089		return (error);
2090	s->bca.len = _2btol(&buf[0]);
2091	if (s->bca.len < 12 || s->bca.len > 188)
2092		return (EIO);
2093	memcpy(s->bca.value, &buf[4], s->bca.len);
2094	return (0);
2095}
2096
2097static int
2098dvd_read_manufact(struct cd_softc *cd, dvd_struct *s)
2099{
2100	struct scsipi_generic cmd;
2101	u_int8_t *buf;
2102	int error;
2103
2104	buf = malloc(4 + 2048, M_TEMP, M_WAITOK|M_ZERO);
2105	if (buf == NULL)
2106		return (EIO);
2107	memset(cmd.bytes, 0, 15);
2108	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
2109	cmd.bytes[6] = s->type;
2110	_lto2b(4 + 2048, &cmd.bytes[7]);
2111
2112	error = scsipi_command(cd->sc_periph, &cmd, 12, buf, 4 + 2048,
2113	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
2114	if (error == 0) {
2115		s->manufact.len = _2btol(&buf[0]);
2116		if (s->manufact.len >= 0 && s->manufact.len <= 2048)
2117			memcpy(s->manufact.value, &buf[4], s->manufact.len);
2118		else
2119			error = EIO;
2120	}
2121	free(buf, M_TEMP);
2122	return error;
2123}
2124
2125static int
2126dvd_read_struct(struct cd_softc *cd, dvd_struct *s)
2127{
2128
2129	switch (s->type) {
2130	case DVD_STRUCT_PHYSICAL:
2131		return (dvd_read_physical(cd, s));
2132	case DVD_STRUCT_COPYRIGHT:
2133		return (dvd_read_copyright(cd, s));
2134	case DVD_STRUCT_DISCKEY:
2135		return (dvd_read_disckey(cd, s));
2136	case DVD_STRUCT_BCA:
2137		return (dvd_read_bca(cd, s));
2138	case DVD_STRUCT_MANUFACT:
2139		return (dvd_read_manufact(cd, s));
2140	default:
2141		return (EINVAL);
2142	}
2143}
2144
2145static int
2146cd_mode_sense(struct cd_softc *cd, u_int8_t byte2, void *sense, size_t size,
2147    int page, int flags, int *big)
2148{
2149
2150	if (cd->sc_periph->periph_quirks & PQUIRK_ONLYBIG) {
2151		*big = 1;
2152		return scsipi_mode_sense_big(cd->sc_periph, byte2, page, sense,
2153		    size + sizeof(struct scsipi_mode_header_big),
2154		    flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000);
2155	} else {
2156		*big = 0;
2157		return scsipi_mode_sense(cd->sc_periph, byte2, page, sense,
2158		    size + sizeof(struct scsipi_mode_header),
2159		    flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000);
2160	}
2161}
2162
2163static int
2164cd_mode_select(struct cd_softc *cd, u_int8_t byte2, void *sense, size_t size,
2165    int flags, int big)
2166{
2167
2168	if (big) {
2169		struct scsipi_mode_header_big *header = sense;
2170
2171		_lto2b(0, header->data_length);
2172		return scsipi_mode_select_big(cd->sc_periph, byte2, sense,
2173		    size + sizeof(struct scsipi_mode_header_big),
2174		    flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000);
2175	} else {
2176		struct scsipi_mode_header *header = sense;
2177
2178		header->data_length = 0;
2179		return scsipi_mode_select(cd->sc_periph, byte2, sense,
2180		    size + sizeof(struct scsipi_mode_header),
2181		    flags | XS_CTL_DATA_ONSTACK, CDRETRIES, 20000);
2182	}
2183}
2184
2185static int
2186cd_set_pa_immed(struct cd_softc *cd, int flags)
2187{
2188	struct {
2189		union {
2190			struct scsipi_mode_header small;
2191			struct scsipi_mode_header_big big;
2192		} header;
2193		struct cd_audio_page page;
2194	} data;
2195	int error;
2196	uint8_t oflags;
2197	int big, byte2;
2198	struct cd_audio_page *page;
2199
2200	byte2 = SMS_DBD;
2201try_again:
2202	if ((error = cd_mode_sense(cd, byte2, &data, sizeof(data.page),
2203	    AUDIO_PAGE, flags, &big)) != 0) {
2204		if (byte2 == SMS_DBD) {
2205			/* Device may not understand DBD; retry without */
2206			byte2 = 0;
2207			goto try_again;
2208		}
2209		return (error);
2210	}
2211
2212	if (big)
2213		page = (void *)((u_long)&data.header.big +
2214				sizeof data.header.big +
2215				_2btol(data.header.big.blk_desc_len));
2216	else
2217		page = (void *)((u_long)&data.header.small +
2218				sizeof data.header.small +
2219				data.header.small.blk_desc_len);
2220
2221	oflags = page->flags;
2222	page->flags &= ~CD_PA_SOTC;
2223	page->flags |= CD_PA_IMMED;
2224	if (oflags == page->flags)
2225		return (0);
2226
2227	return (cd_mode_select(cd, SMS_PF, &data,
2228	    sizeof(struct scsipi_mode_page_header) + page->pg_length,
2229	    flags, big));
2230}
2231
2232static int
2233cd_setchan(struct cd_softc *cd, int p0, int p1, int p2, int p3, int flags)
2234{
2235	struct {
2236		union {
2237			struct scsipi_mode_header small;
2238			struct scsipi_mode_header_big big;
2239		} header;
2240		struct cd_audio_page page;
2241	} data;
2242	int error;
2243	int big, byte2;
2244	struct cd_audio_page *page;
2245
2246	byte2 = SMS_DBD;
2247try_again:
2248	if ((error = cd_mode_sense(cd, byte2, &data, sizeof(data.page),
2249	    AUDIO_PAGE, flags, &big)) != 0) {
2250		if (byte2 == SMS_DBD) {
2251			/* Device may not understand DBD; retry without */
2252			byte2 = 0;
2253			goto try_again;
2254		}
2255		return (error);
2256	}
2257
2258	if (big)
2259		page = (void *)((u_long)&data.header.big +
2260				sizeof data.header.big +
2261				_2btol(data.header.big.blk_desc_len));
2262	else
2263		page = (void *)((u_long)&data.header.small +
2264				sizeof data.header.small +
2265				data.header.small.blk_desc_len);
2266
2267	page->port[0].channels = p0;
2268	page->port[1].channels = p1;
2269	page->port[2].channels = p2;
2270	page->port[3].channels = p3;
2271
2272	return (cd_mode_select(cd, SMS_PF, &data,
2273	    sizeof(struct scsipi_mode_page_header) + page->pg_length,
2274	    flags, big));
2275}
2276
2277static int
2278cd_getvol(struct cd_softc *cd, struct ioc_vol *arg, int flags)
2279{
2280	struct {
2281		union {
2282			struct scsipi_mode_header small;
2283			struct scsipi_mode_header_big big;
2284		} header;
2285		struct cd_audio_page page;
2286	} data;
2287	int error;
2288	int big, byte2;
2289	struct cd_audio_page *page;
2290
2291	byte2 = SMS_DBD;
2292try_again:
2293	if ((error = cd_mode_sense(cd, byte2, &data, sizeof(data.page),
2294	    AUDIO_PAGE, flags, &big)) != 0) {
2295		if (byte2 == SMS_DBD) {
2296			/* Device may not understand DBD; retry without */
2297			byte2 = 0;
2298			goto try_again;
2299		}
2300		return (error);
2301	}
2302
2303	if (big)
2304		page = (void *)((u_long)&data.header.big +
2305				sizeof data.header.big +
2306				_2btol(data.header.big.blk_desc_len));
2307	else
2308		page = (void *)((u_long)&data.header.small +
2309				sizeof data.header.small +
2310				data.header.small.blk_desc_len);
2311
2312	arg->vol[0] = page->port[0].volume;
2313	arg->vol[1] = page->port[1].volume;
2314	arg->vol[2] = page->port[2].volume;
2315	arg->vol[3] = page->port[3].volume;
2316
2317	return (0);
2318}
2319
2320static int
2321cd_setvol(struct cd_softc *cd, const struct ioc_vol *arg, int flags)
2322{
2323	struct {
2324		union {
2325			struct scsipi_mode_header small;
2326			struct scsipi_mode_header_big big;
2327		} header;
2328		struct cd_audio_page page;
2329	} data, mask;
2330	int error;
2331	int big, byte2;
2332	struct cd_audio_page *page, *page2;
2333
2334	byte2 = SMS_DBD;
2335try_again:
2336	if ((error = cd_mode_sense(cd, byte2, &data, sizeof(data.page),
2337	    AUDIO_PAGE, flags, &big)) != 0) {
2338		if (byte2 == SMS_DBD) {
2339			/* Device may not understand DBD; retry without */
2340			byte2 = 0;
2341			goto try_again;
2342		}
2343		return (error);
2344	}
2345	if ((error = cd_mode_sense(cd, byte2, &mask, sizeof(mask.page),
2346	    AUDIO_PAGE|SMS_PAGE_CTRL_CHANGEABLE, flags, &big)) != 0)
2347		return (error);
2348
2349	if (big) {
2350		page = (void *)((u_long)&data.header.big +
2351				sizeof data.header.big +
2352				_2btol(data.header.big.blk_desc_len));
2353		page2 = (void *)((u_long)&mask.header.big +
2354				sizeof mask.header.big +
2355				_2btol(mask.header.big.blk_desc_len));
2356	} else {
2357		page = (void *)((u_long)&data.header.small +
2358				sizeof data.header.small +
2359				data.header.small.blk_desc_len);
2360		page2 = (void *)((u_long)&mask.header.small +
2361				sizeof mask.header.small +
2362				mask.header.small.blk_desc_len);
2363	}
2364
2365	page->port[0].volume = arg->vol[0] & page2->port[0].volume;
2366	page->port[1].volume = arg->vol[1] & page2->port[1].volume;
2367	page->port[2].volume = arg->vol[2] & page2->port[2].volume;
2368	page->port[3].volume = arg->vol[3] & page2->port[3].volume;
2369
2370	page->port[0].channels = CHANNEL_0;
2371	page->port[1].channels = CHANNEL_1;
2372
2373	return (cd_mode_select(cd, SMS_PF, &data,
2374	    sizeof(struct scsipi_mode_page_header) + page->pg_length,
2375	    flags, big));
2376}
2377
2378static int
2379cd_load_unload(struct cd_softc *cd, struct ioc_load_unload *args)
2380{
2381	struct scsipi_load_unload cmd;
2382
2383	memset(&cmd, 0, sizeof(cmd));
2384	cmd.opcode = LOAD_UNLOAD;
2385	cmd.options = args->options;    /* ioctl uses MMC values */
2386	cmd.slot = args->slot;
2387
2388	return (scsipi_command(cd->sc_periph, (void *)&cmd, sizeof(cmd), 0, 0,
2389	    CDRETRIES, 200000, NULL, 0));
2390}
2391
2392static int
2393cd_setblksize(struct cd_softc *cd)
2394{
2395	struct {
2396		union {
2397			struct scsipi_mode_header small;
2398			struct scsipi_mode_header_big big;
2399		} header;
2400		struct scsi_blk_desc blk_desc;
2401	} data;
2402	int error;
2403	int big, bsize;
2404	struct scsi_blk_desc *bdesc;
2405
2406	if ((error = cd_mode_sense(cd, 0, &data, sizeof(data.blk_desc), 0, 0,
2407	    &big)) != 0)
2408		return (error);
2409
2410	if (big) {
2411		bdesc = (void *)(&data.header.big + 1);
2412		bsize = _2btol(data.header.big.blk_desc_len);
2413	} else {
2414		bdesc = (void *)(&data.header.small + 1);
2415		bsize = data.header.small.blk_desc_len;
2416	}
2417
2418	if (bsize == 0) {
2419printf("cd_setblksize: trying to change bsize, but no blk_desc\n");
2420		return (EINVAL);
2421	}
2422	if (_3btol(bdesc->blklen) == 2048) {
2423printf("cd_setblksize: trying to change bsize, but blk_desc is correct\n");
2424		return (EINVAL);
2425	}
2426
2427	_lto3b(2048, bdesc->blklen);
2428
2429	return (cd_mode_select(cd, SMS_PF, &data, sizeof(data.blk_desc), 0,
2430	    big));
2431}
2432