From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Mon, 4 May 2015 11:30:54 -0600 Subject: [U-Boot] [PATCH 01/24] usb: add device connection/disconnection detection Message-ID: <1430760687-28505-2-git-send-email-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de From: Vincent Palatin Provide a function to detect USB device insertion/removal in order to avoid having to do USB enumeration in a tight loop when trying to detect peripheral hotplugging. Signed-off-by: Vincent Palatin Reviewed-by: Stefan Reinauer Tested-by: Stefan Reinauer Signed-off-by: Simon Glass --- common/usb.c | 26 ++++++++++++++++++++++++++ common/usb_hub.c | 2 +- include/usb.h | 2 ++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/common/usb.c b/common/usb.c index a4820d3..bde8f31 100644 --- a/common/usb.c +++ b/common/usb.c @@ -148,6 +148,32 @@ int usb_stop(void) return 0; } +/****************************************************************************** + * Detect if a USB device has been plugged or unplugged. + */ +int usb_detect_change(void) +{ + int i, j; + int change = 0; + + for (j = 0; j < USB_MAX_DEVICE; j++) { + for (i = 0; i < usb_dev[j].maxchild; i++) { + struct usb_port_status status; + + if (usb_get_port_status(&usb_dev[j], i + 1, + &status) < 0) + /* USB request failed */ + continue; + + if (le16_to_cpu(status.wPortChange) & + USB_PORT_STAT_C_CONNECTION) + change++; + } + } + + return change; +} + /* * disables the asynch behaviour of the control message. This is used for data * transfers that uses the exclusiv access to the control and bulk messages. diff --git a/common/usb_hub.c b/common/usb_hub.c index c9be530..bbed1c8 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -79,7 +79,7 @@ static int usb_get_hub_status(struct usb_device *dev, void *data) data, sizeof(struct usb_hub_status), USB_CNTL_TIMEOUT); } -static int usb_get_port_status(struct usb_device *dev, int port, void *data) +int usb_get_port_status(struct usb_device *dev, int port, void *data) { return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT, 0, port, diff --git a/include/usb.h b/include/usb.h index 1984e8f..25dddb8 100644 --- a/include/usb.h +++ b/include/usb.h @@ -265,6 +265,7 @@ int usb_kbd_deregister(int force); /* routines */ int usb_init(void); /* initialize the USB Controller */ int usb_stop(void); /* stop the USB Controller */ +int usb_detect_change(void); /* detect if a USB device has been (un)plugged */ int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); @@ -290,6 +291,7 @@ int usb_get_class_descriptor(struct usb_device *dev, int ifnum, int usb_clear_halt(struct usb_device *dev, int pipe); int usb_string(struct usb_device *dev, int index, char *buf, size_t size); int usb_set_interface(struct usb_device *dev, int interface, int alternate); +int usb_get_port_status(struct usb_device *dev, int port, void *data); /* big endian -> little endian conversion */ /* some CPUs are already little endian e.g. the ARM920T */ -- 2.2.0.rc0.207.ga3a616c