diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index dc4c99b67e33..105e802a5f7d 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -707,6 +707,7 @@ atapi_cmd2str(u_int8_t cmd) case 0x3c: return ("READ_BUFFER"); case 0x42: return ("READ_SUBCHANNEL"); case 0x43: return ("READ_TOC"); + case 0x45: return ("PLAY_10"); case 0x47: return ("PLAY_MSF"); case 0x48: return ("PLAY_TRACK"); case 0x4b: return ("PAUSE"); @@ -724,7 +725,7 @@ atapi_cmd2str(u_int8_t cmd) case 0xa1: return ("BLANK_CMD"); case 0xa3: return ("SEND_KEY"); case 0xa4: return ("REPORT_KEY"); - case 0xa5: return ("PLAY_BIG"); + case 0xa5: return ("PLAY_12"); case 0xa6: return ("LOAD_UNLOAD"); case 0xad: return ("READ_DVD_STRUCTURE"); case 0xb4: return ("PLAY_CD"); diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index fd7c18854cf0..bbd4a7c44860 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -92,6 +92,7 @@ #define ATAPI_READ_BUFFER 0x3c /* read device buffer */ #define ATAPI_READ_SUBCHANNEL 0x42 /* get subchannel info */ #define ATAPI_READ_TOC 0x43 /* get table of contents */ +#define ATAPI_PLAY_10 0x45 /* play by lba */ #define ATAPI_PLAY_MSF 0x47 /* play by MSF address */ #define ATAPI_PLAY_TRACK 0x48 /* play by track number */ #define ATAPI_PAUSE 0x4b /* pause audio operation */ @@ -109,7 +110,7 @@ #define ATAPI_BLANK 0xa1 /* blank the media */ #define ATAPI_SEND_KEY 0xa3 /* send DVD key structure */ #define ATAPI_REPORT_KEY 0xa4 /* get DVD key structure */ -#define ATAPI_PLAY_BIG 0xa5 /* play by lba */ +#define ATAPI_PLAY_12 0xa5 /* play by lba */ #define ATAPI_LOAD_UNLOAD 0xa6 /* changer control command */ #define ATAPI_READ_STRUCTURE 0xad /* get DVD structure */ #define ATAPI_PLAY_CD 0xb4 /* universal play command */ diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index d2a15916d888..651f00c26633 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -76,6 +76,7 @@ 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 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); static void acd_select_slot(struct acd_softc *); static int acd_open_track(struct acd_softc *, struct cdr_track *); @@ -787,40 +788,31 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case CDIOCPLAYMSF: { struct ioc_play_msf *args = (struct ioc_play_msf *)addr; - int8_t ccb[16] = { ATAPI_PLAY_MSF, 0, 0, - args->start_m, args->start_s, args->start_f, - args->end_m, args->end_s, args->end_f, - 0, 0, 0, 0, 0, 0, 0 }; - error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = + acd_play(cdp, + msf2lba(args->start_m, args->start_s, args->start_f), + msf2lba(args->end_m, args->end_s, args->end_f)); break; } case CDIOCPLAYBLOCKS: { struct ioc_play_blocks *args = (struct ioc_play_blocks *)addr; - int8_t ccb[16] = { ATAPI_PLAY_BIG, 0, - args->blk>>24, args->blk>>16, args->blk>>8, - args->blk, args->len>>24, args->len>>16, - args->len>>8, args->len, - 0, 0, 0, 0, 0, 0 }; - error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = acd_play(cdp, args->blk, args->blk + args->len); break; } case CDIOCPLAYTRACKS: { struct ioc_play_track *args = (struct ioc_play_track *)addr; - u_int start, len; int t1, t2; - int8_t ccb[16]; if (!cdp->toc.hdr.ending_track) { error = EIO; break; } - if (args->end_track < cdp->toc.hdr.ending_track + 1) ++args->end_track; if (args->end_track > cdp->toc.hdr.ending_track + 1) @@ -831,21 +823,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) error = EINVAL; break; } - start = ntohl(cdp->toc.tab[t1].addr.lba); - len = ntohl(cdp->toc.tab[t2].addr.lba) - start; - - bzero(ccb, sizeof(ccb)); - ccb[0] = ATAPI_PLAY_BIG; - ccb[2] = start>>24; - ccb[3] = start>>16; - ccb[4] = start>>8; - ccb[5] = start; - ccb[6] = len>>24; - ccb[7] = len>>16; - ccb[8] = len>>8; - ccb[9] = len; - - error = atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); + error = acd_play(cdp, ntohl(cdp->toc.tab[t1].addr.lba), + ntohl(cdp->toc.tab[t2].addr.lba)); break; } @@ -1340,6 +1319,30 @@ acd_read_toc(struct acd_softc *cdp) #endif } +static int +acd_play(struct acd_softc *cdp, int start, int end) +{ + int8_t ccb[16]; + + bzero(ccb, sizeof(ccb)); +#if 1 + ccb[0] = ATAPI_PLAY_MSF; + lba2msf(start, &ccb[3], &ccb[4], &ccb[5]); + lba2msf(end, &ccb[6], &ccb[7], &ccb[8]); +#else + ccb[0] = ATAPI_PLAY_12; + ccb[2] = start>>24; + ccb[3] = start>>16; + ccb[4] = start>>8; + ccb[5] = start; + ccb[6] = (end - start)>>24; + ccb[7] = (end - start)>>16; + ccb[8] = (end - start)>>8; + ccb[9] = (end - start); +#endif + return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 10, NULL, NULL); +} + static int acd_setchan(struct acd_softc *cdp, u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)