X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fusb.c;h=fbaf8ecbe232ce63170228727df1ed7fa23b060f;hb=7fc65bcf8a0a5463db86efbb273a40448c845efc;hp=a4820d3e949a17c15c7deda9a3b0209abd0b3b74;hpb=95fbfe42980ea75c7955a6ddf4f28be1a6407920;p=u-boot diff --git a/common/usb.c b/common/usb.c index a4820d3e94..fbaf8ecbe2 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. @@ -192,6 +218,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, void *data, unsigned short size, int timeout) { ALLOC_CACHE_ALIGN_BUFFER(struct devrequest, setup_packet, 1); + int err; if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ @@ -209,8 +236,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ - if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0) - return -EIO; + err = submit_control_msg(dev, pipe, data, size, setup_packet); + if (err < 0) + return err; if (timeout == 0) return (int)size; @@ -883,26 +911,24 @@ __weak int usb_alloc_device(struct usb_device *udev) } #endif /* !CONFIG_DM_USB */ -#ifndef CONFIG_DM_USB -int usb_legacy_port_reset(struct usb_device *hub, int portnr) +static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub) { if (hub) { unsigned short portstatus; int err; /* reset the port for the second time */ - err = legacy_hub_port_reset(hub, portnr - 1, &portstatus); + err = legacy_hub_port_reset(hub, dev->portnr - 1, &portstatus); if (err < 0) { - printf("\n Couldn't reset port %i\n", portnr); + printf("\n Couldn't reset port %i\n", dev->portnr); return err; } } else { - usb_reset_root_port(); + usb_reset_root_port(dev); } return 0; } -#endif static int get_descriptor_len(struct usb_device *dev, int len, int expect_len) { @@ -931,8 +957,6 @@ static int get_descriptor_len(struct usb_device *dev, int len, int expect_len) static int usb_setup_descriptor(struct usb_device *dev, bool do_read) { - __maybe_unused struct usb_device_descriptor *desc; - /* * This is a Windows scheme of initialization sequence, with double * reset of the device (Linux uses the same sequence) @@ -946,13 +970,18 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read) * send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is * only 18 bytes long, this will terminate with a short packet. But if * the maxpacket size is 8 or 16 the device may be waiting to transmit - * some more, or keeps on retransmitting the 8 byte header. */ + * some more, or keeps on retransmitting the 8 byte header. + */ - dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */ - /* Default to 64 byte max packet size */ - dev->maxpacketsize = PACKET_SIZE_64; - dev->epmaxpacketin[0] = 64; - dev->epmaxpacketout[0] = 64; + if (dev->speed == USB_SPEED_LOW) { + dev->descriptor.bMaxPacketSize0 = 8; + dev->maxpacketsize = PACKET_SIZE_8; + } else { + dev->descriptor.bMaxPacketSize0 = 64; + dev->maxpacketsize = PACKET_SIZE_64; + } + dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; + dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; if (do_read) { int err; @@ -1001,7 +1030,7 @@ static int usb_setup_descriptor(struct usb_device *dev, bool do_read) } static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, - struct usb_device *parent, int portnr) + struct usb_device *parent) { int err; @@ -1019,7 +1048,7 @@ static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read, err = usb_setup_descriptor(dev, do_read); if (err) return err; - err = usb_legacy_port_reset(parent, portnr); + err = usb_hub_port_reset(dev, parent); if (err) return err; @@ -1097,7 +1126,7 @@ int usb_select_config(struct usb_device *dev) } int usb_setup_device(struct usb_device *dev, bool do_read, - struct usb_device *parent, int portnr) + struct usb_device *parent) { int addr; int ret; @@ -1106,7 +1135,7 @@ int usb_setup_device(struct usb_device *dev, bool do_read, addr = dev->devnum; dev->devnum = 0; - ret = usb_prepare_device(dev, addr, do_read, parent, portnr); + ret = usb_prepare_device(dev, addr, do_read, parent); if (ret) return ret; ret = usb_select_config(dev); @@ -1136,7 +1165,7 @@ int usb_new_device(struct usb_device *dev) #ifdef CONFIG_USB_XHCI do_read = false; #endif - err = usb_setup_device(dev, do_read, dev->parent, dev->portnr); + err = usb_setup_device(dev, do_read, dev->parent); if (err) return err;