summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2002-03-16 15:56:54 +0000
committersos <sos@FreeBSD.org>2002-03-16 15:56:54 +0000
commit515ba9517a825ac30dbcc10d081cc36ac3326884 (patch)
treef9216c6df664ce2489b4577996f3295fc64869f0
parent2b25f973e2c2bd3048b444a4bc0b5ce371dcf742 (diff)
downloadFreeBSD-src-515ba9517a825ac30dbcc10d081cc36ac3326884.zip
FreeBSD-src-515ba9517a825ac30dbcc10d081cc36ac3326884.tar.gz
Add more functionality to the CDIOCREADSUBCHANNEL ioctl.
PR: 26644
-rw-r--r--sys/dev/ata/atapi-cd.c54
-rw-r--r--sys/dev/ata/atapi-cd.h12
2 files changed, 30 insertions, 36 deletions
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 */
OpenPOWER on IntegriCloud