1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-14 10:09:48 +00:00

Add more functionality to the CDIOCREADSUBCHANNEL ioctl.

PR: 26644
This commit is contained in:
Søren Schmidt 2002-03-16 15:56:54 +00:00
parent 698d5a2c84
commit 4e887e1915
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=92421
2 changed files with 30 additions and 36 deletions

View File

@ -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;
}
if ((error = atapi_queue_cmd(cdp->device,ccb,(caddr_t)&cdp->subchan,
sizeof(cdp->subchan), ATPR_F_READ, 10,
NULL, NULL))) {
format=args->data_format;
if ((format != CD_CURRENT_POSITION) &&
(format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) {
error = EINVAL;
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;
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)))
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->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;
}

View File

@ -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 */