ChangeSet 1.971, 2003/01/27 23:12:19+11:00, [EMAIL PROTECTED]

[PATCH] USB: usbcore misc cleanup (notably for non-dma hcds)

The support for non-dma HCDs is likely the most interesting bit here.

    - makes dma calls behave sensibly when used with host controllers
      that don't use dma (including sl811).  usb_buffer_map() is a nop
      while scatterlist dma mappings fail (as they must).

    - make usb_sg_init() behave sensibly when used with non-dma hcs.
      the urbs are initted with transfer_buffer, not transfer_dma.
      this is the higher level analogue to usb_buffer_map(), so it
      needs to succeed unless there's a Real Error (tm).

    - moves two compatibility inlines from ehci.h into hcd.h so
      it'll be more practical to have the other hcds work in other
      environments (notably lk 2.4) too

    - remove URB_TIMEOUT_KILLED flag ... no device driver tests it;
      hcds don't really (uhci sets it, never reads it; sl811 doesn't
      enable the path that might set it), and it's not well defined.
      if any hcd needs such state, keep it in hc-private storage.

    - in usb_sg_wait(), use yield() instead of schedule() to let
      other activities free resources needed to continue.  (This
      was noted recently by Oliver.)


diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c    Tue Feb  4 15:17:46 2003
+++ b/drivers/usb/core/hcd.c    Tue Feb  4 15:17:46 2003
@@ -1029,8 +1029,11 @@
                return status;
        }
 
-       /* lower level hcd code should use *_dma exclusively */
-       if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
+       /* lower level hcd code should use *_dma exclusively,
+        * unless it uses pio or talks to another transport.
+        */
+       if (!(urb->transfer_flags & URB_NO_DMA_MAP)
+                       && hcd->controller->dma_mask) {
                if (usb_pipecontrol (urb->pipe))
                        urb->setup_dma = dma_map_single (
                                        hcd->controller,
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h    Tue Feb  4 15:17:45 2003
+++ b/drivers/usb/core/hcd.h    Tue Feb  4 15:17:45 2003
@@ -111,6 +111,13 @@
         */
 };
 
+/* 2.4 does this a bit differently ... */
+static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
+{
+       return &hcd->self;
+}
+
+
 struct hcd_dev {       /* usb_device.hcpriv points to this */
        struct list_head        dev_list;       /* on this hcd */
        struct list_head        urb_list;       /* pending on this dev */
@@ -342,6 +349,13 @@
 
 extern int usb_register_root_hub (struct usb_device *usb_dev,
                struct device *parent_dev);
+
+/* for portability to 2.4, hcds should call this */
+static inline int hcd_register_root (struct usb_hcd *hcd)
+{
+       return usb_register_root_hub (
+               hcd_to_bus (hcd)->root_hub, hcd->controller);
+}
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c        Tue Feb  4 15:17:45 2003
+++ b/drivers/usb/core/message.c        Tue Feb  4 15:17:45 2003
@@ -206,7 +206,8 @@
                kfree (io->urbs);
                io->urbs = 0;
        }
-       usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
+       if (io->dev->dev.dma_mask != 0)
+               usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents);
        io->dev = 0;
 }
 
