summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/ohci-hcd.c35
-rw-r--r--drivers/usb/host/ohci.h4
2 files changed, 38 insertions, 1 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 2f976d2..5364ced 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1478,6 +1478,31 @@ pkt_print(ohci, NULL, dev, pipe, buffer, transfer_len,
/*-------------------------------------------------------------------------*/
+static ohci_dev_t *ohci_get_ohci_dev(ohci_t *ohci, int devnum, int intr)
+{
+ int i;
+
+ if (!intr)
+ return &ohci->ohci_dev;
+
+ /* First see if we already have an ohci_dev for this dev. */
+ for (i = 0; i < NUM_INT_DEVS; i++) {
+ if (ohci->int_dev[i].devnum == devnum)
+ return &ohci->int_dev[i];
+ }
+
+ /* If not then find a free one. */
+ for (i = 0; i < NUM_INT_DEVS; i++) {
+ if (ohci->int_dev[i].devnum == -1) {
+ ohci->int_dev[i].devnum = devnum;
+ return &ohci->int_dev[i];
+ }
+ }
+
+ printf("ohci: Error out of ohci_devs for interrupt endpoints\n");
+ return NULL;
+}
+
/* common code for handling submit messages - used for all but root hub */
/* accesses. */
static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
@@ -1488,6 +1513,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
int maxsize = usb_maxpacket(dev, pipe);
int timeout;
urb_priv_t *urb;
+ ohci_dev_t *ohci_dev;
urb = malloc(sizeof(urb_priv_t));
memset(urb, 0, sizeof(urb_priv_t));
@@ -1511,7 +1537,11 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev,
return -1;
}
- if (sohci_submit_job(ohci, &ohci->ohci_dev, urb, setup) < 0) {
+ ohci_dev = ohci_get_ohci_dev(ohci, dev->devnum, usb_pipeint(pipe));
+ if (!ohci_dev)
+ return -ENOMEM;
+
+ if (sohci_submit_job(ohci, ohci_dev, urb, setup) < 0) {
err("sohci_submit_job failed");
return -1;
}
@@ -1711,8 +1741,11 @@ static int hc_start(ohci_t *ohci)
{
__u32 mask;
unsigned int fminterval;
+ int i;
ohci->disabled = 1;
+ for (i = 0; i < NUM_INT_DEVS; i++)
+ ohci->int_dev[i].devnum = -1;
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 3f9869b..f1526d4 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -367,10 +367,13 @@ typedef struct
#define NUM_TD 64 /* we need more TDs than EDs */
+#define NUM_INT_DEVS 8 /* num of ohci_dev structs for int endpoints */
+
typedef struct ohci_device {
ed_t ed[NUM_EDS] __aligned(ED_ALIGNMENT);
td_t tds[NUM_TD] __aligned(TD_ALIGNMENT);
int ed_cnt;
+ int devnum;
} ohci_dev_t;
/*
@@ -384,6 +387,7 @@ typedef struct ohci_device {
typedef struct ohci {
/* this allocates EDs for all possible endpoints */
struct ohci_device ohci_dev __aligned(TD_ALIGNMENT);
+ struct ohci_device int_dev[NUM_INT_DEVS] __aligned(TD_ALIGNMENT);
struct ohci_hcca *hcca; /* hcca */
/*dma_addr_t hcca_dma;*/