/*
- *
* Most of this source has been derived from the Linux USB
* project:
* (C) Copyright Linus Torvalds 1999
* Adapted for U-Boot:
* (C) Copyright 2001 Denis Peter, MPL AG Switzerland
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
+ * SPDX-License-Identifier: GPL-2.0+
*/
/*
#include <asm/4xx_pci.h>
#endif
-#ifdef DEBUG
-#define USB_DEBUG 1
-#define USB_HUB_DEBUG 1
-#else
-#define USB_DEBUG 0
-#define USB_HUB_DEBUG 0
-#endif
-
-#define USB_PRINTF(fmt, args...) debug_cond(USB_DEBUG, fmt, ##args)
-#define USB_HUB_PRINTF(fmt, args...) debug_cond(USB_HUB_DEBUG, fmt, ##args)
-
#define USB_BUFSIZ 512
static struct usb_device usb_dev[USB_MAX_DEVICE];
usb_started = 1;
}
- USB_PRINTF("scan end\n");
+ debug("scan end\n");
/* if we were not able to find at least one working bus, bail out */
if (!usb_started) {
puts("USB error: all controllers failed lowlevel init\n");
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);
+ debug("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 */
if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0)
/* Control => bidirectional */
dev->epmaxpacketout[b] = ep_wMaxPacketSize;
dev->epmaxpacketin[b] = ep_wMaxPacketSize;
- USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n",
- b, dev->epmaxpacketin[b]);
+ debug("##Control EP epmaxpacketout/in[%d] = %d\n",
+ b, dev->epmaxpacketin[b]);
} else {
if ((ep->bEndpointAddress & 0x80) == 0) {
/* OUT Endpoint */
if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {
dev->epmaxpacketout[b] = ep_wMaxPacketSize;
- USB_PRINTF("##EP epmaxpacketout[%d] = %d\n",
- b, dev->epmaxpacketout[b]);
+ debug("##EP epmaxpacketout[%d] = %d\n",
+ b, dev->epmaxpacketout[b]);
}
} else {
/* IN Endpoint */
if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {
dev->epmaxpacketin[b] = ep_wMaxPacketSize;
- USB_PRINTF("##EP epmaxpacketin[%d] = %d\n",
- b, dev->epmaxpacketin[b]);
+ debug("##EP epmaxpacketin[%d] = %d\n",
+ b, dev->epmaxpacketin[b]);
}
} /* if out */
} /* if control */
{
struct usb_descriptor_header *head;
int index, ifno, epno, curr_if_num;
- int i;
u16 ep_wMaxPacketSize;
+ struct usb_interface *if_desc = NULL;
ifno = -1;
epno = -1;
&buffer[index])->bInterfaceNumber != curr_if_num) {
/* this is a new interface, copy new desc */
ifno = dev->config.no_of_if;
+ if_desc = &dev->config.if_desc[ifno];
dev->config.no_of_if++;
- memcpy(&dev->config.if_desc[ifno],
- &buffer[index], buffer[index]);
- dev->config.if_desc[ifno].no_of_ep = 0;
- dev->config.if_desc[ifno].num_altsetting = 1;
+ memcpy(if_desc, &buffer[index], buffer[index]);
+ if_desc->no_of_ep = 0;
+ if_desc->num_altsetting = 1;
curr_if_num =
- dev->config.if_desc[ifno].desc.bInterfaceNumber;
+ if_desc->desc.bInterfaceNumber;
} else {
/* found alternate setting for the interface */
- dev->config.if_desc[ifno].num_altsetting++;
+ if (ifno >= 0) {
+ if_desc = &dev->config.if_desc[ifno];
+ if_desc->num_altsetting++;
+ }
}
break;
case USB_DT_ENDPOINT:
epno = dev->config.if_desc[ifno].no_of_ep;
+ if_desc = &dev->config.if_desc[ifno];
/* found an endpoint */
- dev->config.if_desc[ifno].no_of_ep++;
- memcpy(&dev->config.if_desc[ifno].ep_desc[epno],
+ if_desc->no_of_ep++;
+ memcpy(&if_desc->ep_desc[epno],
&buffer[index], buffer[index]);
ep_wMaxPacketSize = get_unaligned(&dev->config.\
if_desc[ifno].\
if_desc[ifno].\
ep_desc[epno].\
wMaxPacketSize);
- USB_PRINTF("if %d, ep %d\n", ifno, epno);
+ debug("if %d, ep %d\n", ifno, epno);
+ break;
+ case USB_DT_SS_ENDPOINT_COMP:
+ if_desc = &dev->config.if_desc[ifno];
+ memcpy(&if_desc->ss_ep_comp_desc[epno],
+ &buffer[index], buffer[index]);
break;
default:
if (head->bLength == 0)
return 1;
- USB_PRINTF("unknown Description Type : %x\n",
- head->bDescriptorType);
+ debug("unknown Description Type : %x\n",
+ head->bDescriptorType);
+#ifdef DEBUG
{
-#ifdef USB_DEBUG
unsigned char *ch = (unsigned char *)head;
-#endif
+ int i;
+
for (i = 0; i < head->bLength; i++)
- USB_PRINTF("%02X ", *ch++);
- USB_PRINTF("\n\n\n");
+ debug("%02X ", *ch++);
+ debug("\n\n\n");
}
+#endif
break;
}
index += head->bLength;
{
int result;
unsigned int tmp;
- struct usb_configuration_descriptor *config;
+ struct usb_config_descriptor *config;
- config = (struct usb_configuration_descriptor *)&buffer[0];
+ config = (struct usb_config_descriptor *)&buffer[0];
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 9);
if (result < 9) {
if (result < 0)
tmp = le16_to_cpu(config->wTotalLength);
if (tmp > USB_BUFSIZ) {
- USB_PRINTF("usb_get_configuration_no: failed to get " \
- "descriptor - too long: %d\n", tmp);
+ printf("usb_get_configuration_no: failed to get " \
+ "descriptor - too long: %d\n", tmp);
return -1;
}
result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp);
- USB_PRINTF("get_conf_no %d Result %d, wLength %d\n",
- cfgno, result, tmp);
+ debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, tmp);
return result;
}
{
int res;
- USB_PRINTF("set address %d\n", dev->devnum);
+ debug("set address %d\n", dev->devnum);
res = usb_control_msg(dev, usb_snddefctrl(dev),
USB_REQ_SET_ADDRESS, 0,
(dev->devnum), 0,
static int usb_set_configuration(struct usb_device *dev, int configuration)
{
int res;
- USB_PRINTF("set configuration %d\n", configuration);
+ debug("set configuration %d\n", configuration);
/* set setup command */
res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0,
if (!dev->have_langid) {
err = usb_string_sub(dev, 0, 0, tbuf);
if (err < 0) {
- USB_PRINTF("error getting string descriptor 0 " \
- "(error=%lx)\n", dev->status);
+ debug("error getting string descriptor 0 " \
+ "(error=%lx)\n", dev->status);
return -1;
} else if (tbuf[0] < 4) {
- USB_PRINTF("string descriptor 0 too short\n");
+ debug("string descriptor 0 too short\n");
return -1;
} else {
dev->have_langid = -1;
dev->string_langid = tbuf[2] | (tbuf[3] << 8);
/* always use the first langid listed */
- USB_PRINTF("USB device number %d default " \
- "language ID 0x%x\n",
- dev->devnum, dev->string_langid);
+ debug("USB device number %d default " \
+ "language ID 0x%x\n",
+ dev->devnum, dev->string_langid);
}
}
struct usb_device *usb_alloc_new_device(void *controller)
{
int i;
- USB_PRINTF("New Device %d\n", dev_index);
+ debug("New Device %d\n", dev_index);
if (dev_index == USB_MAX_DEVICE) {
printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
return NULL;
return &usb_dev[dev_index - 1];
}
+/*
+ * Free the newly created device node.
+ * Called in error cases where configuring a newly attached
+ * device fails for some reason.
+ */
+void usb_free_device(void)
+{
+ dev_index--;
+ debug("Freeing device node: %d\n", dev_index);
+ memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
+ usb_dev[dev_index].devnum = -1;
+}
/*
* By the time we get here, the device has gotten a new device ID
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
if (err < 0) {
- USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n");
+ debug("usb_new_device: usb_get_descriptor() failed\n");
return 1;
}
dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
+ /*
+ * Fetch the device class, driver can use this info
+ * to differentiate between HUB and DEVICE.
+ */
+ dev->descriptor.bDeviceClass = desc->bDeviceClass;
/* find the port number we're at */
if (parent) {
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);
+ err = usb_get_configuration_no(dev, tmpbuf, 0);
+ if (err < 0) {
+ printf("usb_new_device: Cannot read configuration, " \
+ "skipping device %04x:%04x\n",
+ dev->descriptor.idVendor, dev->descriptor.idProduct);
+ return -1;
+ }
usb_parse_config(dev, tmpbuf, 0);
usb_set_maxpacket(dev);
/* we set the default configuration here */
"len %d, status %lX\n", dev->act_len, dev->status);
return -1;
}
- USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
- dev->descriptor.iManufacturer, dev->descriptor.iProduct,
- dev->descriptor.iSerialNumber);
+ debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
+ 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.iSerialNumber)
usb_string(dev, dev->descriptor.iSerialNumber,
dev->serial, sizeof(dev->serial));
- USB_PRINTF("Manufacturer %s\n", dev->mf);
- USB_PRINTF("Product %s\n", dev->prod);
- USB_PRINTF("SerialNumber %s\n", dev->serial);
+ debug("Manufacturer %s\n", dev->mf);
+ debug("Product %s\n", dev->prod);
+ debug("SerialNumber %s\n", dev->serial);
/* now prode if the device is a hub */
usb_hub_probe(dev, 0);
return 0;