Commit dbe9d83a authored by David Brownell's avatar David Brownell Committed by Greg Kroah-Hartman

[PATCH] Re: [patch 2.5.31-bk5] uhci, misc

This patch has some small UHCI bugfixes

   - on submit error, frees memory and (!) returns error code
   - root hub should disconnect only once
   - pci pool code shouldn't be given GFP_DMA
   - uses del_timer_sync(), which behaves on SMP, not del_timer()

and cleanups:

   - use container_of
   - doesn't replicate so much hcd state
   - no such status -ECONNABORTED
   - uses bus_name in procfs, not "hc0", "hc1" etc
parent 73073f12
...@@ -146,7 +146,7 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *d ...@@ -146,7 +146,7 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *d
dma_addr_t dma_handle; dma_addr_t dma_handle;
struct uhci_td *td; struct uhci_td *td;
td = pci_pool_alloc(uhci->td_pool, GFP_DMA | GFP_ATOMIC, &dma_handle); td = pci_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle);
if (!td) if (!td)
return NULL; return NULL;
...@@ -325,7 +325,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *d ...@@ -325,7 +325,7 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, struct usb_device *d
dma_addr_t dma_handle; dma_addr_t dma_handle;
struct uhci_qh *qh; struct uhci_qh *qh;
qh = pci_pool_alloc(uhci->qh_pool, GFP_DMA | GFP_ATOMIC, &dma_handle); qh = pci_pool_alloc(uhci->qh_pool, GFP_ATOMIC, &dma_handle);
if (!qh) if (!qh)
return NULL; return NULL;
...@@ -1498,6 +1498,10 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, int mem_flags) ...@@ -1498,6 +1498,10 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, int mem_flags)
spin_unlock_irqrestore(&uhci->urb_list_lock, flags); spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
if (ret != -EINPROGRESS) {
uhci_destroy_urb_priv (uhci, urb);
return ret;
}
return 0; return 0;
} }
...@@ -1806,8 +1810,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb) ...@@ -1806,8 +1810,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb)
spin_lock_irqsave(&urb->lock, flags); spin_lock_irqsave(&urb->lock, flags);
killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED || killed = (urb->status == -ENOENT || urb->status == -ECONNRESET);
urb->status == -ECONNRESET);
resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT && resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
urb->interval); urb->interval);
...@@ -1828,9 +1831,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb) ...@@ -1828,9 +1831,7 @@ static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb)
if (resubmit_interrupt) if (resubmit_interrupt)
/* Recheck the status. The completion handler may have */ /* Recheck the status. The completion handler may have */
/* unlinked the resubmitting interrupt URB */ /* unlinked the resubmitting interrupt URB */
killed = (urb->status == -ENOENT || killed = (urb->status == -ENOENT || urb->status == -ECONNRESET);
urb->status == -ECONNABORTED ||
urb->status == -ECONNRESET);
if (resubmit_interrupt && !killed) { if (resubmit_interrupt && !killed) {
urb->dev = dev; urb->dev = dev;
...@@ -2027,19 +2028,12 @@ static void start_hc(struct uhci_hcd *uhci) ...@@ -2027,19 +2028,12 @@ static void start_hc(struct uhci_hcd *uhci)
uhci->hcd.state = USB_STATE_READY; uhci->hcd.state = USB_STATE_READY;
} }
#ifdef CONFIG_PROC_FS
static int uhci_num = 0;
#endif
/* /*
* De-allocate all resources.. * De-allocate all resources..
*/ */
static void release_uhci(struct uhci_hcd *uhci) static void release_uhci(struct uhci_hcd *uhci)
{ {
int i; int i;
#ifdef CONFIG_PROC_FS
char buf[8];
#endif
for (i = 0; i < UHCI_NUM_SKELQH; i++) for (i = 0; i < UHCI_NUM_SKELQH; i++)
if (uhci->skelqh[i]) { if (uhci->skelqh[i]) {
...@@ -2064,15 +2058,13 @@ static void release_uhci(struct uhci_hcd *uhci) ...@@ -2064,15 +2058,13 @@ static void release_uhci(struct uhci_hcd *uhci)
} }
if (uhci->fl) { if (uhci->fl) {
pci_free_consistent(uhci->dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); pci_free_consistent(uhci->hcd.pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
uhci->fl = NULL; uhci->fl = NULL;
} }
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
if (uhci->proc_entry) { if (uhci->proc_entry) {
sprintf(buf, "hc%d", uhci->num); remove_proc_entry(uhci->hcd.self.bus_name, uhci_proc_root);
remove_proc_entry(buf, uhci_proc_root);
uhci->proc_entry = NULL; uhci->proc_entry = NULL;
} }
#endif #endif
...@@ -2097,33 +2089,20 @@ static void release_uhci(struct uhci_hcd *uhci) ...@@ -2097,33 +2089,20 @@ static void release_uhci(struct uhci_hcd *uhci)
static int __devinit uhci_start(struct usb_hcd *hcd) static int __devinit uhci_start(struct usb_hcd *hcd)
{ {
struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct uhci_hcd *uhci = hcd_to_uhci(hcd);
struct pci_dev *dev = hcd->pdev;
int retval = -EBUSY; int retval = -EBUSY;
int i, port; int i, port;
unsigned io_size;
dma_addr_t dma_handle; dma_addr_t dma_handle;
struct usb_device *udev;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
char buf[8];
struct proc_dir_entry *ent; struct proc_dir_entry *ent;
#endif #endif
uhci->dev = dev; uhci->io_addr = (unsigned) hcd->regs;
io_size = pci_resource_len(hcd->pdev, hcd->region);
/* Should probably move to core/hcd.c */
if (pci_set_dma_mask(dev, 0xFFFFFFFF)) {
err("couldn't set PCI dma mask");
retval = -ENODEV;
goto err_pci_set_dma_mask;
}
uhci->io_addr = pci_resource_start(dev, hcd->region);
uhci->io_size = pci_resource_len(dev, hcd->region);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
uhci->num = uhci_num++; ent = create_proc_entry(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
sprintf(buf, "hc%d", uhci->num);
ent = create_proc_entry(buf, S_IFREG|S_IRUGO|S_IWUSR, uhci_proc_root);
if (!ent) { if (!ent) {
err("couldn't create uhci proc entry"); err("couldn't create uhci proc entry");
retval = -ENOMEM; retval = -ENOMEM;
...@@ -2159,7 +2138,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2159,7 +2138,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
spin_lock_init(&uhci->frame_list_lock); spin_lock_init(&uhci->frame_list_lock);
uhci->fl = pci_alloc_consistent(dev, sizeof(*uhci->fl), &dma_handle); uhci->fl = pci_alloc_consistent(hcd->pdev, sizeof(*uhci->fl), &dma_handle);
if (!uhci->fl) { if (!uhci->fl) {
err("unable to allocate consistent memory for frame list"); err("unable to allocate consistent memory for frame list");
goto err_alloc_fl; goto err_alloc_fl;
...@@ -2169,15 +2148,15 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2169,15 +2148,15 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
uhci->fl->dma_handle = dma_handle; uhci->fl->dma_handle = dma_handle;
uhci->td_pool = pci_pool_create("uhci_td", dev, uhci->td_pool = pci_pool_create("uhci_td", hcd->pdev,
sizeof(struct uhci_td), 16, 0, GFP_DMA | GFP_ATOMIC); sizeof(struct uhci_td), 16, 0, GFP_ATOMIC);
if (!uhci->td_pool) { if (!uhci->td_pool) {
err("unable to create td pci_pool"); err("unable to create td pci_pool");
goto err_create_td_pool; goto err_create_td_pool;
} }
uhci->qh_pool = pci_pool_create("uhci_qh", dev, uhci->qh_pool = pci_pool_create("uhci_qh", hcd->pdev,
sizeof(struct uhci_qh), 16, 0, GFP_DMA | GFP_ATOMIC); sizeof(struct uhci_qh), 16, 0, GFP_ATOMIC);
if (!uhci->qh_pool) { if (!uhci->qh_pool) {
err("unable to create qh pci_pool"); err("unable to create qh pci_pool");
goto err_create_qh_pool; goto err_create_qh_pool;
...@@ -2189,7 +2168,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2189,7 +2168,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
/* they may have more but give no way to determine how many they */ /* they may have more but give no way to determine how many they */
/* have. However, according to the UHCI spec, Bit 7 is always set */ /* have. However, according to the UHCI spec, Bit 7 is always set */
/* to 1. So we try to use this to our advantage */ /* to 1. So we try to use this to our advantage */
for (port = 0; port < (uhci->io_size - 0x10) / 2; port++) { for (port = 0; port < (io_size - 0x10) / 2; port++) {
unsigned int portstatus; unsigned int portstatus;
portstatus = inw(uhci->io_addr + 0x10 + (port * 2)); portstatus = inw(uhci->io_addr + 0x10 + (port * 2));
...@@ -2208,13 +2187,13 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2208,13 +2187,13 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
uhci->rh_numports = port; uhci->rh_numports = port;
hcd->self.root_hub = uhci->rh_dev = usb_alloc_dev(NULL, &hcd->self); hcd->self.root_hub = udev = usb_alloc_dev(NULL, &hcd->self);
if (!uhci->rh_dev) { if (!udev) {
err("unable to allocate root hub"); err("unable to allocate root hub");
goto err_alloc_root_hub; goto err_alloc_root_hub;
} }
uhci->skeltd[0] = uhci_alloc_td(uhci, uhci->rh_dev); uhci->skeltd[0] = uhci_alloc_td(uhci, udev);
if (!uhci->skeltd[0]) { if (!uhci->skeltd[0]) {
err("unable to allocate TD 0"); err("unable to allocate TD 0");
goto err_alloc_skeltd; goto err_alloc_skeltd;
...@@ -2227,7 +2206,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2227,7 +2206,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
for (i = 1; i < 9; i++) { for (i = 1; i < 9; i++) {
struct uhci_td *td; struct uhci_td *td;
td = uhci->skeltd[i] = uhci_alloc_td(uhci, uhci->rh_dev); td = uhci->skeltd[i] = uhci_alloc_td(uhci, udev);
if (!td) { if (!td) {
err("unable to allocate TD %d", i); err("unable to allocate TD %d", i);
goto err_alloc_skeltd; goto err_alloc_skeltd;
...@@ -2238,14 +2217,14 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2238,14 +2217,14 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
td->link = cpu_to_le32(uhci->skeltd[i - 1]->dma_handle); td->link = cpu_to_le32(uhci->skeltd[i - 1]->dma_handle);
} }
uhci->skel_term_td = uhci_alloc_td(uhci, uhci->rh_dev); uhci->skel_term_td = uhci_alloc_td(uhci, udev);
if (!uhci->skel_term_td) { if (!uhci->skel_term_td) {
err("unable to allocate skel TD term"); err("unable to allocate skel TD term");
goto err_alloc_skeltd; goto err_alloc_skeltd;
} }
for (i = 0; i < UHCI_NUM_SKELQH; i++) { for (i = 0; i < UHCI_NUM_SKELQH; i++) {
uhci->skelqh[i] = uhci_alloc_qh(uhci, uhci->rh_dev); uhci->skelqh[i] = uhci_alloc_qh(uhci, udev);
if (!uhci->skelqh[i]) { if (!uhci->skelqh[i]) {
err("unable to allocate QH %d", i); err("unable to allocate QH %d", i);
goto err_alloc_skelqh; goto err_alloc_skelqh;
...@@ -2314,12 +2293,12 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2314,12 +2293,12 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
init_stall_timer(hcd); init_stall_timer(hcd);
/* disable legacy emulation */ /* disable legacy emulation */
pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT); pci_write_config_word(hcd->pdev, USBLEGSUP, USBLEGSUP_DEFAULT);
usb_connect(uhci->rh_dev); usb_connect(udev);
uhci->rh_dev->speed = USB_SPEED_FULL; udev->speed = USB_SPEED_FULL;
if (usb_register_root_hub(uhci->rh_dev, &dev->dev) != 0) { if (usb_register_root_hub(udev, &hcd->pdev->dev) != 0) {
err("unable to start root hub"); err("unable to start root hub");
retval = -ENOMEM; retval = -ENOMEM;
goto err_start_root_hub; goto err_start_root_hub;
...@@ -2333,7 +2312,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2333,7 +2312,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
err_start_root_hub: err_start_root_hub:
reset_hc(uhci); reset_hc(uhci);
del_timer(&uhci->stall_timer); del_timer_sync(&uhci->stall_timer);
for (i = 0; i < UHCI_NUM_SKELQH; i++) for (i = 0; i < UHCI_NUM_SKELQH; i++)
if (uhci->skelqh[i]) { if (uhci->skelqh[i]) {
...@@ -2349,8 +2328,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2349,8 +2328,7 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
} }
err_alloc_skeltd: err_alloc_skeltd:
usb_free_dev(uhci->rh_dev); usb_free_dev(udev);
uhci->rh_dev = NULL;
err_alloc_root_hub: err_alloc_root_hub:
pci_pool_destroy(uhci->qh_pool); pci_pool_destroy(uhci->qh_pool);
...@@ -2361,19 +2339,17 @@ static int __devinit uhci_start(struct usb_hcd *hcd) ...@@ -2361,19 +2339,17 @@ static int __devinit uhci_start(struct usb_hcd *hcd)
uhci->td_pool = NULL; uhci->td_pool = NULL;
err_create_td_pool: err_create_td_pool:
pci_free_consistent(dev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle); pci_free_consistent(hcd->pdev, sizeof(*uhci->fl), uhci->fl, uhci->fl->dma_handle);
uhci->fl = NULL; uhci->fl = NULL;
err_alloc_fl: err_alloc_fl:
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
remove_proc_entry(buf, uhci_proc_root); remove_proc_entry(hcd->self.bus_name, uhci_proc_root);
uhci->proc_entry = NULL; uhci->proc_entry = NULL;
err_create_proc_entry: err_create_proc_entry:
#endif #endif
err_pci_set_dma_mask:
return retval; return retval;
} }
...@@ -2381,10 +2357,7 @@ static void uhci_stop(struct usb_hcd *hcd) ...@@ -2381,10 +2357,7 @@ static void uhci_stop(struct usb_hcd *hcd)
{ {
struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct uhci_hcd *uhci = hcd_to_uhci(hcd);
if (uhci->rh_dev) del_timer_sync(&uhci->stall_timer);
usb_disconnect(&uhci->rh_dev);
del_timer(&uhci->stall_timer);
/* /*
* At this point, we're guaranteed that no new connects can be made * At this point, we're guaranteed that no new connects can be made
...@@ -2413,7 +2386,7 @@ static int uhci_resume(struct usb_hcd *hcd) ...@@ -2413,7 +2386,7 @@ static int uhci_resume(struct usb_hcd *hcd)
{ {
struct uhci_hcd *uhci = hcd_to_uhci(hcd); struct uhci_hcd *uhci = hcd_to_uhci(hcd);
pci_set_master(uhci->dev); pci_set_master(uhci->hcd.pdev);
reset_hc(uhci); reset_hc(uhci);
start_hc(uhci); start_hc(uhci);
......
...@@ -308,7 +308,7 @@ static inline int __interval_to_skel(int interval) ...@@ -308,7 +308,7 @@ static inline int __interval_to_skel(int interval)
return 7; /* int128 for 128-255 ms (Max.) */ return 7; /* int128 for 128-255 ms (Max.) */
} }
#define hcd_to_uhci(hcd_ptr) list_entry(hcd_ptr, struct uhci_hcd, hcd) #define hcd_to_uhci(hcd_ptr) container_of(hcd_ptr, struct uhci_hcd, hcd)
/* /*
* This describes the full uhci information. * This describes the full uhci information.
...@@ -319,18 +319,13 @@ static inline int __interval_to_skel(int interval) ...@@ -319,18 +319,13 @@ static inline int __interval_to_skel(int interval)
struct uhci_hcd { struct uhci_hcd {
struct usb_hcd hcd; struct usb_hcd hcd;
struct pci_dev *dev;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
/* procfs */ /* procfs */
int num;
struct proc_dir_entry *proc_entry; struct proc_dir_entry *proc_entry;
#endif #endif
/* Grabbed from PCI */ /* Grabbed from PCI */
int irq;
unsigned int io_addr; unsigned int io_addr;
unsigned int io_size;
struct pci_pool *qh_pool; struct pci_pool *qh_pool;
struct pci_pool *td_pool; struct pci_pool *td_pool;
...@@ -362,7 +357,6 @@ struct uhci_hcd { ...@@ -362,7 +357,6 @@ struct uhci_hcd {
spinlock_t complete_list_lock; spinlock_t complete_list_lock;
struct list_head complete_list; /* P: uhci->complete_list_lock */ struct list_head complete_list; /* P: uhci->complete_list_lock */
struct usb_device *rh_dev; /* Root hub */
int rh_numports; int rh_numports;
struct timer_list stall_timer; struct timer_list stall_timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment