cd.c revision 1.145
1/*	$NetBSD: cd.c,v 1.145 2001/04/25 17:53:38 bouyer Exp $	*/
2
3/*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *        This product includes software developed by the NetBSD
21 *        Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 *    contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39/*
40 * Originally written by Julian Elischer (julian@tfs.com)
41 * for TRW Financial Systems for use under the MACH(2.5) operating system.
42 *
43 * TRW Financial Systems, in accordance with their agreement with Carnegie
44 * Mellon University, makes this software available to CMU to distribute
45 * or use in any manner that they see fit as long as this message is kept with
46 * the software. For this reason TFS also grants any other persons or
47 * organisations permission to use or modify this software.
48 *
49 * TFS supplies this software to be publicly redistributed
50 * on the understanding that TFS is not responsible for the correct
51 * functioning of this software in any circumstances.
52 *
53 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
54 */
55
56#include "rnd.h"
57
58#include <sys/types.h>
59#include <sys/param.h>
60#include <sys/systm.h>
61#include <sys/kernel.h>
62#include <sys/file.h>
63#include <sys/stat.h>
64#include <sys/ioctl.h>
65#include <sys/buf.h>
66#include <sys/uio.h>
67#include <sys/malloc.h>
68#include <sys/errno.h>
69#include <sys/device.h>
70#include <sys/disklabel.h>
71#include <sys/disk.h>
72#include <sys/cdio.h>
73#include <sys/dvdio.h>
74#include <sys/scsiio.h>
75#include <sys/proc.h>
76#include <sys/conf.h>
77#include <sys/vnode.h>
78#if NRND > 0
79#include <sys/rnd.h>
80#endif
81
82#include <dev/scsipi/scsipi_all.h>
83#include <dev/scsipi/scsipi_cd.h>
84#include <dev/scsipi/scsipi_disk.h>	/* rw_big and start_stop come */
85					/* from there */
86#include <dev/scsipi/scsi_disk.h>	/* rw comes from there */
87#include <dev/scsipi/scsipiconf.h>
88#include <dev/scsipi/cdvar.h>
89
90#include "cd.h"		/* NCD_SCSIBUS and NCD_ATAPIBUS come from here */
91
92#define	CDUNIT(z)			DISKUNIT(z)
93#define	CDPART(z)			DISKPART(z)
94#define	CDMINOR(unit, part)		DISKMINOR(unit, part)
95#define	MAKECDDEV(maj, unit, part)	MAKEDISKDEV(maj, unit, part)
96
97#define MAXTRACK	99
98#define CD_BLOCK_OFFSET	150
99#define CD_FRAMES	75
100#define CD_SECS		60
101
102struct cd_toc {
103	struct ioc_toc_header header;
104	struct cd_toc_entry entries[MAXTRACK+1]; /* One extra for the */
105						 /* leadout */
106};
107
108int	cdlock __P((struct cd_softc *));
109void	cdunlock __P((struct cd_softc *));
110void	cdstart __P((struct scsipi_periph *));
111void	cdminphys __P((struct buf *));
112void	cdgetdefaultlabel __P((struct cd_softc *, struct disklabel *));
113void	cdgetdisklabel __P((struct cd_softc *));
114void	cddone __P((struct scsipi_xfer *));
115int	cd_interpret_sense __P((struct scsipi_xfer *));
116u_long	cd_size __P((struct cd_softc *, int));
117void	lba2msf __P((u_long, u_char *, u_char *, u_char *));
118u_long	msf2lba __P((u_char, u_char, u_char));
119int	cd_play __P((struct cd_softc *, int, int));
120int	cd_play_tracks __P((struct cd_softc *, int, int, int, int));
121int	cd_play_msf __P((struct cd_softc *, int, int, int, int, int, int));
122int	cd_pause __P((struct cd_softc *, int));
123int	cd_reset __P((struct cd_softc *));
124int	cd_read_subchannel __P((struct cd_softc *, int, int, int,
125	    struct cd_sub_channel_info *, int, int));
126int	cd_read_toc __P((struct cd_softc *, int, int, void *, int, int, int));
127int	cd_get_parms __P((struct cd_softc *, int));
128int	cd_load_toc __P((struct cd_softc *, struct cd_toc *, int));
129int	dvd_auth __P((struct cd_softc *, dvd_authinfo *));
130int	dvd_read_physical __P((struct cd_softc *, dvd_struct *));
131int	dvd_read_copyright __P((struct cd_softc *, dvd_struct *));
132int	dvd_read_disckey __P((struct cd_softc *, dvd_struct *));
133int	dvd_read_bca __P((struct cd_softc *, dvd_struct *));
134int	dvd_read_manufact __P((struct cd_softc *, dvd_struct *));
135int	dvd_read_struct __P((struct cd_softc *, dvd_struct *));
136
137extern struct cfdriver cd_cd;
138
139struct dkdriver cddkdriver = { cdstrategy };
140
141const struct scsipi_periphsw cd_switch = {
142	cd_interpret_sense,	/* use our error handler first */
143	cdstart,		/* we have a queue, which is started by this */
144	NULL,			/* we do not have an async handler */
145	cddone,			/* deal with stats at interrupt time */
146};
147
148/*
149 * The routine called by the low level scsi routine when it discovers
150 * A device suitable for this driver
151 */
152void
153cdattach(parent, cd, periph, ops)
154	struct device *parent;
155	struct cd_softc *cd;
156	struct scsipi_periph *periph;
157	const struct cd_ops *ops;
158{
159	SC_DEBUG(periph, SCSIPI_DB2, ("cdattach: "));
160
161	BUFQ_INIT(&cd->buf_queue);
162
163	/*
164	 * Store information needed to contact our base driver
165	 */
166	cd->sc_periph = periph;
167	cd->sc_ops = ops;
168
169	periph->periph_dev = &cd->sc_dev;
170	periph->periph_switch = &cd_switch;
171
172	/*
173	 * Increase our openings to the maximum-per-periph
174	 * supported by the adapter.  This will either be
175	 * clamped down or grown by the adapter if necessary.
176	 */
177	periph->periph_openings =
178	    SCSIPI_CHAN_MAX_PERIPH(periph->periph_channel);
179	periph->periph_flags |= PERIPH_GROW_OPENINGS;
180
181	/*
182	 * Initialize and attach the disk structure.
183	 */
184  	cd->sc_dk.dk_driver = &cddkdriver;
185	cd->sc_dk.dk_name = cd->sc_dev.dv_xname;
186	disk_attach(&cd->sc_dk);
187
188#ifdef __BROKEN_DK_ESTABLISH
189	dk_establish(&cd->sc_dk, &cd->sc_dev);		/* XXX */
190#endif
191
192	printf("\n");
193
194#if NRND > 0
195	rnd_attach_source(&cd->rnd_source, cd->sc_dev.dv_xname,
196			  RND_TYPE_DISK, 0);
197#endif
198}
199
200int
201cdactivate(self, act)
202	struct device *self;
203	enum devact act;
204{
205	int rv = 0;
206
207	switch (act) {
208	case DVACT_ACTIVATE:
209		rv = EOPNOTSUPP;
210		break;
211
212	case DVACT_DEACTIVATE:
213		/*
214		 * Nothing to do; we key off the device's DVF_ACTIVE.
215		 */
216		break;
217	}
218	return (rv);
219}
220
221int
222cddetach(self, flags)
223	struct device *self;
224	int flags;
225{
226	struct cd_softc *cd = (struct cd_softc *) self;
227	struct buf *bp;
228	int s, bmaj, cmaj, mn;
229
230	/* locate the major number */
231	for (bmaj = 0; bmaj <= nblkdev; bmaj++)
232		if (bdevsw[bmaj].d_open == cdopen)
233			break;
234	for (cmaj = 0; cmaj <= nchrdev; cmaj++)
235		if (cdevsw[cmaj].d_open == cdopen)
236			break;
237
238	s = splbio();
239
240	/* Kill off any queued buffers. */
241	while ((bp = BUFQ_FIRST(&cd->buf_queue)) != NULL) {
242		BUFQ_REMOVE(&cd->buf_queue, bp);
243		bp->b_error = EIO;
244		bp->b_flags |= B_ERROR;
245		bp->b_resid = bp->b_bcount;
246		biodone(bp);
247	}
248
249	/* Kill off any pending commands. */
250	scsipi_kill_pending(cd->sc_periph);
251
252	splx(s);
253
254	/* Nuke the vnodes for any open instances */
255	mn = CDMINOR(self->dv_unit, 0);
256	vdevgone(bmaj, mn, mn + (MAXPARTITIONS - 1), VBLK);
257	vdevgone(cmaj, mn, mn + (MAXPARTITIONS - 1), VCHR);
258
259	/* Detach from the disk list. */
260	disk_detach(&cd->sc_dk);
261
262#if 0
263	/* Get rid of the shutdown hook. */
264	if (cd->sc_sdhook != NULL)
265		shutdownhook_disestablish(cd->sc_sdhook);
266#endif
267
268#if NRND > 0
269	/* Unhook the entropy source. */
270	rnd_detach_source(&cd->rnd_source);
271#endif
272
273	return (0);
274}
275
276/*
277 * Wait interruptibly for an exclusive lock.
278 *
279 * XXX
280 * Several drivers do this; it should be abstracted and made MP-safe.
281 */
282int
283cdlock(cd)
284	struct cd_softc *cd;
285{
286	int error;
287
288	while ((cd->flags & CDF_LOCKED) != 0) {
289		cd->flags |= CDF_WANTED;
290		if ((error = tsleep(cd, PRIBIO | PCATCH, "cdlck", 0)) != 0)
291			return (error);
292	}
293	cd->flags |= CDF_LOCKED;
294	return (0);
295}
296
297/*
298 * Unlock and wake up any waiters.
299 */
300void
301cdunlock(cd)
302	struct cd_softc *cd;
303{
304
305	cd->flags &= ~CDF_LOCKED;
306	if ((cd->flags & CDF_WANTED) != 0) {
307		cd->flags &= ~CDF_WANTED;
308		wakeup(cd);
309	}
310}
311
312/*
313 * open the device. Make sure the partition info is a up-to-date as can be.
314 */
315int
316cdopen(dev, flag, fmt, p)
317	dev_t dev;
318	int flag, fmt;
319	struct proc *p;
320{
321	struct cd_softc *cd;
322	struct scsipi_periph *periph;
323	struct scsipi_adapter *adapt;
324	int unit, part;
325	int error;
326
327	unit = CDUNIT(dev);
328	if (unit >= cd_cd.cd_ndevs)
329		return (ENXIO);
330	cd = cd_cd.cd_devs[unit];
331	if (cd == NULL)
332		return (ENXIO);
333
334	periph = cd->sc_periph;
335	adapt = periph->periph_channel->chan_adapter;
336	part = CDPART(dev);
337
338	SC_DEBUG(periph, SCSIPI_DB1,
339	    ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
340	    cd_cd.cd_ndevs, CDPART(dev)));
341
342	/*
343	 * If this is the first open of this device, add a reference
344	 * to the adapter.
345	 */
346	if (cd->sc_dk.dk_openmask == 0 &&
347	    (error = scsipi_adapter_addref(adapt)) != 0)
348		return (error);
349
350	if ((error = cdlock(cd)) != 0)
351		goto bad4;
352
353	if ((periph->periph_flags & PERIPH_OPEN) != 0) {
354		/*
355		 * If any partition is open, but the disk has been invalidated,
356		 * disallow further opens.
357		 */
358		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0 &&
359			(part != RAW_PART || fmt != S_IFCHR )) {
360			error = EIO;
361			goto bad3;
362		}
363	} else {
364		/* Check that it is still responding and ok. */
365		error = scsipi_test_unit_ready(periph,
366		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
367		    XS_CTL_IGNORE_NOT_READY);
368		SC_DEBUG(periph, SCSIPI_DB1,
369		    ("cdopen: scsipi_test_unit_ready, error=%d\n", error));
370		if (error)
371			goto bad3;
372
373		/*
374		 * Start the pack spinning if necessary. Always allow the
375		 * raw parition to be opened, for raw IOCTLs. Data transfers
376		 * will check for SDEV_MEDIA_LOADED.
377		 */
378		error = scsipi_start(periph, SSS_START,
379		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
380		    XS_CTL_SILENT);
381		SC_DEBUG(periph, SCSIPI_DB1,
382		    ("cdopen: scsipi_start, error=%d\n", error));
383		if (error) {
384			if (part != RAW_PART || fmt != S_IFCHR)
385				goto bad3;
386			else
387				goto out;
388		}
389
390		periph->periph_flags |= PERIPH_OPEN;
391
392		/* Lock the pack in. */
393		error = scsipi_prevent(periph, PR_PREVENT,
394		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE);
395		SC_DEBUG(periph, SCSIPI_DB1,
396		    ("cdopen: scsipi_prevent, error=%d\n", error));
397		if (error)
398			goto bad;
399
400		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
401			periph->periph_flags |= PERIPH_MEDIA_LOADED;
402
403			/* Load the physical device parameters. */
404			if (cd_get_parms(cd, 0) != 0) {
405				error = ENXIO;
406				goto bad2;
407			}
408			SC_DEBUG(periph, SCSIPI_DB3, ("Params loaded "));
409
410			/* Fabricate a disk label. */
411			cdgetdisklabel(cd);
412			SC_DEBUG(periph, SCSIPI_DB3, ("Disklabel fabricated "));
413		}
414	}
415
416	/* Check that the partition exists. */
417	if (part != RAW_PART &&
418	    (part >= cd->sc_dk.dk_label->d_npartitions ||
419	    cd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
420		error = ENXIO;
421		goto bad;
422	}
423
424out:	/* Insure only one open at a time. */
425	switch (fmt) {
426	case S_IFCHR:
427		cd->sc_dk.dk_copenmask |= (1 << part);
428		break;
429	case S_IFBLK:
430		cd->sc_dk.dk_bopenmask |= (1 << part);
431		break;
432	}
433	cd->sc_dk.dk_openmask =
434	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
435
436	SC_DEBUG(periph, SCSIPI_DB3, ("open complete\n"));
437	cdunlock(cd);
438	return (0);
439
440bad2:
441	periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
442
443bad:
444	if (cd->sc_dk.dk_openmask == 0) {
445		scsipi_prevent(periph, PR_ALLOW,
446		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE);
447		periph->periph_flags &= ~PERIPH_OPEN;
448	}
449
450bad3:
451	cdunlock(cd);
452bad4:
453	if (cd->sc_dk.dk_openmask == 0)
454		scsipi_adapter_delref(adapt);
455	return (error);
456}
457
458/*
459 * close the device.. only called if we are the LAST
460 * occurence of an open device
461 */
462int
463cdclose(dev, flag, fmt, p)
464	dev_t dev;
465	int flag, fmt;
466	struct proc *p;
467{
468	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
469	struct scsipi_periph *periph = cd->sc_periph;
470	struct scsipi_adapter *adapt = periph->periph_channel->chan_adapter;
471	int part = CDPART(dev);
472	int error;
473
474	if ((error = cdlock(cd)) != 0)
475		return (error);
476
477	switch (fmt) {
478	case S_IFCHR:
479		cd->sc_dk.dk_copenmask &= ~(1 << part);
480		break;
481	case S_IFBLK:
482		cd->sc_dk.dk_bopenmask &= ~(1 << part);
483		break;
484	}
485	cd->sc_dk.dk_openmask =
486	    cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
487
488	if (cd->sc_dk.dk_openmask == 0) {
489		scsipi_wait_drain(periph);
490
491		scsipi_prevent(periph, PR_ALLOW,
492		    XS_CTL_IGNORE_ILLEGAL_REQUEST | XS_CTL_IGNORE_MEDIA_CHANGE |
493		    XS_CTL_IGNORE_NOT_READY);
494		periph->periph_flags &= ~PERIPH_OPEN;
495
496		scsipi_wait_drain(periph);
497
498		scsipi_adapter_delref(adapt);
499	}
500
501	cdunlock(cd);
502	return (0);
503}
504
505/*
506 * Actually translate the requested transfer into one the physical driver can
507 * understand.  The transfer is described by a buf and will include only one
508 * physical transfer.
509 */
510void
511cdstrategy(bp)
512	struct buf *bp;
513{
514	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
515	struct disklabel *lp;
516	struct scsipi_periph *periph = cd->sc_periph;
517	daddr_t blkno;
518	int s;
519
520	SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdstrategy "));
521	SC_DEBUG(cd->sc_periph, SCSIPI_DB1,
522	    ("%ld bytes @ blk %d\n", bp->b_bcount, bp->b_blkno));
523	/*
524	 * If the device has been made invalid, error out
525	 * maybe the media changed
526	 */
527	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
528		if (periph->periph_flags & PERIPH_OPEN)
529			bp->b_error = EIO;
530		else
531			bp->b_error = ENODEV;
532		goto bad;
533	}
534
535	lp = cd->sc_dk.dk_label;
536
537	/*
538	 * The transfer must be a whole number of blocks, offset must not
539	 * be negative.
540	 */
541	if ((bp->b_bcount % lp->d_secsize) != 0 ||
542	    bp->b_blkno < 0 ) {
543		bp->b_error = EINVAL;
544		goto bad;
545	}
546	/*
547	 * If it's a null transfer, return immediately
548	 */
549	if (bp->b_bcount == 0)
550		goto done;
551
552	/*
553	 * Do bounds checking, adjust transfer. if error, process.
554	 * If end of partition, just return.
555	 */
556	if (CDPART(bp->b_dev) != RAW_PART &&
557	    bounds_check_with_label(bp, lp,
558	    (cd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0)
559		goto done;
560
561	/*
562	 * Now convert the block number to absolute and put it in
563	 * terms of the device's logical block size.
564	 */
565	blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
566	if (CDPART(bp->b_dev) != RAW_PART)
567		blkno += lp->d_partitions[CDPART(bp->b_dev)].p_offset;
568
569	bp->b_rawblkno = blkno;
570
571	s = splbio();
572
573	/*
574	 * Place it in the queue of disk activities for this disk.
575	 *
576	 * XXX Only do disksort() if the current operating mode does not
577	 * XXX include tagged queueing.
578	 */
579	disksort_blkno(&cd->buf_queue, bp);
580
581	/*
582	 * Tell the device to get going on the transfer if it's
583	 * not doing anything, otherwise just wait for completion
584	 */
585	cdstart(cd->sc_periph);
586
587	splx(s);
588	return;
589
590bad:
591	bp->b_flags |= B_ERROR;
592done:
593	/*
594	 * Correctly set the buf to indicate a completed xfer
595	 */
596	bp->b_resid = bp->b_bcount;
597	biodone(bp);
598}
599
600/*
601 * cdstart looks to see if there is a buf waiting for the device
602 * and that the device is not already busy. If both are true,
603 * It deques the buf and creates a scsi command to perform the
604 * transfer in the buf. The transfer request will call scsipi_done
605 * on completion, which will in turn call this routine again
606 * so that the next queued transfer is performed.
607 * The bufs are queued by the strategy routine (cdstrategy)
608 *
609 * This routine is also called after other non-queued requests
610 * have been made of the scsi driver, to ensure that the queue
611 * continues to be drained.
612 *
613 * must be called at the correct (highish) spl level
614 * cdstart() is called at splbio from cdstrategy and scsipi_done
615 */
616void
617cdstart(periph)
618	struct scsipi_periph *periph;
619{
620	struct cd_softc *cd = (void *)periph->periph_dev;
621	struct disklabel *lp = cd->sc_dk.dk_label;
622	struct buf *bp = 0;
623	struct scsipi_rw_big cmd_big;
624#if NCD_SCSIBUS > 0
625	struct scsi_rw cmd_small;
626#endif
627	struct scsipi_generic *cmdp;
628	int flags, nblks, cmdlen, error;
629
630	SC_DEBUG(periph, SCSIPI_DB2, ("cdstart "));
631	/*
632	 * Check if the device has room for another command
633	 */
634	while (periph->periph_active < periph->periph_openings) {
635		/*
636		 * there is excess capacity, but a special waits
637		 * It'll need the adapter as soon as we clear out of the
638		 * way and let it run (user level wait).
639		 */
640		if (periph->periph_flags & PERIPH_WAITING) {
641			periph->periph_flags &= ~PERIPH_WAITING;
642			wakeup((caddr_t)periph);
643			return;
644		}
645
646		/*
647		 * See if there is a buf with work for us to do..
648		 */
649		if ((bp = BUFQ_FIRST(&cd->buf_queue)) == NULL)
650			return;
651		BUFQ_REMOVE(&cd->buf_queue, bp);
652
653		/*
654		 * If the device has become invalid, abort all the
655		 * reads and writes until all files have been closed and
656		 * re-opened
657		 */
658		if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
659			bp->b_error = EIO;
660			bp->b_flags |= B_ERROR;
661			bp->b_resid = bp->b_bcount;
662			biodone(bp);
663			continue;
664		}
665
666		/*
667		 * We have a buf, now we should make a command.
668		 */
669
670		nblks = howmany(bp->b_bcount, lp->d_secsize);
671
672#if NCD_SCSIBUS > 0
673		/*
674		 *  Fill out the scsi command.  If the transfer will
675		 *  fit in a "small" cdb, use it.
676		 */
677		if (((bp->b_rawblkno & 0x1fffff) == bp->b_rawblkno) &&
678		    ((nblks & 0xff) == nblks) &&
679		    !(periph->periph_quirks & PQUIRK_ONLYBIG) &&
680		    scsipi_periph_bustype(periph) == SCSIPI_BUSTYPE_SCSI) {
681			/*
682			 * We can fit in a small cdb.
683			 */
684			bzero(&cmd_small, sizeof(cmd_small));
685			cmd_small.opcode = (bp->b_flags & B_READ) ?
686			    SCSI_READ_COMMAND : SCSI_WRITE_COMMAND;
687			_lto3b(bp->b_rawblkno, cmd_small.addr);
688			cmd_small.length = nblks & 0xff;
689			cmdlen = sizeof(cmd_small);
690			cmdp = (struct scsipi_generic *)&cmd_small;
691		} else
692#endif
693		{
694			/*
695			 * Need a large cdb.
696			 */
697			bzero(&cmd_big, sizeof(cmd_big));
698			cmd_big.opcode = (bp->b_flags & B_READ) ?
699			    READ_BIG : WRITE_BIG;
700			_lto4b(bp->b_rawblkno, cmd_big.addr);
701			_lto2b(nblks, cmd_big.length);
702			cmdlen = sizeof(cmd_big);
703			cmdp = (struct scsipi_generic *)&cmd_big;
704		}
705
706		/* Instrumentation. */
707		disk_busy(&cd->sc_dk);
708
709		/*
710		 * Figure out what flags to use.
711		 * XXX Need a B_ORDERED.
712		 */
713		flags = XS_CTL_NOSLEEP|XS_CTL_ASYNC;
714		if (bp->b_flags & B_READ)
715			flags |= XS_CTL_DATA_IN | XS_CTL_SIMPLE_TAG;
716		else
717			flags |= XS_CTL_DATA_OUT | XS_CTL_ORDERED_TAG;
718
719		/*
720		 * Call the routine that chats with the adapter.
721		 * Note: we cannot sleep as we may be an interrupt
722		 */
723		error = scsipi_command(periph, cmdp, cmdlen,
724		    (u_char *)bp->b_data, bp->b_bcount,
725		    CDRETRIES, 30000, bp, flags);
726		if (error) {
727			disk_unbusy(&cd->sc_dk, 0);
728			printf("%s: not queued, error %d\n",
729			    cd->sc_dev.dv_xname, error);
730		}
731	}
732}
733
734void
735cddone(xs)
736	struct scsipi_xfer *xs;
737{
738	struct cd_softc *cd = (void *)xs->xs_periph->periph_dev;
739
740	if (xs->bp != NULL) {
741		disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid);
742#if NRND > 0
743		rnd_add_uint32(&cd->rnd_source, xs->bp->b_rawblkno);
744#endif
745	}
746}
747
748int cd_interpret_sense(xs)
749	struct scsipi_xfer *xs;
750{
751	struct scsipi_periph *periph = xs->xs_periph;
752	struct scsipi_sense_data *sense = &xs->sense.scsi_sense;
753	int retval = EJUSTRETURN;
754
755	/*
756	 * If it isn't a extended or extended/deferred error, let
757	 * the generic code handle it.
758	 */
759	if ((sense->error_code & SSD_ERRCODE) != 0x70 &&
760	    (sense->error_code & SSD_ERRCODE) != 0x71) {	/* DEFFERRED */
761		return (retval);
762	}
763
764	/*
765	 * If we got a "Unit not ready" (SKEY_NOT_READY) and "Logical Unit
766	 * Is In The Process of Becoming Ready" (Sense code 0x04,0x01), then
767	 * wait a bit for the drive to spin up
768	 */
769
770	if ((sense->flags & SSD_KEY) == SKEY_NOT_READY &&
771	    sense->add_sense_code == 0x4 &&
772	    sense->add_sense_code_qual == 0x01)	{
773		/*
774		 * Sleep for 5 seconds to wait for the drive to spin up
775		 */
776
777		SC_DEBUG(periph, SDEV_DB1, ("Waiting 5 sec for CD "
778						"spinup\n"));
779		scsipi_periph_freeze(periph, 1);
780		callout_reset(&periph->periph_callout,
781		    5 * hz, scsipi_periph_timed_thaw, periph);
782		retval = ERESTART;
783	}
784	return (retval);
785}
786
787void
788cdminphys(bp)
789	struct buf *bp;
790{
791	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
792	long max;
793
794	/*
795	 * If the device is ancient, we want to make sure that
796	 * the transfer fits into a 6-byte cdb.
797	 *
798	 * XXX Note that the SCSI-I spec says that 256-block transfers
799	 * are allowed in a 6-byte read/write, and are specified
800	 * by settng the "length" to 0.  However, we're conservative
801	 * here, allowing only 255-block transfers in case an
802	 * ancient device gets confused by length == 0.  A length of 0
803	 * in a 10-byte read/write actually means 0 blocks.
804	 */
805	if (cd->flags & CDF_ANCIENT) {
806		max = cd->sc_dk.dk_label->d_secsize * 0xff;
807
808		if (bp->b_bcount > max)
809			bp->b_bcount = max;
810	}
811
812	(*cd->sc_periph->periph_channel->chan_adapter->adapt_minphys)(bp);
813}
814
815int
816cdread(dev, uio, ioflag)
817	dev_t dev;
818	struct uio *uio;
819	int ioflag;
820{
821
822	return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
823}
824
825int
826cdwrite(dev, uio, ioflag)
827	dev_t dev;
828	struct uio *uio;
829	int ioflag;
830{
831
832	return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
833}
834
835/*
836 * conversion between minute-seconde-frame and logical block adress
837 * adresses format
838 */
839void
840lba2msf (lba, m, s, f)
841	u_long lba;
842	u_char *m, *s, *f;
843{
844	u_long tmp;
845
846	tmp = lba + CD_BLOCK_OFFSET;	/* offset of first logical frame */
847	tmp &= 0xffffff;		/* negative lbas use only 24 bits */
848	*m = tmp / (CD_SECS * CD_FRAMES);
849	tmp %= (CD_SECS * CD_FRAMES);
850	*s = tmp / CD_FRAMES;
851	*f = tmp % CD_FRAMES;
852}
853
854u_long
855msf2lba (m, s, f)
856	u_char m, s, f;
857{
858
859	return ((((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET);
860}
861
862
863/*
864 * Perform special action on behalf of the user.
865 * Knows about the internals of this device
866 */
867int
868cdioctl(dev, cmd, addr, flag, p)
869	dev_t dev;
870	u_long cmd;
871	caddr_t addr;
872	int flag;
873	struct proc *p;
874{
875	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
876	struct scsipi_periph *periph = cd->sc_periph;
877	int part = CDPART(dev);
878	int error;
879#ifdef __HAVE_OLD_DISKLABEL
880	struct disklabel newlabel;
881#endif
882
883	SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdioctl 0x%lx ", cmd));
884
885	/*
886	 * If the device is not valid, some IOCTLs can still be
887	 * handled on the raw partition. Check this here.
888	 */
889	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
890		switch (cmd) {
891		case DIOCWLABEL:
892		case DIOCLOCK:
893		case ODIOCEJECT:
894		case DIOCEJECT:
895		case SCIOCIDENTIFY:
896		case OSCIOCIDENTIFY:
897		case SCIOCCOMMAND:
898		case SCIOCDEBUG:
899		case CDIOCGETVOL:
900		case CDIOCSETVOL:
901		case CDIOCSETMONO:
902		case CDIOCSETSTEREO:
903		case CDIOCSETMUTE:
904		case CDIOCSETLEFT:
905		case CDIOCSETRIGHT:
906		case CDIOCCLOSE:
907		case CDIOCEJECT:
908		case CDIOCALLOW:
909		case CDIOCPREVENT:
910		case CDIOCSETDEBUG:
911		case CDIOCCLRDEBUG:
912		case CDIOCRESET:
913		case SCIOCRESET:
914		case CDIOCLOADUNLOAD:
915		case DVD_AUTH:
916		case DVD_READ_STRUCT:
917			if (part == RAW_PART)
918				break;
919		/* FALLTHROUGH */
920		default:
921			if ((periph->periph_flags & PERIPH_OPEN) == 0)
922				return (ENODEV);
923			else
924				return (EIO);
925		}
926	}
927
928	switch (cmd) {
929	case DIOCGDINFO:
930		*(struct disklabel *)addr = *(cd->sc_dk.dk_label);
931		return (0);
932#ifdef __HAVE_OLD_DISKLABEL
933	case ODIOCGDINFO:
934		newlabel = *(cd->sc_dk.dk_label);
935		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
936			return ENOTTY;
937		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
938		return (0);
939#endif
940
941	case DIOCGPART:
942		((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label;
943		((struct partinfo *)addr)->part =
944		    &cd->sc_dk.dk_label->d_partitions[part];
945		return (0);
946
947	case DIOCWDINFO:
948	case DIOCSDINFO:
949#ifdef __HAVE_OLD_DISKLABEL
950	case ODIOCWDINFO:
951	case ODIOCSDINFO:
952#endif
953	{
954		struct disklabel *lp;
955
956#ifdef __HAVE_OLD_DISKLABEL
957		if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
958			memset(&newlabel, 0, sizeof newlabel);
959			memcpy(&newlabel, addr, sizeof (struct olddisklabel));
960			lp = &newlabel;
961		} else
962#endif
963		lp = (struct disklabel *)addr;
964
965		if ((flag & FWRITE) == 0)
966			return (EBADF);
967
968		if ((error = cdlock(cd)) != 0)
969			return (error);
970		cd->flags |= CDF_LABELLING;
971
972		error = setdisklabel(cd->sc_dk.dk_label,
973		    lp, /*cd->sc_dk.dk_openmask : */0,
974		    cd->sc_dk.dk_cpulabel);
975		if (error == 0) {
976			/* XXX ? */
977		}
978
979		cd->flags &= ~CDF_LABELLING;
980		cdunlock(cd);
981		return (error);
982	}
983
984	case DIOCWLABEL:
985		return (EBADF);
986
987	case DIOCGDEFLABEL:
988		cdgetdefaultlabel(cd, (struct disklabel *)addr);
989		return (0);
990
991#ifdef __HAVE_OLD_DISKLABEL
992	case ODIOCGDEFLABEL:
993		cdgetdefaultlabel(cd, &newlabel);
994		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
995			return ENOTTY;
996		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
997		return (0);
998#endif
999
1000	case CDIOCPLAYTRACKS: {
1001		struct ioc_play_track *args = (struct ioc_play_track *)addr;
1002
1003		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1004			return (error);
1005		return (cd_play_tracks(cd, args->start_track,
1006		    args->start_index, args->end_track, args->end_index));
1007	}
1008	case CDIOCPLAYMSF: {
1009		struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
1010
1011		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1012			return (error);
1013		return (cd_play_msf(cd, args->start_m, args->start_s,
1014		    args->start_f, args->end_m, args->end_s, args->end_f));
1015	}
1016	case CDIOCPLAYBLOCKS: {
1017		struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
1018
1019		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1020			return (error);
1021		return (cd_play(cd, args->blk, args->len));
1022	}
1023	case CDIOCREADSUBCHANNEL: {
1024		struct ioc_read_subchannel *args =
1025		    (struct ioc_read_subchannel *)addr;
1026		struct cd_sub_channel_info data;
1027		int len = args->data_len;
1028
1029		if (len > sizeof(data) ||
1030		    len < sizeof(struct cd_sub_channel_header))
1031			return (EINVAL);
1032		error = cd_read_subchannel(cd, args->address_format,
1033		    args->data_format, args->track, &data, len,
1034		    XS_CTL_DATA_ONSTACK);
1035		if (error)
1036			return (error);
1037		len = min(len, _2btol(data.header.data_len) +
1038		    sizeof(struct cd_sub_channel_header));
1039		return (copyout(&data, args->data, len));
1040	}
1041	case CDIOREADTOCHEADER: {
1042		struct ioc_toc_header th;
1043
1044		if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th),
1045		    XS_CTL_DATA_ONSTACK, 0)) != 0)
1046			return (error);
1047		if (cd->sc_periph->periph_quirks & PQUIRK_LITTLETOC) {
1048#if BYTE_ORDER == BIG_ENDIAN
1049			bswap((u_int8_t *)&th.len, sizeof(th.len));
1050#endif
1051		} else
1052			th.len = ntohs(th.len);
1053		bcopy(&th, addr, sizeof(th));
1054		return (0);
1055	}
1056	case CDIOREADTOCENTRYS: {
1057		struct cd_toc toc;
1058		struct ioc_read_toc_entry *te =
1059		    (struct ioc_read_toc_entry *)addr;
1060		struct ioc_toc_header *th;
1061		struct cd_toc_entry *cte;
1062		int len = te->data_len;
1063		int ntracks;
1064
1065		th = &toc.header;
1066
1067		if (len > sizeof(toc.entries) ||
1068		    len < sizeof(struct cd_toc_entry))
1069			return (EINVAL);
1070		error = cd_read_toc(cd, te->address_format, te->starting_track,
1071		    &toc, len + sizeof(struct ioc_toc_header),
1072		    XS_CTL_DATA_ONSTACK, 0);
1073		if (error)
1074			return (error);
1075		if (te->address_format == CD_LBA_FORMAT)
1076			for (ntracks =
1077			    th->ending_track - th->starting_track + 1;
1078			    ntracks >= 0; ntracks--) {
1079				cte = &toc.entries[ntracks];
1080				cte->addr_type = CD_LBA_FORMAT;
1081				if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1082#if BYTE_ORDER == BIG_ENDIAN
1083					bswap((u_int8_t*)&cte->addr,
1084					    sizeof(cte->addr));
1085#endif
1086				} else
1087					cte->addr.lba = ntohl(cte->addr.lba);
1088			}
1089		if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1090#if BYTE_ORDER == BIG_ENDIAN
1091			bswap((u_int8_t*)&th->len, sizeof(th->len));
1092#endif
1093		} else
1094			th->len = ntohs(th->len);
1095		len = min(len, th->len - (sizeof(th->starting_track) +
1096		    sizeof(th->ending_track)));
1097		return (copyout(toc.entries, te->data, len));
1098	}
1099	case CDIOREADMSADDR: {
1100		struct cd_toc toc;
1101		int sessno = *(int*)addr;
1102		struct cd_toc_entry *cte;
1103
1104		if (sessno != 0)
1105			return (EINVAL);
1106
1107		error = cd_read_toc(cd, 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#if BYTE_ORDER == BIG_ENDIAN
1118			bswap((u_int8_t*)&cte->addr, sizeof(cte->addr));
1119#endif
1120		} else
1121			cte->addr.lba = ntohl(cte->addr.lba);
1122		if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1123#if BYTE_ORDER == BIG_ENDIAN
1124			bswap((u_int8_t*)&toc.header.len,
1125			    sizeof(toc.header.len));
1126#endif
1127		} else
1128			toc.header.len = ntohs(toc.header.len);
1129
1130		*(int*)addr = (toc.header.len >= 10 && cte->track > 1) ?
1131			cte->addr.lba : 0;
1132		return 0;
1133	}
1134	case CDIOCSETPATCH: {
1135		struct ioc_patch *arg = (struct ioc_patch *)addr;
1136
1137		return ((*cd->sc_ops->cdo_setchan)(cd, arg->patch[0],
1138		    arg->patch[1], arg->patch[2], arg->patch[3], 0));
1139	}
1140	case CDIOCGETVOL: {
1141		struct ioc_vol *arg = (struct ioc_vol *)addr;
1142
1143		return ((*cd->sc_ops->cdo_getvol)(cd, arg, 0));
1144	}
1145	case CDIOCSETVOL: {
1146		struct ioc_vol *arg = (struct ioc_vol *)addr;
1147
1148		return ((*cd->sc_ops->cdo_setvol)(cd, arg, 0));
1149	}
1150
1151	case CDIOCSETMONO:
1152		return ((*cd->sc_ops->cdo_setchan)(cd, BOTH_CHANNEL,
1153		    BOTH_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1154
1155	case CDIOCSETSTEREO:
1156		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
1157		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1158
1159	case CDIOCSETMUTE:
1160		return ((*cd->sc_ops->cdo_setchan)(cd, MUTE_CHANNEL,
1161		    MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1162
1163	case CDIOCSETLEFT:
1164		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
1165		    LEFT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1166
1167	case CDIOCSETRIGHT:
1168		return ((*cd->sc_ops->cdo_setchan)(cd, RIGHT_CHANNEL,
1169		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1170
1171	case CDIOCRESUME:
1172		return (cd_pause(cd, PA_RESUME));
1173	case CDIOCPAUSE:
1174		return (cd_pause(cd, PA_PAUSE));
1175	case CDIOCSTART:
1176		return (scsipi_start(periph, SSS_START, 0));
1177	case CDIOCSTOP:
1178		return (scsipi_start(periph, SSS_STOP, 0));
1179	case CDIOCCLOSE:
1180		return (scsipi_start(periph, SSS_START|SSS_LOEJ,
1181		    XS_CTL_IGNORE_NOT_READY | XS_CTL_IGNORE_MEDIA_CHANGE));
1182	case DIOCEJECT:
1183		if (*(int *)addr == 0) {
1184			/*
1185			 * Don't force eject: check that we are the only
1186			 * partition open. If so, unlock it.
1187			 */
1188			if ((cd->sc_dk.dk_openmask & ~(1 << part)) == 0 &&
1189			    cd->sc_dk.dk_bopenmask + cd->sc_dk.dk_copenmask ==
1190			    cd->sc_dk.dk_openmask) {
1191				error = scsipi_prevent(periph, PR_ALLOW,
1192				    XS_CTL_IGNORE_NOT_READY);
1193				if (error)
1194					return (error);
1195			} else {
1196				return (EBUSY);
1197			}
1198		}
1199		/* FALLTHROUGH */
1200	case CDIOCEJECT: /* FALLTHROUGH */
1201	case ODIOCEJECT:
1202		return (scsipi_start(periph, SSS_STOP|SSS_LOEJ, 0));
1203	case CDIOCALLOW:
1204		return (scsipi_prevent(periph, PR_ALLOW, 0));
1205	case CDIOCPREVENT:
1206		return (scsipi_prevent(periph, PR_PREVENT, 0));
1207	case DIOCLOCK:
1208		return (scsipi_prevent(periph,
1209		    (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0));
1210	case CDIOCSETDEBUG:
1211		cd->sc_periph->periph_dbflags |= (SCSIPI_DB1 | SCSIPI_DB2);
1212		return (0);
1213	case CDIOCCLRDEBUG:
1214		cd->sc_periph->periph_dbflags &= ~(SCSIPI_DB1 | SCSIPI_DB2);
1215		return (0);
1216	case CDIOCRESET:
1217	case SCIOCRESET:
1218		return (cd_reset(cd));
1219	case CDIOCLOADUNLOAD: {
1220		struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
1221
1222		return ((*cd->sc_ops->cdo_load_unload)(cd, args->options,
1223			args->slot));
1224	case DVD_AUTH:
1225		return (dvd_auth(cd, (dvd_authinfo *)addr));
1226	case DVD_READ_STRUCT:
1227		return (dvd_read_struct(cd, (dvd_struct *)addr));
1228	}
1229
1230	default:
1231		if (part != RAW_PART)
1232			return (ENOTTY);
1233		return (scsipi_do_ioctl(periph, dev, cmd, addr, flag, p));
1234	}
1235
1236#ifdef DIAGNOSTIC
1237	panic("cdioctl: impossible");
1238#endif
1239}
1240
1241void
1242cdgetdefaultlabel(cd, lp)
1243	struct cd_softc *cd;
1244	struct disklabel *lp;
1245{
1246
1247	bzero(lp, sizeof(struct disklabel));
1248
1249	lp->d_secsize = cd->params.blksize;
1250	lp->d_ntracks = 1;
1251	lp->d_nsectors = 100;
1252	lp->d_ncylinders = (cd->params.disksize / 100) + 1;
1253	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1254
1255	switch (scsipi_periph_bustype(cd->sc_periph)) {
1256#if NCD_SCSIBUS > 0
1257	case SCSIPI_BUSTYPE_SCSI:
1258		lp->d_type = DTYPE_SCSI;
1259		break;
1260#endif
1261#if NCD_ATAPIBUS > 0
1262	case SCSIPI_BUSTYPE_ATAPI:
1263		lp->d_type = DTYPE_ATAPI;
1264		break;
1265#endif
1266	}
1267	strncpy(lp->d_typename, cd->name, 16);
1268	strncpy(lp->d_packname, "fictitious", 16);
1269	lp->d_secperunit = cd->params.disksize;
1270	lp->d_rpm = 300;
1271	lp->d_interleave = 1;
1272	lp->d_flags = D_REMOVABLE;
1273
1274	lp->d_partitions[0].p_offset = 0;
1275	lp->d_partitions[0].p_size =
1276	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1277	lp->d_partitions[0].p_fstype = FS_ISO9660;
1278	lp->d_partitions[RAW_PART].p_offset = 0;
1279	lp->d_partitions[RAW_PART].p_size =
1280	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1281	lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
1282	lp->d_npartitions = RAW_PART + 1;
1283
1284	lp->d_magic = DISKMAGIC;
1285	lp->d_magic2 = DISKMAGIC;
1286	lp->d_checksum = dkcksum(lp);
1287}
1288
1289/*
1290 * Load the label information on the named device
1291 * Actually fabricate a disklabel
1292 *
1293 * EVENTUALLY take information about different
1294 * data tracks from the TOC and put it in the disklabel
1295 */
1296void
1297cdgetdisklabel(cd)
1298	struct cd_softc *cd;
1299{
1300	struct disklabel *lp = cd->sc_dk.dk_label;
1301
1302	bzero(cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
1303
1304	cdgetdefaultlabel(cd, lp);
1305}
1306
1307/*
1308 * Find out from the device what it's capacity is
1309 */
1310u_long
1311cd_size(cd, flags)
1312	struct cd_softc *cd;
1313	int flags;
1314{
1315	struct scsipi_read_cd_cap_data rdcap;
1316	struct scsipi_read_cd_capacity scsipi_cmd;
1317	int blksize;
1318	u_long size;
1319
1320	if (cd->sc_periph->periph_quirks & PQUIRK_NOCAPACITY) {
1321		/*
1322		 * the drive doesn't support the READ_CD_CAPACITY command
1323		 * use a fake size
1324		 */
1325		cd->params.blksize = 2048;
1326		cd->params.disksize = 400000;
1327		return (400000);
1328	}
1329
1330	/*
1331	 * make up a scsi command and ask the scsi driver to do
1332	 * it for you.
1333	 */
1334	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1335	scsipi_cmd.opcode = READ_CD_CAPACITY;
1336
1337	/*
1338	 * If the command works, interpret the result as a 4 byte
1339	 * number of blocks and a blocksize
1340	 */
1341	if (scsipi_command(cd->sc_periph,
1342	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1343	    (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 30000, NULL,
1344	    flags | XS_CTL_DATA_IN | XS_CTL_DATA_IN) != 0)
1345		return (0);
1346
1347	blksize = _4btol(rdcap.length);
1348	if ((blksize < 512) || ((blksize & 511) != 0))
1349		blksize = 2048;	/* some drives lie ! */
1350	cd->params.blksize = blksize;
1351
1352	size = _4btol(rdcap.addr) + 1;
1353	if (size < 100)
1354		size = 400000;	/* ditto */
1355	cd->params.disksize = size;
1356
1357	SC_DEBUG(cd->sc_periph, SCSIPI_DB2,
1358	    ("cd_size: %d %ld\n", blksize, size));
1359	return (size);
1360}
1361
1362/*
1363 * Get scsi driver to send a "start playing" command
1364 */
1365int
1366cd_play(cd, blkno, nblks)
1367	struct cd_softc *cd;
1368	int blkno, nblks;
1369{
1370	struct scsipi_play scsipi_cmd;
1371
1372	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1373	scsipi_cmd.opcode = PLAY;
1374	_lto4b(blkno, scsipi_cmd.blk_addr);
1375	_lto2b(nblks, scsipi_cmd.xfer_len);
1376	return (scsipi_command(cd->sc_periph,
1377	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1378	    0, 0, CDRETRIES, 30000, NULL, 0));
1379}
1380
1381/*
1382 * Get scsi driver to send a "start playing" command
1383 */
1384int
1385cd_play_tracks(cd, strack, sindex, etrack, eindex)
1386	struct cd_softc *cd;
1387	int strack, sindex, etrack, eindex;
1388{
1389	struct cd_toc toc;
1390	int error;
1391
1392	if (!etrack)
1393		return (EIO);
1394	if (strack > etrack)
1395		return (EINVAL);
1396
1397	if ((error = cd_load_toc(cd, &toc, XS_CTL_DATA_ONSTACK)) != 0)
1398		return (error);
1399
1400	if (++etrack > (toc.header.ending_track+1))
1401		etrack = toc.header.ending_track+1;
1402
1403	strack -= toc.header.starting_track;
1404	etrack -= toc.header.starting_track;
1405	if (strack < 0)
1406		return (EINVAL);
1407
1408	return (cd_play_msf(cd, toc.entries[strack].addr.msf.minute,
1409	    toc.entries[strack].addr.msf.second,
1410	    toc.entries[strack].addr.msf.frame,
1411	    toc.entries[etrack].addr.msf.minute,
1412	    toc.entries[etrack].addr.msf.second,
1413	    toc.entries[etrack].addr.msf.frame));
1414}
1415
1416/*
1417 * Get scsi driver to send a "play msf" command
1418 */
1419int
1420cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
1421	struct cd_softc *cd;
1422	int startm, starts, startf, endm, ends, endf;
1423{
1424	struct scsipi_play_msf scsipi_cmd;
1425
1426	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1427	scsipi_cmd.opcode = PLAY_MSF;
1428	scsipi_cmd.start_m = startm;
1429	scsipi_cmd.start_s = starts;
1430	scsipi_cmd.start_f = startf;
1431	scsipi_cmd.end_m = endm;
1432	scsipi_cmd.end_s = ends;
1433	scsipi_cmd.end_f = endf;
1434	return (scsipi_command(cd->sc_periph,
1435	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1436	    0, 0, CDRETRIES, 30000, NULL, 0));
1437}
1438
1439/*
1440 * Get scsi driver to send a "start up" command
1441 */
1442int
1443cd_pause(cd, go)
1444	struct cd_softc *cd;
1445	int go;
1446{
1447	struct scsipi_pause scsipi_cmd;
1448
1449	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1450	scsipi_cmd.opcode = PAUSE;
1451	scsipi_cmd.resume = go & 0xff;
1452	return (scsipi_command(cd->sc_periph,
1453	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1454	    0, 0, CDRETRIES, 30000, NULL, 0));
1455}
1456
1457/*
1458 * Get scsi driver to send a "RESET" command
1459 */
1460int
1461cd_reset(cd)
1462	struct cd_softc *cd;
1463{
1464
1465	return (scsipi_command(cd->sc_periph, 0, 0, 0, 0,
1466	    CDRETRIES, 30000, NULL, XS_CTL_RESET));
1467}
1468
1469/*
1470 * Read subchannel
1471 */
1472int
1473cd_read_subchannel(cd, mode, format, track, data, len, flags)
1474	struct cd_softc *cd;
1475	int mode, format, track, len;
1476	struct cd_sub_channel_info *data;
1477	int flags;
1478{
1479	struct scsipi_read_subchannel scsipi_cmd;
1480
1481	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1482	scsipi_cmd.opcode = READ_SUBCHANNEL;
1483	if (mode == CD_MSF_FORMAT)
1484		scsipi_cmd.byte2 |= CD_MSF;
1485	scsipi_cmd.byte3 = SRS_SUBQ;
1486	scsipi_cmd.subchan_format = format;
1487	scsipi_cmd.track = track;
1488	_lto2b(len, scsipi_cmd.data_len);
1489	return (scsipi_command(cd->sc_periph,
1490	    (struct scsipi_generic *)&scsipi_cmd,
1491	    sizeof(struct scsipi_read_subchannel), (u_char *)data, len,
1492	    CDRETRIES, 30000, NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT));
1493}
1494
1495/*
1496 * Read table of contents
1497 */
1498int
1499cd_read_toc(cd, mode, start, data, len, flags, control)
1500	struct cd_softc *cd;
1501	int mode, start, len, control;
1502	void *data;
1503	int flags;
1504{
1505	struct scsipi_read_toc scsipi_cmd;
1506	int ntoc;
1507
1508	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1509#if 0
1510	if (len != sizeof(struct ioc_toc_header))
1511		ntoc = ((len) - sizeof(struct ioc_toc_header)) /
1512		    sizeof(struct cd_toc_entry);
1513	else
1514#endif
1515	ntoc = len;
1516	scsipi_cmd.opcode = READ_TOC;
1517	if (mode == CD_MSF_FORMAT)
1518		scsipi_cmd.byte2 |= CD_MSF;
1519	scsipi_cmd.from_track = start;
1520	_lto2b(ntoc, scsipi_cmd.data_len);
1521	scsipi_cmd.control = control;
1522	return (scsipi_command(cd->sc_periph,
1523	    (struct scsipi_generic *)&scsipi_cmd,
1524	    sizeof(struct scsipi_read_toc), (u_char *)data, len, CDRETRIES,
1525	    30000, NULL, flags | XS_CTL_DATA_IN));
1526}
1527
1528int
1529cd_load_toc(cd, toc, flags)
1530	struct cd_softc *cd;
1531	struct cd_toc *toc;
1532	int flags;
1533{
1534	int ntracks, len, error;
1535
1536	if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header),
1537	    flags, 0)) != 0)
1538		return (error);
1539
1540	ntracks = toc->header.ending_track - toc->header.starting_track + 1;
1541	len = (ntracks + 1) * sizeof(struct cd_toc_entry) +
1542	    sizeof(toc->header);
1543	if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len,
1544	    flags, 0)) != 0)
1545		return (error);
1546	return (0);
1547}
1548
1549/*
1550 * Get the scsi driver to send a full inquiry to the device and use the
1551 * results to fill out the disk parameter structure.
1552 */
1553int
1554cd_get_parms(cd, flags)
1555	struct cd_softc *cd;
1556	int flags;
1557{
1558
1559	/*
1560	 * give a number of sectors so that sec * trks * cyls
1561	 * is <= disk_size
1562	 */
1563	if (cd_size(cd, flags) == 0)
1564		return (ENXIO);
1565	return (0);
1566}
1567
1568int
1569cdsize(dev)
1570	dev_t dev;
1571{
1572
1573	/* CD-ROMs are read-only. */
1574	return (-1);
1575}
1576
1577int
1578cddump(dev, blkno, va, size)
1579	dev_t dev;
1580	daddr_t blkno;
1581	caddr_t va;
1582	size_t size;
1583{
1584
1585	/* Not implemented. */
1586	return (ENXIO);
1587}
1588
1589#define	dvd_copy_key(dst, src)		memcpy((dst), (src), sizeof(dvd_key))
1590#define	dvd_copy_challenge(dst, src)	memcpy((dst), (src), sizeof(dvd_challenge))
1591
1592int
1593dvd_auth(cd, a)
1594	struct cd_softc *cd;
1595	dvd_authinfo *a;
1596{
1597	struct scsipi_generic cmd;
1598	u_int8_t buf[20];
1599	int error;
1600
1601	memset(cmd.bytes, 0, 15);
1602	memset(buf, 0, sizeof(buf));
1603
1604	switch (a->type) {
1605	case DVD_LU_SEND_AGID:
1606		cmd.opcode = GPCMD_REPORT_KEY;
1607		cmd.bytes[8] = 8;
1608		cmd.bytes[9] = 0 | (0 << 6);
1609		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 8,
1610		    CDRETRIES, 30000, NULL,
1611		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1612		if (error)
1613			return (error);
1614		a->lsa.agid = buf[7] >> 6;
1615		return (0);
1616
1617	case DVD_LU_SEND_CHALLENGE:
1618		cmd.opcode = GPCMD_REPORT_KEY;
1619		cmd.bytes[8] = 16;
1620		cmd.bytes[9] = 1 | (a->lsc.agid << 6);
1621		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1622		    CDRETRIES, 30000, NULL,
1623		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1624		if (error)
1625			return (error);
1626		dvd_copy_challenge(a->lsc.chal, &buf[4]);
1627		return (0);
1628
1629	case DVD_LU_SEND_KEY1:
1630		cmd.opcode = GPCMD_REPORT_KEY;
1631		cmd.bytes[8] = 12;
1632		cmd.bytes[9] = 2 | (a->lsk.agid << 6);
1633		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1634		    CDRETRIES, 30000, NULL,
1635		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1636		if (error)
1637			return (error);
1638		dvd_copy_key(a->lsk.key, &buf[4]);
1639		return (0);
1640
1641	case DVD_LU_SEND_TITLE_KEY:
1642		cmd.opcode = GPCMD_REPORT_KEY;
1643		_lto4b(a->lstk.lba, &cmd.bytes[1]);
1644		cmd.bytes[8] = 12;
1645		cmd.bytes[9] = 4 | (a->lstk.agid << 6);
1646		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1647		    CDRETRIES, 30000, NULL,
1648		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1649		if (error)
1650			return (error);
1651		a->lstk.cpm = (buf[4] >> 7) & 1;
1652		a->lstk.cp_sec = (buf[4] >> 6) & 1;
1653		a->lstk.cgms = (buf[4] >> 4) & 3;
1654		dvd_copy_key(a->lstk.title_key, &buf[5]);
1655		return (0);
1656
1657	case DVD_LU_SEND_ASF:
1658		cmd.opcode = GPCMD_REPORT_KEY;
1659		cmd.bytes[8] = 8;
1660		cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
1661		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 8,
1662		    CDRETRIES, 30000, NULL,
1663		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1664		if (error)
1665			return (error);
1666		a->lsasf.asf = buf[7] & 1;
1667		return (0);
1668
1669	case DVD_HOST_SEND_CHALLENGE:
1670		cmd.opcode = GPCMD_SEND_KEY;
1671		cmd.bytes[8] = 16;
1672		cmd.bytes[9] = 1 | (a->hsc.agid << 6);
1673		buf[1] = 14;
1674		dvd_copy_challenge(&buf[4], a->hsc.chal);
1675		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1676		    CDRETRIES, 30000, NULL,
1677		    XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1678		if (error)
1679			return (error);
1680		a->type = DVD_LU_SEND_KEY1;
1681		return (0);
1682
1683	case DVD_HOST_SEND_KEY2:
1684		cmd.opcode = GPCMD_SEND_KEY;
1685		cmd.bytes[8] = 12;
1686		cmd.bytes[9] = 3 | (a->hsk.agid << 6);
1687		buf[1] = 10;
1688		dvd_copy_key(&buf[4], a->hsk.key);
1689		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1690		    CDRETRIES, 30000, NULL,
1691		    XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1692		if (error) {
1693			a->type = DVD_AUTH_FAILURE;
1694			return (error);
1695		}
1696		a->type = DVD_AUTH_ESTABLISHED;
1697		return (0);
1698
1699	case DVD_INVALIDATE_AGID:
1700		cmd.opcode = GPCMD_REPORT_KEY;
1701		cmd.bytes[9] = 0x3f | (a->lsa.agid << 6);
1702		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1703		    CDRETRIES, 30000, NULL, 0);
1704		if (error)
1705			return (error);
1706		return (0);
1707
1708	default:
1709		return (ENOTTY);
1710	}
1711}
1712
1713int
1714dvd_read_physical(cd, s)
1715	struct cd_softc *cd;
1716	dvd_struct *s;
1717{
1718	struct scsipi_generic cmd;
1719	u_int8_t buf[4 + 4 * 20], *bufp;
1720	int error;
1721	struct dvd_layer *layer;
1722	int i;
1723
1724	memset(cmd.bytes, 0, 15);
1725	memset(buf, 0, sizeof(buf));
1726	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1727	cmd.bytes[6] = s->type;
1728	_lto2b(sizeof(buf), &cmd.bytes[7]);
1729
1730	cmd.bytes[5] = s->physical.layer_num;
1731	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1732	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1733	if (error)
1734		return (error);
1735	for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4;
1736	     i++, bufp += 20, layer++) {
1737		memset(layer, 0, sizeof(*layer));
1738                layer->book_version = bufp[0] & 0xf;
1739                layer->book_type = bufp[0] >> 4;
1740                layer->min_rate = bufp[1] & 0xf;
1741                layer->disc_size = bufp[1] >> 4;
1742                layer->layer_type = bufp[2] & 0xf;
1743                layer->track_path = (bufp[2] >> 4) & 1;
1744                layer->nlayers = (bufp[2] >> 5) & 3;
1745                layer->track_density = bufp[3] & 0xf;
1746                layer->linear_density = bufp[3] >> 4;
1747                layer->start_sector = _4btol(&bufp[4]);
1748                layer->end_sector = _4btol(&bufp[8]);
1749                layer->end_sector_l0 = _4btol(&bufp[12]);
1750                layer->bca = bufp[16] >> 7;
1751	}
1752	return (0);
1753}
1754
1755int
1756dvd_read_copyright(cd, s)
1757	struct cd_softc *cd;
1758	dvd_struct *s;
1759{
1760	struct scsipi_generic cmd;
1761	u_int8_t buf[8];
1762	int error;
1763
1764	memset(cmd.bytes, 0, 15);
1765	memset(buf, 0, sizeof(buf));
1766	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1767	cmd.bytes[6] = s->type;
1768	_lto2b(sizeof(buf), &cmd.bytes[7]);
1769
1770	cmd.bytes[5] = s->copyright.layer_num;
1771	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1772	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1773	if (error)
1774		return (error);
1775	s->copyright.cpst = buf[4];
1776	s->copyright.rmi = buf[5];
1777	return (0);
1778}
1779
1780int
1781dvd_read_disckey(cd, s)
1782	struct cd_softc *cd;
1783	dvd_struct *s;
1784{
1785	struct scsipi_generic cmd;
1786	u_int8_t buf[4 + 2048];
1787	int error;
1788
1789	memset(cmd.bytes, 0, 15);
1790	memset(buf, 0, sizeof(buf));
1791	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1792	cmd.bytes[6] = s->type;
1793	_lto2b(sizeof(buf), &cmd.bytes[7]);
1794
1795	cmd.bytes[9] = s->disckey.agid << 6;
1796	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1797	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1798	if (error)
1799		return (error);
1800	memcpy(s->disckey.value, &buf[4], 2048);
1801	return (0);
1802}
1803
1804int
1805dvd_read_bca(cd, s)
1806	struct cd_softc *cd;
1807	dvd_struct *s;
1808{
1809	struct scsipi_generic cmd;
1810	u_int8_t buf[4 + 188];
1811	int error;
1812
1813	memset(cmd.bytes, 0, 15);
1814	memset(buf, 0, sizeof(buf));
1815	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1816	cmd.bytes[6] = s->type;
1817	_lto2b(sizeof(buf), &cmd.bytes[7]);
1818
1819	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1820	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1821	if (error)
1822		return (error);
1823	s->bca.len = _2btol(&buf[0]);
1824	if (s->bca.len < 12 || s->bca.len > 188)
1825		return (EIO);
1826	memcpy(s->bca.value, &buf[4], s->bca.len);
1827	return (0);
1828}
1829
1830int
1831dvd_read_manufact(cd, s)
1832	struct cd_softc *cd;
1833	dvd_struct *s;
1834{
1835	struct scsipi_generic cmd;
1836	u_int8_t buf[4 + 2048];
1837	int error;
1838
1839	memset(cmd.bytes, 0, 15);
1840	memset(buf, 0, sizeof(buf));
1841	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1842	cmd.bytes[6] = s->type;
1843	_lto2b(sizeof(buf), &cmd.bytes[7]);
1844
1845	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1846	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1847	if (error)
1848		return (error);
1849	s->manufact.len = _2btol(&buf[0]);
1850	if (s->manufact.len < 0 || s->manufact.len > 2048)
1851		return (EIO);
1852	memcpy(s->manufact.value, &buf[4], s->manufact.len);
1853	return (0);
1854}
1855
1856int
1857dvd_read_struct(cd, s)
1858	struct cd_softc *cd;
1859	dvd_struct *s;
1860{
1861
1862	switch (s->type) {
1863	case DVD_STRUCT_PHYSICAL:
1864		return (dvd_read_physical(cd, s));
1865	case DVD_STRUCT_COPYRIGHT:
1866		return (dvd_read_copyright(cd, s));
1867	case DVD_STRUCT_DISCKEY:
1868		return (dvd_read_disckey(cd, s));
1869	case DVD_STRUCT_BCA:
1870		return (dvd_read_bca(cd, s));
1871	case DVD_STRUCT_MANUFACT:
1872		return (dvd_read_manufact(cd, s));
1873	default:
1874		return (EINVAL);
1875	}
1876}
1877