* Modified for the MP2USB by (C) Copyright 2005 Eric Benard
* ebenard@eukrea.com - based on s3c24x0's driver
*
- * 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+
*/
/*
* IMPORTANT NOTES
#include <asm/arch/hardware.h> /* needed for AT91_USB_HOST_BASE */
#endif
-#if defined(CONFIG_ARM920T) || \
+#if defined(CONFIG_CPU_ARM920T) || \
defined(CONFIG_S3C24X0) || \
- defined(CONFIG_S3C6400) || \
defined(CONFIG_440EP) || \
defined(CONFIG_PCI_OHCI) || \
defined(CONFIG_MPC5200) || \
| (usb_pipeisoc(pipe)? 0x8000: 0)
| (usb_pipecontrol(pipe)? 0: \
(usb_pipeout(pipe)? 0x800: 0x1000))
- | usb_pipeslow(pipe) << 13
+ | (usb_dev->speed == USB_SPEED_LOW) << 13
| usb_maxpacket(usb_dev, pipe) << 16);
if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
static void dl_transfer_length(td_t *td)
{
- __u32 tdINFO, tdBE, tdCBP;
+ __u32 tdBE, tdCBP;
urb_priv_t *lurb_priv = td->ed->purb;
- tdINFO = m32_swap(td->hwINFO);
tdBE = m32_swap(td->hwBE);
tdCBP = m32_swap(td->hwCBP);
* Virtual Root Hub
*-------------------------------------------------------------------------*/
-/* Device descriptor */
-static __u8 root_hub_dev_des[] =
-{
- 0x12, /* __u8 bLength; */
- 0x01, /* __u8 bDescriptorType; Device */
- 0x10, /* __u16 bcdUSB; v1.1 */
- 0x01,
- 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
- 0x00, /* __u8 bDeviceSubClass; */
- 0x00, /* __u8 bDeviceProtocol; */
- 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
- 0x00, /* __u16 idVendor; */
- 0x00,
- 0x00, /* __u16 idProduct; */
- 0x00,
- 0x00, /* __u16 bcdDevice; */
- 0x00,
- 0x00, /* __u8 iManufacturer; */
- 0x01, /* __u8 iProduct; */
- 0x00, /* __u8 iSerialNumber; */
- 0x01 /* __u8 bNumConfigurations; */
-};
-
-/* Configuration descriptor */
-static __u8 root_hub_config_des[] =
-{
- 0x09, /* __u8 bLength; */
- 0x02, /* __u8 bDescriptorType; Configuration */
- 0x19, /* __u16 wTotalLength; */
- 0x00,
- 0x01, /* __u8 bNumInterfaces; */
- 0x01, /* __u8 bConfigurationValue; */
- 0x00, /* __u8 iConfiguration; */
- 0x40, /* __u8 bmAttributes;
- Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
- 0x00, /* __u8 MaxPower; */
-
- /* interface */
- 0x09, /* __u8 if_bLength; */
- 0x04, /* __u8 if_bDescriptorType; Interface */
- 0x00, /* __u8 if_bInterfaceNumber; */
- 0x00, /* __u8 if_bAlternateSetting; */
- 0x01, /* __u8 if_bNumEndpoints; */
- 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
- 0x00, /* __u8 if_bInterfaceSubClass; */
- 0x00, /* __u8 if_bInterfaceProtocol; */
- 0x00, /* __u8 if_iInterface; */
-
- /* endpoint */
- 0x07, /* __u8 ep_bLength; */
- 0x05, /* __u8 ep_bDescriptorType; Endpoint */
- 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
- 0x03, /* __u8 ep_bmAttributes; Interrupt */
- 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
- 0x00,
- 0xff /* __u8 ep_bInterval; 255 ms */
-};
-
-static unsigned char root_hub_str_index0[] =
-{
- 0x04, /* __u8 bLength; */
- 0x03, /* __u8 bDescriptorType; String-descriptor */
- 0x09, /* __u8 lang ID */
- 0x04, /* __u8 lang ID */
-};
-
-static unsigned char root_hub_str_index1[] =
-{
- 28, /* __u8 bLength; */
- 0x03, /* __u8 bDescriptorType; String-descriptor */
- 'O', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'H', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'C', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'I', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- ' ', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'R', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'o', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'o', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 't', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- ' ', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'H', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'u', /* __u8 Unicode */
- 0, /* __u8 Unicode */
- 'b', /* __u8 Unicode */
- 0, /* __u8 Unicode */
-};
+#include <usbroothubdes.h>
/* Hub class-specific descriptor is constructed dynamically */
int leni = transfer_len;
int len = 0;
int stat = 0;
- __u32 datab[4];
- __u8 *data_buf = (__u8 *)datab;
__u16 bmRType_bReq;
__u16 wValue;
__u16 wIndex;
__u16 wLength;
+ ALLOC_ALIGN_BUFFER(__u8, databuf, 16, sizeof(u32));
#ifdef DEBUG
pkt_print(NULL, dev, pipe, buffer, transfer_len,
cmd, "SUB(rh)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (usb_pipeint(pipe)) {
info("Root-Hub submit IRQ: NOT implemented");
*/
case RH_GET_STATUS:
- *(__u16 *) data_buf = cpu_to_le16(1);
+ *(u16 *)databuf = cpu_to_le16(1);
OK(2);
case RH_GET_STATUS | RH_INTERFACE:
- *(__u16 *) data_buf = cpu_to_le16(0);
+ *(u16 *)databuf = cpu_to_le16(0);
OK(2);
case RH_GET_STATUS | RH_ENDPOINT:
- *(__u16 *) data_buf = cpu_to_le16(0);
+ *(u16 *)databuf = cpu_to_le16(0);
OK(2);
case RH_GET_STATUS | RH_CLASS:
- *(__u32 *) data_buf = cpu_to_le32(
+ *(u32 *)databuf = cpu_to_le32(
RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
OK(4);
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
- *(__u32 *) data_buf = cpu_to_le32(RD_RH_PORTSTAT);
+ *(u32 *)databuf = cpu_to_le32(RD_RH_PORTSTAT);
OK(4);
case RH_CLEAR_FEATURE | RH_ENDPOINT:
OK(0);
case (RH_PORT_POWER):
WR_RH_PORTSTAT(RH_PS_PPS);
- wait_ms(100);
+ mdelay(100);
OK(0);
case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
if (RD_RH_PORTSTAT & RH_PS_CCS)
min_t(unsigned int,
sizeof(root_hub_dev_des),
wLength));
- data_buf = root_hub_dev_des; OK(len);
+ databuf = root_hub_dev_des; OK(len);
case (0x02): /* configuration descriptor */
len = min_t(unsigned int,
leni,
min_t(unsigned int,
sizeof(root_hub_config_des),
wLength));
- data_buf = root_hub_config_des; OK(len);
+ databuf = root_hub_config_des; OK(len);
case (0x03): /* string descriptors */
if (wValue == 0x0300) {
len = min_t(unsigned int,
min_t(unsigned int,
sizeof(root_hub_str_index0),
wLength));
- data_buf = root_hub_str_index0;
+ databuf = root_hub_str_index0;
OK(len);
}
if (wValue == 0x0301) {
min_t(unsigned int,
sizeof(root_hub_str_index1),
wLength));
- data_buf = root_hub_str_index1;
+ databuf = root_hub_str_index1;
OK(len);
}
default:
{
__u32 temp = roothub_a(&gohci);
- data_buf [0] = 9; /* min length; */
- data_buf [1] = 0x29;
- data_buf [2] = temp & RH_A_NDP;
+ databuf[0] = 9; /* min length; */
+ databuf[1] = 0x29;
+ databuf[2] = temp & RH_A_NDP;
#ifdef CONFIG_AT91C_PQFP_UHPBUG
- data_buf [2] = (data_buf [2] == 2) ? 1:0;
+ databuf[2] = (databuf[2] == 2) ? 1 : 0;
#endif
- data_buf [3] = 0;
+ databuf[3] = 0;
if (temp & RH_A_PSM) /* per-port power switching? */
- data_buf [3] |= 0x1;
+ databuf[3] |= 0x1;
if (temp & RH_A_NOCP) /* no overcurrent reporting? */
- data_buf [3] |= 0x10;
+ databuf[3] |= 0x10;
else if (temp & RH_A_OCPM)/* per-port overcurrent reporting? */
- data_buf [3] |= 0x8;
+ databuf[3] |= 0x8;
- /* corresponds to data_buf[4-7] */
- datab [1] = 0;
- data_buf [5] = (temp & RH_A_POTPGT) >> 24;
+ databuf[4] = 0;
+ databuf[5] = (temp & RH_A_POTPGT) >> 24;
+ databuf[6] = 0;
temp = roothub_b(&gohci);
- data_buf [7] = temp & RH_B_DR;
- if (data_buf [2] < 7) {
- data_buf [8] = 0xff;
+ databuf[7] = temp & RH_B_DR;
+ if (databuf[2] < 7) {
+ databuf[8] = 0xff;
} else {
- data_buf [0] += 2;
- data_buf [8] = (temp & RH_B_DR) >> 8;
- data_buf [10] = data_buf [9] = 0xff;
+ databuf[0] += 2;
+ databuf[8] = (temp & RH_B_DR) >> 8;
+ databuf[10] = databuf[9] = 0xff;
}
len = min_t(unsigned int, leni,
- min_t(unsigned int, data_buf [0], wLength));
+ min_t(unsigned int, databuf[0], wLength));
OK(len);
}
- case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK(1);
+ case RH_GET_CONFIGURATION:
+ databuf[0] = 0x01;
+ OK(1);
- case RH_SET_CONFIGURATION: WR_RH_STAT(0x10000); OK(0);
+ case RH_SET_CONFIGURATION:
+ WR_RH_STAT(0x10000);
+ OK(0);
default:
dbg("unsupported root hub command");
#ifdef DEBUG
ohci_dump_roothub(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
len = min_t(int, len, leni);
- if (data != data_buf)
- memcpy(data, data_buf, len);
+ if (data != databuf)
+ memcpy(data, databuf, len);
dev->act_len = len;
dev->status = stat;
pkt_print(NULL, dev, pipe, buffer,
transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/);
#else
- wait_ms(1);
+ mdelay(1);
#endif
return stat;
pkt_print(urb, dev, pipe, buffer, transfer_len,
setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_common_message: pipesize for pipe %lx is zero",
}
#if 0
- wait_ms(10);
+ mdelay(10);
/* ohci_dump_status(&gohci); */
#endif
- /* allow more time for a BULK device to react - some are slow */
-#define BULK_TO 5000 /* timeout in milliseconds */
- if (usb_pipebulk(pipe))
- timeout = BULK_TO;
- else
- timeout = 1000;
+ timeout = USB_TIMEOUT_MS(pipe);
/* wait for it to complete */
for (;;) {
}
if (--timeout) {
- wait_ms(1);
+ mdelay(1);
if (!urb->finished)
dbg("*");
}
dev->status = stat;
- dev->act_len = transfer_len;
+ dev->act_len = urb->actual_length;
#ifdef DEBUG
pkt_print(urb, dev, pipe, buffer, transfer_len,
setup, "RET(ctlr)", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* free TDs in urb_priv */
pkt_print(NULL, dev, pipe, buffer, transfer_len,
setup, "SUB", usb_pipein(pipe));
#else
- wait_ms(1);
+ mdelay(1);
#endif
if (!maxsize) {
err("submit_control_message: pipesize for pipe %lx is zero",
ohci_writel(OHCI_OCR, &ohci->regs->cmdstatus);
info("USB HC TakeOver from SMM");
while (ohci_readl(&ohci->regs->control) & OHCI_CTRL_IR) {
- wait_ms(10);
+ mdelay(10);
if (--smm_timeout == 0) {
err("USB HC TakeOver failed!");
return -1;
ohci_writel(RH_HS_LPSC, &ohci->regs->roothub.status);
#endif /* OHCI_USE_NPS */
-#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); })
/* POTPGT delay is bits 24-31, in 2 ms units. */
mdelay((roothub_a(ohci) >> 23) & 0x1fe);
/*-------------------------------------------------------------------------*/
-/* Poll USB interrupt. */
-void usb_event_poll(void)
-{
- hc_interrupt();
-}
-
/* an interrupt happens */
static int hc_interrupt(void)
#ifdef DEBUG
ohci_dump(ohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
/* FIXME: be optimistic, hope that bug won't repeat often. */
/* Make some non-interrupt context restart the controller. */
}
if (ints & OHCI_INTR_WDH) {
- wait_ms(1);
+ mdelay(1);
ohci_writel(OHCI_INTR_WDH, ®s->intrdisable);
(void)ohci_readl(®s->intrdisable); /* flush */
stat = dl_done_list(&gohci);
/* FIXME: this assumes SOF (1/ms) interrupts don't get lost... */
if (ints & OHCI_INTR_SF) {
unsigned int frame = m16_swap(ohci->hcca->frame_no) & 1;
- wait_ms(1);
+ mdelay(1);
ohci_writel(OHCI_INTR_SF, ®s->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
ohci_writel(OHCI_INTR_SF, ®s->intrenable);
*/
static char ohci_inited = 0;
-int usb_lowlevel_init(void)
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
{
#ifdef CONFIG_PCI_OHCI
pci_dev_t pdev;
#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
/* board dependant init */
- if (usb_board_init())
+ if (board_usb_init(index, USB_INIT_HOST))
return -1;
#endif
memset(&gohci, 0, sizeof(ohci_t));
err ("can't reset usb-%s", gohci.slot_name);
#ifdef CONFIG_SYS_USB_OHCI_BOARD_INIT
/* board dependant cleanup */
- usb_board_init_fail();
+ board_usb_cleanup(index, USB_INIT_HOST);
#endif
#ifdef CONFIG_SYS_USB_OHCI_CPU_INIT
#ifdef DEBUG
ohci_dump(&gohci, 1);
#else
- wait_ms(1);
+ mdelay(1);
#endif
ohci_inited = 1;
return 0;
}
-int usb_lowlevel_stop(void)
+int usb_lowlevel_stop(int index)
{
/* this gets called really early - before the controller has */
/* even been initialized! */