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.
- 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/stddef.hlinux/module.hlinux/io.hlinux/ioport.hlinux/init.hlinux/gameport.hlinux/slab.hlinux/delay.hlinux/workqueue.hlinux/sched.hlinux/mutex.hlinux/timekeeping.hlinux/i8253.h
Detected Declarations
struct gameport_eventenum gameport_event_typefunction get_time_pitfunction gameport_measure_speedfunction old_gameport_measure_speedfunction gameport_start_pollingfunction gameport_stop_pollingfunction gameport_run_poll_handlerfunction gameport_bind_driverfunction gameport_find_driverfunction gameport_free_eventfunction gameport_remove_duplicate_eventsfunction list_for_each_entry_safefunction gameport_handle_eventsfunction gameport_queue_eventfunction gameport_remove_pending_eventsfunction list_for_each_entry_safefunction portfunction list_for_each_entryfunction gameport_description_showfunction drvctl_storefunction gameport_release_portfunction gameport_set_physfunction gameport_default_triggerfunction gameport_default_readfunction gameport_setup_default_handlersfunction gameport_init_portfunction gameport_add_portfunction gameport_destroy_portfunction childrenfunction gameport_disconnect_portfunction __gameport_register_portfunction gameport_unregister_portfunction description_showfunction gameport_driver_probefunction gameport_driver_removefunction gameport_attach_driverfunction __gameport_register_driverfunction gameport_unregister_driverfunction gameport_bus_matchfunction gameport_set_drvfunction gameport_openfunction gameport_closefunction gameport_initfunction gameport_exitmodule init gameport_initexport gameport_start_pollingexport gameport_stop_polling
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
- Immediate include surface: `linux/export.h`, `linux/stddef.h`, `linux/module.h`, `linux/io.h`, `linux/ioport.h`, `linux/init.h`, `linux/gameport.h`, `linux/slab.h`.
- Detected declarations: `struct gameport_event`, `enum gameport_event_type`, `function get_time_pit`, `function gameport_measure_speed`, `function old_gameport_measure_speed`, `function gameport_start_polling`, `function gameport_stop_polling`, `function gameport_run_poll_handler`, `function gameport_bind_driver`, `function gameport_find_driver`.
- Atlas domain: Driver Families / drivers/input.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.