2020-03-28 09:18:50 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
2016-10-28 21:16:36 +00:00
|
|
|
/*
|
|
|
|
* Released under the GPLv2 only.
|
|
|
|
*/
|
|
|
|
|
2008-11-25 21:39:18 +00:00
|
|
|
#include <linux/pm.h>
|
2012-09-05 05:44:33 +00:00
|
|
|
#include <linux/acpi.h>
|
2008-11-25 21:39:18 +00:00
|
|
|
|
2013-01-21 14:18:00 +00:00
|
|
|
struct usb_hub_descriptor;
|
2014-03-10 08:36:40 +00:00
|
|
|
struct usb_dev_state;
|
2012-07-06 06:13:52 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* Functions local to drivers/usb/core/ */
|
|
|
|
|
2008-01-30 23:21:33 +00:00
|
|
|
extern int usb_create_sysfs_dev_files(struct usb_device *dev);
|
|
|
|
extern void usb_remove_sysfs_dev_files(struct usb_device *dev);
|
2011-04-14 15:47:09 +00:00
|
|
|
extern void usb_create_sysfs_intf_files(struct usb_interface *intf);
|
2008-01-30 23:21:33 +00:00
|
|
|
extern void usb_remove_sysfs_intf_files(struct usb_interface *intf);
|
USB: core: Add wireless_status sysfs attribute
JIRA: https://issues.redhat.com/browse/RHEL-13058
commit f98e0640c5c6b8bb00336dae8d06ede862754c28
Author: Bastien Nocera <hadess@hadess.net>
Date: Thu, 2 Mar 2023 11:55:53 +0100
Add a wireless_status sysfs attribute to USB devices to keep track of
whether a USB device that's comprised of a receiver dongle and an emitter
device over a, most of the time proprietary, wireless link has its emitter
connected or disconnected.
This will be used by user-space OS components to determine whether the
battery-powered part of the device is wirelessly connected or not,
allowing, for example:
- upower to hide the battery for devices where the device is turned off
but the receiver plugged in, rather than showing 0%, or other values
that could be confusing to users
- Pipewire to hide a headset from the list of possible inputs or outputs
or route audio appropriately if the headset is suddenly turned off, or
turned on
- libinput to determine whether a keyboard or mouse is present when its
receiver is plugged in.
This is done at the USB interface level as:
- the interface on which the wireless status is detected is sometimes
not the same as where it could be consumed (eg. the audio interface
on a headset dongle will still appear even if the headset is turned
off), and we cannot have synchronisation of status across subsystems.
- this behaviour is not specific to HID devices, even if the protocols
used to determine whether or not the remote device is connected can
be HID.
This is not an attribute that is meant to replace protocol specific
APIs, such as the ones available for WWAN, WLAN/Wi-Fi, or Bluetooth
or any other sort of networking, but solely for wireless devices with
an ad-hoc “lose it and your device is e-waste” receiver dongle.
The USB interface will only be exporting the wireless_status sysfs
attribute if it gets set through the API exported in the next commit.
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-4-hadess@hadess.net
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Desnes Nunes <desnesn@redhat.com>
2023-10-27 13:39:19 +00:00
|
|
|
extern int usb_update_wireless_status_attr(struct usb_interface *intf);
|
2008-12-05 19:10:34 +00:00
|
|
|
extern int usb_create_ep_devs(struct device *parent,
|
2008-01-30 23:21:33 +00:00
|
|
|
struct usb_host_endpoint *endpoint,
|
2006-06-14 19:14:34 +00:00
|
|
|
struct usb_device *udev);
|
2008-12-05 19:10:34 +00:00
|
|
|
extern void usb_remove_ep_devs(struct usb_host_endpoint *endpoint);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-07-30 21:05:22 +00:00
|
|
|
extern void usb_enable_endpoint(struct usb_device *dev,
|
2008-12-31 16:31:33 +00:00
|
|
|
struct usb_host_endpoint *ep, bool reset_toggle);
|
|
|
|
extern void usb_enable_interface(struct usb_device *dev,
|
|
|
|
struct usb_interface *intf, bool reset_toggles);
|
2009-01-15 22:03:33 +00:00
|
|
|
extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr,
|
|
|
|
bool reset_hardware);
|
2008-01-30 23:21:33 +00:00
|
|
|
extern void usb_disable_interface(struct usb_device *dev,
|
2009-01-15 22:03:33 +00:00
|
|
|
struct usb_interface *intf, bool reset_hardware);
|
2005-04-16 22:20:36 +00:00
|
|
|
extern void usb_release_interface_cache(struct kref *ref);
|
2008-01-30 23:21:33 +00:00
|
|
|
extern void usb_disable_device(struct usb_device *dev, int skip_ep0);
|
|
|
|
extern int usb_deauthorize_device(struct usb_device *);
|
|
|
|
extern int usb_authorize_device(struct usb_device *);
|
2015-08-25 19:10:08 +00:00
|
|
|
extern void usb_deauthorize_interface(struct usb_interface *);
|
|
|
|
extern void usb_authorize_interface(struct usb_interface *);
|
2007-01-26 13:26:21 +00:00
|
|
|
extern void usb_detect_quirks(struct usb_device *udev);
|
2012-07-19 10:39:13 +00:00
|
|
|
extern void usb_detect_interface_quirks(struct usb_device *udev);
|
2018-03-19 16:26:06 +00:00
|
|
|
extern void usb_release_quirk_list(void);
|
2020-06-18 09:42:53 +00:00
|
|
|
extern bool usb_endpoint_is_ignored(struct usb_device *udev,
|
2020-02-03 15:38:28 +00:00
|
|
|
struct usb_host_interface *intf,
|
|
|
|
struct usb_endpoint_descriptor *epd);
|
2009-10-27 19:20:13 +00:00
|
|
|
extern int usb_remove_device(struct usb_device *udev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2023-10-13 18:39:47 +00:00
|
|
|
extern struct usb_device_descriptor *usb_get_device_descriptor(
|
|
|
|
struct usb_device *udev);
|
2017-12-14 07:50:39 +00:00
|
|
|
extern int usb_set_isoch_delay(struct usb_device *dev);
|
2011-09-23 21:19:47 +00:00
|
|
|
extern int usb_get_bos_descriptor(struct usb_device *dev);
|
|
|
|
extern void usb_release_bos_descriptor(struct usb_device *dev);
|
2005-04-16 22:20:36 +00:00
|
|
|
extern int usb_set_configuration(struct usb_device *dev, int configuration);
|
2007-08-03 04:44:27 +00:00
|
|
|
extern int usb_choose_configuration(struct usb_device *udev);
|
2019-10-16 09:39:28 +00:00
|
|
|
extern int usb_generic_driver_probe(struct usb_device *udev);
|
|
|
|
extern void usb_generic_driver_disconnect(struct usb_device *udev);
|
|
|
|
extern int usb_generic_driver_suspend(struct usb_device *udev,
|
|
|
|
pm_message_t msg);
|
|
|
|
extern int usb_generic_driver_resume(struct usb_device *udev,
|
|
|
|
pm_message_t msg);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2012-12-18 14:25:46 +00:00
|
|
|
static inline unsigned usb_get_max_power(struct usb_device *udev,
|
|
|
|
struct usb_host_config *c)
|
|
|
|
{
|
|
|
|
/* SuperSpeed power is in 8 mA units; others are in 2 mA units */
|
2015-12-10 07:59:25 +00:00
|
|
|
unsigned mul = (udev->speed >= USB_SPEED_SUPER ? 8 : 2);
|
2012-12-18 14:25:46 +00:00
|
|
|
|
|
|
|
return c->desc.bMaxPower * mul;
|
|
|
|
}
|
|
|
|
|
2014-09-19 15:32:22 +00:00
|
|
|
extern void usb_kick_hub_wq(struct usb_device *dev);
|
2012-07-19 10:39:13 +00:00
|
|
|
extern int usb_match_one_id_intf(struct usb_device *dev,
|
|
|
|
struct usb_host_interface *intf,
|
|
|
|
const struct usb_device_id *id);
|
2007-01-26 13:26:21 +00:00
|
|
|
extern int usb_match_device(struct usb_device *dev,
|
|
|
|
const struct usb_device_id *id);
|
2019-10-16 09:39:30 +00:00
|
|
|
extern const struct usb_device_id *usb_device_match_id(struct usb_device *udev,
|
|
|
|
const struct usb_device_id *id);
|
2020-10-22 13:55:20 +00:00
|
|
|
extern bool usb_driver_applicable(struct usb_device *udev,
|
2025-03-19 18:50:38 +00:00
|
|
|
const struct usb_device_driver *udrv);
|
2008-06-23 20:00:40 +00:00
|
|
|
extern void usb_forced_unbind_intf(struct usb_interface *intf);
|
2014-03-12 15:30:38 +00:00
|
|
|
extern void usb_unbind_and_rebind_marked_interfaces(struct usb_device *udev);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2012-07-06 06:13:52 +00:00
|
|
|
extern void usb_hub_release_all_ports(struct usb_device *hdev,
|
2014-03-10 08:36:40 +00:00
|
|
|
struct usb_dev_state *owner);
|
2009-06-29 14:56:54 +00:00
|
|
|
extern bool usb_device_is_owned(struct usb_device *udev);
|
|
|
|
|
2005-04-19 00:39:24 +00:00
|
|
|
extern int usb_hub_init(void);
|
|
|
|
extern void usb_hub_cleanup(void);
|
|
|
|
extern int usb_major_init(void);
|
|
|
|
extern void usb_major_cleanup(void);
|
2015-06-16 01:08:26 +00:00
|
|
|
extern int usb_device_supports_lpm(struct usb_device *udev);
|
2017-10-18 07:15:01 +00:00
|
|
|
extern int usb_port_disable(struct usb_device *udev);
|
2005-04-19 00:39:24 +00:00
|
|
|
|
2006-07-02 02:14:24 +00:00
|
|
|
#ifdef CONFIG_PM
|
|
|
|
|
2008-08-12 18:34:10 +00:00
|
|
|
extern int usb_suspend(struct device *dev, pm_message_t msg);
|
2008-11-25 21:39:18 +00:00
|
|
|
extern int usb_resume(struct device *dev, pm_message_t msg);
|
2012-01-11 07:38:35 +00:00
|
|
|
extern int usb_resume_complete(struct device *dev);
|
2008-08-12 18:34:10 +00:00
|
|
|
|
2008-11-25 21:39:18 +00:00
|
|
|
extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg);
|
|
|
|
extern int usb_port_resume(struct usb_device *dev, pm_message_t msg);
|
2006-09-26 18:50:20 +00:00
|
|
|
|
2014-11-29 22:47:05 +00:00
|
|
|
extern void usb_autosuspend_device(struct usb_device *udev);
|
|
|
|
extern int usb_autoresume_device(struct usb_device *udev);
|
|
|
|
extern int usb_remote_wakeup(struct usb_device *dev);
|
|
|
|
extern int usb_runtime_suspend(struct device *dev);
|
|
|
|
extern int usb_runtime_resume(struct device *dev);
|
|
|
|
extern int usb_runtime_idle(struct device *dev);
|
2019-01-11 19:54:24 +00:00
|
|
|
extern int usb_enable_usb2_hardware_lpm(struct usb_device *udev);
|
|
|
|
extern int usb_disable_usb2_hardware_lpm(struct usb_device *udev);
|
2014-11-29 22:47:05 +00:00
|
|
|
|
2019-08-07 14:29:50 +00:00
|
|
|
extern void usbfs_notify_suspend(struct usb_device *udev);
|
|
|
|
extern void usbfs_notify_resume(struct usb_device *udev);
|
|
|
|
|
2006-07-02 02:14:24 +00:00
|
|
|
#else
|
|
|
|
|
2008-11-25 21:39:18 +00:00
|
|
|
static inline int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
2007-05-30 20:51:28 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-11-25 21:39:18 +00:00
|
|
|
static inline int usb_port_resume(struct usb_device *udev, pm_message_t msg)
|
2007-05-30 20:51:28 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-02-20 20:03:32 +00:00
|
|
|
#define usb_autosuspend_device(udev) do {} while (0)
|
2006-11-20 16:38:46 +00:00
|
|
|
static inline int usb_autoresume_device(struct usb_device *udev)
|
2006-09-26 18:50:20 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2006-08-30 19:47:02 +00:00
|
|
|
|
2019-01-11 19:54:24 +00:00
|
|
|
static inline int usb_enable_usb2_hardware_lpm(struct usb_device *udev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int usb_disable_usb2_hardware_lpm(struct usb_device *udev)
|
2011-09-23 21:19:52 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2014-11-29 22:47:05 +00:00
|
|
|
|
2006-08-30 19:47:02 +00:00
|
|
|
#endif
|
|
|
|
|
2024-03-18 18:27:27 +00:00
|
|
|
extern const struct class usbmisc_class;
|
2024-03-18 18:27:26 +00:00
|
|
|
extern const struct bus_type usb_bus_type;
|
2014-05-21 01:08:28 +00:00
|
|
|
extern struct mutex usb_port_peer_mutex;
|
2024-06-10 17:28:39 +00:00
|
|
|
extern const struct device_type usb_device_type;
|
|
|
|
extern const struct device_type usb_if_device_type;
|
|
|
|
extern const struct device_type usb_ep_device_type;
|
|
|
|
extern const struct device_type usb_port_device_type;
|
2006-07-02 02:08:49 +00:00
|
|
|
extern struct usb_device_driver usb_generic_driver;
|
|
|
|
|
2006-08-27 02:48:11 +00:00
|
|
|
static inline int is_usb_device(const struct device *dev)
|
2006-07-02 02:08:49 +00:00
|
|
|
{
|
2007-03-13 14:59:31 +00:00
|
|
|
return dev->type == &usb_device_type;
|
2006-07-02 02:08:49 +00:00
|
|
|
}
|
|
|
|
|
2009-05-04 17:48:32 +00:00
|
|
|
static inline int is_usb_interface(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->type == &usb_if_device_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int is_usb_endpoint(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->type == &usb_ep_device_type;
|
|
|
|
}
|
|
|
|
|
2012-09-05 05:44:33 +00:00
|
|
|
static inline int is_usb_port(const struct device *dev)
|
|
|
|
{
|
|
|
|
return dev->type == &usb_port_device_type;
|
|
|
|
}
|
|
|
|
|
2019-08-06 11:00:50 +00:00
|
|
|
static inline int is_root_hub(struct usb_device *udev)
|
|
|
|
{
|
|
|
|
return (udev->parent == NULL);
|
|
|
|
}
|
|
|
|
|
2024-05-17 15:00:23 +00:00
|
|
|
extern bool is_usb_device_driver(const struct device_driver *drv);
|
2005-09-23 05:45:26 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* for labeling diagnostics */
|
|
|
|
extern const char *usbcore_name;
|
|
|
|
|
2008-04-30 19:37:19 +00:00
|
|
|
/* sysfs stuff */
|
2009-06-24 17:06:31 +00:00
|
|
|
extern const struct attribute_group *usb_device_groups[];
|
|
|
|
extern const struct attribute_group *usb_interface_groups[];
|
2008-04-30 19:37:19 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* usbfs stuff */
|
|
|
|
extern struct usb_driver usbfs_driver;
|
2006-08-05 23:37:11 +00:00
|
|
|
extern const struct file_operations usbfs_devices_fops;
|
2007-03-13 14:59:31 +00:00
|
|
|
extern const struct file_operations usbdev_file_operations;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-03-13 14:59:31 +00:00
|
|
|
extern int usb_devio_init(void);
|
|
|
|
extern void usb_devio_cleanup(void);
|
2005-04-19 00:39:24 +00:00
|
|
|
|
2014-05-21 01:08:40 +00:00
|
|
|
/*
|
|
|
|
* Firmware specific cookie identifying a port's location. '0' == no location
|
|
|
|
* data available
|
|
|
|
*/
|
|
|
|
typedef u32 usb_port_location_t;
|
|
|
|
|
2005-06-21 04:15:16 +00:00
|
|
|
/* internal notify stuff */
|
|
|
|
extern void usb_notify_add_device(struct usb_device *udev);
|
|
|
|
extern void usb_notify_remove_device(struct usb_device *udev);
|
|
|
|
extern void usb_notify_add_bus(struct usb_bus *ubus);
|
|
|
|
extern void usb_notify_remove_bus(struct usb_bus *ubus);
|
2013-01-21 14:18:00 +00:00
|
|
|
extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
|
|
|
|
struct usb_hub_descriptor *desc);
|
2005-06-21 04:15:16 +00:00
|
|
|
|
2012-05-11 08:08:27 +00:00
|
|
|
#ifdef CONFIG_ACPI
|
|
|
|
extern int usb_acpi_register(void);
|
|
|
|
extern void usb_acpi_unregister(void);
|
2012-09-05 05:44:33 +00:00
|
|
|
extern acpi_handle usb_get_hub_port_acpi_handle(struct usb_device *hdev,
|
|
|
|
int port1);
|
2012-05-11 08:08:27 +00:00
|
|
|
#else
|
|
|
|
static inline int usb_acpi_register(void) { return 0; };
|
|
|
|
static inline void usb_acpi_unregister(void) { };
|
|
|
|
#endif
|