2 * Copyright (c) 1998 - 2008 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
);
109 /* local implementation */
111 g_io_deliver(struct bio
*bp
, int error
)
113 struct buf
*bbp
= bp
->bio_buf
;
115 bbp
->b_flags
|= B_ERROR
;
116 bbp
->b_error
= error
;
121 static MALLOC_DEFINE(M_ACD
, "acd_driver", "ATAPI CD driver buffers");
124 acd_probe(device_t dev
)
126 struct ata_device
*atadev
= device_get_softc(dev
);
128 if ((atadev
->param
.config
& ATA_PROTO_ATAPI
) &&
129 (atadev
->param
.config
& ATA_ATAPI_TYPE_MASK
) == ATA_ATAPI_TYPE_CDROM
)
136 acd_attach(device_t dev
)
138 struct ata_device
*atadev
= device_get_softc(dev
);
139 struct acd_softc
*cdp
;
142 /* XXX TGEN We're not in interrupt context, so we can M_WAITOK and remove
144 cdp
= kmalloc(sizeof(struct acd_softc
), M_ACD
, M_INTWAIT
| M_ZERO
);
145 cdp
->block_size
= 2048;
146 device_set_ivars(dev
, cdp
);
147 ATA_SETMODE(device_get_parent(dev
), dev
);
148 ata_controlcmd(dev
, ATA_DEVICE_RESET
, 0, 0, 0);
151 devstat_add_entry(&cdp
->stats
, "acd", device_get_unit(dev
), DEV_BSIZE
,
152 DEVSTAT_NO_ORDERED_TAGS
,
153 DEVSTAT_TYPE_CDROM
| DEVSTAT_TYPE_IF_IDE
,
154 DEVSTAT_PRIORITY_CD
);
156 cdev
= disk_create(device_get_unit(dev
), &cdp
->disk
, &acd_ops
);
157 disk_setdisktype(&cdp
->disk
, "optical");
159 cdev
= make_dev(&acd_ops
, dkmakeminor(device_get_unit(dev
), 0, 0),
160 UID_ROOT
, GID_OPERATOR
, 0644, "acd%d",
161 device_get_unit(dev
));
167 * Even though we do not have media information yet, we have to
168 * tell the disk management layer something or dscheck() will be
173 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
175 /* announce we are here */
181 acd_detach(device_t dev
)
183 struct acd_softc
*cdp
= device_get_ivars(dev
);
186 /* destroy devices from the system so we don't get any further requests */
187 for (track
= 1; track
< MAXTRK
; track
++) {
188 if (cdp
->track
[track
] == NULL
)
190 acd_destroy_tracknode(dev
, track
);
192 destroy_dev(cdp
->cdev
);
194 /* fail requests on the queue and any "in flight" for this device */
195 ata_fail_requests(dev
);
197 /* don't leave anything behind */
198 dev_ops_remove_minor(&acd_ops
, /*dkunitmask(), */dkmakeunit(device_get_unit(dev
)));
199 disk_invalidate(&cdp
->disk
);
200 disk_destroy(&cdp
->disk
);
201 devstat_remove_entry(&cdp
->stats
);
202 device_set_ivars(dev
, NULL
);
208 acd_shutdown(device_t dev
)
210 struct ata_device
*atadev
= device_get_softc(dev
);
212 if (atadev
->param
.support
.command2
& ATA_SUPPORT_FLUSHCACHE
)
213 ata_controlcmd(dev
, ATA_FLUSHCACHE
, 0, 0, 0);
217 acd_reinit(device_t dev
)
219 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
220 struct ata_device
*atadev
= device_get_softc(dev
);
222 if (((atadev
->unit
== ATA_MASTER
) && !(ch
->devices
& ATA_ATAPI_MASTER
)) ||
223 ((atadev
->unit
== ATA_SLAVE
) && !(ch
->devices
& ATA_ATAPI_SLAVE
))) {
226 ATA_SETMODE(device_get_parent(dev
), dev
);
231 acd_open(struct dev_open_args
*ap
)
233 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
234 /* XXX TGEN Sometimes, we're fed a cdev_t which we didn't create. It
235 doesn't have si_drv1 set, leading to evil NULL derefs. I can actually
236 recover our device_t otherwise, but really, this is a bug, so I'll bail
241 struct ata_device
*atadev
= device_get_softc(dev
);
242 struct acd_softc
*cdp
= device_get_ivars(dev
);
243 struct ata_request
*request
;
244 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
250 if (!device_is_attached(dev
))
252 if (!(request
= ata_alloc_request()))
255 /* wait if drive is not finished loading the medium */
257 bzero(request
, sizeof(struct ata_request
));
259 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
260 request
->flags
= ATA_R_ATAPI
;
261 request
->timeout
= ATA_DEFAULT_TIMEOUT
;
262 ata_queue_request(request
);
263 if (!request
->error
&&
264 (request
->u
.atapi
.sense
.key
== 2 ||
265 request
->u
.atapi
.sense
.key
== 7) &&
266 request
->u
.atapi
.sense
.asc
== 4 &&
267 request
->u
.atapi
.sense
.ascq
== 1)
268 tsleep(&timeout
, 0, "acdld", hz
/ 2);
272 ata_free_request(request
);
275 * DragonFly abstracts out the disk layer so our device may not have
276 * a vnode directly associated with it. count_dev() cannot be used.
278 if (atadev
->opencount
== 0) {
279 acd_prevent_allow(dev
, 1);
280 cdp
->flags
|= F_LOCKED
;
288 acd_close(struct dev_close_args
*ap
)
290 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
291 struct acd_softc
*cdp
= device_get_ivars(dev
);
292 struct ata_device
*atadev
= device_get_softc(dev
);
297 if (atadev
->opencount
== 1) {
298 acd_prevent_allow(dev
, 0);
299 cdp
->flags
&= ~F_LOCKED
;
301 if (atadev
->opencount
> 0)
307 acd_ioctl(struct dev_ioctl_args
*ap
)
309 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
310 struct ata_device
*atadev
= device_get_softc(dev
);
311 struct acd_softc
*cdp
= device_get_ivars(dev
);
312 int error
= 0, nocopyout
= 0;
317 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
325 acd_prevent_allow(dev
, 1);
326 cdp
->flags
|= F_LOCKED
;
334 error
= acd_pause_resume(dev
, 1);
338 error
= acd_pause_resume(dev
, 0);
342 error
= acd_start_stop(dev
, 1);
346 error
= acd_start_stop(dev
, 0);
350 error
= acd_prevent_allow(dev
, 0);
351 cdp
->flags
&= ~F_LOCKED
;
355 error
= acd_prevent_allow(dev
, 1);
356 cdp
->flags
|= F_LOCKED
;
360 error
= caps_priv_check(ap
->a_cred
, SYSCAP_RESTRICTEDROOT
);
363 error
= acd_test_ready(dev
);
367 if (atadev
->opencount
> 1) {
371 error
= acd_tray(dev
, 0);
375 if (atadev
->opencount
> 1)
377 error
= acd_tray(dev
, 1);
380 case CDIOREADTOCHEADER
:
381 if (!cdp
->toc
.hdr
.ending_track
) {
385 bcopy(&cdp
->toc
.hdr
, ap
->a_data
, sizeof(cdp
->toc
.hdr
));
388 case CDIOREADTOCENTRYS
:
390 struct ioc_read_toc_entry
*te
= (struct ioc_read_toc_entry
*)ap
->a_data
;
391 struct toc
*toc
= &cdp
->toc
;
392 int starting_track
= te
->starting_track
;
395 if (!toc
->hdr
.ending_track
) {
400 if (te
->data_len
< sizeof(toc
->tab
[0]) ||
401 (te
->data_len
% sizeof(toc
->tab
[0])) != 0 ||
402 (te
->address_format
!= CD_MSF_FORMAT
&&
403 te
->address_format
!= CD_LBA_FORMAT
)) {
409 starting_track
= toc
->hdr
.starting_track
;
410 else if (starting_track
== 170)
411 starting_track
= toc
->hdr
.ending_track
+ 1;
412 else if (starting_track
< toc
->hdr
.starting_track
||
413 starting_track
> toc
->hdr
.ending_track
+ 1) {
418 len
= ((toc
->hdr
.ending_track
+ 1 - starting_track
) + 1) *
420 if (te
->data_len
< len
)
422 if (len
> sizeof(toc
->tab
)) {
427 if (te
->address_format
== CD_MSF_FORMAT
) {
428 struct cd_toc_entry
*entry
;
430 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
431 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_INTWAIT
);
432 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
433 entry
= toc
->tab
+ (toc
->hdr
.ending_track
+ 1 -
434 toc
->hdr
.starting_track
) + 1;
435 while (--entry
>= toc
->tab
) {
436 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
437 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
438 entry
->addr_type
= CD_MSF_FORMAT
;
441 error
= copyout(toc
->tab
+ starting_track
- toc
->hdr
.starting_track
,
443 if (te
->address_format
== CD_MSF_FORMAT
)
448 case CDIOREADTOCENTRY
:
450 struct ioc_read_toc_single_entry
*te
=
451 (struct ioc_read_toc_single_entry
*)ap
->a_data
;
452 struct toc
*toc
= &cdp
->toc
;
453 u_char track
= te
->track
;
455 if (!toc
->hdr
.ending_track
) {
460 if (te
->address_format
!= CD_MSF_FORMAT
&&
461 te
->address_format
!= CD_LBA_FORMAT
) {
467 track
= toc
->hdr
.starting_track
;
468 else if (track
== 170)
469 track
= toc
->hdr
.ending_track
+ 1;
470 else if (track
< toc
->hdr
.starting_track
||
471 track
> toc
->hdr
.ending_track
+ 1) {
476 if (te
->address_format
== CD_MSF_FORMAT
) {
477 struct cd_toc_entry
*entry
;
479 /* XXX TGEN Use M_WAITOK, not in intr ctx. */
480 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_INTWAIT
);
481 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
482 entry
= toc
->tab
+ (track
- toc
->hdr
.starting_track
);
483 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
484 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
486 bcopy(toc
->tab
+ track
- toc
->hdr
.starting_track
,
487 &te
->entry
, sizeof(struct cd_toc_entry
));
488 if (te
->address_format
== CD_MSF_FORMAT
)
493 case CDIOCREADSUBCHANNEL
:
495 struct ioc_read_subchannel
*args
=
496 (struct ioc_read_subchannel
*)ap
->a_data
;
498 int8_t ccb
[16] = { ATAPI_READ_SUBCHANNEL
, 0, 0x40, 1, 0, 0, 0,
499 sizeof(cdp
->subchan
)>>8, sizeof(cdp
->subchan
),
500 0, 0, 0, 0, 0, 0, 0 };
502 if (args
->data_len
> sizeof(struct cd_sub_channel_info
) ||
503 args
->data_len
< sizeof(struct cd_sub_channel_header
)) {
508 format
= args
->data_format
;
509 if ((format
!= CD_CURRENT_POSITION
) &&
510 (format
!= CD_MEDIA_CATALOG
) && (format
!= CD_TRACK_INFO
)) {
515 ccb
[1] = args
->address_format
& CD_MSF_FORMAT
;
517 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
518 sizeof(cdp
->subchan
), ATA_R_READ
, 10)))
521 if ((format
== CD_MEDIA_CATALOG
) || (format
== CD_TRACK_INFO
)) {
522 if (cdp
->subchan
.header
.audio_status
== 0x11) {
528 if (format
== CD_TRACK_INFO
)
529 ccb
[6] = args
->track
;
531 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->subchan
,
532 sizeof(cdp
->subchan
),ATA_R_READ
,10))){
536 if (nocopyout
== 0) {
537 error
= copyout(&cdp
->subchan
, args
->data
, args
->data_len
);
540 bcopy(&cdp
->subchan
, args
->data
, args
->data_len
);
547 struct ioc_play_msf
*args
= (struct ioc_play_msf
*)ap
->a_data
;
551 msf2lba(args
->start_m
, args
->start_s
, args
->start_f
),
552 msf2lba(args
->end_m
, args
->end_s
, args
->end_f
));
556 case CDIOCPLAYBLOCKS
:
558 struct ioc_play_blocks
*args
= (struct ioc_play_blocks
*)ap
->a_data
;
560 error
= acd_play(dev
, args
->blk
, args
->blk
+ args
->len
);
564 case CDIOCPLAYTRACKS
:
566 struct ioc_play_track
*args
= (struct ioc_play_track
*)ap
->a_data
;
569 if (!cdp
->toc
.hdr
.ending_track
) {
573 if (args
->end_track
< cdp
->toc
.hdr
.ending_track
+ 1)
575 if (args
->end_track
> cdp
->toc
.hdr
.ending_track
+ 1)
576 args
->end_track
= cdp
->toc
.hdr
.ending_track
+ 1;
577 t1
= args
->start_track
- cdp
->toc
.hdr
.starting_track
;
578 t2
= args
->end_track
- cdp
->toc
.hdr
.starting_track
;
579 if (t1
< 0 || t2
< 0 ||
580 t1
> (cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
)) {
584 error
= acd_play(dev
, ntohl(cdp
->toc
.tab
[t1
].addr
.lba
),
585 ntohl(cdp
->toc
.tab
[t2
].addr
.lba
));
591 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
593 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
594 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
597 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
601 arg
->vol
[0] = cdp
->au
.port
[0].volume
;
602 arg
->vol
[1] = cdp
->au
.port
[1].volume
;
603 arg
->vol
[2] = cdp
->au
.port
[2].volume
;
604 arg
->vol
[3] = cdp
->au
.port
[3].volume
;
610 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
612 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
,
613 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
615 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
619 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE_MASK
,
620 (caddr_t
)&cdp
->aumask
,
621 sizeof(cdp
->aumask
))))
623 cdp
->au
.data_length
= 0;
624 cdp
->au
.port
[0].channels
= CHANNEL_0
;
625 cdp
->au
.port
[1].channels
= CHANNEL_1
;
626 cdp
->au
.port
[0].volume
= arg
->vol
[0] & cdp
->aumask
.port
[0].volume
;
627 cdp
->au
.port
[1].volume
= arg
->vol
[1] & cdp
->aumask
.port
[1].volume
;
628 cdp
->au
.port
[2].volume
= arg
->vol
[2] & cdp
->aumask
.port
[2].volume
;
629 cdp
->au
.port
[3].volume
= arg
->vol
[3] & cdp
->aumask
.port
[3].volume
;
630 error
= acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
636 struct ioc_patch
*arg
= (struct ioc_patch
*)ap
->a_data
;
638 error
= acd_setchan(dev
, arg
->patch
[0], arg
->patch
[1],
639 arg
->patch
[2], arg
->patch
[3]);
644 error
= acd_setchan(dev
, CHANNEL_0
|CHANNEL_1
, CHANNEL_0
|CHANNEL_1
, 0,0);
648 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_1
, 0, 0);
652 error
= acd_setchan(dev
, 0, 0, 0, 0);
656 error
= acd_setchan(dev
, CHANNEL_0
, CHANNEL_0
, 0, 0);
660 error
= acd_setchan(dev
, CHANNEL_1
, CHANNEL_1
, 0, 0);
664 error
= acd_blank(dev
, (*(int *)ap
->a_data
));
667 case CDRIOCNEXTWRITEABLEADDR
:
669 struct acd_track_info track_info
;
671 if ((error
= acd_read_track_info(dev
, 0xff, &track_info
)))
674 if (!track_info
.nwa_valid
) {
678 *(int*)ap
->a_data
= track_info
.next_writeable_addr
;
682 case CDRIOCINITWRITER
:
683 error
= acd_init_writer(dev
, (*(int *)ap
->a_data
));
686 case CDRIOCINITTRACK
:
687 error
= acd_init_track(dev
, (struct cdr_track
*)ap
->a_data
);
691 error
= acd_flush(dev
);
695 error
= acd_fixate(dev
, (*(int *)ap
->a_data
));
698 case CDRIOCREADSPEED
:
700 int speed
= *(int *)ap
->a_data
;
702 /* Preserve old behavior: units in multiples of CDROM speed */
705 error
= acd_set_speed(dev
, speed
, CDR_MAX_SPEED
);
709 case CDRIOCWRITESPEED
:
711 int speed
= *(int *)ap
->a_data
;
715 error
= acd_set_speed(dev
, CDR_MAX_SPEED
, speed
);
719 case CDRIOCGETBLOCKSIZE
:
720 *(int *)ap
->a_data
= cdp
->block_size
;
723 case CDRIOCSETBLOCKSIZE
:
724 cdp
->block_size
= *(int *)ap
->a_data
;
728 case CDRIOCGETPROGRESS
:
729 error
= acd_get_progress(dev
, (int *)ap
->a_data
);
733 error
= acd_send_cue(dev
, (struct cdr_cuesheet
*)ap
->a_data
);
736 #ifdef ACD_CDR_FORMAT
737 case CDRIOCREADFORMATCAPS
:
738 error
= acd_read_format_caps(dev
,
739 (struct cdr_format_capacities
*)ap
->a_data
);
743 error
= acd_format(dev
, (struct cdr_format_params
*)ap
->a_data
);
745 #endif /* ACD_CDR_FORMAT */
747 case DVDIOCREPORTKEY
:
748 if (cdp
->cap
.media
& MST_READ_DVDROM
)
749 error
= acd_report_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
755 if (cdp
->cap
.media
& MST_READ_DVDROM
)
756 error
= acd_send_key(dev
, (struct dvd_authinfo
*)ap
->a_data
);
761 case DVDIOCREADSTRUCTURE
:
762 if (cdp
->cap
.media
& MST_READ_DVDROM
)
763 error
= acd_read_structure(dev
, (struct dvd_struct
*)ap
->a_data
);
769 error
= ata_device_ioctl(dev
, ap
->a_cmd
, ap
->a_data
);
775 acd_strategy(struct dev_strategy_args
*ap
)
777 device_t dev
= ap
->a_head
.a_dev
->si_drv1
;
778 struct bio
*bp
= ap
->a_bio
;
779 struct buf
*bbp
= bp
->bio_buf
;
780 /* struct ata_device *atadev = device_get_softc(dev);*/
781 struct acd_softc
*cdp
= device_get_ivars(dev
);
782 cdev_t cdev
= cdp
->cdev
;
784 if (bbp
->b_cmd
!= BUF_CMD_READ
&& bbp
->b_cmd
!= BUF_CMD_WRITE
) {
785 g_io_deliver(bp
, EOPNOTSUPP
);
789 if (bbp
->b_cmd
== BUF_CMD_READ
&& cdp
->disk_size
== -1) {
790 g_io_deliver(bp
, EIO
);
794 KASSERT(bbp
->b_bcount
!= 0, ("acd_strategy: 0-length I/O"));
796 bp
->bio_driver_info
= cdev
;
797 bbp
->b_resid
= bbp
->b_bcount
;
803 /* XXX TGEN Collapse this with acd_strategy()? */
805 acd_start(device_t dev
, struct bio
*bp
)
807 struct buf
*bbp
= bp
->bio_buf
;
808 struct ata_device
*atadev
= device_get_softc(dev
);
809 struct acd_softc
*cdp
= device_get_ivars(dev
);
810 struct ata_request
*request
;
811 u_int32_t lba
, lastlba
, count
;
813 int track
, blocksize
;
815 /* reject all queued entries if media changed */
816 if (atadev
->flags
& ATA_D_MEDIA_CHANGED
) {
817 g_io_deliver(bp
, EIO
);
821 bzero(ccb
, sizeof(ccb
));
824 * Special track access is via bio_offset (128-255), and direct
825 * raw access via 128, else normal accesses.
827 track
= (bp
->bio_offset
>> 56) & 127;
830 if (track
> MAXTRK
) {
831 g_io_deliver(bp
, EIO
);
834 blocksize
= (cdp
->toc
.tab
[track
- 1].control
& 4) ? 2048 : 2352;
835 lastlba
= ntohl(cdp
->toc
.tab
[track
].addr
.lba
);
836 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
837 lba
+= ntohl(cdp
->toc
.tab
[track
- 1].addr
.lba
);
840 blocksize
= cdp
->block_size
;
841 lastlba
= cdp
->disk_size
;
842 lba
= (bp
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
845 count
= bbp
->b_bcount
/ blocksize
;
846 KASSERT(count
!= 0, ("acd_strategy: 0-length I/O %d bytes vs %d blksize",
847 bbp
->b_bcount
, blocksize
));
849 if (bbp
->b_cmd
== BUF_CMD_READ
) {
850 /* if transfer goes beyond range adjust it to be within limits */
851 if (lba
+ count
> lastlba
) {
852 /* if we are entirely beyond EOM return EOF */
853 if (lastlba
<= lba
) {
854 bbp
->b_resid
= bbp
->b_bcount
;
858 count
= lastlba
- lba
;
862 ccb
[0] = ATAPI_READ_BIG
;
866 ccb
[0] = ATAPI_READ_CD
;
871 ccb
[0] = ATAPI_READ_CD
;
876 ccb
[0] = ATAPI_WRITE_BIG
;
887 if (!(request
= ata_alloc_request())) {
888 g_io_deliver(bp
, ENOMEM
);
893 bcopy(ccb
, request
->u
.atapi
.ccb
,
894 (atadev
->param
.config
& ATA_PROTO_MASK
) ==
895 ATA_PROTO_ATAPI_12
? 16 : 12);
896 request
->data
= bbp
->b_data
;
897 request
->bytecount
= count
* blocksize
;
898 request
->transfersize
= min(request
->bytecount
, 65534);
899 request
->timeout
= (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30;
900 request
->retries
= 2;
901 request
->callback
= acd_done
;
902 request
->flags
= ATA_R_ATAPI
;
903 if (atadev
->mode
>= ATA_DMA
)
904 request
->flags
|= ATA_R_DMA
;
905 switch (bbp
->b_cmd
) {
907 request
->flags
|= ATA_R_READ
;
910 request
->flags
|= ATA_R_WRITE
;
913 device_printf(dev
, "unknown BUF operation\n");
914 ata_free_request(request
);
915 g_io_deliver(bp
, EIO
);
918 devstat_start_transaction(&cdp
->stats
);
919 ata_queue_request(request
);
923 acd_done(struct ata_request
*request
)
925 struct acd_softc
*cdp
= device_get_ivars(request
->dev
);
926 struct bio
*bp
= request
->bio
;
927 struct buf
*bbp
= bp
->bio_buf
;
929 /* finish up transfer */
930 if ((bbp
->b_error
= request
->result
))
931 bbp
->b_flags
|= B_ERROR
;
932 bbp
->b_resid
= bbp
->b_bcount
- request
->donecount
;
933 devstat_end_transaction_buf(&cdp
->stats
, bbp
);
935 ata_free_request(request
);
939 acd_set_ioparm(device_t dev
)
941 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
942 struct ata_device
*atadev
= device_get_softc(dev
);
943 struct acd_softc
*cdp
= device_get_ivars(dev
);
944 struct disk_info info
;
947 cdp
->iomax
= min(ch
->dma
->max_iosize
, 65534);
949 cdp
->iomax
= min(MAXPHYS
, 65534);
951 cdp
->cdev
->si_iosize_max
= rounddown(cdp
->iomax
, cdp
->block_size
);
952 cdp
->cdev
->si_bsize_phys
= cdp
->block_size
;
953 bzero(&info
, sizeof(info
));
954 info
.d_media_blksize
= cdp
->block_size
;
955 info
.d_media_blocks
= (cdp
->disk_size
== -1) ? 0 : cdp
->disk_size
;
956 info
.d_secpertrack
= 100;
958 info
.d_ncylinders
= cdp
->disk_size
/ info
.d_secpertrack
/ info
.d_nheads
+ 1;
959 info
.d_secpercyl
= info
.d_secpertrack
* info
.d_nheads
;
960 info
.d_dsflags
= DSO_ONESLICE
| DSO_COMPATLABEL
| DSO_COMPATPARTA
|
962 info
.d_serialno
= atadev
->param
.serial
;
963 disk_setdiskinfo(&cdp
->disk
, &info
);
968 lba2msf(u_int32_t lba
, u_int8_t
*m
, u_int8_t
*s
, u_int8_t
*f
)
972 *m
= lba
/ (60 * 75);
979 msf2lba(u_int8_t m
, u_int8_t s
, u_int8_t f
)
981 return (m
* 60 + s
) * 75 + f
- 150;
985 acd_read_toc(device_t dev
)
987 struct ata_device
*atadev
= device_get_softc(dev
);
988 struct acd_softc
*cdp
= device_get_ivars(dev
);
989 struct acd_tracknode
*tracknode
;
992 int track
, ntracks
, len
;
994 atadev
->flags
&= ~ATA_D_MEDIA_CHANGED
;
995 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
997 if (acd_test_ready(dev
))
1000 bzero(ccb
, sizeof(ccb
));
1001 len
= sizeof(struct ioc_toc_header
) + sizeof(struct cd_toc_entry
);
1002 ccb
[0] = ATAPI_READ_TOC
;
1005 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1006 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1007 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1010 ntracks
= cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1;
1011 if (ntracks
<= 0 || ntracks
> MAXTRK
) {
1012 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1016 len
= sizeof(struct ioc_toc_header
)+(ntracks
+1)*sizeof(struct cd_toc_entry
);
1017 bzero(ccb
, sizeof(ccb
));
1018 ccb
[0] = ATAPI_READ_TOC
;
1021 if (ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1022 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1023 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1026 cdp
->toc
.hdr
.len
= ntohs(cdp
->toc
.hdr
.len
);
1028 cdp
->block_size
= (cdp
->toc
.tab
[0].control
& 4) ? 2048 : 2352;
1029 bzero(ccb
, sizeof(ccb
));
1030 ccb
[0] = ATAPI_READ_CAPACITY
;
1031 if (ata_atapicmd(dev
, ccb
, (caddr_t
)sizes
, sizeof(sizes
),
1032 ATA_R_READ
| ATA_R_QUIET
, 30)) {
1033 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1036 cdp
->disk_size
= ntohl(sizes
[0]) + 1;
1037 acd_set_ioparm(dev
);
1039 for (track
= 1; track
<= ntracks
; track
++) {
1040 if (cdp
->track
[track
] != NULL
)
1043 tracknode
= acd_make_tracknode(dev
, track
);
1046 cdp
->track
[track
] = tracknode
;
1048 for (; track
< MAXTRK
; track
++) {
1049 if (cdp
->track
[track
] == NULL
)
1051 acd_destroy_tracknode(dev
, track
);
1052 cdp
->track
[track
] = NULL
;
1056 if (cdp
->disk_size
&& cdp
->toc
.hdr
.ending_track
) {
1057 device_printf(dev
, "(%d sectors (%d bytes)), %d tracks ",
1058 cdp
->disk_size
, cdp
->block_size
,
1059 cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
+1);
1060 if (cdp
->toc
.tab
[0].control
& 4)
1061 kprintf("%dMB\n", cdp
->disk_size
* cdp
->block_size
/ 1048576);
1063 kprintf("%d:%d audio\n",
1064 cdp
->disk_size
/ 75 / 60, cdp
->disk_size
/ 75 % 60);
1070 * Destroys the device node of a numbered track and frees the related struct
1071 * acd_tracknode. It could be done just in acd_read_toc(), but it's nice to
1072 * have a complementary function to acd_make_tracknode().
1075 acd_destroy_tracknode(device_t dev
, int track
)
1077 struct acd_softc
*cdp
= device_get_ivars(dev
);
1078 struct acd_tracknode
*tracknode
;
1080 tracknode
= cdp
->track
[track
];
1081 destroy_dev(tracknode
->cdev
);
1082 kfree(tracknode
, M_ACD
);
1086 acd_play(device_t dev
, int start
, int end
)
1090 bzero(ccb
, sizeof(ccb
));
1091 ccb
[0] = ATAPI_PLAY_MSF
;
1092 lba2msf(start
, &ccb
[3], &ccb
[4], &ccb
[5]);
1093 lba2msf(end
, &ccb
[6], &ccb
[7], &ccb
[8]);
1094 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 10);
1098 acd_setchan(device_t dev
, u_int8_t c0
, u_int8_t c1
, u_int8_t c2
, u_int8_t c3
)
1100 struct acd_softc
*cdp
= device_get_ivars(dev
);
1103 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_AUDIO_PAGE
, (caddr_t
)&cdp
->au
,
1106 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
)
1108 cdp
->au
.data_length
= 0;
1109 cdp
->au
.port
[0].channels
= c0
;
1110 cdp
->au
.port
[1].channels
= c1
;
1111 cdp
->au
.port
[2].channels
= c2
;
1112 cdp
->au
.port
[3].channels
= c3
;
1113 return acd_mode_select(dev
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
1117 acd_init_writer(device_t dev
, int test_write
)
1121 bzero(ccb
, sizeof(ccb
));
1122 ccb
[0] = ATAPI_REZERO
;
1123 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1124 ccb
[0] = ATAPI_SEND_OPC_INFO
;
1126 ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 30);
1131 acd_fixate(device_t dev
, int multisession
)
1133 struct acd_softc
*cdp
= device_get_ivars(dev
);
1134 int8_t ccb
[16] = { ATAPI_CLOSE_TRACK
, 0x01, 0x02, 0, 0, 0, 0, 0,
1135 0, 0, 0, 0, 0, 0, 0, 0 };
1136 int timeout
= 5*60*2;
1138 struct write_param param
;
1140 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1141 (caddr_t
)¶m
, sizeof(param
))))
1144 param
.data_length
= 0;
1146 param
.session_type
= CDR_SESS_MULTI
;
1148 param
.session_type
= CDR_SESS_NONE
;
1150 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1153 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1157 /* some drives just return ready, wait for the expected fixate time */
1158 if ((error
= acd_test_ready(dev
)) != EBUSY
) {
1159 timeout
= timeout
/ (cdp
->cap
.cur_write_speed
/ 177);
1160 tsleep(&error
, 0, "acdfix", timeout
* hz
/ 2);
1161 return acd_test_ready(dev
);
1164 while (timeout
-- > 0) {
1165 if ((error
= acd_get_progress(dev
, &dummy
)))
1167 if ((error
= acd_test_ready(dev
)) != EBUSY
)
1169 tsleep(&error
, 0, "acdcld", hz
/ 2);
1175 acd_init_track(device_t dev
, struct cdr_track
*track
)
1177 struct acd_softc
*cdp
= device_get_ivars(dev
);
1178 struct write_param param
;
1181 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1182 (caddr_t
)¶m
, sizeof(param
))))
1185 param
.data_length
= 0;
1186 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1187 param
.page_length
= 0x32;
1188 param
.test_write
= track
->test_write
? 1 : 0;
1189 param
.write_type
= CDR_WTYPE_TRACK
;
1190 param
.session_type
= CDR_SESS_NONE
;
1192 param
.packet_size
= 0;
1194 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1195 param
.burnproof
= 1;
1197 switch (track
->datablock_type
) {
1201 param
.track_mode
= CDR_TMODE_AUDIO_PREEMP
;
1203 param
.track_mode
= CDR_TMODE_AUDIO
;
1204 cdp
->block_size
= 2352;
1205 param
.datablock_type
= CDR_DB_RAW
;
1206 param
.session_format
= CDR_SESS_CDROM
;
1209 case CDR_DB_ROM_MODE1
:
1210 cdp
->block_size
= 2048;
1211 param
.track_mode
= CDR_TMODE_DATA
;
1212 param
.datablock_type
= CDR_DB_ROM_MODE1
;
1213 param
.session_format
= CDR_SESS_CDROM
;
1216 case CDR_DB_ROM_MODE2
:
1217 cdp
->block_size
= 2336;
1218 param
.track_mode
= CDR_TMODE_DATA
;
1219 param
.datablock_type
= CDR_DB_ROM_MODE2
;
1220 param
.session_format
= CDR_SESS_CDROM
;
1223 case CDR_DB_XA_MODE1
:
1224 cdp
->block_size
= 2048;
1225 param
.track_mode
= CDR_TMODE_DATA
;
1226 param
.datablock_type
= CDR_DB_XA_MODE1
;
1227 param
.session_format
= CDR_SESS_CDROM_XA
;
1230 case CDR_DB_XA_MODE2_F1
:
1231 cdp
->block_size
= 2056;
1232 param
.track_mode
= CDR_TMODE_DATA
;
1233 param
.datablock_type
= CDR_DB_XA_MODE2_F1
;
1234 param
.session_format
= CDR_SESS_CDROM_XA
;
1237 case CDR_DB_XA_MODE2_F2
:
1238 cdp
->block_size
= 2324;
1239 param
.track_mode
= CDR_TMODE_DATA
;
1240 param
.datablock_type
= CDR_DB_XA_MODE2_F2
;
1241 param
.session_format
= CDR_SESS_CDROM_XA
;
1244 case CDR_DB_XA_MODE2_MIX
:
1245 cdp
->block_size
= 2332;
1246 param
.track_mode
= CDR_TMODE_DATA
;
1247 param
.datablock_type
= CDR_DB_XA_MODE2_MIX
;
1248 param
.session_format
= CDR_SESS_CDROM_XA
;
1251 acd_set_ioparm(dev
);
1252 return acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10);
1256 acd_flush(device_t dev
)
1258 int8_t ccb
[16] = { ATAPI_SYNCHRONIZE_CACHE
, 0, 0, 0, 0, 0, 0, 0,
1259 0, 0, 0, 0, 0, 0, 0, 0 };
1261 return ata_atapicmd(dev
, ccb
, NULL
, 0, ATA_R_QUIET
, 60);
1265 acd_read_track_info(device_t dev
, int32_t lba
, struct acd_track_info
*info
)
1267 int8_t ccb
[16] = { ATAPI_READ_TRACK_INFO
, 1,
1268 lba
>>24, lba
>>16, lba
>>8, lba
, 0,
1269 sizeof(*info
)>>8, sizeof(*info
),
1270 0, 0, 0, 0, 0, 0, 0 };
1273 if ((error
= ata_atapicmd(dev
, ccb
, (caddr_t
)info
, sizeof(*info
),
1276 info
->track_start_addr
= ntohl(info
->track_start_addr
);
1277 info
->next_writeable_addr
= ntohl(info
->next_writeable_addr
);
1278 info
->free_blocks
= ntohl(info
->free_blocks
);
1279 info
->fixed_packet_size
= ntohl(info
->fixed_packet_size
);
1280 info
->track_length
= ntohl(info
->track_length
);
1285 acd_get_progress(device_t dev
, int *finished
)
1287 int8_t ccb
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
1288 0, 0, 0, 0, 0, 0, 0, 0 };
1289 struct ata_request
*request
;
1292 if (!(request
= ata_alloc_request()))
1296 bcopy(ccb
, request
->u
.atapi
.ccb
, 16);
1297 request
->data
= dummy
;
1298 request
->bytecount
= sizeof(dummy
);
1299 request
->transfersize
= min(request
->bytecount
, 65534);
1300 request
->flags
= ATA_R_ATAPI
| ATA_R_READ
;
1301 request
->timeout
= 30;
1302 ata_queue_request(request
);
1303 if (!request
->error
&&
1304 request
->u
.atapi
.sense
.specific
& ATA_SENSE_SPEC_VALID
)
1305 *finished
= ((request
->u
.atapi
.sense
.specific2
|
1306 (request
->u
.atapi
.sense
.specific1
<< 8)) * 100) / 65535;
1309 ata_free_request(request
);
1314 acd_send_cue(device_t dev
, struct cdr_cuesheet
*cuesheet
)
1316 struct acd_softc
*cdp
= device_get_ivars(dev
);
1317 struct write_param param
;
1318 int8_t ccb
[16] = { ATAPI_SEND_CUE_SHEET
, 0, 0, 0, 0, 0,
1319 cuesheet
->len
>>16, cuesheet
->len
>>8, cuesheet
->len
,
1320 0, 0, 0, 0, 0, 0, 0 };
1324 if ((error
= acd_mode_sense(dev
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1325 (caddr_t
)¶m
, sizeof(param
))))
1328 param
.data_length
= 0;
1329 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1330 param
.page_length
= 0x32;
1331 param
.test_write
= cuesheet
->test_write
? 1 : 0;
1332 param
.write_type
= CDR_WTYPE_SESSION
;
1333 param
.session_type
= cuesheet
->session_type
;
1335 param
.packet_size
= 0;
1336 param
.track_mode
= CDR_TMODE_AUDIO
;
1337 param
.datablock_type
= CDR_DB_RAW
;
1338 param
.session_format
= cuesheet
->session_format
;
1339 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1340 param
.burnproof
= 1;
1342 if ((error
= acd_mode_select(dev
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1345 if (!(buffer
= kmalloc(cuesheet
->len
, M_ACD
, M_WAITOK
| M_NULLOK
)))
1348 if (!(error
= copyin(cuesheet
->entries
, buffer
, cuesheet
->len
)))
1349 error
= ata_atapicmd(dev
, ccb
, buffer
, cuesheet
->len
, 0, 30);
1350 kfree(buffer
, M_ACD
);
1355 acd_report_key(device_t dev
, struct dvd_authinfo
*ai
)
1357 struct dvd_miscauth
*d
= NULL
;
1363 switch (ai
->format
) {
1364 case DVD_REPORT_AGID
:
1365 case DVD_REPORT_ASF
:
1366 case DVD_REPORT_RPC
:
1369 case DVD_REPORT_KEY1
:
1372 case DVD_REPORT_TITLE_KEY
:
1376 case DVD_REPORT_CHALLENGE
:
1379 case DVD_INVALIDATE_AGID
:
1386 bzero(ccb
, sizeof(ccb
));
1387 ccb
[0] = ATAPI_REPORT_KEY
;
1388 ccb
[2] = (lba
>> 24) & 0xff;
1389 ccb
[3] = (lba
>> 16) & 0xff;
1390 ccb
[4] = (lba
>> 8) & 0xff;
1391 ccb
[5] = lba
& 0xff;
1392 ccb
[8] = (length
>> 8) & 0xff;
1393 ccb
[9] = length
& 0xff;
1394 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1397 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1398 d
->length
= htons(length
- 2);
1401 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
,
1402 ai
->format
== DVD_INVALIDATE_AGID
? 0 : ATA_R_READ
,10);
1409 switch (ai
->format
) {
1410 case DVD_REPORT_AGID
:
1411 ai
->agid
= d
->data
[3] >> 6;
1414 case DVD_REPORT_CHALLENGE
:
1415 bcopy(&d
->data
[0], &ai
->keychal
[0], 10);
1418 case DVD_REPORT_KEY1
:
1419 bcopy(&d
->data
[0], &ai
->keychal
[0], 5);
1422 case DVD_REPORT_TITLE_KEY
:
1423 ai
->cpm
= (d
->data
[0] >> 7);
1424 ai
->cp_sec
= (d
->data
[0] >> 6) & 0x1;
1425 ai
->cgms
= (d
->data
[0] >> 4) & 0x3;
1426 bcopy(&d
->data
[1], &ai
->keychal
[0], 5);
1429 case DVD_REPORT_ASF
:
1430 ai
->asf
= d
->data
[3] & 1;
1433 case DVD_REPORT_RPC
:
1434 ai
->reg_type
= (d
->data
[0] >> 6);
1435 ai
->vend_rsts
= (d
->data
[0] >> 3) & 0x7;
1436 ai
->user_rsts
= d
->data
[0] & 0x7;
1437 ai
->region
= d
->data
[1];
1438 ai
->rpc_scheme
= d
->data
[2];
1441 case DVD_INVALIDATE_AGID
:
1453 acd_send_key(device_t dev
, struct dvd_authinfo
*ai
)
1455 struct dvd_miscauth
*d
;
1460 switch (ai
->format
) {
1461 case DVD_SEND_CHALLENGE
:
1463 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1464 bcopy(ai
->keychal
, &d
->data
[0], 10);
1469 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1470 bcopy(&ai
->keychal
[0], &d
->data
[0], 5);
1475 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1476 d
->data
[0] = ai
->region
;
1483 bzero(ccb
, sizeof(ccb
));
1484 ccb
[0] = ATAPI_SEND_KEY
;
1485 ccb
[8] = (length
>> 8) & 0xff;
1486 ccb
[9] = length
& 0xff;
1487 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1488 d
->length
= htons(length
- 2);
1489 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, 0, 10);
1495 acd_read_structure(device_t dev
, struct dvd_struct
*s
)
1497 struct dvd_miscauth
*d
;
1503 case DVD_STRUCT_PHYSICAL
:
1507 case DVD_STRUCT_COPYRIGHT
:
1511 case DVD_STRUCT_DISCKEY
:
1515 case DVD_STRUCT_BCA
:
1519 case DVD_STRUCT_MANUFACT
:
1523 case DVD_STRUCT_DDS
:
1524 case DVD_STRUCT_PRERECORDED
:
1525 case DVD_STRUCT_UNIQUEID
:
1526 case DVD_STRUCT_LIST
:
1527 case DVD_STRUCT_CMI
:
1528 case DVD_STRUCT_RMD_LAST
:
1529 case DVD_STRUCT_RMD_RMA
:
1530 case DVD_STRUCT_DCB
:
1537 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1538 d
->length
= htons(length
- 2);
1540 bzero(ccb
, sizeof(ccb
));
1541 ccb
[0] = ATAPI_READ_STRUCTURE
;
1542 ccb
[6] = s
->layer_num
;
1544 ccb
[8] = (length
>> 8) & 0xff;
1545 ccb
[9] = length
& 0xff;
1546 ccb
[10] = s
->agid
<< 6;
1547 error
= ata_atapicmd(dev
, ccb
, (caddr_t
)d
, length
, ATA_R_READ
, 30);
1553 switch (s
->format
) {
1554 case DVD_STRUCT_PHYSICAL
: {
1555 struct dvd_layer
*layer
= (struct dvd_layer
*)&s
->data
[0];
1557 layer
->book_type
= d
->data
[0] >> 4;
1558 layer
->book_version
= d
->data
[0] & 0xf;
1559 layer
->disc_size
= d
->data
[1] >> 4;
1560 layer
->max_rate
= d
->data
[1] & 0xf;
1561 layer
->nlayers
= (d
->data
[2] >> 5) & 3;
1562 layer
->track_path
= (d
->data
[2] >> 4) & 1;
1563 layer
->layer_type
= d
->data
[2] & 0xf;
1564 layer
->linear_density
= d
->data
[3] >> 4;
1565 layer
->track_density
= d
->data
[3] & 0xf;
1566 layer
->start_sector
= d
->data
[5] << 16 | d
->data
[6] << 8 | d
->data
[7];
1567 layer
->end_sector
= d
->data
[9] << 16 | d
->data
[10] << 8 | d
->data
[11];
1568 layer
->end_sector_l0
= d
->data
[13] << 16 | d
->data
[14] << 8|d
->data
[15];
1569 layer
->bca
= d
->data
[16] >> 7;
1573 case DVD_STRUCT_COPYRIGHT
:
1574 s
->cpst
= d
->data
[0];
1575 s
->rmi
= d
->data
[1];
1578 case DVD_STRUCT_DISCKEY
:
1579 bcopy(&d
->data
[0], &s
->data
[0], 2048);
1582 case DVD_STRUCT_BCA
:
1583 s
->length
= ntohs(d
->length
);
1584 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1587 case DVD_STRUCT_MANUFACT
:
1588 s
->length
= ntohs(d
->length
);
1589 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1600 acd_tray(device_t dev
, int close
)
1602 struct ata_device
*atadev
= device_get_softc(dev
);
1603 struct acd_softc
*cdp
= device_get_ivars(dev
);
1606 if (cdp
->cap
.mechanism
& MST_EJECT
) {
1608 if (!(error
= acd_start_stop(dev
, 3))) {
1610 acd_prevent_allow(dev
, 1);
1611 cdp
->flags
|= F_LOCKED
;
1615 acd_start_stop(dev
, 0);
1616 acd_prevent_allow(dev
, 0);
1617 cdp
->flags
&= ~F_LOCKED
;
1618 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1619 error
= acd_start_stop(dev
, 2);
1626 acd_blank(device_t dev
, int blanktype
)
1628 struct ata_device
*atadev
= device_get_softc(dev
);
1629 int8_t ccb
[16] = { ATAPI_BLANK
, 0x10 | (blanktype
& 0x7), 0, 0, 0, 0, 0, 0,
1630 0, 0, 0, 0, 0, 0, 0, 0 };
1632 atadev
->flags
|= ATA_D_MEDIA_CHANGED
;
1633 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1637 acd_prevent_allow(device_t dev
, int lock
)
1639 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
1640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1642 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1646 acd_start_stop(device_t dev
, int start
)
1648 int8_t ccb
[16] = { ATAPI_START_STOP
, 0, 0, 0, start
,
1649 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1651 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1655 acd_pause_resume(device_t dev
, int pause
)
1657 int8_t ccb
[16] = { ATAPI_PAUSE
, 0, 0, 0, 0, 0, 0, 0, pause
,
1658 0, 0, 0, 0, 0, 0, 0 };
1660 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1664 acd_mode_sense(device_t dev
, int page
, caddr_t pagebuf
, int pagesize
)
1666 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, page
, 0, 0, 0, 0,
1667 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1670 error
= ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, ATA_R_READ
, 10);
1675 acd_mode_select(device_t dev
, caddr_t pagebuf
, int pagesize
)
1677 int8_t ccb
[16] = { ATAPI_MODE_SELECT_BIG
, 0x10, 0, 0, 0, 0, 0,
1678 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1680 return ata_atapicmd(dev
, ccb
, pagebuf
, pagesize
, 0, 30);
1684 acd_set_speed(device_t dev
, int rdspeed
, int wrspeed
)
1686 int8_t ccb
[16] = { ATAPI_SET_SPEED
, 0, rdspeed
>> 8, rdspeed
,
1687 wrspeed
>> 8, wrspeed
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1690 error
= ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1697 acd_get_cap(device_t dev
)
1699 struct acd_softc
*cdp
= device_get_ivars(dev
);
1700 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, ATAPI_CDROM_CAP_PAGE
,
1701 0, 0, 0, 0, sizeof(cdp
->cap
)>>8, sizeof(cdp
->cap
),
1702 0, 0, 0, 0, 0, 0, 0 };
1705 /* get drive capabilities, some bugridden drives needs this repeated */
1706 for (count
= 0 ; count
< 5 ; count
++) {
1707 if (!ata_atapicmd(dev
, ccb
, (caddr_t
)&cdp
->cap
, sizeof(cdp
->cap
),
1708 ATA_R_READ
| ATA_R_QUIET
, 5)) {
1709 cdp
->cap
.max_read_speed
= ntohs(cdp
->cap
.max_read_speed
);
1710 cdp
->cap
.cur_read_speed
= ntohs(cdp
->cap
.cur_read_speed
);
1711 cdp
->cap
.max_write_speed
= ntohs(cdp
->cap
.max_write_speed
);
1712 cdp
->cap
.cur_write_speed
= max(ntohs(cdp
->cap
.cur_write_speed
),177);
1713 cdp
->cap
.max_vol_levels
= ntohs(cdp
->cap
.max_vol_levels
);
1714 cdp
->cap
.buf_size
= ntohs(cdp
->cap
.buf_size
);
1719 #ifdef ACD_CDR_FORMAT
1721 acd_read_format_caps(device_t dev
, struct cdr_format_capacities
*caps
)
1723 int8_t ccb
[16] = { ATAPI_READ_FORMAT_CAPACITIES
, 0, 0, 0, 0, 0, 0,
1724 (sizeof(struct cdr_format_capacities
) >> 8) & 0xff,
1725 sizeof(struct cdr_format_capacities
) & 0xff,
1726 0, 0, 0, 0, 0, 0, 0 };
1728 return ata_atapicmd(dev
, ccb
, (caddr_t
)caps
,
1729 sizeof(struct cdr_format_capacities
), ATA_R_READ
, 30);
1733 acd_format(device_t dev
, struct cdr_format_params
* params
)
1735 int8_t ccb
[16] = { ATAPI_FORMAT
, 0x11, 0, 0, 0, 0, 0, 0, 0, 0,
1739 error
= ata_atapicmd(dev
, ccb
, (u_int8_t
*)params
,
1740 sizeof(struct cdr_format_params
), 0, 30);
1743 #endif /* ACD_CDR_FORMAT */
1746 acd_test_ready(device_t dev
)
1748 int8_t ccb
[16] = { ATAPI_TEST_UNIT_READY
, 0, 0, 0, 0,
1749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1751 return ata_atapicmd(dev
, ccb
, NULL
, 0, 0, 30);
1755 acd_describe(device_t dev
)
1757 struct ata_channel
*ch
= device_get_softc(device_get_parent(dev
));
1758 struct ata_device
*atadev
= device_get_softc(dev
);
1759 struct acd_softc
*cdp
= device_get_ivars(dev
);
1764 device_printf(dev
, "<%.40s/%.8s> %s drive at ata%d as %s\n",
1765 atadev
->param
.model
, atadev
->param
.revision
,
1766 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1767 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1768 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1769 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1770 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM":"CDROM",
1771 device_get_unit(ch
->dev
), ata_unit2str(atadev
));
1773 device_printf(dev
, "%s", "");
1774 if (cdp
->cap
.cur_read_speed
) {
1775 kprintf("read %dKB/s", cdp
->cap
.cur_read_speed
* 1000 / 1024);
1776 if (cdp
->cap
.max_read_speed
)
1777 kprintf(" (%dKB/s)", cdp
->cap
.max_read_speed
* 1000 / 1024);
1778 if ((cdp
->cap
.cur_write_speed
) &&
1779 (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1780 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
))) {
1781 kprintf(" write %dKB/s", cdp
->cap
.cur_write_speed
* 1000 / 1024);
1782 if (cdp
->cap
.max_write_speed
)
1783 kprintf(" (%dKB/s)", cdp
->cap
.max_write_speed
* 1000 / 1024);
1787 if (cdp
->cap
.buf_size
) {
1788 kprintf("%s %dKB buffer", comma
? "," : "", cdp
->cap
.buf_size
);
1791 kprintf("%s %s\n", comma
? "," : "", ata_mode2str(atadev
->mode
));
1793 device_printf(dev
, "Reads:");
1795 if (cdp
->cap
.media
& MST_READ_CDR
) {
1796 kprintf(" CDR"); comma
= 1;
1798 if (cdp
->cap
.media
& MST_READ_CDRW
) {
1799 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1801 if (cdp
->cap
.capabilities
& MST_READ_CDDA
) {
1802 if (cdp
->cap
.capabilities
& MST_CDDA_STREAM
)
1803 kprintf("%s CDDA stream", comma
? "," : "");
1805 kprintf("%s CDDA", comma
? "," : "");
1808 if (cdp
->cap
.media
& MST_READ_DVDROM
) {
1809 kprintf("%s DVDROM", comma
? "," : ""); comma
= 1;
1811 if (cdp
->cap
.media
& MST_READ_DVDR
) {
1812 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1814 if (cdp
->cap
.media
& MST_READ_DVDRAM
) {
1815 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1817 if (cdp
->cap
.media
& MST_READ_PACKET
)
1818 kprintf("%s packet", comma
? "," : "");
1821 device_printf(dev
, "Writes:");
1822 if (cdp
->cap
.media
& (MST_WRITE_CDR
| MST_WRITE_CDRW
|
1823 MST_WRITE_DVDR
| MST_WRITE_DVDRAM
)) {
1825 if (cdp
->cap
.media
& MST_WRITE_CDR
) {
1826 kprintf(" CDR" ); comma
= 1;
1828 if (cdp
->cap
.media
& MST_WRITE_CDRW
) {
1829 kprintf("%s CDRW", comma
? "," : ""); comma
= 1;
1831 if (cdp
->cap
.media
& MST_WRITE_DVDR
) {
1832 kprintf("%s DVDR", comma
? "," : ""); comma
= 1;
1834 if (cdp
->cap
.media
& MST_WRITE_DVDRAM
) {
1835 kprintf("%s DVDRAM", comma
? "," : ""); comma
= 1;
1837 if (cdp
->cap
.media
& MST_WRITE_TEST
) {
1838 kprintf("%s test write", comma
? "," : ""); comma
= 1;
1840 if (cdp
->cap
.capabilities
& MST_BURNPROOF
)
1841 kprintf("%s burnproof", comma
? "," : "");
1844 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
) {
1845 device_printf(dev
, "Audio: ");
1846 if (cdp
->cap
.capabilities
& MST_AUDIO_PLAY
)
1848 if (cdp
->cap
.max_vol_levels
)
1849 kprintf(", %d volume levels", cdp
->cap
.max_vol_levels
);
1852 device_printf(dev
, "Mechanism: ");
1853 switch (cdp
->cap
.mechanism
& MST_MECH_MASK
) {
1854 case MST_MECH_CADDY
:
1855 mechanism
= "caddy"; break;
1857 mechanism
= "tray"; break;
1858 case MST_MECH_POPUP
:
1859 mechanism
= "popup"; break;
1860 case MST_MECH_CHANGER
:
1861 mechanism
= "changer"; break;
1862 case MST_MECH_CARTRIDGE
:
1863 mechanism
= "cartridge"; break;
1865 mechanism
= NULL
; break;
1868 kprintf("%s%s", (cdp
->cap
.mechanism
& MST_EJECT
) ?
1869 "ejectable " : "", mechanism
);
1870 else if (cdp
->cap
.mechanism
& MST_EJECT
)
1871 kprintf("ejectable");
1873 if (cdp
->cap
.mechanism
& MST_LOCKABLE
)
1874 kprintf((cdp
->cap
.mechanism
& MST_LOCKED
) ? ", locked":", unlocked");
1875 if (cdp
->cap
.mechanism
& MST_PREVENT
)
1876 kprintf(", lock protected");
1879 if ((cdp
->cap
.mechanism
& MST_MECH_MASK
) != MST_MECH_CHANGER
) {
1880 device_printf(dev
, "Medium: ");
1881 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1883 kprintf("CD-ROM "); break;
1885 kprintf("CD-R "); break;
1887 kprintf("CD-RW "); break;
1889 kprintf("DVD "); break;
1891 kprintf("door open"); break;
1893 kprintf("no/blank disc"); break;
1895 kprintf("medium format error"); break;
1897 if ((cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
)<MST_TYPE_MASK_HIGH
){
1898 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_LOW
) {
1900 kprintf("120mm data disc"); break;
1902 kprintf("120mm audio disc"); break;
1904 kprintf("120mm data/audio disc"); break;
1906 kprintf("120mm photo disc"); break;
1908 kprintf("80mm data disc"); break;
1910 kprintf("80mm audio disc"); break;
1912 kprintf("80mm data/audio disc"); break;
1914 kprintf("80mm photo disc"); break;
1916 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
1918 kprintf("unknown"); break;
1921 kprintf("blank"); break;
1925 kprintf("unknown (0x%x)", cdp
->cap
.medium_type
); break;
1932 device_printf(dev
, "%s ",
1933 (cdp
->cap
.media
& MST_WRITE_DVDR
) ? "DVDR" :
1934 (cdp
->cap
.media
& MST_WRITE_DVDRAM
) ? "DVDRAM" :
1935 (cdp
->cap
.media
& MST_WRITE_CDRW
) ? "CDRW" :
1936 (cdp
->cap
.media
& MST_WRITE_CDR
) ? "CDR" :
1937 (cdp
->cap
.media
& MST_READ_DVDROM
) ? "DVDROM" :
1939 kprintf("<%.40s/%.8s> at ata%d-%s %s\n",
1940 atadev
->param
.model
, atadev
->param
.revision
,
1941 device_get_unit(ch
->dev
), ata_unit2str(atadev
),
1942 ata_mode2str(atadev
->mode
) );
1946 static device_method_t acd_methods
[] = {
1947 /* device interface */
1948 DEVMETHOD(device_probe
, acd_probe
),
1949 DEVMETHOD(device_attach
, acd_attach
),
1950 DEVMETHOD(device_detach
, acd_detach
),
1951 DEVMETHOD(device_shutdown
, acd_shutdown
),
1954 DEVMETHOD(ata_reinit
, acd_reinit
),
1959 static driver_t acd_driver
= {
1965 static devclass_t acd_devclass
;
1967 DRIVER_MODULE(acd
, ata
, acd_driver
, acd_devclass
, NULL
, NULL
);
1968 MODULE_VERSION(acd
, 1);
1969 MODULE_DEPEND(acd
, ata
, 1, 1, 1);