Annotation of sys/scsi/cd.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: cd.c,v 1.132 2007/06/20 18:15:47 deraadt 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/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> /* 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 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]; /* One extra for the */
89: /* leadout */
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, /* we have a queue, which is started by this */
147: NULL, /* we do not have an async handler */
148: cddone, /* deal with stats at interrupt time */
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, /* more luns */
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: * The routine called by the low level scsi routine when it discovers
182: * A device suitable for this driver
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: * Store information needed to contact our base driver
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: * Initialize and attach the disk structure.
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: * Note if this device is ancient. This is used in cdminphys().
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: * Nothing to do; we key off the device's DVF_ACTIVATE.
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: /* Locate the lowest minor number to be detached. */
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: /* Get rid of the power hook. */
264: if (cd->sc_cdpwrhook != NULL)
265: powerhook_disestablish(cd->sc_cdpwrhook);
266:
267: /* Detach disk. */
268: disk_detach(&cd->sc_dk);
269:
270: return (0);
271: }
272:
273: /*
274: * Open the device. Make sure the partition info is as up-to-date as can be.
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: * If any partition is open, but the disk has been invalidated,
305: * disallow further opens.
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: * Check that it is still responding and ok. Drive can be in
316: * progress of loading media so use increased retries number
317: * and don't ignore NOT_READY.
318: */
319:
320: /* Use cd_interpret_sense() now. */
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: /* Start the cd spinning if necessary. */
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: /* Lock the cd in. */
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: /* Load the physical device parameters. */
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: /* Fabricate a disk label. */
357: cdgetdisklabel(dev, cd, cd->sc_dk.dk_label, 0);
358: SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated\n"));
359: }
360:
361: /* Check that the partition exists. */
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: /* Insure only one open at a time. */
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: /* It's OK to fall through because dk_openmask is now non-zero. */
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: * Close the device. Only called if we are the last occurrence of an open
396: * device.
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: /* XXXX Must wait for I/O to complete! */
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: * Actually translate the requested transfer into one the physical driver can
448: * understand. The transfer is described by a buf and will include only one
449: * physical transfer.
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: * If the device has been made invalid, error out
466: * maybe the media changed, or no media loaded
467: */
468: if ((cd->sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
469: bp->b_error = EIO;
470: goto bad;
471: }
472: /*
473: * The transfer must be a whole number of blocks.
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: * If it's a null transfer, return immediately
481: */
482: if (bp->b_bcount == 0)
483: goto done;
484:
485: /*
486: * Do bounds checking, adjust transfer. if error, process.
487: * If end of partition, just return.
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: * Place it in the queue of disk activities for this disk
498: */
499: disksort(&cd->buf_queue, bp);
500:
501: /*
502: * Tell the device to get going on the transfer if it's
503: * not doing anything, otherwise just wait for completion
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: * Correctly set the buf to indicate a completed xfer
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: * cdstart looks to see if there is a buf waiting for the device
527: * and that the device is not already busy. If both are true,
528: * It deques the buf and creates a scsi command to perform the
529: * transfer in the buf. The transfer request will call scsi_done
530: * on completion, which will in turn call this routine again
531: * so that the next queued transfer is performed.
532: * The bufs are queued by the strategy routine (cdstrategy)
533: *
534: * This routine is also called after other non-queued requests
535: * have been made of the scsi driver, to ensure that the queue
536: * continues to be drained.
537: *
538: * must be called at the correct (highish) spl level
539: * cdstart() is called at splbio from cdstrategy, cdrestart and scsi_done
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: * Check if the device has room for another command
559: */
560: while (sc_link->openings > 0) {
561: /*
562: * there is excess capacity, but a special waits
563: * It'll need the adapter as soon as we clear out of the
564: * way and let it run (user level wait).
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: * See if there is a buf with work for us to do..
574: */
575: dp = &cd->buf_queue;
576: if ((bp = dp->b_actf) == NULL) /* yes, an assign */
577: return;
578: dp->b_actf = bp->b_actf;
579:
580: /*
581: * If the deivce has become invalid, abort all the
582: * reads and writes until all files have been closed and
583: * re-opened
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: * We have a buf, now we should make a command
595: *
596: * First, translate the block to absolute and put it in terms
597: * of the logical blocksize of the device.
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: * Fill out the scsi command. If the transfer will
607: * fit in a "small" cdb, use it.
608: */
609: if (!(sc_link->flags & SDEV_ATAPI) &&
610: !(sc_link->quirks & SDEV_ONLYBIG) &&
611: ((blkno & 0x1fffff) == blkno) &&
612: ((nblks & 0xff) == nblks)) {
613: /*
614: * We can fit in a small cdb.
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: * Need a large cdb.
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: /* Instrumentation. */
637: disk_busy(&cd->sc_dk);
638:
639: /*
640: * Call the routine that chats with the adapter.
641: * Note: we cannot sleep as we may be an interrupt
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: * The device can't start another i/o. Try again later.
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: * If the device is ancient, we want to make sure that
700: * the transfer fits into a 6-byte cdb.
701: *
702: * XXX Note that the SCSI-I spec says that 256-block transfers
703: * are allowed in a 6-byte read/write, and are specified
704: * by setting the "length" to 0. However, we're conservative
705: * here, allowing only 255-block transfers in case an
706: * ancient device gets confused by length == 0. A length of 0
707: * in a 10-byte read/write actually means 0 blocks.
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: * conversion between minute-seconde-frame and logical block address
737: * addresses format
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; /* offset of first logical frame */
747: tmp &= 0xffffff; /* negative lbas use only 24 bits */
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: * Perform special action on behalf of the user.
765: * Knows about the internals of this device
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: * If the device is not valid.. abandon ship
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: /* FALLTHROUGH */
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, /*cd->sc_dk.dk_openmask : */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 /* control word for "get MS info" */);
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: /* FALLTHROUGH */
1091: case CDIOCEJECT: /* FALLTHROUGH */
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: * Load the label information on the named device
1145: * Actually fabricate a disklabel
1146: *
1147: * EVENTUALLY take information about different
1148: * data tracks from the TOC and put it in the disklabel
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: /* XXX - these values for BBSIZE and SBSIZE assume ffs */
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; /* No valid TOC found == not an audio CD. */
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; /* Found a non-audio track. */
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: /*if (errstring)
1210: printf("%s: %s\n", cd->sc_dev.dv_xname, errstring);*/
1211: }
1212: }
1213:
1214: /*
1215: * Find out from the device what its capacity is
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: /* Reasonable defaults for drives that don't support
1226: READ_CD_CAPACITY */
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: * make up a scsi command and ask the scsi driver to do
1235: * it for you.
1236: */
1237: bzero(&scsi_cmd, sizeof(scsi_cmd));
1238: scsi_cmd.opcode = READ_CD_CAPACITY;
1239:
1240: /*
1241: * If the command works, interpret the result as a 4 byte
1242: * number of blocks and a blocksize
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; /* some drives lie ! */
1253: cd->params.blksize = blksize;
1254:
1255: size = _4btol(rdcap.addr) + 1;
1256: if (size < 100)
1257: size = 400000; /* ditto */
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; /* ioctl uses ATAPI values */
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: /* XXX Noop? */
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: * Get scsi driver to send a "start playing" command
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: * Get scsi driver to send a "start playing" command
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: * The track ends one frame before the next begins. The last track
1481: * is taken care of by the leadoff track.
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: * Get scsi driver to send a "play msf" command
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: * Get scsi driver to send a "start up" command
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: * Get scsi driver to send a "RESET" command
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: * Read subchannel
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: * Read table of contents
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: /* +2 to account for leading out track. */
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: * Get the scsi driver to send a full inquiry to the device and use the
1622: * results to fill out the disk parameter structure.
1623: */
1624: int
1625: cd_get_parms(struct cd_softc *cd, int flags)
1626: {
1627: /*
1628: * give a number of sectors so that sec * trks * cyls
1629: * is <= disk_size
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: /* CD-ROMs are read-only. */
1641: return -1;
1642: }
1643:
1644: int
1645: cddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
1646: {
1647: /* Not implemented. */
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: * When resuming, hardware may have forgotten we locked it. So if
1979: * there are any open partitions, lock the CD.
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); /* let the generic code handle it */
1997:
1998: /*
1999: * We do custom processing in cd for the unit becoming ready
2000: * case. We do not allow xs->retries to be decremented on the
2001: * "Unit Becoming Ready" case. This is because CD drives
2002: * report "Unit Becoming Ready" when loading media and can
2003: * take a long time. Rather than having a massive timeout for
2004: * all operations (which would cause other problems), we allow
2005: * operations to wait (but be interruptable with Ctrl-C)
2006: * forever as long as the drive is reporting that it is
2007: * becoming ready. All other cases of not being ready are
2008: * handled by the default handler.
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: /* don't count this as a retry */
2018: xs->retries++;
2019: return (scsi_delay(xs, 1));
2020: }
2021: break;
2022: /* XXX more to come here for a few other cases */
2023: default:
2024: break;
2025: }
2026: return (EJUSTRETURN); /* use generic handler in scsi_base */
2027: }
2028:
2029: /*
2030: * Remove unprocessed buffers from queue.
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: }
CVSweb