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.189 2006/06/28 15:04:10 sos Exp $
27 * $DragonFly: src/sys/dev/disk/nata/atapi-cd.c,v 1.2 2006/12/20 18:14:38 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>
47 #include <sys/systm.h>
53 /* device structure */
54 static d_open_t acd_open
;
55 static d_close_t acd_close
;
56 static d_ioctl_t acd_ioctl
;
57 static d_strategy_t acd_strategy
;
58 static struct dev_ops acd_ops
= {
59 { "acd", 117, D_DISK
| D_TRACKCLOSE
},
65 .d_strategy
= acd_strategy
,
69 static void acd_set_ioparm(device_t
);
70 static void acd_describe(device_t
);
71 static void lba2msf(u_int32_t
, u_int8_t
*, u_int8_t
*, u_int8_t
*);
72 static u_int32_t
msf2lba(u_int8_t
, u_int8_t
, u_int8_t
);
73 static void acd_start(device_t
, struct bio
*);
74 static void acd_done(struct ata_request
*);
75 static void acd_read_toc(device_t
);
76 static struct acd_tracknode
* acd_make_tracknode(device_t
, int);
77 static void acd_destroy_tracknode(device_t
, int);
78 static int acd_play(device_t
, int, int);
79 static int acd_setchan(device_t
, u_int8_t
, u_int8_t
, u_int8_t
, u_int8_t
);
80 static int acd_init_writer(device_t
, int);
81 static int acd_fixate(device_t
, int);
82 static int acd_init_track(device_t
, struct cdr_track
*);
83 static int acd_flush(device_t
);
84 static int acd_read_track_info(device_t
, int32_t, struct acd_track_info
*);
85 static int acd_get_progress(device_t
, int *);
86 static int acd_send_cue(device_t
, struct cdr_cuesheet
*);
87 static int acd_report_key(device_t
, struct dvd_authinfo
*);
88 static int acd_send_key(device_t
, struct dvd_authinfo
*);
89 static int acd_read_structure(device_t
, struct dvd_struct
*);
90 static int acd_tray(device_t
, int);
91 static int acd_blank(device_t
, int);
92 static int acd_prevent_allow(device_t
, int);
93 static int acd_start_stop(device_t
, int);
94 static int acd_pause_resume(device_t
, int);
95 static int acd_mode_sense(device_t
, int, caddr_t
, int);
96 static int acd_mode_select(device_t
, caddr_t
, int);
97 static int acd_set_speed(device_t
, int, int);
98 static void acd_get_cap(device_t
);
101 static int acd_read_format_caps(device_t
, struct cdr_format_capacities
*);
102 static int acd_format(device_t
, struct cdr_format_params
*);
103 #endif /* ACD_CDR_FORMAT */
104 static int acd_test_ready(device_t
);
107 static MALLOC_DEFINE(M_ACD
, "acd_driver", "ATAPI CD driver buffers");
110 acd_probe(device_t dev
)
112 struct ata_device
*atadev
= device_get_softc(dev
);
114 if ((atadev
->param
.config
& ATA_PROTO_ATAPI
) &&
115 (atadev
->param
.config
& ATA_ATAPI_TYPE_MASK
) == ATA_ATAPI_TYPE_CDROM
)
122 acd_attach(device_t dev
)
124 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
125 struct ata_device
*atadev
= device_get_softc(dev
);
126 struct acd_softc
*cdp
;
129 /* XXX TGEN We're not in interrupt context, so we can M_WAITOK and remove
131 if (!(cdp
= kmalloc(sizeof(struct acd_softc
), M_ACD
, M_NOWAIT
| M_ZERO
))) {
132 device_printf(dev
, "out of memory\n");
135 cdp
->block_size
= 2048;
136 device_set_ivars(dev
, cdp
);
137 ATA_SETMODE(device_get_parent(dev
), dev
);
138 ata_controlcmd(dev
, ATA_DEVICE_RESET
, 0, 0, 0);
141 devstat_add_entry(&cdp
->stats
, "acd", device_get_unit(dev
), DEV_BSIZE
,
142 DEVSTAT_NO_ORDERED_TAGS
,
143 DEVSTAT_TYPE_CDROM
| DEVSTAT_TYPE_IF_IDE
,
144 DEVSTAT_PRIORITY_CD
);
145 dev_ops_add(&acd_ops
, dkunitmask(), dkmakeunit(device_get_unit(dev
)));
146 cdev
= make_dev(&acd_ops
, dkmakeminor(device_get_unit(dev
), 0, 0),
147 UID_ROOT
, GID_OPERATOR
, 0644, "acd%d",
148 device_get_unit(dev
));
151 /* XXX TGEN acd_set_ioparm(dev); */
153 cdev
->si_iosize_max
= ch
->dma
->max_iosize
;
155 cdev
->si_iosize_max
= DFLTPHYS
;
157 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
159 /* announce we are here */
165 acd_detach(device_t dev
)
167 struct acd_softc
*cdp
= device_get_ivars(dev
);
170 /* destroy devices from the system so we don't get any further requests */
171 for (track
= 1; track
< MAXTRK
; track
++) {
172 if (cdp
->track
[track
] == NULL
)
174 acd_destroy_tracknode(dev
, track
);
176 destroy_dev(cdp
->cdev
);
178 /* fail requests on the queue and any "in flight" for this device */
179 ata_fail_requests(dev
);
181 /* don't leave anything behind */
182 dev_ops_remove(&acd_ops
, dkunitmask(), dkmakeunit(device_get_unit(dev
)));
183 devstat_remove_entry(&cdp
->stats
);
184 device_set_ivars(dev
, NULL
);
190 acd_shutdown(device_t dev
)
192 struct ata_device
*atadev
= device_get_softc(dev
);
194 if (atadev
->param
.support
.command2
& ATA_SUPPORT_FLUSHCACHE
)
195 ata_controlcmd(dev
, ATA_FLUSHCACHE
, 0, 0, 0);
199 acd_reinit(device_t dev
)
201 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
202 struct ata_device
*atadev
= device_get_softc(dev
);
203 struct acd_softc
*cdp
= device_get_ivars(dev
);
205 if (((atadev
->unit
== ATA_MASTER
) && !(ch
->devices
& ATA_ATAPI_MASTER
)) ||
206 ((atadev
->unit
== ATA_SLAVE
) && !(ch
->devices
& ATA_ATAPI_SLAVE
))) {
207 device_set_ivars(dev
, NULL
);
211 ATA_SETMODE(device_get_parent(dev
), dev
);
216 acd_open(struct dev_open_args
*ap
)
218 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
219 struct ata_device
*atadev
= device_get_softc(dev
);
220 struct acd_softc
*cdp
= device_get_ivars(dev
);
221 struct ata_request
*request
;
222 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
228 if (!device_is_attached(dev
))
230 if (!(request
= ata_alloc_request()))
233 /* wait if drive is not finished loading the medium */
235 bzero(request
, sizeof(struct ata_request
));
237 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
238 request
->flags
= ATA_R_ATAPI
;
239 request
->timeout
= 5;
240 ata_queue_request(request
);
241 if (!request
->error
&&
242 (request
->u
.atapi
.sense
.key
== 2 ||
243 request
->u
.atapi
.sense
.key
== 7) &&
244 request
->u
.atapi
.sense
.asc
== 4 &&
245 request
->u
.atapi
.sense
.ascq
== 1)
246 tsleep(&timeout
, 0, "acdld", hz
/ 2);
250 ata_free_request(request
);
252 if (count_dev(cdp
->cdev
) == 1) {
253 acd_prevent_allow(dev
, 1);
254 cdp
->flags
|= F_LOCKED
;
261 acd_close(struct dev_close_args
*ap
)
263 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
264 struct acd_softc
*cdp
= device_get_ivars(dev
);
269 if (count_dev(cdp
->cdev
) == 1) {
270 acd_prevent_allow(dev
, 0);
271 cdp
->flags
&= ~F_LOCKED
;
277 acd_ioctl(struct dev_ioctl_args
*ap
)
279 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
280 struct ata_device
*atadev
= device_get_softc(dev
);
281 struct acd_softc
*cdp
= device_get_ivars(dev
);
282 int error
= 0, nocopyout
= 0;
287 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
295 acd_prevent_allow(dev
, 1);
296 cdp
->flags
|= F_LOCKED
;
304 error
= acd_pause_resume(dev
, 1);
308 error
= acd_pause_resume(dev
, 0);
312 error
= acd_start_stop(dev
, 1);
316 error
= acd_start_stop(dev
, 0);
320 error
= acd_prevent_allow(dev
, 0);
321 cdp
->flags
&= ~F_LOCKED
;
325 error
= acd_prevent_allow(dev
, 1);
326 cdp
->flags
|= F_LOCKED
;
330 error
= suser_cred(ap
->a_cred
, 0);
333 error
= acd_test_ready(dev
);
337 if (count_dev(cdp
->cdev
) > 1) {
341 error
= acd_tray(dev
, 0);
345 if (count_dev(cdp
->cdev
) > 1)
347 error
= acd_tray(dev
, 1);
350 case CDIOREADTOCHEADER
:
351 if (!cdp
->toc
.hdr
.ending_track
) {
355 bcopy(&cdp
->toc
.hdr
, ap
->a_data
, sizeof(cdp
->toc
.hdr
));
358 case CDIOREADTOCENTRYS
:
360 struct ioc_read_toc_entry
*te
= (struct ioc_read_toc_entry
*)ap
->a_data
;
361 struct toc
*toc
= &cdp
->toc
;
362 int starting_track
= te
->starting_track
;
365 if (!toc
->hdr
.ending_track
) {
370 if (te
->data_len
< sizeof(toc
->tab
[0]) ||
371 (te
->data_len
% sizeof(toc
->tab
[0])) != 0 ||
372 (te
->address_format
!= CD_MSF_FORMAT
&&
373 te
->address_format
!= CD_LBA_FORMAT
)) {
379 starting_track
= toc
->hdr
.starting_track
;
380 else if (starting_track
== 170)
381 starting_track
= toc
->hdr
.ending_track
+ 1;
382 else if (starting_track
< toc
->hdr
.starting_track
||
383 starting_track
> toc
->hdr
.ending_track
+ 1) {
388 len
= ((toc
->hdr
.ending_track
+ 1 - starting_track
) + 1) *
390 if (te
->data_len
< len
)
392 if (len
> sizeof(toc
->tab
)) {
397 if (te
->address_format
== CD_MSF_FORMAT
) {
398 struct cd_toc_entry
*entry
;
400 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
401 if (!(toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_NOWAIT
))) {
405 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
406 entry
= toc
->tab
+ (toc
->hdr
.ending_track
+ 1 -
407 toc
->hdr
.starting_track
) + 1;
408 while (--entry
>= toc
->tab
) {
409 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
410 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
411 entry
->addr_type
= CD_MSF_FORMAT
;
414 error
= copyout(toc
->tab
+ starting_track
- toc
->hdr
.starting_track
,
416 if (te
->address_format
== CD_MSF_FORMAT
)
421 case CDIOREADTOCENTRY
:
423 struct ioc_read_toc_single_entry
*te
=
424 (struct ioc_read_toc_single_entry
*)ap
->a_data
;
425 struct toc
*toc
= &cdp
->toc
;
426 u_char track
= te
->track
;
428 if (!toc
->hdr
.ending_track
) {
433 if (te
->address_format
!= CD_MSF_FORMAT
&&
434 te
->address_format
!= CD_LBA_FORMAT
) {
440 track
= toc
->hdr
.starting_track
;
441 else if (track
== 170)
442 track
= toc
->hdr
.ending_track
+ 1;
443 else if (track
< toc
->hdr
.starting_track
||
444 track
> toc
->hdr
.ending_track
+ 1) {
449 if (te
->address_format
== CD_MSF_FORMAT
) {
450 struct cd_toc_entry
*entry
;
452 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
453 if (!(toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_NOWAIT
))) {
457 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
458 entry
= toc
->tab
+ (track
- toc
->hdr
.starting_track
);
459 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
460 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
462 bcopy(toc
->tab
+ track
- toc
->hdr
.starting_track
,
463 &te
->entry
, sizeof(struct cd_toc_entry
));
464 if (te
->address_format
== CD_MSF_FORMAT
)
469 /* XXX TGEN Remove this and the rest of the nocopyout logic? */
470 #if __FreeBSD_version > 600008
471 case CDIOCREADSUBCHANNEL_SYSSPACE
:
476 case CDIOCREADSUBCHANNEL
:
478 struct ioc_read_subchannel
*args
=
479 (struct ioc_read_subchannel
*)ap
->a_data
;
481 int8_t ccb
[16] = { ATAPI_READ_SUBCHANNEL
, 0, 0x40, 1, 0, 0, 0,
482 sizeof(cdp
->subchan
)>>8, sizeof(cdp
->subchan
),
483 0, 0, 0, 0, 0, 0, 0 };
485 if (args
->data_len
> sizeof(struct cd_sub_channel_info
) ||
486 args
->data_len
< sizeof(struct cd_sub_channel_header
)) {
491 format
= args
->data_format
;
492 if ((format
!= CD_CURRENT_POSITION
) &&
493 (format
!= CD_MEDIA_CATALOG
) && (format
!= CD_TRACK_INFO
)) {
498 ccb
[1] = args
->address_format
& CD_MSF_FORMAT
;
500 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
501 sizeof(cdp
->subchan
), ATA_R_READ
, 10)))
504 if ((format
== CD_MEDIA_CATALOG
) || (format
== CD_TRACK_INFO
)) {
505 if (cdp
->subchan
.header
.audio_status
== 0x11) {
511 if (format
== CD_TRACK_INFO
)
512 ccb
[6] = args
->track
;
514 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
515 sizeof(cdp
->subchan
),ATA_R_READ
,10))){
519 /* XXX TGEN Remove this and the rest of the nocopyout logic? */
520 if (nocopyout
== 0) {
521 error
= copyout(&cdp
->subchan
, args
->data
, args
->data_len
);
524 bcopy(&cdp
->subchan
, args
->data
, args
->data_len
);
531 struct ioc_play_msf
*args
= (struct ioc_play_msf
*)ap
->a_data
;
535 msf2lba(args
->start_m
, args
->start_s
, args
->start_f
),
536 msf2lba(args
->end_m
, args
->end_s
, args
->end_f
));
540 case CDIOCPLAYBLOCKS
:
542 struct ioc_play_blocks
*args
= (struct ioc_play_blocks
*)ap
->a_data
;
544 error
= acd_play(dev
, args
->blk
, args
->blk
+ args
->len
);
548 case CDIOCPLAYTRACKS
:
550 struct ioc_play_track
*args
= (struct ioc_play_track
*)ap
->a_data
;
553 if (!cdp
->toc
.hdr
.ending_track
) {
557 if (args
->end_track
< cdp
->toc
.hdr
.ending_track
+ 1)
559 if (args
->end_track
> cdp
->toc
.hdr
.ending_track
+ 1)
560 args
->end_track
= cdp
->toc
.hdr
.ending_track
+ 1;
561 t1
= args
->start_track
- cdp
->toc
.hdr
.starting_track
;
562 t2
= args
->end_track
- cdp
->toc
.hdr
.starting_track
;
563 if (t1
< 0 || t2
< 0 ||
564 t1
> (cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
)) {
568 error
= acd_play(dev
, ntohl(cdp
->toc
.tab
[t1
].addr
.lba
),
569 ntohl(cdp
->toc
.tab
[t2
].addr
.lba
));
575 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
577 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
578 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
581 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
585 arg
->vol
[0] = cdp
->au
.port
[0].volume
;
586 arg
->vol
[1] = cdp
->au
.port
[1].volume
;
587 arg
->vol
[2] = cdp
->au
.port
[2].volume
;
588 arg
->vol
[3] = cdp
->au
.port
[3].volume
;
594 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
596 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
597 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
599 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
603 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE_MASK
,
604 (caddr_t
)&cdp
->aumask
,
605 sizeof(cdp
->aumask
))))
607 cdp
->au
.data_length
= 0;
608 cdp
->au
.port
[0].channels
= CHANNEL_0
;
609 cdp
->au
.port
[1].channels
= CHANNEL_1
;
610 cdp
->au
.port
[0].volume
= arg
->vol
[0] & cdp
->aumask
.port
[0].volume
;
611 cdp
->au
.port
[1].volume
= arg
->vol
[1] & cdp
->aumask
.port
[1].volume
;
612 cdp
->au
.port
[2].volume
= arg
->vol
[2] & cdp
->aumask
.port
[2].volume
;
613 cdp
->au
.port
[3].volume
= arg
->vol
[3] & cdp
->aumask
.port
[3].volume
;
614 error
= acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
620 struct ioc_patch
*arg
= (struct ioc_patch
*)ap
->a_data
;
622 error
= acd_setchan(dev
, arg
->patch
[0], arg
->patch
[1],
623 arg
->patch
[2], arg
->patch
[3]);
628 error
= acd_setchan(dev
, CHANNEL_0
|CHANNEL_1
, CHANNEL_0
|CHANNEL_1
, 0,0);
632 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_1
, 0, 0);
636 error
= acd_setchan(dev
, 0, 0, 0, 0);
640 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_0
, 0, 0);
644 error
= acd_setchan(dev
, CHANNEL_1
, CHANNEL_1
, 0, 0);
648 error
= acd_blank(dev
, (*(int *)ap
->a_data
));
651 case CDRIOCNEXTWRITEABLEADDR
:
653 struct acd_track_info track_info
;
655 if ((error
= acd_read_track_info(dev
, 0xff, &track_info
)))
658 if (!track_info
.nwa_valid
) {
662 *(int*)ap
->a_data
= track_info
.next_writeable_addr
;
666 case CDRIOCINITWRITER
:
667 error
= acd_init_writer(dev
, (*(int *)ap
->a_data
));
670 case CDRIOCINITTRACK
:
671 error
= acd_init_track(dev
, (struct cdr_track
*)ap
->a_data
);
675 error
= acd_flush(dev
);
679 error
= acd_fixate(dev
, (*(int *)ap
->a_data
));
682 case CDRIOCREADSPEED
:
684 int speed
= *(int *)ap
->a_data
;
686 /* Preserve old behavior: units in multiples of CDROM speed */
689 error
= acd_set_speed(dev
, speed
, CDR_MAX_SPEED
);
693 case CDRIOCWRITESPEED
:
695 int speed
= *(int *)ap
->a_data
;
699 error
= acd_set_speed(dev
, CDR_MAX_SPEED
, speed
);
703 case CDRIOCGETBLOCKSIZE
:
704 *(int *)ap
->a_data
= cdp
->block_size
;
707 case CDRIOCSETBLOCKSIZE
:
708 cdp
->block_size
= *(int *)ap
->a_data
;
712 case CDRIOCGETPROGRESS
:
713 error
= acd_get_progress(dev
, (int *)ap
->a_data
);
717 error
= acd_send_cue(dev
, (struct cdr_cuesheet
*)ap
->a_data
);
720 #ifdef ACD_CDR_FORMAT
721 case CDRIOCREADFORMATCAPS
:
722 error
= acd_read_format_caps(dev
,
723 (struct cdr_format_capacities
*)ap
->a_data
);
727 error
= acd_format(dev
, (struct cdr_format_params
*)ap
->a_data
);
729 #endif /* ACD_CDR_FORMAT */
731 case DVDIOCREPORTKEY
:
732 if (cdp
->cap
.media
& MST_READ_DVDROM
)
733 error
= acd_report_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
739 if (cdp
->cap
.media
& MST_READ_DVDROM
)
740 error
= acd_send_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
745 case DVDIOCREADSTRUCTURE
:
746 if (cdp
->cap
.media
& MST_READ_DVDROM
)
747 error
= acd_read_structure(dev
, (struct dvd_struct
*)ap
->a_data
);
753 error
= ata_device_ioctl(dev
, ap
->a_cmd
, ap
->a_data
);
759 acd_strategy(struct dev_strategy_args
*ap
)
761 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
762 struct bio
*bp
= ap
->a_bio
;
763 struct buf
*bbp
= bp
->bio_buf
;
764 struct ata_device
*atadev
= device_get_softc(dev
);
765 struct acd_softc
*cdp
= device_get_ivars(dev
);
766 cdev_t cdev
= cdp
->cdev
;
768 if (bbp
->b_cmd
!= BUF_CMD_READ
&& bbp
->b_cmd
!= BUF_CMD_WRITE
) {
769 bbp
->b_flags
|= B_ERROR
;
770 bbp
->b_error
= EOPNOTSUPP
;
775 if (bbp
->b_cmd
== BUF_CMD_READ
&& cdp
->disk_size
== -1) {
776 bbp
->b_flags
|= B_ERROR
;
782 bp
->bio_driver_info
= cdev
;
783 bbp
->b_resid
= bbp
->b_bcount
;
789 /* XXX TGEN Collapse this with acd_strategy()? */
791 acd_start(device_t dev
, struct bio
*bp
)
793 struct buf
*bbp
= bp
->bio_buf
;
794 struct ata_device
*atadev
= device_get_softc(dev
);
795 struct acd_softc
*cdp
= device_get_ivars(dev
);
796 struct ata_request
*request
;
798 u_int32_t lba
, lastlba
, count
;
800 int track
, blocksize
;
802 cdev
= bp
->bio_driver_info
;
804 /* reject all queued entries if media changed */
805 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
806 bbp
->b_flags
|= B_ERROR
;
812 bzero(ccb
, sizeof(ccb
));
814 /* AND the unit number out of the minor, and shift the tracknumber back */
815 track
= (cdev
->si_udev
& 0x00ff0000) >> 16;
818 blocksize
= (cdp
->toc
.tab
[track
- 1].control
& 4) ? 2048 : 2352;
819 lastlba
= ntohl(cdp
->toc
.tab
[track
].addr
.lba
);
820 lba
= bp
->bio_offset
/ blocksize
;
821 lba
+= ntohl(cdp
->toc
.tab
[track
- 1].addr
.lba
);
824 blocksize
= cdp
->block_size
;
825 lastlba
= cdp
->disk_size
;
826 lba
= bp
->bio_offset
/ blocksize
;
829 count
= bbp
->b_bcount
/ blocksize
;
831 if (bbp
->b_cmd
== BUF_CMD_READ
) {
832 /* if transfer goes beyond range adjust it to be within limits */
833 if (lba
+ count
> lastlba
) {
834 /* if we are entirely beyond EOM return EOF */
835 if (lastlba
<= lba
) {
836 bbp
->b_resid
= bbp
->b_bcount
;
840 count
= lastlba
- lba
;
844 ccb
[0] = ATAPI_READ_BIG
;
848 ccb
[0] = ATAPI_READ_CD
;
853 ccb
[0] = ATAPI_READ_CD
;
858 ccb
[0] = ATAPI_WRITE_BIG
;
869 if (!(request
= ata_alloc_request())) {
870 bbp
->b_flags
|= B_ERROR
;
871 bbp
->b_error
= ENOMEM
;
877 bcopy(ccb
, request
->u
.atapi
.ccb
,
878 (atadev
->param
.config
& ATA_PROTO_MASK
) ==
879 ATA_PROTO_ATAPI_12
? 16 : 12);
880 request
->data
= bbp
->b_data
;
881 request
->bytecount
= count
* blocksize
;
882 request
->transfersize
= min(request
->bytecount
, 65534);
883 request
->timeout
= (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30;
884 request
->retries
= 2;
885 request
->callback
= acd_done
;
886 request
->flags
= ATA_R_ATAPI
;
887 if (atadev
->mode
>= ATA_DMA
)
888 request
->flags
|= ATA_R_DMA
;
889 switch (bbp
->b_cmd
) {
891 request
->flags
|= ATA_R_READ
;
894 request
->flags
|= ATA_R_WRITE
;
897 device_printf(dev
, "unknown BUF operation\n");
898 ata_free_request(request
);
899 bbp
->b_flags
|= B_ERROR
;
904 devstat_start_transaction(&cdp
->stats
);
905 ata_queue_request(request
);
909 acd_done(struct ata_request
*request
)
911 struct acd_softc
*cdp
= device_get_ivars(request
->dev
);
912 struct bio
*bp
= request
->bio
;
913 struct buf
*bbp
= bp
->bio_buf
;
915 /* finish up transfer */
916 if ((bbp
->b_error
= request
->result
))
917 bbp
->b_flags
|= B_ERROR
;
918 bbp
->b_resid
= bbp
->b_bcount
- request
->donecount
;
919 devstat_end_transaction_buf(&cdp
->stats
, bbp
);
921 ata_free_request(request
);
925 acd_set_ioparm(device_t dev
)
927 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
928 struct acd_softc
*cdp
= device_get_ivars(dev
);
931 cdp
->iomax
= min(ch
->dma
->max_iosize
, 65534);
933 cdp
->iomax
= min(DFLTPHYS
, 65534);
937 lba2msf(u_int32_t lba
, u_int8_t
*m
, u_int8_t
*s
, u_int8_t
*f
)
941 *m
= lba
/ (60 * 75);
948 msf2lba(u_int8_t m
, u_int8_t s
, u_int8_t f
)
950 return (m
* 60 + s
) * 75 + f
- 150;
954 acd_read_toc(device_t dev
)
956 struct ata_device
*atadev
= device_get_softc(dev
);
957 struct acd_softc
*cdp
= device_get_ivars(dev
);
958 struct acd_tracknode
*tracknode
;
961 int track
, ntracks
, len
;
963 atadev
->flags
&= ~ATA_D_MEDIA_CHANGED
;
964 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
966 if (acd_test_ready(dev
))
969 bzero(ccb
, sizeof(ccb
));
970 len
= sizeof(struct ioc_toc_header
) + sizeof(struct cd_toc_entry
);
971 ccb
[0] = ATAPI_READ_TOC
;
974 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
975 ATA_R_READ
| ATA_R_QUIET
, 30)) {
976 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
979 ntracks
= cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1;
980 if (ntracks
<= 0 || ntracks
> MAXTRK
) {
981 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
985 len
= sizeof(struct ioc_toc_header
)+(ntracks
+1)*sizeof(struct cd_toc_entry
);
986 bzero(ccb
, sizeof(ccb
));
987 ccb
[0] = ATAPI_READ_TOC
;
990 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
991 ATA_R_READ
| ATA_R_QUIET
, 30)) {
992 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
995 cdp
->toc
.hdr
.len
= ntohs(cdp
->toc
.hdr
.len
);
997 cdp
->block_size
= (cdp
->toc
.tab
[0].control
& 4) ? 2048 : 2352;
999 bzero(ccb
, sizeof(ccb
));
1000 ccb
[0] = ATAPI_READ_CAPACITY
;
1001 if (ata_atapicmd(dev
, ccb
, (caddr_t
)sizes
, sizeof(sizes
),
1002 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1003 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1006 cdp
->disk_size
= ntohl(sizes
[0]) + 1;
1008 for (track
= 1; track
<= ntracks
; track
++) {
1009 if (cdp
->track
[track
] != NULL
)
1011 tracknode
= acd_make_tracknode(dev
, track
);
1012 cdp
->track
[track
] = tracknode
;
1014 for (; track
< MAXTRK
; track
++) {
1015 if (cdp
->track
[track
] == NULL
)
1017 acd_destroy_tracknode(dev
, track
);
1018 cdp
->track
[track
] = NULL
;
1022 if (cdp
->disk_size
&& cdp
->toc
.hdr
.ending_track
) {
1023 device_printf(dev
, "(%d sectors (%d bytes)), %d tracks ",
1024 cdp
->disk_size
, cdp
->block_size
,
1025 cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
+1);
1026 if (cdp
->toc
.tab
[0].control
& 4)
1027 printf("%dMB\n", cdp
->disk_size
* cdp
->block_size
/ 1048576);
1029 printf("%d:%d audio\n",
1030 cdp
->disk_size
/ 75 / 60, cdp
->disk_size
/ 75 % 60);
1036 * Makes a new device node for the numbered track and returns a struct
1037 * acd_tracknode pointer to be included in the list of tracks available on the
1040 static struct acd_tracknode
*
1041 acd_make_tracknode(device_t dev
, int track
)
1043 struct acd_softc
*cdp
= device_get_ivars(dev
);
1044 struct acd_tracknode
*tracknode
;
1047 ksprintf(name
, "acd%dt%d", device_get_unit(dev
), track
);
1048 tracknode
= kmalloc(sizeof(struct acd_tracknode
), M_ACD
, M_WAITOK
| M_ZERO
);
1049 tracknode
->cdev
= make_dev(&acd_ops
, (device_get_unit(dev
) << 3) |
1050 (track
<< 16), UID_ROOT
, GID_OPERATOR
, 0644,
1052 tracknode
->cdev
->si_drv1
= cdp
->cdev
->si_drv1
;
1053 reference_dev(tracknode
->cdev
);
1058 * Destroys the device node of a numbered track and frees the related struct
1059 * acd_tracknode. It could be done just in acd_read_toc(), but it's nice to
1060 * have a complementary function to acd_make_tracknode().
1063 acd_destroy_tracknode(device_t dev
, int track
)
1065 struct acd_softc
*cdp
= device_get_ivars(dev
);
1066 struct acd_tracknode
*tracknode
;
1068 tracknode
= cdp
->track
[track
];
1069 destroy_dev(tracknode
->cdev
);
1070 kfree(tracknode
, M_ACD
);
1074 acd_play(device_t dev
, int start
, int end
)
1078 bzero(ccb
, sizeof(ccb
));
1079 ccb
[0] = ATAPI_PLAY_MSF
;
1080 lba2msf(start
, &ccb
[3], &ccb
[4], &ccb
[5]);
1081 lba2msf(end
, &ccb
[6], &ccb
[7], &ccb
[8]);
1082 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 10);
1086 acd_setchan(device_t dev
, u_int8_t c0
, u_int8_t c1
, u_int8_t c2
, u_int8_t c3
)
1088 struct acd_softc
*cdp
= device_get_ivars(dev
);
1091 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
, (caddr_t
)&cdp
->au
,
1094 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
)
1096 cdp
->au
.data_length
= 0;
1097 cdp
->au
.port
[0].channels
= c0
;
1098 cdp
->au
.port
[1].channels
= c1
;
1099 cdp
->au
.port
[2].channels
= c2
;
1100 cdp
->au
.port
[3].channels
= c3
;
1101 return acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
1105 acd_init_writer(device_t dev
, int test_write
)
1109 bzero(ccb
, sizeof(ccb
));
1110 ccb
[0] = ATAPI_REZERO
;
1111 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1112 ccb
[0] = ATAPI_SEND_OPC_INFO
;
1114 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 30);
1119 acd_fixate(device_t dev
, int multisession
)
1121 struct acd_softc
*cdp
= device_get_ivars(dev
);
1122 int8_t ccb
[16] = { ATAPI_CLOSE_TRACK
, 0x01, 0x02, 0, 0, 0, 0, 0,
1123 0, 0, 0, 0, 0, 0, 0, 0 };
1124 int timeout
= 5*60*2;
1126 struct write_param param
;
1128 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1129 (caddr_t
)¶m
, sizeof(param
))))
1132 param
.data_length
= 0;
1134 param
.session_type
= CDR_SESS_MULTI
;
1136 param
.session_type
= CDR_SESS_NONE
;
1138 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1141 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1145 /* some drives just return ready, wait for the expected fixate time */
1146 if ((error
= acd_test_ready(dev
)) != EBUSY
) {
1147 timeout
= timeout
/ (cdp
->cap
.cur_write_speed
/ 177);
1148 tsleep(&error
, 0, "acdfix", timeout
* hz
/ 2);
1149 return acd_test_ready(dev
);
1152 while (timeout
-- > 0) {
1153 if ((error
= acd_get_progress(dev
, &dummy
)))
1155 if ((error
= acd_test_ready(dev
)) != EBUSY
)
1157 tsleep(&error
, 0, "acdcld", hz
/ 2);
1163 acd_init_track(device_t dev
, struct cdr_track
*track
)
1165 struct acd_softc
*cdp
= device_get_ivars(dev
);
1166 struct write_param param
;
1169 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1170 (caddr_t
)¶m
, sizeof(param
))))
1173 param
.data_length
= 0;
1174 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1175 param
.page_length
= 0x32;
1176 param
.test_write
= track
->test_write
? 1 : 0;
1177 param
.write_type
= CDR_WTYPE_TRACK
;
1178 param
.session_type
= CDR_SESS_NONE
;
1180 param
.packet_size
= 0;
1182 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1183 param
.burnproof
= 1;
1185 switch (track
->datablock_type
) {
1189 param
.track_mode
= CDR_TMODE_AUDIO_PREEMP
;
1191 param
.track_mode
= CDR_TMODE_AUDIO
;
1192 cdp
->block_size
= 2352;
1193 param
.datablock_type
= CDR_DB_RAW
;
1194 param
.session_format
= CDR_SESS_CDROM
;
1197 case CDR_DB_ROM_MODE1
:
1198 cdp
->block_size
= 2048;
1199 param
.track_mode
= CDR_TMODE_DATA
;
1200 param
.datablock_type
= CDR_DB_ROM_MODE1
;
1201 param
.session_format
= CDR_SESS_CDROM
;
1204 case CDR_DB_ROM_MODE2
:
1205 cdp
->block_size
= 2336;
1206 param
.track_mode
= CDR_TMODE_DATA
;
1207 param
.datablock_type
= CDR_DB_ROM_MODE2
;
1208 param
.session_format
= CDR_SESS_CDROM
;
1211 case CDR_DB_XA_MODE1
:
1212 cdp
->block_size
= 2048;
1213 param
.track_mode
= CDR_TMODE_DATA
;
1214 param
.datablock_type
= CDR_DB_XA_MODE1
;
1215 param
.session_format
= CDR_SESS_CDROM_XA
;
1218 case CDR_DB_XA_MODE2_F1
:
1219 cdp
->block_size
= 2056;
1220 param
.track_mode
= CDR_TMODE_DATA
;
1221 param
.datablock_type
= CDR_DB_XA_MODE2_F1
;
1222 param
.session_format
= CDR_SESS_CDROM_XA
;
1225 case CDR_DB_XA_MODE2_F2
:
1226 cdp
->block_size
= 2324;
1227 param
.track_mode
= CDR_TMODE_DATA
;
1228 param
.datablock_type
= CDR_DB_XA_MODE2_F2
;
1229 param
.session_format
= CDR_SESS_CDROM_XA
;
1232 case CDR_DB_XA_MODE2_MIX
:
1233 cdp
->block_size
= 2332;
1234 param
.track_mode
= CDR_TMODE_DATA
;
1235 param
.datablock_type
= CDR_DB_XA_MODE2_MIX
;
1236 param
.session_format
= CDR_SESS_CDROM_XA
;
1239 acd_set_ioparm(dev
);
1240 return acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10);
1244 acd_flush(device_t dev
)
1246 int8_t ccb
[16] = { ATAPI_SYNCHRONIZE_CACHE
, 0, 0, 0, 0, 0, 0, 0,
1247 0, 0, 0, 0, 0, 0, 0, 0 };
1249 return ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1253 acd_read_track_info(device_t dev
, int32_t lba
, struct acd_track_info
*info
)
1255 int8_t ccb
[16] = { ATAPI_READ_TRACK_INFO
, 1,
1256 lba
>>24, lba
>>16, lba
>>8, lba
, 0,
1257 sizeof(*info
)>>8, sizeof(*info
),
1258 0, 0, 0, 0, 0, 0, 0 };
1261 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)info
, sizeof(*info
),
1264 info
->track_start_addr
= ntohl(info
->track_start_addr
);
1265 info
->next_writeable_addr
= ntohl(info
->next_writeable_addr
);
1266 info
->free_blocks
= ntohl(info
->free_blocks
);
1267 info
->fixed_packet_size
= ntohl(info
->fixed_packet_size
);
1268 info
->track_length
= ntohl(info
->track_length
);
1273 acd_get_progress(device_t dev
, int *finished
)
1275 int8_t ccb
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
1276 0, 0, 0, 0, 0, 0, 0, 0 };
1277 struct ata_request
*request
;
1280 if (!(request
= ata_alloc_request()))
1284 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
1285 request
->data
= dummy
;
1286 request
->bytecount
= sizeof(dummy
);
1287 request
->transfersize
= min(request
->bytecount
, 65534);
1288 request
->flags
= ATA_R_ATAPI
| ATA_R_READ
;
1289 request
->timeout
= 30;
1290 ata_queue_request(request
);
1291 if (!request
->error
&& request
->u
.atapi
.sense
.error
& ATA_SENSE_VALID
)
1292 *finished
= ((request
->u
.atapi
.sense
.specific2
|
1293 (request
->u
.atapi
.sense
.specific1
<< 8)) * 100) / 65535;
1296 ata_free_request(request
);
1301 acd_send_cue(device_t dev
, struct cdr_cuesheet
*cuesheet
)
1303 struct acd_softc
*cdp
= device_get_ivars(dev
);
1304 struct write_param param
;
1305 int8_t ccb
[16] = { ATAPI_SEND_CUE_SHEET
, 0, 0, 0, 0, 0,
1306 cuesheet
->len
>>16, cuesheet
->len
>>8, cuesheet
->len
,
1307 0, 0, 0, 0, 0, 0, 0 };
1311 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1312 (caddr_t
)¶m
, sizeof(param
))))
1315 param
.data_length
= 0;
1316 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1317 param
.page_length
= 0x32;
1318 param
.test_write
= cuesheet
->test_write
? 1 : 0;
1319 param
.write_type
= CDR_WTYPE_SESSION
;
1320 param
.session_type
= cuesheet
->session_type
;
1322 param
.packet_size
= 0;
1323 param
.track_mode
= CDR_TMODE_AUDIO
;
1324 param
.datablock_type
= CDR_DB_RAW
;
1325 param
.session_format
= cuesheet
->session_format
;
1326 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1327 param
.burnproof
= 1;
1329 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1332 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1333 if (!(buffer
= kmalloc(cuesheet
->len
, M_ACD
, M_NOWAIT
)))
1336 if (!(error
= copyin(cuesheet
->entries
, buffer
, cuesheet
->len
)))
1337 error
= ata_atapicmd(dev
, ccb
, buffer
, cuesheet
->len
, 0, 30);
1338 kfree(buffer
, M_ACD
);
1343 acd_report_key(device_t dev
, struct dvd_authinfo
*ai
)
1345 struct dvd_miscauth
*d
= NULL
;
1351 switch (ai
->format
) {
1352 case DVD_REPORT_AGID
:
1353 case DVD_REPORT_ASF
:
1354 case DVD_REPORT_RPC
:
1357 case DVD_REPORT_KEY1
:
1360 case DVD_REPORT_TITLE_KEY
:
1364 case DVD_REPORT_CHALLENGE
:
1367 case DVD_INVALIDATE_AGID
:
1374 bzero(ccb
, sizeof(ccb
));
1375 ccb
[0] = ATAPI_REPORT_KEY
;
1376 ccb
[2] = (lba
>> 24) & 0xff;
1377 ccb
[3] = (lba
>> 16) & 0xff;
1378 ccb
[4] = (lba
>> 8) & 0xff;
1379 ccb
[5] = lba
& 0xff;
1380 ccb
[8] = (length
>> 8) & 0xff;
1381 ccb
[9] = length
& 0xff;
1382 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1385 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1386 if (!(d
= kmalloc(length
, M_ACD
, M_NOWAIT
| M_ZERO
)))
1388 d
->length
= htons(length
- 2);
1391 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
,
1392 ai
->format
== DVD_INVALIDATE_AGID
? 0 : ATA_R_READ
,10);
1399 switch (ai
->format
) {
1400 case DVD_REPORT_AGID
:
1401 ai
->agid
= d
->data
[3] >> 6;
1404 case DVD_REPORT_CHALLENGE
:
1405 bcopy(&d
->data
[0], &ai
->keychal
[0], 10);
1408 case DVD_REPORT_KEY1
:
1409 bcopy(&d
->data
[0], &ai
->keychal
[0], 5);
1412 case DVD_REPORT_TITLE_KEY
:
1413 ai
->cpm
= (d
->data
[0] >> 7);
1414 ai
->cp_sec
= (d
->data
[0] >> 6) & 0x1;
1415 ai
->cgms
= (d
->data
[0] >> 4) & 0x3;
1416 bcopy(&d
->data
[1], &ai
->keychal
[0], 5);
1419 case DVD_REPORT_ASF
:
1420 ai
->asf
= d
->data
[3] & 1;
1423 case DVD_REPORT_RPC
:
1424 ai
->reg_type
= (d
->data
[0] >> 6);
1425 ai
->vend_rsts
= (d
->data
[0] >> 3) & 0x7;
1426 ai
->user_rsts
= d
->data
[0] & 0x7;
1427 ai
->region
= d
->data
[1];
1428 ai
->rpc_scheme
= d
->data
[2];
1431 case DVD_INVALIDATE_AGID
:
1443 acd_send_key(device_t dev
, struct dvd_authinfo
*ai
)
1445 struct dvd_miscauth
*d
;
1450 switch (ai
->format
) {
1451 case DVD_SEND_CHALLENGE
:
1453 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1454 if (!(d
= kmalloc(length
, M_ACD
, M_NOWAIT
| M_ZERO
)))
1456 bcopy(ai
->keychal
, &d
->data
[0], 10);
1461 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1462 if (!(d
= kmalloc(length
, M_ACD
, M_NOWAIT
| M_ZERO
)))
1464 bcopy(&ai
->keychal
[0], &d
->data
[0], 5);
1469 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1470 if (!(d
= kmalloc(length
, M_ACD
, M_NOWAIT
| M_ZERO
)))
1472 d
->data
[0] = ai
->region
;
1479 bzero(ccb
, sizeof(ccb
));
1480 ccb
[0] = ATAPI_SEND_KEY
;
1481 ccb
[8] = (length
>> 8) & 0xff;
1482 ccb
[9] = length
& 0xff;
1483 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1484 d
->length
= htons(length
- 2);
1485 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, 0, 10);
1491 acd_read_structure(device_t dev
, struct dvd_struct
*s
)
1493 struct dvd_miscauth
*d
;
1499 case DVD_STRUCT_PHYSICAL
:
1503 case DVD_STRUCT_COPYRIGHT
:
1507 case DVD_STRUCT_DISCKEY
:
1511 case DVD_STRUCT_BCA
:
1515 case DVD_STRUCT_MANUFACT
:
1519 case DVD_STRUCT_DDS
:
1520 case DVD_STRUCT_PRERECORDED
:
1521 case DVD_STRUCT_UNIQUEID
:
1522 case DVD_STRUCT_LIST
:
1523 case DVD_STRUCT_CMI
:
1524 case DVD_STRUCT_RMD_LAST
:
1525 case DVD_STRUCT_RMD_RMA
:
1526 case DVD_STRUCT_DCB
:
1533 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
1534 if (!(d
= kmalloc(length
, M_ACD
, M_NOWAIT
| M_ZERO
)))
1536 d
->length
= htons(length
- 2);
1538 bzero(ccb
, sizeof(ccb
));
1539 ccb
[0] = ATAPI_READ_STRUCTURE
;
1540 ccb
[6] = s
->layer_num
;
1542 ccb
[8] = (length
>> 8) & 0xff;
1543 ccb
[9] = length
& 0xff;
1544 ccb
[10] = s
->agid
<< 6;
1545 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, ATA_R_READ
, 30);
1551 switch (s
->format
) {
1552 case DVD_STRUCT_PHYSICAL
: {
1553 struct dvd_layer
*layer
= (struct dvd_layer
*)&s
->data
[0];
1555 layer
->book_type
= d
->data
[0] >> 4;
1556 layer
->book_version
= d
->data
[0] & 0xf;
1557 layer
->disc_size
= d
->data
[1] >> 4;
1558 layer
->max_rate
= d
->data
[1] & 0xf;
1559 layer
->nlayers
= (d
->data
[2] >> 5) & 3;
1560 layer
->track_path
= (d
->data
[2] >> 4) & 1;
1561 layer
->layer_type
= d
->data
[2] & 0xf;
1562 layer
->linear_density
= d
->data
[3] >> 4;
1563 layer
->track_density
= d
->data
[3] & 0xf;
1564 layer
->start_sector
= d
->data
[5] << 16 | d
->data
[6] << 8 | d
->data
[7];
1565 layer
->end_sector
= d
->data
[9] << 16 | d
->data
[10] << 8 | d
->data
[11];
1566 layer
->end_sector_l0
= d
->data
[13] << 16 | d
->data
[14] << 8|d
->data
[15];
1567 layer
->bca
= d
->data
[16] >> 7;
1571 case DVD_STRUCT_COPYRIGHT
:
1572 s
->cpst
= d
->data
[0];
1573 s
->rmi
= d
->data
[1];
1576 case DVD_STRUCT_DISCKEY
:
1577 bcopy(&d
->data
[0], &s
->data
[0], 2048);
1580 case DVD_STRUCT_BCA
:
1581 s
->length
= ntohs(d
->length
);
1582 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1585 case DVD_STRUCT_MANUFACT
:
1586 s
->length
= ntohs(d
->length
);
1587 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1598 acd_tray(device_t dev
, int close
)
1600 struct ata_device
*atadev
= device_get_softc(dev
);
1601 struct acd_softc
*cdp
= device_get_ivars(dev
);
1604 if (cdp
->cap
.mechanism
& MST_EJECT
) {
1606 if (!(error
= acd_start_stop(dev
, 3))) {
1608 acd_prevent_allow(dev
, 1);
1609 cdp
->flags
|= F_LOCKED
;
1613 acd_start_stop(dev
, 0);
1614 acd_prevent_allow(dev
, 0);
1615 cdp
->flags
&= ~F_LOCKED
;
1616 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1617 error
= acd_start_stop(dev
, 2);
1624 acd_blank(device_t dev
, int blanktype
)
1626 struct ata_device
*atadev
= device_get_softc(dev
);
1627 int8_t ccb
[16] = { ATAPI_BLANK
, 0x10 | (blanktype
& 0x7), 0, 0, 0, 0, 0, 0,
1628 0, 0, 0, 0, 0, 0, 0, 0 };
1630 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1631 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1635 acd_prevent_allow(device_t dev
, int lock
)
1637 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
1638 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1640 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1644 acd_start_stop(device_t dev
, int start
)
1646 int8_t ccb
[16] = { ATAPI_START_STOP
, 0, 0, 0, start
,
1647 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1649 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1653 acd_pause_resume(device_t dev
, int pause
)
1655 int8_t ccb
[16] = { ATAPI_PAUSE
, 0, 0, 0, 0, 0, 0, 0, pause
,
1656 0, 0, 0, 0, 0, 0, 0 };
1658 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1662 acd_mode_sense(device_t dev
, int page
, caddr_t pagebuf
, int pagesize
)
1664 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, page
, 0, 0, 0, 0,
1665 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1668 error
= ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, ATA_R_READ
, 10);
1673 acd_mode_select(device_t dev
, caddr_t pagebuf
, int pagesize
)
1675 int8_t ccb
[16] = { ATAPI_MODE_SELECT_BIG
, 0x10, 0, 0, 0, 0, 0,
1676 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1678 return ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, 0, 30);
1682 acd_set_speed(device_t dev
, int rdspeed
, int wrspeed
)
1684 int8_t ccb
[16] = { ATAPI_SET_SPEED
, 0, rdspeed
>> 8, rdspeed
,
1685 wrspeed
>> 8, wrspeed
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1688 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1695 acd_get_cap(device_t dev
)
1697 struct acd_softc
*cdp
= device_get_ivars(dev
);
1700 /* get drive capabilities, some bugridden drives needs this repeated */
1701 for (count
= 0 ; count
< 5 ; count
++) {
1702 if (!acd_mode_sense(dev
, ATAPI_CDROM_CAP_PAGE
,
1703 (caddr_t
)&cdp
->cap
, sizeof(cdp
->cap
)) &&
1704 cdp
->cap
.page_code
== ATAPI_CDROM_CAP_PAGE
) {
1705 cdp
->cap
.max_read_speed
= ntohs(cdp
->cap
.max_read_speed
);
1706 cdp
->cap
.cur_read_speed
= ntohs(cdp
->cap
.cur_read_speed
);
1707 cdp
->cap
.max_write_speed
= ntohs(cdp
->cap
.max_write_speed
);
1708 cdp
->cap
.cur_write_speed
= max(ntohs(cdp
->cap
.cur_write_speed
),177);
1709 cdp
->cap
.max_vol_levels
= ntohs(cdp
->cap
.max_vol_levels
);
1710 cdp
->cap
.buf_size
= ntohs(cdp
->cap
.buf_size
);
1715 #ifdef ACD_CDR_FORMAT
1717 acd_read_format_caps(device_t dev
, struct cdr_format_capacities
*caps
)
1719 int8_t ccb
[16] = { ATAPI_READ_FORMAT_CAPACITIES
, 0, 0, 0, 0, 0, 0,
1720 (sizeof(struct cdr_format_capacities
) >> 8) & 0xff,
1721 sizeof(struct cdr_format_capacities
) & 0xff,
1722 0, 0, 0, 0, 0, 0, 0 };
1724 return ata_atapicmd(dev
, ccb
, (caddr_t
)caps
,
1725 sizeof(struct cdr_format_capacities
), ATA_R_READ
, 30);
1729 acd_format(device_t dev
, struct cdr_format_params
* params
)
1731 int8_t ccb
[16] = { ATAPI_FORMAT
, 0x11, 0, 0, 0, 0, 0, 0, 0, 0,
1735 error
= ata_atapicmd(dev
, ccb
, (u_int8_t
*)params
,
1736 sizeof(struct cdr_format_params
), 0, 30);
1739 #endif /* ACD_CDR_FORMAT */
1742 acd_test_ready(device_t dev
)
1744 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
1745 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1747 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1751 acd_describe(device_t dev
)
1753 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
1754 struct ata_device
*atadev
= device_get_softc(dev
);
1755 struct acd_softc
*cdp
= device_get_ivars(dev
);
1760 device_printf(dev
, "<%.40s/%.8s> %s drive at ata%d as %s\n",
1761 atadev
->param
.model
, atadev
->param
.revision
,
1762 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1763 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1764 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1765 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1766 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM":"CDROM",
1767 device_get_unit(ch
->dev
),
1768 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave");
1770 device_printf(dev
, "%s", "");
1771 if (cdp
->cap
.cur_read_speed
) {
1772 printf("read %dKB/s", cdp
->cap
.cur_read_speed
* 1000 / 1024);
1773 if (cdp
->cap
.max_read_speed
)
1774 printf(" (%dKB/s)", cdp
->cap
.max_read_speed
* 1000 / 1024);
1775 if ((cdp
->cap
.cur_write_speed
) &&
1776 (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1777 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
))) {
1778 printf(" write %dKB/s", cdp
->cap
.cur_write_speed
* 1000 / 1024);
1779 if (cdp
->cap
.max_write_speed
)
1780 printf(" (%dKB/s)", cdp
->cap
.max_write_speed
* 1000 / 1024);
1784 if (cdp
->cap
.buf_size
) {
1785 printf("%s %dKB buffer", comma
? "," : "", cdp
->cap
.buf_size
);
1788 printf("%s %s\n", comma
? "," : "", ata_mode2str(atadev
->mode
));
1790 device_printf(dev
, "Reads:");
1792 if (cdp
->cap
.media
& MST_READ_CDR
) {
1793 printf(" CDR"); comma
= 1;
1795 if (cdp
->cap
.media
& MST_READ_CDRW
) {
1796 printf("%s CDRW", comma
? "," : ""); comma
= 1;
1798 if (cdp
->cap
.capabilities
& MST_READ_CDDA
) {
1799 if (cdp
->cap
.capabilities
& MST_CDDA_STREAM
)
1800 printf("%s CDDA stream", comma
? "," : "");
1802 printf("%s CDDA", comma
? "," : "");
1805 if (cdp
->cap
.media
& MST_READ_DVDROM
) {
1806 printf("%s DVDROM", comma
? "," : ""); comma
= 1;
1808 if (cdp
->cap
.media
& MST_READ_DVDR
) {
1809 printf("%s DVDR", comma
? "," : ""); comma
= 1;
1811 if (cdp
->cap
.media
& MST_READ_DVDRAM
) {
1812 printf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1814 if (cdp
->cap
.media
& MST_READ_PACKET
)
1815 printf("%s packet", comma
? "," : "");
1818 device_printf(dev
, "Writes:");
1819 if (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1820 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
)) {
1822 if (cdp
->cap
.media
& MST_WRITE_CDR
) {
1823 printf(" CDR" ); comma
= 1;
1825 if (cdp
->cap
.media
& MST_WRITE_CDRW
) {
1826 printf("%s CDRW", comma
? "," : ""); comma
= 1;
1828 if (cdp
->cap
.media
& MST_WRITE_DVDR
) {
1829 printf("%s DVDR", comma
? "," : ""); comma
= 1;
1831 if (cdp
->cap
.media
& MST_WRITE_DVDRAM
) {
1832 printf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1834 if (cdp
->cap
.media
& MST_WRITE_TEST
) {
1835 printf("%s test write", comma
? "," : ""); comma
= 1;
1837 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1838 printf("%s burnproof", comma
? "," : "");
1841 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
) {
1842 device_printf(dev
, "Audio: ");
1843 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
)
1845 if (cdp
->cap
.max_vol_levels
)
1846 printf(", %d volume levels", cdp
->cap
.max_vol_levels
);
1849 device_printf(dev
, "Mechanism: ");
1850 switch (cdp
->cap
.mechanism
& MST_MECH_MASK
) {
1851 case MST_MECH_CADDY
:
1852 mechanism
= "caddy"; break;
1854 mechanism
= "tray"; break;
1855 case MST_MECH_POPUP
:
1856 mechanism
= "popup"; break;
1857 case MST_MECH_CHANGER
:
1858 mechanism
= "changer"; break;
1859 case MST_MECH_CARTRIDGE
:
1860 mechanism
= "cartridge"; break;
1862 mechanism
= 0; break;
1865 printf("%s%s", (cdp
->cap
.mechanism
& MST_EJECT
) ?
1866 "ejectable " : "", mechanism
);
1867 else if (cdp
->cap
.mechanism
& MST_EJECT
)
1868 printf("ejectable");
1870 if (cdp
->cap
.mechanism
& MST_LOCKABLE
)
1871 printf((cdp
->cap
.mechanism
& MST_LOCKED
) ? ", locked":", unlocked");
1872 if (cdp
->cap
.mechanism
& MST_PREVENT
)
1873 printf(", lock protected");
1876 if ((cdp
->cap
.mechanism
& MST_MECH_MASK
) != MST_MECH_CHANGER
) {
1877 device_printf(dev
, "Medium: ");
1878 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1880 printf("CD-ROM "); break;
1882 printf("CD-R "); break;
1884 printf("CD-RW "); break;
1886 printf("door open"); break;
1888 printf("no/blank disc"); break;
1890 printf("medium format error"); break;
1892 if ((cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
)<MST_TYPE_MASK_HIGH
){
1893 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_LOW
) {
1895 printf("120mm data disc"); break;
1897 printf("120mm audio disc"); break;
1899 printf("120mm data/audio disc"); break;
1901 printf("120mm photo disc"); break;
1903 printf("80mm data disc"); break;
1905 printf("80mm audio disc"); break;
1907 printf("80mm data/audio disc"); break;
1909 printf("80mm photo disc"); break;
1911 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1913 printf("unknown"); break;
1916 printf("blank"); break;
1920 printf("unknown (0x%x)", cdp
->cap
.medium_type
); break;
1927 device_printf(dev
, "%s ",
1928 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1929 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1930 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1931 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1932 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM" :
1934 printf("<%.40s/%.8s> at ata%d-%s %s\n",
1935 atadev
->param
.model
, atadev
->param
.revision
,
1936 device_get_unit(ch
->dev
),
1937 (atadev
->unit
== ATA_MASTER
) ? "master" : "slave",
1938 ata_mode2str(atadev
->mode
) );
1942 static device_method_t acd_methods
[] = {
1943 /* device interface */
1944 DEVMETHOD(device_probe
, acd_probe
),
1945 DEVMETHOD(device_attach
, acd_attach
),
1946 DEVMETHOD(device_detach
, acd_detach
),
1947 DEVMETHOD(device_shutdown
, acd_shutdown
),
1950 DEVMETHOD(ata_reinit
, acd_reinit
),
1955 static driver_t acd_driver
= {
1961 static devclass_t acd_devclass
;
1963 DRIVER_MODULE(acd
, ata
, acd_driver
, acd_devclass
, NULL
, NULL
);
1964 MODULE_VERSION(acd
, 1);
1965 MODULE_DEPEND(acd
, ata
, 1, 1, 1);