drivers/tty/hvc/hvsi_lib.c

Source file repositories/reference/linux-study-clean/drivers/tty/hvc/hvsi_lib.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/hvc/hvsi_lib.c
Extension
.c
Size
9879 bytes
Lines
427
Domain
Driver Families
Bucket
drivers/tty
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

if (!pv->is_console && pv->opened) {
			pr_devel("HVSI@%x Carrier lost, hanging up !\n",
				 pv->termno);
			hvsi_send_close(pv);
		}
	}
}

static void hvsi_got_control(struct hvsi_priv *pv)
{
	struct hvsi_control *pkt = (struct hvsi_control *)pv->inbuf;

	switch (be16_to_cpu(pkt->verb)) {
	case VSV_CLOSE_PROTOCOL:
		/* We restart the handshaking */
		hvsi_start_handshake(pv);
		break;
	case VSV_MODEM_CTL_UPDATE:
		/* Transition of carrier detect */
		hvsi_cd_change(pv, be32_to_cpu(pkt->word) & HVSI_TSCD);
		break;
	}
}

static void hvsi_got_query(struct hvsi_priv *pv)
{
	struct hvsi_query *pkt = (struct hvsi_query *)pv->inbuf;
	struct hvsi_query_response r;

	/* We only handle version queries */
	if (be16_to_cpu(pkt->verb) != VSV_SEND_VERSION_NUMBER)
		return;

	pr_devel("HVSI@%x: Got version query, sending response...\n",
		 pv->termno);

	/* Send version response */
	r.hdr.type = VS_QUERY_RESPONSE_PACKET_HEADER;
	r.hdr.len = sizeof(struct hvsi_query_response);
	r.verb = cpu_to_be16(VSV_SEND_VERSION_NUMBER);
	r.u.version = HVSI_VERSION;
	r.query_seqno = pkt->hdr.seqno;
	hvsi_send_packet(pv, &r.hdr);

	/* Assume protocol is open now */
	pv->established = 1;
}

static void hvsi_got_response(struct hvsi_priv *pv)
{
	struct hvsi_query_response *r =
		(struct hvsi_query_response *)pv->inbuf;

	switch(r->verb) {
	case VSV_SEND_MODEM_CTL_STATUS:
		hvsi_cd_change(pv, be32_to_cpu(r->u.mctrl_word) & HVSI_TSCD);
		pv->mctrl_update = 1;
		break;
	}
}

static int hvsi_check_packet(struct hvsi_priv *pv)
{
	u8 len, type;

	/* Check header validity. If it's invalid, we ditch
	 * the whole buffer and hope we eventually resync
	 */
	if (pv->inbuf[0] < 0xfc) {
		pv->inbuf_len = pv->inbuf_pktlen = 0;
		return 0;
	}
	type = pv->inbuf[0];
	len = pv->inbuf[1];

	/* Packet incomplete ? */
	if (pv->inbuf_len < len)
		return 0;

	pr_devel("HVSI@%x: Got packet type %x len %d bytes:\n",
		 pv->termno, type, len);

	/* We have a packet, yay ! Handle it */
	switch(type) {
	case VS_DATA_PACKET_HEADER:
		pv->inbuf_pktlen = len - 4;
		pv->inbuf_cur = 4;
		return 1;
	case VS_CONTROL_PACKET_HEADER:
		hvsi_got_control(pv);

Annotation

Implementation Notes