drivers/media/usb/dvb-usb/ttusb2.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/dvb-usb/ttusb2.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/dvb-usb/ttusb2.c
Extension
.c
Size
19006 bytes
Lines
850
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ttusb2_state {
	struct dvb_ca_en50221 ca;
	struct mutex ca_mutex;
	u8 id;
	u16 last_rc_key;
};

static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd,
		u8 *wbuf, int wlen, u8 *rbuf, int rlen)
{
	struct ttusb2_state *st = d->priv;
	u8 *s, *r = NULL;
	int ret = 0;

	if (4 + rlen > 64)
		return -EIO;

	s = kzalloc(wlen+4, GFP_KERNEL);
	if (!s)
		return -ENOMEM;

	r = kzalloc(64, GFP_KERNEL);
	if (!r) {
		kfree(s);
		return -ENOMEM;
	}

	s[0] = 0xaa;
	s[1] = ++st->id;
	s[2] = cmd;
	s[3] = wlen;
	memcpy(&s[4],wbuf,wlen);

	ret = dvb_usb_generic_rw(d, s, wlen+4, r, 64, 0);

	if (ret  != 0 ||
		r[0] != 0x55 ||
		r[1] != s[1] ||
		r[2] != cmd ||
		(rlen > 0 && r[3] != rlen)) {
		warn("there might have been an error during control message transfer. (rlen = %d, was %d)",rlen,r[3]);
		kfree(s);
		kfree(r);
		return -EIO;
	}

	if (rlen > 0)
		memcpy(rbuf, &r[4], rlen);

	kfree(s);
	kfree(r);

	return 0;
}

/* ci */
static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
{
	int ret;
	u8 rx[60];/* (64 -4) */
	ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len);
	if (!ret)
		memcpy(data, rx, read_len);
	return ret;
}

static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len)
{
	struct dvb_usb_device *d = ca->data;
	struct ttusb2_state *state = d->priv;
	int ret;

	mutex_lock(&state->ca_mutex);
	ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
	mutex_unlock(&state->ca_mutex);

	return ret;
}

static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
{
	u8 buf[3];
	int ret = 0;

	if (slot)
		return -EINVAL;

	buf[0] = (address >> 8) & 0x0F;
	buf[1] = address;

Annotation

Implementation Notes