summaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/core/usb.c')
-rw-r--r--drivers/usb/core/usb.c100
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) {