Am Mittwoch, 15. Juni 2011, 01:45:52 schrieb David Herrmann: > +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(). > 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 > + 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 -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html