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