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;
}
Exemple #4
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;
	//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;
}