.. | .. |
---|
7 | 7 | License. See linux/COPYING for more information. |
---|
8 | 8 | |
---|
9 | 9 | Uniform CD-ROM driver for Linux. |
---|
10 | | - See Documentation/cdrom/cdrom-standard.tex for usage information. |
---|
| 10 | + See Documentation/cdrom/cdrom-standard.rst for usage information. |
---|
11 | 11 | |
---|
12 | 12 | The routines in the file provide a uniform interface between the |
---|
13 | 13 | software that uses CD-ROMs and the various low-level drivers that |
---|
.. | .. |
---|
586 | 586 | return 0; |
---|
587 | 587 | } |
---|
588 | 588 | |
---|
589 | | -int register_cdrom(struct cdrom_device_info *cdi) |
---|
| 589 | +int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi) |
---|
590 | 590 | { |
---|
591 | 591 | static char banner_printed; |
---|
592 | 592 | const struct cdrom_device_ops *cdo = cdi->ops; |
---|
.. | .. |
---|
601 | 601 | cdrom_sysctl_register(); |
---|
602 | 602 | } |
---|
603 | 603 | |
---|
| 604 | + cdi->disk = disk; |
---|
| 605 | + disk->cdi = cdi; |
---|
| 606 | + |
---|
604 | 607 | ENSURE(cdo, drive_status, CDC_DRIVE_STATUS); |
---|
605 | | - if (cdo->check_events == NULL && cdo->media_changed == NULL) |
---|
| 608 | + if (cdo->check_events == NULL) |
---|
606 | 609 | WARN_ON_ONCE(cdo->capability & (CDC_MEDIA_CHANGED | CDC_SELECT_DISC)); |
---|
607 | 610 | ENSURE(cdo, tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY); |
---|
608 | 611 | ENSURE(cdo, lock_door, CDC_LOCK); |
---|
.. | .. |
---|
1416 | 1419 | |
---|
1417 | 1420 | if (cdi->ops->check_events) |
---|
1418 | 1421 | cdi->ops->check_events(cdi, 0, slot); |
---|
1419 | | - else |
---|
1420 | | - cdi->ops->media_changed(cdi, slot); |
---|
1421 | 1422 | |
---|
1422 | 1423 | if (slot == CDSL_NONE) { |
---|
1423 | 1424 | /* set media changed bits, on both queues */ |
---|
.. | .. |
---|
1514 | 1515 | return ret; |
---|
1515 | 1516 | |
---|
1516 | 1517 | /* changed since last call? */ |
---|
1517 | | - if (cdi->ops->check_events) { |
---|
1518 | | - BUG_ON(!queue); /* shouldn't be called from VFS path */ |
---|
1519 | | - cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE); |
---|
1520 | | - changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE; |
---|
1521 | | - cdi->ioctl_events = 0; |
---|
1522 | | - } else |
---|
1523 | | - changed = cdi->ops->media_changed(cdi, CDSL_CURRENT); |
---|
| 1518 | + BUG_ON(!queue); /* shouldn't be called from VFS path */ |
---|
| 1519 | + cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE); |
---|
| 1520 | + changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE; |
---|
| 1521 | + cdi->ioctl_events = 0; |
---|
1524 | 1522 | |
---|
1525 | 1523 | if (changed) { |
---|
1526 | 1524 | cdi->mc_flags = 0x3; /* set bit on both queues */ |
---|
.. | .. |
---|
1530 | 1528 | |
---|
1531 | 1529 | cdi->mc_flags &= ~mask; /* clear bit */ |
---|
1532 | 1530 | return ret; |
---|
1533 | | -} |
---|
1534 | | - |
---|
1535 | | -int cdrom_media_changed(struct cdrom_device_info *cdi) |
---|
1536 | | -{ |
---|
1537 | | - /* This talks to the VFS, which doesn't like errors - just 1 or 0. |
---|
1538 | | - * Returning "0" is always safe (media hasn't been changed). Do that |
---|
1539 | | - * if the low-level cdrom driver dosn't support media changed. */ |
---|
1540 | | - if (cdi == NULL || cdi->ops->media_changed == NULL) |
---|
1541 | | - return 0; |
---|
1542 | | - if (!CDROM_CAN(CDC_MEDIA_CHANGED)) |
---|
1543 | | - return 0; |
---|
1544 | | - return media_changed(cdi, 0); |
---|
1545 | 1531 | } |
---|
1546 | 1532 | |
---|
1547 | 1533 | /* Requests to the low-level drivers will /always/ be done in the |
---|
.. | .. |
---|
2292 | 2278 | return cdrom_read_cdda_old(cdi, ubuf, lba, nframes); |
---|
2293 | 2279 | } |
---|
2294 | 2280 | |
---|
2295 | | -static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi, |
---|
2296 | | - void __user *argp) |
---|
| 2281 | +int cdrom_multisession(struct cdrom_device_info *cdi, |
---|
| 2282 | + struct cdrom_multisession *info) |
---|
2297 | 2283 | { |
---|
2298 | | - struct cdrom_multisession ms_info; |
---|
2299 | 2284 | u8 requested_format; |
---|
2300 | 2285 | int ret; |
---|
2301 | | - |
---|
2302 | | - cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); |
---|
2303 | 2286 | |
---|
2304 | 2287 | if (!(cdi->ops->capability & CDC_MULTI_SESSION)) |
---|
2305 | 2288 | return -ENOSYS; |
---|
2306 | 2289 | |
---|
2307 | | - if (copy_from_user(&ms_info, argp, sizeof(ms_info))) |
---|
2308 | | - return -EFAULT; |
---|
2309 | | - |
---|
2310 | | - requested_format = ms_info.addr_format; |
---|
| 2290 | + requested_format = info->addr_format; |
---|
2311 | 2291 | if (requested_format != CDROM_MSF && requested_format != CDROM_LBA) |
---|
2312 | 2292 | return -EINVAL; |
---|
2313 | | - ms_info.addr_format = CDROM_LBA; |
---|
| 2293 | + info->addr_format = CDROM_LBA; |
---|
2314 | 2294 | |
---|
2315 | | - ret = cdi->ops->get_last_session(cdi, &ms_info); |
---|
| 2295 | + ret = cdi->ops->get_last_session(cdi, info); |
---|
| 2296 | + if (!ret) |
---|
| 2297 | + sanitize_format(&info->addr, &info->addr_format, |
---|
| 2298 | + requested_format); |
---|
| 2299 | + return ret; |
---|
| 2300 | +} |
---|
| 2301 | +EXPORT_SYMBOL_GPL(cdrom_multisession); |
---|
| 2302 | + |
---|
| 2303 | +static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi, |
---|
| 2304 | + void __user *argp) |
---|
| 2305 | +{ |
---|
| 2306 | + struct cdrom_multisession info; |
---|
| 2307 | + int ret; |
---|
| 2308 | + |
---|
| 2309 | + cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); |
---|
| 2310 | + |
---|
| 2311 | + if (copy_from_user(&info, argp, sizeof(info))) |
---|
| 2312 | + return -EFAULT; |
---|
| 2313 | + ret = cdrom_multisession(cdi, &info); |
---|
2316 | 2314 | if (ret) |
---|
2317 | 2315 | return ret; |
---|
2318 | | - |
---|
2319 | | - sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format); |
---|
2320 | | - |
---|
2321 | | - if (copy_to_user(argp, &ms_info, sizeof(ms_info))) |
---|
| 2316 | + if (copy_to_user(argp, &info, sizeof(info))) |
---|
2322 | 2317 | return -EFAULT; |
---|
2323 | 2318 | |
---|
2324 | 2319 | cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n"); |
---|
2325 | | - return 0; |
---|
| 2320 | + return ret; |
---|
2326 | 2321 | } |
---|
2327 | 2322 | |
---|
2328 | 2323 | static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) |
---|
.. | .. |
---|
2663 | 2658 | return 0; |
---|
2664 | 2659 | } |
---|
2665 | 2660 | |
---|
| 2661 | +int cdrom_read_tocentry(struct cdrom_device_info *cdi, |
---|
| 2662 | + struct cdrom_tocentry *entry) |
---|
| 2663 | +{ |
---|
| 2664 | + u8 requested_format = entry->cdte_format; |
---|
| 2665 | + int ret; |
---|
| 2666 | + |
---|
| 2667 | + if (requested_format != CDROM_MSF && requested_format != CDROM_LBA) |
---|
| 2668 | + return -EINVAL; |
---|
| 2669 | + |
---|
| 2670 | + /* make interface to low-level uniform */ |
---|
| 2671 | + entry->cdte_format = CDROM_MSF; |
---|
| 2672 | + ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, entry); |
---|
| 2673 | + if (!ret) |
---|
| 2674 | + sanitize_format(&entry->cdte_addr, &entry->cdte_format, |
---|
| 2675 | + requested_format); |
---|
| 2676 | + return ret; |
---|
| 2677 | +} |
---|
| 2678 | +EXPORT_SYMBOL_GPL(cdrom_read_tocentry); |
---|
| 2679 | + |
---|
2666 | 2680 | static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi, |
---|
2667 | 2681 | void __user *argp) |
---|
2668 | 2682 | { |
---|
2669 | 2683 | struct cdrom_tocentry entry; |
---|
2670 | | - u8 requested_format; |
---|
2671 | 2684 | int ret; |
---|
2672 | | - |
---|
2673 | | - /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */ |
---|
2674 | 2685 | |
---|
2675 | 2686 | if (copy_from_user(&entry, argp, sizeof(entry))) |
---|
2676 | 2687 | return -EFAULT; |
---|
2677 | | - |
---|
2678 | | - requested_format = entry.cdte_format; |
---|
2679 | | - if (requested_format != CDROM_MSF && requested_format != CDROM_LBA) |
---|
2680 | | - return -EINVAL; |
---|
2681 | | - /* make interface to low-level uniform */ |
---|
2682 | | - entry.cdte_format = CDROM_MSF; |
---|
2683 | | - ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry); |
---|
2684 | | - if (ret) |
---|
2685 | | - return ret; |
---|
2686 | | - sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format); |
---|
2687 | | - |
---|
2688 | | - if (copy_to_user(argp, &entry, sizeof(entry))) |
---|
| 2688 | + ret = cdrom_read_tocentry(cdi, &entry); |
---|
| 2689 | + if (!ret && copy_to_user(argp, &entry, sizeof(entry))) |
---|
2689 | 2690 | return -EFAULT; |
---|
2690 | | - /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */ |
---|
2691 | | - return 0; |
---|
| 2691 | + return ret; |
---|
2692 | 2692 | } |
---|
2693 | 2693 | |
---|
2694 | 2694 | static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi, |
---|
.. | .. |
---|
3017 | 3017 | struct cdrom_read_audio ra; |
---|
3018 | 3018 | int lba; |
---|
3019 | 3019 | |
---|
3020 | | - if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg, |
---|
3021 | | - sizeof(ra))) |
---|
3022 | | - return -EFAULT; |
---|
| 3020 | +#ifdef CONFIG_COMPAT |
---|
| 3021 | + if (in_compat_syscall()) { |
---|
| 3022 | + struct compat_cdrom_read_audio { |
---|
| 3023 | + union cdrom_addr addr; |
---|
| 3024 | + u8 addr_format; |
---|
| 3025 | + compat_int_t nframes; |
---|
| 3026 | + compat_caddr_t buf; |
---|
| 3027 | + } ra32; |
---|
| 3028 | + |
---|
| 3029 | + if (copy_from_user(&ra32, arg, sizeof(ra32))) |
---|
| 3030 | + return -EFAULT; |
---|
| 3031 | + |
---|
| 3032 | + ra = (struct cdrom_read_audio) { |
---|
| 3033 | + .addr = ra32.addr, |
---|
| 3034 | + .addr_format = ra32.addr_format, |
---|
| 3035 | + .nframes = ra32.nframes, |
---|
| 3036 | + .buf = compat_ptr(ra32.buf), |
---|
| 3037 | + }; |
---|
| 3038 | + } else |
---|
| 3039 | +#endif |
---|
| 3040 | + { |
---|
| 3041 | + if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg, |
---|
| 3042 | + sizeof(ra))) |
---|
| 3043 | + return -EFAULT; |
---|
| 3044 | + } |
---|
3023 | 3045 | |
---|
3024 | 3046 | if (ra.addr_format == CDROM_MSF) |
---|
3025 | 3047 | lba = msf_to_lba(ra.addr.msf.minute, |
---|
.. | .. |
---|
3271 | 3293 | ret = cdrom_get_last_written(cdi, &last); |
---|
3272 | 3294 | if (ret) |
---|
3273 | 3295 | return ret; |
---|
3274 | | - if (copy_to_user((long __user *)arg, &last, sizeof(last))) |
---|
3275 | | - return -EFAULT; |
---|
3276 | | - return 0; |
---|
| 3296 | + if (in_compat_syscall()) |
---|
| 3297 | + return put_user(last, (__s32 __user *)arg); |
---|
| 3298 | + |
---|
| 3299 | + return put_user(last, (long __user *)arg); |
---|
3277 | 3300 | } |
---|
3278 | 3301 | |
---|
3279 | 3302 | static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, |
---|
.. | .. |
---|
3424 | 3447 | EXPORT_SYMBOL(cdrom_open); |
---|
3425 | 3448 | EXPORT_SYMBOL(cdrom_release); |
---|
3426 | 3449 | EXPORT_SYMBOL(cdrom_ioctl); |
---|
3427 | | -EXPORT_SYMBOL(cdrom_media_changed); |
---|
3428 | 3450 | EXPORT_SYMBOL(cdrom_number_of_slots); |
---|
3429 | 3451 | EXPORT_SYMBOL(cdrom_mode_select); |
---|
3430 | 3452 | EXPORT_SYMBOL(cdrom_mode_sense); |
---|
.. | .. |
---|
3495 | 3517 | } |
---|
3496 | 3518 | |
---|
3497 | 3519 | static int cdrom_sysctl_info(struct ctl_table *ctl, int write, |
---|
3498 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
---|
| 3520 | + void *buffer, size_t *lenp, loff_t *ppos) |
---|
3499 | 3521 | { |
---|
3500 | 3522 | int pos; |
---|
3501 | 3523 | char *info = cdrom_sysctl_settings.info; |
---|
.. | .. |
---|
3608 | 3630 | } |
---|
3609 | 3631 | |
---|
3610 | 3632 | static int cdrom_sysctl_handler(struct ctl_table *ctl, int write, |
---|
3611 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
---|
| 3633 | + void *buffer, size_t *lenp, loff_t *ppos) |
---|
3612 | 3634 | { |
---|
3613 | 3635 | int ret; |
---|
3614 | 3636 | |
---|