drivers/net/can/usb/peak_usb/pcan_usb_pro.c

Source file repositories/reference/linux-study-clean/drivers/net/can/usb/peak_usb/pcan_usb_pro.c

File Facts

System
Linux kernel
Corpus path
drivers/net/can/usb/peak_usb/pcan_usb_pro.c
Extension
.c
Size
27823 bytes
Lines
1103
Domain
Driver Families
Bucket
drivers/net
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 pcan_usb_pro_interface {
	struct peak_usb_device *dev[PCAN_USBPRO_CHANNEL_COUNT];
	struct peak_time_ref time_ref;
	int cm_ignore_count;
	int dev_opened_count;
};

/* device information */
struct pcan_usb_pro_device {
	struct peak_usb_device dev;
	struct pcan_usb_pro_interface *usb_if;
	u32 cached_ccbt;
};

/* internal structure used to handle messages sent to bulk urb */
struct pcan_usb_pro_msg {
	u8 *rec_ptr;
	int rec_buffer_size;
	int rec_buffer_len;
	union {
		__le16 *rec_cnt_rd;
		__le32 *rec_cnt;
		u8 *rec_buffer;
	} u;
};

/* records sizes table indexed on message id. (8-bits value) */
static u16 pcan_usb_pro_sizeof_rec[256] = {
	[PCAN_USBPRO_SETBTR] = sizeof(struct pcan_usb_pro_btr),
	[PCAN_USBPRO_SETBUSACT] = sizeof(struct pcan_usb_pro_busact),
	[PCAN_USBPRO_SETSILENT] = sizeof(struct pcan_usb_pro_silent),
	[PCAN_USBPRO_SETFILTR] = sizeof(struct pcan_usb_pro_filter),
	[PCAN_USBPRO_SETTS] = sizeof(struct pcan_usb_pro_setts),
	[PCAN_USBPRO_GETDEVID] = sizeof(struct pcan_usb_pro_devid),
	[PCAN_USBPRO_SETDEVID] = sizeof(struct pcan_usb_pro_devid),
	[PCAN_USBPRO_SETLED] = sizeof(struct pcan_usb_pro_setled),
	[PCAN_USBPRO_RXMSG8] = sizeof(struct pcan_usb_pro_rxmsg),
	[PCAN_USBPRO_RXMSG4] = sizeof(struct pcan_usb_pro_rxmsg) - 4,
	[PCAN_USBPRO_RXMSG0] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
	[PCAN_USBPRO_RXRTR] = sizeof(struct pcan_usb_pro_rxmsg) - 8,
	[PCAN_USBPRO_RXSTATUS] = sizeof(struct pcan_usb_pro_rxstatus),
	[PCAN_USBPRO_RXTS] = sizeof(struct pcan_usb_pro_rxts),
	[PCAN_USBPRO_TXMSG8] = sizeof(struct pcan_usb_pro_txmsg),
	[PCAN_USBPRO_TXMSG4] = sizeof(struct pcan_usb_pro_txmsg) - 4,
	[PCAN_USBPRO_TXMSG0] = sizeof(struct pcan_usb_pro_txmsg) - 8,
};

/*
 * initialize PCAN-USB Pro message data structure
 */
static u8 *pcan_msg_init(struct pcan_usb_pro_msg *pm, void *buffer_addr,
			 int buffer_size)
{
	if (buffer_size < PCAN_USBPRO_MSG_HEADER_LEN)
		return NULL;

	pm->u.rec_buffer = (u8 *)buffer_addr;
	pm->rec_buffer_size = pm->rec_buffer_len = buffer_size;
	pm->rec_ptr = pm->u.rec_buffer + PCAN_USBPRO_MSG_HEADER_LEN;

	return pm->rec_ptr;
}

static u8 *pcan_msg_init_empty(struct pcan_usb_pro_msg *pm,
			       void *buffer_addr, int buffer_size)
{
	u8 *pr = pcan_msg_init(pm, buffer_addr, buffer_size);

	if (pr) {
		pm->rec_buffer_len = PCAN_USBPRO_MSG_HEADER_LEN;
		*pm->u.rec_cnt = 0;
	}
	return pr;
}

/*
 * add one record to a message being built
 */
static int pcan_msg_add_rec(struct pcan_usb_pro_msg *pm, int id, ...)
{
	int len, i;
	u8 *pc;
	va_list ap;

	va_start(ap, id);

	pc = pm->rec_ptr + 1;

	i = 0;
	switch (id) {

Annotation

Implementation Notes