drivers/usb/serial/omninet.c

Source file repositories/reference/linux-study-clean/drivers/usb/serial/omninet.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/serial/omninet.c
Extension
.c
Size
4927 bytes
Lines
180
Domain
Driver Families
Bucket
drivers/usb
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 omninet_header {
	__u8	oh_seq;
	__u8	oh_len;
	__u8	oh_xxx;
	__u8	oh_pad;
};

struct omninet_data {
	__u8	od_outseq;	/* Sequence number for bulk_out URBs */
};

static int omninet_calc_num_ports(struct usb_serial *serial,
					struct usb_serial_endpoints *epds)
{
	/* We need only the second bulk-out for our single-port device. */
	epds->bulk_out[0] = epds->bulk_out[1];
	epds->num_bulk_out = 1;

	return 1;
}

static int omninet_port_probe(struct usb_serial_port *port)
{
	struct omninet_data *od;

	od = kzalloc_obj(*od);
	if (!od)
		return -ENOMEM;

	usb_set_serial_port_data(port, od);

	return 0;
}

static void omninet_port_remove(struct usb_serial_port *port)
{
	struct omninet_data *od;

	od = usb_get_serial_port_data(port);
	kfree(od);
}

static void omninet_process_read_urb(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	const struct omninet_header *hdr = urb->transfer_buffer;
	const unsigned char *data;
	size_t data_len;

	if (urb->actual_length <= OMNINET_HEADERLEN || !hdr->oh_len)
		return;

	data = (char *)urb->transfer_buffer + OMNINET_HEADERLEN;
	data_len = min_t(size_t, urb->actual_length - OMNINET_HEADERLEN,
								hdr->oh_len);
	tty_insert_flip_string(&port->port, data, data_len);
	tty_flip_buffer_push(&port->port);
}

static int omninet_prepare_write_buffer(struct usb_serial_port *port,
					void *buf, size_t count)
{
	struct omninet_data *od = usb_get_serial_port_data(port);
	struct omninet_header *header = buf;

	count = min_t(size_t, count, OMNINET_PAYLOADSIZE);

	count = kfifo_out_locked(&port->write_fifo, buf + OMNINET_HEADERLEN,
			count, &port->lock);

	header->oh_seq = od->od_outseq++;
	header->oh_len = count;
	header->oh_xxx = 0x03;
	header->oh_pad = 0x00;

	/* always 64 bytes */
	return OMNINET_BULKOUTSIZE;
}

module_usb_serial_driver(serial_drivers, id_table);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL v2");

Annotation

Implementation Notes