summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2000-12-26 11:55:44 +0000
committersos <sos@FreeBSD.org>2000-12-26 11:55:44 +0000
commitd65168d03ee4827064914b90fabefe9f404ec66a (patch)
treea8c4847e0f266ef15e7ce484b096d005151909b0 /sys
parent8db92e907c9eaa60ee1aa5df18a50494f78258b4 (diff)
downloadFreeBSD-src-d65168d03ee4827064914b90fabefe9f404ec66a.zip
FreeBSD-src-d65168d03ee4827064914b90fabefe9f404ec66a.tar.gz
Update the burncd interface a bit, dont block the ATA channel on
blank & fixate commands and provide a progress interface for the blank command (for now)
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/atapi-all.c17
-rw-r--r--sys/dev/ata/atapi-all.h5
-rw-r--r--sys/dev/ata/atapi-cd.c96
3 files changed, 70 insertions, 48 deletions
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index d15d893..abb4771 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -273,7 +273,7 @@ atapi_transfer(struct atapi_request *request)
request->timeout_handle = timeout((timeout_t *)atapi_timeout,
request, request->timeout);
- if (request->ccb[0] != ATAPI_REQUEST_SENSE)
+ if (!(request->flags & ATPR_F_INTERNAL))
atp->cmd = request->ccb[0];
/* if DMA enabled setup DMA hardware */
@@ -332,12 +332,8 @@ int
atapi_interrupt(struct atapi_request *request)
{
struct atapi_softc *atp = request->device;
- int8_t **buffer = (int8_t **)&request->data;
int reason, dma_stat = 0;
- if (request->ccb[0] == ATAPI_REQUEST_SENSE)
- *buffer = (int8_t *)&request->sense;
-
reason = (inb(atp->controller->ioaddr+ATA_IREASON) & (ATA_I_CMD|ATA_I_IN)) |
(atp->controller->status & ATA_S_DRQ);
@@ -402,7 +398,7 @@ atapi_interrupt(struct atapi_request *request)
if (atp->controller->status & (ATA_S_ERROR | ATA_S_DWF))
request->result = inb(atp->controller->ioaddr + ATA_ERROR);
else
- if (request->ccb[0] != ATAPI_REQUEST_SENSE)
+ if (!(request->flags & ATPR_F_INTERNAL))
request->result = 0;
break;
@@ -421,11 +417,10 @@ op_finished:
request->ccb[0] = ATAPI_REQUEST_SENSE;
request->ccb[4] = sizeof(struct atapi_reqsense);
request->bytecount = sizeof(struct atapi_reqsense);
- request->flags = ATPR_F_READ;
+ request->flags = ATPR_F_READ | ATPR_F_INTERNAL;
TAILQ_INSERT_HEAD(&atp->controller->atapi_queue, request, chain);
}
else {
- request->error = 0;
if (request->result) {
switch ((request->result & ATAPI_SK_MASK)) {
case ATAPI_SK_RESERVED:
@@ -463,6 +458,8 @@ op_finished:
request->error = EIO;
}
}
+ else
+ request->error = 0;
if (request->callback) {
#ifdef ATAPI_DEBUG
printf("%s: finished %s (callback)\n",
@@ -541,7 +538,7 @@ atapi_read(struct atapi_request *request, int length)
int size = min(request->bytecount, length);
int resid;
- if (request->ccb[0] == ATAPI_REQUEST_SENSE)
+ if (request->flags & ATPR_F_INTERNAL)
*buffer = (int8_t *)&request->sense;
if (request->device->controller->flags & ATA_USE_16BIT ||
@@ -570,7 +567,7 @@ atapi_write(struct atapi_request *request, int length)
int size = min(request->bytecount, length);
int resid;
- if (request->ccb[0] == ATAPI_REQUEST_SENSE)
+ if (request->flags & ATPR_F_INTERNAL)
*buffer = (int8_t *)&request->sense;
if (request->device->controller->flags & ATA_USE_16BIT ||
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index b81770f..15bc6ff 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -136,10 +136,10 @@ struct atapi_reqsense {
u_int8_t asc; /* additional sense code */
u_int8_t ascq; /* additional sense code qual */
u_int8_t replaceable_unit_code; /* replaceable unit code */
- u_int8_t sk_specific1 :7; /* sense key specific */
+ u_int8_t sk_specific :7; /* sense key specific */
u_int8_t sksv :1; /* sense key specific info OK */
+ u_int8_t sk_specific1; /* sense key specific */
u_int8_t sk_specific2; /* sense key specific */
- u_int8_t sk_specific3; /* sense key specific */
};
struct atapi_softc {
@@ -171,6 +171,7 @@ struct atapi_request {
#define ATPR_F_READ 0x0001
#define ATPR_F_DMA_USED 0x0002
#define ATPR_F_AT_HEAD 0x0004
+#define ATPR_F_INTERNAL 0x0008
caddr_t data; /* pointer to data buf */
atapi_callback_t *callback; /* ptr to callback func */
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index f32c5b7..1e0c01e 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -77,13 +77,13 @@ 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_read_toc(struct acd_softc *);
-static void acd_construct_label(struct acd_softc *);
static int acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
static void acd_select_slot(struct acd_softc *);
static int acd_open_track(struct acd_softc *, struct cdr_track *);
static int acd_close_track(struct acd_softc *);
static int acd_close_disk(struct acd_softc *);
static int acd_read_track_info(struct acd_softc *, int32_t, struct acd_track_info*);
+static int acd_get_progress(struct acd_softc *cdp, int *);
static int acd_report_key(struct acd_softc *, struct dvd_authinfo *);
static int acd_send_key(struct acd_softc *, struct dvd_authinfo *);
static int acd_read_structure(struct acd_softc *, struct dvd_struct *);
@@ -530,12 +530,8 @@ acdopen(dev_t dev, int flags, int fmt, struct proc *p)
}
acd_prevent_allow(cdp, 1);
cdp->flags |= F_LOCKED;
- if (!(flags & O_NONBLOCK) && !(flags & FWRITE))
- acd_read_toc(cdp);
- else
- atapi_test_ready(cdp->atp);
+ acd_read_toc(cdp);
}
- acd_construct_label(cdp);
return 0;
}
@@ -553,8 +549,8 @@ acdclose(dev_t dev, int flags, int fmt, struct proc *p)
tsleep(&cdp->changer_info, PRIBIO, "acdclo", 0);
}
acd_prevent_allow(cdp, 0);
+ cdp->flags &= ~F_LOCKED;
}
- cdp->flags &= ~F_LOCKED;
return 0;
}
@@ -602,13 +598,13 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
case CDIOCALLOW:
- cdp->flags &= ~F_LOCKED;
error = acd_prevent_allow(cdp, 0);
+ cdp->flags &= ~F_LOCKED;
break;
case CDIOCPREVENT:
- cdp->flags |= F_LOCKED;
error = acd_prevent_allow(cdp, 1);
+ cdp->flags |= F_LOCKED;
break;
case CDIOCRESET:
@@ -1041,6 +1037,10 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
cdp->block_size = *(int *)addr;
break;
+ case CDRIOCGETPROGRESS:
+ error = acd_get_progress(cdp, (int *)addr);
+ break;
+
case DVDIOCREPORTKEY:
if (!cdp->cap.read_dvdrom)
error = EINVAL;
@@ -1228,7 +1228,8 @@ acd_read_toc(struct acd_softc *cdp)
bzero(&cdp->info, sizeof(cdp->info));
bzero(ccb, sizeof(ccb));
- atapi_test_ready(cdp->atp);
+ if (atapi_test_ready(cdp->atp) != 0)
+ return;
cdp->atp->flags &= ~ATAPI_F_MEDIA_CHANGED;
@@ -1270,25 +1271,6 @@ acd_read_toc(struct acd_softc *cdp)
cdp->info.blksize = ntohl(cdp->info.blksize);
cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352;
-#ifdef ACD_DEBUG
- if (cdp->info.volsize && cdp->toc.hdr.ending_track) {
- printf("acd%d: ", cdp->lun);
- if (cdp->toc.tab[0].control & 4)
- printf("%dMB ", cdp->info.volsize / 512);
- else
- printf("%d:%d audio ", cdp->info.volsize / 75 / 60,
- cdp->info.volsize / 75 % 60);
- printf("(%d sectors (%d bytes)), %d tracks\n",
- cdp->info.volsize, cdp->info.blksize,
- cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1);
- }
-#endif
- return;
-}
-
-static void
-acd_construct_label(struct acd_softc *cdp)
-{
bzero(&cdp->disklabel, sizeof(struct disklabel));
strncpy(cdp->disklabel.d_typename, " ",
sizeof(cdp->disklabel.d_typename));
@@ -1313,6 +1295,20 @@ acd_construct_label(struct acd_softc *cdp)
cdp->disklabel.d_magic = DISKMAGIC;
cdp->disklabel.d_magic2 = DISKMAGIC;
cdp->disklabel.d_checksum = dkcksum(&cdp->disklabel);
+
+#ifdef ACD_DEBUG
+ if (cdp->info.volsize && cdp->toc.hdr.ending_track) {
+ printf("acd%d: ", cdp->lun);
+ if (cdp->toc.tab[0].control & 4)
+ printf("%dMB ", cdp->info.volsize / 512);
+ else
+ printf("%d:%d audio ", cdp->info.volsize / 75 / 60,
+ cdp->info.volsize / 75 % 60);
+ printf("(%d sectors (%d bytes)), %d tracks\n",
+ cdp->info.volsize, cdp->info.blksize,
+ cdp->toc.hdr.ending_track - cdp->toc.hdr.starting_track + 1);
+ }
+#endif
}
static int
@@ -1372,10 +1368,20 @@ acd_select_slot(struct acd_softc *cdp)
static int
acd_close_disk(struct acd_softc *cdp)
{
- int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0, 0x02, 0, 0, 0, 0, 0,
+ int8_t ccb[16] = { ATAPI_CLOSE_TRACK, 0x01, 0x02, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
+ int timeout = 5*60*2;
+ int error;
- return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 5*60, NULL, NULL);
+ error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL);
+ if (error)
+ return error;
+ while (timeout-- > 0) {
+ if ((error = atapi_test_ready(cdp->atp)) != EBUSY)
+ return error;
+ tsleep(&error, PRIBIO, "acdcld", hz/2);
+ }
+ return EIO;
}
static int
@@ -1462,7 +1468,7 @@ static int
acd_close_track(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 };
+ 0, 0, 0, 0, 0, 0, 0, 0 };
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 60, NULL, NULL);
}
@@ -1490,6 +1496,26 @@ acd_read_track_info(struct acd_softc *cdp,
}
static int
+acd_get_progress(struct acd_softc *cdp, int *finished)
+{
+ int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0,
+ sizeof(struct atapi_reqsense),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+ struct atapi_reqsense sense;
+ int error;
+
+ if ((error = atapi_test_ready(cdp->atp)) != EBUSY) {
+ *finished = 100;
+ return error;
+ }
+
+ error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&sense, sizeof(sense),
+ ATPR_F_READ, 10, NULL, NULL);
+ *finished = ((sense.sk_specific2|(sense.sk_specific1<<8))*100) / 65535;
+ return error;
+}
+
+static int
acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
{
struct {
@@ -1758,13 +1784,11 @@ acd_eject(struct acd_softc *cdp, int close)
static int
acd_blank(struct acd_softc *cdp)
{
- int8_t ccb[16] = { ATAPI_BLANK, 1, 0, 0, 0, 0, 0, 0,
+ int8_t ccb[16] = { ATAPI_BLANK, 0x10 | 0x01, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
- int error;
- error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 60*60, NULL, NULL);
cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
- return error;
+ return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL);
}
static int
OpenPOWER on IntegriCloud