📄 1024.usb.patch
字号:
diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/drivers/usb/Config.in linuxmips-2.4.30/drivers/usb/Config.in--- linuxmips-2.4.30.ref/drivers/usb/Config.in 2004-02-19 17:22:18.000000000 -0800+++ linuxmips-2.4.30/drivers/usb/Config.in 2007-06-20 14:13:23.000000000 -0700@@ -4,7 +4,7 @@ mainmenu_option next_comment comment 'USB support' -dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI+dep_tristate 'Support for USB' CONFIG_USB if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then bool ' USB verbose debug messages' CONFIG_USB_DEBUG diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/drivers/usb/hcd.c linuxmips-2.4.30/drivers/usb/hcd.c--- linuxmips-2.4.30.ref/drivers/usb/hcd.c 2004-04-15 20:14:17.000000000 -0700+++ linuxmips-2.4.30/drivers/usb/hcd.c 2007-06-20 14:13:23.000000000 -0700@@ -43,6 +43,9 @@ #include <linux/usb.h> #include "hcd.h"+#ifdef CONFIG_TANGO2+#include "tango2-usb.h"+#endif #include <asm/io.h> #include <asm/irq.h>@@ -562,7 +565,7 @@ /* PCI-based HCs are normal, but custom bus glue should be ok */ -static void hcd_irq (int irq, void *__hcd, struct pt_regs *r);+void hcd_irq (int irq, void *__hcd, struct pt_regs *r); static void hc_died (struct usb_hcd *hcd); /*-------------------------------------------------------------------------*/@@ -902,7 +905,7 @@ /*-------------------------------------------------------------------------*/ /* called from khubd, or root hub init threads for hcd-private init */-static int hcd_alloc_dev (struct usb_device *udev)+int hcd_alloc_dev (struct usb_device *udev) { struct hcd_dev *dev; struct usb_hcd *hcd;@@ -996,7 +999,7 @@ spin_unlock_irqrestore (&hcd_data_lock, flags); } -+#ifdef CONFIG_PCI /* may be called in any context with a valid urb->dev usecount */ /* caller surrenders "ownership" of urb */ @@ -1206,13 +1209,16 @@ if (urb->dev == hcd->bus->root_hub) { status = rh_urb_enqueue (hcd, urb); } else {- if (usb_pipecontrol (urb->pipe))+ if (usb_pipecontrol (urb->pipe)){+ urb->setup_dma = pci_map_single ( hcd->pdev, urb->setup_packet, sizeof (struct usb_ctrlrequest), PCI_DMA_TODEVICE);- if (urb->transfer_buffer_length != 0)+ }+ if (urb->transfer_buffer_length != 0){+ urb->transfer_dma = pci_map_single ( hcd->pdev, urb->transfer_buffer,@@ -1220,6 +1226,238 @@ usb_pipein (urb->pipe) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);+ }+ status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);+ }+ return status;+}+#endif++int tango2_hcd_submit_urb (struct urb *urb)+{+ int status;+ struct usb_hcd *hcd;+ struct hcd_dev *dev;+ unsigned long flags;+ int pipe, temp, max;+ int mem_flags;+++ if (!urb || urb->hcpriv || !urb->complete)+ return -EINVAL;++ urb->status = -EINPROGRESS;+ urb->actual_length = 0;+ urb->bandwidth = 0;+ INIT_LIST_HEAD (&urb->urb_list);++ if (!urb->dev || !urb->dev->bus || urb->dev->devnum <= 0)+ return -ENODEV;+ hcd = urb->dev->bus->hcpriv;+ dev = urb->dev->hcpriv;+ if (!hcd || !dev)+ return -ENODEV;++ /* can't submit new urbs when quiescing, halted, ... */+ if (hcd->state == USB_STATE_QUIESCING || !HCD_IS_RUNNING (hcd->state))+ return -ESHUTDOWN;+ pipe = urb->pipe;+ temp = usb_pipetype (urb->pipe);+ if (usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe),+ usb_pipeout (pipe)))+ return -EPIPE;++ /* NOTE: 2.5 passes this value explicitly in submit() */+ mem_flags = GFP_ATOMIC;++ /* FIXME there should be a sharable lock protecting us against+ * config/altsetting changes and disconnects, kicking in here.+ */++ /* Sanity check, so HCDs can rely on clean data */+ max = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe));+ if (max <= 0) {+ err ("bogus endpoint (bad maxpacket)");+ return -EINVAL;+ }++ /* "high bandwidth" mode, 1-3 packets/uframe? */+ if (urb->dev->speed == USB_SPEED_HIGH) {+ int mult;+ switch (temp) {+ case PIPE_ISOCHRONOUS:+ case PIPE_INTERRUPT:+ mult = 1 + ((max >> 11) & 0x03);+ max &= 0x03ff;+ max *= mult;+ }+ }++ /* periodic transfers limit size per frame/uframe */+ switch (temp) {+ case PIPE_ISOCHRONOUS: {+ int n, len;++ if (urb->number_of_packets <= 0) + return -EINVAL;+ for (n = 0; n < urb->number_of_packets; n++) {+ len = urb->iso_frame_desc [n].length;+ if (len < 0 || len > max) + return -EINVAL;+ }++ }+ break;+ case PIPE_INTERRUPT:+ if (urb->transfer_buffer_length > max)+ return -EINVAL;+ }++ /* the I/O buffer must usually be mapped/unmapped */+ if (urb->transfer_buffer_length < 0)+ return -EINVAL;++ if (urb->next) {+ warn ("use explicit queuing not urb->next");+ return -EINVAL;+ }++#ifdef DEBUG+ /* stuff that drivers shouldn't do, but which shouldn't+ * cause problems in HCDs if they get it wrong.+ */+ {+ unsigned int orig_flags = urb->transfer_flags;+ unsigned int allowed;++ /* enforce simple/standard policy */+ allowed = USB_ASYNC_UNLINK; // affects later unlinks+ allowed |= USB_NO_FSBR; // only affects UHCI+ switch (temp) {+ case PIPE_CONTROL:+ allowed |= USB_DISABLE_SPD;+ break;+ case PIPE_BULK:+ allowed |= USB_DISABLE_SPD | USB_QUEUE_BULK+ | USB_ZERO_PACKET | URB_NO_INTERRUPT;+ break;+ case PIPE_INTERRUPT:+ allowed |= USB_DISABLE_SPD;+ break;+ case PIPE_ISOCHRONOUS:+ allowed |= USB_ISO_ASAP;+ break;+ }+ urb->transfer_flags &= allowed;++ /* fail if submitter gave bogus flags */+ if (urb->transfer_flags != orig_flags) {+ err ("BOGUS urb flags, %x --> %x",+ orig_flags, urb->transfer_flags);+ return -EINVAL;+ }+ }+#endif+ /*+ * Force periodic transfer intervals to be legal values that are+ * a power of two (so HCDs don't need to).+ *+ * FIXME want bus->{intr,iso}_sched_horizon values here. Each HC+ * supports different values... this uses EHCI/UHCI defaults (and+ * EHCI can use smaller non-default values).+ */+ switch (temp) {+ case PIPE_ISOCHRONOUS:+ case PIPE_INTERRUPT:+ /* too small? */+ if (urb->interval <= 0)+ return -EINVAL;+ /* too big? */+ switch (urb->dev->speed) {+ case USB_SPEED_HIGH: /* units are microframes */+ // NOTE usb handles 2^15+ if (urb->interval > (1024 * 8))+ urb->interval = 1024 * 8;+ temp = 1024 * 8;+ break;+ case USB_SPEED_FULL: /* units are frames/msec */+ case USB_SPEED_LOW:+ if (temp == PIPE_INTERRUPT) {+ if (urb->interval > 255)+ return -EINVAL;+ // NOTE ohci only handles up to 32+ temp = 128;+ } else {+ if (urb->interval > 1024)+ urb->interval = 1024;+ // NOTE usb and ohci handle up to 2^15+ temp = 1024;+ }+ break;+ default:+ return -EINVAL;+ }+ /* power of two? */+ while (temp > urb->interval)+ temp >>= 1;+ urb->interval = temp;+ }+++ /*+ * FIXME: make urb timeouts be generic, keeping the HCD cores+ * as simple as possible.+ */++ // NOTE: a generic device/urb monitoring hook would go here.+ // hcd_monitor_hook(MONITOR_URB_SUBMIT, urb)+ // It would catch submission paths for all urbs.++ /*+ * Atomically queue the urb, first to our records, then to the HCD.+ * Access to urb->status is controlled by urb->lock ... changes on+ * i/o completion (normal or fault) or unlinking.+ */++ // FIXME: verify that quiescing hc works right (RH cleans up)++ spin_lock_irqsave (&hcd_data_lock, flags);+ if (HCD_IS_RUNNING (hcd->state) && hcd->state != USB_STATE_QUIESCING) {+ usb_inc_dev_use (urb->dev);+ list_add (&urb->urb_list, &dev->urb_list);+ status = 0;+ } else {+ INIT_LIST_HEAD (&urb->urb_list);+ status = -ESHUTDOWN;+ }+ spin_unlock_irqrestore (&hcd_data_lock, flags);+ if (status)+ return status;++ // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag+ + /* For 2.4, don't map bounce buffer if it's a root hub operation. */+ if (urb->dev == hcd->bus->root_hub) {+ status = rh_urb_enqueue (hcd, urb);+ } else {+ if (usb_pipecontrol (urb->pipe)){+ + urb->setup_dma = tango2_map_single (+ /*hcd->pdev,*/+ urb->setup_packet,+ sizeof (struct usb_ctrlrequest),+ PCI_DMA_TODEVICE);+ }+ if (urb->transfer_buffer_length != 0){++ urb->transfer_dma = tango2_map_single (+ /*hcd->pdev,*/+ urb->transfer_buffer,+ urb->transfer_buffer_length,+ usb_pipein (urb->pipe)+ ? PCI_DMA_FROMDEVICE+ : PCI_DMA_TODEVICE);+ } status = hcd->driver->urb_enqueue (hcd, urb, mem_flags); } return status;@@ -1228,7 +1466,7 @@ /*-------------------------------------------------------------------------*/ /* called in any context */-static int hcd_get_frame_number (struct usb_device *udev)+int hcd_get_frame_number (struct usb_device *udev) { struct usb_hcd *hcd = (struct usb_hcd *)udev->bus->hcpriv; return hcd->driver->get_frame_number (hcd);@@ -1266,7 +1504,7 @@ * caller guarantees urb won't be recycled till both unlink() * and the urb's completion function return */-static int hcd_unlink_urb (struct urb *urb)+int hcd_unlink_urb (struct urb *urb) { struct hcd_dev *dev; struct usb_hcd *hcd = 0;@@ -1389,7 +1627,7 @@ // setup primitives in the usbcore-to-hcd driver API, so nothing // is implicit. kernel 2.5 needs a bunch of config cleanup... -static int hcd_free_dev (struct usb_device *udev)+int hcd_free_dev (struct usb_device *udev) { struct hcd_dev *dev; struct usb_hcd *hcd;@@ -1423,7 +1661,7 @@ kfree (dev); return 0; }-+#ifdef CONFIG_PCI static struct usb_operations hcd_operations = { allocate: hcd_alloc_dev, get_frame_number: hcd_get_frame_number,@@ -1431,10 +1669,10 @@ unlink_urb: hcd_unlink_urb, deallocate: hcd_free_dev, };-+#endif /*-------------------------------------------------------------------------*/ -static void hcd_irq (int irq, void *__hcd, struct pt_regs * r)+void hcd_irq (int irq, void *__hcd, struct pt_regs * r) { struct usb_hcd *hcd = __hcd; int start = hcd->state;@@ -1447,6 +1685,7 @@ hc_died (hcd); } + /*-------------------------------------------------------------------------*/ /**@@ -1489,19 +1728,28 @@ // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag /* For 2.4, don't unmap bounce buffer if it's a root hub operation. */- if (usb_pipecontrol (urb->pipe) && !is_root_hub_operation)- pci_unmap_single (hcd->pdev, urb->setup_dma,+ if (usb_pipecontrol (urb->pipe) && !is_root_hub_operation){+ tango2_unmap_single (/*hcd->pdev,*/ urb->setup_dma, sizeof (struct usb_ctrlrequest), PCI_DMA_TODEVICE);+ } - if ((urb->transfer_buffer_length != 0) && !is_root_hub_operation)- pci_unmap_single (hcd->pdev, urb->transfer_dma,+ if ((urb->transfer_buffer_length != 0) && !is_root_hub_operation){+ tango2_unmap_single (/*hcd->pdev, */urb->transfer_dma, urb->transfer_buffer_length, usb_pipein (urb->pipe) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -