コード例 #1
0
ファイル: dvbsky.c プロジェクト: wejgomi/nexus-player
static int dvbsky_usb_generic_rw(struct dvb_usb_device *d,
		u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
	int ret;
	struct dvbsky_state *state = d_to_priv(d);

	mutex_lock(&d->usb_mutex);
	if (wlen != 0)
		memcpy(state->obuf, wbuf, wlen);

	ret = dvb_usbv2_generic_rw_locked(d, state->obuf, wlen,
			state->ibuf, rlen);

	if (!ret && (rlen != 0))
		memcpy(rbuf, state->ibuf, rlen);

	mutex_unlock(&d->usb_mutex);
	return ret;
}
コード例 #2
0
ファイル: af9015.c プロジェクト: ChineseDr/linux
static int af9015_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
{
#define REQ_HDR_LEN 8 /* send header size */
#define ACK_HDR_LEN 2 /* rece header size */
    struct af9015_state *state = d_to_priv(d);
    int ret, wlen, rlen;
    u8 write = 1;

    mutex_lock(&d->usb_mutex);

    state->buf[0] = req->cmd;
    state->buf[1] = state->seq++;
    state->buf[2] = req->i2c_addr;
    state->buf[3] = req->addr >> 8;
    state->buf[4] = req->addr & 0xff;
    state->buf[5] = req->mbox;
    state->buf[6] = req->addr_len;
    state->buf[7] = req->data_len;

    switch (req->cmd) {
    case GET_CONFIG:
    case READ_MEMORY:
    case RECONNECT_USB:
        write = 0;
        break;
    case READ_I2C:
        write = 0;
        state->buf[2] |= 0x01; /* set I2C direction */
    case WRITE_I2C:
        state->buf[0] = READ_WRITE_I2C;
        break;
    case WRITE_MEMORY:
        if (((req->addr & 0xff00) == 0xff00) ||
                ((req->addr & 0xff00) == 0xae00))
            state->buf[0] = WRITE_VIRTUAL_MEMORY;
    case WRITE_VIRTUAL_MEMORY:
    case COPY_FIRMWARE:
    case DOWNLOAD_FIRMWARE:
    case BOOT:
        break;
    default:
        dev_err(&d->udev->dev, "%s: unknown command=%d\n",
                KBUILD_MODNAME, req->cmd);
        ret = -EIO;
        goto error;
    }

    /* buffer overflow check */
    if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
            (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
        dev_err(&d->udev->dev, "%s: too much data; cmd=%d len=%d\n",
                KBUILD_MODNAME, req->cmd, req->data_len);
        ret = -EINVAL;
        goto error;
    }

    /* write receives seq + status = 2 bytes
       read receives seq + status + data = 2 + N bytes */
    wlen = REQ_HDR_LEN;
    rlen = ACK_HDR_LEN;
    if (write) {
        wlen += req->data_len;
        memcpy(&state->buf[REQ_HDR_LEN], req->data, req->data_len);
    } else {
        rlen += req->data_len;
    }

    /* no ack for these packets */
    if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
        rlen = 0;

    ret = dvb_usbv2_generic_rw_locked(d,
                                      state->buf, wlen, state->buf, rlen);
    if (ret)
        goto error;

    /* check status */
    if (rlen && state->buf[1]) {
        dev_err(&d->udev->dev, "%s: command failed=%d\n",
                KBUILD_MODNAME, state->buf[1]);
        ret = -EIO;
        goto error;
    }

    /* read request, copy returned data to return buf */
    if (!write)
        memcpy(req->data, &state->buf[ACK_HDR_LEN], req->data_len);
error:
    mutex_unlock(&d->usb_mutex);

    return ret;
}