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