The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/scsi/cd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: cd.c,v 1.266 2022/09/01 13:45:27 krw 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/param.h>
   51 #include <sys/systm.h>
   52 #include <sys/timeout.h>
   53 #include <sys/fcntl.h>
   54 #include <sys/stat.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/mtio.h>
   57 #include <sys/buf.h>
   58 #include <sys/uio.h>
   59 #include <sys/malloc.h>
   60 #include <sys/pool.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/conf.h>
   67 #include <sys/scsiio.h>
   68 #include <sys/dkio.h>
   69 #include <sys/vnode.h>
   70 
   71 #include <scsi/scsi_all.h>
   72 #include <scsi/cd.h>
   73 #include <scsi/scsi_debug.h>
   74 #include <scsi/scsi_disk.h>     /* rw_10 and start_stop come from there */
   75 #include <scsi/scsiconf.h>
   76 
   77 
   78 #include <ufs/ffs/fs.h>         /* for BBSIZE and SBSIZE */
   79 
   80 #define CDOUTSTANDING   4
   81 
   82 #define MAXTRACK        99
   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 *, int);
   95 int     cddetach(struct device *, int);
   96 
   97 struct cd_softc {
   98         struct device            sc_dev;
   99         struct disk              sc_dk;
  100 
  101         int                      sc_flags;
  102 #define CDF_DYING       0x40            /* dying, when deactivated */
  103         struct scsi_link        *sc_link;       /* contains targ, lun, etc. */
  104         struct cd_parms {
  105                 u_int32_t secsize;
  106                 u_int64_t disksize;     /* total number sectors */
  107         }                        params;
  108         struct bufq              sc_bufq;
  109         struct scsi_xshandler    sc_xsh;
  110 };
  111 
  112 void    cdstart(struct scsi_xfer *);
  113 void    cd_buf_done(struct scsi_xfer *);
  114 int     cd_cmd_rw6(struct scsi_generic *, int, u_int64_t, u_int32_t);
  115 int     cd_cmd_rw10(struct scsi_generic *, int, u_int64_t, u_int32_t);
  116 int     cd_cmd_rw12(struct scsi_generic *, int, u_int64_t, u_int32_t);
  117 void    cdminphys(struct buf *);
  118 int     cdgetdisklabel(dev_t, struct cd_softc *, struct disklabel *, int);
  119 int     cd_setchan(struct cd_softc *, int, int, int, int, int);
  120 int     cd_getvol(struct cd_softc *cd, struct ioc_vol *, int);
  121 int     cd_setvol(struct cd_softc *, const struct ioc_vol *, int);
  122 int     cd_load_unload(struct cd_softc *, int, int);
  123 int     cd_set_pa_immed(struct cd_softc *, int);
  124 int     cd_play(struct cd_softc *, int, int);
  125 int     cd_play_tracks(struct cd_softc *, int, int, int, int);
  126 int     cd_play_msf(struct cd_softc *, int, int, int, int, int, int);
  127 int     cd_pause(struct cd_softc *, int);
  128 int     cd_reset(struct cd_softc *);
  129 int     cd_read_subchannel(struct cd_softc *, int, int, int,
  130             struct cd_sub_channel_info *, int );
  131 int     cd_read_toc(struct cd_softc *, int, int, void *, int, int);
  132 int     cd_get_parms(struct cd_softc *, int);
  133 int     cd_load_toc(struct cd_softc *, struct cd_toc *, int);
  134 int     cd_interpret_sense(struct scsi_xfer *);
  135 u_int64_t cd_size(struct scsi_link *, int, u_int32_t *);
  136 
  137 int     dvd_auth(struct cd_softc *, union dvd_authinfo *);
  138 int     dvd_read_physical(struct cd_softc *, union dvd_struct *);
  139 int     dvd_read_copyright(struct cd_softc *, union dvd_struct *);
  140 int     dvd_read_disckey(struct cd_softc *, union dvd_struct *);
  141 int     dvd_read_bca(struct cd_softc *, union dvd_struct *);
  142 int     dvd_read_manufact(struct cd_softc *, union dvd_struct *);
  143 int     dvd_read_struct(struct cd_softc *, union dvd_struct *);
  144 
  145 #if defined(__macppc__)
  146 int     cd_eject(void);
  147 #endif /* __macppc__ */
  148 
  149 const struct cfattach cd_ca = {
  150         sizeof(struct cd_softc), cdmatch, cdattach,
  151         cddetach, cdactivate
  152 };
  153 
  154 struct cfdriver cd_cd = {
  155         NULL, "cd", DV_DISK
  156 };
  157 
  158 const struct scsi_inquiry_pattern cd_patterns[] = {
  159         {T_CDROM, T_REMOV,
  160          "",         "",                 ""},
  161         {T_CDROM, T_FIXED,
  162          "",         "",                 ""},
  163         {T_WORM, T_REMOV,
  164          "",         "",                 ""},
  165         {T_WORM, T_FIXED,
  166          "",         "",                 ""},
  167         {T_DIRECT, T_REMOV,
  168          "NEC                 CD-ROM DRIVE:260", "", ""},
  169 #if 0
  170         {T_CDROM, T_REMOV, /* more luns */
  171          "PIONEER ", "CD-ROM DRM-600  ", ""},
  172 #endif /* 0 */
  173 };
  174 
  175 #define cdlookup(unit) (struct cd_softc *)disk_lookup(&cd_cd, (unit))
  176 
  177 int
  178 cdmatch(struct device *parent, void *match, void *aux)
  179 {
  180         struct scsi_attach_args         *sa = aux;
  181         struct scsi_inquiry_data        *inq = &sa->sa_sc_link->inqdata;
  182         int                              priority;
  183 
  184         scsi_inqmatch(inq, cd_patterns, nitems(cd_patterns),
  185             sizeof(cd_patterns[0]), &priority);
  186 
  187         return priority;
  188 }
  189 
  190 /*
  191  * The routine called by the low level scsi routine when it discovers
  192  * A device suitable for this driver
  193  */
  194 void
  195 cdattach(struct device *parent, struct device *self, void *aux)
  196 {
  197         struct cd_softc                 *sc = (struct cd_softc *)self;
  198         struct scsi_attach_args         *sa = aux;
  199         struct scsi_link                *link = sa->sa_sc_link;
  200 
  201         SC_DEBUG(link, SDEV_DB2, ("cdattach:\n"));
  202 
  203         /*
  204          * Store information needed to contact our base driver
  205          */
  206         sc->sc_link = link;
  207         link->interpret_sense = cd_interpret_sense;
  208         link->device_softc = sc;
  209         if (link->openings > CDOUTSTANDING)
  210                 link->openings = CDOUTSTANDING;
  211 
  212         /*
  213          * Initialize disk structures.
  214          */
  215         sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
  216         bufq_init(&sc->sc_bufq, BUFQ_DEFAULT);
  217 
  218         printf("\n");
  219 
  220         scsi_xsh_set(&sc->sc_xsh, link, cdstart);
  221 
  222         /* Attach disk. */
  223         sc->sc_dk.dk_flags = DKF_NOLABELREAD;
  224         disk_attach(&sc->sc_dev, &sc->sc_dk);
  225 }
  226 
  227 
  228 int
  229 cdactivate(struct device *self, int act)
  230 {
  231         struct cd_softc *sc = (struct cd_softc *)self;
  232 
  233         switch (act) {
  234         case DVACT_RESUME:
  235                 /*
  236                  * When resuming, hardware may have forgotten we locked it. So
  237                  * if there are any open partitions, lock the CD.
  238                  */
  239                 if (sc->sc_dk.dk_openmask != 0)
  240                         scsi_prevent(sc->sc_link, PR_PREVENT,
  241                             SCSI_IGNORE_ILLEGAL_REQUEST |
  242                             SCSI_IGNORE_MEDIA_CHANGE |
  243                             SCSI_SILENT | SCSI_AUTOCONF);
  244                 break;
  245         case DVACT_DEACTIVATE:
  246                 SET(sc->sc_flags, CDF_DYING);
  247                 scsi_xsh_del(&sc->sc_xsh);
  248                 break;
  249         }
  250         return 0;
  251 }
  252 
  253 int
  254 cddetach(struct device *self, int flags)
  255 {
  256         struct cd_softc *sc = (struct cd_softc *)self;
  257 
  258         bufq_drain(&sc->sc_bufq);
  259 
  260         disk_gone(cdopen, self->dv_unit);
  261 
  262         /* Detach disk. */
  263         bufq_destroy(&sc->sc_bufq);
  264         disk_detach(&sc->sc_dk);
  265 
  266         return 0;
  267 }
  268 
  269 /*
  270  * Open the device. Make sure the partition info is as up-to-date as can be.
  271  */
  272 int
  273 cdopen(dev_t dev, int flag, int fmt, struct proc *p)
  274 {
  275         struct scsi_link        *link;
  276         struct cd_softc         *sc;
  277         int                      error = 0, part, rawopen, unit;
  278 
  279         unit = DISKUNIT(dev);
  280         part = DISKPART(dev);
  281 
  282         rawopen = (part == RAW_PART) && (fmt == S_IFCHR);
  283 
  284         sc = cdlookup(unit);
  285         if (sc == NULL)
  286                 return ENXIO;
  287         if (ISSET(sc->sc_flags, CDF_DYING)) {
  288                 device_unref(&sc->sc_dev);
  289                 return ENXIO;
  290         }
  291 
  292         link = sc->sc_link;
  293         SC_DEBUG(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 = disk_lock(&sc->sc_dk)) != 0) {
  298                 device_unref(&sc->sc_dev);
  299                 return error;
  300         }
  301 
  302         if (sc->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 (!ISSET(link->flags, SDEV_MEDIA_LOADED)) {
  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                 SET(link->flags, SDEV_OPEN);
  322 
  323                 error = scsi_test_unit_ready(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(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(link, PR_PREVENT,
  343                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE |
  344                     SCSI_SILENT);
  345                 if (error)
  346                         goto bad;
  347 
  348                 /* Load the physical device parameters. */
  349                 SET(link->flags, SDEV_MEDIA_LOADED);
  350                 if (cd_get_parms(sc, (rawopen ? SCSI_SILENT : 0) |
  351                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE)) {
  352                         CLR(link->flags, SDEV_MEDIA_LOADED);
  353                         error = ENXIO;
  354                         goto bad;
  355                 }
  356                 SC_DEBUG(link, SDEV_DB3, ("Params loaded\n"));
  357 
  358                 /* Fabricate a disk label. */
  359                 cdgetdisklabel(dev, sc, sc->sc_dk.dk_label, 0);
  360                 SC_DEBUG(link, SDEV_DB3, ("Disklabel fabricated\n"));
  361         }
  362 
  363 out:
  364         if ((error = disk_openpart(&sc->sc_dk, part, fmt, 1)) != 0)
  365                 goto bad;
  366 
  367         SET(link->flags, SDEV_OPEN);
  368         SC_DEBUG(link, SDEV_DB3, ("open complete\n"));
  369 
  370         /* It's OK to fall through because dk_openmask is now non-zero. */
  371 bad:
  372         if (sc->sc_dk.dk_openmask == 0) {
  373                 scsi_prevent(link, PR_ALLOW,
  374                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_MEDIA_CHANGE |
  375                     SCSI_SILENT);
  376                 CLR(link->flags, SDEV_OPEN | SDEV_MEDIA_LOADED);
  377         }
  378 
  379         disk_unlock(&sc->sc_dk);
  380         device_unref(&sc->sc_dev);
  381         return error;
  382 }
  383 
  384 /*
  385  * Close the device. Only called if we are the last occurrence of an open
  386  * device.
  387  */
  388 int
  389 cdclose(dev_t dev, int flag, int fmt, struct proc *p)
  390 {
  391         struct cd_softc         *sc;
  392         int                      part = DISKPART(dev);
  393 
  394         sc = cdlookup(DISKUNIT(dev));
  395         if (sc == NULL)
  396                 return ENXIO;
  397         if (ISSET(sc->sc_flags, CDF_DYING)) {
  398                 device_unref(&sc->sc_dev);
  399                 return ENXIO;
  400         }
  401 
  402         disk_lock_nointr(&sc->sc_dk);
  403 
  404         disk_closepart(&sc->sc_dk, part, fmt);
  405 
  406         if (sc->sc_dk.dk_openmask == 0) {
  407                 /* XXXX Must wait for I/O to complete! */
  408 
  409                 scsi_prevent(sc->sc_link, PR_ALLOW,
  410                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY |
  411                     SCSI_SILENT);
  412                 CLR(sc->sc_link->flags, SDEV_OPEN | SDEV_MEDIA_LOADED);
  413 
  414                 if (ISSET(sc->sc_link->flags, SDEV_EJECTING)) {
  415                         scsi_start(sc->sc_link, SSS_STOP|SSS_LOEJ, 0);
  416 
  417                         CLR(sc->sc_link->flags, SDEV_EJECTING);
  418                 }
  419 
  420                 scsi_xsh_del(&sc->sc_xsh);
  421         }
  422 
  423         disk_unlock(&sc->sc_dk);
  424 
  425         device_unref(&sc->sc_dev);
  426         return 0;
  427 }
  428 
  429 /*
  430  * Actually translate the requested transfer into one the physical driver can
  431  * understand.  The transfer is described by a buf and will include only one
  432  * physical transfer.
  433  */
  434 void
  435 cdstrategy(struct buf *bp)
  436 {
  437         struct cd_softc         *sc;
  438         int                      s;
  439 
  440         sc = cdlookup(DISKUNIT(bp->b_dev));
  441         if (sc == NULL) {
  442                 bp->b_error = ENXIO;
  443                 goto bad;
  444         }
  445         if (ISSET(sc->sc_flags, CDF_DYING)) {
  446                 bp->b_error = ENXIO;
  447                 goto bad;
  448         }
  449 
  450         SC_DEBUG(sc->sc_link, SDEV_DB2, ("cdstrategy: %ld bytes @ blk %lld\n",
  451             bp->b_bcount, (long long)bp->b_blkno));
  452         /*
  453          * If the device has been made invalid, error out
  454          * maybe the media changed, or no media loaded
  455          */
  456         if (!ISSET(sc->sc_link->flags, SDEV_MEDIA_LOADED)) {
  457                 bp->b_error = EIO;
  458                 goto bad;
  459         }
  460 
  461         /* Validate the request. */
  462         if (bounds_check_with_label(bp, sc->sc_dk.dk_label) == -1)
  463                 goto done;
  464 
  465         /* Place it in the queue of disk activities for this disk. */
  466         bufq_queue(&sc->sc_bufq, bp);
  467 
  468         /*
  469          * Tell the device to get going on the transfer if it's
  470          * not doing anything, otherwise just wait for completion
  471          */
  472         scsi_xsh_add(&sc->sc_xsh);
  473 
  474         device_unref(&sc->sc_dev);
  475         return;
  476 
  477 bad:
  478         SET(bp->b_flags, B_ERROR);
  479         bp->b_resid = bp->b_bcount;
  480 done:
  481         s = splbio();
  482         biodone(bp);
  483         splx(s);
  484         if (sc != NULL)
  485                 device_unref(&sc->sc_dev);
  486 }
  487 
  488 int
  489 cd_cmd_rw6(struct scsi_generic *generic, int read, u_int64_t secno,
  490     u_int32_t nsecs)
  491 {
  492         struct scsi_rw *cmd = (struct scsi_rw *)generic;
  493 
  494         cmd->opcode = read ? READ_COMMAND : WRITE_COMMAND;
  495         _lto3b(secno, cmd->addr);
  496         cmd->length = nsecs & 0xff;
  497 
  498         return sizeof(*cmd);
  499 }
  500 
  501 int
  502 cd_cmd_rw10(struct scsi_generic *generic, int read, u_int64_t secno,
  503     u_int32_t nsecs)
  504 {
  505         struct scsi_rw_10 *cmd = (struct scsi_rw_10 *)generic;
  506 
  507         cmd->opcode = read ? READ_10 : WRITE_10;
  508         _lto4b(secno, cmd->addr);
  509         _lto2b(nsecs, cmd->length);
  510 
  511         return sizeof(*cmd);
  512 }
  513 
  514 int
  515 cd_cmd_rw12(struct scsi_generic *generic, int read, u_int64_t secno,
  516     u_int32_t nsecs)
  517 {
  518         struct scsi_rw_12 *cmd = (struct scsi_rw_12 *)generic;
  519 
  520         cmd->opcode = read ? READ_12 : WRITE_12;
  521         _lto4b(secno, cmd->addr);
  522         _lto4b(nsecs, cmd->length);
  523 
  524         return sizeof(*cmd);
  525 }
  526 
  527 /*
  528  * cdstart looks to see if there is a buf waiting for the device
  529  * and that the device is not already busy. If both are true,
  530  * It dequeues the buf and creates a scsi command to perform the
  531  * transfer in the buf. The transfer request will call scsi_done
  532  * on completion, which will in turn call this routine again
  533  * so that the next queued transfer is performed.
  534  * The bufs are queued by the strategy routine (cdstrategy)
  535  *
  536  * This routine is also called after other non-queued requests
  537  * have been made of the scsi driver, to ensure that the queue
  538  * continues to be drained.
  539  *
  540  * must be called at the correct (highish) spl level
  541  * cdstart() is called at splbio from cdstrategy and scsi_done
  542  */
  543 void
  544 cdstart(struct scsi_xfer *xs)
  545 {
  546         struct scsi_link        *link = xs->sc_link;
  547         struct cd_softc         *sc = link->device_softc;
  548         struct buf              *bp;
  549         struct partition        *p;
  550         u_int64_t                secno;
  551         u_int32_t                nsecs;
  552         int                      read;
  553 
  554         SC_DEBUG(link, SDEV_DB2, ("cdstart\n"));
  555 
  556         if (ISSET(sc->sc_flags, CDF_DYING)) {
  557                 scsi_xs_put(xs);
  558                 return;
  559         }
  560 
  561         if (!ISSET(link->flags, SDEV_MEDIA_LOADED)) {
  562                 bufq_drain(&sc->sc_bufq);
  563                 scsi_xs_put(xs);
  564                 return;
  565         }
  566 
  567         bp = bufq_dequeue(&sc->sc_bufq);
  568         if (bp == NULL) {
  569                 scsi_xs_put(xs);
  570                 return;
  571         }
  572         read = ISSET(bp->b_flags, B_READ);
  573 
  574         SET(xs->flags, (read ? SCSI_DATA_IN : SCSI_DATA_OUT));
  575         xs->timeout = 30000;
  576         xs->data = bp->b_data;
  577         xs->datalen = bp->b_bcount;
  578         xs->done = cd_buf_done;
  579         xs->cookie = bp;
  580         xs->bp = bp;
  581 
  582         p = &sc->sc_dk.dk_label->d_partitions[DISKPART(bp->b_dev)];
  583         secno = DL_GETPOFFSET(p) + DL_BLKTOSEC(sc->sc_dk.dk_label, bp->b_blkno);
  584         nsecs = howmany(bp->b_bcount, sc->sc_dk.dk_label->d_secsize);
  585 
  586         if (!ISSET(link->flags, SDEV_ATAPI | SDEV_UMASS) &&
  587             (SID_ANSII_REV(&link->inqdata) < SCSI_REV_2) &&
  588             ((secno & 0x1fffff) == secno) &&
  589             ((nsecs & 0xff) == nsecs))
  590                 xs->cmdlen = cd_cmd_rw6(&xs->cmd, read, secno, nsecs);
  591         else if (((secno & 0xffffffff) == secno) &&
  592             ((nsecs & 0xffff) == nsecs))
  593                 xs->cmdlen = cd_cmd_rw10(&xs->cmd, read, secno, nsecs);
  594         else
  595                 xs->cmdlen = cd_cmd_rw12(&xs->cmd, read, secno, nsecs);
  596 
  597         disk_busy(&sc->sc_dk);
  598         scsi_xs_exec(xs);
  599 
  600         /* Move onto the next io. */
  601         if (bufq_peek(&sc->sc_bufq))
  602                 scsi_xsh_add(&sc->sc_xsh);
  603 }
  604 
  605 void
  606 cd_buf_done(struct scsi_xfer *xs)
  607 {
  608         struct cd_softc         *sc = xs->sc_link->device_softc;
  609         struct buf              *bp = xs->cookie;
  610         int                      error, s;
  611 
  612         switch (xs->error) {
  613         case XS_NOERROR:
  614                 bp->b_error = 0;
  615                 CLR(bp->b_flags, B_ERROR);
  616                 bp->b_resid = xs->resid;
  617                 break;
  618 
  619         case XS_SENSE:
  620         case XS_SHORTSENSE:
  621                 SC_DEBUG_SENSE(xs);
  622                 error = cd_interpret_sense(xs);
  623                 if (error == 0) {
  624                         bp->b_error = 0;
  625                         CLR(bp->b_flags, B_ERROR);
  626                         bp->b_resid = xs->resid;
  627                         break;
  628                 }
  629                 if (error != ERESTART)
  630                         xs->retries = 0;
  631                 goto retry;
  632 
  633         case XS_BUSY:
  634                 if (xs->retries) {
  635                         if (scsi_delay(xs, 1) != ERESTART)
  636                                 xs->retries = 0;
  637                 }
  638                 goto retry;
  639 
  640         case XS_TIMEOUT:
  641 retry:
  642                 if (xs->retries--) {
  643                         scsi_xs_exec(xs);
  644                         return;
  645                 }
  646                 /* FALLTHROUGH */
  647 
  648         default:
  649                 bp->b_error = EIO;
  650                 SET(bp->b_flags, B_ERROR);
  651                 bp->b_resid = bp->b_bcount;
  652                 break;
  653         }
  654 
  655         disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid, bp->b_blkno,
  656             bp->b_flags & B_READ);
  657 
  658         s = splbio();
  659         biodone(bp);
  660         splx(s);
  661         scsi_xs_put(xs);
  662 }
  663 
  664 void
  665 cdminphys(struct buf *bp)
  666 {
  667         struct scsi_link        *link;
  668         struct cd_softc         *sc;
  669         long                     max;
  670 
  671         sc = cdlookup(DISKUNIT(bp->b_dev));
  672         if (sc == NULL)
  673                 return;
  674         link = sc->sc_link;
  675 
  676         /*
  677          * If the device is ancient, we want to make sure that
  678          * the transfer fits into a 6-byte cdb.
  679          *
  680          * XXX Note that the SCSI-I spec says that 256-block transfers
  681          * are allowed in a 6-byte read/write, and are specified
  682          * by setting the "length" to 0.  However, we're conservative
  683          * here, allowing only 255-block transfers in case an
  684          * ancient device gets confused by length == 0.  A length of 0
  685          * in a 10-byte read/write actually means 0 blocks.
  686          */
  687         if (!ISSET(link->flags, SDEV_ATAPI | SDEV_UMASS) &&
  688             SID_ANSII_REV(&link->inqdata) < SCSI_REV_2) {
  689                 max = sc->sc_dk.dk_label->d_secsize * 0xff;
  690 
  691                 if (bp->b_bcount > max)
  692                         bp->b_bcount = max;
  693         }
  694 
  695         if (link->bus->sb_adapter->dev_minphys != NULL)
  696                 (*link->bus->sb_adapter->dev_minphys)(bp, link);
  697         else
  698                 minphys(bp);
  699 
  700         device_unref(&sc->sc_dev);
  701 }
  702 
  703 int
  704 cdread(dev_t dev, struct uio *uio, int ioflag)
  705 {
  706         return physio(cdstrategy, dev, B_READ, cdminphys, uio);
  707 }
  708 
  709 int
  710 cdwrite(dev_t dev, struct uio *uio, int ioflag)
  711 {
  712         return physio(cdstrategy, dev, B_WRITE, cdminphys, uio);
  713 }
  714 
  715 /*
  716  * Perform special action on behalf of the user.
  717  * Knows about the internals of this device
  718  */
  719 int
  720 cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  721 {
  722         struct cd_softc         *sc;
  723         struct disklabel        *lp;
  724         int                      part = DISKPART(dev);
  725         int                      error = 0;
  726 
  727         sc = cdlookup(DISKUNIT(dev));
  728         if (sc == NULL)
  729                 return ENXIO;
  730         if (ISSET(sc->sc_flags, CDF_DYING)) {
  731                 device_unref(&sc->sc_dev);
  732                 return ENXIO;
  733         }
  734 
  735         SC_DEBUG(sc->sc_link, SDEV_DB2, ("cdioctl 0x%lx\n", cmd));
  736 
  737         /*
  738          * If the device is not valid.. abandon ship
  739          */
  740         if (!ISSET(sc->sc_link->flags, SDEV_MEDIA_LOADED)) {
  741                 switch (cmd) {
  742                 case DIOCLOCK:
  743                 case DIOCEJECT:
  744                 case SCIOCIDENTIFY:
  745                 case SCIOCCOMMAND:
  746                 case SCIOCDEBUG:
  747                 case CDIOCLOADUNLOAD:
  748                 case SCIOCRESET:
  749                 case CDIOCGETVOL:
  750                 case CDIOCSETVOL:
  751                 case CDIOCSETMONO:
  752                 case CDIOCSETSTEREO:
  753                 case CDIOCSETMUTE:
  754                 case CDIOCSETLEFT:
  755                 case CDIOCSETRIGHT:
  756                 case CDIOCCLOSE:
  757                 case CDIOCEJECT:
  758                 case CDIOCALLOW:
  759                 case CDIOCPREVENT:
  760                 case CDIOCSETDEBUG:
  761                 case CDIOCCLRDEBUG:
  762                 case CDIOCRESET:
  763                 case DVD_AUTH:
  764                 case DVD_READ_STRUCT:
  765                 case MTIOCTOP:
  766                         if (part == RAW_PART)
  767                                 break;
  768                 /* FALLTHROUGH */
  769                 default:
  770                         if (!ISSET(sc->sc_link->flags, SDEV_OPEN))
  771                                 error = ENODEV;
  772                         else
  773                                 error = EIO;
  774                         goto exit;
  775                 }
  776         }
  777 
  778         switch (cmd) {
  779         case DIOCRLDINFO:
  780                 lp = malloc(sizeof(*lp), M_TEMP, M_WAITOK);
  781                 cdgetdisklabel(dev, sc, lp, 0);
  782                 memcpy(sc->sc_dk.dk_label, lp, sizeof(*lp));
  783                 free(lp, M_TEMP, sizeof(*lp));
  784                 break;
  785 
  786         case DIOCGPDINFO:
  787                 cdgetdisklabel(dev, sc, (struct disklabel *)addr, 1);
  788                 break;
  789 
  790         case DIOCGDINFO:
  791                 *(struct disklabel *)addr = *(sc->sc_dk.dk_label);
  792                 break;
  793 
  794         case DIOCGPART:
  795                 ((struct partinfo *)addr)->disklab = sc->sc_dk.dk_label;
  796                 ((struct partinfo *)addr)->part =
  797                     &sc->sc_dk.dk_label->d_partitions[DISKPART(dev)];
  798                 break;
  799 
  800         case DIOCWDINFO:
  801         case DIOCSDINFO:
  802                 if (!ISSET(flag, FWRITE)) {
  803                         error = EBADF;
  804                         break;
  805                 }
  806 
  807                 if ((error = disk_lock(&sc->sc_dk)) != 0)
  808                         break;
  809 
  810                 error = setdisklabel(sc->sc_dk.dk_label,
  811                     (struct disklabel *)addr, sc->sc_dk.dk_openmask);
  812                 if (error == 0) {
  813                 }
  814 
  815                 disk_unlock(&sc->sc_dk);
  816                 break;
  817 
  818         case CDIOCPLAYTRACKS: {
  819                 struct ioc_play_track *args = (struct ioc_play_track *)addr;
  820 
  821                 if ((error = cd_set_pa_immed(sc, 0)) != 0)
  822                         break;
  823                 error = cd_play_tracks(sc, args->start_track,
  824                     args->start_index, args->end_track, args->end_index);
  825                 break;
  826         }
  827         case CDIOCPLAYMSF: {
  828                 struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
  829 
  830                 if ((error = cd_set_pa_immed(sc, 0)) != 0)
  831                         break;
  832                 error = cd_play_msf(sc, args->start_m, args->start_s,
  833                     args->start_f, args->end_m, args->end_s, args->end_f);
  834                 break;
  835         }
  836         case CDIOCPLAYBLOCKS: {
  837                 struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
  838 
  839                 if ((error = cd_set_pa_immed(sc, 0)) != 0)
  840                         break;
  841                 error = cd_play(sc, args->blk, args->len);
  842                 break;
  843         }
  844         case CDIOCREADSUBCHANNEL: {
  845                 struct ioc_read_subchannel *args =
  846                     (struct ioc_read_subchannel *)addr;
  847                 struct cd_sub_channel_info *data;
  848                 int len = args->data_len;
  849 
  850                 if (len > sizeof(*data) ||
  851                     len < sizeof(struct cd_sub_channel_header)) {
  852                         error = EINVAL;
  853                         break;
  854                 }
  855                 data = dma_alloc(sizeof(*data), PR_WAITOK);
  856                 error = cd_read_subchannel(sc, args->address_format,
  857                     args->data_format, args->track, data, len);
  858                 if (error) {
  859                         dma_free(data, sizeof(*data));
  860                         break;
  861                 }
  862                 len = min(len, _2btol(data->header.data_len) +
  863                     sizeof(struct cd_sub_channel_header));
  864                 error = copyout(data, args->data, len);
  865                 dma_free(data, sizeof(*data));
  866                 break;
  867         }
  868         case CDIOREADTOCHEADER: {
  869                 struct ioc_toc_header *th;
  870 
  871                 th = dma_alloc(sizeof(*th), PR_WAITOK);
  872                 if ((error = cd_read_toc(sc, 0, 0, th, sizeof(*th), 0)) != 0) {
  873                         dma_free(th, sizeof(*th));
  874                         break;
  875                 }
  876                 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC))
  877                         th->len = letoh16(th->len);
  878                 else
  879                         th->len = betoh16(th->len);
  880                 if (th->len > 0)
  881                         memcpy(addr, th, sizeof(*th));
  882                 else
  883                         error = EIO;
  884                 dma_free(th, sizeof(*th));
  885                 break;
  886         }
  887         case CDIOREADTOCENTRYS: {
  888                 struct cd_toc *toc;
  889                 struct ioc_read_toc_entry *te =
  890                     (struct ioc_read_toc_entry *)addr;
  891                 struct ioc_toc_header *th;
  892                 struct cd_toc_entry *cte;
  893                 int len = te->data_len;
  894                 int ntracks;
  895 
  896                 toc = dma_alloc(sizeof(*toc), PR_WAITOK | PR_ZERO);
  897 
  898                 th = &toc->header;
  899 
  900                 if (len > sizeof(toc->entries) ||
  901                     len < sizeof(struct cd_toc_entry)) {
  902                         dma_free(toc, sizeof(*toc));
  903                         error = EINVAL;
  904                         break;
  905                 }
  906                 error = cd_read_toc(sc, te->address_format, te->starting_track,
  907                     toc, len + sizeof(struct ioc_toc_header), 0);
  908                 if (error) {
  909                         dma_free(toc, sizeof(*toc));
  910                         break;
  911                 }
  912                 if (te->address_format == CD_LBA_FORMAT)
  913                         for (ntracks =
  914                             th->ending_track - th->starting_track + 1;
  915                             ntracks >= 0; ntracks--) {
  916                                 cte = &toc->entries[ntracks];
  917                                 cte->addr_type = CD_LBA_FORMAT;
  918                                 if (ISSET(sc->sc_link->quirks,
  919                                     ADEV_LITTLETOC)) {
  920 #if BYTE_ORDER == BIG_ENDIAN
  921                                         swap16_multi((u_int16_t *)&cte->addr,
  922                                             sizeof(cte->addr) / 2);
  923 #endif /* BYTE_ORDER == BIG_ENDIAN */
  924                                 } else
  925                                         cte->addr.lba = betoh32(cte->addr.lba);
  926                         }
  927                 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)) {
  928                         th->len = letoh16(th->len);
  929                 } else
  930                         th->len = betoh16(th->len);
  931                 len = min(len, th->len - (sizeof(th->starting_track) +
  932                     sizeof(th->ending_track)));
  933 
  934                 error = copyout(toc->entries, te->data, len);
  935                 dma_free(toc, sizeof(*toc));
  936                 break;
  937         }
  938         case CDIOREADMSADDR: {
  939                 struct cd_toc *toc;
  940                 int sessno = *(int *)addr;
  941                 struct cd_toc_entry *cte;
  942 
  943                 if (sessno != 0) {
  944                         error = EINVAL;
  945                         break;
  946                 }
  947 
  948                 toc = dma_alloc(sizeof(*toc), PR_WAITOK | PR_ZERO);
  949 
  950                 error = cd_read_toc(sc, 0, 0, toc,
  951                     sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry),
  952                     0x40 /* control word for "get MS info" */);
  953 
  954                 if (error) {
  955                         dma_free(toc, sizeof(*toc));
  956                         break;
  957                 }
  958 
  959                 cte = &toc->entries[0];
  960                 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC)) {
  961 #if BYTE_ORDER == BIG_ENDIAN
  962                         swap16_multi((u_int16_t *)&cte->addr,
  963                             sizeof(cte->addr) / 2);
  964 #endif /* BYTE_ORDER == BIG_ENDIAN */
  965                 } else
  966                         cte->addr.lba = betoh32(cte->addr.lba);
  967                 if (ISSET(sc->sc_link->quirks, ADEV_LITTLETOC))
  968                         toc->header.len = letoh16(toc->header.len);
  969                 else
  970                         toc->header.len = betoh16(toc->header.len);
  971 
  972                 *(int *)addr = (toc->header.len >= 10 && cte->track > 1) ?
  973                         cte->addr.lba : 0;
  974                 dma_free(toc, sizeof(*toc));
  975                 break;
  976         }
  977         case CDIOCSETPATCH: {
  978                 struct ioc_patch *arg = (struct ioc_patch *)addr;
  979 
  980                 error = cd_setchan(sc, arg->patch[0], arg->patch[1],
  981                     arg->patch[2], arg->patch[3], 0);
  982                 break;
  983         }
  984         case CDIOCGETVOL: {
  985                 struct ioc_vol *arg = (struct ioc_vol *)addr;
  986 
  987                 error = cd_getvol(sc, arg, 0);
  988                 break;
  989         }
  990         case CDIOCSETVOL: {
  991                 struct ioc_vol *arg = (struct ioc_vol *)addr;
  992 
  993                 error = cd_setvol(sc, arg, 0);
  994                 break;
  995         }
  996 
  997         case CDIOCSETMONO:
  998                 error = cd_setchan(sc, BOTH_CHANNEL, BOTH_CHANNEL, MUTE_CHANNEL,
  999                     MUTE_CHANNEL, 0);
 1000                 break;
 1001 
 1002         case CDIOCSETSTEREO:
 1003                 error = cd_setchan(sc, LEFT_CHANNEL, RIGHT_CHANNEL,
 1004                     MUTE_CHANNEL, MUTE_CHANNEL, 0);
 1005                 break;
 1006 
 1007         case CDIOCSETMUTE:
 1008                 error = cd_setchan(sc, MUTE_CHANNEL, MUTE_CHANNEL, MUTE_CHANNEL,
 1009                     MUTE_CHANNEL, 0);
 1010                 break;
 1011 
 1012         case CDIOCSETLEFT:
 1013                 error = cd_setchan(sc, LEFT_CHANNEL, LEFT_CHANNEL, MUTE_CHANNEL,
 1014                     MUTE_CHANNEL, 0);
 1015                 break;
 1016 
 1017         case CDIOCSETRIGHT:
 1018                 error = cd_setchan(sc, RIGHT_CHANNEL, RIGHT_CHANNEL,
 1019                     MUTE_CHANNEL, MUTE_CHANNEL, 0);
 1020                 break;
 1021 
 1022         case CDIOCRESUME:
 1023                 error = cd_pause(sc, 1);
 1024                 break;
 1025 
 1026         case CDIOCPAUSE:
 1027                 error = cd_pause(sc, 0);
 1028                 break;
 1029         case CDIOCSTART:
 1030                 error = scsi_start(sc->sc_link, SSS_START, 0);
 1031                 break;
 1032 
 1033         case CDIOCSTOP:
 1034                 error = scsi_start(sc->sc_link, SSS_STOP, 0);
 1035                 break;
 1036 
 1037 close_tray:
 1038         case CDIOCCLOSE:
 1039                 error = scsi_start(sc->sc_link, SSS_START|SSS_LOEJ,
 1040                     SCSI_IGNORE_NOT_READY | SCSI_IGNORE_MEDIA_CHANGE);
 1041                 break;
 1042 
 1043         case MTIOCTOP:
 1044                 if (((struct mtop *)addr)->mt_op == MTRETEN)
 1045                         goto close_tray;
 1046                 if (((struct mtop *)addr)->mt_op != MTOFFL) {
 1047                         error = EIO;
 1048                         break;
 1049                 }
 1050                 /* FALLTHROUGH */
 1051         case CDIOCEJECT: /* FALLTHROUGH */
 1052         case DIOCEJECT:
 1053                 SET(sc->sc_link->flags, SDEV_EJECTING);
 1054                 break;
 1055         case CDIOCALLOW:
 1056                 error = scsi_prevent(sc->sc_link, PR_ALLOW, 0);
 1057                 break;
 1058         case CDIOCPREVENT:
 1059                 error = scsi_prevent(sc->sc_link, PR_PREVENT, 0);
 1060                 break;
 1061         case DIOCLOCK:
 1062                 error = scsi_prevent(sc->sc_link,
 1063                     (*(int *)addr) ? PR_PREVENT : PR_ALLOW, 0);
 1064                 break;
 1065         case CDIOCSETDEBUG:
 1066                 SET(sc->sc_link->flags, SDEV_DB1 | SDEV_DB2);
 1067                 break;
 1068         case CDIOCCLRDEBUG:
 1069                 CLR(sc->sc_link->flags, SDEV_DB1 | SDEV_DB2);
 1070                 break;
 1071         case CDIOCRESET:
 1072         case SCIOCRESET:
 1073                 error = cd_reset(sc);
 1074                 break;
 1075         case CDIOCLOADUNLOAD: {
 1076                 struct ioc_load_unload *args = (struct ioc_load_unload *)addr;
 1077 
 1078                 error = cd_load_unload(sc, args->options, args->slot);
 1079                 break;
 1080         }
 1081 
 1082         case DVD_AUTH:
 1083                 error = dvd_auth(sc, (union dvd_authinfo *)addr);
 1084                 break;
 1085         case DVD_READ_STRUCT:
 1086                 error = dvd_read_struct(sc, (union dvd_struct *)addr);
 1087                 break;
 1088         default:
 1089                 if (DISKPART(dev) != RAW_PART) {
 1090                         error = ENOTTY;
 1091                         break;
 1092                 }
 1093                 error = scsi_do_ioctl(sc->sc_link, cmd, addr, flag);
 1094                 break;
 1095         }
 1096 
 1097 exit:
 1098 
 1099         device_unref(&sc->sc_dev);
 1100         return error;
 1101 }
 1102 
 1103 /*
 1104  * Load the label information on the named device
 1105  * Actually fabricate a disklabel
 1106  *
 1107  * EVENTUALLY take information about different
 1108  * data tracks from the TOC and put it in the disklabel
 1109  */
 1110 int
 1111 cdgetdisklabel(dev_t dev, struct cd_softc *sc, struct disklabel *lp,
 1112     int spoofonly)
 1113 {
 1114         struct cd_toc           *toc;
 1115         int                      tocidx, n, audioonly = 1;
 1116 
 1117         bzero(lp, sizeof(struct disklabel));
 1118 
 1119         lp->d_secsize = sc->params.secsize;
 1120         lp->d_ntracks = 1;
 1121         lp->d_nsectors = 100;
 1122         lp->d_secpercyl = 100;
 1123         lp->d_ncylinders = (sc->params.disksize / 100) + 1;
 1124 
 1125         if (ISSET(sc->sc_link->flags, SDEV_ATAPI)) {
 1126                 strncpy(lp->d_typename, "ATAPI CD-ROM", sizeof(lp->d_typename));
 1127                 lp->d_type = DTYPE_ATAPI;
 1128         } else {
 1129                 strncpy(lp->d_typename, "SCSI CD-ROM", sizeof(lp->d_typename));
 1130                 lp->d_type = DTYPE_SCSI;
 1131         }
 1132 
 1133         strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
 1134         DL_SETDSIZE(lp, sc->params.disksize);
 1135         lp->d_version = 1;
 1136 
 1137         lp->d_magic = DISKMAGIC;
 1138         lp->d_magic2 = DISKMAGIC;
 1139         lp->d_checksum = dkcksum(lp);
 1140 
 1141         toc = dma_alloc(sizeof(*toc), PR_WAITOK | PR_ZERO);
 1142         if (cd_load_toc(sc, toc, CD_LBA_FORMAT)) {
 1143                 audioonly = 0; /* No valid TOC found == not an audio CD. */
 1144                 goto done;
 1145         }
 1146 
 1147         n = toc->header.ending_track - toc->header.starting_track + 1;
 1148         for (tocidx = 0; tocidx < n; tocidx++)
 1149                 if (toc->entries[tocidx].control & 4) {
 1150                         audioonly = 0; /* Found a non-audio track. */
 1151                         goto done;
 1152                 }
 1153 
 1154 done:
 1155         dma_free(toc, sizeof(*toc));
 1156 
 1157         if (audioonly)
 1158                 return 0;
 1159         return readdisklabel(DISKLABELDEV(dev), cdstrategy, lp, spoofonly);
 1160 }
 1161 
 1162 int
 1163 cd_setchan(struct cd_softc *sc, int p0, int p1, int p2, int p3, int flags)
 1164 {
 1165         union scsi_mode_sense_buf       *data;
 1166         struct cd_audio_page            *audio = NULL;
 1167         int                              error, big;
 1168 
 1169         data = dma_alloc(sizeof(*data), PR_NOWAIT);
 1170         if (data == NULL)
 1171                 return ENOMEM;
 1172 
 1173         error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE, data,
 1174             (void **)&audio, sizeof(*audio), flags, &big);
 1175         if (error == 0 && audio == NULL)
 1176                 error = EIO;
 1177 
 1178         if (error == 0) {
 1179                 audio->port[LEFT_PORT].channels = p0;
 1180                 audio->port[RIGHT_PORT].channels = p1;
 1181                 audio->port[2].channels = p2;
 1182                 audio->port[3].channels = p3;
 1183                 if (big)
 1184                         error = scsi_mode_select_big(sc->sc_link, SMS_PF,
 1185                             &data->hdr_big, flags, 20000);
 1186                 else
 1187                         error = scsi_mode_select(sc->sc_link, SMS_PF,
 1188                             &data->hdr, flags, 20000);
 1189         }
 1190 
 1191         dma_free(data, sizeof(*data));
 1192         return error;
 1193 }
 1194 
 1195 int
 1196 cd_getvol(struct cd_softc *sc, struct ioc_vol *arg, int flags)
 1197 {
 1198         union scsi_mode_sense_buf       *data;
 1199         struct cd_audio_page            *audio = NULL;
 1200         int                              big, error;
 1201 
 1202         data = dma_alloc(sizeof(*data), PR_NOWAIT);
 1203         if (data == NULL)
 1204                 return ENOMEM;
 1205 
 1206         error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE, data,
 1207             (void **)&audio, sizeof(*audio), flags, &big);
 1208         if (error == 0 && audio == NULL)
 1209                 error = EIO;
 1210 
 1211         if (error == 0) {
 1212                 arg->vol[0] = audio->port[0].volume;
 1213                 arg->vol[1] = audio->port[1].volume;
 1214                 arg->vol[2] = audio->port[2].volume;
 1215                 arg->vol[3] = audio->port[3].volume;
 1216         }
 1217 
 1218         dma_free(data, sizeof(*data));
 1219         return 0;
 1220 }
 1221 
 1222 int
 1223 cd_setvol(struct cd_softc *sc, const struct ioc_vol *arg, int flags)
 1224 {
 1225         union scsi_mode_sense_buf       *data;
 1226         struct cd_audio_page            *audio = NULL;
 1227         u_int8_t                         mask_volume[4];
 1228         int                              error, big;
 1229 
 1230         data = dma_alloc(sizeof(*data), PR_NOWAIT);
 1231         if (data == NULL)
 1232                 return ENOMEM;
 1233 
 1234         error = scsi_do_mode_sense(sc->sc_link,
 1235             AUDIO_PAGE | SMS_PAGE_CTRL_CHANGEABLE, data, (void **)&audio,
 1236             sizeof(*audio), flags, &big);
 1237         if (error == 0 && audio == NULL)
 1238                 error = EIO;
 1239         if (error != 0) {
 1240                 dma_free(data, sizeof(*data));
 1241                 return error;
 1242         }
 1243 
 1244         mask_volume[0] = audio->port[0].volume;
 1245         mask_volume[1] = audio->port[1].volume;
 1246         mask_volume[2] = audio->port[2].volume;
 1247         mask_volume[3] = audio->port[3].volume;
 1248 
 1249         error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE, data,
 1250             (void **)&audio, sizeof(*audio), flags, &big);
 1251         if (error == 0 && audio == NULL)
 1252                 error = EIO;
 1253         if (error != 0) {
 1254                 dma_free(data, sizeof(*data));
 1255                 return error;
 1256         }
 1257 
 1258         audio->port[0].volume = arg->vol[0] & mask_volume[0];
 1259         audio->port[1].volume = arg->vol[1] & mask_volume[1];
 1260         audio->port[2].volume = arg->vol[2] & mask_volume[2];
 1261         audio->port[3].volume = arg->vol[3] & mask_volume[3];
 1262 
 1263         if (big)
 1264                 error = scsi_mode_select_big(sc->sc_link, SMS_PF,
 1265                     &data->hdr_big, flags, 20000);
 1266         else
 1267                 error = scsi_mode_select(sc->sc_link, SMS_PF,
 1268                     &data->hdr, flags, 20000);
 1269 
 1270         dma_free(data, sizeof(*data));
 1271         return error;
 1272 }
 1273 
 1274 int
 1275 cd_load_unload(struct cd_softc *sc, int options, int slot)
 1276 {
 1277         struct scsi_load_unload         *cmd;
 1278         struct scsi_xfer                *xs;
 1279         int                              error;
 1280 
 1281         xs = scsi_xs_get(sc->sc_link, 0);
 1282         if (xs == NULL)
 1283                 return ENOMEM;
 1284         xs->cmdlen = sizeof(*cmd);
 1285         xs->timeout = 200000;
 1286 
 1287         cmd = (struct scsi_load_unload *)&xs->cmd;
 1288         cmd->opcode = LOAD_UNLOAD;
 1289         cmd->options = options;    /* ioctl uses ATAPI values */
 1290         cmd->slot = slot;
 1291 
 1292         error = scsi_xs_sync(xs);
 1293         scsi_xs_put(xs);
 1294 
 1295         return error;
 1296 }
 1297 
 1298 int
 1299 cd_set_pa_immed(struct cd_softc *sc, int flags)
 1300 {
 1301         union scsi_mode_sense_buf       *data;
 1302         struct cd_audio_page            *audio = NULL;
 1303         int                              error, oflags, big;
 1304 
 1305         if (ISSET(sc->sc_link->flags, SDEV_ATAPI))
 1306                 /* XXX Noop? */
 1307                 return 0;
 1308 
 1309         data = dma_alloc(sizeof(*data), PR_NOWAIT);
 1310         if (data == NULL)
 1311                 return ENOMEM;
 1312 
 1313         error = scsi_do_mode_sense(sc->sc_link, AUDIO_PAGE, data,
 1314             (void **)&audio, sizeof(*audio), flags, &big);
 1315         if (error == 0 && audio == NULL)
 1316                 error = EIO;
 1317 
 1318         if (error == 0) {
 1319                 oflags = audio->flags;
 1320                 CLR(audio->flags, CD_PA_SOTC);
 1321                 SET(audio->flags, CD_PA_IMMED);
 1322                 if (audio->flags != oflags) {
 1323                         if (big)
 1324                                 error = scsi_mode_select_big(sc->sc_link,
 1325                                     SMS_PF, &data->hdr_big, flags, 20000);
 1326                         else
 1327                                 error = scsi_mode_select(sc->sc_link, SMS_PF,
 1328                                     &data->hdr, flags, 20000);
 1329                 }
 1330         }
 1331 
 1332         dma_free(data, sizeof(*data));
 1333         return error;
 1334 }
 1335 
 1336 /*
 1337  * Get scsi driver to send a "start playing" command
 1338  */
 1339 int
 1340 cd_play(struct cd_softc *sc, int secno, int nsecs)
 1341 {
 1342         struct scsi_play        *cmd;
 1343         struct scsi_xfer        *xs;
 1344         int                      error;
 1345 
 1346         xs = scsi_xs_get(sc->sc_link, 0);
 1347         if (xs == NULL)
 1348                 return ENOMEM;
 1349         xs->cmdlen = sizeof(*cmd);
 1350         xs->timeout = 200000;
 1351 
 1352         cmd = (struct scsi_play *)&xs->cmd;
 1353         cmd->opcode = PLAY;
 1354         _lto4b(secno, cmd->blk_addr);
 1355         _lto2b(nsecs, cmd->xfer_len);
 1356 
 1357         error = scsi_xs_sync(xs);
 1358         scsi_xs_put(xs);
 1359 
 1360         return error;
 1361 }
 1362 
 1363 /*
 1364  * Get scsi driver to send a "start playing" command
 1365  */
 1366 int
 1367 cd_play_tracks(struct cd_softc *sc, int strack, int sindex, int etrack,
 1368     int eindex)
 1369 {
 1370         struct cd_toc           *toc;
 1371         int                      error;
 1372         u_char                   endf, ends, endm;
 1373 
 1374         if (!etrack)
 1375                 return EIO;
 1376         if (strack > etrack)
 1377                 return EINVAL;
 1378 
 1379         toc = dma_alloc(sizeof(*toc), PR_WAITOK | PR_ZERO);
 1380 
 1381         if ((error = cd_load_toc(sc, toc, CD_MSF_FORMAT)) != 0)
 1382                 goto done;
 1383 
 1384         if (++etrack > (toc->header.ending_track+1))
 1385                 etrack = toc->header.ending_track+1;
 1386 
 1387         strack -= toc->header.starting_track;
 1388         etrack -= toc->header.starting_track;
 1389         if (strack < 0) {
 1390                 error = EINVAL;
 1391                 goto done;
 1392         }
 1393 
 1394         /*
 1395          * The track ends one frame before the next begins.  The last track
 1396          * is taken care of by the leadoff track.
 1397          */
 1398         endm = toc->entries[etrack].addr.msf.minute;
 1399         ends = toc->entries[etrack].addr.msf.second;
 1400         endf = toc->entries[etrack].addr.msf.frame;
 1401         if (endf-- == 0) {
 1402                 endf = CD_FRAMES - 1;
 1403                 if (ends-- == 0) {
 1404                         ends = CD_SECS - 1;
 1405                         if (endm-- == 0) {
 1406                                 error = EINVAL;
 1407                                 goto done;
 1408                         }
 1409                 }
 1410         }
 1411 
 1412         error = cd_play_msf(sc, toc->entries[strack].addr.msf.minute,
 1413             toc->entries[strack].addr.msf.second,
 1414             toc->entries[strack].addr.msf.frame,
 1415             endm, ends, endf);
 1416 
 1417 done:
 1418         dma_free(toc, sizeof(*toc));
 1419         return error;
 1420 }
 1421 
 1422 /*
 1423  * Get scsi driver to send a "play msf" command
 1424  */
 1425 int
 1426 cd_play_msf(struct cd_softc *sc, int startm, int starts, int startf, int endm,
 1427     int ends, int endf)
 1428 {
 1429         struct scsi_play_msf            *cmd;
 1430         struct scsi_xfer                *xs;
 1431         int                              error;
 1432 
 1433         xs = scsi_xs_get(sc->sc_link, 0);
 1434         if (xs == NULL)
 1435                 return ENOMEM;
 1436         xs->cmdlen = sizeof(*cmd);
 1437         xs->timeout = 20000;
 1438 
 1439         cmd = (struct scsi_play_msf *)&xs->cmd;
 1440         cmd->opcode = PLAY_MSF;
 1441         cmd->start_m = startm;
 1442         cmd->start_s = starts;
 1443         cmd->start_f = startf;
 1444         cmd->end_m = endm;
 1445         cmd->end_s = ends;
 1446         cmd->end_f = endf;
 1447 
 1448         error = scsi_xs_sync(xs);
 1449         scsi_xs_put(xs);
 1450 
 1451         return error;
 1452 }
 1453 
 1454 /*
 1455  * Get scsi driver to send a "start up" command
 1456  */
 1457 int
 1458 cd_pause(struct cd_softc *sc, int go)
 1459 {
 1460         struct scsi_pause               *cmd;
 1461         struct scsi_xfer                *xs;
 1462         int                              error;
 1463 
 1464         xs = scsi_xs_get(sc->sc_link, 0);
 1465         if (xs == NULL)
 1466                 return ENOMEM;
 1467         xs->cmdlen = sizeof(*cmd);
 1468         xs->timeout = 2000;
 1469 
 1470         cmd = (struct scsi_pause *)&xs->cmd;
 1471         cmd->opcode = PAUSE;
 1472         cmd->resume = go;
 1473 
 1474         error = scsi_xs_sync(xs);
 1475         scsi_xs_put(xs);
 1476 
 1477         return error;
 1478 }
 1479 
 1480 /*
 1481  * Get scsi driver to send a "RESET" command
 1482  */
 1483 int
 1484 cd_reset(struct cd_softc *sc)
 1485 {
 1486         struct scsi_xfer                *xs;
 1487         int                              error;
 1488 
 1489         xs = scsi_xs_get(sc->sc_link, SCSI_RESET);
 1490         if (xs == NULL)
 1491                 return ENOMEM;
 1492 
 1493         xs->timeout = 2000;
 1494 
 1495         error = scsi_xs_sync(xs);
 1496         scsi_xs_put(xs);
 1497 
 1498         return error;
 1499 }
 1500 
 1501 /*
 1502  * Read subchannel
 1503  */
 1504 int
 1505 cd_read_subchannel(struct cd_softc *sc, int mode, int format, int track,
 1506     struct cd_sub_channel_info *data, int len)
 1507 {
 1508         struct scsi_read_subchannel     *cmd;
 1509         struct scsi_xfer                *xs;
 1510         int                              error;
 1511 
 1512         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN | SCSI_SILENT);
 1513         if (xs == NULL)
 1514                 return ENOMEM;
 1515         xs->cmdlen = sizeof(*cmd);
 1516         xs->data = (void *)data;
 1517         xs->datalen = len;
 1518         xs->timeout = 5000;
 1519 
 1520         cmd = (struct scsi_read_subchannel *)&xs->cmd;
 1521         cmd->opcode = READ_SUBCHANNEL;
 1522         if (mode == CD_MSF_FORMAT)
 1523                 SET(cmd->byte2, CD_MSF);
 1524         cmd->byte3 = SRS_SUBQ;
 1525         cmd->subchan_format = format;
 1526         cmd->track = track;
 1527         _lto2b(len, cmd->data_len);
 1528 
 1529         error = scsi_xs_sync(xs);
 1530         scsi_xs_put(xs);
 1531 
 1532         return error;
 1533 }
 1534 
 1535 /*
 1536  * Read table of contents
 1537  */
 1538 int
 1539 cd_read_toc(struct cd_softc *sc, int mode, int start, void *data, int len,
 1540     int control)
 1541 {
 1542         struct scsi_read_toc            *cmd;
 1543         struct scsi_xfer                *xs;
 1544         int                              error;
 1545 
 1546         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN |
 1547             SCSI_IGNORE_ILLEGAL_REQUEST);
 1548         if (xs == NULL)
 1549                 return ENOMEM;
 1550         xs->cmdlen = sizeof(*cmd);
 1551         xs->data = data;
 1552         xs->datalen = len;
 1553         xs->timeout = 5000;
 1554 
 1555         bzero(data, len);
 1556 
 1557         cmd = (struct scsi_read_toc *)&xs->cmd;
 1558         cmd->opcode = READ_TOC;
 1559 
 1560         if (mode == CD_MSF_FORMAT)
 1561                 SET(cmd->byte2, CD_MSF);
 1562         cmd->from_track = start;
 1563         _lto2b(len, cmd->data_len);
 1564         cmd->control = control;
 1565 
 1566         error = scsi_xs_sync(xs);
 1567         scsi_xs_put(xs);
 1568 
 1569         return error;
 1570 }
 1571 
 1572 int
 1573 cd_load_toc(struct cd_softc *sc, struct cd_toc *toc, int fmt)
 1574 {
 1575         int     n, len, error;
 1576 
 1577         error = cd_read_toc(sc, 0, 0, toc, sizeof(toc->header), 0);
 1578 
 1579         if (error == 0) {
 1580                 if (toc->header.ending_track < toc->header.starting_track)
 1581                         return EIO;
 1582                 /* +2 to account for leading out track. */
 1583                 n = toc->header.ending_track - toc->header.starting_track + 2;
 1584                 len = n * sizeof(struct cd_toc_entry) + sizeof(toc->header);
 1585                 error = cd_read_toc(sc, fmt, 0, toc, len, 0);
 1586         }
 1587 
 1588         return error;
 1589 }
 1590 
 1591 
 1592 /*
 1593  * Get the scsi driver to send a full inquiry to the device and use the
 1594  * results to fill out the disk parameter structure.
 1595  */
 1596 int
 1597 cd_get_parms(struct cd_softc *sc, int flags)
 1598 {
 1599         /* Reasonable defaults for drives that don't support READ_CAPACITY */
 1600         sc->params.secsize = 2048;
 1601         sc->params.disksize = 400000;
 1602 
 1603         if (ISSET(sc->sc_link->quirks, ADEV_NOCAPACITY))
 1604                 return 0;
 1605 
 1606         sc->params.disksize = cd_size(sc->sc_link, flags, &sc->params.secsize);
 1607 
 1608         if ((sc->params.secsize < 512) ||
 1609             ((sc->params.secsize & 511) != 0))
 1610                 sc->params.secsize = 2048;      /* some drives lie ! */
 1611 
 1612         if (sc->params.disksize < 100)
 1613                 sc->params.disksize = 400000;
 1614 
 1615         return 0;
 1616 }
 1617 
 1618 daddr_t
 1619 cdsize(dev_t dev)
 1620 {
 1621         /* CD-ROMs are read-only. */
 1622         return -1;
 1623 }
 1624 
 1625 int
 1626 cddump(dev_t dev, daddr_t blkno, caddr_t va, size_t size)
 1627 {
 1628         /* Not implemented. */
 1629         return ENXIO;
 1630 }
 1631 
 1632 #define dvd_copy_key(dst, src)          memcpy((dst), (src), DVD_KEY_SIZE)
 1633 #define dvd_copy_challenge(dst, src)    memcpy((dst), (src), DVD_CHALLENGE_SIZE)
 1634 
 1635 #define DVD_AUTH_BUFSIZE                20
 1636 
 1637 int
 1638 dvd_auth(struct cd_softc *sc, union dvd_authinfo *a)
 1639 {
 1640         struct scsi_generic     *cmd;
 1641         struct scsi_xfer        *xs;
 1642         u_int8_t                *buf;
 1643         int                      error;
 1644 
 1645         buf = dma_alloc(DVD_AUTH_BUFSIZE, PR_WAITOK | PR_ZERO);
 1646         if (buf == NULL)
 1647                 return ENOMEM;
 1648 
 1649         xs = scsi_xs_get(sc->sc_link, 0);
 1650         if (xs == NULL) {
 1651                 error = ENOMEM;
 1652                 goto done;
 1653         }
 1654         xs->cmdlen = sizeof(*cmd);
 1655         xs->timeout = 30000;
 1656         xs->data = buf;
 1657 
 1658         cmd = &xs->cmd;
 1659 
 1660         switch (a->type) {
 1661         case DVD_LU_SEND_AGID:
 1662                 cmd->opcode = GPCMD_REPORT_KEY;
 1663                 cmd->bytes[8] = 8;
 1664                 cmd->bytes[9] = 0 | (0 << 6);
 1665                 xs->datalen = 8;
 1666                 SET(xs->flags, SCSI_DATA_IN);
 1667 
 1668                 error = scsi_xs_sync(xs);
 1669                 scsi_xs_put(xs);
 1670 
 1671                 if (error == 0)
 1672                         a->lsa.agid = buf[7] >> 6;
 1673                 break;
 1674 
 1675         case DVD_LU_SEND_CHALLENGE:
 1676                 cmd->opcode = GPCMD_REPORT_KEY;
 1677                 cmd->bytes[8] = 16;
 1678                 cmd->bytes[9] = 1 | (a->lsc.agid << 6);
 1679                 xs->datalen = 16;
 1680                 SET(xs->flags, SCSI_DATA_IN);
 1681 
 1682                 error = scsi_xs_sync(xs);
 1683                 scsi_xs_put(xs);
 1684                 if (error == 0)
 1685                         dvd_copy_challenge(a->lsc.chal, &buf[4]);
 1686                 break;
 1687 
 1688         case DVD_LU_SEND_KEY1:
 1689                 cmd->opcode = GPCMD_REPORT_KEY;
 1690                 cmd->bytes[8] = 12;
 1691                 cmd->bytes[9] = 2 | (a->lsk.agid << 6);
 1692                 xs->datalen = 12;
 1693                 SET(xs->flags, SCSI_DATA_IN);
 1694 
 1695                 error = scsi_xs_sync(xs);
 1696                 scsi_xs_put(xs);
 1697 
 1698                 if (error == 0)
 1699                         dvd_copy_key(a->lsk.key, &buf[4]);
 1700                 break;
 1701 
 1702         case DVD_LU_SEND_TITLE_KEY:
 1703                 cmd->opcode = GPCMD_REPORT_KEY;
 1704                 _lto4b(a->lstk.lba, &cmd->bytes[1]);
 1705                 cmd->bytes[8] = 12;
 1706                 cmd->bytes[9] = 4 | (a->lstk.agid << 6);
 1707                 xs->datalen = 12;
 1708                 SET(xs->flags, SCSI_DATA_IN);
 1709 
 1710                 error = scsi_xs_sync(xs);
 1711                 scsi_xs_put(xs);
 1712 
 1713                 if (error == 0) {
 1714                         a->lstk.cpm = (buf[4] >> 7) & 1;
 1715                         a->lstk.cp_sec = (buf[4] >> 6) & 1;
 1716                         a->lstk.cgms = (buf[4] >> 4) & 3;
 1717                         dvd_copy_key(a->lstk.title_key, &buf[5]);
 1718                 }
 1719                 break;
 1720 
 1721         case DVD_LU_SEND_ASF:
 1722                 cmd->opcode = GPCMD_REPORT_KEY;
 1723                 cmd->bytes[8] = 8;
 1724                 cmd->bytes[9] = 5 | (a->lsasf.agid << 6);
 1725                 xs->datalen = 8;
 1726                 SET(xs->flags, SCSI_DATA_IN);
 1727 
 1728                 error = scsi_xs_sync(xs);
 1729                 scsi_xs_put(xs);
 1730 
 1731                 if (error == 0)
 1732                         a->lsasf.asf = buf[7] & 1;
 1733                 break;
 1734 
 1735         case DVD_HOST_SEND_CHALLENGE:
 1736                 cmd->opcode = GPCMD_SEND_KEY;
 1737                 cmd->bytes[8] = 16;
 1738                 cmd->bytes[9] = 1 | (a->hsc.agid << 6);
 1739                 buf[1] = 14;
 1740                 dvd_copy_challenge(&buf[4], a->hsc.chal);
 1741                 xs->datalen = 16;
 1742                 SET(xs->flags, SCSI_DATA_OUT);
 1743 
 1744                 error = scsi_xs_sync(xs);
 1745                 scsi_xs_put(xs);
 1746 
 1747                 if (error == 0)
 1748                         a->type = DVD_LU_SEND_KEY1;
 1749                 break;
 1750 
 1751         case DVD_HOST_SEND_KEY2:
 1752                 cmd->opcode = GPCMD_SEND_KEY;
 1753                 cmd->bytes[8] = 12;
 1754                 cmd->bytes[9] = 3 | (a->hsk.agid << 6);
 1755                 buf[1] = 10;
 1756                 dvd_copy_key(&buf[4], a->hsk.key);
 1757                 xs->datalen = 12;
 1758                 SET(xs->flags, SCSI_DATA_OUT);
 1759 
 1760                 error = scsi_xs_sync(xs);
 1761                 scsi_xs_put(xs);
 1762 
 1763                 if (error == 0)
 1764                         a->type = DVD_AUTH_ESTABLISHED;
 1765                 else
 1766                         a->type = DVD_AUTH_FAILURE;
 1767                 break;
 1768 
 1769         case DVD_INVALIDATE_AGID:
 1770                 cmd->opcode = GPCMD_REPORT_KEY;
 1771                 cmd->bytes[9] = 0x3f | (a->lsa.agid << 6);
 1772                 xs->data = NULL;
 1773 
 1774                 error = scsi_xs_sync(xs);
 1775                 scsi_xs_put(xs);
 1776                 break;
 1777 
 1778         case DVD_LU_SEND_RPC_STATE:
 1779                 cmd->opcode = GPCMD_REPORT_KEY;
 1780                 cmd->bytes[8] = 8;
 1781                 cmd->bytes[9] = 8 | (0 << 6);
 1782                 xs->datalen = 8;
 1783                 SET(xs->flags, SCSI_DATA_IN);
 1784 
 1785                 error = scsi_xs_sync(xs);
 1786                 scsi_xs_put(xs);
 1787 
 1788                 if (error == 0) {
 1789                         a->lrpcs.type = (buf[4] >> 6) & 3;
 1790                         a->lrpcs.vra = (buf[4] >> 3) & 7;
 1791                         a->lrpcs.ucca = (buf[4]) & 7;
 1792                         a->lrpcs.region_mask = buf[5];
 1793                         a->lrpcs.rpc_scheme = buf[6];
 1794                 }
 1795                 break;
 1796 
 1797         case DVD_HOST_SEND_RPC_STATE:
 1798                 cmd->opcode = GPCMD_SEND_KEY;
 1799                 cmd->bytes[8] = 8;
 1800                 cmd->bytes[9] = 6 | (0 << 6);
 1801                 buf[1] = 6;
 1802                 buf[4] = a->hrpcs.pdrc;
 1803                 xs->datalen = 8;
 1804                 SET(xs->flags, SCSI_DATA_OUT);
 1805 
 1806                 error = scsi_xs_sync(xs);
 1807                 scsi_xs_put(xs);
 1808                 break;
 1809 
 1810         default:
 1811                 scsi_xs_put(xs);
 1812                 error = ENOTTY;
 1813                 break;
 1814         }
 1815 done:
 1816         dma_free(buf, DVD_AUTH_BUFSIZE);
 1817         return error;
 1818 }
 1819 
 1820 #define DVD_READ_PHYSICAL_BUFSIZE (4 + 4 * 20)
 1821 int
 1822 dvd_read_physical(struct cd_softc *sc, union dvd_struct *s)
 1823 {
 1824         struct scsi_generic             *cmd;
 1825         struct dvd_layer                *layer;
 1826         struct scsi_xfer                *xs;
 1827         u_int8_t                        *buf, *bufp;
 1828         int                              error, i;
 1829 
 1830         buf = dma_alloc(DVD_READ_PHYSICAL_BUFSIZE, PR_WAITOK | PR_ZERO);
 1831         if (buf == NULL)
 1832                 return ENOMEM;
 1833 
 1834         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN);
 1835         if (xs == NULL) {
 1836                 error = ENOMEM;
 1837                 goto done;
 1838         }
 1839         xs->cmdlen = sizeof(*cmd);
 1840         xs->data = buf;
 1841         xs->datalen = DVD_READ_PHYSICAL_BUFSIZE;
 1842         xs->timeout = 30000;
 1843 
 1844         cmd = &xs->cmd;
 1845         cmd->opcode = GPCMD_READ_DVD_STRUCTURE;
 1846         cmd->bytes[6] = s->type;
 1847         _lto2b(xs->datalen, &cmd->bytes[7]);
 1848 
 1849         cmd->bytes[5] = s->physical.layer_num;
 1850 
 1851         error = scsi_xs_sync(xs);
 1852         scsi_xs_put(xs);
 1853 
 1854         if (error == 0) {
 1855                 for (i = 0, bufp = &buf[4], layer = &s->physical.layer[0];
 1856                     i < 4; i++, bufp += 20, layer++) {
 1857                         bzero(layer, sizeof(*layer));
 1858                         layer->book_version = bufp[0] & 0xf;
 1859                         layer->book_type = bufp[0] >> 4;
 1860                         layer->min_rate = bufp[1] & 0xf;
 1861                         layer->disc_size = bufp[1] >> 4;
 1862                         layer->layer_type = bufp[2] & 0xf;
 1863                         layer->track_path = (bufp[2] >> 4) & 1;
 1864                         layer->nlayers = (bufp[2] >> 5) & 3;
 1865                         layer->track_density = bufp[3] & 0xf;
 1866                         layer->linear_density = bufp[3] >> 4;
 1867                         layer->start_sector = _4btol(&bufp[4]);
 1868                         layer->end_sector = _4btol(&bufp[8]);
 1869                         layer->end_sector_l0 = _4btol(&bufp[12]);
 1870                         layer->bca = bufp[16] >> 7;
 1871                 }
 1872         }
 1873 done:
 1874         dma_free(buf, DVD_READ_PHYSICAL_BUFSIZE);
 1875         return error;
 1876 }
 1877 
 1878 #define DVD_READ_COPYRIGHT_BUFSIZE      8
 1879 int
 1880 dvd_read_copyright(struct cd_softc *sc, union dvd_struct *s)
 1881 {
 1882         struct scsi_generic             *cmd;
 1883         struct scsi_xfer                *xs;
 1884         u_int8_t                        *buf;
 1885         int                              error;
 1886 
 1887         buf = dma_alloc(DVD_READ_COPYRIGHT_BUFSIZE, PR_WAITOK | PR_ZERO);
 1888         if (buf == NULL)
 1889                 return ENOMEM;
 1890 
 1891         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN);
 1892         if (xs == NULL) {
 1893                 error = ENOMEM;
 1894                 goto done;
 1895         }
 1896         xs->cmdlen = sizeof(*cmd);
 1897         xs->data = buf;
 1898         xs->datalen = DVD_READ_COPYRIGHT_BUFSIZE;
 1899         xs->timeout = 30000;
 1900 
 1901         cmd = &xs->cmd;
 1902         cmd->opcode = GPCMD_READ_DVD_STRUCTURE;
 1903         cmd->bytes[6] = s->type;
 1904         _lto2b(xs->datalen, &cmd->bytes[7]);
 1905 
 1906         cmd->bytes[5] = s->copyright.layer_num;
 1907 
 1908         error = scsi_xs_sync(xs);
 1909         scsi_xs_put(xs);
 1910 
 1911         if (error == 0) {
 1912                 s->copyright.cpst = buf[4];
 1913                 s->copyright.rmi = buf[5];
 1914         }
 1915 done:
 1916         dma_free(buf, DVD_READ_COPYRIGHT_BUFSIZE);
 1917         return error;
 1918 }
 1919 
 1920 int
 1921 dvd_read_disckey(struct cd_softc *sc, union dvd_struct *s)
 1922 {
 1923         struct scsi_read_dvd_structure_data     *buf;
 1924         struct scsi_read_dvd_structure          *cmd;
 1925         struct scsi_xfer                        *xs;
 1926         int                                      error;
 1927 
 1928         buf = dma_alloc(sizeof(*buf), PR_WAITOK | PR_ZERO);
 1929         if (buf == NULL)
 1930                 return ENOMEM;
 1931 
 1932         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN);
 1933         if (xs == NULL) {
 1934                 error = ENOMEM;
 1935                 goto done;
 1936         }
 1937         xs->cmdlen = sizeof(*cmd);
 1938         xs->data = (void *)buf;
 1939         xs->datalen = sizeof(*buf);
 1940         xs->timeout = 30000;
 1941 
 1942         cmd = (struct scsi_read_dvd_structure *)&xs->cmd;
 1943         cmd->opcode = GPCMD_READ_DVD_STRUCTURE;
 1944         cmd->format = s->type;
 1945         cmd->agid = s->disckey.agid << 6;
 1946         _lto2b(xs->datalen, cmd->length);
 1947 
 1948         error = scsi_xs_sync(xs);
 1949         scsi_xs_put(xs);
 1950 
 1951         if (error == 0)
 1952                 memcpy(s->disckey.value, buf->data, sizeof(s->disckey.value));
 1953 done:
 1954         dma_free(buf, sizeof(*buf));
 1955         return error;
 1956 }
 1957 
 1958 #define DVD_READ_BCA_BUFLEN (4 + 188)
 1959 
 1960 int
 1961 dvd_read_bca(struct cd_softc *sc, union dvd_struct *s)
 1962 {
 1963         struct scsi_generic             *cmd;
 1964         struct scsi_xfer                *xs;
 1965         u_int8_t                        *buf;
 1966         int                              error;
 1967 
 1968         buf = dma_alloc(DVD_READ_BCA_BUFLEN, PR_WAITOK | PR_ZERO);
 1969         if (buf == NULL)
 1970                 return ENOMEM;
 1971 
 1972         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN);
 1973         if (xs == NULL) {
 1974                 error = ENOMEM;
 1975                 goto done;
 1976         }
 1977         xs->cmdlen = sizeof(*cmd);
 1978         xs->data = buf;
 1979         xs->datalen = DVD_READ_BCA_BUFLEN;
 1980         xs->timeout = 30000;
 1981 
 1982         cmd = &xs->cmd;
 1983         cmd->opcode = GPCMD_READ_DVD_STRUCTURE;
 1984         cmd->bytes[6] = s->type;
 1985         _lto2b(xs->datalen, &cmd->bytes[7]);
 1986 
 1987         error = scsi_xs_sync(xs);
 1988         scsi_xs_put(xs);
 1989 
 1990         if (error == 0) {
 1991                 s->bca.len = _2btol(&buf[0]);
 1992                 if (s->bca.len < 12 || s->bca.len > 188)
 1993                         return EIO;
 1994                 memcpy(s->bca.value, &buf[4], s->bca.len);
 1995         }
 1996 done:
 1997         dma_free(buf, DVD_READ_BCA_BUFLEN);
 1998         return error;
 1999 }
 2000 
 2001 int
 2002 dvd_read_manufact(struct cd_softc *sc, union dvd_struct *s)
 2003 {
 2004         struct scsi_read_dvd_structure_data     *buf;
 2005         struct scsi_read_dvd_structure          *cmd;
 2006         struct scsi_xfer                        *xs;
 2007         int                                      error;
 2008 
 2009         buf = dma_alloc(sizeof(*buf), PR_WAITOK | PR_ZERO);
 2010         if (buf == NULL)
 2011                 return ENOMEM;
 2012 
 2013         xs = scsi_xs_get(sc->sc_link, SCSI_DATA_IN);
 2014         if (xs == NULL) {
 2015                 error = ENOMEM;
 2016                 goto done;
 2017         }
 2018         xs->cmdlen = sizeof(*cmd);
 2019         xs->data = (void *)buf;
 2020         xs->datalen = sizeof(*buf);
 2021         xs->timeout = 30000;
 2022 
 2023         cmd = (struct scsi_read_dvd_structure *)&xs->cmd;
 2024         cmd->opcode = GPCMD_READ_DVD_STRUCTURE;
 2025         cmd->format = s->type;
 2026         _lto2b(xs->datalen, cmd->length);
 2027 
 2028         error = scsi_xs_sync(xs);
 2029         scsi_xs_put(xs);
 2030 
 2031         if (error == 0) {
 2032                 s->manufact.len = _2btol(buf->len);
 2033                 if (s->manufact.len >= 0 && s->manufact.len <= 2048)
 2034                         memcpy(s->manufact.value, buf->data, s->manufact.len);
 2035                 else
 2036                         error = EIO;
 2037         }
 2038 done:
 2039         dma_free(buf, sizeof(*buf));
 2040         return error;
 2041 }
 2042 
 2043 int
 2044 dvd_read_struct(struct cd_softc *sc, union dvd_struct *s)
 2045 {
 2046         switch (s->type) {
 2047         case DVD_STRUCT_PHYSICAL:
 2048                 return dvd_read_physical(sc, s);
 2049         case DVD_STRUCT_COPYRIGHT:
 2050                 return dvd_read_copyright(sc, s);
 2051         case DVD_STRUCT_DISCKEY:
 2052                 return dvd_read_disckey(sc, s);
 2053         case DVD_STRUCT_BCA:
 2054                 return dvd_read_bca(sc, s);
 2055         case DVD_STRUCT_MANUFACT:
 2056                 return dvd_read_manufact(sc, s);
 2057         default:
 2058                 return EINVAL;
 2059         }
 2060 }
 2061 
 2062 int
 2063 cd_interpret_sense(struct scsi_xfer *xs)
 2064 {
 2065         struct scsi_sense_data          *sense = &xs->sense;
 2066         struct scsi_link                *link = xs->sc_link;
 2067         u_int8_t                         skey = sense->flags & SSD_KEY;
 2068         u_int8_t                         serr = sense->error_code & SSD_ERRCODE;
 2069 
 2070         if (!ISSET(link->flags, SDEV_OPEN) ||
 2071             (serr != SSD_ERRCODE_CURRENT && serr != SSD_ERRCODE_DEFERRED))
 2072                 return scsi_interpret_sense(xs);
 2073 
 2074         /*
 2075          * We do custom processing in cd for the unit becoming ready
 2076          * case.  We do not allow xs->retries to be decremented on the
 2077          * "Unit Becoming Ready" case. This is because CD drives
 2078          * report "Unit Becoming Ready" when loading media and can
 2079          * take a long time.  Rather than having a massive timeout for
 2080          * all operations (which would cause other problems), we allow
 2081          * operations to wait (but be interruptible with Ctrl-C)
 2082          * forever as long as the drive is reporting that it is
 2083          * becoming ready.  All other cases of not being ready are
 2084          * handled by the default handler.
 2085          */
 2086         switch(skey) {
 2087         case SKEY_NOT_READY:
 2088                 if (ISSET(xs->flags, SCSI_IGNORE_NOT_READY))
 2089                         return 0;
 2090                 if (ASC_ASCQ(sense) == SENSE_NOT_READY_BECOMING_READY) {
 2091                         SC_DEBUG(link, SDEV_DB1, ("not ready: busy (%#x)\n",
 2092                             sense->add_sense_code_qual));
 2093                         /* don't count this as a retry */
 2094                         xs->retries++;
 2095                         return scsi_delay(xs, 1);
 2096                 }
 2097                 break;
 2098                 /* XXX more to come here for a few other cases */
 2099         default:
 2100                 break;
 2101         }
 2102         return scsi_interpret_sense(xs);
 2103 }
 2104 
 2105 /*
 2106  * Find out from the device what its capacity is.
 2107  */
 2108 u_int64_t
 2109 cd_size(struct scsi_link *link, int flags, u_int32_t *blksize)
 2110 {
 2111         struct scsi_read_cap_data_16    *rdcap16;
 2112         struct scsi_read_cap_data       *rdcap;
 2113         u_int64_t                        max_addr;
 2114         int                              error;
 2115 
 2116         if (blksize != NULL)
 2117                 *blksize = 0;
 2118 
 2119         CLR(flags, SCSI_IGNORE_ILLEGAL_REQUEST);
 2120 
 2121         /*
 2122          * Start with a READ CAPACITY(10).
 2123          */
 2124         rdcap = dma_alloc(sizeof(*rdcap), ((flags & SCSI_NOSLEEP) ?
 2125             PR_NOWAIT : PR_WAITOK) | PR_ZERO);
 2126         if (rdcap == NULL)
 2127                 return 0;
 2128 
 2129         error = scsi_read_cap_10(link, rdcap, flags);
 2130         if (error) {
 2131                 dma_free(rdcap, sizeof(*rdcap));
 2132                 return 0;
 2133         }
 2134 
 2135         max_addr = _4btol(rdcap->addr);
 2136         if (blksize != NULL)
 2137                 *blksize = _4btol(rdcap->length);
 2138         dma_free(rdcap, sizeof(*rdcap));
 2139 
 2140         /*
 2141          * pre-SPC (i.e. pre-SCSI-3) devices reporting less than 2^32-1 sectors
 2142          * can stop here.
 2143          */
 2144         if (SID_ANSII_REV(&link->inqdata) < SCSI_REV_SPC &&
 2145             max_addr != 0xffffffff)
 2146                 goto exit;
 2147 
 2148         rdcap16 = dma_alloc(sizeof(*rdcap16), ((flags & SCSI_NOSLEEP) ?
 2149             PR_NOWAIT : PR_WAITOK) | PR_ZERO);
 2150         if (rdcap16 == NULL)
 2151                 goto exit;
 2152 
 2153         error = scsi_read_cap_16(link, rdcap16, flags);
 2154         if (error) {
 2155                 dma_free(rdcap16, sizeof(*rdcap16));
 2156                 goto exit;
 2157         }
 2158 
 2159         max_addr = _8btol(rdcap16->addr);
 2160         if (blksize != NULL)
 2161                 *blksize = _4btol(rdcap16->length);
 2162         /* XXX The other READ CAPACITY(16) info could be stored away. */
 2163         dma_free(rdcap16, sizeof(*rdcap16));
 2164 
 2165         return max_addr + 1;
 2166 
 2167 exit:
 2168         /* Return READ CAPACITY 10 values. */
 2169         if (max_addr != 0xffffffff)
 2170                 return max_addr + 1;
 2171         else if (blksize != NULL)
 2172                 *blksize = 0;
 2173         return 0;
 2174 }
 2175 
 2176 #if defined(__macppc__)
 2177 int
 2178 cd_eject(void)
 2179 {
 2180         struct cd_softc                 *sc;
 2181         int                              error = 0;
 2182 
 2183         if (cd_cd.cd_ndevs == 0 || (sc = cd_cd.cd_devs[0]) == NULL)
 2184                 return ENXIO;
 2185 
 2186         if ((error = disk_lock(&sc->sc_dk)) != 0)
 2187                 return error;
 2188 
 2189         if (sc->sc_dk.dk_openmask == 0) {
 2190                 SET(sc->sc_link->flags, SDEV_EJECTING);
 2191 
 2192                 scsi_prevent(sc->sc_link, PR_ALLOW,
 2193                     SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY |
 2194                     SCSI_SILENT | SCSI_IGNORE_MEDIA_CHANGE);
 2195                 CLR(sc->sc_link->flags, SDEV_MEDIA_LOADED);
 2196 
 2197                 scsi_start(sc->sc_link, SSS_STOP|SSS_LOEJ, 0);
 2198 
 2199                 CLR(sc->sc_link->flags, SDEV_EJECTING);
 2200         }
 2201         disk_unlock(&sc->sc_dk);
 2202 
 2203         return error;
 2204 }
 2205 #endif /* __macppc__ */

Cache object: bab909e71e7cbd6d14b335ba39f51ba4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.