Commit 0a4db185 authored by Bastien Nocera's avatar Bastien Nocera Committed by Benjamin Tissoires

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: default avatarBastien Nocera <hadess@hadess.net>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Link: https://lore.kernel.org/r/20230302105555.51417-5-hadess@hadess.netSigned-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
parent f98e0640
......@@ -1908,6 +1908,45 @@ static void __usb_queue_reset_device(struct work_struct *ws)
usb_put_intf(iface); /* Undo _get_ in usb_queue_reset_device() */
}
/*
* Internal function to set the wireless_status sysfs attribute
* See usb_set_wireless_status() for more details
*/
static void __usb_wireless_status_intf(struct work_struct *ws)
{
struct usb_interface *iface =
container_of(ws, struct usb_interface, wireless_status_work);
device_lock(iface->dev.parent);
if (iface->sysfs_files_created)
usb_update_wireless_status_attr(iface);
device_unlock(iface->dev.parent);
usb_put_intf(iface); /* Undo _get_ in usb_set_wireless_status() */
}
/**
* usb_set_wireless_status - sets the wireless_status struct member
* @dev: the device to modify
* @status: the new wireless status
*
* Set the wireless_status struct member to the new value, and emit
* sysfs changes as necessary.
*
* Returns: 0 on success, -EALREADY if already set.
*/
int usb_set_wireless_status(struct usb_interface *iface,
enum usb_wireless_status status)
{
if (iface->wireless_status == status)
return -EALREADY;
usb_get_intf(iface);
iface->wireless_status = status;
schedule_work(&iface->wireless_status_work);
return 0;
}
EXPORT_SYMBOL_GPL(usb_set_wireless_status);
/*
* usb_set_configuration - Makes a particular device setting be current
......@@ -2100,6 +2139,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.type = &usb_if_device_type;
intf->dev.groups = usb_interface_groups;
INIT_WORK(&intf->reset_ws, __usb_queue_reset_device);
INIT_WORK(&intf->wireless_status_work, __usb_wireless_status_intf);
intf->minor = -1;
device_initialize(&intf->dev);
pm_runtime_no_callbacks(&intf->dev);
......
......@@ -262,6 +262,7 @@ struct usb_interface {
unsigned resetting_device:1; /* true: bandwidth alloc after reset */
unsigned authorized:1; /* used for interface authorization */
enum usb_wireless_status wireless_status;
struct work_struct wireless_status_work;
struct device dev; /* interface specific device info */
struct device *usb_dev;
......@@ -896,6 +897,10 @@ static inline int usb_interface_claimed(struct usb_interface *iface)
extern void usb_driver_release_interface(struct usb_driver *driver,
struct usb_interface *iface);
int usb_set_wireless_status(struct usb_interface *iface,
enum usb_wireless_status status);
const struct usb_device_id *usb_match_id(struct usb_interface *interface,
const struct usb_device_id *id);
extern int usb_match_one_id(struct usb_interface *interface,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment