Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-5.16/cdrom-2021-10-29' of git://git.kernel.dk/linux-block

Pull CDROM updates from Jens Axboe:
"On behalf of Phillip, here are the CDROM updates for the 5.16-rc1
merge window:

- Add ioctl for improved media change detection (Lukas)

- Reformat some documentation (Phillip)

- Redundant variable removal (luo)"

* tag 'for-5.16/cdrom-2021-10-29' of git://git.kernel.dk/linux-block:
cdrom: Remove redundant variable and its assignment
cdrom: docs: reformat table in Documentation/userspace-api/ioctl/cdrom.rst
drivers/cdrom: improved ioctl for media change detection

+146 -61
+11
Documentation/cdrom/cdrom-standard.rst
··· 907 907 specifies the slot for which the information is given. The special 908 908 value *CDSL_CURRENT* requests that information about the currently 909 909 selected slot be returned. 910 + `CDROM_TIMED_MEDIA_CHANGE` 911 + Checks whether the disc has been changed since a user supplied time 912 + and returns the time of the last disc change. 913 + 914 + *arg* is a pointer to a *cdrom_timed_media_change_info* struct. 915 + *arg->last_media_change* may be set by calling code to signal 916 + the timestamp of the last known media change (by the caller). 917 + Upon successful return, this ioctl call will set 918 + *arg->last_media_change* to the latest media change timestamp (in ms) 919 + known by the kernel/driver and set *arg->has_changed* to 1 if 920 + that timestamp is more recent than the timestamp set by the caller. 910 921 `CDROM_DRIVE_STATUS` 911 922 Returns the status of the drive by a call to 912 923 *drive_status()*. Return values are defined in cdrom_drive_status_.
+58 -55
Documentation/userspace-api/ioctl/cdrom.rst
··· 13 13 ioctl values are listed in <linux/cdrom.h>. As of this writing, they 14 14 are as follows: 15 15 16 - ====================== =============================================== 17 - CDROMPAUSE Pause Audio Operation 18 - CDROMRESUME Resume paused Audio Operation 19 - CDROMPLAYMSF Play Audio MSF (struct cdrom_msf) 20 - CDROMPLAYTRKIND Play Audio Track/index (struct cdrom_ti) 21 - CDROMREADTOCHDR Read TOC header (struct cdrom_tochdr) 22 - CDROMREADTOCENTRY Read TOC entry (struct cdrom_tocentry) 23 - CDROMSTOP Stop the cdrom drive 24 - CDROMSTART Start the cdrom drive 25 - CDROMEJECT Ejects the cdrom media 26 - CDROMVOLCTRL Control output volume (struct cdrom_volctrl) 27 - CDROMSUBCHNL Read subchannel data (struct cdrom_subchnl) 28 - CDROMREADMODE2 Read CDROM mode 2 data (2336 Bytes) 29 - (struct cdrom_read) 30 - CDROMREADMODE1 Read CDROM mode 1 data (2048 Bytes) 31 - (struct cdrom_read) 32 - CDROMREADAUDIO (struct cdrom_read_audio) 33 - CDROMEJECT_SW enable(1)/disable(0) auto-ejecting 34 - CDROMMULTISESSION Obtain the start-of-last-session 35 - address of multi session disks 36 - (struct cdrom_multisession) 37 - CDROM_GET_MCN Obtain the "Universal Product Code" 38 - if available (struct cdrom_mcn) 39 - CDROM_GET_UPC Deprecated, use CDROM_GET_MCN instead. 40 - CDROMRESET hard-reset the drive 41 - CDROMVOLREAD Get the drive's volume setting 42 - (struct cdrom_volctrl) 43 - CDROMREADRAW read data in raw mode (2352 Bytes) 44 - (struct cdrom_read) 45 - CDROMREADCOOKED read data in cooked mode 46 - CDROMSEEK seek msf address 47 - CDROMPLAYBLK scsi-cd only, (struct cdrom_blk) 48 - CDROMREADALL read all 2646 bytes 49 - CDROMGETSPINDOWN return 4-bit spindown value 50 - CDROMSETSPINDOWN set 4-bit spindown value 51 - CDROMCLOSETRAY pendant of CDROMEJECT 52 - CDROM_SET_OPTIONS Set behavior options 53 - CDROM_CLEAR_OPTIONS Clear behavior options 54 - CDROM_SELECT_SPEED Set the CD-ROM speed 55 - CDROM_SELECT_DISC Select disc (for juke-boxes) 56 - CDROM_MEDIA_CHANGED Check is media changed 57 - CDROM_DRIVE_STATUS Get tray position, etc. 58 - CDROM_DISC_STATUS Get disc type, etc. 59 - CDROM_CHANGER_NSLOTS Get number of slots 60 - CDROM_LOCKDOOR lock or unlock door 61 - CDROM_DEBUG Turn debug messages on/off 62 - CDROM_GET_CAPABILITY get capabilities 63 - CDROMAUDIOBUFSIZ set the audio buffer size 64 - DVD_READ_STRUCT Read structure 65 - DVD_WRITE_STRUCT Write structure 66 - DVD_AUTH Authentication 67 - CDROM_SEND_PACKET send a packet to the drive 68 - CDROM_NEXT_WRITABLE get next writable block 69 - CDROM_LAST_WRITTEN get last block written on disc 70 - ====================== =============================================== 16 + ======================== =============================================== 17 + CDROMPAUSE Pause Audio Operation 18 + CDROMRESUME Resume paused Audio Operation 19 + CDROMPLAYMSF Play Audio MSF (struct cdrom_msf) 20 + CDROMPLAYTRKIND Play Audio Track/index (struct cdrom_ti) 21 + CDROMREADTOCHDR Read TOC header (struct cdrom_tochdr) 22 + CDROMREADTOCENTRY Read TOC entry (struct cdrom_tocentry) 23 + CDROMSTOP Stop the cdrom drive 24 + CDROMSTART Start the cdrom drive 25 + CDROMEJECT Ejects the cdrom media 26 + CDROMVOLCTRL Control output volume (struct cdrom_volctrl) 27 + CDROMSUBCHNL Read subchannel data (struct cdrom_subchnl) 28 + CDROMREADMODE2 Read CDROM mode 2 data (2336 Bytes) 29 + (struct cdrom_read) 30 + CDROMREADMODE1 Read CDROM mode 1 data (2048 Bytes) 31 + (struct cdrom_read) 32 + CDROMREADAUDIO (struct cdrom_read_audio) 33 + CDROMEJECT_SW enable(1)/disable(0) auto-ejecting 34 + CDROMMULTISESSION Obtain the start-of-last-session 35 + address of multi session disks 36 + (struct cdrom_multisession) 37 + CDROM_GET_MCN Obtain the "Universal Product Code" 38 + if available (struct cdrom_mcn) 39 + CDROM_GET_UPC Deprecated, use CDROM_GET_MCN instead. 40 + CDROMRESET hard-reset the drive 41 + CDROMVOLREAD Get the drive's volume setting 42 + (struct cdrom_volctrl) 43 + CDROMREADRAW read data in raw mode (2352 Bytes) 44 + (struct cdrom_read) 45 + CDROMREADCOOKED read data in cooked mode 46 + CDROMSEEK seek msf address 47 + CDROMPLAYBLK scsi-cd only, (struct cdrom_blk) 48 + CDROMREADALL read all 2646 bytes 49 + CDROMGETSPINDOWN return 4-bit spindown value 50 + CDROMSETSPINDOWN set 4-bit spindown value 51 + CDROMCLOSETRAY pendant of CDROMEJECT 52 + CDROM_SET_OPTIONS Set behavior options 53 + CDROM_CLEAR_OPTIONS Clear behavior options 54 + CDROM_SELECT_SPEED Set the CD-ROM speed 55 + CDROM_SELECT_DISC Select disc (for juke-boxes) 56 + CDROM_MEDIA_CHANGED Check is media changed 57 + CDROM_TIMED_MEDIA_CHANGE Check if media changed 58 + since given time 59 + (struct cdrom_timed_media_change_info) 60 + CDROM_DRIVE_STATUS Get tray position, etc. 61 + CDROM_DISC_STATUS Get disc type, etc. 62 + CDROM_CHANGER_NSLOTS Get number of slots 63 + CDROM_LOCKDOOR lock or unlock door 64 + CDROM_DEBUG Turn debug messages on/off 65 + CDROM_GET_CAPABILITY get capabilities 66 + CDROMAUDIOBUFSIZ set the audio buffer size 67 + DVD_READ_STRUCT Read structure 68 + DVD_WRITE_STRUCT Write structure 69 + DVD_AUTH Authentication 70 + CDROM_SEND_PACKET send a packet to the drive 71 + CDROM_NEXT_WRITABLE get next writable block 72 + CDROM_LAST_WRITTEN get last block written on disc 73 + ======================== =============================================== 71 74 72 75 73 76 The information that follows was determined from reading kernel source
+57 -6
drivers/cdrom/cdrom.c
··· 344 344 345 345 static LIST_HEAD(cdrom_list); 346 346 347 + static void signal_media_change(struct cdrom_device_info *cdi) 348 + { 349 + cdi->mc_flags = 0x3; /* set media changed bits, on both queues */ 350 + cdi->last_media_change_ms = ktime_to_ms(ktime_get()); 351 + } 352 + 347 353 int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, 348 354 struct packet_command *cgc) 349 355 { ··· 622 616 ENSURE(cdo, generic_packet, CDC_GENERIC_PACKET); 623 617 cdi->mc_flags = 0; 624 618 cdi->options = CDO_USE_FFLAGS; 619 + cdi->last_media_change_ms = ktime_to_ms(ktime_get()); 625 620 626 621 if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY)) 627 622 cdi->options |= (int) CDO_AUTO_CLOSE; ··· 871 864 { 872 865 struct packet_command cgc; 873 866 char buffer[32]; 874 - int ret, mmc3_profile; 867 + int mmc3_profile; 875 868 876 869 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ); 877 870 ··· 881 874 cgc.cmd[8] = sizeof(buffer); /* Allocation Length */ 882 875 cgc.quiet = 1; 883 876 884 - if ((ret = cdi->ops->generic_packet(cdi, &cgc))) 877 + if (cdi->ops->generic_packet(cdi, &cgc)) 885 878 mmc3_profile = 0xffff; 886 879 else 887 880 mmc3_profile = (buffer[6] << 8) | buffer[7]; ··· 1428 1421 cdi->ops->check_events(cdi, 0, slot); 1429 1422 1430 1423 if (slot == CDSL_NONE) { 1431 - /* set media changed bits, on both queues */ 1432 - cdi->mc_flags = 0x3; 1424 + signal_media_change(cdi); 1433 1425 return cdrom_load_unload(cdi, -1); 1434 1426 } 1435 1427 ··· 1461 1455 slot = curslot; 1462 1456 1463 1457 /* set media changed bits on both queues */ 1464 - cdi->mc_flags = 0x3; 1458 + signal_media_change(cdi); 1465 1459 if ((ret = cdrom_load_unload(cdi, slot))) 1466 1460 return ret; 1467 1461 ··· 1527 1521 cdi->ioctl_events = 0; 1528 1522 1529 1523 if (changed) { 1530 - cdi->mc_flags = 0x3; /* set bit on both queues */ 1524 + signal_media_change(cdi); 1531 1525 ret |= 1; 1532 1526 cdi->media_written = 0; 1533 1527 } ··· 2340 2334 ret = info->slots[arg].change; 2341 2335 kfree(info); 2342 2336 return ret; 2337 + } 2338 + 2339 + /* 2340 + * Media change detection with timing information. 2341 + * 2342 + * arg is a pointer to a cdrom_timed_media_change_info struct. 2343 + * arg->last_media_change may be set by calling code to signal 2344 + * the timestamp (in ms) of the last known media change (by the caller). 2345 + * Upon successful return, ioctl call will set arg->last_media_change 2346 + * to the latest media change timestamp known by the kernel/driver 2347 + * and set arg->has_changed to 1 if that timestamp is more recent 2348 + * than the timestamp set by the caller. 2349 + */ 2350 + static int cdrom_ioctl_timed_media_change(struct cdrom_device_info *cdi, 2351 + unsigned long arg) 2352 + { 2353 + int ret; 2354 + struct cdrom_timed_media_change_info __user *info; 2355 + struct cdrom_timed_media_change_info tmp_info; 2356 + 2357 + if (!CDROM_CAN(CDC_MEDIA_CHANGED)) 2358 + return -ENOSYS; 2359 + 2360 + info = (struct cdrom_timed_media_change_info __user *)arg; 2361 + cd_dbg(CD_DO_IOCTL, "entering CDROM_TIMED_MEDIA_CHANGE\n"); 2362 + 2363 + ret = cdrom_ioctl_media_changed(cdi, CDSL_CURRENT); 2364 + if (ret < 0) 2365 + return ret; 2366 + 2367 + if (copy_from_user(&tmp_info, info, sizeof(tmp_info)) != 0) 2368 + return -EFAULT; 2369 + 2370 + tmp_info.media_flags = 0; 2371 + if (tmp_info.last_media_change - cdi->last_media_change_ms < 0) 2372 + tmp_info.media_flags |= MEDIA_CHANGED_FLAG; 2373 + 2374 + tmp_info.last_media_change = cdi->last_media_change_ms; 2375 + 2376 + if (copy_to_user(info, &tmp_info, sizeof(*info)) != 0) 2377 + return -EFAULT; 2378 + 2379 + return 0; 2343 2380 } 2344 2381 2345 2382 static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi, ··· 3362 3313 return cdrom_ioctl_eject_sw(cdi, arg); 3363 3314 case CDROM_MEDIA_CHANGED: 3364 3315 return cdrom_ioctl_media_changed(cdi, arg); 3316 + case CDROM_TIMED_MEDIA_CHANGE: 3317 + return cdrom_ioctl_timed_media_change(cdi, arg); 3365 3318 case CDROM_SET_OPTIONS: 3366 3319 return cdrom_ioctl_set_options(cdi, arg); 3367 3320 case CDROM_CLEAR_OPTIONS:
+1
include/linux/cdrom.h
··· 64 64 int for_data; 65 65 int (*exit)(struct cdrom_device_info *); 66 66 int mrw_mode_page; 67 + __s64 last_media_change_ms; 67 68 }; 68 69 69 70 struct cdrom_device_ops {
+19
include/uapi/linux/cdrom.h
··· 147 147 #define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */ 148 148 #define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */ 149 149 150 + #define CDROM_TIMED_MEDIA_CHANGE 0x5396 /* get the timestamp of the last media change */ 151 + 150 152 /******************************************************* 151 153 * CDROM IOCTL structures 152 154 *******************************************************/ ··· 296 294 void __user *unused; 297 295 }; 298 296 }; 297 + 298 + /* This struct is used by CDROM_TIMED_MEDIA_CHANGE */ 299 + struct cdrom_timed_media_change_info { 300 + __s64 last_media_change; /* Timestamp of the last detected media 301 + * change in ms. May be set by caller, 302 + * updated upon successful return of 303 + * ioctl. 304 + */ 305 + __u64 media_flags; /* Flags returned by ioctl to indicate 306 + * media status. 307 + */ 308 + }; 309 + #define MEDIA_CHANGED_FLAG 0x1 /* Last detected media change was more 310 + * recent than last_media_change set by 311 + * caller. 312 + */ 313 + /* other bits of media_flags available for future use */ 299 314 300 315 /* 301 316 * A CD-ROM physical sector size is 2048, 2052, 2056, 2324, 2332, 2336,