2 * Copyright (c) 1998 - 2006 Søren Schmidt <sos@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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 $
32 #include <sys/param.h>
37 #include <sys/cdrio.h>
38 #include <sys/device.h>
39 #include <sys/devicestat.h>
41 #include <sys/dvdio.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/module.h>
48 #include <sys/systm.h>
54 /* device structure */
55 static d_open_t acd_open
;
56 static d_close_t acd_close
;
57 static d_ioctl_t acd_ioctl
;
58 static d_strategy_t acd_strategy
;
59 static struct dev_ops acd_ops
= {
60 { "acd", 117, D_DISK
| D_TRACKCLOSE
},
66 .d_strategy
= acd_strategy
,
70 static void acd_set_ioparm(device_t
);
71 static void acd_describe(device_t
);
72 static void lba2msf(u_int32_t
, u_int8_t
*, u_int8_t
*, u_int8_t
*);
73 static u_int32_t
msf2lba(u_int8_t
, u_int8_t
, u_int8_t
);
74 static void acd_start(device_t
, struct bio
*);
75 static void acd_done(struct ata_request
*);
76 static void acd_read_toc(device_t
);
78 static struct acd_tracknode
* acd_make_tracknode(device_t
, int);
80 static void acd_destroy_tracknode(device_t
, int);
81 static int acd_play(device_t
, int, int);
82 static int acd_setchan(device_t
, u_int8_t
, u_int8_t
, u_int8_t
, u_int8_t
);
83 static int acd_init_writer(device_t
, int);
84 static int acd_fixate(device_t
, int);
85 static int acd_init_track(device_t
, struct cdr_track
*);
86 static int acd_flush(device_t
);
87 static int acd_read_track_info(device_t
, int32_t, struct acd_track_info
*);
88 static int acd_get_progress(device_t
, int *);
89 static int acd_send_cue(device_t
, struct cdr_cuesheet
*);
90 static int acd_report_key(device_t
, struct dvd_authinfo
*);
91 static int acd_send_key(device_t
, struct dvd_authinfo
*);
92 static int acd_read_structure(device_t
, struct dvd_struct
*);
93 static int acd_tray(device_t
, int);
94 static int acd_blank(device_t
, int);
95 static int acd_prevent_allow(device_t
, int);
96 static int acd_start_stop(device_t
, int);
97 static int acd_pause_resume(device_t
, int);
98 static int acd_mode_sense(device_t
, int, caddr_t
, int);
99 static int acd_mode_select(device_t
, caddr_t
, int);
100 static int acd_set_speed(device_t
, int, int);
101 static void acd_get_cap(device_t
);
102 #ifdef ACD_CDR_FORMAT
104 static int acd_read_format_caps(device_t
, struct cdr_format_capacities
*);
105 static int acd_format(device_t
, struct cdr_format_params
*);
106 #endif /* ACD_CDR_FORMAT */
107 static int acd_test_ready(device_t
);
110 static MALLOC_DEFINE(M_ACD
, "acd_driver", "ATAPI CD driver buffers");
113 acd_probe(device_t dev
)
115 struct ata_device
*atadev
= device_get_softc(dev
);
117 if ((atadev
->param
.config
& ATA_PROTO_ATAPI
) &&
118 (atadev
->param
.config
& ATA_ATAPI_TYPE_MASK
) == ATA_ATAPI_TYPE_CDROM
)
125 acd_attach(device_t dev
)
127 struct ata_device
*atadev
= device_get_softc(dev
);
128 struct acd_softc
*cdp
;
131 /* XXX TGEN We're not in interrupt context, so we can M_WAITOK and remove
133 cdp
= kmalloc(sizeof(struct acd_softc
), M_ACD
, M_INTWAIT
| M_ZERO
);
134 cdp
->block_size
= 2048;
135 device_set_ivars(dev
, cdp
);
136 ATA_SETMODE(device_get_parent(dev
), dev
);
137 ata_controlcmd(dev
, ATA_DEVICE_RESET
, 0, 0, 0);
140 devstat_add_entry(&cdp
->stats
, "acd", device_get_unit(dev
), DEV_BSIZE
,
141 DEVSTAT_NO_ORDERED_TAGS
,
142 DEVSTAT_TYPE_CDROM
| DEVSTAT_TYPE_IF_IDE
,
143 DEVSTAT_PRIORITY_CD
);
145 cdev
= disk_create(device_get_unit(dev
), &cdp
->disk
, &acd_ops
);
147 dev_ops_add(&acd_ops
, dkunitmask(), dkmakeunit(device_get_unit(dev
)));
148 cdev
= make_dev(&acd_ops
, dkmakeminor(device_get_unit(dev
), 0, 0),
149 UID_ROOT
, GID_OPERATOR
, 0644, "acd%d",
150 device_get_unit(dev
));
156 * Even though we do not have media information yet, we have to
157 * tell the disk management layer something or dscheck() will be
162 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
164 /* announce we are here */
170 acd_detach(device_t dev
)
172 struct acd_softc
*cdp
= device_get_ivars(dev
);
175 /* destroy devices from the system so we don't get any further requests */
176 for (track
= 1; track
< MAXTRK
; track
++) {
177 if (cdp
->track
[track
] == NULL
)
179 acd_destroy_tracknode(dev
, track
);
181 destroy_dev(cdp
->cdev
);
183 /* fail requests on the queue and any "in flight" for this device */
184 ata_fail_requests(dev
);
186 /* don't leave anything behind */
187 dev_ops_remove(&acd_ops
, dkunitmask(), dkmakeunit(device_get_unit(dev
)));
188 disk_invalidate(&cdp
->disk
);
189 disk_destroy(&cdp
->disk
);
190 devstat_remove_entry(&cdp
->stats
);
191 device_set_ivars(dev
, NULL
);
197 acd_shutdown(device_t dev
)
199 struct ata_device
*atadev
= device_get_softc(dev
);
201 if (atadev
->param
.support
.command2
& ATA_SUPPORT_FLUSHCACHE
)
202 ata_controlcmd(dev
, ATA_FLUSHCACHE
, 0, 0, 0);
206 acd_reinit(device_t dev
)
208 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
209 struct ata_device
*atadev
= device_get_softc(dev
);
211 if (((atadev
->unit
== ATA_MASTER
) && !(ch
->devices
& ATA_ATAPI_MASTER
)) ||
212 ((atadev
->unit
== ATA_SLAVE
) && !(ch
->devices
& ATA_ATAPI_SLAVE
))) {
215 ATA_SETMODE(device_get_parent(dev
), dev
);
220 acd_open(struct dev_open_args
*ap
)
222 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
223 /* XXX TGEN Sometimes, we're fed a cdev_t which we didn't create. It
224 doesn't have si_drv1 set, leading to evil NULL derefs. I can actually
225 recover our device_t otherwise, but really, this is a bug, so I'll bail
230 struct ata_device
*atadev
= device_get_softc(dev
);
231 struct acd_softc
*cdp
= device_get_ivars(dev
);
232 struct ata_request
*request
;
233 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
239 if (!device_is_attached(dev
))
241 if (!(request
= ata_alloc_request()))
244 /* wait if drive is not finished loading the medium */
246 bzero(request
, sizeof(struct ata_request
));
248 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
249 request
->flags
= ATA_R_ATAPI
;
250 request
->timeout
= ATA_DEFAULT_TIMEOUT
;
251 ata_queue_request(request
);
252 if (!request
->error
&&
253 (request
->u
.atapi
.sense
.key
== 2 ||
254 request
->u
.atapi
.sense
.key
== 7) &&
255 request
->u
.atapi
.sense
.asc
== 4 &&
256 request
->u
.atapi
.sense
.ascq
== 1)
257 tsleep(&timeout
, 0, "acdld", hz
/ 2);
261 ata_free_request(request
);
264 * DragonFly abstracts out the disk layer so our device may not have
265 * a vnode directly associated with it. count_dev() cannot be used.
267 if (atadev
->opencount
== 0) {
268 acd_prevent_allow(dev
, 1);
269 cdp
->flags
|= F_LOCKED
;
277 acd_close(struct dev_close_args
*ap
)
279 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
280 struct acd_softc
*cdp
= device_get_ivars(dev
);
281 struct ata_device
*atadev
= device_get_softc(dev
);
286 if (atadev
->opencount
== 1) {
287 acd_prevent_allow(dev
, 0);
288 cdp
->flags
&= ~F_LOCKED
;
290 if (atadev
->opencount
> 0)
296 acd_ioctl(struct dev_ioctl_args
*ap
)
298 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
299 struct ata_device
*atadev
= device_get_softc(dev
);
300 struct acd_softc
*cdp
= device_get_ivars(dev
);
301 int error
= 0, nocopyout
= 0;
306 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
314 acd_prevent_allow(dev
, 1);
315 cdp
->flags
|= F_LOCKED
;
323 error
= acd_pause_resume(dev
, 1);
327 error
= acd_pause_resume(dev
, 0);
331 error
= acd_start_stop(dev
, 1);
335 error
= acd_start_stop(dev
, 0);
339 error
= acd_prevent_allow(dev
, 0);
340 cdp
->flags
&= ~F_LOCKED
;
344 error
= acd_prevent_allow(dev
, 1);
345 cdp
->flags
|= F_LOCKED
;
349 error
= priv_check_cred(ap
->a_cred
, PRIV_ROOT
, 0);
352 error
= acd_test_ready(dev
);
356 if (atadev
->opencount
> 1) {
360 error
= acd_tray(dev
, 0);
364 if (atadev
->opencount
> 1)
366 error
= acd_tray(dev
, 1);
369 case CDIOREADTOCHEADER
:
370 if (!cdp
->toc
.hdr
.ending_track
) {
374 bcopy(&cdp
->toc
.hdr
, ap
->a_data
, sizeof(cdp
->toc
.hdr
));
377 case CDIOREADTOCENTRYS
:
379 struct ioc_read_toc_entry
*te
= (struct ioc_read_toc_entry
*)ap
->a_data
;
380 struct toc
*toc
= &cdp
->toc
;
381 int starting_track
= te
->starting_track
;
384 if (!toc
->hdr
.ending_track
) {
389 if (te
->data_len
< sizeof(toc
->tab
[0]) ||
390 (te
->data_len
% sizeof(toc
->tab
[0])) != 0 ||
391 (te
->address_format
!= CD_MSF_FORMAT
&&
392 te
->address_format
!= CD_LBA_FORMAT
)) {
398 starting_track
= toc
->hdr
.starting_track
;
399 else if (starting_track
== 170)
400 starting_track
= toc
->hdr
.ending_track
+ 1;
401 else if (starting_track
< toc
->hdr
.starting_track
||
402 starting_track
> toc
->hdr
.ending_track
+ 1) {
407 len
= ((toc
->hdr
.ending_track
+ 1 - starting_track
) + 1) *
409 if (te
->data_len
< len
)
411 if (len
> sizeof(toc
->tab
)) {
416 if (te
->address_format
== CD_MSF_FORMAT
) {
417 struct cd_toc_entry
*entry
;
419 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
420 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_INTWAIT
);
421 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
422 entry
= toc
->tab
+ (toc
->hdr
.ending_track
+ 1 -
423 toc
->hdr
.starting_track
) + 1;
424 while (--entry
>= toc
->tab
) {
425 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
426 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
427 entry
->addr_type
= CD_MSF_FORMAT
;
430 error
= copyout(toc
->tab
+ starting_track
- toc
->hdr
.starting_track
,
432 if (te
->address_format
== CD_MSF_FORMAT
)
437 case CDIOREADTOCENTRY
:
439 struct ioc_read_toc_single_entry
*te
=
440 (struct ioc_read_toc_single_entry
*)ap
->a_data
;
441 struct toc
*toc
= &cdp
->toc
;
442 u_char track
= te
->track
;
444 if (!toc
->hdr
.ending_track
) {
449 if (te
->address_format
!= CD_MSF_FORMAT
&&
450 te
->address_format
!= CD_LBA_FORMAT
) {
456 track
= toc
->hdr
.starting_track
;
457 else if (track
== 170)
458 track
= toc
->hdr
.ending_track
+ 1;
459 else if (track
< toc
->hdr
.starting_track
||
460 track
> toc
->hdr
.ending_track
+ 1) {
465 if (te
->address_format
== CD_MSF_FORMAT
) {
466 struct cd_toc_entry
*entry
;
468 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
469 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_INTWAIT
);
470 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
471 entry
= toc
->tab
+ (track
- toc
->hdr
.starting_track
);
472 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
473 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
475 bcopy(toc
->tab
+ track
- toc
->hdr
.starting_track
,
476 &te
->entry
, sizeof(struct cd_toc_entry
));
477 if (te
->address_format
== CD_MSF_FORMAT
)
482 /* XXX TGEN Remove this and the rest of the nocopyout logic? */
483 #if __FreeBSD_version > 600008
484 case CDIOCREADSUBCHANNEL_SYSSPACE
:
489 case CDIOCREADSUBCHANNEL
:
491 struct ioc_read_subchannel
*args
=
492 (struct ioc_read_subchannel
*)ap
->a_data
;
494 int8_t ccb
[16] = { ATAPI_READ_SUBCHANNEL
, 0, 0x40, 1, 0, 0, 0,
495 sizeof(cdp
->subchan
)>>8, sizeof(cdp
->subchan
),
496 0, 0, 0, 0, 0, 0, 0 };
498 if (args
->data_len
> sizeof(struct cd_sub_channel_info
) ||
499 args
->data_len
< sizeof(struct cd_sub_channel_header
)) {
504 format
= args
->data_format
;
505 if ((format
!= CD_CURRENT_POSITION
) &&
506 (format
!= CD_MEDIA_CATALOG
) && (format
!= CD_TRACK_INFO
)) {
511 ccb
[1] = args
->address_format
& CD_MSF_FORMAT
;
513 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
514 sizeof(cdp
->subchan
), ATA_R_READ
, 10)))
517 if ((format
== CD_MEDIA_CATALOG
) || (format
== CD_TRACK_INFO
)) {
518 if (cdp
->subchan
.header
.audio_status
== 0x11) {
524 if (format
== CD_TRACK_INFO
)
525 ccb
[6] = args
->track
;
527 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
528 sizeof(cdp
->subchan
),ATA_R_READ
,10))){
532 /* XXX TGEN Remove this and the rest of the nocopyout logic? */
533 if (nocopyout
== 0) {
534 error
= copyout(&cdp
->subchan
, args
->data
, args
->data_len
);
537 bcopy(&cdp
->subchan
, args
->data
, args
->data_len
);
544 struct ioc_play_msf
*args
= (struct ioc_play_msf
*)ap
->a_data
;
548 msf2lba(args
->start_m
, args
->start_s
, args
->start_f
),
549 msf2lba(args
->end_m
, args
->end_s
, args
->end_f
));
553 case CDIOCPLAYBLOCKS
:
555 struct ioc_play_blocks
*args
= (struct ioc_play_blocks
*)ap
->a_data
;
557 error
= acd_play(dev
, args
->blk
, args
->blk
+ args
->len
);
561 case CDIOCPLAYTRACKS
:
563 struct ioc_play_track
*args
= (struct ioc_play_track
*)ap
->a_data
;
566 if (!cdp
->toc
.hdr
.ending_track
) {
570 if (args
->end_track
< cdp
->toc
.hdr
.ending_track
+ 1)
572 if (args
->end_track
> cdp
->toc
.hdr
.ending_track
+ 1)
573 args
->end_track
= cdp
->toc
.hdr
.ending_track
+ 1;
574 t1
= args
->start_track
- cdp
->toc
.hdr
.starting_track
;
575 t2
= args
->end_track
- cdp
->toc
.hdr
.starting_track
;
576 if (t1
< 0 || t2
< 0 ||
577 t1
> (cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
)) {
581 error
= acd_play(dev
, ntohl(cdp
->toc
.tab
[t1
].addr
.lba
),
582 ntohl(cdp
->toc
.tab
[t2
].addr
.lba
));
588 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
590 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
591 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
594 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
598 arg
->vol
[0] = cdp
->au
.port
[0].volume
;
599 arg
->vol
[1] = cdp
->au
.port
[1].volume
;
600 arg
->vol
[2] = cdp
->au
.port
[2].volume
;
601 arg
->vol
[3] = cdp
->au
.port
[3].volume
;
607 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
609 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
610 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
612 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
616 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE_MASK
,
617 (caddr_t
)&cdp
->aumask
,
618 sizeof(cdp
->aumask
))))
620 cdp
->au
.data_length
= 0;
621 cdp
->au
.port
[0].channels
= CHANNEL_0
;
622 cdp
->au
.port
[1].channels
= CHANNEL_1
;
623 cdp
->au
.port
[0].volume
= arg
->vol
[0] & cdp
->aumask
.port
[0].volume
;
624 cdp
->au
.port
[1].volume
= arg
->vol
[1] & cdp
->aumask
.port
[1].volume
;
625 cdp
->au
.port
[2].volume
= arg
->vol
[2] & cdp
->aumask
.port
[2].volume
;
626 cdp
->au
.port
[3].volume
= arg
->vol
[3] & cdp
->aumask
.port
[3].volume
;
627 error
= acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
633 struct ioc_patch
*arg
= (struct ioc_patch
*)ap
->a_data
;
635 error
= acd_setchan(dev
, arg
->patch
[0], arg
->patch
[1],
636 arg
->patch
[2], arg
->patch
[3]);
641 error
= acd_setchan(dev
, CHANNEL_0
|CHANNEL_1
, CHANNEL_0
|CHANNEL_1
, 0,0);
645 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_1
, 0, 0);
649 error
= acd_setchan(dev
, 0, 0, 0, 0);
653 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_0
, 0, 0);
657 error
= acd_setchan(dev
, CHANNEL_1
, CHANNEL_1
, 0, 0);
661 error
= acd_blank(dev
, (*(int *)ap
->a_data
));
664 case CDRIOCNEXTWRITEABLEADDR
:
666 struct acd_track_info track_info
;
668 if ((error
= acd_read_track_info(dev
, 0xff, &track_info
)))
671 if (!track_info
.nwa_valid
) {
675 *(int*)ap
->a_data
= track_info
.next_writeable_addr
;
679 case CDRIOCINITWRITER
:
680 error
= acd_init_writer(dev
, (*(int *)ap
->a_data
));
683 case CDRIOCINITTRACK
:
684 error
= acd_init_track(dev
, (struct cdr_track
*)ap
->a_data
);
688 error
= acd_flush(dev
);
692 error
= acd_fixate(dev
, (*(int *)ap
->a_data
));
695 case CDRIOCREADSPEED
:
697 int speed
= *(int *)ap
->a_data
;
699 /* Preserve old behavior: units in multiples of CDROM speed */
702 error
= acd_set_speed(dev
, speed
, CDR_MAX_SPEED
);
706 case CDRIOCWRITESPEED
:
708 int speed
= *(int *)ap
->a_data
;
712 error
= acd_set_speed(dev
, CDR_MAX_SPEED
, speed
);
716 case CDRIOCGETBLOCKSIZE
:
717 *(int *)ap
->a_data
= cdp
->block_size
;
720 case CDRIOCSETBLOCKSIZE
:
721 cdp
->block_size
= *(int *)ap
->a_data
;
725 case CDRIOCGETPROGRESS
:
726 error
= acd_get_progress(dev
, (int *)ap
->a_data
);
730 error
= acd_send_cue(dev
, (struct cdr_cuesheet
*)ap
->a_data
);
733 #ifdef ACD_CDR_FORMAT
734 case CDRIOCREADFORMATCAPS
:
735 error
= acd_read_format_caps(dev
,
736 (struct cdr_format_capacities
*)ap
->a_data
);
740 error
= acd_format(dev
, (struct cdr_format_params
*)ap
->a_data
);
742 #endif /* ACD_CDR_FORMAT */
744 case DVDIOCREPORTKEY
:
745 if (cdp
->cap
.media
& MST_READ_DVDROM
)
746 error
= acd_report_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
752 if (cdp
->cap
.media
& MST_READ_DVDROM
)
753 error
= acd_send_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
758 case DVDIOCREADSTRUCTURE
:
759 if (cdp
->cap
.media
& MST_READ_DVDROM
)
760 error
= acd_read_structure(dev
, (struct dvd_struct
*)ap
->a_data
);
766 error
= ata_device_ioctl(dev
, ap
->a_cmd
, ap
->a_data
);
772 acd_strategy(struct dev_strategy_args
*ap
)
774 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
775 struct bio
*bp
= ap
->a_bio
;
776 struct buf
*bbp
= bp
->bio_buf
;
777 /* struct ata_device *atadev = device_get_softc(dev);*/
778 struct acd_softc
*cdp
= device_get_ivars(dev
);
779 cdev_t cdev
= cdp
->cdev
;
781 if (bbp
->b_cmd
!= BUF_CMD_READ
&& bbp
->b_cmd
!= BUF_CMD_WRITE
) {
782 bbp
->b_flags
|= B_ERROR
;
783 bbp
->b_error
= EOPNOTSUPP
;
788 if (bbp
->b_cmd
== BUF_CMD_READ
&& cdp
->disk_size
== -1) {
789 bbp
->b_flags
|= B_ERROR
;
795 KASSERT(bbp
->b_bcount
!= 0, ("acd_strategy: 0-length I/O"));
797 bp
->bio_driver_info
= cdev
;
798 bbp
->b_resid
= bbp
->b_bcount
;
804 /* XXX TGEN Collapse this with acd_strategy()? */
806 acd_start(device_t dev
, struct bio
*bp
)
808 struct buf
*bbp
= bp
->bio_buf
;
809 struct ata_device
*atadev
= device_get_softc(dev
);
810 struct acd_softc
*cdp
= device_get_ivars(dev
);
811 struct ata_request
*request
;
813 u_int32_t lba
, lastlba
, count
;
815 int track
, blocksize
;
817 cdev
= bp
->bio_driver_info
;
819 /* reject all queued entries if media changed */
820 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
821 bbp
->b_flags
|= B_ERROR
;
827 bzero(ccb
, sizeof(ccb
));
830 * Special track access is via bio_offset (128-255), and direct
831 * raw access via 128, else normal accesses.
833 track
= (bp
->bio_offset
>> 56) & 127;
836 if (track
> MAXTRK
) {
837 bbp
->b_flags
|= B_ERROR
;
842 blocksize
= (cdp
->toc
.tab
[track
- 1].control
& 4) ? 2048 : 2352;
843 lastlba
= ntohl(cdp
->toc
.tab
[track
].addr
.lba
);
844 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
845 lba
+= ntohl(cdp
->toc
.tab
[track
- 1].addr
.lba
);
848 blocksize
= cdp
->block_size
;
849 lastlba
= cdp
->disk_size
;
850 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
853 count
= bbp
->b_bcount
/ blocksize
;
854 KASSERT(count
!= 0, ("acd_strategy: 0-length I/O %d bytes vs %d blksize",
855 bbp
->b_bcount
, blocksize
));
857 if (bbp
->b_cmd
== BUF_CMD_READ
) {
858 /* if transfer goes beyond range adjust it to be within limits */
859 if (lba
+ count
> lastlba
) {
860 /* if we are entirely beyond EOM return EOF */
861 if (lastlba
<= lba
) {
862 bbp
->b_resid
= bbp
->b_bcount
;
866 count
= lastlba
- lba
;
870 ccb
[0] = ATAPI_READ_BIG
;
874 ccb
[0] = ATAPI_READ_CD
;
879 ccb
[0] = ATAPI_READ_CD
;
884 ccb
[0] = ATAPI_WRITE_BIG
;
895 if (!(request
= ata_alloc_request())) {
896 bbp
->b_flags
|= B_ERROR
;
897 bbp
->b_error
= ENOMEM
;
903 bcopy(ccb
, request
->u
.atapi
.ccb
,
904 (atadev
->param
.config
& ATA_PROTO_MASK
) ==
905 ATA_PROTO_ATAPI_12
? 16 : 12);
906 request
->data
= bbp
->b_data
;
907 request
->bytecount
= count
* blocksize
;
908 request
->transfersize
= min(request
->bytecount
, 65534);
909 request
->timeout
= (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30;
910 request
->retries
= 2;
911 request
->callback
= acd_done
;
912 request
->flags
= ATA_R_ATAPI
;
913 if (atadev
->mode
>= ATA_DMA
)
914 request
->flags
|= ATA_R_DMA
;
915 switch (bbp
->b_cmd
) {
917 request
->flags
|= ATA_R_READ
;
920 request
->flags
|= ATA_R_WRITE
;
923 device_printf(dev
, "unknown BUF operation\n");
924 ata_free_request(request
);
925 bbp
->b_flags
|= B_ERROR
;
930 devstat_start_transaction(&cdp
->stats
);
931 ata_queue_request(request
);
935 acd_done(struct ata_request
*request
)
937 struct acd_softc
*cdp
= device_get_ivars(request
->dev
);
938 struct bio
*bp
= request
->bio
;
939 struct buf
*bbp
= bp
->bio_buf
;
941 /* finish up transfer */
942 if ((bbp
->b_error
= request
->result
))
943 bbp
->b_flags
|= B_ERROR
;
944 bbp
->b_resid
= bbp
->b_bcount
- request
->donecount
;
945 devstat_end_transaction_buf(&cdp
->stats
, bbp
);
947 ata_free_request(request
);
951 acd_set_ioparm(device_t dev
)
953 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
954 struct acd_softc
*cdp
= device_get_ivars(dev
);
955 struct disk_info info
;
958 cdp
->iomax
= min(ch
->dma
->max_iosize
, 65534);
960 cdp
->iomax
= min(DFLTPHYS
, 65534);
962 cdp
->cdev
->si_iosize_max
= (cdp
->iomax
/ cdp
->block_size
) * cdp
->block_size
;
963 cdp
->cdev
->si_bsize_phys
= cdp
->block_size
;
964 bzero(&info
, sizeof(info
));
965 info
.d_media_blksize
= cdp
->block_size
;
966 info
.d_media_blocks
= (cdp
->disk_size
== -1) ? 0 : cdp
->disk_size
;
967 info
.d_secpertrack
= 100;
969 info
.d_ncylinders
= cdp
->disk_size
/ info
.d_secpertrack
/ info
.d_nheads
+ 1;
970 info
.d_secpercyl
= info
.d_secpertrack
* info
.d_nheads
;
971 info
.d_dsflags
= DSO_ONESLICE
| DSO_COMPATLABEL
| DSO_COMPATPARTA
|
973 disk_setdiskinfo(&cdp
->disk
, &info
);
978 lba2msf(u_int32_t lba
, u_int8_t
*m
, u_int8_t
*s
, u_int8_t
*f
)
982 *m
= lba
/ (60 * 75);
989 msf2lba(u_int8_t m
, u_int8_t s
, u_int8_t f
)
991 return (m
* 60 + s
) * 75 + f
- 150;
995 acd_read_toc(device_t dev
)
997 struct ata_device
*atadev
= device_get_softc(dev
);
998 struct acd_softc
*cdp
= device_get_ivars(dev
);
999 struct acd_tracknode
*tracknode
;
1002 int track
, ntracks
, len
;
1004 atadev
->flags
&= ~ATA_D_MEDIA_CHANGED
;
1005 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1007 if (acd_test_ready(dev
))
1010 bzero(ccb
, sizeof(ccb
));
1011 len
= sizeof(struct ioc_toc_header
) + sizeof(struct cd_toc_entry
);
1012 ccb
[0] = ATAPI_READ_TOC
;
1015 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1016 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1017 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1020 ntracks
= cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1;
1021 if (ntracks
<= 0 || ntracks
> MAXTRK
) {
1022 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1026 len
= sizeof(struct ioc_toc_header
)+(ntracks
+1)*sizeof(struct cd_toc_entry
);
1027 bzero(ccb
, sizeof(ccb
));
1028 ccb
[0] = ATAPI_READ_TOC
;
1031 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1032 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1033 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1036 cdp
->toc
.hdr
.len
= ntohs(cdp
->toc
.hdr
.len
);
1038 cdp
->block_size
= (cdp
->toc
.tab
[0].control
& 4) ? 2048 : 2352;
1039 bzero(ccb
, sizeof(ccb
));
1040 ccb
[0] = ATAPI_READ_CAPACITY
;
1041 if (ata_atapicmd(dev
, ccb
, (caddr_t
)sizes
, sizeof(sizes
),
1042 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1043 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1046 cdp
->disk_size
= ntohl(sizes
[0]) + 1;
1047 acd_set_ioparm(dev
);
1049 for (track
= 1; track
<= ntracks
; track
++) {
1050 if (cdp
->track
[track
] != NULL
)
1053 tracknode
= acd_make_tracknode(dev
, track
);
1056 cdp
->track
[track
] = tracknode
;
1058 for (; track
< MAXTRK
; track
++) {
1059 if (cdp
->track
[track
] == NULL
)
1061 acd_destroy_tracknode(dev
, track
);
1062 cdp
->track
[track
] = NULL
;
1066 if (cdp
->disk_size
&& cdp
->toc
.hdr
.ending_track
) {
1067 device_printf(dev
, "(%d sectors (%d bytes)), %d tracks ",
1068 cdp
->disk_size
, cdp
->block_size
,
1069 cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
+1);
1070 if (cdp
->toc
.tab
[0].control
& 4)
1071 kprintf("%dMB\n", cdp
->disk_size
* cdp
->block_size
/ 1048576);
1073 kprintf("%d:%d audio\n",
1074 cdp
->disk_size
/ 75 / 60, cdp
->disk_size
/ 75 % 60);
1080 * Makes a new device node for the numbered track and returns a struct
1081 * acd_tracknode pointer to be included in the list of tracks available on the
1087 static struct acd_tracknode
*
1088 acd_make_tracknode(device_t dev
, int track
)
1090 struct acd_softc
*cdp
= device_get_ivars(dev
);
1091 struct acd_tracknode
*tracknode
;
1094 ksprintf(name
, "acd%dt%d", device_get_unit(dev
), track
);
1095 tracknode
= kmalloc(sizeof(struct acd_tracknode
), M_ACD
, M_WAITOK
| M_ZERO
);
1096 tracknode
->cdev
= make_dev(&acd_ops
, (device_get_unit(dev
) << 3) |
1097 (track
<< 16), UID_ROOT
, GID_OPERATOR
, 0644,
1099 tracknode
->cdev
->si_drv1
= cdp
->cdev
->si_drv1
;
1100 reference_dev(tracknode
->cdev
);
1107 * Destroys the device node of a numbered track and frees the related struct
1108 * acd_tracknode. It could be done just in acd_read_toc(), but it's nice to
1109 * have a complementary function to acd_make_tracknode().
1112 acd_destroy_tracknode(device_t dev
, int track
)
1114 struct acd_softc
*cdp
= device_get_ivars(dev
);
1115 struct acd_tracknode
*tracknode
;
1117 tracknode
= cdp
->track
[track
];
1118 destroy_dev(tracknode
->cdev
);
1119 kfree(tracknode
, M_ACD
);
1123 acd_play(device_t dev
, int start
, int end
)
1127 bzero(ccb
, sizeof(ccb
));
1128 ccb
[0] = ATAPI_PLAY_MSF
;
1129 lba2msf(start
, &ccb
[3], &ccb
[4], &ccb
[5]);
1130 lba2msf(end
, &ccb
[6], &ccb
[7], &ccb
[8]);
1131 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 10);
1135 acd_setchan(device_t dev
, u_int8_t c0
, u_int8_t c1
, u_int8_t c2
, u_int8_t c3
)
1137 struct acd_softc
*cdp
= device_get_ivars(dev
);
1140 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
, (caddr_t
)&cdp
->au
,
1143 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
)
1145 cdp
->au
.data_length
= 0;
1146 cdp
->au
.port
[0].channels
= c0
;
1147 cdp
->au
.port
[1].channels
= c1
;
1148 cdp
->au
.port
[2].channels
= c2
;
1149 cdp
->au
.port
[3].channels
= c3
;
1150 return acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
1154 acd_init_writer(device_t dev
, int test_write
)
1158 bzero(ccb
, sizeof(ccb
));
1159 ccb
[0] = ATAPI_REZERO
;
1160 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1161 ccb
[0] = ATAPI_SEND_OPC_INFO
;
1163 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 30);
1168 acd_fixate(device_t dev
, int multisession
)
1170 struct acd_softc
*cdp
= device_get_ivars(dev
);
1171 int8_t ccb
[16] = { ATAPI_CLOSE_TRACK
, 0x01, 0x02, 0, 0, 0, 0, 0,
1172 0, 0, 0, 0, 0, 0, 0, 0 };
1173 int timeout
= 5*60*2;
1175 struct write_param param
;
1177 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1178 (caddr_t
)¶m
, sizeof(param
))))
1181 param
.data_length
= 0;
1183 param
.session_type
= CDR_SESS_MULTI
;
1185 param
.session_type
= CDR_SESS_NONE
;
1187 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1190 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1194 /* some drives just return ready, wait for the expected fixate time */
1195 if ((error
= acd_test_ready(dev
)) != EBUSY
) {
1196 timeout
= timeout
/ (cdp
->cap
.cur_write_speed
/ 177);
1197 tsleep(&error
, 0, "acdfix", timeout
* hz
/ 2);
1198 return acd_test_ready(dev
);
1201 while (timeout
-- > 0) {
1202 if ((error
= acd_get_progress(dev
, &dummy
)))
1204 if ((error
= acd_test_ready(dev
)) != EBUSY
)
1206 tsleep(&error
, 0, "acdcld", hz
/ 2);
1212 acd_init_track(device_t dev
, struct cdr_track
*track
)
1214 struct acd_softc
*cdp
= device_get_ivars(dev
);
1215 struct write_param param
;
1218 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1219 (caddr_t
)¶m
, sizeof(param
))))
1222 param
.data_length
= 0;
1223 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1224 param
.page_length
= 0x32;
1225 param
.test_write
= track
->test_write
? 1 : 0;
1226 param
.write_type
= CDR_WTYPE_TRACK
;
1227 param
.session_type
= CDR_SESS_NONE
;
1229 param
.packet_size
= 0;
1231 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1232 param
.burnproof
= 1;
1234 switch (track
->datablock_type
) {
1238 param
.track_mode
= CDR_TMODE_AUDIO_PREEMP
;
1240 param
.track_mode
= CDR_TMODE_AUDIO
;
1241 cdp
->block_size
= 2352;
1242 param
.datablock_type
= CDR_DB_RAW
;
1243 param
.session_format
= CDR_SESS_CDROM
;
1246 case CDR_DB_ROM_MODE1
:
1247 cdp
->block_size
= 2048;
1248 param
.track_mode
= CDR_TMODE_DATA
;
1249 param
.datablock_type
= CDR_DB_ROM_MODE1
;
1250 param
.session_format
= CDR_SESS_CDROM
;
1253 case CDR_DB_ROM_MODE2
:
1254 cdp
->block_size
= 2336;
1255 param
.track_mode
= CDR_TMODE_DATA
;
1256 param
.datablock_type
= CDR_DB_ROM_MODE2
;
1257 param
.session_format
= CDR_SESS_CDROM
;
1260 case CDR_DB_XA_MODE1
:
1261 cdp
->block_size
= 2048;
1262 param
.track_mode
= CDR_TMODE_DATA
;
1263 param
.datablock_type
= CDR_DB_XA_MODE1
;
1264 param
.session_format
= CDR_SESS_CDROM_XA
;
1267 case CDR_DB_XA_MODE2_F1
:
1268 cdp
->block_size
= 2056;
1269 param
.track_mode
= CDR_TMODE_DATA
;
1270 param
.datablock_type
= CDR_DB_XA_MODE2_F1
;
1271 param
.session_format
= CDR_SESS_CDROM_XA
;
1274 case CDR_DB_XA_MODE2_F2
:
1275 cdp
->block_size
= 2324;
1276 param
.track_mode
= CDR_TMODE_DATA
;
1277 param
.datablock_type
= CDR_DB_XA_MODE2_F2
;
1278 param
.session_format
= CDR_SESS_CDROM_XA
;
1281 case CDR_DB_XA_MODE2_MIX
:
1282 cdp
->block_size
= 2332;
1283 param
.track_mode
= CDR_TMODE_DATA
;
1284 param
.datablock_type
= CDR_DB_XA_MODE2_MIX
;
1285 param
.session_format
= CDR_SESS_CDROM_XA
;
1288 acd_set_ioparm(dev
);
1289 return acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10);
1293 acd_flush(device_t dev
)
1295 int8_t ccb
[16] = { ATAPI_SYNCHRONIZE_CACHE
, 0, 0, 0, 0, 0, 0, 0,
1296 0, 0, 0, 0, 0, 0, 0, 0 };
1298 return ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1302 acd_read_track_info(device_t dev
, int32_t lba
, struct acd_track_info
*info
)
1304 int8_t ccb
[16] = { ATAPI_READ_TRACK_INFO
, 1,
1305 lba
>>24, lba
>>16, lba
>>8, lba
, 0,
1306 sizeof(*info
)>>8, sizeof(*info
),
1307 0, 0, 0, 0, 0, 0, 0 };
1310 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)info
, sizeof(*info
),
1313 info
->track_start_addr
= ntohl(info
->track_start_addr
);
1314 info
->next_writeable_addr
= ntohl(info
->next_writeable_addr
);
1315 info
->free_blocks
= ntohl(info
->free_blocks
);
1316 info
->fixed_packet_size
= ntohl(info
->fixed_packet_size
);
1317 info
->track_length
= ntohl(info
->track_length
);
1322 acd_get_progress(device_t dev
, int *finished
)
1324 int8_t ccb
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
1325 0, 0, 0, 0, 0, 0, 0, 0 };
1326 struct ata_request
*request
;
1329 if (!(request
= ata_alloc_request()))
1333 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
1334 request
->data
= dummy
;
1335 request
->bytecount
= sizeof(dummy
);
1336 request
->transfersize
= min(request
->bytecount
, 65534);
1337 request
->flags
= ATA_R_ATAPI
| ATA_R_READ
;
1338 request
->timeout
= 30;
1339 ata_queue_request(request
);
1340 if (!request
->error
&&
1341 request
->u
.atapi
.sense
.specific
& ATA_SENSE_SPEC_VALID
)
1342 *finished
= ((request
->u
.atapi
.sense
.specific2
|
1343 (request
->u
.atapi
.sense
.specific1
<< 8)) * 100) / 65535;
1346 ata_free_request(request
);
1351 acd_send_cue(device_t dev
, struct cdr_cuesheet
*cuesheet
)
1353 struct acd_softc
*cdp
= device_get_ivars(dev
);
1354 struct write_param param
;
1355 int8_t ccb
[16] = { ATAPI_SEND_CUE_SHEET
, 0, 0, 0, 0, 0,
1356 cuesheet
->len
>>16, cuesheet
->len
>>8, cuesheet
->len
,
1357 0, 0, 0, 0, 0, 0, 0 };
1361 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1362 (caddr_t
)¶m
, sizeof(param
))))
1365 param
.data_length
= 0;
1366 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1367 param
.page_length
= 0x32;
1368 param
.test_write
= cuesheet
->test_write
? 1 : 0;
1369 param
.write_type
= CDR_WTYPE_SESSION
;
1370 param
.session_type
= cuesheet
->session_type
;
1372 param
.packet_size
= 0;
1373 param
.track_mode
= CDR_TMODE_AUDIO
;
1374 param
.datablock_type
= CDR_DB_RAW
;
1375 param
.session_format
= cuesheet
->session_format
;
1376 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1377 param
.burnproof
= 1;
1379 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1382 if (!(buffer
= kmalloc(cuesheet
->len
, M_ACD
, M_WAITOK
| M_NULLOK
)))
1385 if (!(error
= copyin(cuesheet
->entries
, buffer
, cuesheet
->len
)))
1386 error
= ata_atapicmd(dev
, ccb
, buffer
, cuesheet
->len
, 0, 30);
1387 kfree(buffer
, M_ACD
);
1392 acd_report_key(device_t dev
, struct dvd_authinfo
*ai
)
1394 struct dvd_miscauth
*d
= NULL
;
1400 switch (ai
->format
) {
1401 case DVD_REPORT_AGID
:
1402 case DVD_REPORT_ASF
:
1403 case DVD_REPORT_RPC
:
1406 case DVD_REPORT_KEY1
:
1409 case DVD_REPORT_TITLE_KEY
:
1413 case DVD_REPORT_CHALLENGE
:
1416 case DVD_INVALIDATE_AGID
:
1423 bzero(ccb
, sizeof(ccb
));
1424 ccb
[0] = ATAPI_REPORT_KEY
;
1425 ccb
[2] = (lba
>> 24) & 0xff;
1426 ccb
[3] = (lba
>> 16) & 0xff;
1427 ccb
[4] = (lba
>> 8) & 0xff;
1428 ccb
[5] = lba
& 0xff;
1429 ccb
[8] = (length
>> 8) & 0xff;
1430 ccb
[9] = length
& 0xff;
1431 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1434 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1435 d
->length
= htons(length
- 2);
1438 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
,
1439 ai
->format
== DVD_INVALIDATE_AGID
? 0 : ATA_R_READ
,10);
1446 switch (ai
->format
) {
1447 case DVD_REPORT_AGID
:
1448 ai
->agid
= d
->data
[3] >> 6;
1451 case DVD_REPORT_CHALLENGE
:
1452 bcopy(&d
->data
[0], &ai
->keychal
[0], 10);
1455 case DVD_REPORT_KEY1
:
1456 bcopy(&d
->data
[0], &ai
->keychal
[0], 5);
1459 case DVD_REPORT_TITLE_KEY
:
1460 ai
->cpm
= (d
->data
[0] >> 7);
1461 ai
->cp_sec
= (d
->data
[0] >> 6) & 0x1;
1462 ai
->cgms
= (d
->data
[0] >> 4) & 0x3;
1463 bcopy(&d
->data
[1], &ai
->keychal
[0], 5);
1466 case DVD_REPORT_ASF
:
1467 ai
->asf
= d
->data
[3] & 1;
1470 case DVD_REPORT_RPC
:
1471 ai
->reg_type
= (d
->data
[0] >> 6);
1472 ai
->vend_rsts
= (d
->data
[0] >> 3) & 0x7;
1473 ai
->user_rsts
= d
->data
[0] & 0x7;
1474 ai
->region
= d
->data
[1];
1475 ai
->rpc_scheme
= d
->data
[2];
1478 case DVD_INVALIDATE_AGID
:
1490 acd_send_key(device_t dev
, struct dvd_authinfo
*ai
)
1492 struct dvd_miscauth
*d
;
1497 switch (ai
->format
) {
1498 case DVD_SEND_CHALLENGE
:
1500 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1501 bcopy(ai
->keychal
, &d
->data
[0], 10);
1506 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1507 bcopy(&ai
->keychal
[0], &d
->data
[0], 5);
1512 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1513 d
->data
[0] = ai
->region
;
1520 bzero(ccb
, sizeof(ccb
));
1521 ccb
[0] = ATAPI_SEND_KEY
;
1522 ccb
[8] = (length
>> 8) & 0xff;
1523 ccb
[9] = length
& 0xff;
1524 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1525 d
->length
= htons(length
- 2);
1526 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, 0, 10);
1532 acd_read_structure(device_t dev
, struct dvd_struct
*s
)
1534 struct dvd_miscauth
*d
;
1540 case DVD_STRUCT_PHYSICAL
:
1544 case DVD_STRUCT_COPYRIGHT
:
1548 case DVD_STRUCT_DISCKEY
:
1552 case DVD_STRUCT_BCA
:
1556 case DVD_STRUCT_MANUFACT
:
1560 case DVD_STRUCT_DDS
:
1561 case DVD_STRUCT_PRERECORDED
:
1562 case DVD_STRUCT_UNIQUEID
:
1563 case DVD_STRUCT_LIST
:
1564 case DVD_STRUCT_CMI
:
1565 case DVD_STRUCT_RMD_LAST
:
1566 case DVD_STRUCT_RMD_RMA
:
1567 case DVD_STRUCT_DCB
:
1574 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1575 d
->length
= htons(length
- 2);
1577 bzero(ccb
, sizeof(ccb
));
1578 ccb
[0] = ATAPI_READ_STRUCTURE
;
1579 ccb
[6] = s
->layer_num
;
1581 ccb
[8] = (length
>> 8) & 0xff;
1582 ccb
[9] = length
& 0xff;
1583 ccb
[10] = s
->agid
<< 6;
1584 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, ATA_R_READ
, 30);
1590 switch (s
->format
) {
1591 case DVD_STRUCT_PHYSICAL
: {
1592 struct dvd_layer
*layer
= (struct dvd_layer
*)&s
->data
[0];
1594 layer
->book_type
= d
->data
[0] >> 4;
1595 layer
->book_version
= d
->data
[0] & 0xf;
1596 layer
->disc_size
= d
->data
[1] >> 4;
1597 layer
->max_rate
= d
->data
[1] & 0xf;
1598 layer
->nlayers
= (d
->data
[2] >> 5) & 3;
1599 layer
->track_path
= (d
->data
[2] >> 4) & 1;
1600 layer
->layer_type
= d
->data
[2] & 0xf;
1601 layer
->linear_density
= d
->data
[3] >> 4;
1602 layer
->track_density
= d
->data
[3] & 0xf;
1603 layer
->start_sector
= d
->data
[5] << 16 | d
->data
[6] << 8 | d
->data
[7];
1604 layer
->end_sector
= d
->data
[9] << 16 | d
->data
[10] << 8 | d
->data
[11];
1605 layer
->end_sector_l0
= d
->data
[13] << 16 | d
->data
[14] << 8|d
->data
[15];
1606 layer
->bca
= d
->data
[16] >> 7;
1610 case DVD_STRUCT_COPYRIGHT
:
1611 s
->cpst
= d
->data
[0];
1612 s
->rmi
= d
->data
[1];
1615 case DVD_STRUCT_DISCKEY
:
1616 bcopy(&d
->data
[0], &s
->data
[0], 2048);
1619 case DVD_STRUCT_BCA
:
1620 s
->length
= ntohs(d
->length
);
1621 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1624 case DVD_STRUCT_MANUFACT
:
1625 s
->length
= ntohs(d
->length
);
1626 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1637 acd_tray(device_t dev
, int close
)
1639 struct ata_device
*atadev
= device_get_softc(dev
);
1640 struct acd_softc
*cdp
= device_get_ivars(dev
);
1643 if (cdp
->cap
.mechanism
& MST_EJECT
) {
1645 if (!(error
= acd_start_stop(dev
, 3))) {
1647 acd_prevent_allow(dev
, 1);
1648 cdp
->flags
|= F_LOCKED
;
1652 acd_start_stop(dev
, 0);
1653 acd_prevent_allow(dev
, 0);
1654 cdp
->flags
&= ~F_LOCKED
;
1655 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1656 error
= acd_start_stop(dev
, 2);
1663 acd_blank(device_t dev
, int blanktype
)
1665 struct ata_device
*atadev
= device_get_softc(dev
);
1666 int8_t ccb
[16] = { ATAPI_BLANK
, 0x10 | (blanktype
& 0x7), 0, 0, 0, 0, 0, 0,
1667 0, 0, 0, 0, 0, 0, 0, 0 };
1669 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1670 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1674 acd_prevent_allow(device_t dev
, int lock
)
1676 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
1677 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1679 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1683 acd_start_stop(device_t dev
, int start
)
1685 int8_t ccb
[16] = { ATAPI_START_STOP
, 0, 0, 0, start
,
1686 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1688 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1692 acd_pause_resume(device_t dev
, int pause
)
1694 int8_t ccb
[16] = { ATAPI_PAUSE
, 0, 0, 0, 0, 0, 0, 0, pause
,
1695 0, 0, 0, 0, 0, 0, 0 };
1697 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1701 acd_mode_sense(device_t dev
, int page
, caddr_t pagebuf
, int pagesize
)
1703 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, page
, 0, 0, 0, 0,
1704 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1707 error
= ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, ATA_R_READ
, 10);
1712 acd_mode_select(device_t dev
, caddr_t pagebuf
, int pagesize
)
1714 int8_t ccb
[16] = { ATAPI_MODE_SELECT_BIG
, 0x10, 0, 0, 0, 0, 0,
1715 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1717 return ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, 0, 30);
1721 acd_set_speed(device_t dev
, int rdspeed
, int wrspeed
)
1723 int8_t ccb
[16] = { ATAPI_SET_SPEED
, 0, rdspeed
>> 8, rdspeed
,
1724 wrspeed
>> 8, wrspeed
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1727 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1734 acd_get_cap(device_t dev
)
1736 struct acd_softc
*cdp
= device_get_ivars(dev
);
1737 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, ATAPI_CDROM_CAP_PAGE
,
1738 0, 0, 0, 0, sizeof(cdp
->cap
)>>8, sizeof(cdp
->cap
),
1739 0, 0, 0, 0, 0, 0, 0 };
1742 /* get drive capabilities, some bugridden drives needs this repeated */
1743 for (count
= 0 ; count
< 5 ; count
++) {
1744 if (!ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->cap
, sizeof(cdp
->cap
),
1745 ATA_R_READ
| ATA_R_QUIET
, 5)) {
1746 cdp
->cap
.max_read_speed
= ntohs(cdp
->cap
.max_read_speed
);
1747 cdp
->cap
.cur_read_speed
= ntohs(cdp
->cap
.cur_read_speed
);
1748 cdp
->cap
.max_write_speed
= ntohs(cdp
->cap
.max_write_speed
);
1749 cdp
->cap
.cur_write_speed
= max(ntohs(cdp
->cap
.cur_write_speed
),177);
1750 cdp
->cap
.max_vol_levels
= ntohs(cdp
->cap
.max_vol_levels
);
1751 cdp
->cap
.buf_size
= ntohs(cdp
->cap
.buf_size
);
1756 #ifdef ACD_CDR_FORMAT
1758 acd_read_format_caps(device_t dev
, struct cdr_format_capacities
*caps
)
1760 int8_t ccb
[16] = { ATAPI_READ_FORMAT_CAPACITIES
, 0, 0, 0, 0, 0, 0,
1761 (sizeof(struct cdr_format_capacities
) >> 8) & 0xff,
1762 sizeof(struct cdr_format_capacities
) & 0xff,
1763 0, 0, 0, 0, 0, 0, 0 };
1765 return ata_atapicmd(dev
, ccb
, (caddr_t
)caps
,
1766 sizeof(struct cdr_format_capacities
), ATA_R_READ
, 30);
1770 acd_format(device_t dev
, struct cdr_format_params
* params
)
1772 int8_t ccb
[16] = { ATAPI_FORMAT
, 0x11, 0, 0, 0, 0, 0, 0, 0, 0,
1776 error
= ata_atapicmd(dev
, ccb
, (u_int8_t
*)params
,
1777 sizeof(struct cdr_format_params
), 0, 30);
1780 #endif /* ACD_CDR_FORMAT */
1783 acd_test_ready(device_t dev
)
1785 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
1786 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1788 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1792 acd_describe(device_t dev
)
1794 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
1795 struct ata_device
*atadev
= device_get_softc(dev
);
1796 struct acd_softc
*cdp
= device_get_ivars(dev
);
1801 device_printf(dev
, "<%.40s/%.8s> %s drive at ata%d as %s\n",
1802 atadev
->param
.model
, atadev
->param
.revision
,
1803 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1804 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1805 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1806 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1807 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM":"CDROM",
1808 device_get_unit(ch
->dev
),
1809 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave");
1811 device_printf(dev
, "%s", "");
1812 if (cdp
->cap
.cur_read_speed
) {
1813 kprintf("read %dKB/s", cdp
->cap
.cur_read_speed
* 1000 / 1024);
1814 if (cdp
->cap
.max_read_speed
)
1815 kprintf(" (%dKB/s)", cdp
->cap
.max_read_speed
* 1000 / 1024);
1816 if ((cdp
->cap
.cur_write_speed
) &&
1817 (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1818 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
))) {
1819 kprintf(" write %dKB/s", cdp
->cap
.cur_write_speed
* 1000 / 1024);
1820 if (cdp
->cap
.max_write_speed
)
1821 kprintf(" (%dKB/s)", cdp
->cap
.max_write_speed
* 1000 / 1024);
1825 if (cdp
->cap
.buf_size
) {
1826 kprintf("%s %dKB buffer", comma
? "," : "", cdp
->cap
.buf_size
);
1829 kprintf("%s %s\n", comma
? "," : "", ata_mode2str(atadev
->mode
));
1831 device_printf(dev
, "Reads:");
1833 if (cdp
->cap
.media
& MST_READ_CDR
) {
1834 kprintf(" CDR"); comma
= 1;
1836 if (cdp
->cap
.media
& MST_READ_CDRW
) {
1837 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1839 if (cdp
->cap
.capabilities
& MST_READ_CDDA
) {
1840 if (cdp
->cap
.capabilities
& MST_CDDA_STREAM
)
1841 kprintf("%s CDDA stream", comma
? "," : "");
1843 kprintf("%s CDDA", comma
? "," : "");
1846 if (cdp
->cap
.media
& MST_READ_DVDROM
) {
1847 kprintf("%s DVDROM", comma
? "," : ""); comma
= 1;
1849 if (cdp
->cap
.media
& MST_READ_DVDR
) {
1850 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1852 if (cdp
->cap
.media
& MST_READ_DVDRAM
) {
1853 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1855 if (cdp
->cap
.media
& MST_READ_PACKET
)
1856 kprintf("%s packet", comma
? "," : "");
1859 device_printf(dev
, "Writes:");
1860 if (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1861 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
)) {
1863 if (cdp
->cap
.media
& MST_WRITE_CDR
) {
1864 kprintf(" CDR" ); comma
= 1;
1866 if (cdp
->cap
.media
& MST_WRITE_CDRW
) {
1867 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1869 if (cdp
->cap
.media
& MST_WRITE_DVDR
) {
1870 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1872 if (cdp
->cap
.media
& MST_WRITE_DVDRAM
) {
1873 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1875 if (cdp
->cap
.media
& MST_WRITE_TEST
) {
1876 kprintf("%s test write", comma
? "," : ""); comma
= 1;
1878 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1879 kprintf("%s burnproof", comma
? "," : "");
1882 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
) {
1883 device_printf(dev
, "Audio: ");
1884 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
)
1886 if (cdp
->cap
.max_vol_levels
)
1887 kprintf(", %d volume levels", cdp
->cap
.max_vol_levels
);
1890 device_printf(dev
, "Mechanism: ");
1891 switch (cdp
->cap
.mechanism
& MST_MECH_MASK
) {
1892 case MST_MECH_CADDY
:
1893 mechanism
= "caddy"; break;
1895 mechanism
= "tray"; break;
1896 case MST_MECH_POPUP
:
1897 mechanism
= "popup"; break;
1898 case MST_MECH_CHANGER
:
1899 mechanism
= "changer"; break;
1900 case MST_MECH_CARTRIDGE
:
1901 mechanism
= "cartridge"; break;
1903 mechanism
= 0; break;
1906 kprintf("%s%s", (cdp
->cap
.mechanism
& MST_EJECT
) ?
1907 "ejectable " : "", mechanism
);
1908 else if (cdp
->cap
.mechanism
& MST_EJECT
)
1909 kprintf("ejectable");
1911 if (cdp
->cap
.mechanism
& MST_LOCKABLE
)
1912 kprintf((cdp
->cap
.mechanism
& MST_LOCKED
) ? ", locked":", unlocked");
1913 if (cdp
->cap
.mechanism
& MST_PREVENT
)
1914 kprintf(", lock protected");
1917 if ((cdp
->cap
.mechanism
& MST_MECH_MASK
) != MST_MECH_CHANGER
) {
1918 device_printf(dev
, "Medium: ");
1919 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1921 kprintf("CD-ROM "); break;
1923 kprintf("CD-R "); break;
1925 kprintf("CD-RW "); break;
1927 kprintf("DVD "); break;
1929 kprintf("door open"); break;
1931 kprintf("no/blank disc"); break;
1933 kprintf("medium format error"); break;
1935 if ((cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
)<MST_TYPE_MASK_HIGH
){
1936 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_LOW
) {
1938 kprintf("120mm data disc"); break;
1940 kprintf("120mm audio disc"); break;
1942 kprintf("120mm data/audio disc"); break;
1944 kprintf("120mm photo disc"); break;
1946 kprintf("80mm data disc"); break;
1948 kprintf("80mm audio disc"); break;
1950 kprintf("80mm data/audio disc"); break;
1952 kprintf("80mm photo disc"); break;
1954 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1956 kprintf("unknown"); break;
1959 kprintf("blank"); break;
1963 kprintf("unknown (0x%x)", cdp
->cap
.medium_type
); break;
1970 device_printf(dev
, "%s ",
1971 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1972 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1973 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1974 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1975 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM" :
1977 kprintf("<%.40s/%.8s> at ata%d-%s %s\n",
1978 atadev
->param
.model
, atadev
->param
.revision
,
1979 device_get_unit(ch
->dev
),
1980 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave",
1981 ata_mode2str(atadev
->mode
) );
1985 static device_method_t acd_methods
[] = {
1986 /* device interface */
1987 DEVMETHOD(device_probe
, acd_probe
),
1988 DEVMETHOD(device_attach
, acd_attach
),
1989 DEVMETHOD(device_detach
, acd_detach
),
1990 DEVMETHOD(device_shutdown
, acd_shutdown
),
1993 DEVMETHOD(ata_reinit
, acd_reinit
),
1998 static driver_t acd_driver
= {
2004 static devclass_t acd_devclass
;
2006 DRIVER_MODULE(acd
, ata
, acd_driver
, acd_devclass
, NULL
, NULL
);
2007 MODULE_VERSION(acd
, 1);
2008 MODULE_DEPEND(acd
, ata
, 1, 1, 1);