[rt2x00-users] [RFC 1/2] rt2x00: Make rt2x00_queue_entry_for_each more flexible

Gertjan van Wingerde gwingerde at gmail.com
Wed Mar 30 05:46:41 EST 2011


On 03/29/11 14:02, Helmut Schaa wrote:
> Allow passing a void pointer to rt2x00_queue_entry_for_each which in
> turn in provided to the callback function.
>
> Furthermore, allow the callback function to stop processing by returning
> true. And also notify the caller of rt2x00_queue_entry_for_each if the
> loop was canceled by the callback.
>
> No functional changes, just preparation for an upcoming patch.
>
> Signed-off-by: Helmut Schaa <helmut.schaa at googlemail.com>

Acked-by: Gertjan van Wingerde <gwingerde at gmail.com>

> ---
>  drivers/net/wireless/rt2x00/rt2x00queue.c |   16 +++++++++++-----
>  drivers/net/wireless/rt2x00/rt2x00queue.h |   10 ++++++++--
>  drivers/net/wireless/rt2x00/rt2x00usb.c   |   29 +++++++++++++++++++----------
>  3 files changed, 38 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
> index 9fc4a1e..afc84c0 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
> @@ -650,10 +650,12 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev,
>  	return ret;
>  }
>  
> -void rt2x00queue_for_each_entry(struct data_queue *queue,
> +bool rt2x00queue_for_each_entry(struct data_queue *queue,
>  				enum queue_index start,
>  				enum queue_index end,
> -				void (*fn)(struct queue_entry *entry))
> +				void *data,
> +				bool (*fn)(struct queue_entry *entry,
> +					   void *data))
>  {
>  	unsigned long irqflags;
>  	unsigned int index_start;
> @@ -684,14 +686,18 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
>  	 */
>  	if (index_start < index_end) {
>  		for (i = index_start; i < index_end; i++)
> -			fn(&queue->entries[i]);
> +			if (fn(&queue->entries[i], data))
> +				return true;
>  	} else {
>  		for (i = index_start; i < queue->limit; i++)
> -			fn(&queue->entries[i]);
> +			if (fn(&queue->entries[i], data))
> +				return true;
>  
>  		for (i = 0; i < index_end; i++)
> -			fn(&queue->entries[i]);
> +			if (fn(&queue->entries[i], data))
> +				return true;
>  	}
> +	return false;
>  }
>  EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
>  
> diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
> index 6ae8200..6b66452 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00queue.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
> @@ -580,16 +580,22 @@ struct data_queue_desc {
>   * @queue: Pointer to @data_queue
>   * @start: &enum queue_index Pointer to start index
>   * @end: &enum queue_index Pointer to end index
> + * @data: Data to pass to the callback function
>   * @fn: The function to call for each &struct queue_entry
>   *
>   * This will walk through all entries in the queue, in chronological
>   * order. This means it will start at the current @start pointer
>   * and will walk through the queue until it reaches the @end pointer.
> + *
> + * If fn returns true for an entry rt2x00queue_for_each_entry will stop
> + * processing and return true as well.
>   */
> -void rt2x00queue_for_each_entry(struct data_queue *queue,
> +bool rt2x00queue_for_each_entry(struct data_queue *queue,
>  				enum queue_index start,
>  				enum queue_index end,
> -				void (*fn)(struct queue_entry *entry));
> +				void *data,
> +				bool (*fn)(struct queue_entry *entry,
> +					   void *data));
>  
>  /**
>   * rt2x00queue_empty - Check if the queue is empty.
> diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
> index fbe735f..2b65ef2 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00usb.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
> @@ -230,7 +230,7 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb)
>  	queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
>  }
>  
> -static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
> +static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
>  {
>  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
>  	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
> @@ -240,7 +240,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
>  
>  	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
>  	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> -		return;
> +		return false;
>  
>  	/*
>  	 * USB devices cannot blindly pass the skb->len as the
> @@ -261,6 +261,7 @@ static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
>  		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
>  		rt2x00lib_dmadone(entry);
>  	}
> +	return false;
>  }
>  
>  /*
> @@ -323,7 +324,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
>  	queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
>  }
>  
> -static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
> +static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data)
>  {
>  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
>  	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
> @@ -332,7 +333,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
>  
>  	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
>  	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
> -		return;
> +		return false;
>  
>  	rt2x00lib_dmastart(entry);
>  
> @@ -348,6 +349,7 @@ static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
>  		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
>  		rt2x00lib_dmadone(entry);
>  	}
> +	return false;
>  }
>  
>  void rt2x00usb_kick_queue(struct data_queue *queue)
> @@ -358,12 +360,18 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
>  	case QID_AC_BE:
>  	case QID_AC_BK:
>  		if (!rt2x00queue_empty(queue))
> -			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
> +			rt2x00queue_for_each_entry(queue,
> +						   Q_INDEX_DONE,
> +						   Q_INDEX,
> +						   NULL,
>  						   rt2x00usb_kick_tx_entry);
>  		break;
>  	case QID_RX:
>  		if (!rt2x00queue_full(queue))
> -			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
> +			rt2x00queue_for_each_entry(queue,
> +						   Q_INDEX_DONE,
> +						   Q_INDEX,
> +						   NULL,
>  						   rt2x00usb_kick_rx_entry);
>  		break;
>  	default:
> @@ -372,14 +380,14 @@ void rt2x00usb_kick_queue(struct data_queue *queue)
>  }
>  EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
>  
> -static void rt2x00usb_flush_entry(struct queue_entry *entry)
> +static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
>  {
>  	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
>  	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
>  	struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
>  
>  	if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
> -		return;
> +		return false;
>  
>  	usb_kill_urb(entry_priv->urb);
>  
> @@ -389,6 +397,7 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry)
>  	if ((entry->queue->qid == QID_BEACON) &&
>  	    (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
>  		usb_kill_urb(bcn_priv->guardian_urb);
> +	return false;
>  }
>  
>  void rt2x00usb_flush_queue(struct data_queue *queue)
> @@ -396,7 +405,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue)
>  	struct work_struct *completion;
>  	unsigned int i;
>  
> -	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
> +	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
>  				   rt2x00usb_flush_entry);
>  
>  	/*
> @@ -489,7 +498,7 @@ void rt2x00usb_clear_entry(struct queue_entry *entry)
>  	entry->flags = 0;
>  
>  	if (entry->queue->qid == QID_RX)
> -		rt2x00usb_kick_rx_entry(entry);
> +		rt2x00usb_kick_rx_entry(entry, NULL);
>  }
>  EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
>  


-- 
---
Gertjan




More information about the users mailing list