summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata/atapi-cd.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/atapi-cd.c')
-rw-r--r--sys/dev/ata/atapi-cd.c562
1 files changed, 290 insertions, 272 deletions
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 751a2c4..9b7e865 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -44,36 +44,40 @@
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/ctype.h>
+#include <sys/taskqueue.h>
+#include <sys/mutex.h>
#include <machine/bus.h>
#include <dev/ata/ata-all.h>
-#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-cd.h>
/* device structures */
-static d_open_t acdopen;
-static d_close_t acdclose;
-static d_ioctl_t acdioctl;
-static d_strategy_t acdstrategy;
+static d_open_t acd_open;
+static d_close_t acd_close;
+static d_ioctl_t acd_ioctl;
+static d_strategy_t acd_strategy;
static struct cdevsw acd_cdevsw = {
- .d_open = acdopen,
- .d_close = acdclose,
+ .d_open = acd_open,
+ .d_close = acd_close,
.d_read = physread,
.d_write = physwrite,
- .d_ioctl = acdioctl,
- .d_strategy = acdstrategy,
+ .d_ioctl = acd_ioctl,
+ .d_strategy = acd_strategy,
.d_name = "acd",
.d_maj = 117,
- .d_flags = D_DISK | D_TRACKCLOSE,
+ .d_flags = D_DISK | D_TRACKCLOSE | D_NOGIANT,
};
/* prototypes */
+static void acd_detach(struct ata_device *atadev);
+static void acd_start(struct ata_device *atadev);
+
static struct acd_softc *acd_init_lun(struct ata_device *);
static void acd_make_dev(struct acd_softc *);
static void acd_set_ioparm(struct acd_softc *);
static void acd_describe(struct acd_softc *);
static void lba2msf(u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
static u_int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
-static int acd_done(struct atapi_request *);
+static void acd_done(struct ata_request *);
static void acd_read_toc(struct acd_softc *);
static int acd_play(struct acd_softc *, int, int);
static int acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
@@ -99,27 +103,29 @@ static int acd_set_speed(struct acd_softc *, int, int);
static void acd_get_cap(struct acd_softc *);
static int acd_read_format_caps(struct acd_softc *, struct cdr_format_capacities *);
static int acd_format(struct acd_softc *, struct cdr_format_params *);
+static int acd_test_ready(struct ata_device *atadev);
+static int acd_request_sense(struct ata_device *atadev, struct atapi_sense *sense);
/* internal vars */
static u_int32_t acd_lun_map = 0;
static MALLOC_DEFINE(M_ACD, "ACD driver", "ATAPI CD driver buffers");
-int
-acdattach(struct ata_device *atadev)
+void
+acd_attach(struct ata_device *atadev)
{
struct acd_softc *cdp;
struct changer *chp;
if ((cdp = acd_init_lun(atadev)) == NULL) {
- ata_prtdev(atadev, "acd: out of memory\n");
- return 0;
+ ata_prtdev(atadev, "out of memory\n");
+ return;
}
ata_set_name(atadev, "acd", cdp->lun);
acd_get_cap(cdp);
/* if this is a changer device, allocate the neeeded lun's */
- if (cdp->cap.mech == MST_MECH_CHANGER) {
+ if ((cdp->cap.mechanism & MST_MECH_MASK) == MST_MECH_CHANGER) {
int8_t ccb[16] = { ATAPI_MECH_STATUS, 0, 0, 0, 0, 0, 0, 0,
sizeof(struct changer)>>8, sizeof(struct changer),
0, 0, 0, 0, 0, 0 };
@@ -128,11 +134,10 @@ acdattach(struct ata_device *atadev)
if (chp == NULL) {
ata_prtdev(atadev, "out of memory\n");
free(cdp, M_ACD);
- return 0;
+ return;
}
- if (!atapi_queue_cmd(cdp->device, ccb, (caddr_t)chp,
- sizeof(struct changer),
- ATPR_F_READ, 60, NULL, NULL)) {
+ if (!ata_atapicmd(cdp->device, ccb, (caddr_t)chp,
+ sizeof(struct changer), ATA_R_READ, 60)) {
struct acd_softc *tmpcdp = cdp;
struct acd_softc **cdparr;
char *name;
@@ -144,7 +149,7 @@ acdattach(struct ata_device *atadev)
ata_prtdev(atadev, "out of memory\n");
free(chp, M_ACD);
free(cdp, M_ACD);
- return 0;
+ return;
}
for (count = 0; count < chp->slots; count++) {
if (count > 0) {
@@ -167,7 +172,7 @@ acdattach(struct ata_device *atadev)
if (!(name = malloc(strlen(atadev->name) + 2, M_ACD, M_NOWAIT))) {
ata_prtdev(atadev, "out of memory\n");
free(cdp, M_ACD);
- return 0;
+ return;
}
strcpy(name, atadev->name);
strcat(name, "-");
@@ -183,15 +188,27 @@ acdattach(struct ata_device *atadev)
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
DEVSTAT_PRIORITY_CD);
}
+
+ /* use DMA if allowed and if drive/controller supports it */
+ if (atapi_dma && atadev->channel->dma &&
+ (atadev->param->config & ATA_DRQ_MASK) != ATA_DRQ_INTR)
+ atadev->setmode(atadev, ATA_DMA_MAX);
+ else
+ atadev->setmode(atadev, ATA_PIO_MAX);
+
+ /* setup the function ptrs */
+ atadev->detach = acd_detach;
+ atadev->start = acd_start;
+ atadev->softc = cdp;
+
+ /* announce we are here */
acd_describe(cdp);
- atadev->driver = cdp;
- return 1;
}
-void
-acddetach(struct ata_device *atadev)
+static void
+acd_detach(struct ata_device *atadev)
{
- struct acd_softc *cdp = atadev->driver;
+ struct acd_softc *cdp = atadev->softc;
struct acd_devlist *entry;
int subdev;
@@ -199,7 +216,9 @@ acddetach(struct ata_device *atadev)
for (subdev = 0; subdev < cdp->changer_info->slots; subdev++) {
if (cdp->driver[subdev] == cdp)
continue;
+ mtx_lock(&cdp->driver[subdev]->queue_mtx);
bioq_flush(&cdp->driver[subdev]->queue, NULL, ENXIO);
+ mtx_unlock(&cdp->driver[subdev]->queue_mtx);
destroy_dev(cdp->driver[subdev]->dev);
while ((entry = TAILQ_FIRST(&cdp->driver[subdev]->dev_list))) {
destroy_dev(entry->dev);
@@ -213,7 +232,9 @@ acddetach(struct ata_device *atadev)
free(cdp->driver, M_ACD);
free(cdp->changer_info, M_ACD);
}
+ mtx_lock(&cdp->queue_mtx);
bioq_flush(&cdp->queue, NULL, ENXIO);
+ mtx_unlock(&cdp->queue_mtx);
while ((entry = TAILQ_FIRST(&cdp->dev_list))) {
destroy_dev(entry->dev);
TAILQ_REMOVE(&cdp->dev_list, entry, chain);
@@ -222,10 +243,15 @@ acddetach(struct ata_device *atadev)
destroy_dev(cdp->dev);
EVENTHANDLER_DEREGISTER(dev_clone, cdp->clone_evh);
devstat_remove_entry(cdp->stats);
+ ata_prtdev(atadev, "WARNING - removed from configuration\n");
ata_free_name(atadev);
ata_free_lun(&acd_lun_map, cdp->lun);
+ atadev->attach = NULL;
+ atadev->detach = NULL;
+ atadev->start = NULL;
+ atadev->softc = NULL;
+ atadev->flags = 0;
free(cdp, M_ACD);
- atadev->driver = NULL;
}
static struct acd_softc *
@@ -237,6 +263,7 @@ acd_init_lun(struct ata_device *atadev)
return NULL;
TAILQ_INIT(&cdp->dev_list);
bioq_init(&cdp->queue);
+ mtx_init(&cdp->queue_mtx, "ATAPI CD bioqueue lock", MTX_DEF, 0);
cdp->device = atadev;
cdp->lun = ata_get_lun(&acd_lun_map);
cdp->block_size = 2048;
@@ -279,7 +306,12 @@ acd_make_dev(struct acd_softc *cdp)
static void
acd_set_ioparm(struct acd_softc *cdp)
{
- cdp->dev->si_iosize_max = ((256*DEV_BSIZE)/cdp->block_size)*cdp->block_size;
+ if (cdp->device->channel->dma)
+ cdp->dev->si_iosize_max = (min(cdp->device->channel->dma->max_iosize,
+ 65534)/cdp->block_size)*cdp->block_size;
+ else
+ cdp->dev->si_iosize_max = (min(DFLTPHYS,
+ 65534)/cdp->block_size)*cdp->block_size;
cdp->dev->si_bsize_phys = cdp->block_size;
}
@@ -292,11 +324,11 @@ acd_describe(struct acd_softc *cdp)
if (bootverbose) {
ata_prtdev(cdp->device, "<%.40s/%.8s> %s drive at ata%d as %s\n",
cdp->device->param->model, cdp->device->param->revision,
- (cdp->cap.write_dvdr) ? "DVD-R" :
- (cdp->cap.write_dvdram) ? "DVD-RAM" :
- (cdp->cap.write_cdrw) ? "CD-RW" :
- (cdp->cap.write_cdr) ? "CD-R" :
- (cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM",
+ (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" :
+ (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" :
+ (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" :
+ (cdp->cap.media & MST_WRITE_CDR) ? "CDR" :
+ (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM" : "CDROM",
device_get_unit(cdp->device->channel->dev),
(cdp->device->unit == ATA_MASTER) ? "master" : "slave");
@@ -306,8 +338,8 @@ acd_describe(struct acd_softc *cdp)
if (cdp->cap.max_read_speed)
printf(" (%dKB/s)", cdp->cap.max_read_speed * 1000 / 1024);
if ((cdp->cap.cur_write_speed) &&
- (cdp->cap.write_cdr || cdp->cap.write_cdrw ||
- cdp->cap.write_dvdr || cdp->cap.write_dvdram)) {
+ (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW |
+ MST_WRITE_DVDR | MST_WRITE_DVDRAM))) {
printf(" write %dKB/s", cdp->cap.cur_write_speed * 1000 / 1024);
if (cdp->cap.max_write_speed)
printf(" (%dKB/s)", cdp->cap.max_write_speed * 1000 / 1024);
@@ -322,65 +354,65 @@ acd_describe(struct acd_softc *cdp)
ata_prtdev(cdp->device, "Reads:");
comma = 0;
- if (cdp->cap.read_cdr) {
- printf(" CD-R"); comma = 1;
+ if (cdp->cap.media & MST_READ_CDR) {
+ printf(" CDR"); comma = 1;
}
- if (cdp->cap.read_cdrw) {
- printf("%s CD-RW", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_READ_CDRW) {
+ printf("%s CDRW", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.cd_da) {
- if (cdp->cap.cd_da_stream)
- printf("%s CD-DA stream", comma ? "," : "");
+ if (cdp->cap.capabilities & MST_READ_CDDA) {
+ if (cdp->cap.capabilities & MST_CDDA_STREAM)
+ printf("%s CDDA stream", comma ? "," : "");
else
- printf("%s CD-DA", comma ? "," : "");
+ printf("%s CDDA", comma ? "," : "");
comma = 1;
}
- if (cdp->cap.read_dvdrom) {
- printf("%s DVD-ROM", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_READ_DVDROM) {
+ printf("%s DVDROM", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.read_dvdr) {
- printf("%s DVD-R", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_READ_DVDR) {
+ printf("%s DVDR", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.read_dvdram) {
- printf("%s DVD-RAM", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_READ_DVDRAM) {
+ printf("%s DVDRAM", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.read_packet)
+ if (cdp->cap.media & MST_READ_PACKET)
printf("%s packet", comma ? "," : "");
printf("\n");
ata_prtdev(cdp->device, "Writes:");
- if (cdp->cap.write_cdr || cdp->cap.write_cdrw ||
- cdp->cap.write_dvdr || cdp->cap.write_dvdram) {
+ if (cdp->cap.media & (MST_WRITE_CDR | MST_WRITE_CDRW |
+ MST_WRITE_DVDR | MST_WRITE_DVDRAM)) {
comma = 0;
- if (cdp->cap.write_cdr) {
- printf(" CD-R" ); comma = 1;
+ if (cdp->cap.media & MST_WRITE_CDR) {
+ printf(" CDR" ); comma = 1;
}
- if (cdp->cap.write_cdrw) {
- printf("%s CD-RW", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_WRITE_CDRW) {
+ printf("%s CDRW", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.write_dvdr) {
- printf("%s DVD-R", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_WRITE_DVDR) {
+ printf("%s DVDR", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.write_dvdram) {
- printf("%s DVD-RAM", comma ? "," : ""); comma = 1;
+ if (cdp->cap.media & MST_WRITE_DVDRAM) {
+ printf("%s DVDRAM", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.test_write) {
+ if (cdp->cap.media & MST_WRITE_TEST) {
printf("%s test write", comma ? "," : ""); comma = 1;
}
- if (cdp->cap.burnproof)
+ if (cdp->cap.capabilities & MST_BURNPROOF)
printf("%s burnproof", comma ? "," : "");
}
printf("\n");
- if (cdp->cap.audio_play) {
+ if (cdp->cap.capabilities & MST_AUDIO_PLAY) {
ata_prtdev(cdp->device, "Audio: ");
- if (cdp->cap.audio_play)
+ if (cdp->cap.capabilities & MST_AUDIO_PLAY)
printf("play");
if (cdp->cap.max_vol_levels)
printf(", %d volume levels", cdp->cap.max_vol_levels);
printf("\n");
}
ata_prtdev(cdp->device, "Mechanism: ");
- switch (cdp->cap.mech) {
+ switch (cdp->cap.mechanism & MST_MECH_MASK) {
case MST_MECH_CADDY:
mechanism = "caddy"; break;
case MST_MECH_TRAY:
@@ -395,17 +427,18 @@ acd_describe(struct acd_softc *cdp)
mechanism = 0; break;
}
if (mechanism)
- printf("%s%s", cdp->cap.eject ? "ejectable " : "", mechanism);
- else if (cdp->cap.eject)
+ printf("%s%s", (cdp->cap.mechanism & MST_EJECT) ?
+ "ejectable " : "", mechanism);
+ else if (cdp->cap.mechanism & MST_EJECT)
printf("ejectable");
- if (cdp->cap.lock)
- printf(cdp->cap.locked ? ", locked" : ", unlocked");
- if (cdp->cap.prevent)
+ if (cdp->cap.mechanism & MST_LOCKABLE)
+ printf((cdp->cap.mechanism & MST_LOCKED) ? ", locked":", unlocked");
+ if (cdp->cap.mechanism & MST_PREVENT)
printf(", lock protected");
printf("\n");
- if (cdp->cap.mech != MST_MECH_CHANGER) {
+ if ((cdp->cap.mechanism & MST_MECH_MASK) != MST_MECH_CHANGER) {
ata_prtdev(cdp->device, "Medium: ");
switch (cdp->cap.medium_type & MST_TYPE_MASK_HIGH) {
case MST_CDROM:
@@ -457,15 +490,13 @@ acd_describe(struct acd_softc *cdp)
}
else {
ata_prtdev(cdp->device, "%s ",
- (cdp->cap.write_dvdr) ? "DVD-R" :
- (cdp->cap.write_dvdram) ? "DVD-RAM" :
- (cdp->cap.write_cdrw) ? "CD-RW" :
- (cdp->cap.write_cdr) ? "CD-R" :
- (cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM");
-
+ (cdp->cap.media & MST_WRITE_DVDR) ? "DVDR" :
+ (cdp->cap.media & MST_WRITE_DVDRAM) ? "DVDRAM" :
+ (cdp->cap.media & MST_WRITE_CDRW) ? "CDRW" :
+ (cdp->cap.media & MST_WRITE_CDR) ? "CDR" :
+ (cdp->cap.media & MST_READ_DVDROM) ? "DVDROM" : "CDROM");
if (cdp->changer_info)
printf("with %d CD changer ", cdp->changer_info->slots);
-
printf("<%.40s> at ata%d-%s %s\n", cdp->device->param->model,
device_get_unit(cdp->device->channel->dev),
(cdp->device->unit == ATA_MASTER) ? "master" : "slave",
@@ -491,26 +522,26 @@ msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
}
static int
-acdopen(dev_t dev, int flags, int fmt, struct thread *td)
+acd_open(dev_t dev, int flags, int fmt, struct thread *td)
{
struct acd_softc *cdp = dev->si_drv1;
int timeout = 60;
- if (!cdp)
+ if (!cdp || cdp->device->flags & ATA_D_DETACHING)
return ENXIO;
/* wait if drive is not finished loading the medium */
while (timeout--) {
- struct atapi_reqsense *sense = cdp->device->result;
+ struct atapi_sense sense;
- if (!atapi_test_ready(cdp->device))
+ if (!acd_test_ready(cdp->device))
break;
- if (sense->sense_key == 2 && sense->asc == 4 && sense->ascq == 1)
+ acd_request_sense(cdp->device, &sense);
+ if (sense.sense_key == 2 && sense.asc == 4 && sense.ascq == 1)
tsleep(&timeout, PRIBIO, "acdld", hz / 2);
else
break;
}
-
if (count_dev(dev) == 1) {
if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
acd_select_slot(cdp);
@@ -524,7 +555,7 @@ acdopen(dev_t dev, int flags, int fmt, struct thread *td)
}
static int
-acdclose(dev_t dev, int flags, int fmt, struct thread *td)
+acd_close(dev_t dev, int flags, int fmt, struct thread *td)
{
struct acd_softc *cdp = dev->si_drv1;
@@ -543,7 +574,7 @@ acdclose(dev_t dev, int flags, int fmt, struct thread *td)
}
static int
-acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
+acd_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
struct acd_softc *cdp = dev->si_drv1;
int error = 0;
@@ -558,7 +589,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
if (cdp->device->flags & ATA_D_MEDIA_CHANGED)
switch (cmd) {
case CDIOCRESET:
- atapi_test_ready(cdp->device);
+ acd_test_ready(cdp->device);
break;
default:
@@ -599,7 +630,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
error = suser(td);
if (error)
break;
- error = atapi_test_ready(cdp->device);
+ error = acd_test_ready(cdp->device);
break;
case CDIOCEJECT:
@@ -749,9 +780,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
ccb[1] = args->address_format & CD_MSF_FORMAT;
- if ((error = atapi_queue_cmd(cdp->device,ccb,(caddr_t)&cdp->subchan,
- sizeof(cdp->subchan), ATPR_F_READ, 10,
- NULL, NULL)))
+ if ((error = ata_atapicmd(cdp->device,ccb,(caddr_t)&cdp->subchan,
+ sizeof(cdp->subchan), ATA_R_READ, 10)))
break;
if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) {
@@ -764,10 +794,9 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
if (format == CD_TRACK_INFO)
ccb[6] = args->track;
- if ((error = atapi_queue_cmd(cdp->device, ccb,
- (caddr_t)&cdp->subchan,
- sizeof(cdp->subchan), ATPR_F_READ,
- 10, NULL, NULL))) {
+ if ((error = ata_atapicmd(cdp->device, ccb,
+ (caddr_t)&cdp->subchan,
+ sizeof(cdp->subchan),ATA_R_READ,10))){
break;
}
}
@@ -819,79 +848,6 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
break;
}
- case CDIOCREADAUDIO:
- {
- struct ioc_read_audio *args = (struct ioc_read_audio *)addr;
- int32_t lba;
- caddr_t buffer, ubuf = args->buffer;
- int8_t ccb[16];
- int frames;
-
- if (!cdp->toc.hdr.ending_track) {
- error = EIO;
- break;
- }
-
- if ((frames = args->nframes) < 0) {
- error = EINVAL;
- break;
- }
-
- if (args->address_format == CD_LBA_FORMAT)
- lba = args->address.lba;
- else if (args->address_format == CD_MSF_FORMAT)
- lba = msf2lba(args->address.msf.minute,
- args->address.msf.second,
- args->address.msf.frame);
- else {
- error = EINVAL;
- break;
- }
-
-#ifndef CD_BUFFER_BLOCKS
-#define CD_BUFFER_BLOCKS 13
-#endif
- if (!(buffer = malloc(CD_BUFFER_BLOCKS * 2352, M_ACD, M_NOWAIT))){
- error = ENOMEM;
- break;
- }
- bzero(ccb, sizeof(ccb));
- while (frames > 0) {
- int8_t blocks;
- int size;
-
- blocks = (frames>CD_BUFFER_BLOCKS) ? CD_BUFFER_BLOCKS : frames;
- size = blocks * 2352;
-
- ccb[0] = ATAPI_READ_CD;
- ccb[1] = 4;
- ccb[2] = lba>>24;
- ccb[3] = lba>>16;
- ccb[4] = lba>>8;
- ccb[5] = lba;
- ccb[8] = blocks;
- ccb[9] = 0xf0;
- if ((error = atapi_queue_cmd(cdp->device, ccb, buffer, size,
- ATPR_F_READ, 30, NULL,NULL)))
- break;
-
- if ((error = copyout(buffer, ubuf, size)))
- break;
-
- ubuf += size;
- frames -= blocks;
- lba += blocks;
- }
- free(buffer, M_ACD);
- if (args->address_format == CD_LBA_FORMAT)
- args->address.lba = lba;
- else if (args->address_format == CD_MSF_FORMAT)
- lba2msf(lba, &args->address.msf.minute,
- &args->address.msf.second,
- &args->address.msf.frame);
- break;
- }
-
case CDIOCGETVOL:
{
struct ioc_vol *arg = (struct ioc_vol *)addr;
@@ -1047,24 +1003,24 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
break;
case DVDIOCREPORTKEY:
- if (!cdp->cap.read_dvdrom)
- error = EINVAL;
- else
+ if (cdp->cap.media & MST_READ_DVDROM)
error = acd_report_key(cdp, (struct dvd_authinfo *)addr);
+ else
+ error = EINVAL;
break;
case DVDIOCSENDKEY:
- if (!cdp->cap.read_dvdrom)
- error = EINVAL;
- else
+ if (cdp->cap.media & MST_READ_DVDROM)
error = acd_send_key(cdp, (struct dvd_authinfo *)addr);
+ else
+ error = EINVAL;
break;
case DVDIOCREADSTRUCTURE:
- if (!cdp->cap.read_dvdrom)
- error = EINVAL;
- else
+ if (cdp->cap.media & MST_READ_DVDROM)
error = acd_read_structure(cdp, (struct dvd_struct *)addr);
+ else
+ error = EINVAL;
break;
default:
@@ -1074,10 +1030,9 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
}
static void
-acdstrategy(struct bio *bp)
+acd_strategy(struct bio *bp)
{
struct acd_softc *cdp = bp->bio_dev->si_drv1;
- int s;
if (cdp->device->flags & ATA_D_DETACHING) {
biofinish(bp, NULL, ENXIO);
@@ -1094,17 +1049,18 @@ acdstrategy(struct bio *bp)
bp->bio_pblkno = bp->bio_blkno;
bp->bio_resid = bp->bio_bcount;
- s = splbio();
+ mtx_lock(&cdp->queue_mtx);
bioq_disksort(&cdp->queue, bp);
- splx(s);
+ mtx_unlock(&cdp->queue_mtx);
ata_start(cdp->device->channel);
}
-void
+static void
acd_start(struct ata_device *atadev)
{
- struct acd_softc *cdp = atadev->driver;
- struct bio *bp = bioq_first(&cdp->queue);
+ struct acd_softc *cdp = atadev->softc;
+ struct bio *bp;
+ struct ata_request *request;
u_int32_t lba, lastlba, count;
int8_t ccb[16];
int track, blocksize;
@@ -1113,23 +1069,34 @@ acd_start(struct ata_device *atadev)
int i;
cdp = cdp->driver[cdp->changer_info->current_slot];
+ mtx_lock(&cdp->queue_mtx);
bp = bioq_first(&cdp->queue);
+ mtx_unlock(&cdp->queue_mtx);
/* check for work pending on any other slot */
for (i = 0; i < cdp->changer_info->slots; i++) {
if (i == cdp->changer_info->current_slot)
continue;
+ mtx_lock(&cdp->queue_mtx);
if (bioq_first(&(cdp->driver[i]->queue))) {
if (!bp || time_second > (cdp->timestamp + 10)) {
+ mtx_unlock(&cdp->queue_mtx);
acd_select_slot(cdp->driver[i]);
return;
}
}
+ mtx_unlock(&cdp->queue_mtx);
+
}
}
- if (!bp)
+ mtx_lock(&cdp->queue_mtx);
+ bp = bioq_first(&cdp->queue);
+ if (!bp) {
+ mtx_unlock(&cdp->queue_mtx);
return;
+ }
bioq_remove(&cdp->queue, bp);
+ mtx_unlock(&cdp->queue_mtx);
/* reject all queued entries if media changed */
if (cdp->device->flags & ATA_D_MEDIA_CHANGED) {
@@ -1197,27 +1164,54 @@ acd_start(struct ata_device *atadev)
ccb[7] = count>>8;
ccb[8] = count;
- devstat_start_transaction_bio(cdp->stats, bp);
bp->bio_caller1 = cdp;
- atapi_queue_cmd(cdp->device, ccb, bp->bio_data, count * blocksize,
- bp->bio_cmd == BIO_READ ? ATPR_F_READ : 0,
- (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30, acd_done, bp);
+ if (!(request = ata_alloc_request())) {
+ biofinish(bp, NULL, EIO);
+ return;
+ }
+ request->device = atadev;
+ request->driver = bp;
+ bcopy(ccb, request->u.atapi.ccb,
+ (request->device->param->config & ATA_PROTO_MASK) ==
+ ATA_PROTO_ATAPI_12 ? 16 : 12);
+ request->data = bp->bio_data;
+ request->bytecount = count * blocksize;
+ request->transfersize = min(request->bytecount, 65534);
+ request->timeout = (ccb[0] == ATAPI_WRITE_BIG) ? 60 : 30;
+ request->retries = 2;
+ request->callback = acd_done;
+ request->flags = ATA_R_SKIPSTART | ATA_R_ATAPI;
+ if (request->device->mode >= ATA_DMA)
+ request->flags |= ATA_R_DMA;
+ switch (bp->bio_cmd) {
+ case BIO_READ:
+ request->flags |= ATA_R_READ;
+ break;
+ case BIO_WRITE:
+ request->flags |= ATA_R_WRITE;
+ break;
+ default:
+ ata_prtdev(atadev, "unknown BIO operation\n");
+ ata_free_request(request);
+ biofinish(bp, NULL, EIO);
+ return;
+ }
+ devstat_start_transaction_bio(cdp->stats, bp);
+ ata_queue_request(request);
}
-static int
-acd_done(struct atapi_request *request)
+static void
+acd_done(struct ata_request *request)
{
struct bio *bp = request->driver;
struct acd_softc *cdp = bp->bio_caller1;
- if (request->error) {
- bp->bio_error = request->error;
+ /* finish up transfer */
+ if ((bp->bio_error = request->result))
bp->bio_flags |= BIO_ERROR;
- }
- else
- bp->bio_resid = bp->bio_bcount - request->donecount;
+ bp->bio_resid = bp->bio_bcount - request->donecount;
biofinish(bp, cdp->stats, 0);
- return 0;
+ ata_free_request(request);
}
static void
@@ -1231,7 +1225,7 @@ acd_read_toc(struct acd_softc *cdp)
bzero(&cdp->toc, sizeof(cdp->toc));
bzero(ccb, sizeof(ccb));
- if (atapi_test_ready(cdp->device) != 0)
+ if (acd_test_ready(cdp->device) != 0)
return;
cdp->device->flags &= ~ATA_D_MEDIA_CHANGED;
@@ -1240,8 +1234,8 @@ acd_read_toc(struct acd_softc *cdp)
ccb[0] = ATAPI_READ_TOC;
ccb[7] = len>>8;
ccb[8] = len;
- if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
- ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
+ if (ata_atapicmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
+ ATA_R_READ | ATA_R_QUIET, 30)) {
bzero(&cdp->toc, sizeof(cdp->toc));
return;
}
@@ -1256,8 +1250,8 @@ acd_read_toc(struct acd_softc *cdp)
ccb[0] = ATAPI_READ_TOC;
ccb[7] = len>>8;
ccb[8] = len;
- if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
- ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
+ if (ata_atapicmd(cdp->device, ccb, (caddr_t)&cdp->toc, len,
+ ATA_R_READ | ATA_R_QUIET, 30)) {
bzero(&cdp->toc, sizeof(cdp->toc));
return;
}
@@ -1267,8 +1261,8 @@ acd_read_toc(struct acd_softc *cdp)
acd_set_ioparm(cdp);
bzero(ccb, sizeof(ccb));
ccb[0] = ATAPI_READ_CAPACITY;
- if (atapi_queue_cmd(cdp->device, ccb, (caddr_t)sizes, sizeof(sizes),
- ATPR_F_READ | ATPR_F_QUIET, 30, NULL, NULL)) {
+ if (ata_atapicmd(cdp->device, ccb, (caddr_t)sizes, sizeof(sizes),
+ ATA_R_READ | ATA_R_QUIET, 30)) {
bzero(&cdp->toc, sizeof(cdp->toc));
return;
}
@@ -1313,7 +1307,7 @@ acd_play(struct acd_softc *cdp, int start, int end)
ccb[0] = ATAPI_PLAY_MSF;
lba2msf(start, &ccb[3], &ccb[4], &ccb[5]);
lba2msf(end, &ccb[6], &ccb[7], &ccb[8]);
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 10, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 10);
}
static int
@@ -1335,39 +1329,52 @@ acd_setchan(struct acd_softc *cdp,
return acd_mode_select(cdp, (caddr_t)&cdp->au, sizeof(cdp->au));
}
-static int
-acd_select_done1(struct atapi_request *request)
+static void
+acd_load_done(struct ata_request *request)
{
struct acd_softc *cdp = request->driver;
+ /* finish the slot select and wakeup caller */
cdp->changer_info->current_slot = cdp->slot;
cdp->driver[cdp->changer_info->current_slot]->timestamp = time_second;
wakeup(&cdp->changer_info);
- return 0;
}
-static int
-acd_select_done(struct atapi_request *request)
+static void
+acd_unload_done(struct ata_request *request)
{
struct acd_softc *cdp = request->driver;
int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 3, 0, 0, 0,
cdp->slot, 0, 0, 0, 0, 0, 0, 0 };
/* load the wanted slot */
- atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30,
- acd_select_done1, cdp);
- return 0;
+ bcopy(ccb, request->u.atapi.ccb,
+ (request->device->param->config & ATA_PROTO_MASK) ==
+ ATA_PROTO_ATAPI_12 ? 16 : 12);
+ request->callback = acd_load_done;
+ ata_queue_request(request);
}
static void
acd_select_slot(struct acd_softc *cdp)
{
+ struct ata_request *request;
int8_t ccb[16] = { ATAPI_LOAD_UNLOAD, 0, 0, 0, 2, 0, 0, 0,
cdp->changer_info->current_slot, 0, 0, 0, 0, 0, 0, 0 };
/* unload the current media from player */
- atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_AT_HEAD, 30,
- acd_select_done, cdp);
+ if (!(request = ata_alloc_request())) {
+ return;
+ }
+ request->device = cdp->device;
+ request->driver = cdp;
+ bcopy(ccb, request->u.atapi.ccb,
+ (request->device->param->config & ATA_PROTO_MASK) ==
+ ATA_PROTO_ATAPI_12 ? 16 : 12);
+ request->timeout = 30;
+ request->callback = acd_unload_done;
+ request->flags |= (ATA_R_ATAPI | ATA_R_AT_HEAD);
+ ata_queue_request(request);
}
static int
@@ -1377,10 +1384,10 @@ acd_init_writer(struct acd_softc *cdp, int test_write)
bzero(ccb, sizeof(ccb));
ccb[0] = ATAPI_REZERO;
- atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL);
+ ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 60);
ccb[0] = ATAPI_SEND_OPC_INFO;
ccb[1] = 0x01;
- atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL);
+ ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 30);
return 0;
}
@@ -1406,19 +1413,19 @@ acd_fixate(struct acd_softc *cdp, int multisession)
if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
return error;
- error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
if (error)
return error;
/* some drives just return ready, wait for the expected fixate time */
- if ((error = atapi_test_ready(cdp->device)) != EBUSY) {
+ if ((error = acd_test_ready(cdp->device)) != EBUSY) {
timeout = timeout / (cdp->cap.cur_write_speed / 177);
tsleep(&error, PRIBIO, "acdfix", timeout * hz / 2);
- return atapi_test_ready(cdp->device);
+ return acd_test_ready(cdp->device);
}
while (timeout-- > 0) {
- if ((error = atapi_test_ready(cdp->device)) != EBUSY)
+ if ((error = acd_test_ready(cdp->device)) != EBUSY)
return error;
tsleep(&error, PRIBIO, "acdcld", hz/2);
}
@@ -1444,7 +1451,7 @@ acd_init_track(struct acd_softc *cdp, struct cdr_track *track)
param.fp = 0;
param.packet_size = 0;
- if (cdp->cap.burnproof)
+ if (cdp->cap.capabilities & MST_BURNPROOF)
param.burnproof = 1;
switch (track->datablock_type) {
@@ -1511,8 +1518,7 @@ acd_flush(struct acd_softc *cdp)
int8_t ccb[16] = { ATAPI_SYNCHRONIZE_CACHE, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, ATPR_F_QUIET, 60,
- NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, ATA_R_QUIET, 60);
}
static int
@@ -1526,8 +1532,8 @@ acd_read_track_info(struct acd_softc *cdp,
0, 0, 0, 0, 0, 0, 0 };
int error;
- if ((error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)info, sizeof(*info),
- ATPR_F_READ, 30, NULL, NULL)))
+ if ((error = ata_atapicmd(cdp->device, ccb, (caddr_t)info, sizeof(*info),
+ ATA_R_READ, 30)))
return error;
info->track_start_addr = ntohl(info->track_start_addr);
info->next_writeable_addr = ntohl(info->next_writeable_addr);
@@ -1542,16 +1548,14 @@ acd_get_progress(struct acd_softc *cdp, int *finished)
{
int8_t ccb[16] = { ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- struct atapi_reqsense *sense = cdp->device->result;
+ struct atapi_sense sense;
int8_t dummy[8];
- if (atapi_queue_cmd(cdp->device, ccb, dummy, sizeof(dummy),
- ATPR_F_READ, 30, NULL, NULL) != EBUSY) {
- *finished = 100;
- return 0;
- }
- if (sense->sksv)
- *finished = ((sense->sk_specific2|(sense->sk_specific1<<8))*100)/65535;
+ ata_atapicmd(cdp->device, ccb, dummy, sizeof(dummy), ATA_R_READ, 30);
+ acd_request_sense(cdp->device, &sense);
+
+ if (sense.sksv)
+ *finished = ((sense.sk_specific2|(sense.sk_specific1<<8))*100)/65535;
else
*finished = 0;
return 0;
@@ -1585,7 +1589,7 @@ acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet)
param.track_mode = CDR_TMODE_AUDIO;
param.datablock_type = CDR_DB_RAW;
param.session_format = cuesheet->session_format;
- if (cdp->cap.burnproof)
+ if (cdp->cap.capabilities & MST_BURNPROOF)
param.burnproof = 1;
if ((error = acd_mode_select(cdp, (caddr_t)&param, param.page_length + 10)))
@@ -1604,8 +1608,7 @@ acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet)
printf("\n%02x", buffer[i]);
printf("\n");
#endif
- error = atapi_queue_cmd(cdp->device, ccb, buffer, cuesheet->len, 0,
- 30, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, buffer, cuesheet->len, 0, 30);
}
free(buffer, M_ACD);
return error;
@@ -1656,9 +1659,8 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
d->length = htons(length - 2);
- error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length,
- ai->format == DVD_INVALIDATE_AGID ? 0 : ATPR_F_READ,
- 10, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length,
+ ai->format == DVD_INVALIDATE_AGID ? 0 : ATA_R_READ,10);
if (error) {
free(d, M_ACD);
return error;
@@ -1743,8 +1745,7 @@ acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
ccb[9] = length & 0xff;
ccb[10] = (ai->agid << 6) | ai->format;
d->length = htons(length - 2);
- error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, 0,
- 10, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length, 0, 10);
free(d, M_ACD);
return error;
}
@@ -1802,8 +1803,7 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
ccb[8] = (length >> 8) & 0xff;
ccb[9] = length & 0xff;
ccb[10] = s->agid << 6;
- error = atapi_queue_cmd(cdp->device, ccb, (caddr_t)d, length, ATPR_F_READ,
- 30, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, (caddr_t)d, length, ATA_R_READ, 30);
if (error) {
free(d, M_ACD);
return error;
@@ -1887,7 +1887,7 @@ acd_blank(struct acd_softc *cdp, int blanktype)
0, 0, 0, 0, 0, 0, 0, 0 };
cdp->device->flags |= ATA_D_MEDIA_CHANGED;
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
}
static int
@@ -1896,7 +1896,7 @@ acd_prevent_allow(struct acd_softc *cdp, int lock)
int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
}
static int
@@ -1905,7 +1905,7 @@ acd_start_stop(struct acd_softc *cdp, int start)
int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
}
static int
@@ -1914,7 +1914,7 @@ acd_pause_resume(struct acd_softc *cdp, int pause)
int8_t ccb[16] = { ATAPI_PAUSE, 0, 0, 0, 0, 0, 0, 0, pause,
0, 0, 0, 0, 0, 0, 0 };
- return atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
}
static int
@@ -1924,8 +1924,7 @@ acd_mode_sense(struct acd_softc *cdp, int page, caddr_t pagebuf, int pagesize)
pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 };
int error;
- error = atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, ATPR_F_READ,
- 10, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, pagebuf, pagesize, ATA_R_READ, 10);
#ifdef ACD_DEBUG
atapi_dump("acd: mode sense ", pagebuf, pagesize);
#endif
@@ -1943,8 +1942,7 @@ acd_mode_select(struct acd_softc *cdp, caddr_t pagebuf, int pagesize)
"modeselect pagesize=%d\n", pagesize);
atapi_dump("mode select ", pagebuf, pagesize);
#endif
- return atapi_queue_cmd(cdp->device, ccb, pagebuf, pagesize, 0,
- 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, pagebuf, pagesize, 0, 30);
}
static int
@@ -1954,7 +1952,7 @@ acd_set_speed(struct acd_softc *cdp, int rdspeed, int wrspeed)
wrspeed >> 8, wrspeed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int error;
- error = atapi_queue_cmd(cdp->device, ccb, NULL, 0, 0, 30, NULL, NULL);
+ error = ata_atapicmd(cdp->device, ccb, NULL, 0, 0, 30);
if (!error)
acd_get_cap(cdp);
return error;
@@ -1963,18 +1961,21 @@ acd_set_speed(struct acd_softc *cdp, int rdspeed, int wrspeed)
static void
acd_get_cap(struct acd_softc *cdp)
{
- int retry = 5;
-
- /* get drive capabilities, some drives needs this repeated */
- while (retry-- && acd_mode_sense(cdp, ATAPI_CDROM_CAP_PAGE,
- (caddr_t)&cdp->cap, sizeof(cdp->cap)))
-
- cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed);
- cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed);
- cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed);
- cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed), 177);
- cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels);
- cdp->cap.buf_size = ntohs(cdp->cap.buf_size);
+ int count;
+
+ /* get drive capabilities, some bugridden drives needs this repeated */
+ for (count = 0 ; count < 5 ; count++) {
+ if (!acd_mode_sense(cdp, ATAPI_CDROM_CAP_PAGE,
+ (caddr_t)&cdp->cap, sizeof(cdp->cap)) &&
+ cdp->cap.page_code == ATAPI_CDROM_CAP_PAGE) {
+ cdp->cap.max_read_speed = ntohs(cdp->cap.max_read_speed);
+ cdp->cap.cur_read_speed = ntohs(cdp->cap.cur_read_speed);
+ cdp->cap.max_write_speed = ntohs(cdp->cap.max_write_speed);
+ cdp->cap.cur_write_speed = max(ntohs(cdp->cap.cur_write_speed),177);
+ cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels);
+ cdp->cap.buf_size = ntohs(cdp->cap.buf_size);
+ }
+ }
}
static int
@@ -1985,9 +1986,8 @@ acd_read_format_caps(struct acd_softc *cdp, struct cdr_format_capacities *caps)
sizeof(struct cdr_format_capacities) & 0xff,
0, 0, 0, 0, 0, 0, 0 };
- return atapi_queue_cmd(cdp->device, ccb, (caddr_t)caps,
- sizeof(struct cdr_format_capacities),
- ATPR_F_READ, 30, NULL, NULL);
+ return ata_atapicmd(cdp->device, ccb, (caddr_t)caps,
+ sizeof(struct cdr_format_capacities), ATA_R_READ, 30);
}
static int
@@ -1997,8 +1997,26 @@ acd_format(struct acd_softc *cdp, struct cdr_format_params* params)
int8_t ccb[16] = { ATAPI_FORMAT, 0x11, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 };
- error = atapi_queue_cmd(cdp->device, ccb, (u_int8_t *)params,
- sizeof(struct cdr_format_params), 0, 30, NULL,NULL);
-
+ error = ata_atapicmd(cdp->device, ccb, (u_int8_t *)params,
+ sizeof(struct cdr_format_params), 0, 30);
return error;
}
+
+static int
+acd_test_ready(struct ata_device *atadev)
+{
+ int8_t ccb[16] = { ATAPI_TEST_UNIT_READY, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ return ata_atapicmd(atadev, ccb, NULL, 0, 0, 30);
+}
+
+static int
+acd_request_sense(struct ata_device *atadev, struct atapi_sense *sense)
+{
+ int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0, sizeof(struct atapi_sense),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ return ata_atapicmd(atadev, ccb, (caddr_t)sense,
+ sizeof(struct atapi_sense), ATA_R_READ, 30);
+}
OpenPOWER on IntegriCloud