staging: octeon-usb: use list_for_each_entry_safe()
[deliverable/linux.git] / drivers / staging / octeon-usb / octeon-hcd.c
index 1859c050b9184c461bf8db5ea7e3104d739a6cf0..8e0fcbd173f219ced4bbf0390e131cdc691a0173 100644 (file)
@@ -66,8 +66,7 @@
 #include <asm/octeon/cvmx-sysinfo.h>
 #include <asm/octeon/cvmx-helper-board.h>
 
-#include "cvmx-usbcx-defs.h"
-#include "cvmx-usbnx-defs.h"
+#include "octeon-hcd.h"
 
 /**
  * enum cvmx_usb_speed - the possible USB device speeds
@@ -235,8 +234,6 @@ enum cvmx_usb_initialize_flags {
 /**
  * enum cvmx_usb_pipe_flags - internal flags for a pipe.
  *
- * @__CVMX_USB_PIPE_FLAGS_OPEN:             Used internally to determine if a pipe is
- *                                  open. Do not use.
  * @__CVMX_USB_PIPE_FLAGS_SCHEDULED: Used internally to determine if a pipe is
  *                                  actively using hardware. Do not use.
  * @__CVMX_USB_PIPE_FLAGS_NEED_PING: Used internally to determine if a high
@@ -244,7 +241,6 @@ enum cvmx_usb_initialize_flags {
  *                                  use.
  */
 enum cvmx_usb_pipe_flags {
-       __CVMX_USB_PIPE_FLAGS_OPEN      = 1 << 16,
        __CVMX_USB_PIPE_FLAGS_SCHEDULED = 1 << 17,
        __CVMX_USB_PIPE_FLAGS_NEED_PING = 1 << 18,
 };
