summaryrefslogtreecommitdiff
path: root/cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c')
-rw-r--r--cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c113
1 files changed, 108 insertions, 5 deletions
diff --git a/cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c b/cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c
index 8a8e08a51b..2c665dbde2 100644
--- a/cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c
+++ b/cleopatre/linux-2.6.25.10-spc300/drivers/usb/host/ehci-sched.c
@@ -35,6 +35,9 @@
*/
static int ehci_get_frame (struct usb_hcd *hcd);
+#if _USB_T3_WBTIMEOUT_PATCH
+extern void chip_flush_memory(void);
+#endif
/*-------------------------------------------------------------------------*/
@@ -840,7 +843,9 @@ static int intr_submit (
/* ... update usbfs periodic stats */
ehci_to_hcd(ehci)->self.bandwidth_int_reqs++;
-
+#if _USB_T3_WBTIMEOUT_PATCH
+ chip_flush_memory();
+#endif
done:
if (unlikely(status))
usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
@@ -886,7 +891,9 @@ iso_stream_init (
unsigned epnum, maxp;
int is_input;
long bandwidth;
-
+#if defined(MSTAR_PATCH_USB_HCD)
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
/*
* this might be a "high bandwidth" highspeed endpoint,
* as encoded in the ep descriptor's wMaxPacket field
@@ -927,10 +934,16 @@ iso_stream_init (
int hs_transfers;
addr = dev->ttport << 24;
+#if defined(MSTAR_PATCH_USB_HCD)
+ if (dev->tt) {
+#endif
if (!ehci_is_TDI(ehci)
|| (dev->tt->hub !=
ehci_to_hcd(ehci)->self.root_hub))
addr |= dev->tt->hub->devnum << 16;
+#if defined(MSTAR_PATCH_USB_HCD)
+ }
+#endif
addr |= epnum << 8;
addr |= dev->devnum;
stream->usecs = HS_USECS_ISO (maxp);
@@ -956,6 +969,21 @@ iso_stream_init (
/* stream->splits gets created from raw_mask later */
stream->address = cpu_to_hc32(ehci, addr);
+
+#if defined(MSTAR_PATCH_USB_HCD)
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (dev->speed != USB_SPEED_HIGH)) {
+ unsigned multi = 1;
+
+ maxp = max_packet(maxp);
+ buf1 |= maxp;
+
+ stream->buf0 = cpu_to_hc32(ehci, (epnum << 8) | dev->devnum);
+ stream->buf1 = cpu_to_hc32(ehci, buf1);
+ stream->buf2 = cpu_to_hc32(ehci, multi);
+ }
+#endif
}
stream->bandwidth = bandwidth;
@@ -969,6 +997,9 @@ iso_stream_init (
static void
iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
{
+#if defined(MSTAR_PATCH_USB_HCD)
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
stream->refcount--;
/* free whenever just a dev->ep reference remains.
@@ -994,12 +1025,26 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
dma_pool_free (ehci->itd_pool, itd,
itd->itd_dma);
} else {
+#if defined(MSTAR_PATCH_USB_HCD)
+ /* Colin, patch for not real split-transaction mode */
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (stream->udev->speed != USB_SPEED_HIGH)) {
+ struct ehci_itd *itd;
+
+ itd = list_entry (entry, struct ehci_itd, itd_list);
+ dma_pool_free (ehci->itd_pool, itd, itd->itd_dma);
+ } else {
+#endif
+
struct ehci_sitd *sitd;
sitd = list_entry (entry, struct ehci_sitd,
sitd_list);
dma_pool_free (ehci->sitd_pool, sitd,
sitd->sitd_dma);
+#if defined(MSTAR_PATCH_USB_HCD)
+ }
+#endif
}
}
@@ -1157,17 +1202,28 @@ itd_urb_transaction (
unsigned num_itds;
struct ehci_iso_sched *sched;
unsigned long flags;
-
+#if defined(MSTAR_PATCH_USB_HCD)
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
sched = iso_sched_alloc (urb->number_of_packets, mem_flags);
if (unlikely (sched == NULL))
return -ENOMEM;
itd_sched_init(ehci, sched, stream, urb);
-
+#if defined(MSTAR_PATCH_USB_HCD)
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (urb->dev->speed != USB_SPEED_HIGH)) {
+ num_itds = urb->number_of_packets;
+ } else {
+#endif
if (urb->interval < 8)
num_itds = 1 + (sched->span + 7) / 8;
else
num_itds = urb->number_of_packets;
+#if defined(MSTAR_PATCH_USB_HCD)
+ }
+#endif
/* allocate/init ITDs */
spin_lock_irqsave (&ehci->lock, flags);
@@ -1502,7 +1558,15 @@ itd_link_urb (
unsigned next_uframe, uframe, frame;
struct ehci_iso_sched *iso_sched = urb->hcpriv;
struct ehci_itd *itd;
+#if defined(MSTAR_PATCH_USB_HCD)
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (urb->dev->speed != USB_SPEED_HIGH))
+ next_uframe = stream->next_uframe;
+ else
+#endif
next_uframe = stream->next_uframe % mod;
if (unlikely (list_empty(&stream->td_list))) {
@@ -1533,7 +1597,21 @@ itd_link_urb (
itd->urb = usb_get_urb (urb);
itd_init (ehci, stream, itd);
}
+#if defined(MSTAR_PATCH_USB_HCD)
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (urb->dev->speed != USB_SPEED_HIGH)) {
+ uframe = 0; //always is transaction 0 of itd
+ frame = next_uframe >> 3;
+ itd_patch(ehci, itd, iso_sched, packet, uframe);
+ itd_link (ehci, frame % ehci->periodic_size, itd);
+ itd = NULL;
+ next_uframe += stream->interval << 3;
+ stream->depth += stream->interval << 3;
+ packet++;
+ } else {
+#endif
uframe = next_uframe & 0x07;
frame = next_uframe >> 3;
@@ -1551,6 +1629,14 @@ itd_link_urb (
itd = NULL;
}
}
+#if defined(MSTAR_PATCH_USB_HCD)
+ }
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (urb->dev->speed != USB_SPEED_HIGH))
+ stream->next_uframe = next_uframe % mod;
+ else
+#endif
stream->next_uframe = next_uframe;
/* don't need that schedule data any more */
@@ -1588,7 +1674,9 @@ itd_complete (
struct ehci_iso_stream *stream = itd->stream;
struct usb_device *dev;
unsigned retval = false;
-
+#if defined(MSTAR_PATCH_USB_HCD)
+ struct usb_hcd *hcd = ehci_to_hcd(ehci);
+#endif
/* for each uframe with a packet */
for (uframe = 0; uframe < 8; uframe++) {
if (likely (itd->index[uframe] == -1))
@@ -1598,6 +1686,13 @@ itd_complete (
t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]);
itd->hw_transaction [uframe] = 0;
+#if defined(MSTAR_PATCH_USB_HCD)
+ //Colin, patch for not real split-transaction mode
+ if (((readb((void*)(hcd->ehc_base+0x41*2-1)) & 0x06) != 0x04)
+ && (urb->dev->speed != USB_SPEED_HIGH))
+ stream->depth -= stream->interval << 3;
+ else
+#endif
stream->depth -= stream->interval;
/* report transfer status */
@@ -1617,7 +1712,12 @@ itd_complete (
desc->actual_length = EHCI_ITD_LENGTH (t);
} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
desc->status = 0;
+#if defined(MSTAR_PATCH_USB_HCD)
+ //Our EHCI send back left data which haven't recved
+ desc->actual_length = desc->length - EHCI_ITD_LENGTH (t);
+#else
desc->actual_length = EHCI_ITD_LENGTH (t);
+#endif
}
}
@@ -1712,6 +1812,9 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb,
itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream);
else
usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb);
+#if _USB_T3_WBTIMEOUT_PATCH
+ chip_flush_memory();
+#endif
done_not_linked:
spin_unlock_irqrestore (&ehci->lock, flags);