hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/cdrom/cdrom.c
....@@ -7,7 +7,7 @@
77 License. See linux/COPYING for more information.
88
99 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.
1111
1212 The routines in the file provide a uniform interface between the
1313 software that uses CD-ROMs and the various low-level drivers that
....@@ -586,7 +586,7 @@
586586 return 0;
587587 }
588588
589
-int register_cdrom(struct cdrom_device_info *cdi)
589
+int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi)
590590 {
591591 static char banner_printed;
592592 const struct cdrom_device_ops *cdo = cdi->ops;
....@@ -601,8 +601,11 @@
601601 cdrom_sysctl_register();
602602 }
603603
604
+ cdi->disk = disk;
605
+ disk->cdi = cdi;
606
+
604607 ENSURE(cdo, drive_status, CDC_DRIVE_STATUS);
605
- if (cdo->check_events == NULL && cdo->media_changed == NULL)
608
+ if (cdo->check_events == NULL)
606609 WARN_ON_ONCE(cdo->capability & (CDC_MEDIA_CHANGED | CDC_SELECT_DISC));
607610 ENSURE(cdo, tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
608611 ENSURE(cdo, lock_door, CDC_LOCK);
....@@ -1416,8 +1419,6 @@
14161419
14171420 if (cdi->ops->check_events)
14181421 cdi->ops->check_events(cdi, 0, slot);
1419
- else
1420
- cdi->ops->media_changed(cdi, slot);
14211422
14221423 if (slot == CDSL_NONE) {
14231424 /* set media changed bits, on both queues */
....@@ -1514,13 +1515,10 @@
15141515 return ret;
15151516
15161517 /* 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;
15241522
15251523 if (changed) {
15261524 cdi->mc_flags = 0x3; /* set bit on both queues */
....@@ -1530,18 +1528,6 @@
15301528
15311529 cdi->mc_flags &= ~mask; /* clear bit */
15321530 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);
15451531 }
15461532
15471533 /* Requests to the low-level drivers will /always/ be done in the
....@@ -2292,37 +2278,46 @@
22922278 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
22932279 }
22942280
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)
22972283 {
2298
- struct cdrom_multisession ms_info;
22992284 u8 requested_format;
23002285 int ret;
2301
-
2302
- cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
23032286
23042287 if (!(cdi->ops->capability & CDC_MULTI_SESSION))
23052288 return -ENOSYS;
23062289
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;
23112291 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
23122292 return -EINVAL;
2313
- ms_info.addr_format = CDROM_LBA;
2293
+ info->addr_format = CDROM_LBA;
23142294
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);
23162314 if (ret)
23172315 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)))
23222317 return -EFAULT;
23232318
23242319 cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
2325
- return 0;
2320
+ return ret;
23262321 }
23272322
23282323 static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
....@@ -2663,32 +2658,37 @@
26632658 return 0;
26642659 }
26652660
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
+
26662680 static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
26672681 void __user *argp)
26682682 {
26692683 struct cdrom_tocentry entry;
2670
- u8 requested_format;
26712684 int ret;
2672
-
2673
- /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
26742685
26752686 if (copy_from_user(&entry, argp, sizeof(entry)))
26762687 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)))
26892690 return -EFAULT;
2690
- /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
2691
- return 0;
2691
+ return ret;
26922692 }
26932693
26942694 static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
....@@ -3017,9 +3017,31 @@
30173017 struct cdrom_read_audio ra;
30183018 int lba;
30193019
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
+ }
30233045
30243046 if (ra.addr_format == CDROM_MSF)
30253047 lba = msf_to_lba(ra.addr.msf.minute,
....@@ -3271,9 +3293,10 @@
32713293 ret = cdrom_get_last_written(cdi, &last);
32723294 if (ret)
32733295 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);
32773300 }
32783301
32793302 static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
....@@ -3424,7 +3447,6 @@
34243447 EXPORT_SYMBOL(cdrom_open);
34253448 EXPORT_SYMBOL(cdrom_release);
34263449 EXPORT_SYMBOL(cdrom_ioctl);
3427
-EXPORT_SYMBOL(cdrom_media_changed);
34283450 EXPORT_SYMBOL(cdrom_number_of_slots);
34293451 EXPORT_SYMBOL(cdrom_mode_select);
34303452 EXPORT_SYMBOL(cdrom_mode_sense);
....@@ -3495,7 +3517,7 @@
34953517 }
34963518
34973519 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)
34993521 {
35003522 int pos;
35013523 char *info = cdrom_sysctl_settings.info;
....@@ -3608,7 +3630,7 @@
36083630 }
36093631
36103632 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)
36123634 {
36133635 int ret;
36143636