Пример #1
0
/*
 * Context: tasklet
 */
static int oz_usb_vendor_class_req(void *hpd, u8 req_id, u8 req_type,
	u8 request, __le16 value, __le16 index, const u8 *data, int data_len)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
	struct oz_vendor_class_req *body;

	if (ei == NULL)
		return -1;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_vendor_class_req) - 1 + data_len;
	body = (struct oz_vendor_class_req *)(elt+1);
	body->type = OZ_VENDOR_CLASS_REQ;
	body->req_id = req_id;
	body->req_type = req_type;
	body->request = request;
	put_unaligned(value, &body->value);
	put_unaligned(index, &body->index);
	if (data_len)
		memcpy(body->data, data, data_len);
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
Пример #2
0
/*
 * Context: softirq
 */
int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type,
	u8 index, u16 windex, int offset, int len)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_get_desc_req *body;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);

	oz_dbg(ON, "    req_type = 0x%x\n", req_type);
	oz_dbg(ON, "    desc_type = 0x%x\n", desc_type);
	oz_dbg(ON, "    index = 0x%x\n", index);
	oz_dbg(ON, "    windex = 0x%x\n", windex);
	oz_dbg(ON, "    offset = 0x%x\n", offset);
	oz_dbg(ON, "    len = 0x%x\n", len);
	if (len > 200)
		len = 200;
	if (ei == NULL)
		return -1;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_get_desc_req);
	body = (struct oz_get_desc_req *)(elt+1);
	body->type = OZ_GET_DESC_REQ;
	body->req_id = req_id;
	put_unaligned(cpu_to_le16(offset), &body->offset);
	put_unaligned(cpu_to_le16(len), &body->size);
	body->req_type = req_type;
	body->desc_type = desc_type;
	body->w_index = windex;
	body->index = index;
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
Пример #3
0
/*------------------------------------------------------------------------------
 * Context: softirq
 */
int oz_usb_get_desc_req(void *hpd, u8 req_id, u8 req_type, u8 desc_type,
	u8 index, u16 windex, int offset, int len)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_get_desc_req *body;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
	if (len > 200)
		len = 200;
	if (ei == 0)
		return -1;
	ei->callback = oz_usb_setup_elt_completion_callback;
	ei->context = req_id;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_get_desc_req);
	body = (struct oz_get_desc_req *)(elt+1);
	body->type = OZ_GET_DESC_REQ;
	body->req_id = req_id;
	put_unaligned(cpu_to_le16(offset), &body->offset);
	put_unaligned(cpu_to_le16(len), &body->size);
	body->req_type = req_type;
	body->desc_type = desc_type;
	body->w_index = windex;
	body->index = index;
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
Пример #4
0
/*------------------------------------------------------------------------------
 * Context: process
 */
ssize_t oz_cdev_write(struct file *filp, const char __user *buf, size_t count,
		loff_t *fpos)
{
	struct oz_pd *pd;
	struct oz_elt_buf *eb;
	struct oz_elt_info *ei = 0;
	struct oz_elt *elt;
	struct oz_app_hdr *app_hdr;
	struct oz_serial_ctx *ctx;

if (count > sizeof(ei->data) - sizeof(*elt) - sizeof(*app_hdr))
    return -EINVAL;

	spin_lock_bh(&g_cdev.lock);
	pd = g_cdev.active_pd;
	if (pd)
		oz_pd_get(pd);
	spin_unlock_bh(&g_cdev.lock);
	if (pd == 0)
		return -1;
	eb = &pd->elt_buff;
	ei = oz_elt_info_alloc(eb);
	if (ei == 0) {
		count = 0;
		goto out;
	}
	elt = (struct oz_elt *)ei->data;
	app_hdr = (struct oz_app_hdr *)(elt+1);
	elt->length = sizeof(struct oz_app_hdr) + count;
	elt->type = OZ_ELT_APP_DATA;
	ei->app_id = OZ_APPID_SERIAL;
	ei->length = elt->length + sizeof(struct oz_elt);
	app_hdr->app_id = OZ_APPID_SERIAL;
	if (copy_from_user(app_hdr+1, buf, count))
		goto out;
	spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]);
	ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1];
	if (ctx) {
		app_hdr->elt_seq_num = ctx->tx_seq_num++;
		if (ctx->tx_seq_num == 0)
			ctx->tx_seq_num = 1;
		spin_lock(&eb->lock);
		if (oz_queue_elt_info(eb, 0, 0, ei) == 0)
			ei = 0;
		spin_unlock(&eb->lock);
	}
	spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]);
out:
	if (ei) {
		count = 0;
		spin_lock_bh(&eb->lock);
		oz_elt_info_free(eb, ei);
		spin_unlock_bh(&eb->lock);
	}
	oz_pd_put(pd);
	return count;
}
Пример #5
0
/*------------------------------------------------------------------------------
 * Context: tasklet
 */
static int oz_usb_set_config_req(void *hpd, u8 req_id, u8 index)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
	struct oz_set_config_req *body;
	if (ei == 0)
		return -1;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_set_config_req);
	body = (struct oz_set_config_req *)(elt+1);
	body->type = OZ_SET_CONFIG_REQ;
	body->req_id = req_id;
	body->index = index;
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
Пример #6
0
/*
 * Context: tasklet
 */
static int oz_usb_set_interface_req(void *hpd, u8 req_id, u8 index, u8 alt)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
	struct oz_set_interface_req *body;

	if (ei == NULL)
		return -1;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_set_interface_req);
	body = (struct oz_set_interface_req *)(elt+1);
	body->type = OZ_SET_INTERFACE_REQ;
	body->req_id = req_id;
	body->index = index;
	body->alternative = alt;
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}
Пример #7
0
/*------------------------------------------------------------------------------
 * Context: tasklet
 */
static int oz_usb_set_clear_feature_req(void *hpd, u8 req_id, u8 type,
			u8 recipient, u8 index, __le16 feature)
{
	struct oz_usb_ctx *usb_ctx = (struct oz_usb_ctx *)hpd;
	struct oz_pd *pd = usb_ctx->pd;
	struct oz_elt *elt;
	struct oz_elt_buf *eb = &pd->elt_buff;
	struct oz_elt_info *ei = oz_elt_info_alloc(&pd->elt_buff);
	struct oz_feature_req *body;
	if (ei == 0)
		return -1;
	elt = (struct oz_elt *)ei->data;
	elt->length = sizeof(struct oz_feature_req);
	body = (struct oz_feature_req *)(elt+1);
	body->type = type;
	body->req_id = req_id;
	body->recipient = recipient;
	body->index = index;
	put_unaligned(feature, &body->feature);
	return oz_usb_submit_elt(eb, ei, usb_ctx, 0, 0);
}