static int diag2arm9_open(struct inode *ip, struct file *fp) { struct diag_context *ctxt = &_context; DBG_OP("+diag2arm9_open()\n"); if (_lock(&ctxt->open_arm9_excl)) return -EBUSY; msm_diag_smd_open(); diag_configure(1, ctxt); DBG_OP("-diag2arm9_open()\n"); return 0; }
static int diag2arm9_release(struct inode *ip, struct file *fp) { struct diag_context *ctxt = &_context; struct diag_request *req; DBG_OP("+%s\n", __func__); diag_configure(0, ctxt); msm_diag_smd_close(); /* recycle unhandled rx reqs to user if any */ while ((req = get_req(ctxt, &ctxt->rx_arm9_done))) put_req(ctxt, &ctxt->rx_arm9_idle, req); /* Release readers that might be blocked */ wake_up(&ctxt->read_arm9_wq); _unlock(&ctxt->open_arm9_excl); DBG_OP("-%s\n", __func__); return 0; }
static ssize_t diag2arm9_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) { struct diag_context *ctxt = &_context; struct diag_request *req; int r = 0, xfer; int ret; DBG("diag2arm9_read(%d)\n", count); if (_lock(&ctxt->read_arm9_excl)) return -EBUSY; while (count > 0) { /* if we have data pending, give it to userspace */ if (ctxt->read_arm9_count > 0) { xfer = (ctxt->read_arm9_count < count) ? ctxt->read_arm9_count : count; if (copy_to_user(buf, ctxt->read_arm9_buf, xfer)) { DBG("diag: copy_to_user fail\n"); r = -EFAULT; break; } ctxt->read_arm9_buf += xfer; ctxt->read_arm9_count -= xfer; buf += xfer; count -= xfer; r += xfer; /* if we've emptied the buffer, release the request */ if (ctxt->read_arm9_count == 0) { put_req(ctxt, &ctxt->rx_arm9_idle, ctxt->read_arm9_req); ctxt->read_arm9_req = 0; } continue; } /* wait for a request to complete */ req = 0; ret = wait_event_interruptible(ctxt->read_arm9_wq, ((req = get_req(ctxt, &ctxt->rx_arm9_done)) || ctxt->error)); if (req != 0) { /* if we got a 0-len one we need to put it back into ** service. if we made it the current read req we'd ** be stuck forever */ if (req->actual == 0) { put_req(ctxt, &ctxt->rx_arm9_idle, req); continue; } ctxt->read_arm9_req = req; ctxt->read_arm9_count = req->actual; ctxt->read_arm9_buf = req->buf; if (ctxt->read_arm9_count < count) count = ctxt->read_arm9_count; DBG("rx %p %d\n", req, req->actual); } if (ret < 0) { DBG_OP("%s: ret < 0\n", __func__); r = ret; break; } } _unlock(&ctxt->read_arm9_excl); return r; }
static ssize_t diag2arm9_read(struct file *fp, char __user *buf, size_t count, loff_t *pos) { struct diag_context *ctxt = &_context; struct diag_request *req; int r = 0, xfer; int ret; //ctxt->isRead = 1; DBG("diag2arm9_read(%d)\n", count); if (_lock(&ctxt->read_arm9_excl)) return -EBUSY; /* we will block until we're offline */ /* while (ctxt->online) { ret = wait_event_interruptible(ctxt->read_arm9_wq, !(ctxt->online)); if (ret < 0) { _unlock(&ctxt->read_arm9_excl); return ret; } } */ while (count > 0) { /* if (ctxt->error) { r = -EIO; break; } */ /* if we have idle read requests, get them queued */ /* while ((req = get_req(ctxt, &ctxt->rx_idle))) { requeue_req: req->length = TXN_MAX; ret = usb_ept_queue_xfer(ctxt->out, req); if (ret < 0) { DBG("diag_read: failed to queue req %p (%d)\n", req, ret); r = -EIO; ctxt->error = 1; put_req(ctxt, &ctxt->rx_idle, req); goto fail; } else { DBG("rx %p queue\n", req); } } */ /* if we have data pending, give it to userspace */ if (ctxt->read_arm9_count > 0) { xfer = (ctxt->read_arm9_count < count) ? ctxt->read_arm9_count : count; if (copy_to_user(buf, ctxt->read_arm9_buf, xfer)) { DBG("diag: copy_to_user fail\n"); r = -EFAULT; break; } ctxt->read_arm9_buf += xfer; ctxt->read_arm9_count -= xfer; buf += xfer; count -= xfer; r += xfer; /* if we've emptied the buffer, release the request */ if (ctxt->read_arm9_count == 0) { put_req(ctxt, &ctxt->rx_arm9_idle, ctxt->read_arm9_req); ctxt->read_arm9_req = 0; } continue; } /* wait for a request to complete */ req = 0; ret = wait_event_interruptible(ctxt->read_arm9_wq, ((req = get_req(ctxt, &ctxt->rx_arm9_done)) || ctxt->error)); if (req != 0) { /* if we got a 0-len one we need to put it back into ** service. if we made it the current read req we'd ** be stuck forever */ if (req->actual == 0) { // goto requeue_req; put_req(ctxt, &ctxt->rx_arm9_idle, req); continue; } ctxt->read_arm9_req = req; ctxt->read_arm9_count = req->actual; ctxt->read_arm9_buf = req->buf; if (ctxt->read_arm9_count < count) count = ctxt->read_arm9_count; DBG("rx %p %d\n", req, req->actual); } if (ret < 0) { DBG_OP("%s: ret < 0\n", __func__); r = ret; break; } } //fail: _unlock(&ctxt->read_arm9_excl); //ctxt->isRead = 0; return r; }