@@ -255,12 +251,6 @@ enum cvmx_usb_pipe_flags {
 /* Maximum number of times to retry failed transactions */
 #define MAX_RETRIES            3
 
-/* Maximum number of pipes that can be open at once */
-#define MAX_PIPES              32
-
-/* Maximum number of outstanding transactions across all pipes */
-#define MAX_TRANSACTIONS       256
-
 /* Maximum number of hardware channels supported by the USB block */
 #define MAX_CHANNELS           8
 
@@ -285,10 +275,6 @@ enum cvmx_usb_pipe_flags {
  */
 #define MAX_TRANSFER_PACKETS   ((1<<10)-1)
 
-enum cvmx_usb_transaction_flags {
-       __CVMX_USB_TRANSACTION_FLAGS_IN_USE = 1<<16,
-};
-
 enum {
        USB_CLOCK_TYPE_REF_12,
        USB_CLOCK_TYPE_REF_24,
@@ -340,7 +326,6 @@ struct cvmx_usb_transaction {
        struct cvmx_usb_transaction *prev;
        struct cvmx_usb_transaction *next;
        enum cvmx_usb_transfer type;
-       enum cvmx_usb_transaction_flags flags;
        uint64_t buffer;
        int buffer_length;
        uint64_t control_header;
@@ -435,13 +420,9 @@ struct cvmx_usb_tx_fifo {
  * usbcx_hprt:            Stored port status so we don't need to read a CSR to
  *                        determine splits.
  * pipe_for_channel:      Map channels to pipes.
- * free_transaction_head:  List of free transactions head.
- * free_transaction_tail:  List of free transactions tail.
  * pipe:                  Storage for pipes.
- * transaction:                   Storage for transactions.
  * indent:                Used by debug output to indent functions.
  * port_status:                   Last port status used for change notification.
- * free_pipes:            List of all pipes that are currently closed.
  * idle_pipes:            List of open pipes that have no transactions.
  * active_pipes:          Active pipes indexed by transfer type.
  * frame_number:          Increments every SOF interrupt for time keeping.
@@ -453,13 +434,8 @@ struct cvmx_usb_state {
        int idle_hardware_channels;
        union cvmx_usbcx_hprt usbcx_hprt;
        struct cvmx_usb_pipe *pipe_for_channel[MAX_CHANNELS];
-       struct cvmx_usb_transaction *free_transaction_head;
-       struct cvmx_usb_transaction *free_transaction_tail;
-       struct cvmx_usb_pipe pipe[MAX_PIPES];
-       struct cvmx_usb_transaction transaction[MAX_TRANSACTIONS];
        int indent;
        struct cvmx_usb_port_status port_status;
-       struct cvmx_usb_pipe_list free_pipes;
        struct cvmx_usb_pipe_list idle_pipes;
        struct cvmx_usb_pipe_list active_pipes[4];
        uint64_t frame_number;
@@ -653,54 +629,6 @@ static int cvmx_usb_get_num_ports(void)
        return arch_ports;
 }
 
-
-/**
- * Allocate a usb transaction for use
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- *
- * Returns: Transaction or NULL
- */
-static inline struct cvmx_usb_transaction *__cvmx_usb_alloc_transaction(struct cvmx_usb_state *usb)
-{
-       struct cvmx_usb_transaction *t;
-       t = usb->free_transaction_head;
-       if (t) {
-               usb->free_transaction_head = t->next;
-               if (!usb->free_transaction_head)
-                       usb->free_transaction_tail = NULL;
-       }
-       if (t) {
-               memset(t, 0, sizeof(*t));
-               t->flags = __CVMX_USB_TRANSACTION_FLAGS_IN_USE;
-       }
-       return t;
-}
-
-
-/**
- * Free a usb transaction
- *
- * @usb:        USB device state populated by
- *              cvmx_usb_initialize().
- * @transaction:
- *              Transaction to free
- */
-static inline void __cvmx_usb_free_transaction(struct cvmx_usb_state *usb,
-                                              struct cvmx_usb_transaction *transaction)
-{
-       transaction->flags = 0;
-       transaction->prev = NULL;
-       transaction->next = NULL;
-       if (usb->free_transaction_tail)
-               usb->free_transaction_tail->next = transaction;
-       else
-               usb->free_transaction_head = transaction;
-       usb->free_transaction_tail = transaction;
-}
-
-
 /**
  * Add a pipe to the tail of a list
  * @list:   List to add pipe to
@@ -799,18 +727,7 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
        usb->init_flags = flags;
 
        /* Initialize the USB state structure */
-       {
-               int i;
-               usb->index = usb_port_number;
-
-               /* Initialize the transaction double linked list */
-               usb->free_transaction_head = NULL;
-               usb->free_transaction_tail = NULL;
-               for (i = 0; i < MAX_TRANSACTIONS; i++)
-                       __cvmx_usb_free_transaction(usb, usb->transaction + i);
-               for (i = 0; i < MAX_PIPES; i++)
-                       __cvmx_usb_append_pipe(&usb->free_pipes, usb->pipe + i);
-       }
+       usb->index = usb_port_number;
 
        /*
         * Power On Reset and PHY Initialization
@@ -836,16 +753,14 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
                 * source at USB_XO. USB_XI should be tied to GND.
                 * Most Octeon evaluation boards require this setting
                 */
-               if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
-                       /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1;
-                       usbn_clk_ctl.cn31xx.p_xenbn = 0;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       /* From CN56XX,CN50XX manual */
-                       usbn_clk_ctl.cn56xx.p_rtype = 2;
+               if (OCTEON_IS_MODEL(OCTEON_CN3XXX) ||
+                   OCTEON_IS_MODEL(OCTEON_CN56XX) ||
+                   OCTEON_IS_MODEL(OCTEON_CN50XX))
+                       /* From CN56XX,CN50XX,CN31XX,CN30XX manuals */
+                       usbn_clk_ctl.s.p_rtype = 2; /* p_rclk=1 & p_xenbn=0 */
                else
                        /* From CN52XX manual */
-                       usbn_clk_ctl.cn52xx.p_rtype = 1;
+                       usbn_clk_ctl.s.p_rtype = 1;
 
                switch (flags & CVMX_USB_INITIALIZE_FLAGS_CLOCK_MHZ_MASK) {
                case CVMX_USB_INITIALIZE_FLAGS_CLOCK_12MHZ:
@@ -863,16 +778,12 @@ static int cvmx_usb_initialize(struct cvmx_usb_state *usb,
                 * The USB port uses a 12MHz crystal as clock source
                 * at USB_XO and USB_XI
                 */
-               if (OCTEON_IS_MODEL(OCTEON_CN3XXX)) {
+               if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
                        /* From CN31XX,CN30XX manual */
-                       usbn_clk_ctl.cn31xx.p_rclk  = 1;
-                       usbn_clk_ctl.cn31xx.p_xenbn = 1;
-               } else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN50XX))
-                       /* From CN56XX,CN50XX manual */
-                       usbn_clk_ctl.cn56xx.p_rtype = 0;
+                       usbn_clk_ctl.s.p_rtype = 3; /* p_rclk=1 & p_xenbn=1 */
                else
-                       /* From CN52XX manual */
-                       usbn_clk_ctl.cn52xx.p_rtype = 0;
+                       /* From CN56XX,CN52XX,CN50XX manuals. */
+                       usbn_clk_ctl.s.p_rtype = 0;
 
                usbn_clk_ctl.s.p_c_sel = 0;
        }
@@ -1347,12 +1258,9 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
        if (unlikely((hub_port < 0) || (hub_port > MAX_USB_HUB_PORT)))
                return NULL;
 
-       /* Find a free pipe */
-       pipe = usb->free_pipes.head;
+       pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC);
        if (!pipe)
                return NULL;
-       __cvmx_usb_remove_pipe(&usb->free_pipes, pipe);
-       pipe->flags = __CVMX_USB_PIPE_FLAGS_OPEN;
        if ((device_speed == CVMX_USB_SPEED_HIGH) &&
                (transfer_dir == CVMX_USB_DIRECTION_OUT) &&
                (transfer_type == CVMX_USB_TRANSFER_BULK))
@@ -2128,17 +2036,14 @@ static void octeon_usb_urb_complete_callback(struct cvmx_usb_state *usb,
        urb->actual_length = bytes_transferred;
        urb->hcpriv = NULL;
 
-       if (!list_empty(&urb->urb_list)) {
+       if (!list_empty(&urb->urb_list))
                /*
                 * It is on the dequeue_list, but we are going to call
                 * usb_hcd_giveback_urb(), so we must clear it from
                 * the list.  We got to it before the
                 * octeon_usb_urb_dequeue_work() tasklet did.
                 */
-               list_del(&urb->urb_list);
-               /* No longer on the dequeue_list. */
-               INIT_LIST_HEAD(&urb->urb_list);
-       }
+               list_del_init(&urb->urb_list);
 
        /* For Isochronous transactions we need to update the URB packet status
           list from data in our private copy */
@@ -2270,7 +2175,7 @@ static void __cvmx_usb_perform_complete(struct cvmx_usb_state *usb,
                                         transaction,
                                         transaction->actual_bytes,
                                         transaction->urb);
-       __cvmx_usb_free_transaction(usb, transaction);
+       kfree(transaction);
 done:
        return;
 }
@@ -2311,13 +2216,10 @@ static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(struct cvmx_us
 {
        struct cvmx_usb_transaction *transaction;
 
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return NULL;
        if (unlikely(pipe->transfer_type != type))
                return NULL;
 
-       transaction = __cvmx_usb_alloc_transaction(usb);
+       transaction = kzalloc(sizeof(*transaction), GFP_ATOMIC);
        if (unlikely(!transaction))
                return NULL;
 
@@ -2483,14 +2385,6 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
                           struct cvmx_usb_pipe *pipe,
                           struct cvmx_usb_transaction *transaction)
 {
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
-       /* Fail if this transaction already completed */
-       if (unlikely((transaction->flags & __CVMX_USB_TRANSACTION_FLAGS_IN_USE) == 0))
-               return -EINVAL;
-
        /*
         * If the transaction is the HEAD of the queue and scheduled. We need to
         * treat it special
@@ -2531,10 +2425,6 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
 static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb,
                               struct cvmx_usb_pipe *pipe)
 {
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
        /* Simply loop through and attempt to cancel each transaction */
        while (pipe->head) {
                int result = cvmx_usb_cancel(usb, pipe, pipe->head);
@@ -2557,17 +2447,12 @@ static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb,
 static int cvmx_usb_close_pipe(struct cvmx_usb_state *usb,
                               struct cvmx_usb_pipe *pipe)
 {
-       /* Fail if the pipe isn't open */
-       if (unlikely((pipe->flags & __CVMX_USB_PIPE_FLAGS_OPEN) == 0))
-               return -EINVAL;
-
        /* Fail if the pipe has pending transactions */
        if (unlikely(pipe->head))
                return -EBUSY;
 
-       pipe->flags = 0;
        __cvmx_usb_remove_pipe(&usb->idle_pipes, pipe);
-       __cvmx_usb_append_pipe(&usb->free_pipes, pipe);
+       kfree(pipe);
 
        return 0;
 }
@@ -3338,16 +3223,15 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd,
 
 static void octeon_usb_urb_dequeue_work(unsigned long arg)
 {
+       struct urb *urb;
+       struct urb *next;
        unsigned long flags;
        struct octeon_hcd *priv = (struct octeon_hcd *)arg;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       while (!list_empty(&priv->dequeue_list)) {
-               struct urb *urb = container_of(priv->dequeue_list.next, struct urb, urb_list);
-               list_del(&urb->urb_list);
-               /* not enqueued on dequeue_list */
-               INIT_LIST_HEAD(&urb->urb_list);
+       list_for_each_entry_safe(urb, next, &priv->dequeue_list, urb_list) {
+               list_del_init(&urb->urb_list);
                cvmx_usb_cancel(&priv->usb, urb->ep->hcpriv, urb->hcpriv);
        }
 
This page took 0.030262 seconds and 5 git commands to generate.