static ssize_t hsi_char_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int ch = (int)file->private_data; DECLARE_WAITQUEUE(wait, current); u32 *data; unsigned int data_len; struct char_queue *entry; ssize_t ret; /*printk(KERN_DEBUG "%s, count = %d\n", __func__, count); */ /* only 32bit data is supported for now */ if ((count < 4) || (count & 3)) return -EINVAL; data = kmalloc(count, GFP_ATOMIC); ret = if_hsi_read(ch, data, count); if (ret < 0) { kfree(data); goto out2; } spin_lock_bh(&hsi_char_data[ch].lock); add_wait_queue(&hsi_char_data[ch].rx_wait, &wait); spin_unlock_bh(&hsi_char_data[ch].lock); for (;;) { data = NULL; data_len = 0; set_current_state(TASK_INTERRUPTIBLE); spin_lock_bh(&hsi_char_data[ch].lock); if (!list_empty(&hsi_char_data[ch].rx_queue)) { entry = list_entry(hsi_char_data[ch].rx_queue.next, struct char_queue, list); data = entry->data; data_len = entry->count; list_del(&entry->list); kfree(entry); } spin_unlock_bh(&hsi_char_data[ch].lock); pr_debug("%s, data = 0x%p, data_len = %d\n", __func__, data, data_len); if (data_len) { pr_debug("%s, RX finished\n", __func__); spin_lock_bh(&hsi_char_data[ch].lock); hsi_char_data[ch].poll_event &= ~(POLLIN | POLLRDNORM); spin_unlock_bh(&hsi_char_data[ch].lock); if_hsi_poll(ch); break; } else if (file->f_flags & O_NONBLOCK) { pr_debug("%s, O_NONBLOCK\n", __func__); ret = -EAGAIN; goto out; } else if (signal_pending(current)) { pr_debug("%s, ERESTARTSYS\n", __func__); ret = -EAGAIN; if_hsi_cancel_read(ch); /* goto out; */ break; } /*printk(KERN_DEBUG "%s, going to sleep...\n", __func__); */ schedule(); /*printk(KERN_DEBUG "%s, woke up\n", __func__); */ }
int hsi_proto_read(int ch, u32 *buffer, int count) { DECLARE_WAITQUEUE(wait, current); u32 *data; unsigned int data_len = 0; struct protocol_queue *entry; int ret, recv_data = 0; /*printk(KERN_DEBUG "%s, count = %d\n", __func__, count); */ /* if (count > MAX_HSI_IPC_BUFFER) count = MAX_HSI_IPC_BUFFER; data = kmalloc(count, GFP_ATOMIC);*/ ret = if_hsi_read(ch, buffer, count); if (ret < 0) { pr_err("Can not submit read. READ Error \n"); goto out2; } spin_lock_bh(&hsi_protocol_data[ch].lock); add_wait_queue(&hsi_protocol_data[ch].rx_wait, &wait); spin_unlock_bh(&hsi_protocol_data[ch].lock); for (;;) { data = NULL; data_len = 0; set_current_state(TASK_INTERRUPTIBLE); spin_lock_bh(&hsi_protocol_data[ch].lock); if (!list_empty(&hsi_protocol_data[ch].rx_queue)) { entry = list_entry(hsi_protocol_data[ch].rx_queue.next, struct protocol_queue, list); data = entry->data; data_len = entry->count; list_del(&entry->list); kfree(entry); } spin_unlock_bh(&hsi_protocol_data[ch].lock); pr_debug("%s, data = 0x%p, data_len = %d\n", __func__, data, data_len); if (data_len) { pr_debug("%s, RX finished\n", __func__); //printk("%s, RX finished, ch-> %d, length = %d\n", __func__, ch, count); spin_lock_bh(&hsi_protocol_data[ch].lock); hsi_protocol_data[ch].poll_event &= ~(POLLIN | POLLRDNORM); spin_unlock_bh(&hsi_protocol_data[ch].lock); if_hsi_poll(ch); //memcpy(buffer, data, count); recv_data += data_len; //buffer += data_len; //if ((recv_data == count) || (recv_data => MAX_HSI_IPC_BUFFER)) break; } else if (signal_pending(current)) { pr_debug("%s, ERESTARTSYS\n", __func__); recv_data = -EAGAIN; if_hsi_cancel_read(ch); /* goto out; */ break; } /*printk(KERN_DEBUG "%s, going to sleep...\n", __func__); */ schedule(); /*printk(KERN_DEBUG "%s, woke up\n", __func__); */ }