2 * Copyright (c) 1998,1999,2000,2001,2002 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.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.48.2.20 2002/11/25 05:30:31 njl Exp $
29 * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.36 2007/06/03 03:44:16 dillon Exp $
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
42 #include <sys/diskslice.h>
43 #include <sys/devicestat.h>
45 #include <sys/cdrio.h>
46 #include <sys/dvdio.h>
47 #include <sys/fcntl.h>
49 #include <sys/ctype.h>
51 #include <sys/thread2.h>
54 #include "atapi-all.h"
57 /* device structures */
58 static d_open_t acdopen
;
59 static d_close_t acdclose
;
60 static d_ioctl_t acdioctl
;
61 static d_strategy_t acdstrategy
;
63 static struct dev_ops acd_ops
= {
64 { "acd", 117, D_DISK
| D_TRACKCLOSE
},
70 .d_strategy
= acdstrategy
,
74 static struct acd_softc
*acd_init_lun(struct ata_device
*);
75 static void acd_make_dev(struct acd_softc
*);
76 static void acd_set_ioparm(struct acd_softc
*);
77 static void acd_describe(struct acd_softc
*);
78 static void lba2msf(u_int32_t
, u_int8_t
*, u_int8_t
*, u_int8_t
*);
79 static u_int32_t
msf2lba(u_int8_t
, u_int8_t
, u_int8_t
);
80 static int acd_done(struct atapi_request
*);
81 static void acd_read_toc(struct acd_softc
*);
82 static int acd_play(struct acd_softc
*, int, int);
83 static int acd_setchan(struct acd_softc
*, u_int8_t
, u_int8_t
, u_int8_t
, u_int8_t
);
84 static void acd_select_slot(struct acd_softc
*);
85 static int acd_init_writer(struct acd_softc
*, int);
86 static int acd_fixate(struct acd_softc
*, int);
87 static int acd_init_track(struct acd_softc
*, struct cdr_track
*);
88 static int acd_flush(struct acd_softc
*);
89 static int acd_read_track_info(struct acd_softc
*, int32_t, struct acd_track_info
*);
90 static int acd_get_progress(struct acd_softc
*, int *);
91 static int acd_send_cue(struct acd_softc
*, struct cdr_cuesheet
*);
92 static int acd_report_key(struct acd_softc
*, struct dvd_authinfo
*);
93 static int acd_send_key(struct acd_softc
*, struct dvd_authinfo
*);
94 static int acd_read_structure(struct acd_softc
*, struct dvd_struct
*);
95 static int acd_eject(struct acd_softc
*, int);
96 static int acd_blank(struct acd_softc
*, int);
97 static int acd_prevent_allow(struct acd_softc
*, int);
98 static int acd_start_stop(struct acd_softc
*, int);
99 static int acd_pause_resume(struct acd_softc
*, int);
100 static int acd_mode_sense(struct acd_softc
*, int, caddr_t
, int);
101 static int acd_mode_select(struct acd_softc
*, caddr_t
, int);
102 static int acd_set_speed(struct acd_softc
*, int, int);
103 static void acd_get_cap(struct acd_softc
*);
106 static u_int32_t acd_lun_map
= 0;
107 static MALLOC_DEFINE(M_ACD
, "ACD driver", "ATAPI CD driver buffers");
110 acdattach(struct ata_device
*atadev
)
112 struct acd_softc
*cdp
;
115 if ((cdp
= acd_init_lun(atadev
)) == NULL
) {
116 ata_prtdev(atadev
, "acd: out of memory\n");
120 ata_set_name(atadev
, "acd", cdp
->lun
);
121 ata_command(atadev
, ATA_C_ATAPI_RESET
, 0, 0, 0, ATA_IMMEDIATE
);
124 /* if this is a changer device, allocate the neeeded lun's */
125 if (cdp
->cap
.mech
== MST_MECH_CHANGER
) {
126 int8_t ccb
[16] = { ATAPI_MECH_STATUS
, 0, 0, 0, 0, 0, 0, 0,
127 sizeof(struct changer
)>>8, sizeof(struct changer
),
130 chp
= kmalloc(sizeof(struct changer
), M_ACD
, M_WAITOK
| M_ZERO
);
131 if (!atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)chp
,
132 sizeof(struct changer
),
133 ATPR_F_READ
, 60, NULL
, NULL
)) {
134 struct acd_softc
*tmpcdp
= cdp
;
135 struct acd_softc
**cdparr
;
139 chp
->table_length
= htons(chp
->table_length
);
140 cdparr
= kmalloc(sizeof(struct acd_softc
) * chp
->slots
,
142 for (count
= 0; count
< chp
->slots
; count
++) {
144 tmpcdp
= acd_init_lun(atadev
);
146 ata_prtdev(atadev
, "out of memory\n");
150 cdparr
[count
] = tmpcdp
;
151 tmpcdp
->driver
= cdparr
;
152 tmpcdp
->slot
= count
;
153 tmpcdp
->changer_info
= chp
;
154 acd_make_dev(tmpcdp
);
155 devstat_add_entry(tmpcdp
->stats
, "acd", tmpcdp
->lun
, DEV_BSIZE
,
156 DEVSTAT_NO_ORDERED_TAGS
,
157 DEVSTAT_TYPE_CDROM
| DEVSTAT_TYPE_IF_IDE
,
158 DEVSTAT_PRIORITY_CD
);
160 name
= kmalloc(strlen(atadev
->name
) + 2, M_ACD
, M_WAITOK
);
161 strcpy(name
, atadev
->name
);
163 ata_free_name(atadev
);
164 ata_set_name(atadev
, name
, cdp
->lun
+ cdp
->changer_info
->slots
- 1);
170 devstat_add_entry(cdp
->stats
, "acd", cdp
->lun
, DEV_BSIZE
,
171 DEVSTAT_NO_ORDERED_TAGS
,
172 DEVSTAT_TYPE_CDROM
| DEVSTAT_TYPE_IF_IDE
,
173 DEVSTAT_PRIORITY_CD
);
176 atadev
->driver
= cdp
;
181 acddetach(struct ata_device
*atadev
)
183 struct acd_softc
*cdp
= atadev
->driver
;
184 struct acd_devlist
*entry
;
188 if (cdp
->changer_info
) {
189 for (subdev
= 0; subdev
< cdp
->changer_info
->slots
; subdev
++) {
190 if (cdp
->driver
[subdev
] == cdp
)
192 while ((bio
= bioq_first(&cdp
->driver
[subdev
]->bio_queue
))) {
193 bioq_remove(&cdp
->driver
[subdev
]->bio_queue
, bio
);
194 bio
->bio_buf
->b_flags
|= B_ERROR
;
195 bio
->bio_buf
->b_error
= ENXIO
;
198 release_dev(cdp
->driver
[subdev
]->dev
);
199 while ((entry
= TAILQ_FIRST(&cdp
->driver
[subdev
]->dev_list
))) {
200 release_dev(entry
->dev
);
201 TAILQ_REMOVE(&cdp
->driver
[subdev
]->dev_list
, entry
, chain
);
204 devstat_remove_entry(cdp
->driver
[subdev
]->stats
);
205 kfree(cdp
->driver
[subdev
]->stats
, M_ACD
);
206 ata_free_lun(&acd_lun_map
, cdp
->driver
[subdev
]->lun
);
207 kfree(cdp
->driver
[subdev
], M_ACD
);
209 kfree(cdp
->driver
, M_ACD
);
210 kfree(cdp
->changer_info
, M_ACD
);
212 while ((bio
= bioq_first(&cdp
->bio_queue
))) {
213 bio
->bio_buf
->b_flags
|= B_ERROR
;
214 bio
->bio_buf
->b_error
= ENXIO
;
217 while ((entry
= TAILQ_FIRST(&cdp
->dev_list
))) {
218 release_dev(entry
->dev
);
219 TAILQ_REMOVE(&cdp
->dev_list
, entry
, chain
);
222 disk_invalidate(&cdp
->disk
);
223 disk_destroy(&cdp
->disk
);
224 devstat_remove_entry(cdp
->stats
);
225 kfree(cdp
->stats
, M_ACD
);
226 ata_free_name(atadev
);
227 ata_free_lun(&acd_lun_map
, cdp
->lun
);
229 atadev
->driver
= NULL
;
232 static struct acd_softc
*
233 acd_init_lun(struct ata_device
*atadev
)
235 struct acd_softc
*cdp
;
237 cdp
= kmalloc(sizeof(struct acd_softc
), M_ACD
, M_WAITOK
| M_ZERO
);
238 TAILQ_INIT(&cdp
->dev_list
);
239 bioq_init(&cdp
->bio_queue
);
240 cdp
->device
= atadev
;
241 cdp
->lun
= ata_get_lun(&acd_lun_map
);
242 cdp
->block_size
= 2048;
244 cdp
->changer_info
= NULL
;
245 cdp
->stats
= kmalloc(sizeof(struct devstat
), M_ACD
, M_WAITOK
| M_ZERO
);
250 acd_make_dev(struct acd_softc
*cdp
)
254 dev
= disk_create(cdp
->lun
, &cdp
->disk
, &acd_ops
);
257 cdp
->device
->flags
|= ATA_D_MEDIA_CHANGED
;
262 acd_set_ioparm(struct acd_softc
*cdp
)
264 struct disk_info info
;
266 cdp
->dev
->si_iosize_max
=
267 ((256*DEV_BSIZE
)/cdp
->block_size
)*cdp
->block_size
;
268 cdp
->dev
->si_bsize_phys
= cdp
->block_size
;
269 bzero(&info
, sizeof(info
));
270 info
.d_media_blksize
= cdp
->block_size
;
271 info
.d_media_blocks
= cdp
->disk_size
;
272 info
.d_secpertrack
= 100;
274 info
.d_ncylinders
= cdp
->disk_size
/ info
.d_secpertrack
/ info
.d_nheads
+ 1;
275 info
.d_secpercyl
= info
.d_secpertrack
* info
.d_nheads
;
276 info
.d_dsflags
= DSO_ONESLICE
| DSO_COMPATLABEL
| DSO_COMPATPARTA
|
278 disk_setdiskinfo(&cdp
->disk
, &info
);
282 acd_describe(struct acd_softc
*cdp
)
288 ata_prtdev(cdp
->device
, "<%.40s/%.8s> %s drive at ata%d as %s\n",
289 cdp
->device
->param
->model
, cdp
->device
->param
->revision
,
290 (cdp
->cap
.write_dvdr
) ? "DVD-R" :
291 (cdp
->cap
.write_dvdram
) ? "DVD-RAM" :
292 (cdp
->cap
.write_cdrw
) ? "CD-RW" :
293 (cdp
->cap
.write_cdr
) ? "CD-R" :
294 (cdp
->cap
.read_dvdrom
) ? "DVD-ROM" : "CDROM",
295 device_get_unit(cdp
->device
->channel
->dev
),
296 (cdp
->device
->unit
== ATA_MASTER
) ? "master" : "slave");
298 ata_prtdev(cdp
->device
, "%s", "");
299 if (cdp
->cap
.cur_read_speed
) {
300 kprintf("read %dKB/s", cdp
->cap
.cur_read_speed
* 1000 / 1024);
301 if (cdp
->cap
.max_read_speed
)
302 kprintf(" (%dKB/s)", cdp
->cap
.max_read_speed
* 1000 / 1024);
303 if ((cdp
->cap
.cur_write_speed
) &&
304 (cdp
->cap
.write_cdr
|| cdp
->cap
.write_cdrw
||
305 cdp
->cap
.write_dvdr
|| cdp
->cap
.write_dvdram
)) {
306 kprintf(" write %dKB/s", cdp
->cap
.cur_write_speed
* 1000 / 1024);
307 if (cdp
->cap
.max_write_speed
)
308 kprintf(" (%dKB/s)", cdp
->cap
.max_write_speed
* 1000 / 1024);
312 if (cdp
->cap
.buf_size
) {
313 kprintf("%s %dKB buffer", comma
? "," : "", cdp
->cap
.buf_size
);
316 kprintf("%s %s\n", comma
? "," : "", ata_mode2str(cdp
->device
->mode
));
318 ata_prtdev(cdp
->device
, "Reads:");
320 if (cdp
->cap
.read_cdr
) {
321 kprintf(" CD-R"); comma
= 1;
323 if (cdp
->cap
.read_cdrw
) {
324 kprintf("%s CD-RW", comma
? "," : ""); comma
= 1;
326 if (cdp
->cap
.cd_da
) {
327 if (cdp
->cap
.cd_da_stream
)
328 kprintf("%s CD-DA stream", comma
? "," : "");
330 kprintf("%s CD-DA", comma
? "," : "");
333 if (cdp
->cap
.read_dvdrom
) {
334 kprintf("%s DVD-ROM", comma
? "," : ""); comma
= 1;
336 if (cdp
->cap
.read_dvdr
) {
337 kprintf("%s DVD-R", comma
? "," : ""); comma
= 1;
339 if (cdp
->cap
.read_dvdram
) {
340 kprintf("%s DVD-RAM", comma
? "," : ""); comma
= 1;
342 if (cdp
->cap
.read_packet
)
343 kprintf("%s packet", comma
? "," : "");
346 ata_prtdev(cdp
->device
, "Writes:");
347 if (cdp
->cap
.write_cdr
|| cdp
->cap
.write_cdrw
||
348 cdp
->cap
.write_dvdr
|| cdp
->cap
.write_dvdram
) {
350 if (cdp
->cap
.write_cdr
) {
351 kprintf(" CD-R" ); comma
= 1;
353 if (cdp
->cap
.write_cdrw
) {
354 kprintf("%s CD-RW", comma
? "," : ""); comma
= 1;
356 if (cdp
->cap
.write_dvdr
) {
357 kprintf("%s DVD-R", comma
? "," : ""); comma
= 1;
359 if (cdp
->cap
.write_dvdram
) {
360 kprintf("%s DVD-RAM", comma
? "," : ""); comma
= 1;
362 if (cdp
->cap
.test_write
) {
363 kprintf("%s test write", comma
? "," : ""); comma
= 1;
365 if (cdp
->cap
.burnproof
)
366 kprintf("%s burnproof", comma
? "," : "");
369 if (cdp
->cap
.audio_play
) {
370 ata_prtdev(cdp
->device
, "Audio: ");
371 if (cdp
->cap
.audio_play
)
373 if (cdp
->cap
.max_vol_levels
)
374 kprintf(", %d volume levels", cdp
->cap
.max_vol_levels
);
377 ata_prtdev(cdp
->device
, "Mechanism: ");
378 switch (cdp
->cap
.mech
) {
380 mechanism
= "caddy"; break;
382 mechanism
= "tray"; break;
384 mechanism
= "popup"; break;
385 case MST_MECH_CHANGER
:
386 mechanism
= "changer"; break;
387 case MST_MECH_CARTRIDGE
:
388 mechanism
= "cartridge"; break;
390 mechanism
= 0; break;
393 kprintf("%s%s", cdp
->cap
.eject
? "ejectable " : "", mechanism
);
394 else if (cdp
->cap
.eject
)
395 kprintf("ejectable");
398 kprintf(cdp
->cap
.locked
? ", locked" : ", unlocked");
399 if (cdp
->cap
.prevent
)
400 kprintf(", lock protected");
403 if (cdp
->cap
.mech
!= MST_MECH_CHANGER
) {
404 ata_prtdev(cdp
->device
, "Medium: ");
405 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
407 kprintf("CD-ROM "); break;
409 kprintf("CD-R "); break;
411 kprintf("CD-RW "); break;
413 kprintf("door open"); break;
415 kprintf("no/blank disc"); break;
417 kprintf("medium format error"); break;
419 if ((cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
)<MST_TYPE_MASK_HIGH
){
420 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_LOW
) {
422 kprintf("120mm data disc"); break;
424 kprintf("120mm audio disc"); break;
426 kprintf("120mm data/audio disc"); break;
428 kprintf("120mm photo disc"); break;
430 kprintf("80mm data disc"); break;
432 kprintf("80mm audio disc"); break;
434 kprintf("80mm data/audio disc"); break;
436 kprintf("80mm photo disc"); break;
438 switch (cdp
->cap
.medium_type
& MST_TYPE_MASK_HIGH
) {
440 kprintf("unknown"); break;
443 kprintf("blank"); break;
447 kprintf("unknown (0x%x)", cdp
->cap
.medium_type
); break;
454 ata_prtdev(cdp
->device
, "%s ",
455 (cdp
->cap
.write_dvdr
) ? "DVD-R" :
456 (cdp
->cap
.write_dvdram
) ? "DVD-RAM" :
457 (cdp
->cap
.write_cdrw
) ? "CD-RW" :
458 (cdp
->cap
.write_cdr
) ? "CD-R" :
459 (cdp
->cap
.read_dvdrom
) ? "DVD-ROM" : "CDROM");
461 if (cdp
->changer_info
)
462 kprintf("with %d CD changer ", cdp
->changer_info
->slots
);
464 kprintf("<%.40s> at ata%d-%s %s\n", cdp
->device
->param
->model
,
465 device_get_unit(cdp
->device
->channel
->dev
),
466 (cdp
->device
->unit
== ATA_MASTER
) ? "master" : "slave",
467 ata_mode2str(cdp
->device
->mode
) );
472 lba2msf(u_int32_t lba
, u_int8_t
*m
, u_int8_t
*s
, u_int8_t
*f
)
476 *m
= lba
/ (60 * 75);
482 static __inline u_int32_t
483 msf2lba(u_int8_t m
, u_int8_t s
, u_int8_t f
)
485 return (m
* 60 + s
) * 75 + f
- 150;
489 acdopen(struct dev_open_args
*ap
)
491 cdev_t dev
= ap
->a_head
.a_dev
;
492 struct acd_softc
*cdp
= dev
->si_drv1
;
498 if (ap
->a_oflags
& FWRITE
) {
499 if (count_dev(dev
) > 1)
503 /* wait if drive is not finished loading the medium */
505 struct atapi_reqsense
*sense
= cdp
->device
->result
;
507 if (!atapi_test_ready(cdp
->device
))
509 if (sense
->sense_key
== 2 && sense
->asc
== 4 && sense
->ascq
== 1)
510 tsleep(&timeout
, 0, "acdld", hz
/ 2);
515 if (cdp
->changer_info
&& cdp
->slot
!= cdp
->changer_info
->current_slot
) {
516 acd_select_slot(cdp
);
517 tsleep(&cdp
->changer_info
, 0, "acdopn", 0);
519 acd_prevent_allow(cdp
, 1);
520 cdp
->flags
|= F_LOCKED
;
526 acdclose(struct dev_close_args
*ap
)
528 cdev_t dev
= ap
->a_head
.a_dev
;
529 struct acd_softc
*cdp
= dev
->si_drv1
;
534 if (cdp
->changer_info
&& cdp
->slot
!= cdp
->changer_info
->current_slot
) {
535 acd_select_slot(cdp
);
536 tsleep(&cdp
->changer_info
, 0, "acdclo", 0);
538 acd_prevent_allow(cdp
, 0);
539 cdp
->flags
&= ~F_LOCKED
;
544 acdioctl(struct dev_ioctl_args
*ap
)
546 cdev_t dev
= ap
->a_head
.a_dev
;
547 struct acd_softc
*cdp
= dev
->si_drv1
;
553 if (cdp
->changer_info
&& cdp
->slot
!= cdp
->changer_info
->current_slot
) {
554 acd_select_slot(cdp
);
555 tsleep(&cdp
->changer_info
, 0, "acdctl", 0);
557 if (cdp
->device
->flags
& ATA_D_MEDIA_CHANGED
)
560 atapi_test_ready(cdp
->device
);
565 acd_prevent_allow(cdp
, 1);
566 cdp
->flags
|= F_LOCKED
;
572 error
= acd_pause_resume(cdp
, 1);
576 error
= acd_pause_resume(cdp
, 0);
580 error
= acd_start_stop(cdp
, 1);
584 error
= acd_start_stop(cdp
, 0);
588 error
= acd_prevent_allow(cdp
, 0);
589 cdp
->flags
&= ~F_LOCKED
;
593 error
= acd_prevent_allow(cdp
, 1);
594 cdp
->flags
|= F_LOCKED
;
598 ; /* note: if no proc EPERM will be returned */
599 error
= suser_cred(ap
->a_cred
, 0);
602 error
= atapi_test_ready(cdp
->device
);
606 if (count_dev(dev
) > 1) {
610 error
= acd_eject(cdp
, 0);
614 if (count_dev(dev
) > 1)
616 error
= acd_eject(cdp
, 1);
619 case CDIOREADTOCHEADER
:
620 if (!cdp
->toc
.hdr
.ending_track
) {
624 bcopy(&cdp
->toc
.hdr
, ap
->a_data
, sizeof(cdp
->toc
.hdr
));
627 case CDIOREADTOCENTRYS
:
629 struct ioc_read_toc_entry
*te
= (struct ioc_read_toc_entry
*)ap
->a_data
;
630 struct toc
*toc
= &cdp
->toc
;
631 int starting_track
= te
->starting_track
;
634 if (!toc
->hdr
.ending_track
) {
639 if (te
->data_len
< sizeof(toc
->tab
[0]) ||
640 (te
->data_len
% sizeof(toc
->tab
[0])) != 0 ||
641 (te
->address_format
!= CD_MSF_FORMAT
&&
642 te
->address_format
!= CD_LBA_FORMAT
)) {
648 starting_track
= toc
->hdr
.starting_track
;
649 else if (starting_track
== 170)
650 starting_track
= toc
->hdr
.ending_track
+ 1;
651 else if (starting_track
< toc
->hdr
.starting_track
||
652 starting_track
> toc
->hdr
.ending_track
+ 1) {
657 len
= ((toc
->hdr
.ending_track
+ 1 - starting_track
) + 1) *
659 if (te
->data_len
< len
)
661 if (len
> sizeof(toc
->tab
)) {
666 if (te
->address_format
== CD_MSF_FORMAT
) {
667 struct cd_toc_entry
*entry
;
669 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_WAITOK
| M_ZERO
);
670 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
671 entry
= toc
->tab
+ (toc
->hdr
.ending_track
+ 1 -
672 toc
->hdr
.starting_track
) + 1;
673 while (--entry
>= toc
->tab
)
674 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
675 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
677 error
= copyout(toc
->tab
+ starting_track
- toc
->hdr
.starting_track
,
679 if (te
->address_format
== CD_MSF_FORMAT
)
683 case CDIOREADTOCENTRY
:
685 struct ioc_read_toc_single_entry
*te
=
686 (struct ioc_read_toc_single_entry
*)ap
->a_data
;
687 struct toc
*toc
= &cdp
->toc
;
688 u_char track
= te
->track
;
690 if (!toc
->hdr
.ending_track
) {
695 if (te
->address_format
!= CD_MSF_FORMAT
&&
696 te
->address_format
!= CD_LBA_FORMAT
) {
702 track
= toc
->hdr
.starting_track
;
703 else if (track
== 170)
704 track
= toc
->hdr
.ending_track
+ 1;
705 else if (track
< toc
->hdr
.starting_track
||
706 track
> toc
->hdr
.ending_track
+ 1) {
711 if (te
->address_format
== CD_MSF_FORMAT
) {
712 struct cd_toc_entry
*entry
;
714 toc
= kmalloc(sizeof(struct toc
), M_ACD
, M_WAITOK
| M_ZERO
);
715 bcopy(&cdp
->toc
, toc
, sizeof(struct toc
));
717 entry
= toc
->tab
+ (track
- toc
->hdr
.starting_track
);
718 lba2msf(ntohl(entry
->addr
.lba
), &entry
->addr
.msf
.minute
,
719 &entry
->addr
.msf
.second
, &entry
->addr
.msf
.frame
);
721 bcopy(toc
->tab
+ track
- toc
->hdr
.starting_track
,
722 &te
->entry
, sizeof(struct cd_toc_entry
));
723 if (te
->address_format
== CD_MSF_FORMAT
)
728 case CDIOCREADSUBCHANNEL
:
730 struct ioc_read_subchannel
*args
=
731 (struct ioc_read_subchannel
*)ap
->a_data
;
733 int8_t ccb
[16] = { ATAPI_READ_SUBCHANNEL
, 0, 0x40, 1, 0, 0, 0,
734 sizeof(cdp
->subchan
)>>8, sizeof(cdp
->subchan
),
735 0, 0, 0, 0, 0, 0, 0 };
737 if (args
->data_len
> sizeof(struct cd_sub_channel_info
) ||
738 args
->data_len
< sizeof(struct cd_sub_channel_header
)) {
743 format
=args
->data_format
;
744 if ((format
!= CD_CURRENT_POSITION
) &&
745 (format
!= CD_MEDIA_CATALOG
) && (format
!= CD_TRACK_INFO
)) {
750 ccb
[1] = args
->address_format
& CD_MSF_FORMAT
;
752 if ((error
= atapi_queue_cmd(cdp
->device
,ccb
,(caddr_t
)&cdp
->subchan
,
753 sizeof(cdp
->subchan
), ATPR_F_READ
, 10,
757 if ((format
== CD_MEDIA_CATALOG
) || (format
== CD_TRACK_INFO
)) {
758 if (cdp
->subchan
.header
.audio_status
== 0x11) {
764 if (format
== CD_TRACK_INFO
)
765 ccb
[6] = args
->track
;
767 if ((error
= atapi_queue_cmd(cdp
->device
, ccb
,
768 (caddr_t
)&cdp
->subchan
,
769 sizeof(cdp
->subchan
), ATPR_F_READ
,
774 error
= copyout(&cdp
->subchan
, args
->data
, args
->data_len
);
780 struct ioc_play_msf
*args
= (struct ioc_play_msf
*)ap
->a_data
;
784 msf2lba(args
->start_m
, args
->start_s
, args
->start_f
),
785 msf2lba(args
->end_m
, args
->end_s
, args
->end_f
));
789 case CDIOCPLAYBLOCKS
:
791 struct ioc_play_blocks
*args
= (struct ioc_play_blocks
*)ap
->a_data
;
793 error
= acd_play(cdp
, args
->blk
, args
->blk
+ args
->len
);
797 case CDIOCPLAYTRACKS
:
799 struct ioc_play_track
*args
= (struct ioc_play_track
*)ap
->a_data
;
802 if (!cdp
->toc
.hdr
.ending_track
) {
806 if (args
->end_track
< cdp
->toc
.hdr
.ending_track
+ 1)
808 if (args
->end_track
> cdp
->toc
.hdr
.ending_track
+ 1)
809 args
->end_track
= cdp
->toc
.hdr
.ending_track
+ 1;
810 t1
= args
->start_track
- cdp
->toc
.hdr
.starting_track
;
811 t2
= args
->end_track
- cdp
->toc
.hdr
.starting_track
;
812 if (t1
< 0 || t2
< 0 ||
813 t1
> (cdp
->toc
.hdr
.ending_track
-cdp
->toc
.hdr
.starting_track
)) {
817 error
= acd_play(cdp
, ntohl(cdp
->toc
.tab
[t1
].addr
.lba
),
818 ntohl(cdp
->toc
.tab
[t2
].addr
.lba
));
824 struct ioc_read_audio
*args
= (struct ioc_read_audio
*)ap
->a_data
;
826 caddr_t buffer
, ubuf
= args
->buffer
;
830 if (!cdp
->toc
.hdr
.ending_track
) {
835 if ((frames
= args
->nframes
) < 0) {
840 if (args
->address_format
== CD_LBA_FORMAT
)
841 lba
= args
->address
.lba
;
842 else if (args
->address_format
== CD_MSF_FORMAT
)
843 lba
= msf2lba(args
->address
.msf
.minute
,
844 args
->address
.msf
.second
,
845 args
->address
.msf
.frame
);
851 #ifndef CD_BUFFER_BLOCKS
852 #define CD_BUFFER_BLOCKS 13
854 if (!(buffer
= kmalloc(CD_BUFFER_BLOCKS
* 2352, M_ACD
, M_WAITOK
))){
858 bzero(ccb
, sizeof(ccb
));
863 blocks
= (frames
>CD_BUFFER_BLOCKS
) ? CD_BUFFER_BLOCKS
: frames
;
864 size
= blocks
* 2352;
866 ccb
[0] = ATAPI_READ_CD
;
874 if ((error
= atapi_queue_cmd(cdp
->device
, ccb
, buffer
, size
,
875 ATPR_F_READ
, 30, NULL
,NULL
)))
878 if ((error
= copyout(buffer
, ubuf
, size
)))
885 kfree(buffer
, M_ACD
);
886 if (args
->address_format
== CD_LBA_FORMAT
)
887 args
->address
.lba
= lba
;
888 else if (args
->address_format
== CD_MSF_FORMAT
)
889 lba2msf(lba
, &args
->address
.msf
.minute
,
890 &args
->address
.msf
.second
,
891 &args
->address
.msf
.frame
);
897 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
899 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_AUDIO_PAGE
,
900 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
903 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
907 arg
->vol
[0] = cdp
->au
.port
[0].volume
;
908 arg
->vol
[1] = cdp
->au
.port
[1].volume
;
909 arg
->vol
[2] = cdp
->au
.port
[2].volume
;
910 arg
->vol
[3] = cdp
->au
.port
[3].volume
;
916 struct ioc_vol
*arg
= (struct ioc_vol
*)ap
->a_data
;
918 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_AUDIO_PAGE
,
919 (caddr_t
)&cdp
->au
, sizeof(cdp
->au
))))
921 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
) {
925 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_AUDIO_PAGE_MASK
,
926 (caddr_t
)&cdp
->aumask
,
927 sizeof(cdp
->aumask
))))
929 cdp
->au
.data_length
= 0;
930 cdp
->au
.port
[0].channels
= CHANNEL_0
;
931 cdp
->au
.port
[1].channels
= CHANNEL_1
;
932 cdp
->au
.port
[0].volume
= arg
->vol
[0] & cdp
->aumask
.port
[0].volume
;
933 cdp
->au
.port
[1].volume
= arg
->vol
[1] & cdp
->aumask
.port
[1].volume
;
934 cdp
->au
.port
[2].volume
= arg
->vol
[2] & cdp
->aumask
.port
[2].volume
;
935 cdp
->au
.port
[3].volume
= arg
->vol
[3] & cdp
->aumask
.port
[3].volume
;
936 error
= acd_mode_select(cdp
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
941 struct ioc_patch
*arg
= (struct ioc_patch
*)ap
->a_data
;
943 error
= acd_setchan(cdp
, arg
->patch
[0], arg
->patch
[1],
944 arg
->patch
[2], arg
->patch
[3]);
949 error
= acd_setchan(cdp
, CHANNEL_0
|CHANNEL_1
, CHANNEL_0
|CHANNEL_1
, 0,0);
953 error
= acd_setchan(cdp
, CHANNEL_0
, CHANNEL_1
, 0, 0);
957 error
= acd_setchan(cdp
, 0, 0, 0, 0);
961 error
= acd_setchan(cdp
, CHANNEL_0
, CHANNEL_0
, 0, 0);
965 error
= acd_setchan(cdp
, CHANNEL_1
, CHANNEL_1
, 0, 0);
969 error
= acd_blank(cdp
, (*(int *)ap
->a_data
));
972 case CDRIOCNEXTWRITEABLEADDR
:
974 struct acd_track_info track_info
;
976 if ((error
= acd_read_track_info(cdp
, 0xff, &track_info
)))
979 if (!track_info
.nwa_valid
) {
983 *(int*)ap
->a_data
= track_info
.next_writeable_addr
;
987 case CDRIOCINITWRITER
:
988 error
= acd_init_writer(cdp
, (*(int *)ap
->a_data
));
991 case CDRIOCINITTRACK
:
992 error
= acd_init_track(cdp
, (struct cdr_track
*)ap
->a_data
);
996 error
= acd_flush(cdp
);
1000 error
= acd_fixate(cdp
, (*(int *)ap
->a_data
));
1003 case CDRIOCREADSPEED
:
1005 int speed
= *(int *)ap
->a_data
;
1007 /* Preserve old behavior: units in multiples of CDROM speed */
1010 error
= acd_set_speed(cdp
, speed
, CDR_MAX_SPEED
);
1014 case CDRIOCWRITESPEED
:
1016 int speed
= *(int *)ap
->a_data
;
1020 error
= acd_set_speed(cdp
, CDR_MAX_SPEED
, speed
);
1024 case CDRIOCGETBLOCKSIZE
:
1025 *(int *)ap
->a_data
= cdp
->block_size
;
1028 case CDRIOCSETBLOCKSIZE
:
1029 cdp
->block_size
= *(int *)ap
->a_data
;
1030 acd_set_ioparm(cdp
);
1033 case CDRIOCGETPROGRESS
:
1034 error
= acd_get_progress(cdp
, (int *)ap
->a_data
);
1038 error
= acd_send_cue(cdp
, (struct cdr_cuesheet
*)ap
->a_data
);
1041 case DVDIOCREPORTKEY
:
1042 if (!cdp
->cap
.read_dvdrom
)
1045 error
= acd_report_key(cdp
, (struct dvd_authinfo
*)ap
->a_data
);
1049 if (!cdp
->cap
.read_dvdrom
)
1052 error
= acd_send_key(cdp
, (struct dvd_authinfo
*)ap
->a_data
);
1055 case DVDIOCREADSTRUCTURE
:
1056 if (!cdp
->cap
.read_dvdrom
)
1059 error
= acd_read_structure(cdp
, (struct dvd_struct
*)ap
->a_data
);
1069 acdstrategy(struct dev_strategy_args
*ap
)
1071 cdev_t dev
= ap
->a_head
.a_dev
;
1072 struct bio
*bio
= ap
->a_bio
;
1073 struct buf
*bp
= bio
->bio_buf
;
1074 struct acd_softc
*cdp
= dev
->si_drv1
;
1076 if (cdp
->device
->flags
& ATA_D_DETACHING
) {
1077 bp
->b_flags
|= B_ERROR
;
1078 bp
->b_error
= ENXIO
;
1083 /* if it's a null transfer, return immediatly. */
1084 if (bp
->b_bcount
== 0) {
1090 KKASSERT(bio
->bio_offset
!= NOOFFSET
);
1091 bio
->bio_driver_info
= dev
;
1092 bp
->b_resid
= bp
->b_bcount
;
1095 bioqdisksort(&cdp
->bio_queue
, bio
);
1097 ata_start(cdp
->device
->channel
);
1102 acd_start(struct ata_device
*atadev
)
1104 struct acd_softc
*cdp
= atadev
->driver
;
1105 struct bio
*bio
= bioq_first(&cdp
->bio_queue
);
1108 u_int32_t lba
, lastlba
, count
;
1110 int track
, blocksize
;
1112 if (cdp
->changer_info
) {
1115 cdp
= cdp
->driver
[cdp
->changer_info
->current_slot
];
1116 bio
= bioq_first(&cdp
->bio_queue
);
1118 /* check for work pending on any other slot */
1119 for (i
= 0; i
< cdp
->changer_info
->slots
; i
++) {
1120 if (i
== cdp
->changer_info
->current_slot
)
1122 if (bioq_first(&(cdp
->driver
[i
]->bio_queue
))) {
1123 if (bio
== NULL
|| time_second
> (cdp
->timestamp
+ 10)) {
1124 acd_select_slot(cdp
->driver
[i
]);
1132 bioq_remove(&cdp
->bio_queue
, bio
);
1133 dev
= bio
->bio_driver_info
;
1136 /* reject all queued entries if media changed */
1137 if (cdp
->device
->flags
& ATA_D_MEDIA_CHANGED
) {
1138 bp
->b_flags
|= B_ERROR
;
1145 * Special track access is via the high 8 bits of bio_offset
1146 * (128-254). The first track is 129. 128 is used for direct
1147 * raw CD device access which bypasses the disk layer entirely
1148 * (so e.g. writes by burncd don't error out in the disk layer).
1150 track
= (bio
->bio_offset
>> 56) & 127;
1153 if (track
> MAXTRK
) {
1154 bp
->b_flags
|= B_ERROR
;
1159 blocksize
= (cdp
->toc
.tab
[track
- 1].control
& 4) ? 2048 : 2352;
1160 lastlba
= ntohl(cdp
->toc
.tab
[track
].addr
.lba
);
1161 lba
= (bio
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
1162 lba
+= ntohl(cdp
->toc
.tab
[track
- 1].addr
.lba
);
1164 blocksize
= cdp
->block_size
;
1165 lastlba
= cdp
->disk_size
;
1166 lba
= (bio
->bio_offset
& 0x00FFFFFFFFFFFFFFULL
) / blocksize
;
1168 bzero(ccb
, sizeof(ccb
));
1170 if (bp
->b_bcount
% blocksize
!= 0) {
1171 bp
->b_flags
|= B_ERROR
;
1172 bp
->b_error
= EINVAL
;
1176 count
= bp
->b_bcount
/ blocksize
;
1178 if (bp
->b_cmd
== BUF_CMD_READ
) {
1179 /* if transfer goes beyond range adjust it to be within limits */
1180 if (lba
+ count
> lastlba
) {
1181 /* if we are entirely beyond EOM return EOF */
1182 if (lastlba
<= lba
) {
1183 bp
->b_resid
= bp
->b_bcount
;
1187 count
= lastlba
- lba
;
1189 switch (blocksize
) {
1191 ccb
[0] = ATAPI_READ_BIG
;
1195 ccb
[0] = ATAPI_READ_CD
;
1200 ccb
[0] = ATAPI_READ_CD
;
1205 ccb
[0] = ATAPI_WRITE_BIG
;
1216 devstat_start_transaction(cdp
->stats
);
1217 bio
->bio_caller_info1
.ptr
= cdp
;
1218 atapi_queue_cmd(cdp
->device
, ccb
, bp
->b_data
, count
* blocksize
,
1219 ((bp
->b_cmd
== BUF_CMD_READ
) ? ATPR_F_READ
: 0),
1220 (ccb
[0] == ATAPI_WRITE_BIG
) ? 60 : 30, acd_done
, bio
);
1224 acd_done(struct atapi_request
*request
)
1226 struct bio
*bio
= request
->driver
;
1227 struct buf
*bp
= bio
->bio_buf
;
1228 struct acd_softc
*cdp
= bio
->bio_caller_info1
.ptr
;
1230 if (request
->error
) {
1231 bp
->b_error
= request
->error
;
1232 bp
->b_flags
|= B_ERROR
;
1234 bp
->b_resid
= bp
->b_bcount
- request
->donecount
;
1236 devstat_end_transaction_buf(cdp
->stats
, bp
);
1242 acd_read_toc(struct acd_softc
*cdp
)
1244 struct acd_devlist
*entry
;
1245 int track
, ntracks
, len
;
1249 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1250 bzero(ccb
, sizeof(ccb
));
1252 if (atapi_test_ready(cdp
->device
) != 0)
1255 cdp
->device
->flags
&= ~ATA_D_MEDIA_CHANGED
;
1257 len
= sizeof(struct ioc_toc_header
) + sizeof(struct cd_toc_entry
);
1258 ccb
[0] = ATAPI_READ_TOC
;
1261 if (atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1262 ATPR_F_READ
| ATPR_F_QUIET
, 30, NULL
, NULL
)) {
1263 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1266 ntracks
= cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1;
1267 if (ntracks
<= 0 || ntracks
> MAXTRK
) {
1268 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1272 len
= sizeof(struct ioc_toc_header
)+(ntracks
+1)*sizeof(struct cd_toc_entry
);
1273 bzero(ccb
, sizeof(ccb
));
1274 ccb
[0] = ATAPI_READ_TOC
;
1277 if (atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)&cdp
->toc
, len
,
1278 ATPR_F_READ
| ATPR_F_QUIET
, 30, NULL
, NULL
)) {
1279 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1282 cdp
->toc
.hdr
.len
= ntohs(cdp
->toc
.hdr
.len
);
1284 cdp
->block_size
= (cdp
->toc
.tab
[0].control
& 4) ? 2048 : 2352;
1286 bzero(ccb
, sizeof(ccb
));
1287 ccb
[0] = ATAPI_READ_CAPACITY
;
1288 if (atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)sizes
, sizeof(sizes
),
1289 ATPR_F_READ
| ATPR_F_QUIET
, 30, NULL
, NULL
)) {
1290 bzero(&cdp
->toc
, sizeof(cdp
->toc
));
1291 acd_set_ioparm(cdp
);
1294 cdp
->disk_size
= ntohl(sizes
[0]) + 1;
1295 acd_set_ioparm(cdp
);
1297 while ((entry
= TAILQ_FIRST(&cdp
->dev_list
))) {
1298 destroy_dev(entry
->dev
);
1299 TAILQ_REMOVE(&cdp
->dev_list
, entry
, chain
);
1300 kfree(entry
, M_ACD
);
1302 for (track
= 1; track
<= ntracks
; track
++) {
1305 ksprintf(name
, "acd%dt%d", cdp
->lun
, track
);
1306 entry
= kmalloc(sizeof(struct acd_devlist
), M_ACD
, M_WAITOK
| M_ZERO
);
1307 entry
->dev
= make_dev(&acd_ops
,
1308 dkmakepart(track
+ 128) | dkmakeunit(cdp
->lun
) |
1309 dkmakeslice(WHOLE_DISK_SLICE
),
1310 0, 0, 0644, name
, NULL
);
1311 entry
->dev
->si_drv1
= cdp
->dev
->si_drv1
;
1312 reference_dev(entry
->dev
);
1313 TAILQ_INSERT_TAIL(&cdp
->dev_list
, entry
, chain
);
1317 if (cdp
->disk_size
&& cdp
->toc
.hdr
.ending_track
) {
1318 ata_prtdev(cdp
->device
, "(%d sectors (%d bytes)), %d tracks ",
1319 cdp
->disk_size
, cdp
->block_size
,
1320 cdp
->toc
.hdr
.ending_track
- cdp
->toc
.hdr
.starting_track
+ 1);
1321 if (cdp
->toc
.tab
[0].control
& 4)
1322 kprintf("%dMB\n", cdp
->disk_size
/ 512);
1324 kprintf("%d:%d audio\n",
1325 cdp
->disk_size
/ 75 / 60, cdp
->disk_size
/ 75 % 60);
1331 acd_play(struct acd_softc
*cdp
, int start
, int end
)
1335 bzero(ccb
, sizeof(ccb
));
1336 ccb
[0] = ATAPI_PLAY_MSF
;
1337 lba2msf(start
, &ccb
[3], &ccb
[4], &ccb
[5]);
1338 lba2msf(end
, &ccb
[6], &ccb
[7], &ccb
[8]);
1339 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 10, NULL
, NULL
);
1343 acd_setchan(struct acd_softc
*cdp
,
1344 u_int8_t c0
, u_int8_t c1
, u_int8_t c2
, u_int8_t c3
)
1348 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_AUDIO_PAGE
, (caddr_t
)&cdp
->au
,
1351 if (cdp
->au
.page_code
!= ATAPI_CDROM_AUDIO_PAGE
)
1353 cdp
->au
.data_length
= 0;
1354 cdp
->au
.port
[0].channels
= c0
;
1355 cdp
->au
.port
[1].channels
= c1
;
1356 cdp
->au
.port
[2].channels
= c2
;
1357 cdp
->au
.port
[3].channels
= c3
;
1358 return acd_mode_select(cdp
, (caddr_t
)&cdp
->au
, sizeof(cdp
->au
));
1362 acd_select_done1(struct atapi_request
*request
)
1364 struct acd_softc
*cdp
= request
->driver
;
1366 cdp
->changer_info
->current_slot
= cdp
->slot
;
1367 cdp
->driver
[cdp
->changer_info
->current_slot
]->timestamp
= time_second
;
1368 wakeup(&cdp
->changer_info
);
1373 acd_select_done(struct atapi_request
*request
)
1375 struct acd_softc
*cdp
= request
->driver
;
1376 int8_t ccb
[16] = { ATAPI_LOAD_UNLOAD
, 0, 0, 0, 3, 0, 0, 0,
1377 cdp
->slot
, 0, 0, 0, 0, 0, 0, 0 };
1379 /* load the wanted slot */
1380 atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, ATPR_F_AT_HEAD
, 30,
1381 acd_select_done1
, cdp
);
1386 acd_select_slot(struct acd_softc
*cdp
)
1388 int8_t ccb
[16] = { ATAPI_LOAD_UNLOAD
, 0, 0, 0, 2, 0, 0, 0,
1389 cdp
->changer_info
->current_slot
, 0, 0, 0, 0, 0, 0, 0 };
1391 /* unload the current media from player */
1392 atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, ATPR_F_AT_HEAD
, 30,
1393 acd_select_done
, cdp
);
1397 acd_init_writer(struct acd_softc
*cdp
, int test_write
)
1401 bzero(ccb
, sizeof(ccb
));
1402 ccb
[0] = ATAPI_REZERO
;
1403 atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, ATPR_F_QUIET
, 60, NULL
, NULL
);
1404 ccb
[0] = ATAPI_SEND_OPC_INFO
;
1406 atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, ATPR_F_QUIET
, 30, NULL
, NULL
);
1411 acd_fixate(struct acd_softc
*cdp
, int multisession
)
1413 int8_t ccb
[16] = { ATAPI_CLOSE_TRACK
, 0x01, 0x02, 0, 0, 0, 0, 0,
1414 0, 0, 0, 0, 0, 0, 0, 0 };
1415 int timeout
= 5*60*2;
1417 struct write_param param
;
1419 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1420 (caddr_t
)¶m
, sizeof(param
))))
1423 param
.data_length
= 0;
1425 param
.session_type
= CDR_SESS_MULTI
;
1427 param
.session_type
= CDR_SESS_NONE
;
1429 if ((error
= acd_mode_select(cdp
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1432 error
= atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1436 /* some drives just return ready, wait for the expected fixate time */
1437 if ((error
= atapi_test_ready(cdp
->device
)) != EBUSY
) {
1438 timeout
= timeout
/ (cdp
->cap
.cur_write_speed
/ 177);
1439 tsleep(&error
, 0, "acdfix", timeout
* hz
/ 2);
1440 return atapi_test_ready(cdp
->device
);
1443 while (timeout
-- > 0) {
1444 if ((error
= atapi_test_ready(cdp
->device
)) != EBUSY
)
1446 tsleep(&error
, 0, "acdcld", hz
/2);
1452 acd_init_track(struct acd_softc
*cdp
, struct cdr_track
*track
)
1454 struct write_param param
;
1457 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1458 (caddr_t
)¶m
, sizeof(param
))))
1461 param
.data_length
= 0;
1462 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1463 param
.page_length
= 0x32;
1464 param
.test_write
= track
->test_write
? 1 : 0;
1465 param
.write_type
= CDR_WTYPE_TRACK
;
1466 param
.session_type
= CDR_SESS_NONE
;
1468 param
.packet_size
= 0;
1470 if (cdp
->cap
.burnproof
)
1471 param
.burnproof
= 1;
1473 switch (track
->datablock_type
) {
1477 param
.track_mode
= CDR_TMODE_AUDIO_PREEMP
;
1479 param
.track_mode
= CDR_TMODE_AUDIO
;
1480 cdp
->block_size
= 2352;
1481 param
.datablock_type
= CDR_DB_RAW
;
1482 param
.session_format
= CDR_SESS_CDROM
;
1485 case CDR_DB_ROM_MODE1
:
1486 cdp
->block_size
= 2048;
1487 param
.track_mode
= CDR_TMODE_DATA
;
1488 param
.datablock_type
= CDR_DB_ROM_MODE1
;
1489 param
.session_format
= CDR_SESS_CDROM
;
1492 case CDR_DB_ROM_MODE2
:
1493 cdp
->block_size
= 2336;
1494 param
.track_mode
= CDR_TMODE_DATA
;
1495 param
.datablock_type
= CDR_DB_ROM_MODE2
;
1496 param
.session_format
= CDR_SESS_CDROM
;
1499 case CDR_DB_XA_MODE1
:
1500 cdp
->block_size
= 2048;
1501 param
.track_mode
= CDR_TMODE_DATA
;
1502 param
.datablock_type
= CDR_DB_XA_MODE1
;
1503 param
.session_format
= CDR_SESS_CDROM_XA
;
1506 case CDR_DB_XA_MODE2_F1
:
1507 cdp
->block_size
= 2056;
1508 param
.track_mode
= CDR_TMODE_DATA
;
1509 param
.datablock_type
= CDR_DB_XA_MODE2_F1
;
1510 param
.session_format
= CDR_SESS_CDROM_XA
;
1513 case CDR_DB_XA_MODE2_F2
:
1514 cdp
->block_size
= 2324;
1515 param
.track_mode
= CDR_TMODE_DATA
;
1516 param
.datablock_type
= CDR_DB_XA_MODE2_F2
;
1517 param
.session_format
= CDR_SESS_CDROM_XA
;
1520 case CDR_DB_XA_MODE2_MIX
:
1521 cdp
->block_size
= 2332;
1522 param
.track_mode
= CDR_TMODE_DATA
;
1523 param
.datablock_type
= CDR_DB_XA_MODE2_MIX
;
1524 param
.session_format
= CDR_SESS_CDROM_XA
;
1527 acd_set_ioparm(cdp
);
1528 return acd_mode_select(cdp
, (caddr_t
)¶m
, param
.page_length
+ 10);
1532 acd_flush(struct acd_softc
*cdp
)
1534 int8_t ccb
[16] = { ATAPI_SYNCHRONIZE_CACHE
, 0, 0, 0, 0, 0, 0, 0,
1535 0, 0, 0, 0, 0, 0, 0, 0 };
1537 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, ATPR_F_QUIET
, 60,
1542 acd_read_track_info(struct acd_softc
*cdp
,
1543 int32_t lba
, struct acd_track_info
*info
)
1545 int8_t ccb
[16] = { ATAPI_READ_TRACK_INFO
, 1,
1546 lba
>>24, lba
>>16, lba
>>8, lba
,
1548 sizeof(*info
)>>8, sizeof(*info
),
1549 0, 0, 0, 0, 0, 0, 0 };
1552 if ((error
= atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)info
, sizeof(*info
),
1553 ATPR_F_READ
, 30, NULL
, NULL
)))
1555 info
->track_start_addr
= ntohl(info
->track_start_addr
);
1556 info
->next_writeable_addr
= ntohl(info
->next_writeable_addr
);
1557 info
->free_blocks
= ntohl(info
->free_blocks
);
1558 info
->fixed_packet_size
= ntohl(info
->fixed_packet_size
);
1559 info
->track_length
= ntohl(info
->track_length
);
1564 acd_get_progress(struct acd_softc
*cdp
, int *finished
)
1566 int8_t ccb
[16] = { ATAPI_READ_CAPACITY
, 0, 0, 0, 0, 0, 0, 0,
1567 0, 0, 0, 0, 0, 0, 0, 0 };
1568 struct atapi_reqsense
*sense
= cdp
->device
->result
;
1571 if (atapi_test_ready(cdp
->device
) != EBUSY
) {
1572 if (atapi_queue_cmd(cdp
->device
, ccb
, tmp
, sizeof(tmp
),
1573 ATPR_F_READ
, 30, NULL
, NULL
) != EBUSY
) {
1580 ((sense
->sk_specific2
| (sense
->sk_specific1
<< 8)) * 100) / 65535;
1587 acd_send_cue(struct acd_softc
*cdp
, struct cdr_cuesheet
*cuesheet
)
1589 struct write_param param
;
1590 int8_t ccb
[16] = { ATAPI_SEND_CUE_SHEET
, 0, 0, 0, 0, 0,
1591 cuesheet
->len
>>16, cuesheet
->len
>>8, cuesheet
->len
,
1592 0, 0, 0, 0, 0, 0, 0 };
1599 if ((error
= acd_mode_sense(cdp
, ATAPI_CDROM_WRITE_PARAMETERS_PAGE
,
1600 (caddr_t
)¶m
, sizeof(param
))))
1602 param
.data_length
= 0;
1603 param
.page_code
= ATAPI_CDROM_WRITE_PARAMETERS_PAGE
;
1604 param
.page_length
= 0x32;
1605 param
.test_write
= cuesheet
->test_write
? 1 : 0;
1606 param
.write_type
= CDR_WTYPE_SESSION
;
1607 param
.session_type
= cuesheet
->session_type
;
1609 param
.packet_size
= 0;
1610 param
.track_mode
= CDR_TMODE_AUDIO
;
1611 param
.datablock_type
= CDR_DB_RAW
;
1612 param
.session_format
= cuesheet
->session_format
;
1613 if (cdp
->cap
.burnproof
)
1614 param
.burnproof
= 1;
1615 if ((error
= acd_mode_select(cdp
, (caddr_t
)¶m
, param
.page_length
+ 10)))
1618 buffer
= kmalloc(cuesheet
->len
, M_ACD
, M_WAITOK
);
1621 if ((error
= copyin(cuesheet
->entries
, buffer
, cuesheet
->len
)))
1624 kprintf("acd: cuesheet lenght = %d\n", cuesheet
->len
);
1625 for (i
=0; i
<cuesheet
->len
; i
++)
1627 kprintf(" %02x", buffer
[i
]);
1629 kprintf("\n%02x", buffer
[i
]);
1632 error
= atapi_queue_cmd(cdp
->device
, ccb
, buffer
, cuesheet
->len
, 0,
1634 kfree(buffer
, M_ACD
);
1639 acd_report_key(struct acd_softc
*cdp
, struct dvd_authinfo
*ai
)
1641 struct dvd_miscauth
*d
;
1647 /* this is common even for ai->format == DVD_INVALIDATE_AGID */
1648 bzero(ccb
, sizeof(ccb
));
1649 ccb
[0] = ATAPI_REPORT_KEY
;
1650 ccb
[2] = (lba
>> 24) & 0xff;
1651 ccb
[3] = (lba
>> 16) & 0xff;
1652 ccb
[4] = (lba
>> 8) & 0xff;
1653 ccb
[5] = lba
& 0xff;
1654 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1656 switch (ai
->format
) {
1657 case DVD_REPORT_AGID
:
1658 case DVD_REPORT_ASF
:
1659 case DVD_REPORT_RPC
:
1662 case DVD_REPORT_KEY1
:
1665 case DVD_REPORT_TITLE_KEY
:
1669 case DVD_REPORT_CHALLENGE
:
1672 case DVD_INVALIDATE_AGID
:
1673 return(atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 10, NULL
, NULL
));
1678 ccb
[8] = (length
>> 8) & 0xff;
1679 ccb
[9] = length
& 0xff;
1681 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1682 d
->length
= htons(length
- 2);
1684 error
= atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)d
, length
,
1685 ATPR_F_READ
, 10, NULL
, NULL
);
1691 switch (ai
->format
) {
1692 case DVD_REPORT_AGID
:
1693 ai
->agid
= d
->data
[3] >> 6;
1696 case DVD_REPORT_CHALLENGE
:
1697 bcopy(&d
->data
[0], &ai
->keychal
[0], 10);
1700 case DVD_REPORT_KEY1
:
1701 bcopy(&d
->data
[0], &ai
->keychal
[0], 5);
1704 case DVD_REPORT_TITLE_KEY
:
1705 ai
->cpm
= (d
->data
[0] >> 7);
1706 ai
->cp_sec
= (d
->data
[0] >> 6) & 0x1;
1707 ai
->cgms
= (d
->data
[0] >> 4) & 0x3;
1708 bcopy(&d
->data
[1], &ai
->keychal
[0], 5);
1711 case DVD_REPORT_ASF
:
1712 ai
->asf
= d
->data
[3] & 1;
1715 case DVD_REPORT_RPC
:
1716 ai
->reg_type
= (d
->data
[0] >> 6);
1717 ai
->vend_rsts
= (d
->data
[0] >> 3) & 0x7;
1718 ai
->user_rsts
= d
->data
[0] & 0x7;
1719 ai
->region
= d
->data
[1];
1720 ai
->rpc_scheme
= d
->data
[2];
1723 case DVD_INVALIDATE_AGID
:
1735 acd_send_key(struct acd_softc
*cdp
, struct dvd_authinfo
*ai
)
1737 struct dvd_miscauth
*d
;
1742 switch (ai
->format
) {
1743 case DVD_SEND_CHALLENGE
:
1745 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1746 bcopy(ai
->keychal
, &d
->data
[0], 10);
1751 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1752 bcopy(&ai
->keychal
[0], &d
->data
[0], 5);
1757 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1758 d
->data
[0] = ai
->region
;
1765 bzero(ccb
, sizeof(ccb
));
1766 ccb
[0] = ATAPI_SEND_KEY
;
1767 ccb
[8] = (length
>> 8) & 0xff;
1768 ccb
[9] = length
& 0xff;
1769 ccb
[10] = (ai
->agid
<< 6) | ai
->format
;
1770 d
->length
= htons(length
- 2);
1771 error
= atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)d
, length
, 0,
1778 acd_read_structure(struct acd_softc
*cdp
, struct dvd_struct
*s
)
1780 struct dvd_miscauth
*d
;
1786 case DVD_STRUCT_PHYSICAL
:
1790 case DVD_STRUCT_COPYRIGHT
:
1794 case DVD_STRUCT_DISCKEY
:
1798 case DVD_STRUCT_BCA
:
1802 case DVD_STRUCT_MANUFACT
:
1806 case DVD_STRUCT_DDS
:
1807 case DVD_STRUCT_PRERECORDED
:
1808 case DVD_STRUCT_UNIQUEID
:
1809 case DVD_STRUCT_LIST
:
1810 case DVD_STRUCT_CMI
:
1811 case DVD_STRUCT_RMD_LAST
:
1812 case DVD_STRUCT_RMD_RMA
:
1813 case DVD_STRUCT_DCB
:
1820 d
= kmalloc(length
, M_ACD
, M_WAITOK
| M_ZERO
);
1821 d
->length
= htons(length
- 2);
1823 bzero(ccb
, sizeof(ccb
));
1824 ccb
[0] = ATAPI_READ_STRUCTURE
;
1825 ccb
[6] = s
->layer_num
;
1827 ccb
[8] = (length
>> 8) & 0xff;
1828 ccb
[9] = length
& 0xff;
1829 ccb
[10] = s
->agid
<< 6;
1830 error
= atapi_queue_cmd(cdp
->device
, ccb
, (caddr_t
)d
, length
, ATPR_F_READ
,
1837 switch (s
->format
) {
1838 case DVD_STRUCT_PHYSICAL
: {
1839 struct dvd_layer
*layer
= (struct dvd_layer
*)&s
->data
[0];
1841 layer
->book_type
= d
->data
[0] >> 4;
1842 layer
->book_version
= d
->data
[0] & 0xf;
1843 layer
->disc_size
= d
->data
[1] >> 4;
1844 layer
->max_rate
= d
->data
[1] & 0xf;
1845 layer
->nlayers
= (d
->data
[2] >> 5) & 3;
1846 layer
->track_path
= (d
->data
[2] >> 4) & 1;
1847 layer
->layer_type
= d
->data
[2] & 0xf;
1848 layer
->linear_density
= d
->data
[3] >> 4;
1849 layer
->track_density
= d
->data
[3] & 0xf;
1850 layer
->start_sector
= d
->data
[5] << 16 | d
->data
[6] << 8 | d
->data
[7];
1851 layer
->end_sector
= d
->data
[9] << 16 | d
->data
[10] << 8 | d
->data
[11];
1852 layer
->end_sector_l0
= d
->data
[13] << 16 | d
->data
[14] << 8|d
->data
[15];
1853 layer
->bca
= d
->data
[16] >> 7;
1857 case DVD_STRUCT_COPYRIGHT
:
1858 s
->cpst
= d
->data
[0];
1859 s
->rmi
= d
->data
[0];
1862 case DVD_STRUCT_DISCKEY
:
1863 bcopy(&d
->data
[0], &s
->data
[0], 2048);
1866 case DVD_STRUCT_BCA
:
1867 s
->length
= ntohs(d
->length
);
1868 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1871 case DVD_STRUCT_MANUFACT
:
1872 s
->length
= ntohs(d
->length
);
1873 bcopy(&d
->data
[0], &s
->data
[0], s
->length
);
1884 acd_eject(struct acd_softc
*cdp
, int close
)
1888 if ((error
= acd_start_stop(cdp
, 0)) == EBUSY
) {
1891 if ((error
= acd_start_stop(cdp
, 3)))
1894 acd_prevent_allow(cdp
, 1);
1895 cdp
->flags
|= F_LOCKED
;
1902 acd_prevent_allow(cdp
, 0);
1903 cdp
->flags
&= ~F_LOCKED
;
1904 cdp
->device
->flags
|= ATA_D_MEDIA_CHANGED
;
1905 return acd_start_stop(cdp
, 2);
1909 acd_blank(struct acd_softc
*cdp
, int blanktype
)
1911 int8_t ccb
[16] = { ATAPI_BLANK
, 0x10 | (blanktype
& 0x7), 0, 0, 0, 0, 0, 0,
1912 0, 0, 0, 0, 0, 0, 0, 0 };
1914 cdp
->device
->flags
|= ATA_D_MEDIA_CHANGED
;
1915 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1919 acd_prevent_allow(struct acd_softc
*cdp
, int lock
)
1921 int8_t ccb
[16] = { ATAPI_PREVENT_ALLOW
, 0, 0, 0, lock
,
1922 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1924 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1928 acd_start_stop(struct acd_softc
*cdp
, int start
)
1930 int8_t ccb
[16] = { ATAPI_START_STOP
, 0, 0, 0, start
,
1931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1933 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1937 acd_pause_resume(struct acd_softc
*cdp
, int pause
)
1939 int8_t ccb
[16] = { ATAPI_PAUSE
, 0, 0, 0, 0, 0, 0, 0, pause
,
1940 0, 0, 0, 0, 0, 0, 0 };
1942 return atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1946 acd_mode_sense(struct acd_softc
*cdp
, int page
, caddr_t pagebuf
, int pagesize
)
1948 int8_t ccb
[16] = { ATAPI_MODE_SENSE_BIG
, 0, page
, 0, 0, 0, 0,
1949 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1952 error
= atapi_queue_cmd(cdp
->device
, ccb
, pagebuf
, pagesize
, ATPR_F_READ
,
1955 atapi_dump("acd: mode sense ", pagebuf
, pagesize
);
1961 acd_mode_select(struct acd_softc
*cdp
, caddr_t pagebuf
, int pagesize
)
1963 int8_t ccb
[16] = { ATAPI_MODE_SELECT_BIG
, 0x10, 0, 0, 0, 0, 0,
1964 pagesize
>>8, pagesize
, 0, 0, 0, 0, 0, 0, 0 };
1967 ata_prtdev(cdp
->device
,
1968 "modeselect pagesize=%d\n", pagesize
);
1969 atapi_dump("mode select ", pagebuf
, pagesize
);
1971 return atapi_queue_cmd(cdp
->device
, ccb
, pagebuf
, pagesize
, 0,
1976 acd_set_speed(struct acd_softc
*cdp
, int rdspeed
, int wrspeed
)
1978 int8_t ccb
[16] = { ATAPI_SET_SPEED
, 0, rdspeed
>> 8, rdspeed
,
1979 wrspeed
>> 8, wrspeed
, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1982 error
= atapi_queue_cmd(cdp
->device
, ccb
, NULL
, 0, 0, 30, NULL
, NULL
);
1989 acd_get_cap(struct acd_softc
*cdp
)
1993 /* get drive capabilities, some drives needs this repeated */
1994 while (retry
-- && acd_mode_sense(cdp
, ATAPI_CDROM_CAP_PAGE
,
1995 (caddr_t
)&cdp
->cap
, sizeof(cdp
->cap
)))
1997 cdp
->cap
.max_read_speed
= ntohs(cdp
->cap
.max_read_speed
);
1998 cdp
->cap
.cur_read_speed
= ntohs(cdp
->cap
.cur_read_speed
);
1999 cdp
->cap
.max_write_speed
= ntohs(cdp
->cap
.max_write_speed
);
2000 cdp
->cap
.cur_write_speed
= max(ntohs(cdp
->cap
.cur_write_speed
), 177);
2001 cdp
->cap
.max_vol_levels
= ntohs(cdp
->cap
.max_vol_levels
);
2002 cdp
->cap
.buf_size
= ntohs(cdp
->cap
.buf_size
);