Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 33771 Details for
Bug 54684
Pegasos patches for gentoo-dev-sources
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
2905_uhci.patch
2905_uhci.patch (text/plain), 7.71 KB, created by
David Holm (RETIRED)
on 2004-06-21 13:37:51 UTC
(
hide
)
Description:
2905_uhci.patch
Filename:
MIME Type:
Creator:
David Holm (RETIRED)
Created:
2004-06-21 13:37:51 UTC
Size:
7.71 KB
patch
obsolete
>--- drivers/usb/host/uhci-hcd.c.orig 2004-06-21 21:25:40.000000000 +0200 >+++ drivers/usb/host/uhci-hcd.c 2004-06-21 21:36:31.916149088 +0200 >@@ -135,6 +135,41 @@ > list_move_tail(&urbp->urb_list, &uhci->complete_list); > } > >+/********************************/ >+/********************************/ >+/********************************/ >+/********************************/ >+// PATCH >+// >+// Stop the interrupt inside the chip >+// You have to pass the uhci structure >+// you will get back the old interrupt state that you have >+// to pass back to start_interrupt >+static u16 stop_interrupt(struct usb_hcd *hcd) >+{ >+ struct uhci_hcd *uhci = hcd_to_uhci(hcd); >+ unsigned int io_addr = uhci->io_addr; >+ >+ u16 old_value = uhci->IntEnableReg_SW; >+ uhci->IntEnableReg_SW = 0; >+ outw(0, io_addr + USBINTR); >+ >+ return old_value; >+} >+ >+static void start_interrupt(struct usb_hcd *hcd, u16 restore_value) >+{ >+ struct uhci_hcd *uhci = hcd_to_uhci(hcd); >+ unsigned int io_addr = uhci->io_addr; >+ >+ uhci->IntEnableReg_SW = restore_value; >+ outw(restore_value, io_addr + USBINTR); >+} >+/********************************/ >+/********************************/ >+/********************************/ >+/********************************/ >+ > static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci, struct usb_device *dev) > { > dma_addr_t dma_handle; >@@ -1346,11 +1381,14 @@ > { > int ret = -EINVAL; > struct uhci_hcd *uhci = hcd_to_uhci(hcd); >- unsigned long flags; >+ //unsigned long flags; >+ u16 irq_state; > struct urb *eurb; > int bustime; > >- spin_lock_irqsave(&uhci->schedule_lock, flags); >+ //PATCH >+ spin_lock_irq(&uhci->schedule_lock); >+ irq_state = stop_interrupt(hcd); > > if (urb->status != -EINPROGRESS) /* URB already unlinked! */ > goto out; >@@ -1407,7 +1445,10 @@ > ret = 0; > > out: >- spin_unlock_irqrestore(&uhci->schedule_lock, flags); >+ //PATCH >+ spin_unlock(&uhci->schedule_lock); >+ start_interrupt(hcd, irq_state); >+ > return ret; > } > >@@ -1528,11 +1569,15 @@ > static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) > { > struct uhci_hcd *uhci = hcd_to_uhci(hcd); >- unsigned long flags; >+ //unsigned long flags; >+ u16 irq_state; > struct urb_priv *urbp; > unsigned int age; > >- spin_lock_irqsave(&uhci->schedule_lock, flags); >+ // PATCH >+ spin_lock_irq(&uhci->schedule_lock); >+ irq_state = stop_interrupt(hcd); >+ > urbp = urb->hcpriv; > if (!urbp) /* URB was never linked! */ > goto done; >@@ -1552,7 +1597,9 @@ > list_add_tail(&urbp->urb_list, &uhci->urb_remove_list); > > done: >- spin_unlock_irqrestore(&uhci->schedule_lock, flags); >+ // PATCH >+ spin_unlock(&uhci->schedule_lock); >+ start_interrupt(hcd, irq_state); > return 0; > } > >@@ -1610,11 +1657,16 @@ > struct usb_hcd *hcd = (struct usb_hcd *)ptr; > struct uhci_hcd *uhci = hcd_to_uhci(hcd); > struct list_head list, *tmp, *head; >- unsigned long flags; >+ //unsigned long flags; >+ >+ // PATCH >+ u16 irq_state; > > INIT_LIST_HEAD(&list); > >- spin_lock_irqsave(&uhci->schedule_lock, flags); >+ spin_lock(&uhci->schedule_lock); >+ irq_state = stop_interrupt(hcd); >+ > if (!list_empty(&uhci->urb_remove_list) && > uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) { > uhci_remove_pending_urbps(uhci); >@@ -1644,7 +1696,9 @@ > > spin_unlock(&u->lock); > } >- spin_unlock_irqrestore(&uhci->schedule_lock, flags); >+ // PATCH >+ spin_unlock(&uhci->schedule_lock); >+ start_interrupt(hcd, irq_state); > > head = &list; > tmp = head->next; >@@ -1761,14 +1815,24 @@ > struct list_head *tmp, *head; > unsigned int age; > >+ // PATCH >+ irqreturn_t retval = IRQ_HANDLED; >+ >+ // disable interrupt >+ outw(0, io_addr + USBINTR); >+ > /* > * Read the interrupt status, and write it back to clear the > * interrupt cause. Contrary to the UHCI specification, the > * "HC Halted" status bit is persistent: it is RO, not R/WC. > */ > status = inw(io_addr + USBSTS); >- if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ >- return IRQ_NONE; >+ if ( (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ >+ || (!uhci->IntEnableReg_SW) ) >+ { >+ retval = IRQ_NONE; >+ goto end; >+ } > outw(status, io_addr + USBSTS); /* Clear it */ > > if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { >@@ -1788,7 +1852,7 @@ > if (status & USBSTS_RD) > uhci->resume_detect = 1; > >- spin_lock(&uhci->schedule_lock); >+ //spin_lock(&uhci->schedule_lock); > > age = uhci_get_current_frame_number(uhci); > if (age != uhci->qh_remove_age) >@@ -1819,12 +1883,14 @@ > } > uhci_finish_completion(hcd, regs); > >- spin_unlock(&uhci->schedule_lock); >- > /* Wake up anyone waiting for an URB to complete */ > wake_up_all(&uhci->waitqh); > >- return IRQ_HANDLED; >+ // PATCH >+end: >+ //spin_unlock(&uhci->schedule_lock); >+ outw(uhci->IntEnableReg_SW, io_addr + USBINTR); >+ return retval; > } > > static void reset_hc(struct uhci_hcd *uhci) >@@ -1991,6 +2057,8 @@ > } > > /* Turn on all interrupts */ >+ // PATCH >+ uhci->IntEnableReg_SW = USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP; > outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, > io_addr + USBINTR); > >@@ -2113,7 +2181,8 @@ > uhci->fsbr = 0; > uhci->fsbrtimeout = 0; > >- spin_lock_init(&uhci->schedule_lock); >+ // PATCH >+ //spin_lock_init(&uhci->schedule_lock); > INIT_LIST_HEAD(&uhci->qh_remove_list); > > INIT_LIST_HEAD(&uhci->td_remove_list); >@@ -2139,14 +2208,14 @@ > uhci->fl->dma_handle = dma_handle; > > uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), >- sizeof(struct uhci_td), 16, 0); >+ sizeof(struct uhci_td), UHCI_ALIGN, 0); > if (!uhci->td_pool) { > dev_err(uhci_dev(uhci), "unable to create td dma_pool\n"); > goto err_create_td_pool; > } > > uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci), >- sizeof(struct uhci_qh), 16, 0); >+ sizeof(struct uhci_qh), UHCI_ALIGN, 0); > if (!uhci->qh_pool) { > dev_err(uhci_dev(uhci), "unable to create qh dma_pool\n"); > goto err_create_qh_pool; >@@ -2317,6 +2386,7 @@ > static void uhci_stop(struct usb_hcd *hcd) > { > struct uhci_hcd *uhci = hcd_to_uhci(hcd); >+ u16 irq_state; > > del_timer_sync(&uhci->stall_timer); > >@@ -2327,7 +2397,10 @@ > > reset_hc(uhci); > >- spin_lock_irq(&uhci->schedule_lock); >+ //PATCH >+ spin_lock(&uhci->schedule_lock); >+ irq_state = stop_interrupt(hcd); >+ > uhci_free_pending_qhs(uhci); > uhci_free_pending_tds(uhci); > uhci_remove_pending_urbps(uhci); >@@ -2335,10 +2408,13 @@ > > uhci_free_pending_qhs(uhci); > uhci_free_pending_tds(uhci); >- spin_unlock_irq(&uhci->schedule_lock); > > /* Wake up anyone waiting for an URB to complete */ > wake_up_all(&uhci->waitqh); >+ >+ // PATCH >+ spin_unlock(&uhci->schedule_lock); >+ start_interrupt(hcd, irq_state); > > release_uhci(uhci); > } >--- drivers/usb/host/uhci-hcd.h.orig 2004-06-21 21:25:40.000000000 +0200 >+++ drivers/usb/host/uhci-hcd.h 2004-06-21 21:37:02.584486792 +0200 >@@ -7,6 +7,14 @@ > #define usb_packetid(pipe) (usb_pipein(pipe) ? USB_PID_IN : USB_PID_OUT) > #define PIPE_DEVEP_MASK 0x0007ff00 > >+//PATCH >+#if L1_CACHE_LINE_SIZE > 16 >+#define UHCI_ALIGN L1_CACHE_LINE_SIZE >+#else >+#define UHCI_ALIGN 16 >+#endif >+ >+ > /* > * Universal Host Controller Interface data structures and defines > */ >@@ -109,14 +117,15 @@ > u32 element; /* Queue element pointer */ > > /* Software fields */ >- dma_addr_t dma_handle; >+ // PATCH >+ dma_addr_t dma_handle __attribute__((aligned( UHCI_ALIGN ))); // Ensure that the software fields are out of any cache line or burst write so they can't be overwrite by DMA operation > > struct usb_device *dev; > struct urb_priv *urbp; > > struct list_head list; /* P: uhci->frame_list_lock */ > struct list_head remove_list; /* P: uhci->remove_list_lock */ >-} __attribute__((aligned(16))); >+} __attribute__((aligned( UHCI_ALIGN ))); > > /* > * for TD <status>: >@@ -374,6 +383,10 @@ > > struct timer_list stall_timer; > >+ // PATCH >+ // Software state of the interrupt register >+ u16 IntEnableReg_SW; >+ > wait_queue_head_t waitqh; /* endpoint_disable waiters */ > }; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 54684
:
33769
|
33770
|
33771
|
33772