Commit 5669601d authored by Aaro Koskinen's avatar Aaro Koskinen Committed by Greg Kroah-Hartman

staging: octeon-usb: use list.h for transactions

Use list.h helpers for transactions.
Signed-off-by: default avatarAaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4a23ee1b
...@@ -306,8 +306,7 @@ enum cvmx_usb_stage { ...@@ -306,8 +306,7 @@ enum cvmx_usb_stage {
* regardless of type. These are linked together * regardless of type. These are linked together
* to form a list of pending requests for a pipe. * to form a list of pending requests for a pipe.
* *
* @prev: Transaction before this one in the pipe. * @node: List node for transactions in the pipe.
* @next: Transaction after this one in the pipe.
* @type: Type of transaction, duplicated of the pipe. * @type: Type of transaction, duplicated of the pipe.
* @flags: State flags for this transaction. * @flags: State flags for this transaction.
* @buffer: User's physical buffer address to read/write. * @buffer: User's physical buffer address to read/write.
...@@ -323,8 +322,7 @@ enum cvmx_usb_stage { ...@@ -323,8 +322,7 @@ enum cvmx_usb_stage {
* @urb: URB. * @urb: URB.
*/ */
struct cvmx_usb_transaction { struct cvmx_usb_transaction {
struct cvmx_usb_transaction *prev; struct list_head node;
struct cvmx_usb_transaction *next;
enum cvmx_usb_transfer type; enum cvmx_usb_transfer type;
uint64_t buffer; uint64_t buffer;
int buffer_length; int buffer_length;
...@@ -347,8 +345,7 @@ struct cvmx_usb_transaction { ...@@ -347,8 +345,7 @@ struct cvmx_usb_transaction {
* *
* @node: List node for pipe list * @node: List node for pipe list
* @next: Pipe after this one in the list * @next: Pipe after this one in the list
* @head: The first pending transaction * @transactions: List of pending transactions
* @tail: The last pending transaction
* @interval: For periodic pipes, the interval between packets in * @interval: For periodic pipes, the interval between packets in
* frames * frames
* @next_tx_frame: The next frame this pipe is allowed to transmit on * @next_tx_frame: The next frame this pipe is allowed to transmit on
...@@ -370,8 +367,7 @@ struct cvmx_usb_transaction { ...@@ -370,8 +367,7 @@ struct cvmx_usb_transaction {
*/ */
struct cvmx_usb_pipe { struct cvmx_usb_pipe {
struct list_head node; struct list_head node;
struct cvmx_usb_transaction *head; struct list_head transactions;
struct cvmx_usb_transaction *tail;
uint64_t interval; uint64_t interval;
uint64_t next_tx_frame; uint64_t next_tx_frame;
enum cvmx_usb_pipe_flags flags; enum cvmx_usb_pipe_flags flags;
...@@ -1219,6 +1215,8 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb, ...@@ -1219,6 +1215,8 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct cvmx_usb_state *usb,
pipe->max_packet = max_packet; pipe->max_packet = max_packet;
pipe->transfer_type = transfer_type; pipe->transfer_type = transfer_type;
pipe->transfer_dir = transfer_dir; pipe->transfer_dir = transfer_dir;
INIT_LIST_HEAD(&pipe->transactions);
/* /*
* All pipes use interval to rate limit NAK processing. Force an * All pipes use interval to rate limit NAK processing. Force an
* interval if one wasn't supplied * interval if one wasn't supplied
...@@ -1444,7 +1442,9 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb, ...@@ -1444,7 +1442,9 @@ static void __cvmx_usb_start_channel_control(struct cvmx_usb_state *usb,
int channel, int channel,
struct cvmx_usb_pipe *pipe) struct cvmx_usb_pipe *pipe)
{ {
struct cvmx_usb_transaction *transaction = pipe->head; struct cvmx_usb_transaction *transaction =
list_first_entry(&pipe->transactions, typeof(*transaction),
node);
union cvmx_usb_control_header *header = union cvmx_usb_control_header *header =
cvmx_phys_to_ptr(transaction->control_header); cvmx_phys_to_ptr(transaction->control_header);
int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes; int bytes_to_transfer = transaction->buffer_length - transaction->actual_bytes;
...@@ -1573,7 +1573,9 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb, ...@@ -1573,7 +1573,9 @@ static void __cvmx_usb_start_channel(struct cvmx_usb_state *usb,
int channel, int channel,
struct cvmx_usb_pipe *pipe) struct cvmx_usb_pipe *pipe)
{ {
struct cvmx_usb_transaction *transaction = pipe->head; struct cvmx_usb_transaction *transaction =
list_first_entry(&pipe->transactions, typeof(*transaction),
node);
/* Make sure all writes to the DMA region get flushed */ /* Make sure all writes to the DMA region get flushed */
CVMX_SYNCW; CVMX_SYNCW;
...@@ -1872,12 +1874,14 @@ static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_state *u ...@@ -1872,12 +1874,14 @@ static struct cvmx_usb_pipe *__cvmx_usb_find_ready_pipe(struct cvmx_usb_state *u
struct cvmx_usb_pipe *pipe; struct cvmx_usb_pipe *pipe;
list_for_each_entry(pipe, list, node) { list_for_each_entry(pipe, list, node) {
if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && pipe->head && struct cvmx_usb_transaction *t =
list_first_entry(&pipe->transactions, typeof(*t), node);
if (!(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED) && t &&
(pipe->next_tx_frame <= current_frame) && (pipe->next_tx_frame <= current_frame) &&
((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) && ((pipe->split_sc_frame == -1) || ((((int)current_frame - (int)pipe->split_sc_frame) & 0x7f) < 0x40)) &&
(!usb->active_split || (usb->active_split == pipe->head))) { (!usb->active_split || (usb->active_split == t))) {
CVMX_PREFETCH(pipe, 128); CVMX_PREFETCH(pipe, 128);
CVMX_PREFETCH(pipe->head, 0); CVMX_PREFETCH(t, 0);
return pipe; return pipe;
} }
} }
...@@ -2104,15 +2108,8 @@ static void __cvmx_usb_perform_complete(struct cvmx_usb_state *usb, ...@@ -2104,15 +2108,8 @@ static void __cvmx_usb_perform_complete(struct cvmx_usb_state *usb,
} }
/* Remove the transaction from the pipe list */ /* Remove the transaction from the pipe list */
if (transaction->next) list_del(&transaction->node);
transaction->next->prev = transaction->prev; if (list_empty(&pipe->transactions))
else
pipe->tail = transaction->prev;
if (transaction->prev)
transaction->prev->next = transaction->next;
else
pipe->head = transaction->next;
if (!pipe->head)
list_move_tail(&pipe->node, &usb->idle_pipes); list_move_tail(&pipe->node, &usb->idle_pipes);
octeon_usb_urb_complete_callback(usb, complete_code, pipe, octeon_usb_urb_complete_callback(usb, complete_code, pipe,
transaction, transaction,
...@@ -2180,24 +2177,19 @@ static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(struct cvmx_us ...@@ -2180,24 +2177,19 @@ static struct cvmx_usb_transaction *__cvmx_usb_submit_transaction(struct cvmx_us
else else
transaction->stage = CVMX_USB_STAGE_NON_CONTROL; transaction->stage = CVMX_USB_STAGE_NON_CONTROL;
transaction->next = NULL; if (!list_empty(&pipe->transactions)) {
if (pipe->tail) { list_add_tail(&transaction->node, &pipe->transactions);
transaction->prev = pipe->tail;
transaction->prev->next = transaction;
} else { } else {
if (pipe->next_tx_frame < usb->frame_number) list_add_tail(&transaction->node, &pipe->transactions);
pipe->next_tx_frame = usb->frame_number + pipe->interval -
(usb->frame_number - pipe->next_tx_frame) % pipe->interval;
transaction->prev = NULL;
pipe->head = transaction;
list_move_tail(&pipe->node, list_move_tail(&pipe->node,
&usb->active_pipes[pipe->transfer_type]); &usb->active_pipes[pipe->transfer_type]);
}
pipe->tail = transaction;
/* We may need to schedule the pipe if this was the head of the pipe */ /*
if (!transaction->prev) * We may need to schedule the pipe if this was the head of the
* pipe.
*/
__cvmx_usb_schedule(usb, 0); __cvmx_usb_schedule(usb, 0);
}
return transaction; return transaction;
} }
...@@ -2332,8 +2324,8 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb, ...@@ -2332,8 +2324,8 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
* If the transaction is the HEAD of the queue and scheduled. We need to * If the transaction is the HEAD of the queue and scheduled. We need to
* treat it special * treat it special
*/ */
if ((pipe->head == transaction) && if (list_first_entry(&pipe->transactions, typeof(*transaction), node) ==
(pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) { transaction && (pipe->flags & __CVMX_USB_PIPE_FLAGS_SCHEDULED)) {
union cvmx_usbcx_hccharx usbc_hcchar; union cvmx_usbcx_hccharx usbc_hcchar;
usb->pipe_for_channel[pipe->channel] = NULL; usb->pipe_for_channel[pipe->channel] = NULL;
...@@ -2368,9 +2360,11 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb, ...@@ -2368,9 +2360,11 @@ static int cvmx_usb_cancel(struct cvmx_usb_state *usb,
static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb, static int cvmx_usb_cancel_all(struct cvmx_usb_state *usb,
struct cvmx_usb_pipe *pipe) struct cvmx_usb_pipe *pipe)
{ {
struct cvmx_usb_transaction *transaction, *next;
/* Simply loop through and attempt to cancel each transaction */ /* Simply loop through and attempt to cancel each transaction */
while (pipe->head) { list_for_each_entry_safe(transaction, next, &pipe->transactions, node) {
int result = cvmx_usb_cancel(usb, pipe, pipe->head); int result = cvmx_usb_cancel(usb, pipe, transaction);
if (unlikely(result != 0)) if (unlikely(result != 0))
return result; return result;
} }
...@@ -2391,7 +2385,7 @@ static int cvmx_usb_close_pipe(struct cvmx_usb_state *usb, ...@@ -2391,7 +2385,7 @@ static int cvmx_usb_close_pipe(struct cvmx_usb_state *usb,
struct cvmx_usb_pipe *pipe) struct cvmx_usb_pipe *pipe)
{ {
/* Fail if the pipe has pending transactions */ /* Fail if the pipe has pending transactions */
if (unlikely(pipe->head)) if (!list_empty(&pipe->transactions))
return -EBUSY; return -EBUSY;
list_del(&pipe->node); list_del(&pipe->node);
...@@ -2499,7 +2493,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel) ...@@ -2499,7 +2493,8 @@ static int __cvmx_usb_poll_channel(struct cvmx_usb_state *usb, int channel)
CVMX_PREFETCH(pipe, 128); CVMX_PREFETCH(pipe, 128);
if (!pipe) if (!pipe)
return 0; return 0;
transaction = pipe->head; transaction = list_first_entry(&pipe->transactions, typeof(*transaction),
node);
CVMX_PREFETCH(transaction, 0); CVMX_PREFETCH(transaction, 0);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment