This source file includes following definitions.
- cdmatch
- cdattach
- cdactivate
- cddetach
- cdopen
- cdclose
- cdstrategy
- cdstart
- cdrestart
- cddone
- cdminphys
- cdread
- cdwrite
- lba2msf
- msf2lba
- cdioctl
- cdgetdisklabel
- cd_size
- cd_setchan
- cd_getvol
- cd_setvol
- cd_load_unload
- cd_set_pa_immed
- cd_play
- cd_play_tracks
- cd_play_msf
- cd_pause
- cd_reset
- cd_read_subchannel
- cd_read_toc
- cd_load_toc
- cd_get_parms
- cdsize
- cddump
- dvd_auth
- dvd_read_physical
- dvd_read_copyright
- dvd_read_disckey
- dvd_read_bca
- dvd_read_manufact
- dvd_read_struct
- cd_powerhook
- cd_interpret_sense
- cd_kill_buffers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 #include <sys/types.h>
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/timeout.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>
74 #include <scsi/scsiconf.h>
75
76
77 #include <ufs/ffs/fs.h>
78
79 #define CDOUTSTANDING 4
80
81 #define MAXTRACK 99
82 #define CD_BLOCK_OFFSET 150
83 #define CD_FRAMES 75
84 #define CD_SECS 60
85
86 struct cd_toc {
87 struct ioc_toc_header header;
88 struct cd_toc_entry entries[MAXTRACK+1];
89
90 };
91
92 int cdmatch(struct device *, void *, void *);
93 void cdattach(struct device *, struct device *, void *);
94 int cdactivate(struct device *, enum devact);
95 int cddetach(struct device *, int);
96
97 void cdstart(void *);
98 void cdrestart(void *);
99 void cdminphys(struct buf *);
100 void cdgetdisklabel(dev_t, struct cd_softc *, struct disklabel *, int);
101 void cddone(struct scsi_xfer *);
102 u_long cd_size(struct cd_softc *, int);
103 void cd_kill_buffers(struct cd_softc *);
104 void lba2msf(u_long, u_char *, u_char *, u_char *);
105 u_long msf2lba(u_char, u_char, u_char);
106 int cd_setchan(struct cd_softc *, int, int, int, int, int);
107 int cd_getvol(struct cd_softc *cd, struct ioc_vol *, int);
108 int cd_setvol(struct cd_softc *, const struct ioc_vol *, int);
109 int cd_load_unload(struct cd_softc *, int, int);
110 int cd_set_pa_immed(struct cd_softc *, int);
111 int cd_play(struct cd_softc *, int, int);
112 int cd_play_tracks(struct cd_softc *, int, int, int, int);
113 int cd_play_msf(struct cd_softc *, int, int, int, int, int, int);
114 int cd_pause(struct cd_softc *, int);
115 int cd_reset(struct cd_softc *);
116 int cd_read_subchannel(struct cd_softc *, int, int, int,
117 struct cd_sub_channel_info *, int );
118 int cd_read_toc(struct cd_softc *, int, int, void *, int, int);
119 int cd_get_parms(struct cd_softc *, int);
120 int cd_load_toc(struct cd_softc *, struct cd_toc *, int);
121 int cd_interpret_sense(struct scsi_xfer *);
122
123 int dvd_auth(struct cd_softc *, union dvd_authinfo *);
124 int dvd_read_physical(struct cd_softc *, union dvd_struct *);
125 int dvd_read_copyright(struct cd_softc *, union dvd_struct *);
126 int dvd_read_disckey(struct cd_softc *, union dvd_struct *);
127 int dvd_read_bca(struct cd_softc *, union dvd_struct *);
128 int dvd_read_manufact(struct cd_softc *, union dvd_struct *);
129 int dvd_read_struct(struct cd_softc *, union dvd_struct *);
130
131 void cd_powerhook(int why, void *arg);
132
133 struct cfattach cd_ca = {
134 sizeof(struct cd_softc), cdmatch, cdattach,
135 cddetach, cdactivate
136 };
137
138 struct cfdriver cd_cd = {
139 NULL, "cd", DV_DISK
140 };
141
142 struct dkdriver cddkdriver = { cdstrategy };
143
144 struct scsi_device cd_switch = {
145 cd_interpret_sense,
146 cdstart,
147 NULL,
148 cddone,
149 };
150
151 const struct scsi_inquiry_pattern cd_patterns[] = {
152 {T_CDROM, T_REMOV,
153 "", "", ""},
154 {T_WORM, T_REMOV,
155 "", "", ""},
156 {T_DIRECT, T_REMOV,
157 "NEC CD-ROM DRIVE:260", "", ""},
158 #if 0
159 {T_CDROM, T_REMOV,
160 "PIONEER ", "CD-ROM DRM-600 ", ""},
161 #endif
162 };
163
164 #define cdlock(softc) disk_lock(&(softc)->sc_dk)
165 #define cdunlock(softc) disk_unlock(&(softc)->sc_dk)
166 #define cdlookup(unit) (struct cd_softc *)device_lookup(&cd_cd, (unit))
167
168 int
169 cdmatch(struct device *parent, void *match, void *aux)
170 {
171 struct scsi_attach_args *sa = aux;
172 int priority;
173
174 scsi_inqmatch(sa->sa_inqbuf, cd_patterns,
175 sizeof(cd_patterns)/sizeof(cd_patterns[0]), sizeof(cd_patterns[0]),
176 &priority);
177 return (priority);
178 }
179
180
181
182
183
184 void
185 cdattach(struct device *parent, struct device *self, void *aux)
186 {
187 struct scsi_attach_args *sa = aux;
188 struct scsi_link *sc_link = sa->sa_sc_link;
189 struct cd_softc *cd = (struct cd_softc *)self;
190
191 SC_DEBUG(sc_link, SDEV_DB2, ("cdattach:\n"));
192
193
194
195
196 cd->sc_link = sc_link;
197 sc_link->device = &cd_switch;
198 sc_link->device_softc = cd;
199 if (sc_link->openings > CDOUTSTANDING)
200 sc_link->openings = CDOUTSTANDING;
201
202
203
204
205 cd->sc_dk.dk_driver = &cddkdriver;
206 cd->sc_dk.dk_name = cd->sc_dev.dv_xname;
207 disk_attach(&cd->sc_dk);
208
209
210
211
212 if (!(sc_link->flags & SDEV_ATAPI) &&
213 SCSISPC(sa->sa_inqbuf->version) == 0)
214 cd->flags |= CDF_ANCIENT;
215
216 printf("\n");
217
218 timeout_set(&cd->sc_timeout, cdrestart, cd);
219
220 if ((cd->sc_cdpwrhook = powerhook_establish(cd_powerhook, cd)) == NULL)
221 printf("%s: WARNING: unable to establish power hook\n",
222 cd->sc_dev.dv_xname);
223 }
224
225
226 int
227 cdactivate(struct device *self, enum devact act)
228 {
229 int rv = 0;
230
231 switch (act) {
232 case DVACT_ACTIVATE:
233 break;
234
235 case DVACT_DEACTIVATE:
236
237
238
239 break;
240 }
241 return (rv);
242 }
243
244
245 int
246 cddetach(struct device *self, int flags)
247 {
248 struct cd_softc *cd = (struct cd_softc *)self;
249 int bmaj, cmaj, mn;
250
251 cd_kill_buffers(cd);
252
253
254 mn = DISKMINOR(self->dv_unit, 0);
255
256 for (bmaj = 0; bmaj < nblkdev; bmaj++)
257 if (bdevsw[bmaj].d_open == cdopen)
258 vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
259 for (cmaj = 0; cmaj < nchrdev; cmaj++)
260 if (cdevsw[cmaj].d_open == cdopen)
261 vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
262
263
264 if (cd->sc_cdpwrhook != NULL)
265 powerhook_disestablish(cd->sc_cdpwrhook);
266
267
268 disk_detach(&cd->sc_dk);
269
270 return (0);
271 }
272
273
274
275
276 int
277 cdopen(dev_t dev, int flag, int fmt, struct proc *p)
278 {
279 struct scsi_link *sc_link;
280 struct cd_softc *cd;
281 int error = 0, part, rawopen, unit;
282
283 unit = DISKUNIT(dev);
284 part = DISKPART(dev);
285
286 rawopen = (part == RAW_PART) && (fmt == S_IFCHR);
287
288 cd = cdlookup(unit);
289 if (cd == NULL)
290 return (ENXIO);
291
292 sc_link = cd->sc_link;
293 SC_DEBUG(sc_link, SDEV_DB1,
294 ("cdopen: dev=0x%x (unit %d (of %d), partition %d)\n", dev, unit,
295 cd_cd.cd_ndevs, part));
296
297 if ((error = cdlock(cd)) != 0) {
298 device_unref(&cd->sc_dev);
299 return (error);
300 }
301
302 if (cd->sc_dk.dk_openmask != 0) {
303
304
305
306
307 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
308 if (rawopen)
309 goto out;
310 error = EIO;
311 goto bad;
312 }
313 } else {
314
315
316
317
318
319
320
321 sc_link->flags |= SDEV_OPEN;
322
323 error = scsi_test_unit_ready(sc_link, TEST_READY_RETRIES,
324 (rawopen ? SCSI_SILENT : 0) | SCSI_IGNORE_ILLEGAL_REQUEST |
325 SCSI_IGNORE_MEDIA_CHANGE);
326
327
328 if (error == EIO)
329 error = scsi_start(sc_link, SSS_START,
330 SCSI_IGNORE_ILLEGAL_REQUEST |
331 SCSI_IGNORE_MEDIA_CHANGE | SCSI_SILENT);
332
333 if (error) {
334 if (rawopen) {
335 error = 0;
336 goto out;
337 } else
338 goto bad;
339 }
340
341
342 error = scsi_prevent(sc_link, PR_PREVENT,
343 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
344 if (error)
345 goto bad;
346
347
348 sc_link->flags |= SDEV_MEDIA_LOADED;
349 if (cd_get_parms(cd, 0) != 0) {
350 sc_link->flags &= ~SDEV_MEDIA_LOADED;
351 error = ENXIO;
352 goto bad;
353 }
354 SC_DEBUG(sc_link, SDEV_DB3, ("Params loaded\n"));
355
356
357 cdgetdisklabel(dev, cd, cd->sc_dk.dk_label, 0);
358 SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated\n"));
359 }
360
361
362 if (part != RAW_PART && (part >= cd->sc_dk.dk_label->d_npartitions ||
363 cd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
364 error = ENXIO;
365 goto bad;
366 }
367
368 out:
369 switch (fmt) {
370 case S_IFCHR:
371 cd->sc_dk.dk_copenmask |= (1 << part);
372 break;
373 case S_IFBLK:
374 cd->sc_dk.dk_bopenmask |= (1 << part);
375 break;
376 }
377 cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
378 sc_link->flags |= SDEV_OPEN;
379 SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
380
381
382 bad:
383 if (cd->sc_dk.dk_openmask == 0) {
384 scsi_prevent(sc_link, PR_ALLOW,
385 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
386 sc_link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED);
387 }
388
389 cdunlock(cd);
390 device_unref(&cd->sc_dev);
391 return (error);
392 }
393
394
395
396
397
398 int
399 cdclose(dev_t dev, int flag, int fmt, struct proc *p)
400 {
401 struct cd_softc *cd;
402 int part = DISKPART(dev);
403 int error;
404
405 cd = cdlookup(DISKUNIT(dev));
406 if (cd == NULL)
407 return ENXIO;
408
409 if ((error = cdlock(cd)) != 0) {
410 device_unref(&cd->sc_dev);
411 return error;
412 }
413
414 switch (fmt) {
415 case S_IFCHR:
416 cd->sc_dk.dk_copenmask &= ~(1 << part);
417 break;
418 case S_IFBLK:
419 cd->sc_dk.dk_bopenmask &= ~(1 << part);
420 break;
421 }
422 cd->sc_dk.dk_openmask = cd->sc_dk.dk_copenmask | cd->sc_dk.dk_bopenmask;
423
424 if (cd->sc_dk.dk_openmask == 0) {
425
426
427 scsi_prevent(cd->sc_link, PR_ALLOW,
428 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
429 cd->sc_link->flags &= ~(SDEV_OPEN | SDEV_MEDIA_LOADED);
430
431 if (cd->sc_link->flags & SDEV_EJECTING) {
432 scsi_start(cd->sc_link, SSS_STOP|SSS_LOEJ, 0);
433
434 cd->sc_link->flags &= ~SDEV_EJECTING;
435 }
436
437 timeout_del(&cd->sc_timeout);
438 }
439
440 cdunlock(cd);
441
442 device_unref(&cd->sc_dev);
443 return 0;
444 }
445
446
447
448
449
450
451 void
452 cdstrategy(struct buf *bp)
453 {
454 struct cd_softc *cd;
455 int s;
456
457 if ((cd = cdlookup(DISKUNIT(bp->b_dev))) == NULL) {
458 bp->b_error = ENXIO;
459 goto bad;
460 }
461
462 SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdstrategy: %ld bytes @ blk %d\n",
463 bp->b_bcount, bp->b_blkno));
464
465
466
467
468 if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
469 bp->b_error = EIO;
470 goto bad;
471 }
472
473
474
475 if ((bp->b_bcount % cd->sc_dk.dk_label->d_secsize) != 0) {
476 bp->b_error = EINVAL;
477 goto bad;
478 }
479
480
481
482 if (bp->b_bcount == 0)
483 goto done;
484
485
486
487
488
489 if (DISKPART(bp->b_dev) != RAW_PART &&
490 bounds_check_with_label(bp, cd->sc_dk.dk_label,
491 (cd->flags & (CDF_WLABEL|CDF_LABELLING)) != 0) <= 0)
492 goto done;
493
494 s = splbio();
495
496
497
498
499 disksort(&cd->buf_queue, bp);
500
501
502
503
504
505 cdstart(cd);
506
507 device_unref(&cd->sc_dev);
508 splx(s);
509 return;
510
511 bad:
512 bp->b_flags |= B_ERROR;
513 done:
514
515
516
517 bp->b_resid = bp->b_bcount;
518 s = splbio();
519 biodone(bp);
520 splx(s);
521 if (cd != NULL)
522 device_unref(&cd->sc_dev);
523 }
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541 void
542 cdstart(void *v)
543 {
544 struct cd_softc *cd = v;
545 struct scsi_link *sc_link = cd->sc_link;
546 struct buf *bp = 0;
547 struct buf *dp;
548 struct scsi_rw_big cmd_big;
549 struct scsi_rw cmd_small;
550 struct scsi_generic *cmdp;
551 int blkno, nblks, cmdlen, error;
552 struct partition *p;
553
554 splassert(IPL_BIO);
555
556 SC_DEBUG(sc_link, SDEV_DB2, ("cdstart\n"));
557
558
559
560 while (sc_link->openings > 0) {
561
562
563
564
565
566 if (sc_link->flags & SDEV_WAITING) {
567 sc_link->flags &= ~SDEV_WAITING;
568 wakeup((caddr_t)sc_link);
569 return;
570 }
571
572
573
574
575 dp = &cd->buf_queue;
576 if ((bp = dp->b_actf) == NULL)
577 return;
578 dp->b_actf = bp->b_actf;
579
580
581
582
583
584
585 if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
586 bp->b_error = EIO;
587 bp->b_flags |= B_ERROR;
588 bp->b_resid = bp->b_bcount;
589 biodone(bp);
590 continue;
591 }
592
593
594
595
596
597
598
599 blkno =
600 bp->b_blkno / (cd->sc_dk.dk_label->d_secsize / DEV_BSIZE);
601 p = &cd->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)];
602 blkno += DL_GETPOFFSET(p);
603 nblks = howmany(bp->b_bcount, cd->sc_dk.dk_label->d_secsize);
604
605
606
607
608
609 if (!(sc_link->flags & SDEV_ATAPI) &&
610 !(sc_link->quirks & SDEV_ONLYBIG) &&
611 ((blkno & 0x1fffff) == blkno) &&
612 ((nblks & 0xff) == nblks)) {
613
614
615
616 bzero(&cmd_small, sizeof(cmd_small));
617 cmd_small.opcode = (bp->b_flags & B_READ) ?
618 READ_COMMAND : WRITE_COMMAND;
619 _lto3b(blkno, cmd_small.addr);
620 cmd_small.length = nblks & 0xff;
621 cmdlen = sizeof(cmd_small);
622 cmdp = (struct scsi_generic *)&cmd_small;
623 } else {
624
625
626
627 bzero(&cmd_big, sizeof(cmd_big));
628 cmd_big.opcode = (bp->b_flags & B_READ) ?
629 READ_BIG : WRITE_BIG;
630 _lto4b(blkno, cmd_big.addr);
631 _lto2b(nblks, cmd_big.length);
632 cmdlen = sizeof(cmd_big);
633 cmdp = (struct scsi_generic *)&cmd_big;
634 }
635
636
637 disk_busy(&cd->sc_dk);
638
639
640
641
642
643 error = scsi_scsi_cmd(sc_link, cmdp, cmdlen,
644 (u_char *) bp->b_data, bp->b_bcount, CDRETRIES, 30000, bp,
645 SCSI_NOSLEEP | ((bp->b_flags & B_READ) ? SCSI_DATA_IN :
646 SCSI_DATA_OUT));
647 switch (error) {
648 case 0:
649 timeout_del(&cd->sc_timeout);
650 break;
651 case EAGAIN:
652
653
654
655 dp->b_actf = bp;
656 disk_unbusy(&cd->sc_dk, 0, 0);
657 timeout_add(&cd->sc_timeout, 1);
658 return;
659 default:
660 disk_unbusy(&cd->sc_dk, 0, 0);
661 printf("%s: not queued, error %d\n",
662 cd->sc_dev.dv_xname, error);
663 break;
664 }
665 }
666 }
667
668 void
669 cdrestart(void *v)
670 {
671 int s;
672
673 s = splbio();
674 cdstart(v);
675 splx(s);
676 }
677
678 void
679 cddone(struct scsi_xfer *xs)
680 {
681 struct cd_softc *cd = xs->sc_link->device_softc;
682
683 if (xs->bp != NULL)
684 disk_unbusy(&cd->sc_dk, xs->bp->b_bcount - xs->bp->b_resid,
685 (xs->bp->b_flags & B_READ));
686 }
687
688 void
689 cdminphys(struct buf *bp)
690 {
691 struct cd_softc *cd;
692 long max;
693
694 cd = cdlookup(DISKUNIT(bp->b_dev));
695 if (cd == NULL)
696 return;
697
698
699
700
701
702
703
704
705
706
707
708
709 if (cd->flags & CDF_ANCIENT) {
710 max = cd->sc_dk.dk_label->d_secsize * 0xff;
711
712 if (bp->b_bcount > max)
713 bp->b_bcount = max;
714 }
715
716 (*cd->sc_link->adapter->scsi_minphys)(bp);
717
718 device_unref(&cd->sc_dev);
719 }
720
721 int
722 cdread(dev_t dev, struct uio *uio, int ioflag)
723 {
724
725 return (physio(cdstrategy, NULL, dev, B_READ, cdminphys, uio));
726 }
727
728 int
729 cdwrite(dev_t dev, struct uio *uio, int ioflag)
730 {
731
732 return (physio(cdstrategy, NULL, dev, B_WRITE, cdminphys, uio));
733 }
734
735
736
737
738
739 void
740 lba2msf (lba, m, s, f)
741 u_long lba;
742 u_char *m, *s, *f;
743 {
744 u_long tmp;
745
746 tmp = lba + CD_BLOCK_OFFSET;
747 tmp &= 0xffffff;
748 *m = tmp / (CD_SECS * CD_FRAMES);
749 tmp %= (CD_SECS * CD_FRAMES);
750 *s = tmp / CD_FRAMES;
751 *f = tmp % CD_FRAMES;
752 }
753
754 u_long
755 msf2lba (m, s, f)
756 u_char m, s, f;
757 {
758
759 return ((((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET);
760 }
761
762
763
764
765
766
767 int
768 cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
769 {
770 struct cd_softc *cd;
771 struct disklabel *lp;
772 int part = DISKPART(dev);
773 int error = 0;
774
775 cd = cdlookup(DISKUNIT(dev));
776 if (cd == NULL)
777 return ENXIO;
778
779 SC_DEBUG(cd->sc_link, SDEV_DB2, ("cdioctl 0x%lx\n", cmd));
780
781
782
783
784 if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
785 switch (cmd) {
786 case DIOCWLABEL:
787 case DIOCLOCK:
788 case DIOCEJECT:
789 case SCIOCIDENTIFY:
790 case SCIOCCOMMAND:
791 case SCIOCDEBUG:
792 case CDIOCLOADUNLOAD:
793 case SCIOCRESET:
794 case CDIOCGETVOL:
795 case CDIOCSETVOL:
796 case CDIOCSETMONO:
797 case CDIOCSETSTEREO:
798 case CDIOCSETMUTE:
799 case CDIOCSETLEFT:
800 case CDIOCSETRIGHT:
801 case CDIOCCLOSE:
802 case CDIOCEJECT:
803 case CDIOCALLOW:
804 case CDIOCPREVENT:
805 case CDIOCSETDEBUG:
806 case CDIOCCLRDEBUG:
807 case CDIOCRESET:
808 case DVD_AUTH:
809 case DVD_READ_STRUCT:
810 case MTIOCTOP:
811 if (part == RAW_PART)
812 break;
813
814 default:
815 if ((cd->sc_link->flags & SDEV_OPEN) == 0)
816 error = ENODEV;
817 else
818 error = EIO;
819 goto exit;
820 }
821 }
822
823 switch (cmd) {
824 case DIOCRLDINFO:
825 lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK);
826 cdgetdisklabel(dev, cd, lp, 0);
827 bcopy(lp, cd->sc_dk.dk_label, sizeof(*lp));
828 free(lp, M_TEMP);
829 break;
830 case DIOCGDINFO:
831 case DIOCGPDINFO:
832 *(struct disklabel *)addr = *(cd->sc_dk.dk_label);
833 break;
834
835 case DIOCGPART:
836 ((struct partinfo *)addr)->disklab = cd->sc_dk.dk_label;
837 ((struct partinfo *)addr)->part =
838 &cd->sc_dk.dk_label->d_partitions[DISKPART(dev)];
839 break;
840
841 case DIOCWDINFO:
842 case DIOCSDINFO:
843 if ((flag & FWRITE) == 0) {
844 error = EBADF;
845 break;
846 }
847
848 if ((error = cdlock(cd)) != 0)
849 break;
850
851 cd->flags |= CDF_LABELLING;
852
853 error = setdisklabel(cd->sc_dk.dk_label,
854 (struct disklabel *)addr, 0);
855 if (error == 0) {
856 }
857
858 cd->flags &= ~CDF_LABELLING;
859 cdunlock(cd);
860 break;
861
862 case DIOCWLABEL:
863 error = EBADF;
864 break;
865
866 case CDIOCPLAYTRACKS: {
867 struct ioc_play_track *args = (struct ioc_play_track *)addr;
868
869 if ((error = cd_set_pa_immed(cd, 0)) != 0)
870 break;
871 error = cd_play_tracks(cd, args->start_track,
872 args->start_index, args->end_track, args->end_index);
873 break;
874 }
875 case CDIOCPLAYMSF: {
876 struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
877
878 if ((error = cd_set_pa_immed(cd, 0)) != 0)
879 break;
880 error = cd_play_msf(cd, args->start_m, args->start_s,
881 args->start_f, args->end_m, args->end_s, args->end_f);
882 break;
883 }
884 case CDIOCPLAYBLOCKS: {
885 struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
886
887 if ((error = cd_set_pa_immed(cd, 0)) != 0)
888 break;
889 error = cd_play(cd, args->blk, args->len);
890 break;
891 }
892 case CDIOCREADSUBCHANNEL: {
893 struct ioc_read_subchannel *args
894 = (struct ioc_read_subchannel *)addr;
895 struct cd_sub_channel_info data;
896 int len = args->data_len;
897 if (len > sizeof(data) ||
898 len < sizeof(struct cd_sub_channel_header)) {
899 error = EINVAL;
900 break;
901 }
902 error = cd_read_subchannel(cd, args->address_format,
903 args->data_format, args->track,
904 &data, len);
905 if (error)
906 break;
907 len = min(len, _2btol(data.header.data_len) +
908 sizeof(struct cd_sub_channel_header));
909 error = copyout(&data, args->data, len);
910 break;
911 }
912 case CDIOREADTOCHEADER: {
913 struct ioc_toc_header th;
914
915 if ((error = cd_read_toc(cd, 0, 0, &th, sizeof(th), 0)) != 0)
916 break;
917 if (cd->sc_link->quirks & ADEV_LITTLETOC)
918 th.len = letoh16(th.len);
919 else
920 th.len = betoh16(th.len);
921 bcopy(&th, addr, sizeof(th));
922 break;
923 }
924 case CDIOREADTOCENTRYS: {
925 struct cd_toc *toc;
926 struct ioc_read_toc_entry *te =
927 (struct ioc_read_toc_entry *)addr;
928 struct ioc_toc_header *th;
929 struct cd_toc_entry *cte;
930 int len = te->data_len;
931 int ntracks;
932
933 MALLOC(toc, struct cd_toc *, sizeof(struct cd_toc), M_TEMP,
934 M_WAITOK);
935 bzero(toc, sizeof(*toc));
936
937 th = &toc->header;
938
939 if (len > sizeof(toc->entries) ||
940 len < sizeof(struct cd_toc_entry)) {
941 FREE(toc, M_TEMP);
942 error = EINVAL;
943 break;
944 }
945 error = cd_read_toc(cd, te->address_format, te->starting_track,
946 toc, len + sizeof(struct ioc_toc_header), 0);
947 if (error) {
948 FREE(toc, M_TEMP);
949 break;
950 }
951 if (te->address_format == CD_LBA_FORMAT)
952 for (ntracks =
953 th->ending_track - th->starting_track + 1;
954 ntracks >= 0; ntracks--) {
955 cte = &toc->entries[ntracks];
956 cte->addr_type = CD_LBA_FORMAT;
957 if (cd->sc_link->quirks & ADEV_LITTLETOC) {
958 #if BYTE_ORDER == BIG_ENDIAN
959 swap16_multi((u_int16_t *)&cte->addr,
960 sizeof(cte->addr) / 2);
961 #endif
962 } else
963 cte->addr.lba = betoh32(cte->addr.lba);
964 }
965 if (cd->sc_link->quirks & ADEV_LITTLETOC) {
966 th->len = letoh16(th->len);
967 } else
968 th->len = betoh16(th->len);
969 len = min(len, th->len - (sizeof(th->starting_track) +
970 sizeof(th->ending_track)));
971
972 error = copyout(toc->entries, te->data, len);
973 FREE(toc, M_TEMP);
974 break;
975 }
976 case CDIOREADMSADDR: {
977 struct cd_toc *toc;
978 int sessno = *(int *)addr;
979 struct cd_toc_entry *cte;
980
981 if (sessno != 0) {
982 error = EINVAL;
983 break;
984 }
985
986 MALLOC(toc, struct cd_toc *, sizeof(struct cd_toc), M_TEMP,
987 M_WAITOK);
988 bzero(toc, sizeof(*toc));
989
990 error = cd_read_toc(cd, 0, 0, toc,
991 sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
992 0x40 );
993
994 if (error) {
995 FREE(toc, M_TEMP);
996 break;
997 }
998
999 cte = &toc->entries[0];
1000 if (cd->sc_link->quirks & ADEV_LITTLETOC) {
1001 #if BYTE_ORDER == BIG_ENDIAN
1002 swap16_multi((u_int16_t *)&cte->addr,
1003 sizeof(cte->addr) / 2);
1004 #endif
1005 } else
1006 cte->addr.lba = betoh32(cte->addr.lba);
1007 if (cd->sc_link->quirks & ADEV_LITTLETOC)
1008 toc->header.len = letoh16(toc->header.len);
1009 else
1010 toc->header.len = betoh16(toc->header.len);
1011
1012 *(int *)addr = (toc->header.len >= 10 && cte->track > 1) ?
1013 cte->addr.lba : 0;
1014 FREE(toc, M_TEMP);
1015 break;
1016 }
1017 case CDIOCSETPATCH: {
1018 struct ioc_patch *arg = (struct ioc_patch *)addr;
1019
1020 error = cd_setchan(cd, arg->patch[0], arg->patch[1],
1021 arg->patch[2], arg->patch[3], 0);
1022 break;
1023 }
1024 case CDIOCGETVOL: {
1025 struct ioc_vol *arg = (struct ioc_vol *)addr;
1026
1027 error = cd_getvol(cd, arg, 0);
1028 break;
1029 }
1030 case CDIOCSETVOL: {
1031 struct ioc_vol *arg = (struct ioc_vol *)addr;
1032
1033 error = cd_setvol(cd, arg, 0);
1034 break;
1035 }
1036
1037 case CDIOCSETMONO:
1038 error = cd_setchan(cd, BOTH_CHANNEL, BOTH_CHANNEL, MUTE_CHANNEL,
1039 MUTE_CHANNEL, 0);
1040 break;
1041
1042 case CDIOCSETSTEREO:
1043 error = cd_setchan(cd, LEFT_CHANNEL, RIGHT_CHANNEL,
1044 MUTE_CHANNEL, MUTE_CHANNEL, 0);
1045 break;
1046
1047 case CDIOCSETMUTE:
1048 error = cd_setchan(cd, MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL,
1049 MUTE_CHANNEL, 0);
1050 break;
1051
1052 case CDIOCSETLEFT:
1053 error = cd_setchan(cd, LEFT_CHANNEL, LEFT_CHANNEL, MUTE_CHANNEL,
1054 MUTE_CHANNEL, 0);
1055 break;
1056
1057 case CDIOCSETRIGHT:
1058 error = cd_setchan(cd, RIGHT_CHANNEL, RIGHT_CHANNEL,
1059 MUTE_CHANNEL, MUTE_CHANNEL, 0);
1060 break;
1061
1062 case CDIOCRESUME:
1063 error = cd_pause(cd, 1);
1064 break;
1065
1066 case CDIOCPAUSE:
1067 error = cd_pause(cd, 0);
1068 break;
1069 case CDIOCSTART:
1070 error = scsi_start(cd->sc_link, SSS_START, 0);
1071 break;
1072
1073 case CDIOCSTOP:
1074 error = scsi_start(cd->sc_link, SSS_STOP, 0);
1075 break;
1076
1077 close_tray:
1078 case CDIOCCLOSE:
1079 error = scsi_start(cd->sc_link, SSS_START|SSS_LOEJ,
1080 SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
1081 break;
1082
1083 case MTIOCTOP:
1084 if (((struct mtop *)addr)->mt_op == MTRETEN)
1085 goto close_tray;
1086 if (((struct mtop *)addr)->mt_op != MTOFFL) {
1087 error = EIO;
1088 break;
1089 }
1090
1091 case CDIOCEJECT:
1092 case DIOCEJECT:
1093 cd->sc_link->flags |= SDEV_EJECTING;
1094 break;
1095 case CDIOCALLOW:
1096 error = scsi_prevent(cd->sc_link, PR_ALLOW, 0);
1097 break;
1098 case CDIOCPREVENT:
1099 error = scsi_prevent(cd->sc_link, PR_PREVENT, 0);
1100 break;
1101 case DIOCLOCK:
1102 error = scsi_prevent(cd->sc_link,
1103 (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0);
1104 break;
1105 case CDIOCSETDEBUG:
1106 cd->sc_link->flags |= (SDEV_DB1 | SDEV_DB2);
1107 break;
1108 case CDIOCCLRDEBUG:
1109 cd->sc_link->flags &= ~(SDEV_DB1 | SDEV_DB2);
1110 break;
1111 case CDIOCRESET:
1112 case SCIOCRESET:
1113 error = cd_reset(cd);
1114 break;
1115 case CDIOCLOADUNLOAD: {
1116 struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
1117
1118 error = cd_load_unload(cd, args->options, args->slot);
1119 break;
1120 }
1121
1122 case DVD_AUTH:
1123 error = dvd_auth(cd, (union dvd_authinfo *)addr);
1124 break;
1125 case DVD_READ_STRUCT:
1126 error = dvd_read_struct(cd, (union dvd_struct *)addr);
1127 break;
1128 default:
1129 if (DISKPART(dev) != RAW_PART) {
1130 error = ENOTTY;
1131 break;
1132 }
1133 error = scsi_do_ioctl(cd->sc_link, dev, cmd, addr, flag, p);
1134 break;
1135 }
1136
1137 exit:
1138
1139 device_unref(&cd->sc_dev);
1140 return (error);
1141 }
1142
1143
1144
1145
1146
1147
1148
1149
1150 void
1151 cdgetdisklabel(dev_t dev, struct cd_softc *cd, struct disklabel *lp,
1152 int spoofonly)
1153 {
1154 struct cd_toc *toc;
1155 char *errstring;
1156 int tocidx, n, audioonly = 1;
1157
1158 bzero(lp, sizeof(struct disklabel));
1159
1160 MALLOC(toc, struct cd_toc *, sizeof(struct cd_toc), M_TEMP, M_WAITOK);
1161 bzero(toc, sizeof(*toc));
1162
1163 lp->d_secsize = cd->params.blksize;
1164 lp->d_ntracks = 1;
1165 lp->d_nsectors = 100;
1166 lp->d_secpercyl = 100;
1167 lp->d_ncylinders = (cd->params.disksize / 100) + 1;
1168
1169 if (cd->sc_link->flags & SDEV_ATAPI) {
1170 strncpy(lp->d_typename, "ATAPI CD-ROM", sizeof(lp->d_typename));
1171 lp->d_type = DTYPE_ATAPI;
1172 } else {
1173 strncpy(lp->d_typename, "SCSI CD-ROM", sizeof(lp->d_typename));
1174 lp->d_type = DTYPE_SCSI;
1175 }
1176
1177 strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
1178 DL_SETDSIZE(lp, cd->params.disksize);
1179 lp->d_rpm = 300;
1180 lp->d_interleave = 1;
1181 lp->d_version = 1;
1182
1183
1184 lp->d_bbsize = BBSIZE;
1185 lp->d_sbsize = SBSIZE;
1186
1187 lp->d_magic = DISKMAGIC;
1188 lp->d_magic2 = DISKMAGIC;
1189 lp->d_checksum = dkcksum(lp);
1190
1191 if (cd_load_toc(cd, toc, CD_LBA_FORMAT)) {
1192 audioonly = 0;
1193 goto done;
1194 }
1195
1196 n = toc->header.ending_track - toc->header.starting_track + 1;
1197 for (tocidx = 0; tocidx < n; tocidx++)
1198 if (toc->entries[tocidx].control & 4) {
1199 audioonly = 0;
1200 goto done;
1201 }
1202
1203 done:
1204 free(toc, M_TEMP);
1205
1206 if (!audioonly) {
1207 errstring = readdisklabel(DISKLABELDEV(dev), cdstrategy, lp,
1208 spoofonly);
1209
1210
1211 }
1212 }
1213
1214
1215
1216
1217 u_long
1218 cd_size(struct cd_softc *cd, int flags)
1219 {
1220 struct scsi_read_cd_cap_data rdcap;
1221 struct scsi_read_cd_capacity scsi_cmd;
1222 u_long size;
1223 int blksize;
1224
1225
1226
1227 cd->params.blksize = 2048;
1228 cd->params.disksize = 400000;
1229
1230 if (cd->sc_link->quirks & ADEV_NOCAPACITY)
1231 goto exit;
1232
1233
1234
1235
1236
1237 bzero(&scsi_cmd, sizeof(scsi_cmd));
1238 scsi_cmd.opcode = READ_CD_CAPACITY;
1239
1240
1241
1242
1243
1244 if (scsi_scsi_cmd(cd->sc_link,
1245 (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd),
1246 (u_char *)&rdcap, sizeof(rdcap), CDRETRIES, 20000, NULL,
1247 flags | SCSI_DATA_IN) != 0)
1248 goto exit;
1249
1250 blksize = _4btol(rdcap.length);
1251 if ((blksize < 512) || ((blksize & 511) != 0))
1252 blksize = 2048;
1253 cd->params.blksize = blksize;
1254
1255 size = _4btol(rdcap.addr) + 1;
1256 if (size < 100)
1257 size = 400000;
1258 cd->params.disksize = size;
1259
1260 exit:
1261 SC_DEBUG(cd->sc_link, SDEV_DB2, ("cd_size: %d %ld\n", blksize, size));
1262 return (cd->params.disksize);
1263 }
1264
1265 int
1266 cd_setchan(struct cd_softc *cd, int p0, int p1, int p2, int p3, int flags)
1267 {
1268 union scsi_mode_sense_buf *data;
1269 struct cd_audio_page *audio = NULL;
1270 int error, big;
1271
1272 data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
1273 if (data == NULL)
1274 return (ENOMEM);
1275
1276 error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
1277 (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
1278 if (error == 0 && audio == NULL)
1279 error = EIO;
1280
1281 if (error == 0) {
1282 audio->port[LEFT_PORT].channels = p0;
1283 audio->port[RIGHT_PORT].channels = p1;
1284 audio->port[2].channels = p2;
1285 audio->port[3].channels = p3;
1286 if (big)
1287 error = scsi_mode_select_big(cd->sc_link, SMS_PF,
1288 &data->hdr_big, flags, 20000);
1289 else
1290 error = scsi_mode_select(cd->sc_link, SMS_PF,
1291 &data->hdr, flags, 20000);
1292 }
1293
1294 free(data, M_TEMP);
1295 return (error);
1296 }
1297
1298 int
1299 cd_getvol(struct cd_softc *cd, struct ioc_vol *arg, int flags)
1300 {
1301 union scsi_mode_sense_buf *data;
1302 struct cd_audio_page *audio = NULL;
1303 int error;
1304
1305 data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
1306 if (data == NULL)
1307 return (ENOMEM);
1308
1309 error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
1310 (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, NULL);
1311 if (error == 0 && audio == NULL)
1312 error = EIO;
1313
1314 if (error == 0) {
1315 arg->vol[0] = audio->port[0].volume;
1316 arg->vol[1] = audio->port[1].volume;
1317 arg->vol[2] = audio->port[2].volume;
1318 arg->vol[3] = audio->port[3].volume;
1319 }
1320
1321 free(data, M_TEMP);
1322 return (0);
1323 }
1324
1325 int
1326 cd_setvol(struct cd_softc *cd, const struct ioc_vol *arg, int flags)
1327 {
1328 union scsi_mode_sense_buf *data;
1329 struct cd_audio_page *audio = NULL;
1330 u_int8_t mask_volume[4];
1331 int error, big;
1332
1333 data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
1334 if (data == NULL)
1335 return (ENOMEM);
1336
1337 error = scsi_do_mode_sense(cd->sc_link,
1338 AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, data, (void **)&audio, NULL,
1339 NULL, NULL, sizeof(*audio), flags, NULL);
1340 if (error == 0 && audio == NULL)
1341 error = EIO;
1342 if (error != 0) {
1343 free(data, M_TEMP);
1344 return (error);
1345 }
1346
1347 mask_volume[0] = audio->port[0].volume;
1348 mask_volume[1] = audio->port[1].volume;
1349 mask_volume[2] = audio->port[2].volume;
1350 mask_volume[3] = audio->port[3].volume;
1351
1352 error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
1353 (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
1354 if (error == 0 && audio == NULL)
1355 error = EIO;
1356 if (error != 0) {
1357 free(data, M_TEMP);
1358 return (error);
1359 }
1360
1361 audio->port[0].volume = arg->vol[0] & mask_volume[0];
1362 audio->port[1].volume = arg->vol[1] & mask_volume[1];
1363 audio->port[2].volume = arg->vol[2] & mask_volume[2];
1364 audio->port[3].volume = arg->vol[3] & mask_volume[3];
1365
1366 if (big)
1367 error = scsi_mode_select_big(cd->sc_link, SMS_PF,
1368 &data->hdr_big, flags, 20000);
1369 else
1370 error = scsi_mode_select(cd->sc_link, SMS_PF,
1371 &data->hdr, flags, 20000);
1372
1373 free(data, M_TEMP);
1374 return (error);
1375 }
1376
1377 int
1378 cd_load_unload(struct cd_softc *cd, int options, int slot)
1379 {
1380 struct scsi_load_unload cmd;
1381
1382 bzero(&cmd, sizeof(cmd));
1383 cmd.opcode = LOAD_UNLOAD;
1384 cmd.options = options;
1385 cmd.slot = slot;
1386
1387 return (scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&cmd,
1388 sizeof(cmd), 0, 0, CDRETRIES, 200000, NULL, 0));
1389 }
1390
1391 int
1392 cd_set_pa_immed(struct cd_softc *cd, int flags)
1393 {
1394 union scsi_mode_sense_buf *data;
1395 struct cd_audio_page *audio = NULL;
1396 int error, oflags, big;
1397
1398 if (cd->sc_link->flags & SDEV_ATAPI)
1399
1400 return (0);
1401
1402 data = malloc(sizeof(*data), M_TEMP, M_NOWAIT);
1403 if (data == NULL)
1404 return (ENOMEM);
1405
1406 error = scsi_do_mode_sense(cd->sc_link, AUDIO_PAGE, data,
1407 (void **)&audio, NULL, NULL, NULL, sizeof(*audio), flags, &big);
1408 if (error == 0 && audio == NULL)
1409 error = EIO;
1410
1411 if (error == 0) {
1412 oflags = audio->flags;
1413 audio->flags &= ~CD_PA_SOTC;
1414 audio->flags |= CD_PA_IMMED;
1415 if (audio->flags != oflags) {
1416 if (big)
1417 error = scsi_mode_select_big(cd->sc_link,
1418 SMS_PF, &data->hdr_big, flags,
1419 20000);
1420 else
1421 error = scsi_mode_select(cd->sc_link, SMS_PF,
1422 &data->hdr, flags, 20000);
1423 }
1424 }
1425
1426 free(data, M_TEMP);
1427 return (error);
1428 }
1429
1430
1431
1432
1433 int
1434 cd_play(struct cd_softc *cd, int blkno, int nblks)
1435 {
1436 struct scsi_play scsi_cmd;
1437
1438 bzero(&scsi_cmd, sizeof(scsi_cmd));
1439 scsi_cmd.opcode = PLAY;
1440 _lto4b(blkno, scsi_cmd.blk_addr);
1441 _lto2b(nblks, scsi_cmd.xfer_len);
1442 return (scsi_scsi_cmd(cd->sc_link,
1443 (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd),
1444 0, 0, CDRETRIES, 200000, NULL, 0));
1445 }
1446
1447
1448
1449
1450 int
1451 cd_play_tracks(struct cd_softc *cd, int strack, int sindex, int etrack,
1452 int eindex)
1453 {
1454 struct cd_toc *toc;
1455 u_char endf, ends, endm;
1456 int error;
1457
1458 if (!etrack)
1459 return (EIO);
1460 if (strack > etrack)
1461 return (EINVAL);
1462
1463 MALLOC(toc, struct cd_toc *, sizeof(struct cd_toc), M_TEMP, M_WAITOK);
1464 bzero(toc, sizeof(*toc));
1465
1466 if ((error = cd_load_toc(cd, toc, CD_MSF_FORMAT)) != 0)
1467 goto done;
1468
1469 if (++etrack > (toc->header.ending_track+1))
1470 etrack = toc->header.ending_track+1;
1471
1472 strack -= toc->header.starting_track;
1473 etrack -= toc->header.starting_track;
1474 if (strack < 0) {
1475 error = EINVAL;
1476 goto done;
1477 }
1478
1479
1480
1481
1482
1483 endm = toc->entries[etrack].addr.msf.minute;
1484 ends = toc->entries[etrack].addr.msf.second;
1485 endf = toc->entries[etrack].addr.msf.frame;
1486 if (endf-- == 0) {
1487 endf = CD_FRAMES - 1;
1488 if (ends-- == 0) {
1489 ends = CD_SECS - 1;
1490 if (endm-- == 0) {
1491 error = EINVAL;
1492 goto done;
1493 }
1494 }
1495 }
1496
1497 error = cd_play_msf(cd, toc->entries[strack].addr.msf.minute,
1498 toc->entries[strack].addr.msf.second,
1499 toc->entries[strack].addr.msf.frame,
1500 endm, ends, endf);
1501
1502 done:
1503 FREE(toc, M_TEMP);
1504 return (error);
1505 }
1506
1507
1508
1509
1510 int
1511 cd_play_msf(struct cd_softc *cd, int startm, int starts, int startf, int endm,
1512 int ends, int endf)
1513 {
1514 struct scsi_play_msf scsi_cmd;
1515
1516 bzero(&scsi_cmd, sizeof(scsi_cmd));
1517 scsi_cmd.opcode = PLAY_MSF;
1518 scsi_cmd.start_m = startm;
1519 scsi_cmd.start_s = starts;
1520 scsi_cmd.start_f = startf;
1521 scsi_cmd.end_m = endm;
1522 scsi_cmd.end_s = ends;
1523 scsi_cmd.end_f = endf;
1524 return (scsi_scsi_cmd(cd->sc_link,
1525 (struct scsi_generic *)&scsi_cmd, sizeof(scsi_cmd),
1526 0, 0, CDRETRIES, 20000, NULL, 0));
1527 }
1528
1529
1530
1531
1532 int
1533 cd_pause(struct cd_softc *cd, int go)
1534 {
1535 struct scsi_pause scsi_cmd;
1536
1537 bzero(&scsi_cmd, sizeof(scsi_cmd));
1538 scsi_cmd.opcode = PAUSE;
1539 scsi_cmd.resume = go;
1540 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1541 sizeof(scsi_cmd), 0, 0, CDRETRIES, 2000, NULL, 0);
1542 }
1543
1544
1545
1546
1547 int
1548 cd_reset(struct cd_softc *cd)
1549 {
1550 return scsi_scsi_cmd(cd->sc_link, 0, 0, 0, 0, CDRETRIES, 2000, NULL,
1551 SCSI_RESET);
1552 }
1553
1554
1555
1556
1557 int
1558 cd_read_subchannel(struct cd_softc *cd, int mode, int format, int track,
1559 struct cd_sub_channel_info *data, int len)
1560 {
1561 struct scsi_read_subchannel scsi_cmd;
1562
1563 bzero(&scsi_cmd, sizeof(scsi_cmd));
1564 scsi_cmd.opcode = READ_SUBCHANNEL;
1565 if (mode == CD_MSF_FORMAT)
1566 scsi_cmd.byte2 |= CD_MSF;
1567 scsi_cmd.byte3 = SRS_SUBQ;
1568 scsi_cmd.subchan_format = format;
1569 scsi_cmd.track = track;
1570 _lto2b(len, scsi_cmd.data_len);
1571 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1572 sizeof(struct scsi_read_subchannel), (u_char *)data, len,
1573 CDRETRIES, 5000, NULL, SCSI_DATA_IN|SCSI_SILENT);
1574 }
1575
1576
1577
1578
1579 int
1580 cd_read_toc(struct cd_softc *cd, int mode, int start, void *data, int len,
1581 int control)
1582 {
1583 struct scsi_read_toc scsi_cmd;
1584
1585 bzero(&scsi_cmd, sizeof(scsi_cmd));
1586 bzero(data, len);
1587
1588 scsi_cmd.opcode = READ_TOC;
1589 if (mode == CD_MSF_FORMAT)
1590 scsi_cmd.byte2 |= CD_MSF;
1591 scsi_cmd.from_track = start;
1592 _lto2b(len, scsi_cmd.data_len);
1593 scsi_cmd.control = control;
1594
1595 return scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&scsi_cmd,
1596 sizeof(struct scsi_read_toc), (u_char *)data, len, CDRETRIES,
1597 5000, NULL, SCSI_DATA_IN | SCSI_IGNORE_ILLEGAL_REQUEST);
1598 }
1599
1600 int
1601 cd_load_toc(struct cd_softc *cd, struct cd_toc *toc, int fmt)
1602 {
1603 int n, len, error;
1604
1605 error = cd_read_toc(cd, 0, 0, toc, sizeof(toc->header), 0);
1606
1607 if (error == 0) {
1608 if (toc->header.ending_track < toc->header.starting_track)
1609 return (EIO);
1610
1611 n = toc->header.ending_track - toc->header.starting_track + 2;
1612 len = n * sizeof(struct cd_toc_entry) + sizeof(toc->header);
1613 error = cd_read_toc(cd, fmt, 0, toc, len, 0);
1614 }
1615
1616 return (error);
1617 }
1618
1619
1620
1621
1622
1623
1624 int
1625 cd_get_parms(struct cd_softc *cd, int flags)
1626 {
1627
1628
1629
1630
1631 if (cd_size(cd, flags) == 0)
1632 return (ENXIO);
1633 return (0);
1634 }
1635
1636 daddr64_t
1637 cdsize(dev_t dev)
1638 {
1639
1640
1641 return -1;
1642 }
1643
1644 int
1645 cddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
1646 {
1647
1648 return ENXIO;
1649 }
1650
1651 #define dvd_copy_key(dst, src) bcopy((src), (dst), DVD_KEY_SIZE)
1652 #define dvd_copy_challenge(dst, src) bcopy((src), (dst), DVD_CHALLENGE_SIZE)
1653
1654 int
1655 dvd_auth(struct cd_softc *cd, union dvd_authinfo *a)
1656 {
1657 struct scsi_generic cmd;
1658 u_int8_t buf[20];
1659 int error;
1660
1661 bzero(cmd.bytes, sizeof(cmd.bytes));
1662 bzero(buf, sizeof(buf));
1663
1664 switch (a->type) {
1665 case DVD_LU_SEND_AGID:
1666 cmd.opcode = GPCMD_REPORT_KEY;
1667 cmd.bytes[8] = 8;
1668 cmd.bytes[9] = 0 | (0 << 6);
1669 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 8,
1670 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1671 if (error)
1672 return (error);
1673 a->lsa.agid = buf[7] >> 6;
1674 return (0);
1675
1676 case DVD_LU_SEND_CHALLENGE:
1677 cmd.opcode = GPCMD_REPORT_KEY;
1678 cmd.bytes[8] = 16;
1679 cmd.bytes[9] = 1 | (a->lsc.agid << 6);
1680 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 16,
1681 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1682 if (error)
1683 return (error);
1684 dvd_copy_challenge(a->lsc.chal, &buf[4]);
1685 return (0);
1686
1687 case DVD_LU_SEND_KEY1:
1688 cmd.opcode = GPCMD_REPORT_KEY;
1689 cmd.bytes[8] = 12;
1690 cmd.bytes[9] = 2 | (a->lsk.agid << 6);
1691 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 12,
1692 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1693 if (error)
1694 return (error);
1695 dvd_copy_key(a->lsk.key, &buf[4]);
1696 return (0);
1697
1698 case DVD_LU_SEND_TITLE_KEY:
1699 cmd.opcode = GPCMD_REPORT_KEY;
1700 _lto4b(a->lstk.lba, &cmd.bytes[1]);
1701 cmd.bytes[8] = 12;
1702 cmd.bytes[9] = 4 | (a->lstk.agid << 6);
1703 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 12,
1704 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1705 if (error)
1706 return (error);
1707 a->lstk.cpm = (buf[4] >> 7) & 1;
1708 a->lstk.cp_sec = (buf[4] >> 6) & 1;
1709 a->lstk.cgms = (buf[4] >> 4) & 3;
1710 dvd_copy_key(a->lstk.title_key, &buf[5]);
1711 return (0);
1712
1713 case DVD_LU_SEND_ASF:
1714 cmd.opcode = GPCMD_REPORT_KEY;
1715 cmd.bytes[8] = 8;
1716 cmd.bytes[9] = 5 | (a->lsasf.agid << 6);
1717 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 8,
1718 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1719 if (error)
1720 return (error);
1721 a->lsasf.asf = buf[7] & 1;
1722 return (0);
1723
1724 case DVD_HOST_SEND_CHALLENGE:
1725 cmd.opcode = GPCMD_SEND_KEY;
1726 cmd.bytes[8] = 16;
1727 cmd.bytes[9] = 1 | (a->hsc.agid << 6);
1728 buf[1] = 14;
1729 dvd_copy_challenge(&buf[4], a->hsc.chal);
1730 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 16,
1731 CDRETRIES, 30000, NULL, SCSI_DATA_OUT);
1732 if (error)
1733 return (error);
1734 a->type = DVD_LU_SEND_KEY1;
1735 return (0);
1736
1737 case DVD_HOST_SEND_KEY2:
1738 cmd.opcode = GPCMD_SEND_KEY;
1739 cmd.bytes[8] = 12;
1740 cmd.bytes[9] = 3 | (a->hsk.agid << 6);
1741 buf[1] = 10;
1742 dvd_copy_key(&buf[4], a->hsk.key);
1743 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 12,
1744 CDRETRIES, 30000, NULL, SCSI_DATA_OUT);
1745 if (error) {
1746 a->type = DVD_AUTH_FAILURE;
1747 return (error);
1748 }
1749 a->type = DVD_AUTH_ESTABLISHED;
1750 return (0);
1751
1752 case DVD_INVALIDATE_AGID:
1753 cmd.opcode = GPCMD_REPORT_KEY;
1754 cmd.bytes[9] = 0x3f | (a->lsa.agid << 6);
1755 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 16,
1756 CDRETRIES, 30000, NULL, 0);
1757 if (error)
1758 return (error);
1759 return (0);
1760
1761 case DVD_LU_SEND_RPC_STATE:
1762 cmd.opcode = GPCMD_REPORT_KEY;
1763 cmd.bytes[8] = 8;
1764 cmd.bytes[9] = 8 | (0 << 6);
1765 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 8,
1766 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1767 if (error)
1768 return (error);
1769 a->lrpcs.type = (buf[4] >> 6) & 3;
1770 a->lrpcs.vra = (buf[4] >> 3) & 7;
1771 a->lrpcs.ucca = (buf[4]) & 7;
1772 a->lrpcs.region_mask = buf[5];
1773 a->lrpcs.rpc_scheme = buf[6];
1774 return (0);
1775
1776 case DVD_HOST_SEND_RPC_STATE:
1777 cmd.opcode = GPCMD_SEND_KEY;
1778 cmd.bytes[8] = 8;
1779 cmd.bytes[9] = 6 | (0 << 6);
1780 buf[1] = 6;
1781 buf[4] = a->hrpcs.pdrc;
1782 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, 8,
1783 CDRETRIES, 30000, NULL, SCSI_DATA_OUT);
1784 if (error)
1785 return (error);
1786 return (0);
1787
1788 default:
1789 return (ENOTTY);
1790 }
1791 }
1792
1793 int
1794 dvd_read_physical(cd, s)
1795 struct cd_softc *cd;
1796 union dvd_struct *s;
1797 {
1798 struct scsi_generic cmd;
1799 u_int8_t buf[4 + 4 * 20], *bufp;
1800 int error;
1801 struct dvd_layer *layer;
1802 int i;
1803
1804 bzero(cmd.bytes, sizeof(cmd.bytes));
1805 bzero(buf, sizeof(buf));
1806 cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1807 cmd.bytes[6] = s->type;
1808 _lto2b(sizeof(buf), &cmd.bytes[7]);
1809
1810 cmd.bytes[5] = s->physical.layer_num;
1811 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf),
1812 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1813 if (error)
1814 return (error);
1815 for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0]; i < 4;
1816 i++, bufp += 20, layer++) {
1817 bzero(layer, sizeof(*layer));
1818 layer->book_version = bufp[0] & 0xf;
1819 layer->book_type = bufp[0] >> 4;
1820 layer->min_rate = bufp[1] & 0xf;
1821 layer->disc_size = bufp[1] >> 4;
1822 layer->layer_type = bufp[2] & 0xf;
1823 layer->track_path = (bufp[2] >> 4) & 1;
1824 layer->nlayers = (bufp[2] >> 5) & 3;
1825 layer->track_density = bufp[3] & 0xf;
1826 layer->linear_density = bufp[3] >> 4;
1827 layer->start_sector = _4btol(&bufp[4]);
1828 layer->end_sector = _4btol(&bufp[8]);
1829 layer->end_sector_l0 = _4btol(&bufp[12]);
1830 layer->bca = bufp[16] >> 7;
1831 }
1832 return (0);
1833 }
1834
1835 int
1836 dvd_read_copyright(cd, s)
1837 struct cd_softc *cd;
1838 union dvd_struct *s;
1839 {
1840 struct scsi_generic cmd;
1841 u_int8_t buf[8];
1842 int error;
1843
1844 bzero(cmd.bytes, sizeof(cmd.bytes));
1845 bzero(buf, sizeof(buf));
1846 cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1847 cmd.bytes[6] = s->type;
1848 _lto2b(sizeof(buf), &cmd.bytes[7]);
1849
1850 cmd.bytes[5] = s->copyright.layer_num;
1851 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf),
1852 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1853 if (error)
1854 return (error);
1855 s->copyright.cpst = buf[4];
1856 s->copyright.rmi = buf[5];
1857 return (0);
1858 }
1859
1860 int
1861 dvd_read_disckey(cd, s)
1862 struct cd_softc *cd;
1863 union dvd_struct *s;
1864 {
1865 struct scsi_read_dvd_structure cmd;
1866 struct scsi_read_dvd_structure_data *buf;
1867 int error;
1868
1869 buf = malloc(sizeof(*buf), M_TEMP, M_WAITOK);
1870 if (buf == NULL)
1871 return (ENOMEM);
1872 bzero(buf, sizeof(*buf));
1873
1874 bzero(&cmd, sizeof(cmd));
1875 cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1876 cmd.format = s->type;
1877 cmd.agid = s->disckey.agid << 6;
1878 _lto2b(sizeof(*buf), cmd.length);
1879
1880 error = scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&cmd,
1881 sizeof(cmd), (u_char *)buf, sizeof(*buf), CDRETRIES, 30000, NULL,
1882 SCSI_DATA_IN);
1883 if (error == 0)
1884 bcopy(buf->data, s->disckey.value, sizeof(s->disckey.value));
1885
1886 free(buf, M_TEMP);
1887 return (error);
1888 }
1889
1890 int
1891 dvd_read_bca(cd, s)
1892 struct cd_softc *cd;
1893 union dvd_struct *s;
1894 {
1895 struct scsi_generic cmd;
1896 u_int8_t buf[4 + 188];
1897 int error;
1898
1899 bzero(cmd.bytes, sizeof(cmd.bytes));
1900 bzero(buf, sizeof(buf));
1901 cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1902 cmd.bytes[6] = s->type;
1903 _lto2b(sizeof(buf), &cmd.bytes[7]);
1904
1905 error = scsi_scsi_cmd(cd->sc_link, &cmd, sizeof(cmd), buf, sizeof(buf),
1906 CDRETRIES, 30000, NULL, SCSI_DATA_IN);
1907 if (error)
1908 return (error);
1909 s->bca.len = _2btol(&buf[0]);
1910 if (s->bca.len < 12 || s->bca.len > 188)
1911 return (EIO);
1912 bcopy(&buf[4], s->bca.value, s->bca.len);
1913 return (0);
1914 }
1915
1916 int
1917 dvd_read_manufact(cd, s)
1918 struct cd_softc *cd;
1919 union dvd_struct *s;
1920 {
1921 struct scsi_read_dvd_structure cmd;
1922 struct scsi_read_dvd_structure_data *buf;
1923 int error;
1924
1925 buf = malloc(sizeof(*buf), M_TEMP, M_WAITOK);
1926 if (buf == NULL)
1927 return (ENOMEM);
1928 bzero(buf, sizeof(*buf));
1929
1930 bzero(&cmd, sizeof(cmd));
1931 cmd.opcode = GPCMD_READ_DVD_STRUCTURE;
1932 cmd.format = s->type;
1933 _lto2b(sizeof(*buf), cmd.length);
1934
1935 error = scsi_scsi_cmd(cd->sc_link, (struct scsi_generic *)&cmd,
1936 sizeof(cmd), (u_char *)buf, sizeof(*buf), CDRETRIES, 30000, NULL,
1937 SCSI_DATA_IN);
1938 if (error == 0) {
1939 s->manufact.len = _2btol(buf->len);
1940 if (s->manufact.len >= 0 && s->manufact.len <= 2048)
1941 bcopy(buf->data, s->manufact.value, s->manufact.len);
1942 else
1943 error = EIO;
1944 }
1945
1946 free(buf, M_TEMP);
1947 return (error);
1948 }
1949
1950 int
1951 dvd_read_struct(cd, s)
1952 struct cd_softc *cd;
1953 union dvd_struct *s;
1954 {
1955
1956 switch (s->type) {
1957 case DVD_STRUCT_PHYSICAL:
1958 return (dvd_read_physical(cd, s));
1959 case DVD_STRUCT_COPYRIGHT:
1960 return (dvd_read_copyright(cd, s));
1961 case DVD_STRUCT_DISCKEY:
1962 return (dvd_read_disckey(cd, s));
1963 case DVD_STRUCT_BCA:
1964 return (dvd_read_bca(cd, s));
1965 case DVD_STRUCT_MANUFACT:
1966 return (dvd_read_manufact(cd, s));
1967 default:
1968 return (EINVAL);
1969 }
1970 }
1971
1972 void
1973 cd_powerhook(int why, void *arg)
1974 {
1975 struct cd_softc *cd = arg;
1976
1977
1978
1979
1980
1981 if (why == PWR_RESUME && cd->sc_dk.dk_openmask != 0)
1982 scsi_prevent(cd->sc_link, PR_PREVENT,
1983 SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE);
1984 }
1985
1986 int
1987 cd_interpret_sense(struct scsi_xfer *xs)
1988 {
1989 struct scsi_sense_data *sense = &xs->sense;
1990 struct scsi_link *sc_link = xs->sc_link;
1991 u_int8_t skey = sense->flags & SSD_KEY;
1992 u_int8_t serr = sense->error_code & SSD_ERRCODE;
1993
1994 if (((sc_link->flags & SDEV_OPEN) == 0) ||
1995 (serr != SSD_ERRCODE_CURRENT && serr != SSD_ERRCODE_DEFERRED))
1996 return (EJUSTRETURN);
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010 switch(skey) {
2011 case SKEY_NOT_READY:
2012 if ((xs->flags & SCSI_IGNORE_NOT_READY) != 0)
2013 return (0);
2014 if (ASC_ASCQ(sense) == SENSE_NOT_READY_BECOMING_READY) {
2015 SC_DEBUG(sc_link, SDEV_DB1, ("not ready: busy (%#x)\n",
2016 sense->add_sense_code_qual));
2017
2018 xs->retries++;
2019 return (scsi_delay(xs, 1));
2020 }
2021 break;
2022
2023 default:
2024 break;
2025 }
2026 return (EJUSTRETURN);
2027 }
2028
2029
2030
2031
2032 void
2033 cd_kill_buffers(struct cd_softc *cd)
2034 {
2035 struct buf *dp, *bp;
2036 int s;
2037
2038 s = splbio();
2039 for (dp = &cd->buf_queue; (bp = dp->b_actf) != NULL; ) {
2040 dp->b_actf = bp->b_actf;
2041
2042 bp->b_error = ENXIO;
2043 bp->b_flags |= B_ERROR;
2044 biodone(bp);
2045 }
2046 splx(s);
2047 }