in cdrom.c [3010:3056]
static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi,
void __user *arg)
{
struct cdrom_read_audio ra;
int lba;
#ifdef CONFIG_COMPAT
if (in_compat_syscall()) {
struct compat_cdrom_read_audio {
union cdrom_addr addr;
u8 addr_format;
compat_int_t nframes;
compat_caddr_t buf;
} ra32;
if (copy_from_user(&ra32, arg, sizeof(ra32)))
return -EFAULT;
ra = (struct cdrom_read_audio) {
.addr = ra32.addr,
.addr_format = ra32.addr_format,
.nframes = ra32.nframes,
.buf = compat_ptr(ra32.buf),
};
} else
#endif
{
if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg,
sizeof(ra)))
return -EFAULT;
}
if (ra.addr_format == CDROM_MSF)
lba = msf_to_lba(ra.addr.msf.minute,
ra.addr.msf.second,
ra.addr.msf.frame);
else if (ra.addr_format == CDROM_LBA)
lba = ra.addr.lba;
else
return -EINVAL;
/* FIXME: we need upper bound checking, too!! */
if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
return -EINVAL;
return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
}