static int dhd_get_scheduled_work(struct dhd_deferred_wq *deferred_wq, struct dhd_deferred_event_t *event) { int status = 0; if (!deferred_wq) { DHD_ERROR(("%s: work queue not initialized \n", __FUNCTION__)); return DHD_WQ_STS_UNINITIALIZED; } /* * default element size is 1 byte, which can be changed * using kfifo_esize(). Older kernel(FC11) doesn't support * changing element size. For compatibility changing * element size is not prefered */ ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1); ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1); /* first read priorit event fifo */ status = kfifo_out_spinlocked(deferred_wq->prio_fifo, event, DEFRD_EVT_SIZE, &deferred_wq->work_lock); if (!status) { /* priority fifo is empty. Now read low prio work fifo */ status = kfifo_out_spinlocked(deferred_wq->work_fifo, event, DEFRD_EVT_SIZE, &deferred_wq->work_lock); } return status; }
static ssize_t tmsi_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct tmsi_data* dev; char* temp_buffer = NULL; int retval = 0; size_t true_count; dev = (struct tmsi_data*) file->private_data; if (down_timeout(dev->fifo_sem, HZ / 2) != 0) return -ETIME; while (down_trylock(dev->fifo_sem) == 0); temp_buffer = kmalloc(count, GFP_KERNEL); if (!temp_buffer) { retval = -ENOMEM; goto exit; } #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) true_count = kfifo_out_spinlocked(dev->packet_buffer, temp_buffer, count, &dev->buffer_lock); #elif LINUX_VERSION_CODE > KERNEL_VERSION(2,6,32) true_count = kfifo_out_locked(dev->packet_buffer, temp_buffer, count, &dev->buffer_lock); #else true_count = kfifo_get(dev->packet_buffer, temp_buffer, count); #endif /* if the read was successful, copy the data to userspace */ if (copy_to_user(buffer, temp_buffer, true_count)) retval = -EFAULT; else retval = true_count; kfree(temp_buffer); exit: if (kfifo_len(dev->packet_buffer) > 0) up(dev->fifo_sem); return retval; }