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