drivers/usb/serial/pl2303.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/serial/pl2303.c
Extension
.c
Size
34922 bytes
Lines
1311
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 pl2303_type_data {
	const char *name;
	speed_t max_baud_rate;
	unsigned long quirks;
	unsigned int no_autoxonxoff:1;
	unsigned int no_divisors:1;
	unsigned int alt_divisors:1;
};

struct pl2303_serial_private {
	const struct pl2303_type_data *type;
	unsigned long quirks;
};

struct pl2303_private {
	spinlock_t lock;
	u8 line_control;
	u8 line_status;

	u8 line_settings[7];
};

static const struct pl2303_type_data pl2303_type_data[TYPE_COUNT] = {
	[TYPE_H] = {
		.name			= "H",
		.max_baud_rate		= 1228800,
		.quirks			= PL2303_QUIRK_LEGACY,
		.no_autoxonxoff		= true,
	},
	[TYPE_HX] = {
		.name			= "HX",
		.max_baud_rate		= 6000000,
	},
	[TYPE_TA] = {
		.name			= "TA",
		.max_baud_rate		= 6000000,
		.alt_divisors		= true,
	},
	[TYPE_TB] = {
		.name			= "TB",
		.max_baud_rate		= 12000000,
		.alt_divisors		= true,
	},
	[TYPE_HXD] = {
		.name			= "HXD",
		.max_baud_rate		= 12000000,
	},
	[TYPE_HXN] = {
		.name			= "G",
		.max_baud_rate		= 12000000,
		.no_divisors		= true,
	},
};

static int pl2303_vendor_read(struct usb_serial *serial, u16 value,
							unsigned char buf[1])
{
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
	struct device *dev = &serial->interface->dev;
	u8 request;
	int res;

	if (spriv->type == &pl2303_type_data[TYPE_HXN])
		request = VENDOR_READ_NREQUEST;
	else
		request = VENDOR_READ_REQUEST;

	res = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
			request, VENDOR_READ_REQUEST_TYPE,
			value, 0, buf, 1, 100);
	if (res != 1) {
		dev_err(dev, "%s - failed to read [%04x]: %d\n", __func__,
								value, res);
		if (res >= 0)
			res = -EIO;

		return res;
	}

	dev_dbg(dev, "%s - [%04x] = %02x\n", __func__, value, buf[0]);

	return 0;
}

static int pl2303_vendor_write(struct usb_serial *serial, u16 value, u16 index)
{
	struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
	struct device *dev = &serial->interface->dev;
	u8 request;
	int res;

Annotation

Implementation Notes