aboutsummaryrefslogtreecommitdiff
path: root/sys/i386/isa
diff options
context:
space:
mode:
authorAndrey A. Chernov <ache@FreeBSD.org>1996-01-30 11:32:20 +0000
committerAndrey A. Chernov <ache@FreeBSD.org>1996-01-30 11:32:20 +0000
commit71517d7ccfe9b41ea3f8f26c0103df662671a698 (patch)
treef4311ab18a87c83e23e6972f721ef4ded23753df /sys/i386/isa
parent76bd0c0a9d32cbd8ccfdf0b4cf134141b670df20 (diff)
Fix READTOCENTRYS partialy based on kientzle@netcom.com patch partialy on
my own ideas
Notes
Notes: svn path=/head/; revision=13734
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/wcd.c39
1 files changed, 24 insertions, 15 deletions
diff --git a/sys/i386/isa/wcd.c b/sys/i386/isa/wcd.c
index 933a73b2f7bc..bfb018d5051e 100644
--- a/sys/i386/isa/wcd.c
+++ b/sys/i386/isa/wcd.c
@@ -760,19 +760,32 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
struct toc *toc = &t->toc;
struct toc buf;
u_long len;
+ u_char starting_track = te->starting_track;
if (! t->toc.hdr.ending_track)
return (EIO);
- if (te->starting_track < toc->hdr.starting_track ||
- te->starting_track > toc->hdr.ending_track)
- return (EINVAL);
- len = (toc->hdr.ending_track - te->starting_track + 2) *
+ if ( te->data_len > sizeof(toc->tab)
+ || te->data_len < sizeof(toc->tab[0])
+ || (te->data_len % sizeof(toc->tab[0])) != 0
+ )
+ return EINVAL;
+ if (te->address_format != CD_MSF_FORMAT &&
+ te->address_format != CD_LBA_FORMAT)
+ return EINVAL;
+
+ if (starting_track == 0)
+ starting_track = toc->hdr.starting_track;
+ else if (starting_track == 170) /* Handle leadout request */
+ starting_track = toc->hdr.ending_track + 1;
+ else if (starting_track < toc->hdr.starting_track ||
+ starting_track > toc->hdr.ending_track + 1)
+ return (EINVAL);
+
+ len = ((toc->hdr.ending_track + 1 - starting_track) + 1) *
sizeof(toc->tab[0]);
if (te->data_len < len)
len = te->data_len;
- if (len <= 0)
- return (EINVAL);
/* Convert to MSF format, if needed. */
if (te->address_format == CD_MSF_FORMAT) {
@@ -780,16 +793,14 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
buf = t->toc;
toc = &buf;
- e = toc->tab + toc->hdr.ending_track -
- te->starting_track + 2;
+ e = toc->tab + (toc->hdr.ending_track + 1 -
+ toc->hdr.starting_track) + 1;
while (--e >= toc->tab)
lba2msf (e->addr.lba, &e->addr.msf.minute,
&e->addr.msf.second, &e->addr.msf.frame);
}
- if (copyout (toc->tab + te->starting_track -
- toc->hdr.starting_track, te->data, len) != 0)
- error = EFAULT;
- break;
+ return copyout (toc->tab + starting_track -
+ toc->hdr.starting_track, te->data, len);
}
case CDIOCREADSUBCHANNEL: {
struct ioc_read_subchannel *args =
@@ -829,9 +840,7 @@ int wcdioctl (dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p)
data.what.position.track_number = t->subchan.track;
data.what.position.index_number = t->subchan.indx;
- if (copyout (&data, args->data, len) != 0)
- error = EFAULT;
- break;
+ return copyout (&data, args->data, len);
}
case CDIOCPLAYMSF: {
struct ioc_play_msf *args = (struct ioc_play_msf*) addr;