diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 35 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 4 |
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;*/ |