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