Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10e11568 authored by Helmut Schaa's avatar Helmut Schaa Committed by John W. Linville
Browse files

rt2x00: Make rt2x00_queue_entry_for_each more flexible



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: default avatarHelmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Acked-by: default avatarGertjan van Wingerde <gwingerde@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7dab73b3
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -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;
@@ -664,7 +666,7 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
		ERROR(queue->rt2x00dev,
		      "Entry requested from invalid index range (%d - %d)\n",
		      start, end);
		return;
		return true;
	}

	/*
@@ -683,16 +685,24 @@ void rt2x00queue_for_each_entry(struct data_queue *queue,
	 * send out all frames in the correct order.
	 */
	if (index_start < index_end) {
		for (i = index_start; i < index_end; i++)
			fn(&queue->entries[i]);
		for (i = index_start; i < index_end; i++) {
			if (fn(&queue->entries[i], data))
				return true;
		}
	} else {
		for (i = index_start; i < queue->limit; i++)
			fn(&queue->entries[i]);
		for (i = index_start; i < queue->limit; i++) {
			if (fn(&queue->entries[i], data))
				return true;
		}

		for (i = 0; i < index_end; i++)
			fn(&queue->entries[i]);
		for (i = 0; i < index_end; i++) {
			if (fn(&queue->entries[i], data))
				return true;
		}
	}

	return false;
}
EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);

struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue,
+8 −2
Original line number Diff line number Diff line
@@ -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.
+22 −10
Original line number Diff line number Diff line
@@ -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 true;

	/*
	 * USB devices cannot blindly pass the skb->len as the
@@ -261,6 +261,8 @@ 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 +325,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 +334,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 true;

	rt2x00lib_dmastart(entry);

@@ -348,6 +350,8 @@ 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 +362,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 +382,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 true;

	usb_kill_urb(entry_priv->urb);

@@ -389,6 +399,8 @@ static void rt2x00usb_flush_entry(struct queue_entry *entry)
	if ((entry->queue->qid == QID_BEACON) &&
	    (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)))
		usb_kill_urb(bcn_priv->guardian_urb);

	return false;
}

void rt2x00usb_flush_queue(struct data_queue *queue)
@@ -396,7 +408,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 +501,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);