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