@@ -301,6 +302,7 @@
 {
        int                     i;
        int                     urb_flags;
+       int                     dma;
 
        if (!io || !dev || !sg
                        || usb_pipecontrol (pipe)
@@ -314,8 +316,16 @@
        io->sg = sg;
        io->nents = nents;
 
+       /* not all host controllers use DMA (like the mainstream pci ones);
+        * they can use PIO (sl811) or be software over another transport.
+        */
+       dma = (dev->dev.dma_mask == 0);
+       if (dma)
+               io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
+       else
+               io->entries = nents;
+
        /* initialize all the urbs we'll use */
-       io->entries = usb_buffer_map_sg (dev, pipe, sg, nents);
        if (io->entries <= 0)
                return io->entries;
 
@@ -347,8 +357,17 @@
                io->urbs [i]->status = -EINPROGRESS;
                io->urbs [i]->actual_length = 0;
 
-               io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
-               len = sg_dma_len (sg + i);
+               if (dma) {
+                       /* hc may use _only_ transfer_dma */
+                       io->urbs [i]->transfer_dma = sg_dma_address (sg + i);
+                       len = sg_dma_len (sg + i);
+               } else {
+                       /* hc may use _only_ transfer_buffer */
+                       io->urbs [i]->transfer_buffer =
+                               page_address (sg [i].page) + sg [i].offset;
+                       len = sg [i].length;
+               }
+
                if (length) {
                        len = min_t (unsigned, len, length);
                        length -= len;
@@ -434,9 +453,7 @@
                        retval = 0;
                        i--;
                        // FIXME:  should it usb_sg_cancel() on INTERRUPT?
-                       // how about imposing a backoff?
-                       set_current_state (TASK_UNINTERRUPTIBLE);
-                       schedule ();
+                       yield ();
                        break;
 
                        /* no error? continue immediately.
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c    Tue Feb  4 15:17:45 2003
+++ b/drivers/usb/core/usb.c    Tue Feb  4 15:17:45 2003
@@ -1224,7 +1224,8 @@
  *
  * Return value is either null (indicating no buffer could be mapped), or
  * the parameter.  URB_NO_DMA_MAP is added to urb->transfer_flags if the
- * operation succeeds.
+ * operation succeeds.  If the device is connected to this system through
+ * a non-DMA controller, this operation always succeeds.
  *
  * This call would normally be used for an urb which is reused, perhaps
  * as the target of a large periodic transfer, with usb_buffer_dmasync()
@@ -1245,12 +1246,15 @@
                        || !(controller = bus->controller))
                return 0;
 
-       urb->transfer_dma = dma_map_single (controller,
+       if (controller->dma_mask) {
+               urb->transfer_dma = dma_map_single (controller,
                        urb->transfer_buffer, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
        // FIXME generic api broken like pci, can't report errors
        // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
+       } else
+               urb->transfer_dma = ~0;
        urb->transfer_flags |= URB_NO_DMA_MAP;
        return urb;
 }
@@ -1271,7 +1275,8 @@
                        || !(controller = bus->controller))
                return;
 
-       dma_sync_single (controller,
+       if (controller->dma_mask)
+               dma_sync_single (controller,
                        urb->transfer_dma, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
@@ -1295,10 +1300,12 @@
                        || !(controller = bus->controller))
                return;
 
-       dma_unmap_single (controller,
+       if (controller->dma_mask)
+               dma_unmap_single (controller,
                        urb->transfer_dma, urb->transfer_buffer_length,
                        usb_pipein (urb->pipe)
                                ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+       urb->transfer_flags &= ~URB_NO_DMA_MAP;
 }
 
 /**
@@ -1336,7 +1343,8 @@
        if (!dev
                        || usb_pipecontrol (pipe)
                        || !(bus = dev->bus)
-                       || !(controller = bus->controller))
+                       || !(controller = bus->controller)
+                       || !controller->dma_mask)
                return -1;
 
        // FIXME generic api broken like pci, can't report errors
@@ -1362,7 +1370,8 @@
 
        if (!dev
                        || !(bus = dev->bus)
-                       || !(controller = bus->controller))
+                       || !(controller = bus->controller)
+                       || !controller->dma_mask)
                return;
 
        dma_sync_sg (controller, sg, n_hw_ents,
@@ -1386,7 +1395,8 @@
 
        if (!dev
                        || !(bus = dev->bus)
-                       || !(controller = bus->controller))
+                       || !(controller = bus->controller)
+                       || !controller->dma_mask)
                return;
 
        dma_unmap_sg (controller, sg, n_hw_ents,
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h   Tue Feb  4 15:17:46 2003
+++ b/drivers/usb/host/ehci.h   Tue Feb  4 15:17:46 2003
@@ -426,16 +426,6 @@
 
 #else  /* LINUX_VERSION_CODE */
 
-// hcd_to_bus() eventually moves to hcd.h on 2.5 too
-static inline struct usb_bus *hcd_to_bus (struct usb_hcd *hcd)
-       { return &hcd->self; }
-// ... as does hcd_register_root()
-static inline int hcd_register_root (struct usb_hcd *hcd)
-{
-       return usb_register_root_hub (
-               hcd_to_bus (hcd)->root_hub, &hcd->pdev->dev);
-}
-
 #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
 
 #ifndef DEBUG
diff -Nru a/drivers/usb/host/hc_simple.c b/drivers/usb/host/hc_simple.c
--- a/drivers/usb/host/hc_simple.c      Tue Feb  4 15:17:46 2003
+++ b/drivers/usb/host/hc_simple.c      Tue Feb  4 15:17:46 2003
@@ -219,7 +219,7 @@
        if (!list_empty (&urb->urb_list) && urb->status == -EINPROGRESS) {
                /* URB active? */
 
-               if (urb->transfer_flags & (URB_ASYNC_UNLINK | URB_TIMEOUT_KILLED)) {
+               if (urb->transfer_flags & URB_ASYNC_UNLINK) {
                        /* asynchronous with callback */
                        /* relink the urb to the del list */
                        list_move (&urb->urb_list, &hci->del_list);
@@ -388,7 +388,6 @@
        struct urb *urb = (struct urb *) lurb;
 
        DBGFUNC ("enter qu_urb_timeout\n");
-       urb->transfer_flags |= URB_TIMEOUT_KILLED;
        hci_unlink_urb (urb);
 }
 #endif
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c       Tue Feb  4 15:17:46 2003
+++ b/drivers/usb/host/uhci-hcd.c       Tue Feb  4 15:17:46 2003
@@ -1747,7 +1747,6 @@
 
                tmp = tmp->next;
 
-               u->transfer_flags |= URB_TIMEOUT_KILLED;
                uhci_urb_dequeue(hcd, u);
        }
 
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h       Tue Feb  4 15:17:45 2003
+++ b/include/linux/usb.h       Tue Feb  4 15:17:45 2003
@@ -554,7 +554,6 @@
 #define URB_NO_FSBR            0x0020  /* UHCI-specific */
 #define URB_ZERO_PACKET                0x0040  /* Finish bulk OUTs with short packet 
*/
 #define URB_NO_INTERRUPT       0x0080  /* HINT: no non-error interrupt needed */
-#define URB_TIMEOUT_KILLED     0x1000  /* only set by HCD! */
 
 struct usb_iso_packet_descriptor {
        unsigned int offset;



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to