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)
This commit is contained in:
Søren Schmidt 2000-12-26 11:55:44 +00:00
parent ce3598adfe
commit dec35f9164
3 changed files with 70 additions and 48 deletions

View File

@ -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 @@ atapi_interrupt(struct atapi_request *request)
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 @@ atapi_interrupt(struct atapi_request *request)
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 ||

View File

@ -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 */

View File

@ -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);
}
@ -1489,6 +1495,26 @@ acd_read_track_info(struct acd_softc *cdp,
return 0;
}
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)
{
@ -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