[BACK]Return to cd.c CVS log [TXT][DIR] Up to [local] / sys / scsi

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