diff options
author | sos <sos@FreeBSD.org> | 2000-12-26 11:55:44 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2000-12-26 11:55:44 +0000 |
commit | d65168d03ee4827064914b90fabefe9f404ec66a (patch) | |
tree | a8c4847e0f266ef15e7ce484b096d005151909b0 /sys | |
parent | 8db92e907c9eaa60ee1aa5df18a50494f78258b4 (diff) | |
download | FreeBSD-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.c | 17 | ||||
-rw-r--r-- | sys/dev/ata/atapi-all.h | 5 | ||||
-rw-r--r-- | sys/dev/ata/atapi-cd.c | 96 |
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 |