Re: Re: Re: Re: [PATCH] USB: add usbfs ioctl to get specific superspeedplus rates

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Aug 19, 2023 at 12:32:43PM +0800, Dingyan Li wrote:
> 
> At 2023-08-04 22:55:49, "Alan Stern" <stern@xxxxxxxxxxxxxxxxxxx> wrote:
> 
> >> Another issue is that USB_SPEED_SUPER_PLUS has been widely used in
> >> so many files to execute conditional banches. Once we extend and store device's
> >> speed with new values in the first place, we might need to check all places where
> >> USB_SPEED_SUPER_PLUS is used in case of any regression.
> >
> >Certainly.  That's part of auditing all the current users of 
> >usb_device_speed.
> 
> This might not be a good idea and feels kind of drift away from what we originally
> want to do. Besides, suppose later new speed values are added, someone still has
> to revisit all the files to modify those checks. I think we should try to avoid this situation.

That's bad reasoning.  If you're worried that existing code will stop 
working right when a new speed designation is added then you _have_ to 
audit the code sooner or later.

> >> I think maybe we can try to remove the dependency on enum usb_device_speed
> >> in usbfs and define a separate set of speed values similar to previous design
> >> at https://www.spinics.net/lists/linux-usb/msg157709.html
> >> By this way, in usbfs we get more freedom to determine how to explain
> >> usb_device_speed and usb_ssp_rate, without the risk of breaking anything
> >> elsewhere.
> >> 
> >> For example, define an USBDEVFS_SPEED_SUPER_PLUS to indicate
> >> USB_SPEED_SUPER_PLUS with ssp rates GEN_UNKNOWN, GEN_2x1 and
> >> GEN_1x2. They all stand for 10Gbps and we don't need to tell one from
> >> another, similar to how it works in sysfs. Then define an
> >> USBDEVFS_SPEED_SUPER_PLUS_BY2(maybe there is a more proper name)
> >> to indicate USB_SPEED_SUPER_PLUS with ssp rate GEN_2x2, which stands
> >> for 20Gbps.
> >
> >You can't really do that.  The values returned by the USBDEVFS_GET_SPEED 
> >ioctl are the ones defined in include/uapi/linux/usb/ch9.h.  They are 
> >USB_SPEED_UNKNOWN, etc., not USBDEVFS_SPEED_UNKNOWN, etc.  The only way 
> >to extend them is by adding new entries to enum usb_device_speed.
> >
> >For example, you must not do anything that would break a user program 
> >which does something like this:
> >
> >#include <linux/usbdevfs.h>
> >#include <linux/usb/ch9.h>
> >
> >...
> >
> >	enum usb_device_speed s;
> >
> >	s = ioctl(fd, USBDEVFS_GET_SPEED);
> >	if (s == USB_SPEED_HIGH) ...
> >
> >Alan Stern
> 
> Since those speed definitions are just int values, we could manage to maintain the compatibility
> by keeping the same value.

No.  The values would be the same, but someone who tried to compile an 
old program under a new kernel would get an error because USB_SPEED_HIGH 
would be undefined.  The update would be binary-compatible but it 
wouldn't be source-compatible.

>  But anyway, my latest idea is not to extend enum usb_device_speed.
> There are three basic cases:
> 1) When speed is less than USB_SPEED_SUPER_PLUS, just return dev->speed;
> 2) When speed is USB_SPEED_SUPER_PLUS but ssp_rate is less than USB_SSP_GEN_2x2,
> return dev->speed;
> 3) When speed is USB_SPEED_SUPER_PLUS and ssp_rate is USB_SSP_GEN_2x2, a new
> speed for usbdevfs should be #defined and let's call it USBDEVFS_SPEED_SUPER_PLUS_BY2.
> This value won't be overlapped with any value in enum usb_device_speed, for example 7.
> In this case, return USBDEVFS_SPEED_SUPER_PLUS_BY2.
> 
> The code could be like:
> 
>         case USBDEVFS_GET_SPEED:
>                 ret = ps->dev->speed;
> +               if (ret == USB_SPEED_SUPER_PLUS &&
> +                               ps->dev->ssp_rate == USB_SSP_GEN_2x2)
> +                       ret = USBDEVFS_SPEED_SUPER_PLUS_BY2;
>                 break;
> 
> By this way, no need to add a new ioctl. No need to touch so many files.

If you do it my way (add new entries to enum usb_device_speed) then you 
wouldn't need a new ioctl.  And if one way requires touching a bunch of 
files, so does the other way.

>  And when new
> speeds are added later, just #define new values and extend the checks in above code.
> Compatibility is also maintained. Before this change, USBDEVFS_GET_SPEED could
> return 0-6. After this change, we can still return 0-6 for most of the cases, and 7 for
> GEN_2x2 devices.

The same would be true if you take my advice.

Alan Stern



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux