drivers/input/gameport/gameport.c

Source file repositories/reference/linux-study-clean/drivers/input/gameport/gameport.c

File Facts

System
Linux kernel
Corpus path
drivers/input/gameport/gameport.c
Extension
.c
Size
20969 bytes
Lines
888
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct bus_type gameport_bus;

static void gameport_add_port(struct gameport *gameport);
static void gameport_attach_driver(struct gameport_driver *drv);
static void gameport_reconnect_port(struct gameport *gameport);
static void gameport_disconnect_port(struct gameport *gameport);

#if defined(__i386__)

#include <linux/i8253.h>

#define DELTA(x,y)      ((y)-(x)+((y)<(x)?1193182/HZ:0))
#define GET_TIME(x)     do { x = get_time_pit(); } while (0)

static unsigned int get_time_pit(void)
{
	unsigned long flags;
	unsigned int count;

	raw_spin_lock_irqsave(&i8253_lock, flags);
	outb_p(0x00, 0x43);
	count = inb_p(0x40);
	count |= inb_p(0x40) << 8;
	raw_spin_unlock_irqrestore(&i8253_lock, flags);

	return count;
}

#endif



/*
 * gameport_measure_speed() measures the gameport i/o speed.
 */

static int gameport_measure_speed(struct gameport *gameport)
{
	unsigned int i, t, tx;
	u64 t1, t2, t3;
	unsigned long flags;

	if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
		return 0;

	tx = ~0;

	for (i = 0; i < 50; i++) {
		local_irq_save(flags);
		t1 = ktime_get_ns();
		for (t = 0; t < 50; t++)
			gameport_read(gameport);
		t2 = ktime_get_ns();
		t3 = ktime_get_ns();
		local_irq_restore(flags);
		udelay(i * 10);
		t = (t2 - t1) - (t3 - t2);
		if (t < tx)
			tx = t;
	}

	gameport_close(gameport);
	t = 1000000 * 50;
	if (tx)
		t /= tx;
	return t;
}

static int old_gameport_measure_speed(struct gameport *gameport)
{
#if defined(__i386__)

	unsigned int i, t, t1, t2, t3, tx;
	unsigned long flags;

	if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW))
		return 0;

	tx = 1 << 30;

	for(i = 0; i < 50; i++) {
		local_irq_save(flags);
		GET_TIME(t1);
		for (t = 0; t < 50; t++) gameport_read(gameport);
		GET_TIME(t2);
		GET_TIME(t3);
		local_irq_restore(flags);
		udelay(i * 10);
		if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t;
	}

Annotation

Implementation Notes