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