LCOV - code coverage report
Current view: top level - scsi - cd.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 1040 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 39 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13