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 $
31 #include <sys/param.h>
36 #include <sys/cdrio.h>
37 #include <sys/device.h>
38 #include <sys/devicestat.h>
40 #include <sys/dvdio.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/module.h>
47 #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
);
146 disk_setdisktype(&cdp
->disk
, "optical");
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_minor(&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 0 /* __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
;
812 u_int32_t lba
, lastlba
, count
;
814 int track
, blocksize
;
816 /* reject all queued entries if media changed */
817 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
818 bbp
->b_flags
|= B_ERROR
;
824 bzero(ccb
, sizeof(ccb
));
827 * Special track access is via bio_offset (128-255), and direct
828 * raw access via 128, else normal accesses.
830 track
= (bp
->bio_offset
>> 56) & 127;
833 if (track
> MAXTRK
) {
834 bbp
->b_flags
|= B_ERROR
;
839 blocksize
= (cdp
->toc
.tab
[track
- 1].control
& 4) ? 2048 : 2352;
840 lastlba
= ntohl(cdp
->toc
.tab
[track
].addr
.lba
);
841 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
842 lba
+= ntohl(cdp
->toc
.tab
[track
- 1].addr
.lba
);
845 blocksize
= cdp
->block_size
;
846 lastlba
= cdp
->disk_size
;
847 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
850 count
= bbp
->b_bcount
/ blocksize
;
851 KASSERT(count
!= 0, ("acd_strategy: 0-length I/O %d bytes vs %d blksize",
852 bbp
->b_bcount
, blocksize
));
854 if (bbp
->b_cmd
== BUF_CMD_READ
) {
855 /* if transfer goes beyond range adjust it to be within limits */
856 if (lba
+ count
> lastlba
) {
857 /* if we are entirely beyond EOM return EOF */
858 if (lastlba
<= lba
) {
859 bbp
->b_resid
= bbp
->b_bcount
;
863 count
= lastlba
- lba
;
867 ccb
[0] = ATAPI_READ_BIG
;
871 ccb
[0] = ATAPI_READ_CD
;
876 ccb
[0] = ATAPI_READ_CD
;
881 ccb
[0] = ATAPI_WRITE_BIG
;
892 if (!(request
= ata_alloc_request())) {
893 bbp
->b_flags
|= B_ERROR
;
894 bbp
->b_error
= ENOMEM
;
900 bcopy(ccb
, request
->u
.atapi
.ccb
,
901 (atadev
->param
.config
& ATA_PROTO_MASK
) ==
902 ATA_PROTO_ATAPI_12
? 16 : 12);
903 request
->data
= bbp
->b_data
;
904 request
->bytecount
= count
* blocksize
;
905 request
->transfersize
= min(request
->bytecount
, 65534);
906 request
->timeout
= (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30;
907 request
->retries
= 2;
908 request
->callback
= acd_done
;
909 request
->flags
= ATA_R_ATAPI
;
910 if (atadev
->mode
>= ATA_DMA
)
911 request
->flags
|= ATA_R_DMA
;
912 switch (bbp
->b_cmd
) {
914 request
->flags
|= ATA_R_READ
;
917 request
->flags
|= ATA_R_WRITE
;
920 device_printf(dev
, "unknown BUF operation\n");
921 ata_free_request(request
);
922 bbp
->b_flags
|= B_ERROR
;
927 devstat_start_transaction(&cdp
->stats
);
928 ata_queue_request(request
);
932 acd_done(struct ata_request
*request
)
934 struct acd_softc
*cdp
= device_get_ivars(request
->dev
);
935 struct bio
*bp
= request
->bio
;
936 struct buf
*bbp
= bp
->bio_buf
;
938 /* finish up transfer */
939 if ((bbp
->b_error
= request
->result
))
940 bbp
->b_flags
|= B_ERROR
;
941 bbp
->b_resid
= bbp
->b_bcount
- request
->donecount
;
942 devstat_end_transaction_buf(&cdp
->stats
, bbp
);
944 ata_free_request(request
);
948 acd_set_ioparm(device_t dev
)
950 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
951 struct ata_device
*atadev
= device_get_softc(dev
);
952 struct acd_softc
*cdp
= device_get_ivars(dev
);
953 struct disk_info info
;
956 cdp
->iomax
= min(ch
->dma
->max_iosize
, 65534);
958 cdp
->iomax
= min(MAXPHYS
, 65534);
960 cdp
->cdev
->si_iosize_max
= (cdp
->iomax
/ cdp
->block_size
) * cdp
->block_size
;
961 cdp
->cdev
->si_bsize_phys
= cdp
->block_size
;
962 bzero(&info
, sizeof(info
));
963 info
.d_media_blksize
= cdp
->block_size
;
964 info
.d_media_blocks
= (cdp
->disk_size
== -1) ? 0 : cdp
->disk_size
;
965 info
.d_secpertrack
= 100;
967 info
.d_ncylinders
= cdp
->disk_size
/ info
.d_secpertrack
/ info
.d_nheads
+ 1;
968 info
.d_secpercyl
= info
.d_secpertrack
* info
.d_nheads
;
969 info
.d_dsflags
= DSO_ONESLICE
| DSO_COMPATLABEL
| DSO_COMPATPARTA
|
971 info
.d_serialno
= atadev
->param
.serial
;
972 disk_setdiskinfo(&cdp
->disk
, &info
);
977 lba2msf(u_int32_t lba
, u_int8_t
*m
, u_int8_t
*s
, u_int8_t
*f
)
981 *m
= lba
/ (60 * 75);
988 msf2lba(u_int8_t m
, u_int8_t s
, u_int8_t f
)
990 return (m
* 60 + s
) * 75 + f
- 150;
994 acd_read_toc(device_t dev
)
996 struct ata_device
*atadev
= device_get_softc(dev
);
997 struct acd_softc
*cdp
= device_get_ivars(dev
);
998 struct acd_tracknode
*tracknode
;
1001 int track
, ntracks
, len
;
1003 atadev
->flags
&= ~ATA_D_MEDIA_CHANGED
;
1004 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1006 if (acd_test_ready(dev
))
1009 bzero(ccb
, sizeof(ccb
));
1010 len
= sizeof(struct ioc_toc_header
) + sizeof(struct cd_toc_entry
);
1011 ccb
[0] = ATAPI_READ_TOC
;
1014 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1015 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1016 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1019 ntracks
= cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1;
1020 if (ntracks
<= 0 || ntracks
> MAXTRK
) {
1021 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1025 len
= sizeof(struct ioc_toc_header
)+(ntracks
+1)*sizeof(struct cd_toc_entry
);
1026 bzero(ccb
, sizeof(ccb
));
1027 ccb
[0] = ATAPI_READ_TOC
;
1030 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1031 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1032 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1035 cdp
->toc
.hdr
.len
= ntohs(cdp
->toc
.hdr
.len
);
1037 cdp
->block_size
= (cdp
->toc
.tab
[0].control
& 4) ? 2048 : 2352;
1038 bzero(ccb
, sizeof(ccb
));
1039 ccb
[0] = ATAPI_READ_CAPACITY
;
1040 if (ata_atapicmd(dev
, ccb
, (caddr_t
)sizes
, sizeof(sizes
),
1041 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1042 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1045 cdp
->disk_size
= ntohl(sizes
[0]) + 1;
1046 acd_set_ioparm(dev
);
1048 for (track
= 1; track
<= ntracks
; track
++) {
1049 if (cdp
->track
[track
] != NULL
)
1052 tracknode
= acd_make_tracknode(dev
, track
);
1055 cdp
->track
[track
] = tracknode
;
1057 for (; track
< MAXTRK
; track
++) {
1058 if (cdp
->track
[track
] == NULL
)
1060 acd_destroy_tracknode(dev
, track
);
1061 cdp
->track
[track
] = NULL
;
1065 if (cdp
->disk_size
&& cdp
->toc
.hdr
.ending_track
) {
1066 device_printf(dev
, "(%d sectors (%d bytes)), %d tracks ",
1067 cdp
->disk_size
, cdp
->block_size
,
1068 cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
+1);
1069 if (cdp
->toc
.tab
[0].control
& 4)
1070 kprintf("%dMB\n", cdp
->disk_size
* cdp
->block_size
/ 1048576);
1072 kprintf("%d:%d audio\n",
1073 cdp
->disk_size
/ 75 / 60, cdp
->disk_size
/ 75 % 60);
1079 * Makes a new device node for the numbered track and returns a struct
1080 * acd_tracknode pointer to be included in the list of tracks available on the
1086 static struct acd_tracknode
*
1087 acd_make_tracknode(device_t dev
, int track
)
1089 struct acd_softc
*cdp
= device_get_ivars(dev
);
1090 struct acd_tracknode
*tracknode
;
1093 ksprintf(name
, "acd%dt%d", device_get_unit(dev
), track
);
1094 tracknode
= kmalloc(sizeof(struct acd_tracknode
), M_ACD
, M_WAITOK
| M_ZERO
);
1095 tracknode
->cdev
= make_dev(&acd_ops
, (device_get_unit(dev
) << 3) |
1096 (track
<< 16), UID_ROOT
, GID_OPERATOR
, 0644,
1098 tracknode
->cdev
->si_drv1
= cdp
->cdev
->si_drv1
;
1099 reference_dev(tracknode
->cdev
);
1106 * Destroys the device node of a numbered track and frees the related struct
1107 * acd_tracknode. It could be done just in acd_read_toc(), but it's nice to
1108 * have a complementary function to acd_make_tracknode().
1111 acd_destroy_tracknode(device_t dev
, int track
)
1113 struct acd_softc
*cdp
= device_get_ivars(dev
);
1114 struct acd_tracknode
*tracknode
;
1116 tracknode
= cdp
->track
[track
];
1117 destroy_dev(tracknode
->cdev
);
1118 kfree(tracknode
, M_ACD
);
1122 acd_play(device_t dev
, int start
, int end
)
1126 bzero(ccb
, sizeof(ccb
));
1127 ccb
[0] = ATAPI_PLAY_MSF
;
1128 lba2msf(start
, &ccb
[3], &ccb
[4], &ccb
[5]);
1129 lba2msf(end
, &ccb
[6], &ccb
[7], &ccb
[8]);
1130 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 10);
1134 acd_setchan(device_t dev
, u_int8_t c0
, u_int8_t c1
, u_int8_t c2
, u_int8_t c3
)
1136 struct acd_softc
*cdp
= device_get_ivars(dev
);
1139 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
, (caddr_t
)&cdp
->au
,
1142 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
)
1144 cdp
->au
.data_length
= 0;
1145 cdp
->au
.port
[0].channels
= c0
;
1146 cdp
->au
.port
[1].channels
= c1
;
1147 cdp
->au
.port
[2].channels
= c2
;
1148 cdp
->au
.port
[3].channels
= c3
;
1149 return acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
1153 acd_init_writer(device_t dev
, int test_write
)
1157 bzero(ccb
, sizeof(ccb
));
1158 ccb
[0] = ATAPI_REZERO
;
1159 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1160 ccb
[0] = ATAPI_SEND_OPC_INFO
;
1162 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 30);
1167 acd_fixate(device_t dev
, int multisession
)
1169 struct acd_softc
*cdp
= device_get_ivars(dev
);
1170 int8_t ccb
[16] = { ATAPI_CLOSE_TRACK
, 0x01, 0x02, 0, 0, 0, 0, 0,
1171 0, 0, 0, 0, 0, 0, 0, 0 };
1172 int timeout
= 5*60*2;
1174 struct write_param param
;
1176 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1177 (caddr_t
)¶m
, sizeof(param
))))
1180 param
.data_length
= 0;
1182 param
.session_type
= CDR_SESS_MULTI
;
1184 param
.session_type
= CDR_SESS_NONE
;
1186 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1189 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1193 /* some drives just return ready, wait for the expected fixate time */
1194 if ((error
= acd_test_ready(dev
)) != EBUSY
) {
1195 timeout
= timeout
/ (cdp
->cap
.cur_write_speed
/ 177);
1196 tsleep(&error
, 0, "acdfix", timeout
* hz
/ 2);
1197 return acd_test_ready(dev
);
1200 while (timeout
-- > 0) {
1201 if ((error
= acd_get_progress(dev
, &dummy
)))
1203 if ((error
= acd_test_ready(dev
)) != EBUSY
)
1205 tsleep(&error
, 0, "acdcld", hz
/ 2);
1211 acd_init_track(device_t dev
, struct cdr_track
*track
)
1213 struct acd_softc
*cdp
= device_get_ivars(dev
);
1214 struct write_param param
;
1217 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1218 (caddr_t
)¶m
, sizeof(param
))))
1221 param
.data_length
= 0;
1222 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1223 param
.page_length
= 0x32;
1224 param
.test_write
= track
->test_write
? 1 : 0;
1225 param
.write_type
= CDR_WTYPE_TRACK
;
1226 param
.session_type
= CDR_SESS_NONE
;
1228 param
.packet_size
= 0;
1230 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1231 param
.burnproof
= 1;
1233 switch (track
->datablock_type
) {
1237 param
.track_mode
= CDR_TMODE_AUDIO_PREEMP
;
1239 param
.track_mode
= CDR_TMODE_AUDIO
;
1240 cdp
->block_size
= 2352;
1241 param
.datablock_type
= CDR_DB_RAW
;
1242 param
.session_format
= CDR_SESS_CDROM
;
1245 case CDR_DB_ROM_MODE1
:
1246 cdp
->block_size
= 2048;
1247 param
.track_mode
= CDR_TMODE_DATA
;
1248 param
.datablock_type
= CDR_DB_ROM_MODE1
;
1249 param
.session_format
= CDR_SESS_CDROM
;
1252 case CDR_DB_ROM_MODE2
:
1253 cdp
->block_size
= 2336;
1254 param
.track_mode
= CDR_TMODE_DATA
;
1255 param
.datablock_type
= CDR_DB_ROM_MODE2
;
1256 param
.session_format
= CDR_SESS_CDROM
;
1259 case CDR_DB_XA_MODE1
:
1260 cdp
->block_size
= 2048;
1261 param
.track_mode
= CDR_TMODE_DATA
;
1262 param
.datablock_type
= CDR_DB_XA_MODE1
;
1263 param
.session_format
= CDR_SESS_CDROM_XA
;
1266 case CDR_DB_XA_MODE2_F1
:
1267 cdp
->block_size
= 2056;
1268 param
.track_mode
= CDR_TMODE_DATA
;
1269 param
.datablock_type
= CDR_DB_XA_MODE2_F1
;
1270 param
.session_format
= CDR_SESS_CDROM_XA
;
1273 case CDR_DB_XA_MODE2_F2
:
1274 cdp
->block_size
= 2324;
1275 param
.track_mode
= CDR_TMODE_DATA
;
1276 param
.datablock_type
= CDR_DB_XA_MODE2_F2
;
1277 param
.session_format
= CDR_SESS_CDROM_XA
;
1280 case CDR_DB_XA_MODE2_MIX
:
1281 cdp
->block_size
= 2332;
1282 param
.track_mode
= CDR_TMODE_DATA
;
1283 param
.datablock_type
= CDR_DB_XA_MODE2_MIX
;
1284 param
.session_format
= CDR_SESS_CDROM_XA
;
1287 acd_set_ioparm(dev
);
1288 return acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10);
1292 acd_flush(device_t dev
)
1294 int8_t ccb
[16] = { ATAPI_SYNCHRONIZE_CACHE
, 0, 0, 0, 0, 0, 0, 0,
1295 0, 0, 0, 0, 0, 0, 0, 0 };
1297 return ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1301 acd_read_track_info(device_t dev
, int32_t lba
, struct acd_track_info
*info
)
1303 int8_t ccb
[16] = { ATAPI_READ_TRACK_INFO
, 1,
1304 lba
>>24, lba
>>16, lba
>>8, lba
, 0,
1305 sizeof(*info
)>>8, sizeof(*info
),
1306 0, 0, 0, 0, 0, 0, 0 };
1309 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)info
, sizeof(*info
),
1312 info
->track_start_addr
= ntohl(info
->track_start_addr
);
1313 info
->next_writeable_addr
= ntohl(info
->next_writeable_addr
);
1314 info
->free_blocks
= ntohl(info
->free_blocks
);
1315 info
->fixed_packet_size
= ntohl(info
->fixed_packet_size
);
1316 info
->track_length
= ntohl(info
->track_length
);
1321 acd_get_progress(device_t dev
, int *finished
)
1323 int8_t ccb
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
1324 0, 0, 0, 0, 0, 0, 0, 0 };
1325 struct ata_request
*request
;
1328 if (!(request
= ata_alloc_request()))
1332 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
1333 request
->data
= dummy
;
1334 request
->bytecount
= sizeof(dummy
);
1335 request
->transfersize
= min(request
->bytecount
, 65534);
1336 request
->flags
= ATA_R_ATAPI
| ATA_R_READ
;
1337 request
->timeout
= 30;
1338 ata_queue_request(request
);
1339 if (!request
->error
&&
1340 request
->u
.atapi
.sense
.specific
& ATA_SENSE_SPEC_VALID
)
1341 *finished
= ((request
->u
.atapi
.sense
.specific2
|
1342 (request
->u
.atapi
.sense
.specific1
<< 8)) * 100) / 65535;
1345 ata_free_request(request
);
1350 acd_send_cue(device_t dev
, struct cdr_cuesheet
*cuesheet
)
1352 struct acd_softc
*cdp
= device_get_ivars(dev
);
1353 struct write_param param
;
1354 int8_t ccb
[16] = { ATAPI_SEND_CUE_SHEET
, 0, 0, 0, 0, 0,
1355 cuesheet
->len
>>16, cuesheet
->len
>>8, cuesheet
->len
,
1356 0, 0, 0, 0, 0, 0, 0 };
1360 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1361 (caddr_t
)¶m
, sizeof(param
))))
1364 param
.data_length
= 0;
1365 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1366 param
.page_length
= 0x32;
1367 param
.test_write
= cuesheet
->test_write
? 1 : 0;
1368 param
.write_type
= CDR_WTYPE_SESSION
;
1369 param
.session_type
= cuesheet
->session_type
;
1371 param
.packet_size
= 0;
1372 param
.track_mode
= CDR_TMODE_AUDIO
;
1373 param
.datablock_type
= CDR_DB_RAW
;
1374 param
.session_format
= cuesheet
->session_format
;
1375 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1376 param
.burnproof
= 1;
1378 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1381 if (!(buffer
= kmalloc(cuesheet
->len
, M_ACD
, M_WAITOK
| M_NULLOK
)))
1384 if (!(error
= copyin(cuesheet
->entries
, buffer
, cuesheet
->len
)))
1385 error
= ata_atapicmd(dev
, ccb
, buffer
, cuesheet
->len
, 0, 30);
1386 kfree(buffer
, M_ACD
);
1391 acd_report_key(device_t dev
, struct dvd_authinfo
*ai
)
1393 struct dvd_miscauth
*d
= NULL
;
1399 switch (ai
->format
) {
1400 case DVD_REPORT_AGID
:
1401 case DVD_REPORT_ASF
:
1402 case DVD_REPORT_RPC
:
1405 case DVD_REPORT_KEY1
:
1408 case DVD_REPORT_TITLE_KEY
:
1412 case DVD_REPORT_CHALLENGE
:
1415 case DVD_INVALIDATE_AGID
:
1422 bzero(ccb
, sizeof(ccb
));
1423 ccb
[0] = ATAPI_REPORT_KEY
;
1424 ccb
[2] = (lba
>> 24) & 0xff;
1425 ccb
[3] = (lba
>> 16) & 0xff;
1426 ccb
[4] = (lba
>> 8) & 0xff;
1427 ccb
[5] = lba
& 0xff;
1428 ccb
[8] = (length
>> 8) & 0xff;
1429 ccb
[9] = length
& 0xff;
1430 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1433 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1434 d
->length
= htons(length
- 2);
1437 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
,
1438 ai
->format
== DVD_INVALIDATE_AGID
? 0 : ATA_R_READ
,10);
1445 switch (ai
->format
) {
1446 case DVD_REPORT_AGID
:
1447 ai
->agid
= d
->data
[3] >> 6;
1450 case DVD_REPORT_CHALLENGE
:
1451 bcopy(&d
->data
[0], &ai
->keychal
[0], 10);
1454 case DVD_REPORT_KEY1
:
1455 bcopy(&d
->data
[0], &ai
->keychal
[0], 5);
1458 case DVD_REPORT_TITLE_KEY
:
1459 ai
->cpm
= (d
->data
[0] >> 7);
1460 ai
->cp_sec
= (d
->data
[0] >> 6) & 0x1;
1461 ai
->cgms
= (d
->data
[0] >> 4) & 0x3;
1462 bcopy(&d
->data
[1], &ai
->keychal
[0], 5);
1465 case DVD_REPORT_ASF
:
1466 ai
->asf
= d
->data
[3] & 1;
1469 case DVD_REPORT_RPC
:
1470 ai
->reg_type
= (d
->data
[0] >> 6);
1471 ai
->vend_rsts
= (d
->data
[0] >> 3) & 0x7;
1472 ai
->user_rsts
= d
->data
[0] & 0x7;
1473 ai
->region
= d
->data
[1];
1474 ai
->rpc_scheme
= d
->data
[2];
1477 case DVD_INVALIDATE_AGID
:
1489 acd_send_key(device_t dev
, struct dvd_authinfo
*ai
)
1491 struct dvd_miscauth
*d
;
1496 switch (ai
->format
) {
1497 case DVD_SEND_CHALLENGE
:
1499 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1500 bcopy(ai
->keychal
, &d
->data
[0], 10);
1505 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1506 bcopy(&ai
->keychal
[0], &d
->data
[0], 5);
1511 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1512 d
->data
[0] = ai
->region
;
1519 bzero(ccb
, sizeof(ccb
));
1520 ccb
[0] = ATAPI_SEND_KEY
;
1521 ccb
[8] = (length
>> 8) & 0xff;
1522 ccb
[9] = length
& 0xff;
1523 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1524 d
->length
= htons(length
- 2);
1525 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, 0, 10);
1531 acd_read_structure(device_t dev
, struct dvd_struct
*s
)
1533 struct dvd_miscauth
*d
;
1539 case DVD_STRUCT_PHYSICAL
:
1543 case DVD_STRUCT_COPYRIGHT
:
1547 case DVD_STRUCT_DISCKEY
:
1551 case DVD_STRUCT_BCA
:
1555 case DVD_STRUCT_MANUFACT
:
1559 case DVD_STRUCT_DDS
:
1560 case DVD_STRUCT_PRERECORDED
:
1561 case DVD_STRUCT_UNIQUEID
:
1562 case DVD_STRUCT_LIST
:
1563 case DVD_STRUCT_CMI
:
1564 case DVD_STRUCT_RMD_LAST
:
1565 case DVD_STRUCT_RMD_RMA
:
1566 case DVD_STRUCT_DCB
:
1573 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1574 d
->length
= htons(length
- 2);
1576 bzero(ccb
, sizeof(ccb
));
1577 ccb
[0] = ATAPI_READ_STRUCTURE
;
1578 ccb
[6] = s
->layer_num
;
1580 ccb
[8] = (length
>> 8) & 0xff;
1581 ccb
[9] = length
& 0xff;
1582 ccb
[10] = s
->agid
<< 6;
1583 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, ATA_R_READ
, 30);
1589 switch (s
->format
) {
1590 case DVD_STRUCT_PHYSICAL
: {
1591 struct dvd_layer
*layer
= (struct dvd_layer
*)&s
->data
[0];
1593 layer
->book_type
= d
->data
[0] >> 4;
1594 layer
->book_version
= d
->data
[0] & 0xf;
1595 layer
->disc_size
= d
->data
[1] >> 4;
1596 layer
->max_rate
= d
->data
[1] & 0xf;
1597 layer
->nlayers
= (d
->data
[2] >> 5) & 3;
1598 layer
->track_path
= (d
->data
[2] >> 4) & 1;
1599 layer
->layer_type
= d
->data
[2] & 0xf;
1600 layer
->linear_density
= d
->data
[3] >> 4;
1601 layer
->track_density
= d
->data
[3] & 0xf;
1602 layer
->start_sector
= d
->data
[5] << 16 | d
->data
[6] << 8 | d
->data
[7];
1603 layer
->end_sector
= d
->data
[9] << 16 | d
->data
[10] << 8 | d
->data
[11];
1604 layer
->end_sector_l0
= d
->data
[13] << 16 | d
->data
[14] << 8|d
->data
[15];
1605 layer
->bca
= d
->data
[16] >> 7;
1609 case DVD_STRUCT_COPYRIGHT
:
1610 s
->cpst
= d
->data
[0];
1611 s
->rmi
= d
->data
[1];
1614 case DVD_STRUCT_DISCKEY
:
1615 bcopy(&d
->data
[0], &s
->data
[0], 2048);
1618 case DVD_STRUCT_BCA
:
1619 s
->length
= ntohs(d
->length
);
1620 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1623 case DVD_STRUCT_MANUFACT
:
1624 s
->length
= ntohs(d
->length
);
1625 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1636 acd_tray(device_t dev
, int close
)
1638 struct ata_device
*atadev
= device_get_softc(dev
);
1639 struct acd_softc
*cdp
= device_get_ivars(dev
);
1642 if (cdp
->cap
.mechanism
& MST_EJECT
) {
1644 if (!(error
= acd_start_stop(dev
, 3))) {
1646 acd_prevent_allow(dev
, 1);
1647 cdp
->flags
|= F_LOCKED
;
1651 acd_start_stop(dev
, 0);
1652 acd_prevent_allow(dev
, 0);
1653 cdp
->flags
&= ~F_LOCKED
;
1654 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1655 error
= acd_start_stop(dev
, 2);
1662 acd_blank(device_t dev
, int blanktype
)
1664 struct ata_device
*atadev
= device_get_softc(dev
);
1665 int8_t ccb
[16] = { ATAPI_BLANK
, 0x10 | (blanktype
& 0x7), 0, 0, 0, 0, 0, 0,
1666 0, 0, 0, 0, 0, 0, 0, 0 };
1668 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1669 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1673 acd_prevent_allow(device_t dev
, int lock
)
1675 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
1676 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1678 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1682 acd_start_stop(device_t dev
, int start
)
1684 int8_t ccb
[16] = { ATAPI_START_STOP
, 0, 0, 0, start
,
1685 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1687 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1691 acd_pause_resume(device_t dev
, int pause
)
1693 int8_t ccb
[16] = { ATAPI_PAUSE
, 0, 0, 0, 0, 0, 0, 0, pause
,
1694 0, 0, 0, 0, 0, 0, 0 };
1696 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1700 acd_mode_sense(device_t dev
, int page
, caddr_t pagebuf
, int pagesize
)
1702 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, page
, 0, 0, 0, 0,
1703 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1706 error
= ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, ATA_R_READ
, 10);
1711 acd_mode_select(device_t dev
, caddr_t pagebuf
, int pagesize
)
1713 int8_t ccb
[16] = { ATAPI_MODE_SELECT_BIG
, 0x10, 0, 0, 0, 0, 0,
1714 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1716 return ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, 0, 30);
1720 acd_set_speed(device_t dev
, int rdspeed
, int wrspeed
)
1722 int8_t ccb
[16] = { ATAPI_SET_SPEED
, 0, rdspeed
>> 8, rdspeed
,
1723 wrspeed
>> 8, wrspeed
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1726 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1733 acd_get_cap(device_t dev
)
1735 struct acd_softc
*cdp
= device_get_ivars(dev
);
1736 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, ATAPI_CDROM_CAP_PAGE
,
1737 0, 0, 0, 0, sizeof(cdp
->cap
)>>8, sizeof(cdp
->cap
),
1738 0, 0, 0, 0, 0, 0, 0 };
1741 /* get drive capabilities, some bugridden drives needs this repeated */
1742 for (count
= 0 ; count
< 5 ; count
++) {
1743 if (!ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->cap
, sizeof(cdp
->cap
),
1744 ATA_R_READ
| ATA_R_QUIET
, 5)) {
1745 cdp
->cap
.max_read_speed
= ntohs(cdp
->cap
.max_read_speed
);
1746 cdp
->cap
.cur_read_speed
= ntohs(cdp
->cap
.cur_read_speed
);
1747 cdp
->cap
.max_write_speed
= ntohs(cdp
->cap
.max_write_speed
);
1748 cdp
->cap
.cur_write_speed
= max(ntohs(cdp
->cap
.cur_write_speed
),177);
1749 cdp
->cap
.max_vol_levels
= ntohs(cdp
->cap
.max_vol_levels
);
1750 cdp
->cap
.buf_size
= ntohs(cdp
->cap
.buf_size
);
1755 #ifdef ACD_CDR_FORMAT
1757 acd_read_format_caps(device_t dev
, struct cdr_format_capacities
*caps
)
1759 int8_t ccb
[16] = { ATAPI_READ_FORMAT_CAPACITIES
, 0, 0, 0, 0, 0, 0,
1760 (sizeof(struct cdr_format_capacities
) >> 8) & 0xff,
1761 sizeof(struct cdr_format_capacities
) & 0xff,
1762 0, 0, 0, 0, 0, 0, 0 };
1764 return ata_atapicmd(dev
, ccb
, (caddr_t
)caps
,
1765 sizeof(struct cdr_format_capacities
), ATA_R_READ
, 30);
1769 acd_format(device_t dev
, struct cdr_format_params
* params
)
1771 int8_t ccb
[16] = { ATAPI_FORMAT
, 0x11, 0, 0, 0, 0, 0, 0, 0, 0,
1775 error
= ata_atapicmd(dev
, ccb
, (u_int8_t
*)params
,
1776 sizeof(struct cdr_format_params
), 0, 30);
1779 #endif /* ACD_CDR_FORMAT */
1782 acd_test_ready(device_t dev
)
1784 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
1785 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1787 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1791 acd_describe(device_t dev
)
1793 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
1794 struct ata_device
*atadev
= device_get_softc(dev
);
1795 struct acd_softc
*cdp
= device_get_ivars(dev
);
1800 device_printf(dev
, "<%.40s/%.8s> %s drive at ata%d as %s\n",
1801 atadev
->param
.model
, atadev
->param
.revision
,
1802 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1803 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1804 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1805 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1806 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM":"CDROM",
1807 device_get_unit(ch
->dev
),
1808 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave");
1810 device_printf(dev
, "%s", "");
1811 if (cdp
->cap
.cur_read_speed
) {
1812 kprintf("read %dKB/s", cdp
->cap
.cur_read_speed
* 1000 / 1024);
1813 if (cdp
->cap
.max_read_speed
)
1814 kprintf(" (%dKB/s)", cdp
->cap
.max_read_speed
* 1000 / 1024);
1815 if ((cdp
->cap
.cur_write_speed
) &&
1816 (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1817 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
))) {
1818 kprintf(" write %dKB/s", cdp
->cap
.cur_write_speed
* 1000 / 1024);
1819 if (cdp
->cap
.max_write_speed
)
1820 kprintf(" (%dKB/s)", cdp
->cap
.max_write_speed
* 1000 / 1024);
1824 if (cdp
->cap
.buf_size
) {
1825 kprintf("%s %dKB buffer", comma
? "," : "", cdp
->cap
.buf_size
);
1828 kprintf("%s %s\n", comma
? "," : "", ata_mode2str(atadev
->mode
));
1830 device_printf(dev
, "Reads:");
1832 if (cdp
->cap
.media
& MST_READ_CDR
) {
1833 kprintf(" CDR"); comma
= 1;
1835 if (cdp
->cap
.media
& MST_READ_CDRW
) {
1836 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1838 if (cdp
->cap
.capabilities
& MST_READ_CDDA
) {
1839 if (cdp
->cap
.capabilities
& MST_CDDA_STREAM
)
1840 kprintf("%s CDDA stream", comma
? "," : "");
1842 kprintf("%s CDDA", comma
? "," : "");
1845 if (cdp
->cap
.media
& MST_READ_DVDROM
) {
1846 kprintf("%s DVDROM", comma
? "," : ""); comma
= 1;
1848 if (cdp
->cap
.media
& MST_READ_DVDR
) {
1849 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1851 if (cdp
->cap
.media
& MST_READ_DVDRAM
) {
1852 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1854 if (cdp
->cap
.media
& MST_READ_PACKET
)
1855 kprintf("%s packet", comma
? "," : "");
1858 device_printf(dev
, "Writes:");
1859 if (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1860 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
)) {
1862 if (cdp
->cap
.media
& MST_WRITE_CDR
) {
1863 kprintf(" CDR" ); comma
= 1;
1865 if (cdp
->cap
.media
& MST_WRITE_CDRW
) {
1866 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1868 if (cdp
->cap
.media
& MST_WRITE_DVDR
) {
1869 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1871 if (cdp
->cap
.media
& MST_WRITE_DVDRAM
) {
1872 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1874 if (cdp
->cap
.media
& MST_WRITE_TEST
) {
1875 kprintf("%s test write", comma
? "," : ""); comma
= 1;
1877 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1878 kprintf("%s burnproof", comma
? "," : "");
1881 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
) {
1882 device_printf(dev
, "Audio: ");
1883 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
)
1885 if (cdp
->cap
.max_vol_levels
)
1886 kprintf(", %d volume levels", cdp
->cap
.max_vol_levels
);
1889 device_printf(dev
, "Mechanism: ");
1890 switch (cdp
->cap
.mechanism
& MST_MECH_MASK
) {
1891 case MST_MECH_CADDY
:
1892 mechanism
= "caddy"; break;
1894 mechanism
= "tray"; break;
1895 case MST_MECH_POPUP
:
1896 mechanism
= "popup"; break;
1897 case MST_MECH_CHANGER
:
1898 mechanism
= "changer"; break;
1899 case MST_MECH_CARTRIDGE
:
1900 mechanism
= "cartridge"; break;
1902 mechanism
= NULL
; break;
1905 kprintf("%s%s", (cdp
->cap
.mechanism
& MST_EJECT
) ?
1906 "ejectable " : "", mechanism
);
1907 else if (cdp
->cap
.mechanism
& MST_EJECT
)
1908 kprintf("ejectable");
1910 if (cdp
->cap
.mechanism
& MST_LOCKABLE
)
1911 kprintf((cdp
->cap
.mechanism
& MST_LOCKED
) ? ", locked":", unlocked");
1912 if (cdp
->cap
.mechanism
& MST_PREVENT
)
1913 kprintf(", lock protected");
1916 if ((cdp
->cap
.mechanism
& MST_MECH_MASK
) != MST_MECH_CHANGER
) {
1917 device_printf(dev
, "Medium: ");
1918 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1920 kprintf("CD-ROM "); break;
1922 kprintf("CD-R "); break;
1924 kprintf("CD-RW "); break;
1926 kprintf("DVD "); break;
1928 kprintf("door open"); break;
1930 kprintf("no/blank disc"); break;
1932 kprintf("medium format error"); break;
1934 if ((cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
)<MST_TYPE_MASK_HIGH
){
1935 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_LOW
) {
1937 kprintf("120mm data disc"); break;
1939 kprintf("120mm audio disc"); break;
1941 kprintf("120mm data/audio disc"); break;
1943 kprintf("120mm photo disc"); break;
1945 kprintf("80mm data disc"); break;
1947 kprintf("80mm audio disc"); break;
1949 kprintf("80mm data/audio disc"); break;
1951 kprintf("80mm photo disc"); break;
1953 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1955 kprintf("unknown"); break;
1958 kprintf("blank"); break;
1962 kprintf("unknown (0x%x)", cdp
->cap
.medium_type
); break;
1969 device_printf(dev
, "%s ",
1970 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1971 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1972 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1973 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1974 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM" :
1976 kprintf("<%.40s/%.8s> at ata%d-%s %s\n",
1977 atadev
->param
.model
, atadev
->param
.revision
,
1978 device_get_unit(ch
->dev
),
1979 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave",
1980 ata_mode2str(atadev
->mode
) );
1984 static device_method_t acd_methods
[] = {
1985 /* device interface */
1986 DEVMETHOD(device_probe
, acd_probe
),
1987 DEVMETHOD(device_attach
, acd_attach
),
1988 DEVMETHOD(device_detach
, acd_detach
),
1989 DEVMETHOD(device_shutdown
, acd_shutdown
),
1992 DEVMETHOD(ata_reinit
, acd_reinit
),
1997 static driver_t acd_driver
= {
2003 static devclass_t acd_devclass
;
2005 DRIVER_MODULE(acd
, ata
, acd_driver
, acd_devclass
, NULL
, NULL
);
2006 MODULE_VERSION(acd
, 1);
2007 MODULE_DEPEND(acd
, ata
, 1, 1, 1);