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