diff options
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r-- | drivers/usb/core/usb.c | 100 |
1 files changed, 57 insertions, 43 deletions
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index bd2938d2b7..a5075d5436 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -52,6 +52,7 @@ #include <asm/byteorder.h> #include <xfuncs.h> #include <init.h> +#include <dma.h> #include <usb/usb.h> @@ -67,7 +68,6 @@ static int dev_index; static int asynch_allowed; -static struct devrequest setup_packet; static int usb_hub_probe(struct usb_device *dev, int ifnum); static int hub_port_reset(struct usb_device *dev, int port, @@ -80,8 +80,8 @@ static void print_usb_device(struct usb_device *dev) { printf("Bus %03d Device %03d: ID %04x:%04x %s\n", dev->host->busnum, dev->devnum, - dev->descriptor.idVendor, - dev->descriptor.idProduct, + dev->descriptor->idVendor, + dev->descriptor->idProduct, dev->prod); } @@ -299,12 +299,14 @@ static int usb_new_device(struct usb_device *dev) { int addr, err; int tmp; - unsigned char tmpbuf[USB_BUFSIZ]; + void *buf; struct usb_device_descriptor *desc; int port = -1; struct usb_device *parent = dev->parent; unsigned short portstatus; + buf = dma_alloc(USB_BUFSIZ); + /* We still haven't set the Address yet */ addr = dev->devnum; dev->devnum = 0; @@ -322,8 +324,8 @@ static int usb_new_device(struct usb_device *dev) * the maxpacket size is 8 or 16 the device may be waiting to transmit * some more, or keeps on retransmitting the 8 byte header. */ - desc = (struct usb_device_descriptor *)tmpbuf; - dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */ + desc = buf; + 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; @@ -332,10 +334,10 @@ static int usb_new_device(struct usb_device *dev) err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64); if (err < 0) { USB_PRINTF("%s: usb_get_descriptor() failed with %d\n", __func__, err); - return 1; + goto err_out; } - dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0; + dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0; /* find the port number we're at */ if (parent) { @@ -349,20 +351,21 @@ static int usb_new_device(struct usb_device *dev) } if (port < 0) { printf("%s: cannot locate device's port.\n", __func__); - return 1; + err = -ENODEV; + goto err_out; } /* reset the port for the second time */ err = hub_port_reset(dev->parent, port, &portstatus); if (err < 0) { printf("\n Couldn't reset port %i\n", port); - return 1; + goto err_out; } } - dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0; - dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0; - switch (dev->descriptor.bMaxPacketSize0) { + dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0; + dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0; + switch (dev->descriptor->bMaxPacketSize0) { case 8: dev->maxpacketsize = PACKET_SIZE_8; break; @@ -383,15 +386,15 @@ static int usb_new_device(struct usb_device *dev) if (err < 0) { printf("\n USB device not accepting new address " \ "(error=%lX)\n", dev->status); - return 1; + goto err_out; } wait_ms(10); /* Let the SET_ADDRESS settle */ - tmp = sizeof(dev->descriptor); + tmp = sizeof(*dev->descriptor); err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, - &dev->descriptor, sizeof(dev->descriptor)); + dev->descriptor, sizeof(*dev->descriptor)); if (err < tmp) { if (err < 0) printf("unable to get device descriptor (error=%d)\n", @@ -399,37 +402,37 @@ static int usb_new_device(struct usb_device *dev) else printf("USB device descriptor short read " \ "(expected %i, got %i)\n", tmp, err); - return 1; + goto err_out; } /* correct le values */ - le16_to_cpus(&dev->descriptor.bcdUSB); - le16_to_cpus(&dev->descriptor.idVendor); - le16_to_cpus(&dev->descriptor.idProduct); - le16_to_cpus(&dev->descriptor.bcdDevice); + le16_to_cpus(&dev->descriptor->bcdUSB); + le16_to_cpus(&dev->descriptor->idVendor); + le16_to_cpus(&dev->descriptor->idProduct); + le16_to_cpus(&dev->descriptor->bcdDevice); /* only support for one config for now */ - usb_get_configuration_no(dev, &tmpbuf[0], 0); - usb_parse_config(dev, &tmpbuf[0], 0); + usb_get_configuration_no(dev, buf, 0); + usb_parse_config(dev, buf, 0); usb_set_maxpacket(dev); /* we set the default configuration here */ if (usb_set_configuration(dev, dev->config.bConfigurationValue)) { printf("failed to set default configuration " \ "len %d, status %lX\n", dev->act_len, dev->status); - return -1; + goto err_out; } USB_PRINTF("new device: Mfr=%d, Product=%d, SerialNumber=%d\n", - dev->descriptor.iManufacturer, dev->descriptor.iProduct, - dev->descriptor.iSerialNumber); + dev->descriptor->iManufacturer, dev->descriptor->iProduct, + dev->descriptor->iSerialNumber); memset(dev->mf, 0, sizeof(dev->mf)); memset(dev->prod, 0, sizeof(dev->prod)); memset(dev->serial, 0, sizeof(dev->serial)); - if (dev->descriptor.iManufacturer) - usb_string(dev, dev->descriptor.iManufacturer, + if (dev->descriptor->iManufacturer) + usb_string(dev, dev->descriptor->iManufacturer, dev->mf, sizeof(dev->mf)); - if (dev->descriptor.iProduct) - usb_string(dev, dev->descriptor.iProduct, + if (dev->descriptor->iProduct) + usb_string(dev, dev->descriptor->iProduct, dev->prod, sizeof(dev->prod)); - if (dev->descriptor.iSerialNumber) - usb_string(dev, dev->descriptor.iSerialNumber, + if (dev->descriptor->iSerialNumber) + usb_string(dev, dev->descriptor->iSerialNumber, dev->serial, sizeof(dev->serial)); /* now prode if the device is a hub */ usb_hub_probe(dev, 0); @@ -441,7 +444,11 @@ static int usb_new_device(struct usb_device *dev) register_device(&dev->dev); list_add_tail(&dev->list, &usb_device_list); - return 0; + err = 0; + +err_out: + dma_free(buf); + return err; } static struct usb_device *usb_alloc_new_device(void) @@ -454,6 +461,8 @@ static struct usb_device *usb_alloc_new_device(void) usbdev->devnum = dev_index + 1; usbdev->maxchild = 0; usbdev->dev.bus = &usb_bus_type; + usbdev->setup_packet = dma_alloc(sizeof(*usbdev->setup_packet)); + usbdev->descriptor = dma_alloc(sizeof(*usbdev->descriptor)); dev_index++; @@ -471,6 +480,8 @@ void usb_rescan(void) unregister_device(&dev->dev); if (dev->hub) free(dev->hub); + dma_free(dev->setup_packet); + dma_free(dev->descriptor); free(dev); } @@ -532,6 +543,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, { struct usb_host *host = dev->host; int ret; + struct devrequest *setup_packet = dev->setup_packet; if ((timeout == 0) && (!asynch_allowed)) { /* request for a asynch control pipe is not allowed */ @@ -539,17 +551,18 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, } /* set setup command */ - setup_packet.requesttype = requesttype; - setup_packet.request = request; - setup_packet.value = cpu_to_le16(value); - setup_packet.index = cpu_to_le16(index); - setup_packet.length = cpu_to_le16(size); + setup_packet->requesttype = requesttype; + setup_packet->request = request; + setup_packet->value = cpu_to_le16(value); + setup_packet->index = cpu_to_le16(index); + setup_packet->length = cpu_to_le16(size); USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ "value 0x%X index 0x%X length 0x%X\n", request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ - ret = host->submit_control_msg(dev, pipe, data, size, &setup_packet, timeout); + ret = host->submit_control_msg(dev, pipe, data, size, setup_packet, + timeout); if (ret) return ret; @@ -1284,11 +1297,11 @@ int usb_driver_register(struct usb_driver *drv) static int usb_match_device(struct usb_device *dev, const struct usb_device_id *id) { if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && - id->idVendor != le16_to_cpu(dev->descriptor.idVendor)) + id->idVendor != le16_to_cpu(dev->descriptor->idVendor)) return 0; if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) && - id->idProduct != le16_to_cpu(dev->descriptor.idProduct)) + id->idProduct != le16_to_cpu(dev->descriptor->idProduct)) return 0; return 1; @@ -1311,7 +1324,7 @@ static int usb_match_one_id(struct usb_device *usbdev, /* The interface class, subclass, and protocol should never be * checked for a match if the device class is Vendor Specific, * unless the match record specifies the Vendor ID. */ - if (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && + if (usbdev->descriptor->bDeviceClass == USB_CLASS_VENDOR_SPEC && !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO)) return 0; @@ -1371,7 +1384,8 @@ static int usb_match(struct device_d *dev, struct driver_d *drv) struct usb_driver *usbdrv = container_of(dev->driver, struct usb_driver, driver); const struct usb_device_id *id; - debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); + debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor->idVendor, + usbdev->descriptor->idProduct); id = usb_match_id(usbdev, usbdrv->id_table); if (id) { |