drivers/usb/serial/kl5kusb105.c

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

File Facts

System
Linux kernel
Corpus path
drivers/usb/serial/kl5kusb105.c
Extension
.c
Size
13685 bytes
Lines
515
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 klsi_105_port_settings {
	u8	pktlen;		/* always 5, it seems */
	u8	baudrate;
	u8	databits;
	u8	unknown1;
	u8	unknown2;
};

struct klsi_105_private {
	struct klsi_105_port_settings	cfg;
	unsigned long			line_state; /* modem line settings */
	spinlock_t			lock;
};


/*
 * Handle vendor specific USB requests
 */


#define KLSI_TIMEOUT	 5000 /* default urb timeout */

static int klsi_105_chg_port_settings(struct usb_serial_port *port,
				      struct klsi_105_port_settings *settings)
{
	int rc;

	rc = usb_control_msg_send(port->serial->dev,
				  0,
				  KL5KUSB105A_SIO_SET_DATA,
				  USB_TYPE_VENDOR | USB_DIR_OUT |
				  USB_RECIP_INTERFACE,
				  0, /* value */
				  0, /* index */
				  settings,
				  sizeof(struct klsi_105_port_settings),
				  KLSI_TIMEOUT,
				  GFP_KERNEL);
	if (rc)
		dev_err(&port->dev,
			"Change port settings failed (error = %d)\n", rc);

	dev_dbg(&port->dev,
		"pktlen %u, baudrate 0x%02x, databits %u, u1 %u, u2 %u\n",
		settings->pktlen, settings->baudrate, settings->databits,
		settings->unknown1, settings->unknown2);

	return rc;
}

/*
 * Read line control via vendor command and return result through
 * the state pointer.
 */
static int klsi_105_get_line_state(struct usb_serial_port *port,
				   unsigned long *state)
{
	u16 status;
	int rc;

	rc = usb_control_msg_recv(port->serial->dev, 0,
				  KL5KUSB105A_SIO_POLL,
				  USB_TYPE_VENDOR | USB_DIR_IN,
				  0, /* value */
				  0, /* index */
				  &status, sizeof(status),
				  10000,
				  GFP_KERNEL);
	if (rc) {
		dev_err(&port->dev, "reading line status failed: %d\n", rc);
		return rc;
	}

	le16_to_cpus(&status);

	dev_dbg(&port->dev, "read status %04x\n", status);

	*state = ((status & KL5KUSB105A_DSR) ? TIOCM_DSR : 0) |
		 ((status & KL5KUSB105A_CTS) ? TIOCM_CTS : 0);

	return 0;
}


/*
 * Driver's tty interface functions
 */

static int klsi_105_port_probe(struct usb_serial_port *port)
{

Annotation

Implementation Notes