cd.c revision 1.147
1/*	$NetBSD: cd.c,v 1.147 2001/04/28 09:33:25 tsutsui 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		 */
712		flags = XS_CTL_NOSLEEP|XS_CTL_ASYNC;
713		if (bp->b_flags & B_READ)
714			flags |= XS_CTL_DATA_IN;
715		else
716			flags |= XS_CTL_DATA_OUT;
717		if (bp->b_flags & B_ORDERED)
718			flags |= XS_CTL_ORDERED_TAG;
719		else
720			flags |= XS_CTL_SIMPLE_TAG;
721
722		/*
723		 * Call the routine that chats with the adapter.
724		 * Note: we cannot sleep as we may be an interrupt
725		 */
726		error = scsipi_command(periph, cmdp, cmdlen,
727		    (u_char *)bp->b_data, bp->b_bcount,
728		    CDRETRIES, 30000, bp, flags);
729		if (error) {
730			disk_unbusy(&cd->sc_dk, 0);
731			printf("%s: not queued, error %d\n",
732			    cd->sc_dev.dv_xname, error);
733		}
734	}
735}
736
737void
738cddone(xs)
739	struct scsipi_xfer *xs;
740{
741	struct cd_softc *cd = (void *)xs->xs_periph->periph_dev;
742
743	if (xs->bp != NULL) {
744		disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid);
745#if NRND > 0
746		rnd_add_uint32(&cd->rnd_source, xs->bp->b_rawblkno);
747#endif
748	}
749}
750
751int cd_interpret_sense(xs)
752	struct scsipi_xfer *xs;
753{
754	struct scsipi_periph *periph = xs->xs_periph;
755	struct scsipi_sense_data *sense = &xs->sense.scsi_sense;
756	int retval = EJUSTRETURN;
757
758	/*
759	 * If it isn't a extended or extended/deferred error, let
760	 * the generic code handle it.
761	 */
762	if ((sense->error_code & SSD_ERRCODE) != 0x70 &&
763	    (sense->error_code & SSD_ERRCODE) != 0x71) {	/* DEFFERRED */
764		return (retval);
765	}
766
767	/*
768	 * If we got a "Unit not ready" (SKEY_NOT_READY) and "Logical Unit
769	 * Is In The Process of Becoming Ready" (Sense code 0x04,0x01), then
770	 * wait a bit for the drive to spin up
771	 */
772
773	if ((sense->flags & SSD_KEY) == SKEY_NOT_READY &&
774	    sense->add_sense_code == 0x4 &&
775	    sense->add_sense_code_qual == 0x01)	{
776		/*
777		 * Sleep for 5 seconds to wait for the drive to spin up
778		 */
779
780		SC_DEBUG(periph, SDEV_DB1, ("Waiting 5 sec for CD "
781						"spinup\n"));
782		scsipi_periph_freeze(periph, 1);
783		callout_reset(&periph->periph_callout,
784		    5 * hz, scsipi_periph_timed_thaw, periph);
785		retval = ERESTART;
786	}
787	return (retval);
788}
789
790void
791cdminphys(bp)
792	struct buf *bp;
793{
794	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(bp->b_dev)];
795	long max;
796
797	/*
798	 * If the device is ancient, we want to make sure that
799	 * the transfer fits into a 6-byte cdb.
800	 *
801	 * XXX Note that the SCSI-I spec says that 256-block transfers
802	 * are allowed in a 6-byte read/write, and are specified
803	 * by settng the "length" to 0.  However, we're conservative
804	 * here, allowing only 255-block transfers in case an
805	 * ancient device gets confused by length == 0.  A length of 0
806	 * in a 10-byte read/write actually means 0 blocks.
807	 */
808	if (cd->flags & CDF_ANCIENT) {
809		max = cd->sc_dk.dk_label->d_secsize * 0xff;
810
811		if (bp->b_bcount > max)
812			bp->b_bcount = max;
813	}
814
815	(*cd->sc_periph->periph_channel->chan_adapter->adapt_minphys)(bp);
816}
817
818int
819cdread(dev, uio, ioflag)
820	dev_t dev;
821	struct uio *uio;
822	int ioflag;
823{
824
825	return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
826}
827
828int
829cdwrite(dev, uio, ioflag)
830	dev_t dev;
831	struct uio *uio;
832	int ioflag;
833{
834
835	return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
836}
837
838/*
839 * conversion between minute-seconde-frame and logical block adress
840 * adresses format
841 */
842void
843lba2msf (lba, m, s, f)
844	u_long lba;
845	u_char *m, *s, *f;
846{
847	u_long tmp;
848
849	tmp = lba + CD_BLOCK_OFFSET;	/* offset of first logical frame */
850	tmp &= 0xffffff;		/* negative lbas use only 24 bits */
851	*m = tmp / (CD_SECS * CD_FRAMES);
852	tmp %= (CD_SECS * CD_FRAMES);
853	*s = tmp / CD_FRAMES;
854	*f = tmp % CD_FRAMES;
855}
856
857u_long
858msf2lba (m, s, f)
859	u_char m, s, f;
860{
861
862	return ((((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET);
863}
864
865
866/*
867 * Perform special action on behalf of the user.
868 * Knows about the internals of this device
869 */
870int
871cdioctl(dev, cmd, addr, flag, p)
872	dev_t dev;
873	u_long cmd;
874	caddr_t addr;
875	int flag;
876	struct proc *p;
877{
878	struct cd_softc *cd = cd_cd.cd_devs[CDUNIT(dev)];
879	struct scsipi_periph *periph = cd->sc_periph;
880	int part = CDPART(dev);
881	int error;
882#ifdef __HAVE_OLD_DISKLABEL
883	struct disklabel newlabel;
884#endif
885
886	SC_DEBUG(cd->sc_periph, SCSIPI_DB2, ("cdioctl 0x%lx ", cmd));
887
888	/*
889	 * If the device is not valid, some IOCTLs can still be
890	 * handled on the raw partition. Check this here.
891	 */
892	if ((periph->periph_flags & PERIPH_MEDIA_LOADED) == 0) {
893		switch (cmd) {
894		case DIOCWLABEL:
895		case DIOCLOCK:
896		case ODIOCEJECT:
897		case DIOCEJECT:
898		case SCIOCIDENTIFY:
899		case OSCIOCIDENTIFY:
900		case SCIOCCOMMAND:
901		case SCIOCDEBUG:
902		case CDIOCGETVOL:
903		case CDIOCSETVOL:
904		case CDIOCSETMONO:
905		case CDIOCSETSTEREO:
906		case CDIOCSETMUTE:
907		case CDIOCSETLEFT:
908		case CDIOCSETRIGHT:
909		case CDIOCCLOSE:
910		case CDIOCEJECT:
911		case CDIOCALLOW:
912		case CDIOCPREVENT:
913		case CDIOCSETDEBUG:
914		case CDIOCCLRDEBUG:
915		case CDIOCRESET:
916		case SCIOCRESET:
917		case CDIOCLOADUNLOAD:
918		case DVD_AUTH:
919		case DVD_READ_STRUCT:
920			if (part == RAW_PART)
921				break;
922		/* FALLTHROUGH */
923		default:
924			if ((periph->periph_flags & PERIPH_OPEN) == 0)
925				return (ENODEV);
926			else
927				return (EIO);
928		}
929	}
930
931	switch (cmd) {
932	case DIOCGDINFO:
933		*(struct disklabel *)addr = *(cd->sc_dk.dk_label);
934		return (0);
935#ifdef __HAVE_OLD_DISKLABEL
936	case ODIOCGDINFO:
937		newlabel = *(cd->sc_dk.dk_label);
938		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
939			return ENOTTY;
940		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
941		return (0);
942#endif
943
944	case DIOCGPART:
945		((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label;
946		((struct partinfo *)addr)->part =
947		    &cd->sc_dk.dk_label->d_partitions[part];
948		return (0);
949
950	case DIOCWDINFO:
951	case DIOCSDINFO:
952#ifdef __HAVE_OLD_DISKLABEL
953	case ODIOCWDINFO:
954	case ODIOCSDINFO:
955#endif
956	{
957		struct disklabel *lp;
958
959#ifdef __HAVE_OLD_DISKLABEL
960		if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
961			memset(&newlabel, 0, sizeof newlabel);
962			memcpy(&newlabel, addr, sizeof (struct olddisklabel));
963			lp = &newlabel;
964		} else
965#endif
966		lp = (struct disklabel *)addr;
967
968		if ((flag & FWRITE) == 0)
969			return (EBADF);
970
971		if ((error = cdlock(cd)) != 0)
972			return (error);
973		cd->flags |= CDF_LABELLING;
974
975		error = setdisklabel(cd->sc_dk.dk_label,
976		    lp, /*cd->sc_dk.dk_openmask : */0,
977		    cd->sc_dk.dk_cpulabel);
978		if (error == 0) {
979			/* XXX ? */
980		}
981
982		cd->flags &= ~CDF_LABELLING;
983		cdunlock(cd);
984		return (error);
985	}
986
987	case DIOCWLABEL:
988		return (EBADF);
989
990	case DIOCGDEFLABEL:
991		cdgetdefaultlabel(cd, (struct disklabel *)addr);
992		return (0);
993
994#ifdef __HAVE_OLD_DISKLABEL
995	case ODIOCGDEFLABEL:
996		cdgetdefaultlabel(cd, &newlabel);
997		if (newlabel.d_npartitions > OLDMAXPARTITIONS)
998			return ENOTTY;
999		memcpy(addr, &newlabel, sizeof (struct olddisklabel));
1000		return (0);
1001#endif
1002
1003	case CDIOCPLAYTRACKS: {
1004		struct ioc_play_track *args = (struct ioc_play_track *)addr;
1005
1006		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1007			return (error);
1008		return (cd_play_tracks(cd, args->start_track,
1009		    args->start_index, args->end_track, args->end_index));
1010	}
1011	case CDIOCPLAYMSF: {
1012		struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
1013
1014		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1015			return (error);
1016		return (cd_play_msf(cd, args->start_m, args->start_s,
1017		    args->start_f, args->end_m, args->end_s, args->end_f));
1018	}
1019	case CDIOCPLAYBLOCKS: {
1020		struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
1021
1022		if ((error = (*cd->sc_ops->cdo_set_pa_immed)(cd, 0)) != 0)
1023			return (error);
1024		return (cd_play(cd, args->blk, args->len));
1025	}
1026	case CDIOCREADSUBCHANNEL: {
1027		struct ioc_read_subchannel *args =
1028		    (struct ioc_read_subchannel *)addr;
1029		struct cd_sub_channel_info data;
1030		int len = args->data_len;
1031
1032		if (len > sizeof(data) ||
1033		    len < sizeof(struct cd_sub_channel_header))
1034			return (EINVAL);
1035		error = cd_read_subchannel(cd, args->address_format,
1036		    args->data_format, args->track, &data, len,
1037		    XS_CTL_DATA_ONSTACK);
1038		if (error)
1039			return (error);
1040		len = min(len, _2btol(data.header.data_len) +
1041		    sizeof(struct cd_sub_channel_header));
1042		return (copyout(&data, args->data, len));
1043	}
1044	case CDIOREADTOCHEADER: {
1045		struct ioc_toc_header th;
1046
1047		if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th),
1048		    XS_CTL_DATA_ONSTACK, 0)) != 0)
1049			return (error);
1050		if (cd->sc_periph->periph_quirks & PQUIRK_LITTLETOC) {
1051#if BYTE_ORDER == BIG_ENDIAN
1052			bswap((u_int8_t *)&th.len, sizeof(th.len));
1053#endif
1054		} else
1055			th.len = ntohs(th.len);
1056		bcopy(&th, addr, sizeof(th));
1057		return (0);
1058	}
1059	case CDIOREADTOCENTRYS: {
1060		struct cd_toc toc;
1061		struct ioc_read_toc_entry *te =
1062		    (struct ioc_read_toc_entry *)addr;
1063		struct ioc_toc_header *th;
1064		struct cd_toc_entry *cte;
1065		int len = te->data_len;
1066		int ntracks;
1067
1068		th = &toc.header;
1069
1070		if (len > sizeof(toc.entries) ||
1071		    len < sizeof(struct cd_toc_entry))
1072			return (EINVAL);
1073		error = cd_read_toc(cd, te->address_format, te->starting_track,
1074		    &toc, len + sizeof(struct ioc_toc_header),
1075		    XS_CTL_DATA_ONSTACK, 0);
1076		if (error)
1077			return (error);
1078		if (te->address_format == CD_LBA_FORMAT)
1079			for (ntracks =
1080			    th->ending_track - th->starting_track + 1;
1081			    ntracks >= 0; ntracks--) {
1082				cte = &toc.entries[ntracks];
1083				cte->addr_type = CD_LBA_FORMAT;
1084				if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1085#if BYTE_ORDER == BIG_ENDIAN
1086					bswap((u_int8_t*)&cte->addr,
1087					    sizeof(cte->addr));
1088#endif
1089				} else
1090					cte->addr.lba = ntohl(cte->addr.lba);
1091			}
1092		if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1093#if BYTE_ORDER == BIG_ENDIAN
1094			bswap((u_int8_t*)&th->len, sizeof(th->len));
1095#endif
1096		} else
1097			th->len = ntohs(th->len);
1098		len = min(len, th->len - (sizeof(th->starting_track) +
1099		    sizeof(th->ending_track)));
1100		return (copyout(toc.entries, te->data, len));
1101	}
1102	case CDIOREADMSADDR: {
1103		struct cd_toc toc;
1104		int sessno = *(int*)addr;
1105		struct cd_toc_entry *cte;
1106
1107		if (sessno != 0)
1108			return (EINVAL);
1109
1110		error = cd_read_toc(cd, 0, 0, &toc,
1111		  sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
1112		  XS_CTL_DATA_ONSTACK,
1113		  0x40 /* control word for "get MS info" */);
1114
1115		if (error)
1116			return (error);
1117
1118		cte = &toc.entries[0];
1119		if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1120#if BYTE_ORDER == BIG_ENDIAN
1121			bswap((u_int8_t*)&cte->addr, sizeof(cte->addr));
1122#endif
1123		} else
1124			cte->addr.lba = ntohl(cte->addr.lba);
1125		if (periph->periph_quirks & PQUIRK_LITTLETOC) {
1126#if BYTE_ORDER == BIG_ENDIAN
1127			bswap((u_int8_t*)&toc.header.len,
1128			    sizeof(toc.header.len));
1129#endif
1130		} else
1131			toc.header.len = ntohs(toc.header.len);
1132
1133		*(int*)addr = (toc.header.len >= 10 && cte->track > 1) ?
1134			cte->addr.lba : 0;
1135		return 0;
1136	}
1137	case CDIOCSETPATCH: {
1138		struct ioc_patch *arg = (struct ioc_patch *)addr;
1139
1140		return ((*cd->sc_ops->cdo_setchan)(cd, arg->patch[0],
1141		    arg->patch[1], arg->patch[2], arg->patch[3], 0));
1142	}
1143	case CDIOCGETVOL: {
1144		struct ioc_vol *arg = (struct ioc_vol *)addr;
1145
1146		return ((*cd->sc_ops->cdo_getvol)(cd, arg, 0));
1147	}
1148	case CDIOCSETVOL: {
1149		struct ioc_vol *arg = (struct ioc_vol *)addr;
1150
1151		return ((*cd->sc_ops->cdo_setvol)(cd, arg, 0));
1152	}
1153
1154	case CDIOCSETMONO:
1155		return ((*cd->sc_ops->cdo_setchan)(cd, BOTH_CHANNEL,
1156		    BOTH_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1157
1158	case CDIOCSETSTEREO:
1159		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
1160		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1161
1162	case CDIOCSETMUTE:
1163		return ((*cd->sc_ops->cdo_setchan)(cd, MUTE_CHANNEL,
1164		    MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1165
1166	case CDIOCSETLEFT:
1167		return ((*cd->sc_ops->cdo_setchan)(cd, LEFT_CHANNEL,
1168		    LEFT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1169
1170	case CDIOCSETRIGHT:
1171		return ((*cd->sc_ops->cdo_setchan)(cd, RIGHT_CHANNEL,
1172		    RIGHT_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL, 0));
1173
1174	case CDIOCRESUME:
1175		return (cd_pause(cd, PA_RESUME));
1176	case CDIOCPAUSE:
1177		return (cd_pause(cd, PA_PAUSE));
1178	case CDIOCSTART:
1179		return (scsipi_start(periph, SSS_START, 0));
1180	case CDIOCSTOP:
1181		return (scsipi_start(periph, SSS_STOP, 0));
1182	case CDIOCCLOSE:
1183		return (scsipi_start(periph, SSS_START|SSS_LOEJ,
1184		    XS_CTL_IGNORE_NOT_READY | XS_CTL_IGNORE_MEDIA_CHANGE));
1185	case DIOCEJECT:
1186		if (*(int *)addr == 0) {
1187			/*
1188			 * Don't force eject: check that we are the only
1189			 * partition open. If so, unlock it.
1190			 */
1191			if ((cd->sc_dk.dk_openmask & ~(1 << part)) == 0 &&
1192			    cd->sc_dk.dk_bopenmask + cd->sc_dk.dk_copenmask ==
1193			    cd->sc_dk.dk_openmask) {
1194				error = scsipi_prevent(periph, PR_ALLOW,
1195				    XS_CTL_IGNORE_NOT_READY);
1196				if (error)
1197					return (error);
1198			} else {
1199				return (EBUSY);
1200			}
1201		}
1202		/* FALLTHROUGH */
1203	case CDIOCEJECT: /* FALLTHROUGH */
1204	case ODIOCEJECT:
1205		return (scsipi_start(periph, SSS_STOP|SSS_LOEJ, 0));
1206	case CDIOCALLOW:
1207		return (scsipi_prevent(periph, PR_ALLOW, 0));
1208	case CDIOCPREVENT:
1209		return (scsipi_prevent(periph, PR_PREVENT, 0));
1210	case DIOCLOCK:
1211		return (scsipi_prevent(periph,
1212		    (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0));
1213	case CDIOCSETDEBUG:
1214		cd->sc_periph->periph_dbflags |= (SCSIPI_DB1 | SCSIPI_DB2);
1215		return (0);
1216	case CDIOCCLRDEBUG:
1217		cd->sc_periph->periph_dbflags &= ~(SCSIPI_DB1 | SCSIPI_DB2);
1218		return (0);
1219	case CDIOCRESET:
1220	case SCIOCRESET:
1221		return (cd_reset(cd));
1222	case CDIOCLOADUNLOAD: {
1223		struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
1224
1225		return ((*cd->sc_ops->cdo_load_unload)(cd, args->options,
1226			args->slot));
1227	case DVD_AUTH:
1228		return (dvd_auth(cd, (dvd_authinfo *)addr));
1229	case DVD_READ_STRUCT:
1230		return (dvd_read_struct(cd, (dvd_struct *)addr));
1231	}
1232
1233	default:
1234		if (part != RAW_PART)
1235			return (ENOTTY);
1236		return (scsipi_do_ioctl(periph, dev, cmd, addr, flag, p));
1237	}
1238
1239#ifdef DIAGNOSTIC
1240	panic("cdioctl: impossible");
1241#endif
1242}
1243
1244void
1245cdgetdefaultlabel(cd, lp)
1246	struct cd_softc *cd;
1247	struct disklabel *lp;
1248{
1249
1250	bzero(lp, sizeof(struct disklabel));
1251
1252	lp->d_secsize = cd->params.blksize;
1253	lp->d_ntracks = 1;
1254	lp->d_nsectors = 100;
1255	lp->d_ncylinders = (cd->params.disksize / 100) + 1;
1256	lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
1257
1258	switch (scsipi_periph_bustype(cd->sc_periph)) {
1259#if NCD_SCSIBUS > 0
1260	case SCSIPI_BUSTYPE_SCSI:
1261		lp->d_type = DTYPE_SCSI;
1262		break;
1263#endif
1264#if NCD_ATAPIBUS > 0
1265	case SCSIPI_BUSTYPE_ATAPI:
1266		lp->d_type = DTYPE_ATAPI;
1267		break;
1268#endif
1269	}
1270	strncpy(lp->d_typename, cd->name, 16);
1271	strncpy(lp->d_packname, "fictitious", 16);
1272	lp->d_secperunit = cd->params.disksize;
1273	lp->d_rpm = 300;
1274	lp->d_interleave = 1;
1275	lp->d_flags = D_REMOVABLE;
1276
1277	lp->d_partitions[0].p_offset = 0;
1278	lp->d_partitions[0].p_size =
1279	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1280	lp->d_partitions[0].p_fstype = FS_ISO9660;
1281	lp->d_partitions[RAW_PART].p_offset = 0;
1282	lp->d_partitions[RAW_PART].p_size =
1283	    lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
1284	lp->d_partitions[RAW_PART].p_fstype = FS_ISO9660;
1285	lp->d_npartitions = RAW_PART + 1;
1286
1287	lp->d_magic = DISKMAGIC;
1288	lp->d_magic2 = DISKMAGIC;
1289	lp->d_checksum = dkcksum(lp);
1290}
1291
1292/*
1293 * Load the label information on the named device
1294 * Actually fabricate a disklabel
1295 *
1296 * EVENTUALLY take information about different
1297 * data tracks from the TOC and put it in the disklabel
1298 */
1299void
1300cdgetdisklabel(cd)
1301	struct cd_softc *cd;
1302{
1303	struct disklabel *lp = cd->sc_dk.dk_label;
1304
1305	bzero(cd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel));
1306
1307	cdgetdefaultlabel(cd, lp);
1308}
1309
1310/*
1311 * Find out from the device what it's capacity is
1312 */
1313u_long
1314cd_size(cd, flags)
1315	struct cd_softc *cd;
1316	int flags;
1317{
1318	struct scsipi_read_cd_cap_data rdcap;
1319	struct scsipi_read_cd_capacity scsipi_cmd;
1320	int blksize;
1321	u_long size;
1322
1323	if (cd->sc_periph->periph_quirks & PQUIRK_NOCAPACITY) {
1324		/*
1325		 * the drive doesn't support the READ_CD_CAPACITY command
1326		 * use a fake size
1327		 */
1328		cd->params.blksize = 2048;
1329		cd->params.disksize = 400000;
1330		return (400000);
1331	}
1332
1333	/*
1334	 * make up a scsi command and ask the scsi driver to do
1335	 * it for you.
1336	 */
1337	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1338	scsipi_cmd.opcode = READ_CD_CAPACITY;
1339
1340	/*
1341	 * If the command works, interpret the result as a 4 byte
1342	 * number of blocks and a blocksize
1343	 */
1344	if (scsipi_command(cd->sc_periph,
1345	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1346	    (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 30000, NULL,
1347	    flags | XS_CTL_DATA_IN | XS_CTL_DATA_IN) != 0)
1348		return (0);
1349
1350	blksize = _4btol(rdcap.length);
1351	if ((blksize < 512) || ((blksize & 511) != 0))
1352		blksize = 2048;	/* some drives lie ! */
1353	cd->params.blksize = blksize;
1354
1355	size = _4btol(rdcap.addr) + 1;
1356	if (size < 100)
1357		size = 400000;	/* ditto */
1358	cd->params.disksize = size;
1359
1360	SC_DEBUG(cd->sc_periph, SCSIPI_DB2,
1361	    ("cd_size: %d %ld\n", blksize, size));
1362	return (size);
1363}
1364
1365/*
1366 * Get scsi driver to send a "start playing" command
1367 */
1368int
1369cd_play(cd, blkno, nblks)
1370	struct cd_softc *cd;
1371	int blkno, nblks;
1372{
1373	struct scsipi_play scsipi_cmd;
1374
1375	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1376	scsipi_cmd.opcode = PLAY;
1377	_lto4b(blkno, scsipi_cmd.blk_addr);
1378	_lto2b(nblks, scsipi_cmd.xfer_len);
1379	return (scsipi_command(cd->sc_periph,
1380	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1381	    0, 0, CDRETRIES, 30000, NULL, 0));
1382}
1383
1384/*
1385 * Get scsi driver to send a "start playing" command
1386 */
1387int
1388cd_play_tracks(cd, strack, sindex, etrack, eindex)
1389	struct cd_softc *cd;
1390	int strack, sindex, etrack, eindex;
1391{
1392	struct cd_toc toc;
1393	int error;
1394
1395	if (!etrack)
1396		return (EIO);
1397	if (strack > etrack)
1398		return (EINVAL);
1399
1400	if ((error = cd_load_toc(cd, &toc, XS_CTL_DATA_ONSTACK)) != 0)
1401		return (error);
1402
1403	if (++etrack > (toc.header.ending_track+1))
1404		etrack = toc.header.ending_track+1;
1405
1406	strack -= toc.header.starting_track;
1407	etrack -= toc.header.starting_track;
1408	if (strack < 0)
1409		return (EINVAL);
1410
1411	return (cd_play_msf(cd, toc.entries[strack].addr.msf.minute,
1412	    toc.entries[strack].addr.msf.second,
1413	    toc.entries[strack].addr.msf.frame,
1414	    toc.entries[etrack].addr.msf.minute,
1415	    toc.entries[etrack].addr.msf.second,
1416	    toc.entries[etrack].addr.msf.frame));
1417}
1418
1419/*
1420 * Get scsi driver to send a "play msf" command
1421 */
1422int
1423cd_play_msf(cd, startm, starts, startf, endm, ends, endf)
1424	struct cd_softc *cd;
1425	int startm, starts, startf, endm, ends, endf;
1426{
1427	struct scsipi_play_msf scsipi_cmd;
1428
1429	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1430	scsipi_cmd.opcode = PLAY_MSF;
1431	scsipi_cmd.start_m = startm;
1432	scsipi_cmd.start_s = starts;
1433	scsipi_cmd.start_f = startf;
1434	scsipi_cmd.end_m = endm;
1435	scsipi_cmd.end_s = ends;
1436	scsipi_cmd.end_f = endf;
1437	return (scsipi_command(cd->sc_periph,
1438	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1439	    0, 0, CDRETRIES, 30000, NULL, 0));
1440}
1441
1442/*
1443 * Get scsi driver to send a "start up" command
1444 */
1445int
1446cd_pause(cd, go)
1447	struct cd_softc *cd;
1448	int go;
1449{
1450	struct scsipi_pause scsipi_cmd;
1451
1452	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1453	scsipi_cmd.opcode = PAUSE;
1454	scsipi_cmd.resume = go & 0xff;
1455	return (scsipi_command(cd->sc_periph,
1456	    (struct scsipi_generic *)&scsipi_cmd, sizeof(scsipi_cmd),
1457	    0, 0, CDRETRIES, 30000, NULL, 0));
1458}
1459
1460/*
1461 * Get scsi driver to send a "RESET" command
1462 */
1463int
1464cd_reset(cd)
1465	struct cd_softc *cd;
1466{
1467
1468	return (scsipi_command(cd->sc_periph, 0, 0, 0, 0,
1469	    CDRETRIES, 30000, NULL, XS_CTL_RESET));
1470}
1471
1472/*
1473 * Read subchannel
1474 */
1475int
1476cd_read_subchannel(cd, mode, format, track, data, len, flags)
1477	struct cd_softc *cd;
1478	int mode, format, track, len;
1479	struct cd_sub_channel_info *data;
1480	int flags;
1481{
1482	struct scsipi_read_subchannel scsipi_cmd;
1483
1484	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1485	scsipi_cmd.opcode = READ_SUBCHANNEL;
1486	if (mode == CD_MSF_FORMAT)
1487		scsipi_cmd.byte2 |= CD_MSF;
1488	scsipi_cmd.byte3 = SRS_SUBQ;
1489	scsipi_cmd.subchan_format = format;
1490	scsipi_cmd.track = track;
1491	_lto2b(len, scsipi_cmd.data_len);
1492	return (scsipi_command(cd->sc_periph,
1493	    (struct scsipi_generic *)&scsipi_cmd,
1494	    sizeof(struct scsipi_read_subchannel), (u_char *)data, len,
1495	    CDRETRIES, 30000, NULL, flags | XS_CTL_DATA_IN | XS_CTL_SILENT));
1496}
1497
1498/*
1499 * Read table of contents
1500 */
1501int
1502cd_read_toc(cd, mode, start, data, len, flags, control)
1503	struct cd_softc *cd;
1504	int mode, start, len, control;
1505	void *data;
1506	int flags;
1507{
1508	struct scsipi_read_toc scsipi_cmd;
1509	int ntoc;
1510
1511	bzero(&scsipi_cmd, sizeof(scsipi_cmd));
1512#if 0
1513	if (len != sizeof(struct ioc_toc_header))
1514		ntoc = ((len) - sizeof(struct ioc_toc_header)) /
1515		    sizeof(struct cd_toc_entry);
1516	else
1517#endif
1518	ntoc = len;
1519	scsipi_cmd.opcode = READ_TOC;
1520	if (mode == CD_MSF_FORMAT)
1521		scsipi_cmd.byte2 |= CD_MSF;
1522	scsipi_cmd.from_track = start;
1523	_lto2b(ntoc, scsipi_cmd.data_len);
1524	scsipi_cmd.control = control;
1525	return (scsipi_command(cd->sc_periph,
1526	    (struct scsipi_generic *)&scsipi_cmd,
1527	    sizeof(struct scsipi_read_toc), (u_char *)data, len, CDRETRIES,
1528	    30000, NULL, flags | XS_CTL_DATA_IN));
1529}
1530
1531int
1532cd_load_toc(cd, toc, flags)
1533	struct cd_softc *cd;
1534	struct cd_toc *toc;
1535	int flags;
1536{
1537	int ntracks, len, error;
1538
1539	if ((error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header),
1540	    flags, 0)) != 0)
1541		return (error);
1542
1543	ntracks = toc->header.ending_track - toc->header.starting_track + 1;
1544	len = (ntracks + 1) * sizeof(struct cd_toc_entry) +
1545	    sizeof(toc->header);
1546	if ((error = cd_read_toc(cd, CD_MSF_FORMAT, 0, toc, len,
1547	    flags, 0)) != 0)
1548		return (error);
1549	return (0);
1550}
1551
1552/*
1553 * Get the scsi driver to send a full inquiry to the device and use the
1554 * results to fill out the disk parameter structure.
1555 */
1556int
1557cd_get_parms(cd, flags)
1558	struct cd_softc *cd;
1559	int flags;
1560{
1561
1562	/*
1563	 * give a number of sectors so that sec * trks * cyls
1564	 * is <= disk_size
1565	 */
1566	if (cd_size(cd, flags) == 0)
1567		return (ENXIO);
1568	return (0);
1569}
1570
1571int
1572cdsize(dev)
1573	dev_t dev;
1574{
1575
1576	/* CD-ROMs are read-only. */
1577	return (-1);
1578}
1579
1580int
1581cddump(dev, blkno, va, size)
1582	dev_t dev;
1583	daddr_t blkno;
1584	caddr_t va;
1585	size_t size;
1586{
1587
1588	/* Not implemented. */
1589	return (ENXIO);
1590}
1591
1592#define	dvd_copy_key(dst, src)		memcpy((dst), (src), sizeof(dvd_key))
1593#define	dvd_copy_challenge(dst, src)	memcpy((dst), (src), sizeof(dvd_challenge))
1594
1595int
1596dvd_auth(cd, a)
1597	struct cd_softc *cd;
1598	dvd_authinfo *a;
1599{
1600	struct scsipi_generic cmd;
1601	u_int8_t buf[20];
1602	int error;
1603
1604	memset(cmd.bytes, 0, 15);
1605	memset(buf, 0, sizeof(buf));
1606
1607	switch (a->type) {
1608	case DVD_LU_SEND_AGID:
1609		cmd.opcode = GPCMD_REPORT_KEY;
1610		cmd.bytes[8] = 8;
1611		cmd.bytes[9] = 0 | (0 << 6);
1612		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 8,
1613		    CDRETRIES, 30000, NULL,
1614		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1615		if (error)
1616			return (error);
1617		a->lsa.agid = buf[7] >> 6;
1618		return (0);
1619
1620	case DVD_LU_SEND_CHALLENGE:
1621		cmd.opcode = GPCMD_REPORT_KEY;
1622		cmd.bytes[8] = 16;
1623		cmd.bytes[9] = 1 | (a->lsc.agid << 6);
1624		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1625		    CDRETRIES, 30000, NULL,
1626		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1627		if (error)
1628			return (error);
1629		dvd_copy_challenge(a->lsc.chal, &buf[4]);
1630		return (0);
1631
1632	case DVD_LU_SEND_KEY1:
1633		cmd.opcode = GPCMD_REPORT_KEY;
1634		cmd.bytes[8] = 12;
1635		cmd.bytes[9] = 2 | (a->lsk.agid << 6);
1636		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1637		    CDRETRIES, 30000, NULL,
1638		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1639		if (error)
1640			return (error);
1641		dvd_copy_key(a->lsk.key, &buf[4]);
1642		return (0);
1643
1644	case DVD_LU_SEND_TITLE_KEY:
1645		cmd.opcode = GPCMD_REPORT_KEY;
1646		_lto4b(a->lstk.lba, &cmd.bytes[1]);
1647		cmd.bytes[8] = 12;
1648		cmd.bytes[9] = 4 | (a->lstk.agid << 6);
1649		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1650		    CDRETRIES, 30000, NULL,
1651		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1652		if (error)
1653			return (error);
1654		a->lstk.cpm = (buf[4] >> 7) & 1;
1655		a->lstk.cp_sec = (buf[4] >> 6) & 1;
1656		a->lstk.cgms = (buf[4] >> 4) & 3;
1657		dvd_copy_key(a->lstk.title_key, &buf[5]);
1658		return (0);
1659
1660	case DVD_LU_SEND_ASF:
1661		cmd.opcode = GPCMD_REPORT_KEY;
1662		cmd.bytes[8] = 8;
1663		cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
1664		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 8,
1665		    CDRETRIES, 30000, NULL,
1666		    XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1667		if (error)
1668			return (error);
1669		a->lsasf.asf = buf[7] & 1;
1670		return (0);
1671
1672	case DVD_HOST_SEND_CHALLENGE:
1673		cmd.opcode = GPCMD_SEND_KEY;
1674		cmd.bytes[8] = 16;
1675		cmd.bytes[9] = 1 | (a->hsc.agid << 6);
1676		buf[1] = 14;
1677		dvd_copy_challenge(&buf[4], a->hsc.chal);
1678		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1679		    CDRETRIES, 30000, NULL,
1680		    XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1681		if (error)
1682			return (error);
1683		a->type = DVD_LU_SEND_KEY1;
1684		return (0);
1685
1686	case DVD_HOST_SEND_KEY2:
1687		cmd.opcode = GPCMD_SEND_KEY;
1688		cmd.bytes[8] = 12;
1689		cmd.bytes[9] = 3 | (a->hsk.agid << 6);
1690		buf[1] = 10;
1691		dvd_copy_key(&buf[4], a->hsk.key);
1692		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 12,
1693		    CDRETRIES, 30000, NULL,
1694		    XS_CTL_DATA_OUT|XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1695		if (error) {
1696			a->type = DVD_AUTH_FAILURE;
1697			return (error);
1698		}
1699		a->type = DVD_AUTH_ESTABLISHED;
1700		return (0);
1701
1702	case DVD_INVALIDATE_AGID:
1703		cmd.opcode = GPCMD_REPORT_KEY;
1704		cmd.bytes[9] = 0x3f | (a->lsa.agid << 6);
1705		error = scsipi_command(cd->sc_periph, &cmd, 16, buf, 16,
1706		    CDRETRIES, 30000, NULL, 0);
1707		if (error)
1708			return (error);
1709		return (0);
1710
1711	default:
1712		return (ENOTTY);
1713	}
1714}
1715
1716int
1717dvd_read_physical(cd, s)
1718	struct cd_softc *cd;
1719	dvd_struct *s;
1720{
1721	struct scsipi_generic cmd;
1722	u_int8_t buf[4 + 4 * 20], *bufp;
1723	int error;
1724	struct dvd_layer *layer;
1725	int i;
1726
1727	memset(cmd.bytes, 0, 15);
1728	memset(buf, 0, sizeof(buf));
1729	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1730	cmd.bytes[6] = s->type;
1731	_lto2b(sizeof(buf), &cmd.bytes[7]);
1732
1733	cmd.bytes[5] = s->physical.layer_num;
1734	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1735	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1736	if (error)
1737		return (error);
1738	for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4;
1739	     i++, bufp += 20, layer++) {
1740		memset(layer, 0, sizeof(*layer));
1741                layer->book_version = bufp[0] & 0xf;
1742                layer->book_type = bufp[0] >> 4;
1743                layer->min_rate = bufp[1] & 0xf;
1744                layer->disc_size = bufp[1] >> 4;
1745                layer->layer_type = bufp[2] & 0xf;
1746                layer->track_path = (bufp[2] >> 4) & 1;
1747                layer->nlayers = (bufp[2] >> 5) & 3;
1748                layer->track_density = bufp[3] & 0xf;
1749                layer->linear_density = bufp[3] >> 4;
1750                layer->start_sector = _4btol(&bufp[4]);
1751                layer->end_sector = _4btol(&bufp[8]);
1752                layer->end_sector_l0 = _4btol(&bufp[12]);
1753                layer->bca = bufp[16] >> 7;
1754	}
1755	return (0);
1756}
1757
1758int
1759dvd_read_copyright(cd, s)
1760	struct cd_softc *cd;
1761	dvd_struct *s;
1762{
1763	struct scsipi_generic cmd;
1764	u_int8_t buf[8];
1765	int error;
1766
1767	memset(cmd.bytes, 0, 15);
1768	memset(buf, 0, sizeof(buf));
1769	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1770	cmd.bytes[6] = s->type;
1771	_lto2b(sizeof(buf), &cmd.bytes[7]);
1772
1773	cmd.bytes[5] = s->copyright.layer_num;
1774	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1775	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1776	if (error)
1777		return (error);
1778	s->copyright.cpst = buf[4];
1779	s->copyright.rmi = buf[5];
1780	return (0);
1781}
1782
1783int
1784dvd_read_disckey(cd, s)
1785	struct cd_softc *cd;
1786	dvd_struct *s;
1787{
1788	struct scsipi_generic cmd;
1789	u_int8_t buf[4 + 2048];
1790	int error;
1791
1792	memset(cmd.bytes, 0, 15);
1793	memset(buf, 0, sizeof(buf));
1794	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1795	cmd.bytes[6] = s->type;
1796	_lto2b(sizeof(buf), &cmd.bytes[7]);
1797
1798	cmd.bytes[9] = s->disckey.agid << 6;
1799	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1800	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1801	if (error)
1802		return (error);
1803	memcpy(s->disckey.value, &buf[4], 2048);
1804	return (0);
1805}
1806
1807int
1808dvd_read_bca(cd, s)
1809	struct cd_softc *cd;
1810	dvd_struct *s;
1811{
1812	struct scsipi_generic cmd;
1813	u_int8_t buf[4 + 188];
1814	int error;
1815
1816	memset(cmd.bytes, 0, 15);
1817	memset(buf, 0, sizeof(buf));
1818	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1819	cmd.bytes[6] = s->type;
1820	_lto2b(sizeof(buf), &cmd.bytes[7]);
1821
1822	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1823	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1824	if (error)
1825		return (error);
1826	s->bca.len = _2btol(&buf[0]);
1827	if (s->bca.len < 12 || s->bca.len > 188)
1828		return (EIO);
1829	memcpy(s->bca.value, &buf[4], s->bca.len);
1830	return (0);
1831}
1832
1833int
1834dvd_read_manufact(cd, s)
1835	struct cd_softc *cd;
1836	dvd_struct *s;
1837{
1838	struct scsipi_generic cmd;
1839	u_int8_t buf[4 + 2048];
1840	int error;
1841
1842	memset(cmd.bytes, 0, 15);
1843	memset(buf, 0, sizeof(buf));
1844	cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1845	cmd.bytes[6] = s->type;
1846	_lto2b(sizeof(buf), &cmd.bytes[7]);
1847
1848	error = scsipi_command(cd->sc_periph, &cmd, 16, buf, sizeof(buf),
1849	    CDRETRIES, 30000, NULL, XS_CTL_DATA_IN|XS_CTL_DATA_ONSTACK);
1850	if (error)
1851		return (error);
1852	s->manufact.len = _2btol(&buf[0]);
1853	if (s->manufact.len < 0 || s->manufact.len > 2048)
1854		return (EIO);
1855	memcpy(s->manufact.value, &buf[4], s->manufact.len);
1856	return (0);
1857}
1858
1859int
1860dvd_read_struct(cd, s)
1861	struct cd_softc *cd;
1862	dvd_struct *s;
1863{
1864
1865	switch (s->type) {
1866	case DVD_STRUCT_PHYSICAL:
1867		return (dvd_read_physical(cd, s));
1868	case DVD_STRUCT_COPYRIGHT:
1869		return (dvd_read_copyright(cd, s));
1870	case DVD_STRUCT_DISCKEY:
1871		return (dvd_read_disckey(cd, s));
1872	case DVD_STRUCT_BCA:
1873		return (dvd_read_bca(cd, s));
1874	case DVD_STRUCT_MANUFACT:
1875		return (dvd_read_manufact(cd, s));
1876	default:
1877		return (EINVAL);
1878	}
1879}
1880