drivers/tty/ipwireless/tty.c

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

File Facts

System
Linux kernel
Corpus path
drivers/tty/ipwireless/tty.c
Extension
.c
Size
14073 bytes
Lines
628
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

struct ipw_tty {
	struct tty_port port;
	int index;
	struct ipw_hardware *hardware;
	unsigned int channel_idx;
	unsigned int secondary_channel_idx;
	int tty_type;
	struct ipw_network *network;
	unsigned int control_lines;
	struct mutex ipw_tty_mutex;
	int tx_bytes_queued;
};

static struct ipw_tty *ttys[IPWIRELESS_PCMCIA_MINORS];

static struct tty_driver *ipw_tty_driver;

static char *tty_type_name(int tty_type)
{
	static char *channel_names[] = {
		"modem",
		"monitor",
		"RAS-raw"
	};

	return channel_names[tty_type];
}

static struct ipw_tty *get_tty(int index)
{
	/*
	 * The 'ras_raw' channel is only available when 'loopback' mode
	 * is enabled.
	 * Number of minor starts with 16 (_RANGE * _RAS_RAW).
	 */
	if (!ipwireless_loopback && index >=
			 IPWIRELESS_PCMCIA_MINOR_RANGE * TTYTYPE_RAS_RAW)
		return NULL;

	return ttys[index];
}

static int ipw_open(struct tty_struct *linux_tty, struct file *filp)
{
	struct ipw_tty *tty = get_tty(linux_tty->index);

	if (!tty)
		return -ENODEV;

	mutex_lock(&tty->ipw_tty_mutex);
	if (tty->port.count == 0)
		tty->tx_bytes_queued = 0;

	tty->port.count++;

	tty->port.tty = linux_tty;
	linux_tty->driver_data = tty;

	if (tty->tty_type == TTYTYPE_MODEM)
		ipwireless_ppp_open(tty->network);

	mutex_unlock(&tty->ipw_tty_mutex);

	return 0;
}

static void do_ipw_close(struct ipw_tty *tty)
{
	tty->port.count--;

	if (tty->port.count == 0) {
		struct tty_struct *linux_tty = tty->port.tty;

		if (linux_tty != NULL) {
			tty->port.tty = NULL;
			linux_tty->driver_data = NULL;

			if (tty->tty_type == TTYTYPE_MODEM)
				ipwireless_ppp_close(tty->network);
		}
	}
}

static void ipw_hangup(struct tty_struct *linux_tty)
{
	struct ipw_tty *tty = linux_tty->driver_data;

	if (!tty)
		return;

Annotation

Implementation Notes