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:
parent
ce3598adfe
commit
dec35f9164
@ -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 ||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user