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

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.net


Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
parent f98e0640
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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,