Skip to content

Commit 0a4db18

Browse files
hadessbentiss
authored andcommitted
USB: core: Add API to change the wireless_status
This adds the API that allows device specific drivers to tell user-space about whether the wireless device is connected to its receiver dongle. See "USB: core: Add wireless_status sysfs attribute" for a detailed explanation of what this attribute should be used for. Signed-off-by: Bastien Nocera <hadess@hadess.net> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Alan Stern <stern@rowland.harvard.edu> Link: https://lore.kernel.org/r/20230302105555.51417-5-hadess@hadess.net Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
1 parent f98e064 commit 0a4db18

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

drivers/usb/core/message.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,45 @@ static void __usb_queue_reset_device(struct work_struct *ws)
19081908
usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */
19091909
}
19101910

1911+
/*
1912+
* Internal function to set the wireless_status sysfs attribute
1913+
* See usb_set_wireless_status() for more details
1914+
*/
1915+
static void __usb_wireless_status_intf(struct work_struct *ws)
1916+
{
1917+
struct usb_interface *iface =
1918+
container_of(ws, struct usb_interface, wireless_status_work);
1919+
1920+
device_lock(iface->dev.parent);
1921+
if (iface->sysfs_files_created)
1922+
usb_update_wireless_status_attr(iface);
1923+
device_unlock(iface->dev.parent);
1924+
usb_put_intf(iface); /* Undo _get_ in usb_set_wireless_status() */
1925+
}
1926+
1927+
/**
1928+
* usb_set_wireless_status - sets the wireless_status struct member
1929+
* @dev: the device to modify
1930+
* @status: the new wireless status
1931+
*
1932+
* Set the wireless_status struct member to the new value, and emit
1933+
* sysfs changes as necessary.
1934+
*
1935+
* Returns: 0 on success, -EALREADY if already set.
1936+
*/
1937+
int usb_set_wireless_status(struct usb_interface *iface,
1938+
enum usb_wireless_status status)
1939+
{
1940+
if (iface->wireless_status == status)
1941+
return -EALREADY;
1942+
1943+
usb_get_intf(iface);
1944+
iface->wireless_status = status;
1945+
schedule_work(&iface->wireless_status_work);
1946+
1947+
return 0;
1948+
}
1949+
EXPORT_SYMBOL_GPL(usb_set_wireless_status);
19111950

19121951
/*
19131952
* usb_set_configuration - Makes a particular device setting be current
@@ -2100,6 +2139,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
21002139
intf->dev.type = &usb_if_device_type;
21012140
intf->dev.groups = usb_interface_groups;
21022141
INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
2142+
INIT_WORK(&intf->wireless_status_work, __usb_wireless_status_intf);
21032143
intf->minor = -1;
21042144
device_initialize(&intf->dev);
21052145
pm_runtime_no_callbacks(&intf->dev);

include/linux/usb.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ struct usb_interface {
262262
unsigned resetting_device:1; /* true: bandwidth alloc after reset */
263263
unsigned authorized:1; /* used for interface authorization */
264264
enum usb_wireless_status wireless_status;
265+
struct work_struct wireless_status_work;
265266

266267
struct device dev; /* interface specific device info */
267268
struct device *usb_dev;
@@ -896,6 +897,10 @@ static inline int usb_interface_claimed(struct usb_interface *iface)
896897

897898
extern void usb_driver_release_interface(struct usb_driver *driver,
898899
struct usb_interface *iface);
900+
901+
int usb_set_wireless_status(struct usb_interface *iface,
902+
enum usb_wireless_status status);
903+
899904
const struct usb_device_id *usb_match_id(struct usb_interface *interface,
900905
const struct usb_device_id *id);
901906
extern int usb_match_one_id(struct usb_interface *interface,

0 commit comments

Comments
 (0)