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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/ata/atapi-cd.c

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

    1 /*-
    2  * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer,
   10  *    without modification, immediately at the beginning of the file.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 #include <sys/cdefs.h>
   30 __FBSDID("$FreeBSD$");
   31 
   32 #include "opt_ata.h"
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/ata.h>
   36 #include <sys/kernel.h>
   37 #include <sys/malloc.h>
   38 #include <sys/proc.h>
   39 #include <sys/bio.h>
   40 #include <sys/bus.h>
   41 #include <sys/cdio.h>
   42 #include <sys/cdrio.h>
   43 #include <sys/dvdio.h>
   44 #include <sys/disk.h>
   45 #include <sys/fcntl.h>
   46 #include <sys/conf.h>
   47 #include <sys/ctype.h>
   48 #include <sys/sema.h>
   49 #include <sys/taskqueue.h>
   50 #include <vm/uma.h>
   51 #include <machine/bus.h>
   52 #include <geom/geom.h>
   53 #include <dev/ata/ata-all.h>
   54 #include <dev/ata/atapi-cd.h>
   55 
   56 /* prototypes */
   57 static void acd_detach(struct ata_device *);
   58 static void acd_start(struct ata_device *);
   59 static struct acd_softc *acd_init_lun(struct ata_device *);
   60 static void acd_geom_create(void *, int);
   61 static void acd_set_ioparm(struct acd_softc *);
   62 static void acd_describe(struct acd_softc *);
   63 static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
   64 static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
   65 static int acd_geom_access(struct g_provider *, int, int, int);
   66 static g_ioctl_t acd_geom_ioctl;
   67 static void acd_geom_start(struct bio *);
   68 static void acd_done(struct ata_request *);
   69 static void acd_read_toc(struct acd_softc *);
   70 static int acd_play(struct acd_softc *, int, int);
   71 static int acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
   72 static void acd_select_slot(struct acd_softc *);
   73 static int acd_init_writer(struct acd_softc *, int);
   74 static int acd_fixate(struct acd_softc *, int);
   75 static int acd_init_track(struct acd_softc *, struct cdr_track *);
   76 static int acd_flush(struct acd_softc *);
   77 static int acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info *);
   78 static int acd_get_progress(struct acd_softc *, int *);
   79 static int acd_send_cue(struct acd_softc *, struct cdr_cuesheet *);
   80 static int acd_report_key(struct acd_softc *, struct dvd_authinfo *);
   81 static int acd_send_key(struct acd_softc *, struct dvd_authinfo *);
   82 static int acd_read_structure(struct acd_softc *, struct dvd_struct *);
   83 static int acd_tray(struct acd_softc *, int);
   84 static int acd_blank(struct acd_softc *, int);
   85 static int acd_prevent_allow(struct acd_softc *, int);
   86 static int acd_start_stop(struct acd_softc *, int);
   87 static int acd_pause_resume(struct acd_softc *, int);
   88 static int acd_mode_sense(struct acd_softc *, int, caddr_t, int);
   89 static int acd_mode_select(struct acd_softc *, caddr_t, int);
   90 static int acd_set_speed(struct acd_softc *, int, int);
   91 static void acd_get_cap(struct acd_softc *);
   92 static int acd_read_format_caps(struct acd_softc *, struct cdr_format_capacities *);
   93 static int acd_format(struct acd_softc *, struct cdr_format_params *);
   94 static int acd_test_ready(struct ata_device *);
   95 
   96 /* internal vars */
   97 static u_int32_t acd_lun_map = 0;
   98 static MALLOC_DEFINE(M_ACD, "ACD driver", "ATAPI CD driver buffers");
   99 static struct g_class acd_class = {
  100         .name = "ACD",
  101         .version = G_VERSION,
  102         .access = acd_geom_access,
  103         .ioctl = acd_geom_ioctl,
  104         .start = acd_geom_start,
  105 };
  106 DECLARE_GEOM_CLASS(acd_class, acd);
  107 
  108 void
  109 acd_attach(struct ata_device *atadev)
  110 {
  111     struct acd_softc *cdp;
  112     struct changer *chp;
  113 
  114     if ((cdp = acd_init_lun(atadev)) == NULL) {
  115         ata_prtdev(atadev, "out of memory\n");
  116         return;
  117     }
  118 
  119     ata_set_name(atadev, "acd", cdp->lun);
  120     acd_get_cap(cdp);
  121 
  122     /* if this is a changer device, allocate the neeeded lun's */
  123     if ((cdp->cap.mechanism & MST_MECH_MASK) == MST_MECH_CHANGER) {
  124         int8_t ccb[16] = { ATAPI_MECH_STATUS, 0, 0, 0, 0, 0, 0, 0, 
  125                            sizeof(struct changer)>>8, sizeof(struct changer),
  126                            0, 0, 0, 0, 0, 0 };
  127 
  128         if (!(chp = malloc(sizeof(struct changer), M_ACD, M_NOWAIT | M_ZERO))) {
  129             ata_prtdev(atadev, "out of memory\n");
  130             free(cdp, M_ACD);
  131             return;
  132         }
  133         if (!ata_atapicmd(cdp->device, ccb, (caddr_t)chp, 
  134                           sizeof(struct changer), ATA_R_READ, 60)) {
  135             struct acd_softc *tmpcdp = cdp;
  136             struct acd_softc **cdparr;
  137             char *name;
  138             int count;
  139 
  140             chp->table_length = htons(chp->table_length);
  141             if (!(cdparr = malloc(sizeof(struct acd_softc) * chp->slots,
  142                                   M_ACD, M_NOWAIT))) {
  143                 ata_prtdev(atadev, "out of memory\n");
  144                 free(chp, M_ACD);
  145                 free(cdp, M_ACD);
  146                 return;
  147             }
  148             for (count = 0; count < chp->slots; count++) {
  149                 if (count > 0) {
  150                     tmpcdp = acd_init_lun(atadev);
  151                     if (!tmpcdp) {
  152                         ata_prtdev(atadev, "out of memory\n");
  153                         break;
  154                     }
  155                 }
  156                 cdparr[count] = tmpcdp;
  157                 tmpcdp->driver = cdparr;
  158                 tmpcdp->slot = count;
  159                 tmpcdp->changer_info = chp;
  160                 g_post_event(acd_geom_create, tmpcdp, M_WAITOK, NULL);
  161             }
  162             if (!(name = malloc(strlen(atadev->name) + 2, M_ACD, M_NOWAIT))) {
  163                 ata_prtdev(atadev, "out of memory\n");
  164                 free(cdp, M_ACD);
  165                 return;
  166             }
  167             strcpy(name, atadev->name);
  168             strcat(name, "-");
  169             ata_free_name(atadev);
  170             ata_set_name(atadev, name, cdp->lun + cdp->changer_info->slots - 1);
  171             free(name, M_ACD);
  172         }
  173     }
  174     else 
  175         g_post_event(acd_geom_create, cdp, M_WAITOK, NULL);
  176 
  177     /* setup the function ptrs */
  178     atadev->detach = acd_detach;
  179     atadev->start = acd_start;
  180     atadev->softc = cdp;
  181 
  182     /* announce we are here */
  183     acd_describe(cdp);
  184 }
  185 
  186 static void
  187 acd_geom_detach(void *arg, int flag)
  188 {   
  189     struct ata_device *atadev = arg;
  190     struct acd_softc *cdp = atadev->softc;
  191     int subdev;
  192 
  193     g_wither_geom(cdp->gp, ENXIO);
  194     if (cdp->changer_info) {
  195         for (subdev = 0; subdev < cdp->changer_info->slots; subdev++) {
  196             if (cdp->driver[subdev] == cdp)
  197                 continue;
  198             mtx_lock(&cdp->driver[subdev]->queue_mtx);
  199             bioq_flush(&cdp->driver[subdev]->queue, NULL, ENXIO);
  200             mtx_unlock(&cdp->driver[subdev]->queue_mtx);
  201             ata_free_lun(&acd_lun_map, cdp->driver[subdev]->lun);
  202             free(cdp->driver[subdev], M_ACD);
  203         }
  204         free(cdp->driver, M_ACD);
  205         free(cdp->changer_info, M_ACD);
  206     }
  207     mtx_lock(&cdp->queue_mtx);
  208     bioq_flush(&cdp->queue, NULL, ENXIO);
  209     mtx_unlock(&cdp->queue_mtx);
  210     mtx_destroy(&cdp->queue_mtx);
  211     ata_prtdev(atadev, "WARNING - removed from configuration\n");
  212     ata_free_name(atadev);
  213     ata_free_lun(&acd_lun_map, cdp->lun);
  214     atadev->attach = NULL;
  215     atadev->detach = NULL;
  216     atadev->start = NULL;
  217     atadev->softc = NULL;
  218     atadev->flags = 0;
  219     free(cdp, M_ACD);
  220 }
  221 
  222 static void
  223 acd_detach(struct ata_device *atadev)
  224 {   
  225     g_waitfor_event(acd_geom_detach, atadev, M_WAITOK, NULL);
  226 }
  227 
  228 static struct acd_softc *
  229 acd_init_lun(struct ata_device *atadev)
  230 {
  231     struct acd_softc *cdp;
  232 
  233     if (!(cdp = malloc(sizeof(struct acd_softc), M_ACD, M_NOWAIT | M_ZERO)))
  234         return NULL;
  235     bioq_init(&cdp->queue);
  236     mtx_init(&cdp->queue_mtx, "ATAPI CD bioqueue lock", NULL, MTX_DEF);
  237     cdp->device = atadev;
  238     cdp->lun = ata_get_lun(&acd_lun_map);
  239     cdp->block_size = 2048;
  240     cdp->slot = -1;
  241     cdp->changer_info = NULL;
  242     return cdp;
  243 }
  244 
  245 static void
  246 acd_geom_create(void *arg, int flag)
  247 {
  248     struct acd_softc *cdp;
  249     struct g_geom *gp;
  250     struct g_provider *pp;
  251 
  252     cdp = arg;
  253     g_topology_assert();
  254     gp = g_new_geomf(&acd_class, "acd%d", cdp->lun);
  255     gp->softc = cdp;
  256     cdp->gp = gp;
  257     pp = g_new_providerf(gp, "acd%d", cdp->lun);
  258     pp->index = 0;
  259     cdp->pp[0] = pp;
  260     g_error_provider(pp, 0);
  261     cdp->device->flags |= ATA_D_MEDIA_CHANGED;
  262     acd_set_ioparm(cdp);
  263 }
  264 
  265 static void
  266 acd_set_ioparm(struct acd_softc *cdp)
  267 {
  268 
  269     if (cdp->device->channel->dma)
  270         cdp->iomax = min(cdp->device->channel->dma->max_iosize, 65534);
  271     else
  272         cdp->iomax = min(DFLTPHYS, 65534);
  273 }
  274 
  275 static void 
  276 acd_describe(struct acd_softc *cdp)
  277 {
  278     int comma = 0;
  279     char *mechanism;
  280 
  281     if (bootverbose) {
  282         ata_prtdev(cdp->device, "<%.40s/%.8s> %s drive at ata%d as %s\n",
  283                    cdp->device->param->model, cdp->device->param->revision,
  284                    (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" : 
  285                     (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" : 
  286                      (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" :
  287                       (cdp->cap.media & MST_WRITE_CDR) ? "CDR" : 
  288                        (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM" : "CDROM",
  289                    device_get_unit(cdp->device->channel->dev),
  290                    (cdp->device->unit == ATA_MASTER) ? "master" : "slave");
  291 
  292         ata_prtdev(cdp->device, "%s", "");
  293         if (cdp->cap.cur_read_speed) {
  294             printf("read %dKB/s", cdp->cap.cur_read_speed * 1000 / 1024);
  295             if (cdp->cap.max_read_speed) 
  296                 printf(" (%dKB/s)", cdp->cap.max_read_speed * 1000 / 1024);
  297             if ((cdp->cap.cur_write_speed) &&
  298                 (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW |
  299                                    MST_WRITE_DVDR | MST_WRITE_DVDRAM))) {
  300                 printf(" write %dKB/s", cdp->cap.cur_write_speed * 1000 / 1024);
  301                 if (cdp->cap.max_write_speed)
  302                     printf(" (%dKB/s)", cdp->cap.max_write_speed * 1000 / 1024);
  303             }
  304             comma = 1;
  305         }
  306         if (cdp->cap.buf_size) {
  307             printf("%s %dKB buffer", comma ? "," : "", cdp->cap.buf_size);
  308             comma = 1;
  309         }
  310         printf("%s %s\n", comma ? "," : "", ata_mode2str(cdp->device->mode));
  311 
  312         ata_prtdev(cdp->device, "Reads:");
  313         comma = 0;
  314         if (cdp->cap.media & MST_READ_CDR) {
  315             printf(" CDR"); comma = 1;
  316         }
  317         if (cdp->cap.media & MST_READ_CDRW) {
  318             printf("%s CDRW", comma ? "," : ""); comma = 1;
  319         }
  320         if (cdp->cap.capabilities & MST_READ_CDDA) {
  321             if (cdp->cap.capabilities & MST_CDDA_STREAM)
  322                 printf("%s CDDA stream", comma ? "," : "");
  323             else
  324                 printf("%s CDDA", comma ? "," : "");
  325             comma = 1;
  326         }
  327         if (cdp->cap.media & MST_READ_DVDROM) {
  328             printf("%s DVDROM", comma ? "," : ""); comma = 1;
  329         }
  330         if (cdp->cap.media & MST_READ_DVDR) {
  331             printf("%s DVDR", comma ? "," : ""); comma = 1;
  332         }
  333         if (cdp->cap.media & MST_READ_DVDRAM) {
  334             printf("%s DVDRAM", comma ? "," : ""); comma = 1;
  335         }
  336         if (cdp->cap.media & MST_READ_PACKET)
  337             printf("%s packet", comma ? "," : "");
  338 
  339         printf("\n");
  340         ata_prtdev(cdp->device, "Writes:");
  341         if (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW |
  342                               MST_WRITE_DVDR | MST_WRITE_DVDRAM)) {
  343             comma = 0;
  344             if (cdp->cap.media & MST_WRITE_CDR) {
  345                 printf(" CDR" ); comma = 1;
  346             }
  347             if (cdp->cap.media & MST_WRITE_CDRW) {
  348                 printf("%s CDRW", comma ? "," : ""); comma = 1;
  349             }
  350             if (cdp->cap.media & MST_WRITE_DVDR) {
  351                 printf("%s DVDR", comma ? "," : ""); comma = 1;
  352             }
  353             if (cdp->cap.media & MST_WRITE_DVDRAM) {
  354                 printf("%s DVDRAM", comma ? "," : ""); comma = 1; 
  355             }
  356             if (cdp->cap.media & MST_WRITE_TEST) {
  357                 printf("%s test write", comma ? "," : ""); comma = 1;
  358             }
  359             if (cdp->cap.capabilities & MST_BURNPROOF)
  360                 printf("%s burnproof", comma ? "," : "");
  361         }
  362         printf("\n");
  363         if (cdp->cap.capabilities & MST_AUDIO_PLAY) {
  364             ata_prtdev(cdp->device, "Audio: ");
  365             if (cdp->cap.capabilities & MST_AUDIO_PLAY)
  366                 printf("play");
  367             if (cdp->cap.max_vol_levels)
  368                 printf(", %d volume levels", cdp->cap.max_vol_levels);
  369             printf("\n");
  370         }
  371         ata_prtdev(cdp->device, "Mechanism: ");
  372         switch (cdp->cap.mechanism & MST_MECH_MASK) {
  373         case MST_MECH_CADDY:
  374             mechanism = "caddy"; break;
  375         case MST_MECH_TRAY:
  376             mechanism = "tray"; break;
  377         case MST_MECH_POPUP:
  378             mechanism = "popup"; break;
  379         case MST_MECH_CHANGER:
  380             mechanism = "changer"; break;
  381         case MST_MECH_CARTRIDGE:
  382             mechanism = "cartridge"; break;
  383         default:
  384             mechanism = 0; break;
  385         }
  386         if (mechanism)
  387             printf("%s%s", (cdp->cap.mechanism & MST_EJECT) ?
  388                    "ejectable " : "", mechanism);
  389         else if (cdp->cap.mechanism & MST_EJECT)
  390             printf("ejectable");
  391 
  392         if (cdp->cap.mechanism & MST_LOCKABLE)
  393             printf((cdp->cap.mechanism & MST_LOCKED) ? ", locked":", unlocked");
  394         if (cdp->cap.mechanism & MST_PREVENT)
  395             printf(", lock protected");
  396         printf("\n");
  397 
  398         if ((cdp->cap.mechanism & MST_MECH_MASK) != MST_MECH_CHANGER) {
  399             ata_prtdev(cdp->device, "Medium: ");
  400             switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) {
  401             case MST_CDROM:
  402                 printf("CD-ROM "); break;
  403             case MST_CDR:
  404                 printf("CD-R "); break;
  405             case MST_CDRW:
  406                 printf("CD-RW "); break;
  407             case MST_DOOR_OPEN:
  408                 printf("door open"); break;
  409             case MST_NO_DISC:
  410                 printf("no/blank disc"); break;
  411             case MST_FMT_ERROR:
  412                 printf("medium format error"); break;
  413             }
  414             if ((cdp->cap.medium_type & MST_TYPE_MASK_HIGH)<MST_TYPE_MASK_HIGH){
  415                 switch (cdp->cap.medium_type & MST_TYPE_MASK_LOW) {
  416                 case MST_DATA_120:
  417                     printf("120mm data disc"); break;
  418                 case MST_AUDIO_120:
  419                     printf("120mm audio disc"); break;
  420                 case MST_COMB_120:
  421                     printf("120mm data/audio disc"); break;
  422                 case MST_PHOTO_120:
  423                     printf("120mm photo disc"); break;
  424                 case MST_DATA_80:
  425                     printf("80mm data disc"); break;
  426                 case MST_AUDIO_80:
  427                     printf("80mm audio disc"); break;
  428                 case MST_COMB_80:
  429                     printf("80mm data/audio disc"); break;
  430                 case MST_PHOTO_80:
  431                     printf("80mm photo disc"); break;
  432                 case MST_FMT_NONE:
  433                     switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) {
  434                     case MST_CDROM:
  435                         printf("unknown"); break;
  436                     case MST_CDR:
  437                     case MST_CDRW:
  438                         printf("blank"); break;
  439                     }
  440                     break;
  441                 default:
  442                     printf("unknown (0x%x)", cdp->cap.medium_type); break;
  443                 }
  444             }
  445             printf("\n");
  446         }
  447     }
  448     else {
  449         ata_prtdev(cdp->device, "%s ",
  450                    (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" : 
  451                     (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" : 
  452                      (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" :
  453                       (cdp->cap.media & MST_WRITE_CDR) ? "CDR" : 
  454                        (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM" : "CDROM");
  455         if (cdp->changer_info)
  456             printf("with %d CD changer ", cdp->changer_info->slots);
  457         printf("<%.40s/%.8s> at ata%d-%s %s\n",
  458                cdp->device->param->model, cdp->device->param->revision,
  459                device_get_unit(cdp->device->channel->dev),
  460                (cdp->device->unit == ATA_MASTER) ? "master" : "slave",
  461                ata_mode2str(cdp->device->mode) );
  462     }
  463 }
  464 
  465 static __inline void 
  466 lba2msf(u_int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f)
  467 {
  468     lba += 150;
  469     lba &= 0xffffff;
  470     *m = lba / (60 * 75);
  471     lba %= (60 * 75);
  472     *s = lba / 75;
  473     *f = lba % 75;
  474 }
  475 
  476 static __inline u_int32_t 
  477 msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
  478 {
  479     return (m * 60 + s) * 75 + f - 150;
  480 }
  481 
  482 static int
  483 acd_geom_access(struct g_provider *pp, int dr, int dw, int de)
  484 {
  485     struct acd_softc *cdp;
  486     struct ata_request *request;
  487     int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
  488                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  489     int timeout = 60, track;
  490 
  491     
  492     cdp = pp->geom->softc;
  493     if (cdp->device->flags & ATA_D_DETACHING)
  494         return ENXIO;
  495 
  496     if (!(request = ata_alloc_request()))
  497         return ENOMEM;
  498 
  499     /* wait if drive is not finished loading the medium */
  500     while (timeout--) {
  501         bzero(request, sizeof(struct ata_request));
  502         request->device = cdp->device;
  503         request->driver = cdp;
  504         bcopy(ccb, request->u.atapi.ccb, 16);
  505         request->flags = ATA_R_ATAPI;
  506         request->timeout = 5;
  507         ata_queue_request(request);
  508         if (!request->error &&
  509             (request->u.atapi.sense_data.sense_key == 2 ||
  510              request->u.atapi.sense_data.sense_key == 7) &&
  511             request->u.atapi.sense_data.asc == 4 &&
  512             request->u.atapi.sense_data.ascq == 1)
  513             tsleep(&timeout, PRIBIO, "acdld", hz / 2);
  514         else
  515             break;
  516     }
  517     ata_free_request(request);
  518 
  519     if (pp->acr == 0) {
  520         if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  521             acd_select_slot(cdp);
  522             tsleep(&cdp->changer_info, PRIBIO, "acdopn", 0);
  523         }
  524         acd_prevent_allow(cdp, 1);
  525         cdp->flags |= F_LOCKED;
  526         acd_read_toc(cdp);
  527     }
  528 
  529     if (dr + pp->acr == 0) {
  530         if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  531             acd_select_slot(cdp);
  532             tsleep(&cdp->changer_info, PRIBIO, "acdclo", 0);
  533         }
  534         acd_prevent_allow(cdp, 0);
  535         cdp->flags &= ~F_LOCKED;
  536     }
  537 
  538     if ((track = pp->index)) {
  539         pp->sectorsize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
  540         pp->mediasize = ntohl(cdp->toc.tab[track].addr.lba) -
  541                         ntohl(cdp->toc.tab[track - 1].addr.lba);
  542     }
  543     else {
  544         pp->sectorsize = cdp->block_size;
  545         pp->mediasize = cdp->disk_size;
  546     }
  547     pp->mediasize *= pp->sectorsize;
  548 
  549     return 0;
  550 }
  551 
  552 static int 
  553 acd_geom_ioctl(struct g_provider *pp, u_long cmd, void *addr, int fflag, struct thread *td)
  554 {
  555     struct acd_softc *cdp = pp->geom->softc;
  556     int error = 0;
  557 
  558     if (!cdp)
  559         return ENXIO;
  560 
  561     if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
  562         acd_select_slot(cdp);
  563         tsleep(&cdp->changer_info, PRIBIO, "acdctl", 0);
  564     }
  565     if (cdp->device->flags & ATA_D_MEDIA_CHANGED)
  566         switch (cmd) {
  567         case CDIOCRESET:
  568             acd_test_ready(cdp->device);
  569             break;
  570            
  571         default:
  572             acd_read_toc(cdp);
  573             acd_prevent_allow(cdp, 1);
  574             cdp->flags |= F_LOCKED;
  575             break;
  576         }
  577     switch (cmd) {
  578 
  579     case CDIOCRESUME:
  580         error = acd_pause_resume(cdp, 1);
  581         break;
  582 
  583     case CDIOCPAUSE:
  584         error = acd_pause_resume(cdp, 0);
  585         break;
  586 
  587     case CDIOCSTART:
  588         error = acd_start_stop(cdp, 1);
  589         break;
  590 
  591     case CDIOCSTOP:
  592         error = acd_start_stop(cdp, 0);
  593         break;
  594 
  595     case CDIOCALLOW:
  596         error = acd_prevent_allow(cdp, 0);
  597         cdp->flags &= ~F_LOCKED;
  598         break;
  599 
  600     case CDIOCPREVENT:
  601         error = acd_prevent_allow(cdp, 1);
  602         cdp->flags |= F_LOCKED;
  603         break;
  604 
  605     case CDIOCRESET:
  606         error = suser(td);
  607         if (error)
  608             break;
  609         error = acd_test_ready(cdp->device);
  610         break;
  611 
  612     case CDIOCEJECT:
  613         if (pp->acr != 1) {
  614             error = EBUSY;
  615             break;
  616         }
  617         error = acd_tray(cdp, 0);
  618         break;
  619 
  620     case CDIOCCLOSE:
  621         if (pp->acr != 1)
  622             break;
  623         error = acd_tray(cdp, 1);
  624         break;
  625 
  626     case CDIOREADTOCHEADER:
  627         if (!cdp->toc.hdr.ending_track) {
  628             error = EIO;
  629             break;
  630         }
  631         bcopy(&cdp->toc.hdr, addr, sizeof(cdp->toc.hdr));
  632         break;
  633 
  634     case CDIOREADTOCENTRYS:
  635         {
  636             struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr;
  637             struct toc *toc = &cdp->toc;
  638             int starting_track = te->starting_track;
  639             int len;
  640 
  641             if (!toc->hdr.ending_track) {
  642                 error = EIO;
  643                 break;
  644             }
  645 
  646             if (te->data_len < sizeof(toc->tab[0]) || 
  647                 (te->data_len % sizeof(toc->tab[0])) != 0 || 
  648                 (te->address_format != CD_MSF_FORMAT &&
  649                 te->address_format != CD_LBA_FORMAT)) {
  650                 error = EINVAL;
  651                 break;
  652             }
  653 
  654             if (!starting_track)
  655                 starting_track = toc->hdr.starting_track;
  656             else if (starting_track == 170) 
  657                 starting_track = toc->hdr.ending_track + 1;
  658             else if (starting_track < toc->hdr.starting_track ||
  659                      starting_track > toc->hdr.ending_track + 1) {
  660                 error = EINVAL;
  661                 break;
  662             }
  663 
  664             len = ((toc->hdr.ending_track + 1 - starting_track) + 1) *
  665                   sizeof(toc->tab[0]);
  666             if (te->data_len < len)
  667                 len = te->data_len;
  668             if (len > sizeof(toc->tab)) {
  669                 error = EINVAL;
  670                 break;
  671             }
  672 
  673             if (te->address_format == CD_MSF_FORMAT) {
  674                 struct cd_toc_entry *entry;
  675 
  676                 if (!(toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT))) {
  677                     error = ENOMEM;
  678                     break;
  679                 }
  680                 bcopy(&cdp->toc, toc, sizeof(struct toc));
  681                 entry = toc->tab + (toc->hdr.ending_track + 1 -
  682                         toc->hdr.starting_track) + 1;
  683                 while (--entry >= toc->tab)
  684                     lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute,
  685                             &entry->addr.msf.second, &entry->addr.msf.frame);
  686             }
  687             error = copyout(toc->tab + starting_track - toc->hdr.starting_track,
  688                             te->data, len);
  689             if (te->address_format == CD_MSF_FORMAT)
  690                 free(toc, M_ACD);
  691         }
  692         break;
  693 
  694     case CDIOREADTOCENTRY:
  695         {
  696             struct ioc_read_toc_single_entry *te =
  697                 (struct ioc_read_toc_single_entry *)addr;
  698             struct toc *toc = &cdp->toc;
  699             u_char track = te->track;
  700 
  701             if (!toc->hdr.ending_track) {
  702                 error = EIO;
  703                 break;
  704             }
  705 
  706             if (te->address_format != CD_MSF_FORMAT && 
  707                 te->address_format != CD_LBA_FORMAT) {
  708                 error = EINVAL;
  709                 break;
  710             }
  711 
  712             if (!track)
  713                 track = toc->hdr.starting_track;
  714             else if (track == 170)
  715                 track = toc->hdr.ending_track + 1;
  716             else if (track < toc->hdr.starting_track ||
  717                      track > toc->hdr.ending_track + 1) {
  718                 error = EINVAL;
  719                 break;
  720             }
  721 
  722             if (te->address_format == CD_MSF_FORMAT) {
  723                 struct cd_toc_entry *entry;
  724 
  725                 if (!(toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT))) {
  726                     error = ENOMEM;
  727                     break;
  728                 }
  729                 bcopy(&cdp->toc, toc, sizeof(struct toc));
  730                 entry = toc->tab + (track - toc->hdr.starting_track);
  731                 lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute,
  732                         &entry->addr.msf.second, &entry->addr.msf.frame);
  733             }
  734             bcopy(toc->tab + track - toc->hdr.starting_track,
  735                   &te->entry, sizeof(struct cd_toc_entry));
  736             if (te->address_format == CD_MSF_FORMAT)
  737                 free(toc, M_ACD);
  738         }
  739         break;
  740 
  741     case CDIOCREADSUBCHANNEL:
  742         {
  743             struct ioc_read_subchannel *args =
  744                 (struct ioc_read_subchannel *)addr;
  745             u_int8_t format;
  746             int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0,
  747                                sizeof(cdp->subchan)>>8, sizeof(cdp->subchan),
  748                                0, 0, 0, 0, 0, 0, 0 };
  749 
  750             if (args->data_len > sizeof(struct cd_sub_channel_info) ||
  751                 args->data_len < sizeof(struct cd_sub_channel_header)) {
  752                 error = EINVAL;
  753                 break;
  754             }
  755 
  756             format = args->data_format;
  757             if ((format != CD_CURRENT_POSITION) &&
  758                 (format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) {
  759                 error = EINVAL;
  760                 break;
  761             }
  762 
  763             ccb[1] = args->address_format & CD_MSF_FORMAT;
  764 
  765             if ((error = ata_atapicmd(cdp->device, ccb, (caddr_t)&cdp->subchan,
  766                                       sizeof(cdp->subchan), ATA_R_READ, 10)))
  767                 break;
  768 
  769             if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) {
  770                 if (cdp->subchan.header.audio_status == 0x11) {
  771                     error = EINVAL;
  772                     break;
  773                 }
  774 
  775                 ccb[3] = format;
  776                 if (format == CD_TRACK_INFO)
  777                     ccb[6] = args->track;
  778 
  779                 if ((error = ata_atapicmd(cdp->device, ccb,
  780                                           (caddr_t)&cdp->subchan, 
  781                                           sizeof(cdp->subchan),ATA_R_READ,10))){
  782                     break;
  783                 }
  784             }
  785             error = copyout(&cdp->subchan, args->data, args->data_len);
  786         }
  787         break;
  788 
  789     case CDIOCPLAYMSF:
  790         {
  791             struct ioc_play_msf *args = (struct ioc_play_msf *)addr;
  792 
  793             error = 
  794                 acd_play(cdp, 
  795                          msf2lba(args->start_m, args->start_s, args->start_f),
  796                          msf2lba(args->end_m, args->end_s, args->end_f));
  797         }
  798         break;
  799 
  800     case CDIOCPLAYBLOCKS:
  801         {
  802             struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr;
  803 
  804             error = acd_play(cdp, args->blk, args->blk + args->len);
  805         }
  806         break;
  807 
  808     case CDIOCPLAYTRACKS:
  809         {
  810             struct ioc_play_track *args = (struct ioc_play_track *)addr;
  811             int t1, t2;
  812 
  813             if (!cdp->toc.hdr.ending_track) {
  814                 error = EIO;
  815                 break;
  816             }
  817             if (args->end_track < cdp->toc.hdr.ending_track + 1)
  818                 ++args->end_track;
  819             if (args->end_track > cdp->toc.hdr.ending_track + 1)
  820                 args->end_track = cdp->toc.hdr.ending_track + 1;
  821             t1 = args->start_track - cdp->toc.hdr.starting_track;
  822             t2 = args->end_track - cdp->toc.hdr.starting_track;
  823             if (t1 < 0 || t2 < 0 ||
  824                 t1 > (cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track)) {
  825                 error = EINVAL;
  826                 break;
  827             }
  828             error = acd_play(cdp, ntohl(cdp->toc.tab[t1].addr.lba),
  829                              ntohl(cdp->toc.tab[t2].addr.lba));
  830         }
  831         break;
  832 
  833     case CDIOCGETVOL:
  834         {
  835             struct ioc_vol *arg = (struct ioc_vol *)addr;
  836 
  837             if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
  838                                         (caddr_t)&cdp->au, sizeof(cdp->au))))
  839                 break;
  840 
  841             if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
  842                 error = EIO;
  843                 break;
  844             }
  845             arg->vol[0] = cdp->au.port[0].volume;
  846             arg->vol[1] = cdp->au.port[1].volume;
  847             arg->vol[2] = cdp->au.port[2].volume;
  848             arg->vol[3] = cdp->au.port[3].volume;
  849         }
  850         break;
  851 
  852     case CDIOCSETVOL:
  853         {
  854             struct ioc_vol *arg = (struct ioc_vol *)addr;
  855 
  856             if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE,
  857                                         (caddr_t)&cdp->au, sizeof(cdp->au))))
  858                 break;
  859             if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE) {
  860                 error = EIO;
  861                 break;
  862             }
  863             if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE_MASK,
  864                                         (caddr_t)&cdp->aumask,
  865                                         sizeof(cdp->aumask))))
  866                 break;
  867             cdp->au.data_length = 0;
  868             cdp->au.port[0].channels = CHANNEL_0;
  869             cdp->au.port[1].channels = CHANNEL_1;
  870             cdp->au.port[0].volume = arg->vol[0] & cdp->aumask.port[0].volume;
  871             cdp->au.port[1].volume = arg->vol[1] & cdp->aumask.port[1].volume;
  872             cdp->au.port[2].volume = arg->vol[2] & cdp->aumask.port[2].volume;
  873             cdp->au.port[3].volume = arg->vol[3] & cdp->aumask.port[3].volume;
  874             error =  acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
  875         }
  876         break;
  877 
  878     case CDIOCSETPATCH:
  879         {
  880             struct ioc_patch *arg = (struct ioc_patch *)addr;
  881 
  882             error = acd_setchan(cdp, arg->patch[0], arg->patch[1],
  883                                 arg->patch[2], arg->patch[3]);
  884         }
  885         break;
  886 
  887     case CDIOCSETMONO:
  888         error = acd_setchan(cdp, CHANNEL_0|CHANNEL_1, CHANNEL_0|CHANNEL_1, 0,0);
  889         break;
  890 
  891     case CDIOCSETSTEREO:
  892         error = acd_setchan(cdp, CHANNEL_0, CHANNEL_1, 0, 0);
  893         break;
  894 
  895     case CDIOCSETMUTE:
  896         error = acd_setchan(cdp, 0, 0, 0, 0);
  897         break;
  898 
  899     case CDIOCSETLEFT:
  900         error = acd_setchan(cdp, CHANNEL_0, CHANNEL_0, 0, 0);
  901         break;
  902 
  903     case CDIOCSETRIGHT:
  904         error = acd_setchan(cdp, CHANNEL_1, CHANNEL_1, 0, 0);
  905         break;
  906 
  907     case CDRIOCBLANK:
  908         error = acd_blank(cdp, (*(int *)addr));
  909         break;
  910 
  911     case CDRIOCNEXTWRITEABLEADDR:
  912         {
  913             struct acd_track_info track_info;
  914 
  915             if ((error = acd_read_track_info(cdp, 0xff, &track_info)))
  916                 break;
  917 
  918             if (!track_info.nwa_valid) {
  919                 error = EINVAL;
  920                 break;
  921             }
  922             *(int*)addr = track_info.next_writeable_addr;
  923         }
  924         break;
  925  
  926     case CDRIOCINITWRITER:
  927         error = acd_init_writer(cdp, (*(int *)addr));
  928         break;
  929 
  930     case CDRIOCINITTRACK:
  931         error = acd_init_track(cdp, (struct cdr_track *)addr);
  932         break;
  933 
  934     case CDRIOCFLUSH:
  935         error = acd_flush(cdp);
  936         break;
  937 
  938     case CDRIOCFIXATE:
  939         error = acd_fixate(cdp, (*(int *)addr));
  940         break;
  941 
  942     case CDRIOCREADSPEED:
  943         {
  944             int speed = *(int *)addr;
  945 
  946             /* Preserve old behavior: units in multiples of CDROM speed */
  947             if (speed < 177)
  948                 speed *= 177;
  949             error = acd_set_speed(cdp, speed, CDR_MAX_SPEED);
  950         }
  951         break;
  952 
  953     case CDRIOCWRITESPEED:
  954         {
  955             int speed = *(int *)addr;
  956 
  957             if (speed < 177)
  958                 speed *= 177;
  959             error = acd_set_speed(cdp, CDR_MAX_SPEED, speed);
  960         }
  961         break;
  962 
  963     case CDRIOCGETBLOCKSIZE:
  964         *(int *)addr = cdp->block_size;
  965         break;
  966 
  967     case CDRIOCSETBLOCKSIZE:
  968         cdp->block_size = *(int *)addr;
  969         pp->sectorsize = cdp->block_size;       /* hack for GEOM SOS */
  970         acd_set_ioparm(cdp);
  971         break;
  972 
  973     case CDRIOCGETPROGRESS:
  974         error = acd_get_progress(cdp, (int *)addr);
  975         break;
  976 
  977     case CDRIOCSENDCUE:
  978         error = acd_send_cue(cdp, (struct cdr_cuesheet *)addr);
  979         break;
  980 
  981     case CDRIOCREADFORMATCAPS:
  982         error = acd_read_format_caps(cdp, (struct cdr_format_capacities *)addr);
  983         break;
  984 
  985     case CDRIOCFORMAT:
  986         error = acd_format(cdp, (struct cdr_format_params *)addr);
  987         break;
  988 
  989     case DVDIOCREPORTKEY:
  990         if (cdp->cap.media & MST_READ_DVDROM)
  991             error = acd_report_key(cdp, (struct dvd_authinfo *)addr);
  992         else
  993             error = EINVAL;
  994         break;
  995 
  996     case DVDIOCSENDKEY:
  997         if (cdp->cap.media & MST_READ_DVDROM)
  998             error = acd_send_key(cdp, (struct dvd_authinfo *)addr);
  999         else
 1000             error = EINVAL;
 1001         break;
 1002 
 1003     case DVDIOCREADSTRUCTURE:
 1004         if (cdp->cap.media & MST_READ_DVDROM)
 1005             error = acd_read_structure(cdp, (struct dvd_struct *)addr);
 1006         else
 1007             error = EINVAL;
 1008         break;
 1009 
 1010     default:
 1011         error = ENOTTY;
 1012     }
 1013     return error;
 1014 }
 1015 
 1016 static void 
 1017 acd_geom_start(struct bio *bp)
 1018 {
 1019     struct acd_softc *cdp = bp->bio_to->geom->softc;
 1020 
 1021     if (cdp->device->flags & ATA_D_DETACHING) {
 1022         g_io_deliver(bp, ENXIO);
 1023         return;
 1024     }
 1025 
 1026     if (bp->bio_cmd != BIO_READ && bp->bio_cmd != BIO_WRITE) {
 1027         g_io_deliver(bp, EOPNOTSUPP);
 1028         return;
 1029     }
 1030 
 1031     if (bp->bio_cmd == BIO_READ && cdp->disk_size == -1) {
 1032         g_io_deliver(bp, EIO);
 1033         return;
 1034     }
 1035 
 1036     /* GEOM classes must do their own request limiting */
 1037     if (bp->bio_length <= cdp->iomax) {
 1038         mtx_lock(&cdp->queue_mtx);
 1039         bp->bio_pblkno = bp->bio_offset / bp->bio_to->sectorsize;
 1040         bioq_disksort(&cdp->queue, bp);
 1041         mtx_unlock(&cdp->queue_mtx);
 1042     }
 1043     else {
 1044         u_int pos, size = cdp->iomax - cdp->iomax % bp->bio_to->sectorsize;
 1045         struct bio *bp2;
 1046 
 1047         for (pos = 0; pos < bp->bio_length; pos += size) {
 1048             if (!(bp2 = g_clone_bio(bp))) {
 1049                 bp->bio_error = ENOMEM;
 1050                 break;
 1051             }
 1052             bp2->bio_done = g_std_done;
 1053             bp2->bio_to = bp->bio_to;
 1054             bp2->bio_offset += pos;
 1055             bp2->bio_data += pos;
 1056             bp2->bio_length = MIN(size, bp->bio_length - pos);
 1057             mtx_lock(&cdp->queue_mtx);
 1058             bp2->bio_pblkno = bp2->bio_offset / bp2->bio_to->sectorsize;
 1059             bioq_disksort(&cdp->queue, bp2);
 1060             mtx_unlock(&cdp->queue_mtx);
 1061         }
 1062     }
 1063     ata_start(cdp->device->channel);
 1064 }
 1065 
 1066 static void 
 1067 acd_start(struct ata_device *atadev)
 1068 {
 1069     struct acd_softc *cdp = atadev->softc;
 1070     struct bio *bp;
 1071     struct ata_request *request;
 1072     u_int32_t lba, lastlba, count;
 1073     int8_t ccb[16];
 1074     int track, blocksize;
 1075 
 1076     if (cdp->changer_info) {
 1077         int i;
 1078 
 1079         cdp = cdp->driver[cdp->changer_info->current_slot];
 1080         mtx_lock(&cdp->queue_mtx);
 1081         bp = bioq_first(&cdp->queue);
 1082         mtx_unlock(&cdp->queue_mtx);
 1083 
 1084         /* check for work pending on any other slot */
 1085         for (i = 0; i < cdp->changer_info->slots; i++) {
 1086             if (i == cdp->changer_info->current_slot)
 1087                 continue;
 1088             mtx_lock(&cdp->queue_mtx);
 1089             if (bioq_first(&(cdp->driver[i]->queue))) {
 1090                 if (!bp || time_second > (cdp->timestamp + 10)) {
 1091                     mtx_unlock(&cdp->queue_mtx);
 1092                     acd_select_slot(cdp->driver[i]);
 1093                     return;
 1094                 }
 1095             }
 1096             mtx_unlock(&cdp->queue_mtx);
 1097 
 1098         }
 1099     }
 1100     mtx_lock(&cdp->queue_mtx);
 1101     bp = bioq_first(&cdp->queue);
 1102     if (bp)
 1103         bioq_remove(&cdp->queue, bp);
 1104     mtx_unlock(&cdp->queue_mtx);
 1105     if (!bp)
 1106         return;
 1107 
 1108     /* reject all queued entries if media changed */
 1109     if (cdp->device->flags & ATA_D_MEDIA_CHANGED) {
 1110         g_io_deliver(bp, EIO);
 1111         return;
 1112     }
 1113 
 1114     bzero(ccb, sizeof(ccb));
 1115 
 1116     track = bp->bio_to->index;
 1117 
 1118     if (track) {
 1119         blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
 1120         lastlba = ntohl(cdp->toc.tab[track].addr.lba);
 1121         lba = bp->bio_offset / blocksize;
 1122         lba += ntohl(cdp->toc.tab[track - 1].addr.lba);
 1123     }
 1124     else {
 1125         blocksize = cdp->block_size;
 1126         lastlba = cdp->disk_size;
 1127         lba = bp->bio_offset / blocksize;
 1128     }
 1129 
 1130     count = bp->bio_length / blocksize;
 1131 
 1132     if (bp->bio_cmd == BIO_READ) {
 1133         /* if transfer goes beyond range adjust it to be within limits */
 1134         if (lba + count > lastlba) {
 1135             /* if we are entirely beyond EOM return EOF */
 1136             if (lastlba <= lba) {
 1137                 g_io_deliver(bp, 0);
 1138                 return;
 1139             }
 1140             count = lastlba - lba;
 1141         }
 1142         switch (blocksize) {
 1143         case 2048:
 1144             ccb[0] = ATAPI_READ_BIG;
 1145             break;
 1146 
 1147         case 2352: 
 1148             ccb[0] = ATAPI_READ_CD;
 1149             ccb[9] = 0xf8;
 1150             break;
 1151 
 1152         default:
 1153             ccb[0] = ATAPI_READ_CD;
 1154             ccb[9] = 0x10;
 1155         }
 1156     }
 1157     else
 1158         ccb[0] = ATAPI_WRITE_BIG;
 1159     
 1160     ccb[1] = 0;
 1161     ccb[2] = lba>>24;
 1162     ccb[3] = lba>>16;
 1163     ccb[4] = lba>>8;
 1164     ccb[5] = lba;
 1165     ccb[6] = count>>16;
 1166     ccb[7] = count>>8;
 1167     ccb[8] = count;
 1168 
 1169     if (!(request = ata_alloc_request())) {
 1170         g_io_deliver(bp, ENOMEM);
 1171         return;
 1172     }
 1173     request->device = atadev;
 1174     request->driver = bp;
 1175     bcopy(ccb, request->u.atapi.ccb,
 1176           (request->device->param->config & ATA_PROTO_MASK) == 
 1177           ATA_PROTO_ATAPI_12 ? 16 : 12);
 1178     request->data = bp->bio_data;
 1179     request->bytecount = count * blocksize;
 1180     request->transfersize = min(request->bytecount, 65534);
 1181     request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30;
 1182     request->retries = 2;
 1183     request->callback = acd_done;
 1184     request->flags = ATA_R_ATAPI;
 1185     if (request->device->mode >= ATA_DMA)
 1186         request->flags |= ATA_R_DMA;
 1187     switch (bp->bio_cmd) {
 1188     case BIO_READ:
 1189         request->flags |= ATA_R_READ;
 1190         break;
 1191     case BIO_WRITE:
 1192         request->flags |= ATA_R_WRITE;
 1193         break;
 1194     default:
 1195         ata_prtdev(atadev, "unknown BIO operation\n");
 1196         ata_free_request(request);
 1197         g_io_deliver(bp, EIO);
 1198         return;
 1199     }
 1200     ata_queue_request(request);
 1201 }
 1202 
 1203 static void 
 1204 acd_done(struct ata_request *request)
 1205 {
 1206     struct bio *bp = request->driver;
 1207     
 1208     /* finish up transfer */
 1209     bp->bio_completed = request->donecount;
 1210     g_io_deliver(bp, request->result);
 1211     ata_free_request(request);
 1212 }
 1213 
 1214 static void 
 1215 acd_read_toc(struct acd_softc *cdp)
 1216 {
 1217     int track, ntracks, len;
 1218     u_int32_t sizes[2];
 1219     int8_t ccb[16];
 1220     struct g_provider *pp;
 1221 
 1222     if (acd_test_ready(cdp->device))
 1223         return;
 1224 
 1225     if (!(cdp->device->flags & ATA_D_MEDIA_CHANGED))
 1226         return;
 1227 
 1228     cdp->device->flags &= ~ATA_D_MEDIA_CHANGED;
 1229     bzero(&cdp->toc, sizeof(cdp->toc));
 1230     bzero(ccb, sizeof(ccb));
 1231     cdp->disk_size = -1;                        /* hack for GEOM SOS */
 1232 
 1233     len = sizeof(struct ioc_toc_header) + sizeof(struct cd_toc_entry);
 1234     ccb[0] = ATAPI_READ_TOC;
 1235     ccb[7] = len>>8;
 1236     ccb[8] = len;
 1237     if (ata_atapicmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
 1238                      ATA_R_READ | ATA_R_QUIET, 30)) {
 1239         bzero(&cdp->toc, sizeof(cdp->toc));
 1240         return;
 1241     }
 1242     ntracks = cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1;
 1243     if (ntracks <= 0 || ntracks > MAXTRK) {
 1244         bzero(&cdp->toc, sizeof(cdp->toc));
 1245         return;
 1246     }
 1247 
 1248     len = sizeof(struct ioc_toc_header)+(ntracks+1)*sizeof(struct cd_toc_entry);
 1249     bzero(ccb, sizeof(ccb));
 1250     ccb[0] = ATAPI_READ_TOC;
 1251     ccb[7] = len>>8;
 1252     ccb[8] = len;
 1253     if (ata_atapicmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
 1254                      ATA_R_READ | ATA_R_QUIET, 30)) {
 1255         bzero(&cdp->toc, sizeof(cdp->toc));
 1256         return;
 1257     }
 1258     cdp->toc.hdr.len = ntohs(cdp->toc.hdr.len);
 1259 
 1260     cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352;
 1261     acd_set_ioparm(cdp);
 1262     bzero(ccb, sizeof(ccb));
 1263     ccb[0] = ATAPI_READ_CAPACITY;
 1264     if (ata_atapicmd(cdp->device, ccb, (caddr_t)sizes, sizeof(sizes),
 1265                      ATA_R_READ | ATA_R_QUIET, 30)) {
 1266         bzero(&cdp->toc, sizeof(cdp->toc));
 1267         return;
 1268     }
 1269     cdp->disk_size = ntohl(sizes[0]) + 1;
 1270 
 1271     for (track = 1; track <= ntracks; track ++) {
 1272         if (cdp->pp[track] != NULL)
 1273             continue;
 1274         pp = g_new_providerf(cdp->gp, "acd%dt%02d", cdp->lun, track);
 1275         pp->index = track;
 1276         cdp->pp[track] = pp;
 1277         g_error_provider(pp, 0);
 1278     }
 1279     for (; track < MAXTRK; track ++) {
 1280         if (cdp->pp[track] == NULL)
 1281             continue;
 1282         cdp->pp[track]->flags |= G_PF_WITHER;
 1283         g_orphan_provider(cdp->pp[track], ENXIO);
 1284         cdp->pp[track] = NULL;
 1285     }
 1286 
 1287 #ifdef ACD_DEBUG
 1288     if (cdp->disk_size && cdp->toc.hdr.ending_track) {
 1289         ata_prtdev(cdp->device, "(%d sectors (%d bytes)), %d tracks ", 
 1290                    cdp->disk_size, cdp->block_size,
 1291                    cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1);
 1292         if (cdp->toc.tab[0].control & 4)
 1293             printf("%dMB\n", cdp->disk_size / 512);
 1294         else
 1295             printf("%d:%d audio\n",
 1296                    cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60);
 1297     }
 1298 #endif
 1299 }
 1300 
 1301 static int
 1302 acd_play(struct acd_softc *cdp, int start, int end)
 1303 {
 1304     int8_t ccb[16];
 1305 
 1306     bzero(ccb, sizeof(ccb));
 1307     ccb[0] = ATAPI_PLAY_MSF;
 1308     lba2msf(start, &ccb[3], &ccb[4], &ccb[5]);
 1309     lba2msf(end, &ccb[6], &ccb[7], &ccb[8]);
 1310     return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 10);
 1311 }
 1312 
 1313 static int 
 1314 acd_setchan(struct acd_softc *cdp,
 1315             u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)
 1316 {
 1317     int error;
 1318 
 1319     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_AUDIO_PAGE, (caddr_t)&cdp->au, 
 1320                                 sizeof(cdp->au))))
 1321         return error;
 1322     if (cdp->au.page_code != ATAPI_CDROM_AUDIO_PAGE)
 1323         return EIO;
 1324     cdp->au.data_length = 0;
 1325     cdp->au.port[0].channels = c0;
 1326     cdp->au.port[1].channels = c1;
 1327     cdp->au.port[2].channels = c2;
 1328     cdp->au.port[3].channels = c3;
 1329     return acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
 1330 }
 1331 
 1332 static void 
 1333 acd_load_done(struct ata_request *request)
 1334 {
 1335     struct acd_softc *cdp = request->driver;
 1336 
 1337     /* finish the slot select and wakeup caller */
 1338     cdp->changer_info->current_slot = cdp->slot;
 1339     cdp->driver[cdp->changer_info->current_slot]->timestamp = time_second;
 1340     wakeup(&cdp->changer_info);
 1341 }
 1342 
 1343 static void 
 1344 acd_unload_done(struct ata_request *request)
 1345 {
 1346     struct acd_softc *cdp = request->driver;
 1347     int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 3, 0, 0, 0, 
 1348                        cdp->slot, 0, 0, 0, 0, 0, 0, 0 };
 1349 
 1350     /* load the wanted slot */
 1351     bcopy(ccb, request->u.atapi.ccb,
 1352           (request->device->param->config & ATA_PROTO_MASK) ==
 1353           ATA_PROTO_ATAPI_12 ? 16 : 12);
 1354     request->callback = acd_load_done;
 1355     ata_queue_request(request);
 1356 }
 1357 
 1358 static void 
 1359 acd_select_slot(struct acd_softc *cdp)
 1360 {
 1361     struct ata_request *request;
 1362     int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 2, 0, 0, 0, 
 1363                        cdp->changer_info->current_slot, 0, 0, 0, 0, 0, 0, 0 };
 1364 
 1365     /* unload the current media from player */
 1366     if (!(request = ata_alloc_request()))
 1367         return;
 1368 
 1369     request->device = cdp->device;
 1370     request->driver = cdp;
 1371     bcopy(ccb, request->u.atapi.ccb,
 1372           (request->device->param->config & ATA_PROTO_MASK) ==
 1373           ATA_PROTO_ATAPI_12 ? 16 : 12);
 1374     request->timeout = 30;
 1375     request->callback = acd_unload_done;
 1376     request->flags |= (ATA_R_ATAPI | ATA_R_IMMEDIATE);
 1377     ata_queue_request(request);
 1378 }
 1379 
 1380 static int
 1381 acd_init_writer(struct acd_softc *cdp, int test_write)
 1382 {
 1383     int8_t ccb[16];
 1384 
 1385     bzero(ccb, sizeof(ccb));
 1386     ccb[0] = ATAPI_REZERO;
 1387     ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 60);
 1388     ccb[0] = ATAPI_SEND_OPC_INFO;
 1389     ccb[1] = 0x01;
 1390     ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 30);
 1391     return 0;
 1392 }
 1393 
 1394 static int
 1395 acd_fixate(struct acd_softc *cdp, int multisession)
 1396 {
 1397     int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0x01, 0x02, 0, 0, 0, 0, 0, 
 1398                        0, 0, 0, 0, 0, 0, 0, 0 };
 1399     int timeout = 5*60*2;
 1400     int error, dummy;
 1401     struct write_param param;
 1402 
 1403     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1404                                 (caddr_t)&param, sizeof(param))))
 1405         return error;
 1406 
 1407     param.data_length = 0;
 1408     if (multisession)
 1409         param.session_type = CDR_SESS_MULTI;
 1410     else
 1411         param.session_type = CDR_SESS_NONE;
 1412 
 1413     if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
 1414         return error;
 1415   
 1416     error = ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1417     if (error)
 1418         return error;
 1419 
 1420     /* some drives just return ready, wait for the expected fixate time */
 1421     if ((error = acd_test_ready(cdp->device)) != EBUSY) {
 1422         timeout = timeout / (cdp->cap.cur_write_speed / 177);
 1423         tsleep(&error, PRIBIO, "acdfix", timeout * hz / 2);
 1424         return acd_test_ready(cdp->device);
 1425     }
 1426 
 1427     while (timeout-- > 0) {
 1428         if ((error = acd_get_progress(cdp, &dummy)))
 1429             return error;
 1430         if ((error = acd_test_ready(cdp->device)) != EBUSY)
 1431             return error;
 1432         tsleep(&error, PRIBIO, "acdcld", hz / 2);
 1433     }
 1434     return EIO;
 1435 }
 1436 
 1437 static int
 1438 acd_init_track(struct acd_softc *cdp, struct cdr_track *track)
 1439 {
 1440     struct write_param param;
 1441     int error;
 1442 
 1443     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1444                                 (caddr_t)&param, sizeof(param))))
 1445         return error;
 1446 
 1447     param.data_length = 0;
 1448     param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE;
 1449     param.page_length = 0x32;
 1450     param.test_write = track->test_write ? 1 : 0;
 1451     param.write_type = CDR_WTYPE_TRACK;
 1452     param.session_type = CDR_SESS_NONE;
 1453     param.fp = 0;
 1454     param.packet_size = 0;
 1455 
 1456     if (cdp->cap.capabilities & MST_BURNPROOF) 
 1457         param.burnproof = 1;
 1458 
 1459     switch (track->datablock_type) {
 1460 
 1461     case CDR_DB_RAW:
 1462         if (track->preemp)
 1463             param.track_mode = CDR_TMODE_AUDIO_PREEMP;
 1464         else
 1465             param.track_mode = CDR_TMODE_AUDIO;
 1466         cdp->block_size = 2352;
 1467         param.datablock_type = CDR_DB_RAW;
 1468         param.session_format = CDR_SESS_CDROM;
 1469         break;
 1470 
 1471     case CDR_DB_ROM_MODE1:
 1472         cdp->block_size = 2048;
 1473         param.track_mode = CDR_TMODE_DATA;
 1474         param.datablock_type = CDR_DB_ROM_MODE1;
 1475         param.session_format = CDR_SESS_CDROM;
 1476         break;
 1477 
 1478     case CDR_DB_ROM_MODE2:
 1479         cdp->block_size = 2336;
 1480         param.track_mode = CDR_TMODE_DATA;
 1481         param.datablock_type = CDR_DB_ROM_MODE2;
 1482         param.session_format = CDR_SESS_CDROM;
 1483         break;
 1484 
 1485     case CDR_DB_XA_MODE1:
 1486         cdp->block_size = 2048;
 1487         param.track_mode = CDR_TMODE_DATA;
 1488         param.datablock_type = CDR_DB_XA_MODE1;
 1489         param.session_format = CDR_SESS_CDROM_XA;
 1490         break;
 1491 
 1492     case CDR_DB_XA_MODE2_F1:
 1493         cdp->block_size = 2056;
 1494         param.track_mode = CDR_TMODE_DATA;
 1495         param.datablock_type = CDR_DB_XA_MODE2_F1;
 1496         param.session_format = CDR_SESS_CDROM_XA;
 1497         break;
 1498 
 1499     case CDR_DB_XA_MODE2_F2:
 1500         cdp->block_size = 2324;
 1501         param.track_mode = CDR_TMODE_DATA;
 1502         param.datablock_type = CDR_DB_XA_MODE2_F2;
 1503         param.session_format = CDR_SESS_CDROM_XA;
 1504         break;
 1505 
 1506     case CDR_DB_XA_MODE2_MIX:
 1507         cdp->block_size = 2332;
 1508         param.track_mode = CDR_TMODE_DATA;
 1509         param.datablock_type = CDR_DB_XA_MODE2_MIX;
 1510         param.session_format = CDR_SESS_CDROM_XA;
 1511         break;
 1512     }
 1513     acd_set_ioparm(cdp);
 1514     return acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10);
 1515 }
 1516 
 1517 static int
 1518 acd_flush(struct acd_softc *cdp)
 1519 {
 1520     int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0,
 1521                        0, 0, 0, 0, 0, 0, 0, 0 };
 1522 
 1523     return ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 60);
 1524 }
 1525 
 1526 static int
 1527 acd_read_track_info(struct acd_softc *cdp,
 1528                     int32_t lba, struct acd_track_info *info)
 1529 {
 1530     int8_t ccb[16] = { ATAPI_READ_TRACK_INFO, 1,
 1531                        lba>>24, lba>>16, lba>>8, lba, 0,
 1532                        sizeof(*info)>>8, sizeof(*info),
 1533                        0, 0, 0, 0, 0, 0, 0 };
 1534     int error;
 1535 
 1536     if ((error = ata_atapicmd(cdp->device, ccb, (caddr_t)info, sizeof(*info),
 1537                               ATA_R_READ, 30)))
 1538         return error;
 1539     info->track_start_addr = ntohl(info->track_start_addr);
 1540     info->next_writeable_addr = ntohl(info->next_writeable_addr);
 1541     info->free_blocks = ntohl(info->free_blocks);
 1542     info->fixed_packet_size = ntohl(info->fixed_packet_size);
 1543     info->track_length = ntohl(info->track_length);
 1544     return 0;
 1545 }
 1546 
 1547 static int
 1548 acd_get_progress(struct acd_softc *cdp, int *finished)
 1549 {
 1550     int8_t ccb[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0,
 1551                        0, 0, 0, 0, 0, 0, 0, 0 };
 1552     struct ata_request *request;
 1553     int8_t dummy[8];
 1554 
 1555     if (!(request = ata_alloc_request()))
 1556         return ENOMEM;
 1557 
 1558     request->device = cdp->device;
 1559     request->driver = cdp;
 1560     bcopy(ccb, request->u.atapi.ccb, 16);
 1561     request->data = dummy;
 1562     request->bytecount = sizeof(dummy);
 1563     request->transfersize = min(request->bytecount, 65534);
 1564     request->flags = ATA_R_ATAPI | ATA_R_READ;
 1565     request->timeout = 30;
 1566     ata_queue_request(request);
 1567     if (!request->error && request->u.atapi.sense_data.sksv)
 1568         *finished = ((request->u.atapi.sense_data.sk_specific2 |
 1569                      (request->u.atapi.sense_data.sk_specific1<<8))*100)/65535;
 1570     else
 1571         *finished = 0;
 1572     ata_free_request(request);
 1573     return 0;
 1574 }
 1575 
 1576 static int
 1577 acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet)
 1578 {
 1579     struct write_param param;
 1580     int8_t ccb[16] = { ATAPI_SEND_CUE_SHEET, 0, 0, 0, 0, 0, 
 1581                        cuesheet->len>>16, cuesheet->len>>8, cuesheet->len,
 1582                        0, 0, 0, 0, 0, 0, 0 };
 1583     int8_t *buffer;
 1584     int32_t error;
 1585 #ifdef ACD_DEBUG
 1586     int i;
 1587 #endif
 1588 
 1589     if ((error = acd_mode_sense(cdp, ATAPI_CDROM_WRITE_PARAMETERS_PAGE,
 1590                                 (caddr_t)&param, sizeof(param))))
 1591         return error;
 1592 
 1593     param.data_length = 0;
 1594     param.page_code = ATAPI_CDROM_WRITE_PARAMETERS_PAGE;
 1595     param.page_length = 0x32;
 1596     param.test_write = cuesheet->test_write ? 1 : 0;
 1597     param.write_type = CDR_WTYPE_SESSION;
 1598     param.session_type = cuesheet->session_type;
 1599     param.fp = 0;
 1600     param.packet_size = 0;
 1601     param.track_mode = CDR_TMODE_AUDIO;
 1602     param.datablock_type = CDR_DB_RAW;
 1603     param.session_format = cuesheet->session_format;
 1604     if (cdp->cap.capabilities & MST_BURNPROOF) 
 1605         param.burnproof = 1;
 1606 
 1607     if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
 1608         return error;
 1609 
 1610     if (!(buffer = malloc(cuesheet->len, M_ACD, M_NOWAIT)))
 1611         return ENOMEM;
 1612 
 1613     if (!(error = copyin(cuesheet->entries, buffer, cuesheet->len))) {
 1614 #ifdef ACD_DEBUG
 1615         printf("acd: cuesheet lenght = %d\n", cuesheet->len);
 1616         for (i=0; i<cuesheet->len; i++)
 1617             if (i%8)
 1618                 printf(" %02x", buffer[i]);
 1619             else
 1620                 printf("\n%02x", buffer[i]);
 1621         printf("\n");
 1622 #endif
 1623         error = ata_atapicmd(cdp->device, ccb, buffer, cuesheet->len, 0, 30);
 1624     }
 1625     free(buffer, M_ACD);
 1626     return error;
 1627 }
 1628 
 1629 static int
 1630 acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
 1631 {
 1632     struct dvd_miscauth *d = NULL;
 1633     u_int32_t lba = 0;
 1634     int16_t length;
 1635     int8_t ccb[16];
 1636     int error;
 1637 
 1638     switch (ai->format) {
 1639     case DVD_REPORT_AGID:
 1640     case DVD_REPORT_ASF:
 1641     case DVD_REPORT_RPC:
 1642         length = 8;
 1643         break;
 1644     case DVD_REPORT_KEY1:
 1645         length = 12;
 1646         break;
 1647     case DVD_REPORT_TITLE_KEY:
 1648         length = 12;
 1649         lba = ai->lba;
 1650         break;
 1651     case DVD_REPORT_CHALLENGE:
 1652         length = 16;
 1653         break;
 1654     case DVD_INVALIDATE_AGID:
 1655         length = 0;
 1656         break;
 1657     default:
 1658         return EINVAL;
 1659     }
 1660 
 1661     bzero(ccb, sizeof(ccb));
 1662     ccb[0] = ATAPI_REPORT_KEY;
 1663     ccb[2] = (lba >> 24) & 0xff;
 1664     ccb[3] = (lba >> 16) & 0xff;
 1665     ccb[4] = (lba >> 8) & 0xff;
 1666     ccb[5] = lba & 0xff;
 1667     ccb[8] = (length >> 8) & 0xff;
 1668     ccb[9] = length & 0xff;
 1669     ccb[10] = (ai->agid << 6) | ai->format;
 1670 
 1671     if (length) {
 1672         if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO)))
 1673             return ENOMEM;
 1674         d->length = htons(length - 2);
 1675     }
 1676 
 1677     error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length,
 1678                          ai->format == DVD_INVALIDATE_AGID ? 0 : ATA_R_READ,10);
 1679     if (error) {
 1680         free(d, M_ACD);
 1681         return error;
 1682     }
 1683 
 1684     switch (ai->format) {
 1685     case DVD_REPORT_AGID:
 1686         ai->agid = d->data[3] >> 6;
 1687         break;
 1688     
 1689     case DVD_REPORT_CHALLENGE:
 1690         bcopy(&d->data[0], &ai->keychal[0], 10);
 1691         break;
 1692     
 1693     case DVD_REPORT_KEY1:
 1694         bcopy(&d->data[0], &ai->keychal[0], 5);
 1695         break;
 1696     
 1697     case DVD_REPORT_TITLE_KEY:
 1698         ai->cpm = (d->data[0] >> 7);
 1699         ai->cp_sec = (d->data[0] >> 6) & 0x1;
 1700         ai->cgms = (d->data[0] >> 4) & 0x3;
 1701         bcopy(&d->data[1], &ai->keychal[0], 5);
 1702         break;
 1703     
 1704     case DVD_REPORT_ASF:
 1705         ai->asf = d->data[3] & 1;
 1706         break;
 1707     
 1708     case DVD_REPORT_RPC:
 1709         ai->reg_type = (d->data[0] >> 6);
 1710         ai->vend_rsts = (d->data[0] >> 3) & 0x7;
 1711         ai->user_rsts = d->data[0] & 0x7;
 1712         ai->region = d->data[1];
 1713         ai->rpc_scheme = d->data[2];
 1714         break;
 1715     
 1716     case DVD_INVALIDATE_AGID:
 1717         break;
 1718 
 1719     default:
 1720         error = EINVAL;
 1721     }
 1722     free(d, M_ACD);
 1723     return error;
 1724 }
 1725 
 1726 static int
 1727 acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
 1728 {
 1729     struct dvd_miscauth *d;
 1730     int16_t length;
 1731     int8_t ccb[16];
 1732     int error;
 1733 
 1734     switch (ai->format) {
 1735     case DVD_SEND_CHALLENGE:
 1736         length = 16;
 1737         if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO)))
 1738             return ENOMEM;
 1739         bcopy(ai->keychal, &d->data[0], 10);
 1740         break;
 1741 
 1742     case DVD_SEND_KEY2:
 1743         length = 12;
 1744         if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO)))
 1745             return ENOMEM;
 1746         bcopy(&ai->keychal[0], &d->data[0], 5);
 1747         break;
 1748     
 1749     case DVD_SEND_RPC:
 1750         length = 8;
 1751         if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO)))
 1752             return ENOMEM;
 1753         d->data[0] = ai->region;
 1754         break;
 1755 
 1756     default:
 1757         return EINVAL;
 1758     }
 1759 
 1760     bzero(ccb, sizeof(ccb));
 1761     ccb[0] = ATAPI_SEND_KEY;
 1762     ccb[8] = (length >> 8) & 0xff;
 1763     ccb[9] = length & 0xff;
 1764     ccb[10] = (ai->agid << 6) | ai->format;
 1765     d->length = htons(length - 2);
 1766     error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length, 0, 10);
 1767     free(d, M_ACD);
 1768     return error;
 1769 }
 1770 
 1771 static int
 1772 acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
 1773 {
 1774     struct dvd_miscauth *d;
 1775     u_int16_t length;
 1776     int8_t ccb[16];
 1777     int error = 0;
 1778 
 1779     switch(s->format) {
 1780     case DVD_STRUCT_PHYSICAL:
 1781         length = 21;
 1782         break;
 1783 
 1784     case DVD_STRUCT_COPYRIGHT:
 1785         length = 8;
 1786         break;
 1787 
 1788     case DVD_STRUCT_DISCKEY:
 1789         length = 2052;
 1790         break;
 1791 
 1792     case DVD_STRUCT_BCA:
 1793         length = 192;
 1794         break;
 1795 
 1796     case DVD_STRUCT_MANUFACT:
 1797         length = 2052;
 1798         break;
 1799 
 1800     case DVD_STRUCT_DDS:
 1801     case DVD_STRUCT_PRERECORDED:
 1802     case DVD_STRUCT_UNIQUEID:
 1803     case DVD_STRUCT_LIST:
 1804     case DVD_STRUCT_CMI:
 1805     case DVD_STRUCT_RMD_LAST:
 1806     case DVD_STRUCT_RMD_RMA:
 1807     case DVD_STRUCT_DCB:
 1808         return ENOSYS;
 1809 
 1810     default:
 1811         return EINVAL;
 1812     }
 1813 
 1814     if (!(d = malloc(length, M_ACD, M_NOWAIT | M_ZERO)))
 1815         return ENOMEM;
 1816     d->length = htons(length - 2);
 1817         
 1818     bzero(ccb, sizeof(ccb));
 1819     ccb[0] = ATAPI_READ_STRUCTURE;
 1820     ccb[6] = s->layer_num;
 1821     ccb[7] = s->format;
 1822     ccb[8] = (length >> 8) & 0xff;
 1823     ccb[9] = length & 0xff;
 1824     ccb[10] = s->agid << 6;
 1825     error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length, ATA_R_READ, 30);
 1826     if (error) {
 1827         free(d, M_ACD);
 1828         return error;
 1829     }
 1830 
 1831     switch (s->format) {
 1832     case DVD_STRUCT_PHYSICAL: {
 1833         struct dvd_layer *layer = (struct dvd_layer *)&s->data[0];
 1834 
 1835         layer->book_type = d->data[0] >> 4;
 1836         layer->book_version = d->data[0] & 0xf;
 1837         layer->disc_size = d->data[1] >> 4;
 1838         layer->max_rate = d->data[1] & 0xf;
 1839         layer->nlayers = (d->data[2] >> 5) & 3;
 1840         layer->track_path = (d->data[2] >> 4) & 1;
 1841         layer->layer_type = d->data[2] & 0xf;
 1842         layer->linear_density = d->data[3] >> 4;
 1843         layer->track_density = d->data[3] & 0xf;
 1844         layer->start_sector = d->data[5] << 16 | d->data[6] << 8 | d->data[7];
 1845         layer->end_sector = d->data[9] << 16 | d->data[10] << 8 | d->data[11];
 1846         layer->end_sector_l0 = d->data[13] << 16 | d->data[14] << 8|d->data[15];
 1847         layer->bca = d->data[16] >> 7;
 1848         break;
 1849     }
 1850 
 1851     case DVD_STRUCT_COPYRIGHT:
 1852         s->cpst = d->data[0];
 1853         s->rmi = d->data[0];
 1854         break;
 1855 
 1856     case DVD_STRUCT_DISCKEY:
 1857         bcopy(&d->data[0], &s->data[0], 2048);
 1858         break;
 1859 
 1860     case DVD_STRUCT_BCA:
 1861         s->length = ntohs(d->length);
 1862         bcopy(&d->data[0], &s->data[0], s->length);
 1863         break;
 1864 
 1865     case DVD_STRUCT_MANUFACT:
 1866         s->length = ntohs(d->length);
 1867         bcopy(&d->data[0], &s->data[0], s->length);
 1868         break;
 1869                 
 1870     default:
 1871         error = EINVAL;
 1872     }
 1873     free(d, M_ACD);
 1874     return error;
 1875 }
 1876 
 1877 static int 
 1878 acd_tray(struct acd_softc *cdp, int close)
 1879 {
 1880     int error = ENODEV;
 1881 
 1882     if (cdp->cap.mechanism & MST_EJECT) {
 1883         if (close) {
 1884             if (!(error = acd_start_stop(cdp, 3))) {
 1885                 acd_read_toc(cdp);
 1886                 acd_prevent_allow(cdp, 1);
 1887                 cdp->flags |= F_LOCKED;
 1888             }
 1889         }
 1890         else {
 1891             acd_start_stop(cdp, 0);
 1892             acd_prevent_allow(cdp, 0);
 1893             cdp->flags &= ~F_LOCKED;
 1894             cdp->device->flags |= ATA_D_MEDIA_CHANGED;
 1895             error = acd_start_stop(cdp, 2);
 1896         }
 1897     }
 1898     return error;
 1899 }
 1900 
 1901 static int
 1902 acd_blank(struct acd_softc *cdp, int blanktype)
 1903 {
 1904     int8_t ccb[16] = { ATAPI_BLANK, 0x10 | (blanktype & 0x7), 0, 0, 0, 0, 0, 0, 
 1905                        0, 0, 0, 0, 0, 0, 0, 0 };
 1906 
 1907     cdp->device->flags |= ATA_D_MEDIA_CHANGED;
 1908     return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1909 }
 1910 
 1911 static int
 1912 acd_prevent_allow(struct acd_softc *cdp, int lock)
 1913 {
 1914     int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
 1915                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 1916 
 1917     return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1918 }
 1919 
 1920 static int
 1921 acd_start_stop(struct acd_softc *cdp, int start)
 1922 {
 1923     int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start,
 1924                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 1925 
 1926     return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1927 }
 1928 
 1929 static int
 1930 acd_pause_resume(struct acd_softc *cdp, int pause)
 1931 {
 1932     int8_t ccb[16] = { ATAPI_PAUSE, 0, 0, 0, 0, 0, 0, 0, pause,
 1933                        0, 0, 0, 0, 0, 0, 0 };
 1934 
 1935     return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1936 }
 1937 
 1938 static int
 1939 acd_mode_sense(struct acd_softc *cdp, int page, caddr_t pagebuf, int pagesize)
 1940 {
 1941     int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, page, 0, 0, 0, 0,
 1942                        pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
 1943     int error;
 1944 
 1945     error = ata_atapicmd(cdp->device, ccb, pagebuf, pagesize, ATA_R_READ, 10);
 1946 #ifdef ACD_DEBUG
 1947     atapi_dump("acd: mode sense ", pagebuf, pagesize);
 1948 #endif
 1949     return error;
 1950 }
 1951 
 1952 static int
 1953 acd_mode_select(struct acd_softc *cdp, caddr_t pagebuf, int pagesize)
 1954 {
 1955     int8_t ccb[16] = { ATAPI_MODE_SELECT_BIG, 0x10, 0, 0, 0, 0, 0,
 1956                      pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
 1957 
 1958 #ifdef ACD_DEBUG
 1959     ata_prtdev(cdp->device,
 1960                "modeselect pagesize=%d\n", pagesize);
 1961     atapi_dump("mode select ", pagebuf, pagesize);
 1962 #endif
 1963     return ata_atapicmd(cdp->device, ccb, pagebuf, pagesize, 0, 30);
 1964 }
 1965 
 1966 static int
 1967 acd_set_speed(struct acd_softc *cdp, int rdspeed, int wrspeed)
 1968 {
 1969     int8_t ccb[16] = { ATAPI_SET_SPEED, 0, rdspeed >> 8, rdspeed, 
 1970                        wrspeed >> 8, wrspeed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 1971     int error;
 1972 
 1973     error = ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
 1974     if (!error)
 1975         acd_get_cap(cdp);
 1976     return error;
 1977 }
 1978 
 1979 static void
 1980 acd_get_cap(struct acd_softc *cdp)
 1981 {
 1982     int count;
 1983 
 1984     /* get drive capabilities, some bugridden drives needs this repeated */
 1985     for (count = 0 ; count < 5 ; count++) {
 1986         if (!acd_mode_sense(cdp, ATAPI_CDROM_CAP_PAGE,
 1987                             (caddr_t)&cdp->cap, sizeof(cdp->cap)) &&
 1988                             cdp->cap.page_code == ATAPI_CDROM_CAP_PAGE) {
 1989             cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed);
 1990             cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed);
 1991             cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed);
 1992             cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed),177);
 1993             cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels);
 1994             cdp->cap.buf_size = ntohs(cdp->cap.buf_size);
 1995         }
 1996     }
 1997 }
 1998 
 1999 static int
 2000 acd_read_format_caps(struct acd_softc *cdp, struct cdr_format_capacities *caps)
 2001 {
 2002     int8_t ccb[16] = { ATAPI_READ_FORMAT_CAPACITIES, 0, 0, 0, 0, 0, 0,
 2003                        (sizeof(struct cdr_format_capacities) >> 8) & 0xff,
 2004                        sizeof(struct cdr_format_capacities) & 0xff, 
 2005                        0, 0, 0, 0, 0, 0, 0 };
 2006     
 2007     return ata_atapicmd(cdp->device, ccb, (caddr_t)caps,
 2008                         sizeof(struct cdr_format_capacities), ATA_R_READ, 30);
 2009 }
 2010 
 2011 static int
 2012 acd_format(struct acd_softc *cdp, struct cdr_format_params* params)
 2013 {
 2014     int error;
 2015     int8_t ccb[16] = { ATAPI_FORMAT, 0x11, 0, 0, 0, 0, 0, 0, 0, 0, 
 2016                        0, 0, 0, 0, 0, 0 };
 2017 
 2018     error = ata_atapicmd(cdp->device, ccb, (u_int8_t *)params, 
 2019                          sizeof(struct cdr_format_params), 0, 30);
 2020     return error;
 2021 }
 2022 
 2023 static int
 2024 acd_test_ready(struct ata_device *atadev)
 2025 {
 2026     int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
 2027                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 2028 
 2029     return ata_atapicmd(atadev, ccb, NULL, 0, 0, 30);
 2030 }

Cache object: 22ef431dad76c69d841f4c9c33de2bb9


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


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