Thread (24 messages) 24 messages, 4 authors, 2011-06-17

Re: [RFC 07/12] HID: wiimote: Add output queue for wiimote driver

flat view

From: Oliver Neukum <oliver@neukum.org>
Date: 2011-06-15 06:42:19

Am Mittwoch, 15. Juni 2011, 01:45:52 schrieb David Herrmann:
quoted hunk ↗ jump to hunk
+struct wiimote_buf {
+	__u8 data[HID_MAX_BUFFER_SIZE];
+	size_t size;
+};
As this probably goes out over USB -> BT
you are violating the DMA buffer constraints.
Every buffer must be separately allocated with kmalloc().
quoted hunk ↗ jump to hunk
 struct wiimote_data {
 	atomic_t ready;
 	struct hid_device *hdev;
 	struct input_dev *input;
+
+	spinlock_t qlock;
+	__u8 head;
+	__u8 tail;
+	struct wiimote_buf outq[WIIMOTE_BUFSIZE];
+	struct work_struct worker;
 };
 
 static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
@@ -36,6 +49,78 @@ static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
 							HID_OUTPUT_REPORT);
 }
 
+static void wiimote_worker(struct work_struct *work)
+{
+	struct wiimote_data *wdata = container_of(work, struct wiimote_data,
+									worker);
+
+	if (!atomic_read(&wdata->ready))
+		return;
+
+	spin_lock(&wdata->qlock);
You want _irqsave
quoted hunk ↗ jump to hunk
+	if (wdata->head != wdata->tail) {
+		spin_unlock(&wdata->qlock);
+		wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
+						wdata->outq[wdata->tail].size);
+		spin_lock(&wdata->qlock);
+
+		wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
+
+		/*
+		 * We are using the shared workqueue so send at most one whole
+		 * buffer and then reschedule ourself so we do not occupy the
+		 * shared workqueue for too long.
+		 */
+		if (wdata->head != wdata->tail)
+			schedule_work(&wdata->worker);
+	}
+
+	spin_unlock(&wdata->qlock);
+}
	Regards
		Oliver
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help