UPSTREAM: usb: Add nonblock argument to submit_int_msg

This will be used to implement non-blocking keyboard polling in case of
errors.

Conflicts:
	common/usb.c
	common/usb_kbd.c
	common/usb_storage.c
	include/usb.h

Change-Id: I4a951d779e2cf9e80380f93000a87a617453fb32
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
Signed-off-by: Frank Wang <frank.wang@rock-chips.com>
(cherry picked from commit 3437121c037f502a3b0faaec97059777034a1ead)
This commit is contained in:
Michal Suchanek 2019-08-18 10:55:27 +02:00 committed by Frank Wang
parent 5e8c228de7
commit 92937b1f66
14 changed files with 66 additions and 47 deletions

View File

@ -193,12 +193,15 @@ int usb_disable_asynch(int disable)
*/ */
/* /*
* submits an Interrupt Message * submits an Interrupt Message. Some drivers may implement non-blocking
* polling: when non-block is true and the device is not responding return
* -EAGAIN instead of waiting for device to respond.
*/ */
int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, int usb_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len, int interval) void *buffer, int transfer_len, int interval, bool nonblock)
{ {
return submit_int_msg(dev, pipe, buffer, transfer_len, interval); return submit_int_msg(dev, pipe, buffer, transfer_len, interval,
nonblock);
} }
/* /*

View File

@ -317,9 +317,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
struct usb_kbd_pdata *data = dev->privptr; struct usb_kbd_pdata *data = dev->privptr;
/* Submit a interrupt transfer request */ /* Submit a interrupt transfer request */
usb_submit_int_msg(dev, data->intpipe, &data->new[0], data->intpktsize, if (usb_int_msg(dev, data->intpipe, &data->new[0],
data->intinterval); data->intpktsize, data->intinterval, true) >= 0)
usb_kbd_irq_worker(dev); usb_kbd_irq_worker(dev);
#elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \ #elif defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP) || \
defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE) defined(CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE)
@ -480,8 +479,8 @@ static int usb_kbd_probe_dev(struct usb_device *dev, unsigned int ifnum)
if (usb_get_report(dev, iface->desc.bInterfaceNumber, if (usb_get_report(dev, iface->desc.bInterfaceNumber,
1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) { 1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE) < 0) {
#else #else
if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize, if (usb_int_msg(dev, data->intpipe, data->new, data->intpktsize,
data->intinterval) < 0) { data->intinterval, false) < 0) {
#endif #endif
printf("Failed to get keyboard state from device %04x:%04x\n", printf("Failed to get keyboard state from device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct); dev->descriptor.idVendor, dev->descriptor.idProduct);

View File

@ -654,8 +654,8 @@ static int usb_stor_CBI_get_status(struct scsi_cmd *srb, struct us_data *us)
int timeout; int timeout;
us->ip_wanted = 1; us->ip_wanted = 1;
submit_int_msg(us->pusb_dev, us->irqpipe, usb_int_msg(us->pusb_dev, us->irqpipe,
(void *) &us->ip_data, us->irqmaxp, us->irqinterval); (void *)&us->ip_data, us->irqmaxp, us->irqinterval, false);
timeout = 1000; timeout = 1000;
while (timeout--) { while (timeout--) {
if (us->ip_wanted == 0) if (us->ip_wanted == 0)

View File

@ -181,7 +181,8 @@ static int sandbox_keyb_control(struct udevice *dev, struct usb_device *udev,
} }
static int sandbox_keyb_interrupt(struct udevice *dev, struct usb_device *udev, static int sandbox_keyb_interrupt(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, int interval) unsigned long pipe, void *buffer, int length, int interval,
bool nonblock)
{ {
struct sandbox_keyb_priv *priv = dev_get_priv(dev); struct sandbox_keyb_priv *priv = dev_get_priv(dev);
uint8_t *data = buffer; uint8_t *data = buffer;

View File

@ -248,7 +248,8 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
} }
int usb_emul_int(struct udevice *emul, struct usb_device *udev, int usb_emul_int(struct udevice *emul, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, int interval) unsigned long pipe, void *buffer, int length, int interval,
bool nonblock)
{ {
struct dm_usb_ops *ops = usb_get_emul_ops(emul); struct dm_usb_ops *ops = usb_get_emul_ops(emul);
@ -256,7 +257,8 @@ int usb_emul_int(struct udevice *emul, struct usb_device *udev,
return -ENOSYS; return -ENOSYS;
debug("%s: dev=%s\n", __func__, emul->name); debug("%s: dev=%s\n", __func__, emul->name);
return ops->interrupt(emul, udev, pipe, buffer, length, interval); return ops->interrupt(emul, udev, pipe, buffer, length, interval,
nonblock);
} }
int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings, int usb_emul_setup_device(struct udevice *dev, struct usb_string *strings,

View File

@ -1111,7 +1111,8 @@ static int _submit_control_msg(struct dwc2_priv *priv, struct usb_device *dev,
} }
int _submit_int_msg(struct dwc2_priv *priv, struct usb_device *dev, int _submit_int_msg(struct dwc2_priv *priv, struct usb_device *dev,
unsigned long pipe, void *buffer, int len, int interval) unsigned long pipe, void *buffer, int len, int interval,
bool nonblock)
{ {
unsigned long timeout; unsigned long timeout;
int ret; int ret;
@ -1239,9 +1240,10 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
} }
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int len, int interval) int len, int interval, bool nonblock)
{ {
return _submit_int_msg(&local, dev, pipe, buffer, len, interval); return _submit_int_msg(&local, dev, pipe, buffer, len, interval,
nonblock);
} }
/* U-Boot USB control interface */ /* U-Boot USB control interface */
@ -1295,13 +1297,14 @@ static int dwc2_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
static int dwc2_submit_int_msg(struct udevice *dev, struct usb_device *udev, static int dwc2_submit_int_msg(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
struct dwc2_priv *priv = dev_get_priv(dev); struct dwc2_priv *priv = dev_get_priv(dev);
debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
return _submit_int_msg(priv, udev, pipe, buffer, length, interval); return _submit_int_msg(priv, udev, pipe, buffer, length, interval,
nonblock);
} }
static int dwc2_usb_ofdata_to_platdata(struct udevice *dev) static int dwc2_usb_ofdata_to_platdata(struct udevice *dev)

View File

@ -1473,7 +1473,8 @@ out:
} }
static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe, static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int length, int interval) void *buffer, int length, int interval,
bool nonblock)
{ {
void *backbuffer; void *backbuffer;
struct int_queue *queue; struct int_queue *queue;
@ -1523,9 +1524,10 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
} }
int submit_int_msg(struct usb_device *dev, unsigned long pipe, int submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int length, int interval) void *buffer, int length, int interval, bool nonblock)
{ {
return _ehci_submit_int_msg(dev, pipe, buffer, length, interval); return _ehci_submit_int_msg(dev, pipe, buffer, length, interval,
nonblock);
} }
struct int_queue *create_int_queue(struct usb_device *dev, struct int_queue *create_int_queue(struct usb_device *dev,
@ -1567,10 +1569,11 @@ static int ehci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
static int ehci_submit_int_msg(struct udevice *dev, struct usb_device *udev, static int ehci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
return _ehci_submit_int_msg(udev, pipe, buffer, length, interval); return _ehci_submit_int_msg(udev, pipe, buffer, length, interval,
nonblock);
} }
static struct int_queue *ehci_create_int_queue(struct udevice *dev, static struct int_queue *ehci_create_int_queue(struct udevice *dev,

View File

@ -1704,7 +1704,7 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
} }
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval) int transfer_len, int interval, bool nonblock)
{ {
info("submit_int_msg"); info("submit_int_msg");
return submit_common_msg(&gohci, dev, pipe, buffer, transfer_len, NULL, return submit_common_msg(&gohci, dev, pipe, buffer, transfer_len, NULL,
@ -2156,7 +2156,7 @@ static int ohci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
static int ohci_submit_int_msg(struct udevice *dev, struct usb_device *udev, static int ohci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
ohci_t *ohci = dev_get_priv(usb_get_bus(dev)); ohci_t *ohci = dev_get_priv(usb_get_bus(dev));

View File

@ -385,7 +385,7 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
} }
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int len, int interval) int len, int interval, bool nonblock)
{ {
PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe, PDEBUG(0, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe,
buffer, len, interval); buffer, len, interval);

View File

@ -102,7 +102,7 @@ static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev,
static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev, static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
struct udevice *emul; struct udevice *emul;
int ret; int ret;
@ -113,7 +113,8 @@ static int sandbox_submit_int(struct udevice *bus, struct usb_device *udev,
usbmon_trace(bus, pipe, NULL, emul); usbmon_trace(bus, pipe, NULL, emul);
if (ret) if (ret)
return ret; return ret;
ret = usb_emul_int(emul, udev, pipe, buffer, length, interval); ret = usb_emul_int(emul, udev, pipe, buffer, length, interval,
nonblock);
return ret; return ret;
} }

View File

@ -34,7 +34,7 @@ int usb_disable_asynch(int disable)
} }
int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
int length, int interval) int length, int interval, bool nonblock)
{ {
struct udevice *bus = udev->controller_dev; struct udevice *bus = udev->controller_dev;
struct dm_usb_ops *ops = usb_get_ops(bus); struct dm_usb_ops *ops = usb_get_ops(bus);
@ -42,7 +42,8 @@ int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
if (!ops->interrupt) if (!ops->interrupt)
return -ENOSYS; return -ENOSYS;
return ops->interrupt(bus, udev, pipe, buffer, length, interval); return ops->interrupt(bus, udev, pipe, buffer, length, interval,
nonblock);
} }
int submit_control_msg(struct usb_device *udev, unsigned long pipe, int submit_control_msg(struct usb_device *udev, unsigned long pipe,

View File

@ -1110,7 +1110,8 @@ unknown:
* @return 0 * @return 0
*/ */
static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
void *buffer, int length, int interval) void *buffer, int length, int interval,
bool nonblock)
{ {
if (usb_pipetype(pipe) != PIPE_INTERRUPT) { if (usb_pipetype(pipe) != PIPE_INTERRUPT) {
printf("non-interrupt pipe (type=%lu)", usb_pipetype(pipe)); printf("non-interrupt pipe (type=%lu)", usb_pipetype(pipe));
@ -1278,9 +1279,10 @@ int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
} }
int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
int length, int interval) int length, int interval, bool nonblock)
{ {
return _xhci_submit_int_msg(udev, pipe, buffer, length, interval); return _xhci_submit_int_msg(udev, pipe, buffer, length, interval,
nonblock);
} }
/** /**
@ -1387,10 +1389,11 @@ static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev, static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev); debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
return _xhci_submit_int_msg(udev, pipe, buffer, length, interval); return _xhci_submit_int_msg(udev, pipe, buffer, length, interval,
nonblock);
} }
static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev) static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev)

View File

@ -113,7 +113,7 @@ static int _musb_submit_bulk_msg(struct musb_host_data *host,
static int _musb_submit_int_msg(struct musb_host_data *host, static int _musb_submit_int_msg(struct musb_host_data *host,
struct usb_device *dev, unsigned long pipe, struct usb_device *dev, unsigned long pipe,
void *buffer, int len, int interval) void *buffer, int len, int interval, bool nonblock)
{ {
construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_INT, pipe, construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_INT, pipe,
buffer, len, NULL, interval); buffer, len, NULL, interval);
@ -274,9 +274,10 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe,
} }
int submit_int_msg(struct usb_device *dev, unsigned long pipe, int submit_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int length, int interval) void *buffer, int length, int interval, bool nonblock)
{ {
return _musb_submit_int_msg(&musb_host, dev, pipe, buffer, length, interval); return _musb_submit_int_msg(&musb_host, dev, pipe, buffer, length,
interval, nonblock);
} }
struct int_queue *create_int_queue(struct usb_device *dev, struct int_queue *create_int_queue(struct usb_device *dev,
@ -326,10 +327,11 @@ static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
static int musb_submit_int_msg(struct udevice *dev, struct usb_device *udev, static int musb_submit_int_msg(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval) int interval, bool nonblock)
{ {
struct musb_host_data *host = dev_get_priv(dev); struct musb_host_data *host = dev_get_priv(dev);
return _musb_submit_int_msg(host, udev, pipe, buffer, length, interval); return _musb_submit_int_msg(host, udev, pipe, buffer, length, interval,
nonblock);
} }
static struct int_queue *musb_create_int_queue(struct udevice *dev, static struct int_queue *musb_create_int_queue(struct udevice *dev,

View File

@ -185,7 +185,7 @@ int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, struct devrequest *setup); int transfer_len, struct devrequest *setup);
int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int transfer_len, int interval); int transfer_len, int interval, bool nonblock);
#if defined CONFIG_USB_EHCI_HCD || defined CONFIG_USB_MUSB_HOST \ #if defined CONFIG_USB_EHCI_HCD || defined CONFIG_USB_MUSB_HOST \
|| CONFIG_IS_ENABLED(DM_USB) || CONFIG_IS_ENABLED(DM_USB)
@ -262,8 +262,8 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
void *data, unsigned short size, int timeout); void *data, unsigned short size, int timeout);
int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, int usb_bulk_msg(struct usb_device *dev, unsigned int pipe,
void *data, int len, int *actual_length, int timeout); void *data, int len, int *actual_length, int timeout);
int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, int usb_int_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int transfer_len, int interval); void *buffer, int transfer_len, int interval, bool nonblock);
int usb_disable_asynch(int disable); int usb_disable_asynch(int disable);
int usb_maxpacket(struct usb_device *dev, unsigned long pipe); int usb_maxpacket(struct usb_device *dev, unsigned long pipe);
int usb_get_configuration_no(struct usb_device *dev, int cfgno, int usb_get_configuration_no(struct usb_device *dev, int cfgno,
@ -709,7 +709,7 @@ struct dm_usb_ops {
*/ */
int (*interrupt)(struct udevice *bus, struct usb_device *udev, int (*interrupt)(struct udevice *bus, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, unsigned long pipe, void *buffer, int length,
int interval); int interval, bool nonblock);
/** /**
* create_int_queue() - Create and queue interrupt packets * create_int_queue() - Create and queue interrupt packets
@ -1030,7 +1030,8 @@ int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
* @return 0 if OK, -ve on error * @return 0 if OK, -ve on error
*/ */
int usb_emul_int(struct udevice *emul, struct usb_device *udev, int usb_emul_int(struct udevice *emul, struct usb_device *udev,
unsigned long pipe, void *buffer, int length, int interval); unsigned long pipe, void *buffer, int length, int interval,
bool nonblock);
/** /**
* usb_emul_find() - Find an emulator for a particular device * usb_emul_find() - Find an emulator for a particular device