From 515ba9517a825ac30dbcc10d081cc36ac3326884 Mon Sep 17 00:00:00 2001 From: sos Date: Sat, 16 Mar 2002 15:56:54 +0000 Subject: Add more functionality to the CDIOCREADSUBCHANNEL ioctl. PR: 26644 --- sys/dev/ata/atapi-cd.c | 54 +++++++++++++++++++++++++++----------------------- sys/dev/ata/atapi-cd.h | 12 +---------- 2 files changed, 30 insertions(+), 36 deletions(-) (limited to 'sys/dev/ata') diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index bb19b7d..f96267c 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -709,7 +709,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) { struct ioc_read_subchannel *args = (struct ioc_read_subchannel *)addr; - struct cd_sub_channel_info *data; + u_int8_t format; int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0, sizeof(cdp->subchan)>>8, sizeof(cdp->subchan), 0, 0, 0, 0, 0, 0, 0 }; @@ -720,34 +720,38 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td) break; } + format=args->data_format; + if ((format != CD_CURRENT_POSITION) && + (format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) { + error = EINVAL; + break; + } + + ccb[1] = args->address_format & CD_MSF_FORMAT; + if ((error = atapi_queue_cmd(cdp->device,ccb,(caddr_t)&cdp->subchan, sizeof(cdp->subchan), ATPR_F_READ, 10, - NULL, NULL))) { + NULL, NULL))) break; + + if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) { + if (cdp->subchan.header.audio_status == 0x11) { + error = EINVAL; + break; + } + + ccb[3] = format; + if (format == CD_TRACK_INFO) + ccb[6] = args->track; + + if ((error = atapi_queue_cmd(cdp->device, ccb, + (caddr_t)&cdp->subchan, + sizeof(cdp->subchan), ATPR_F_READ, + 10, NULL, NULL))) { + break; + } } - data = malloc(sizeof(struct cd_sub_channel_info), - M_ACD, M_NOWAIT | M_ZERO); - - if (args->address_format == CD_MSF_FORMAT) { - lba2msf(ntohl(cdp->subchan.abslba), - &data->what.position.absaddr.msf.minute, - &data->what.position.absaddr.msf.second, - &data->what.position.absaddr.msf.frame); - lba2msf(ntohl(cdp->subchan.rellba), - &data->what.position.reladdr.msf.minute, - &data->what.position.reladdr.msf.second, - &data->what.position.reladdr.msf.frame); - } else { - data->what.position.absaddr.lba = cdp->subchan.abslba; - data->what.position.reladdr.lba = cdp->subchan.rellba; - } - data->header.audio_status = cdp->subchan.audio_status; - data->what.position.control = cdp->subchan.control & 0xf; - data->what.position.addr_type = cdp->subchan.control >> 4; - data->what.position.track_number = cdp->subchan.track; - data->what.position.index_number = cdp->subchan.indx; - error = copyout(data, args->data, args->data_len); - free(data, M_ACD); + error = copyout(&cdp->subchan, args->data, args->data_len); break; } diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h index 7660531..e40191d 100644 --- a/sys/dev/ata/atapi-cd.h +++ b/sys/dev/ata/atapi-cd.h @@ -316,17 +316,7 @@ struct acd_softc { struct audiopage au; /* audio page info */ struct audiopage aumask; /* audio page mask */ struct cappage cap; /* capabilities page info */ - struct { /* subchannel info */ - u_int8_t void0; - u_int8_t audio_status; - u_int16_t data_length; - u_int8_t data_format; - u_int8_t control; - u_int8_t track; - u_int8_t indx; - u_int32_t abslba; - u_int32_t rellba; - } subchan; + struct cd_sub_channel_info subchan; /* subchannel info */ struct changer *changer_info; /* changer info */ struct acd_softc **driver; /* softc's of changer slots */ int slot; /* this instance slot number */ -- cgit v1.1