← Documents Documentation/input/gameport-programming.rst GitHub 원문 ↗

Linux 6.18.37 · Input

Programming gameport drivers

Classic I/O, MMIO와 cooked ADC gameport를 등록하고 callback과 자원을 관리하는 방법입니다.

Source pathDocumentation/input/gameport-programming.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

gameport-programming.rst:1-233

Gameport driver가 raw I/O, MMIO, cooked ADC mode를 제공하는 방식과 `struct gameport`의 callback, calibration, open·close, 등록·해제 생명주기를 설명합니다.

문서 개요
Mode핵심 필드·함수
Classic raw`io`, `gameport_register_port()`
MMIO raw`trigger`, `read`
Cooked ADC`cooked_read`, `open`, `fuzz`
Calibration`calibrate`
Lifecycle`open`, `close`, `gameport_unregister_port()`

Hardware 접근 방식에 따라 설정할 필드를 구분합니다.

Gameport driver 구성
Raw·MMIO·cooked capability 확인주소와 callback 설정Noise·calibration parameter 설정`gameport_register_port()`로 등록`open`·`close`에서 mode와 자원 관리제거 시 `gameport_unregister_port()` 호출

Hardware capability에서 callback과 자원 관리 방식이 결정됩니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 Programming gameport drivers
3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
5 A basic classic gameport
6 ~~~~~~~~~~~~~~~~~~~~~~~~
7
8 If the gameport doesn't provide more than the inb()/outb() functionality,
9 the code needed to register it with the joystick drivers is simple::
10
11 struct gameport gameport;
12
13 gameport.io = MY_IO_ADDRESS;
14 gameport_register_port(&gameport);
15
16 Make sure struct gameport is initialized to 0 in all other fields. The
17 gameport generic code will take care of the rest.
18
19 If your hardware supports more than one io address, and your driver can
20 choose which one to program the hardware to, starting from the more exotic
21 addresses is preferred, because the likelihood of clashing with the standard
22 0x201 address is smaller.
23
24 E.g. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
25 0x218 would be the address of first choice.
26
27 If your hardware supports a gameport address that is not mapped to ISA io
28 space (is above 0x1000), use that one, and don't map the ISA mirror.
29
30 Also, always request_region() on the whole io space occupied by the
31 gameport. Although only one ioport is really used, the gameport usually
32 occupies from one to sixteen addresses in the io space.
33
34 Please also consider enabling the gameport on the card in the ->open()
35 callback if the io is mapped to ISA space - this way it'll occupy the io
36 space only when something really is using it. Disable it again in the
37 ->close() callback. You also can select the io address in the ->open()
38 callback, so that it doesn't fail if some of the possible addresses are
39 already occupied by other gameports.
40
41 Memory mapped gameport
42 ~~~~~~~~~~~~~~~~~~~~~~
43
44 When a gameport can be accessed through MMIO, this way is preferred, because
45 it is faster, allowing more reads per second. Registering such a gameport
46 isn't as easy as a basic IO one, but not so much complex::
47
48 struct gameport gameport;
49
50 void my_trigger(struct gameport *gameport)
51 {
52 my_mmio = 0xff;
53 }
54
55 unsigned char my_read(struct gameport *gameport)
56 {
57 return my_mmio;
58 }
59
60 gameport.read = my_read;
61 gameport.trigger = my_trigger;
62 gameport_register_port(&gameport);
63
64 .. _gameport_pgm_cooked_mode:
65
66 Cooked mode gameport
67 ~~~~~~~~~~~~~~~~~~~~
68
69 There are gameports that can report the axis values as numbers, that means
70 the driver doesn't have to measure them the old way - an ADC is built into
71 the gameport. To register a cooked gameport::
72
73 struct gameport gameport;
74
75 int my_cooked_read(struct gameport *gameport, int *axes, int *buttons)
76 {
77 int i;
78
79 for (i = 0; i < 4; i++)
80 axes[i] = my_mmio[i];
81 buttons[0] = my_mmio[4];
82 }
83
84 int my_open(struct gameport *gameport, int mode)
85 {
86 return -(mode != GAMEPORT_MODE_COOKED);
87 }
88
89 gameport.cooked_read = my_cooked_read;
90 gameport.open = my_open;
91 gameport.fuzz = 8;
92 gameport_register_port(&gameport);
93
94 The only confusing thing here is the fuzz value. Best determined by
95 experimentation, it is the amount of noise in the ADC data. Perfect
96 gameports can set this to zero, most common have fuzz between 8 and 32.
97 See analog.c and input.c for handling of fuzz - the fuzz value determines
98 the size of a gaussian filter window that is used to eliminate the noise
99 in the data.
100
101 More complex gameports
102 ~~~~~~~~~~~~~~~~~~~~~~
103
104 Gameports can support both raw and cooked modes. In that case combine either
105 examples 1+2 or 1+3. Gameports can support internal calibration - see below,
106 and also lightning.c and analog.c on how that works. If your driver supports
107 more than one gameport instance simultaneously, use the ->private member of
108 the gameport struct to point to your data.
109
110 Unregistering a gameport
111 ~~~~~~~~~~~~~~~~~~~~~~~~
112
113 Simple::
114
115 gameport_unregister_port(&gameport);
116
117 The gameport structure
118 ~~~~~~~~~~~~~~~~~~~~~~
119
120 ::
121
122 struct gameport {
123
124 void *port_data;
125
126 A private pointer for free use in the gameport driver. (Not the joystick
127 driver!)
128
129 ::
130
131 char name[32];
132
133 Driver's name as set by driver calling gameport_set_name(). Informational
134 purpose only.
135
136 ::
137
138 char phys[32];
139
140 gameport's physical name/description as set by driver calling gameport_set_phys().
141 Informational purpose only.
142
143 ::
144
145 int io;
146
147 I/O address for use with raw mode. You have to either set this, or ->read()
148 to some value if your gameport supports raw mode.
149
150 ::
151
152 int speed;
153
154 Raw mode speed of the gameport reads in thousands of reads per second.
155
156 ::
157
158 int fuzz;
159
160 If the gameport supports cooked mode, this should be set to a value that
161 represents the amount of noise in the data. See
162 :ref:`gameport_pgm_cooked_mode`.
163
164 ::
165
166 void (*trigger)(struct gameport *);
167
168 Trigger. This function should trigger the ns558 oneshots. If set to NULL,
169 outb(0xff, io) will be used.
170
171 ::
172
173 unsigned char (*read)(struct gameport *);
174
175 Read the buttons and ns558 oneshot bits. If set to NULL, inb(io) will be
176 used instead.
177
178 ::
179
180 int (*cooked_read)(struct gameport *, int *axes, int *buttons);
181
182 If the gameport supports cooked mode, it should point this to its cooked
183 read function. It should fill axes[0..3] with four values of the joystick axes
184 and buttons[0] with four bits representing the buttons.
185
186 ::
187
188 int (*calibrate)(struct gameport *, int *axes, int *max);
189
190 Function for calibrating the ADC hardware. When called, axes[0..3] should be
191 pre-filled by cooked data by the caller, max[0..3] should be pre-filled with
192 expected maximums for each axis. The calibrate() function should set the
193 sensitivity of the ADC hardware so that the maximums fit in its range and
194 recompute the axes[] values to match the new sensitivity or re-read them from
195 the hardware so that they give valid values.
196
197 ::
198
199 int (*open)(struct gameport *, int mode);
200
201 Open() serves two purposes. First a driver either opens the port in raw or
202 in cooked mode, the open() callback can decide which modes are supported.
203 Second, resource allocation can happen here. The port can also be enabled
204 here. Prior to this call, other fields of the gameport struct (namely the io
205 member) need not to be valid.
206
207 ::
208
209 void (*close)(struct gameport *);
210
211 Close() should free the resources allocated by open, possibly disabling the
212 gameport.
213
214 ::
215
216 struct timer_list poll_timer;
217 unsigned int poll_interval; /* in msecs */
218 spinlock_t timer_lock;
219 unsigned int poll_cnt;
220 void (*poll_handler)(struct gameport *);
221 struct gameport *parent, *child;
222 struct gameport_driver *drv;
223 struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */
224 struct device dev;
225 struct list_head node;
226
227 For internal use by the gameport layer.
228
229 ::
230
231 };
232
233 Enjoy!
234

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

기본 classic gameport 등록과 I/O 자원

1-40

Gameport가 `inb()`와 `outb()` 기능만 제공한다면 `struct gameport`를 0으로 초기화하고 `io`에 주소를 넣은 뒤 `gameport_register_port()`를 호출하면 됩니다. 나머지는 generic gameport code가 처리합니다.

기본 gameport 등록
단계코드 또는 규칙
구조체`struct gameport gameport`를 0으로 초기화
주소`gameport.io = MY_IO_ADDRESS`
등록`gameport_register_port(&gameport)`
나머지 필드0 유지, generic code가 처리

Classic I/O port 방식에 필요한 최소 설정입니다.

Hardware가 여러 I/O 주소를 지원하고 driver가 선택할 수 있다면 표준 `0x201`과 충돌할 가능성이 낮은 비표준 주소부터 시도합니다. 예를 들어 `0x200`, `0x208`, `0x210`, `0x218`을 지원하면 `0x218`을 첫 선택으로 삼습니다.

ISA I/O 공간에 매핑되지 않은 `0x1000` 초과 주소를 지원하면 그 주소를 사용하고 ISA mirror는 매핑하지 않습니다. 실제로 한 I/O port만 읽더라도 gameport가 1~16개 주소를 점유할 수 있으므로 전체 범위에 `request_region()`을 호출해야 합니다.

ISA 공간의 gameport는 `->open()`에서 card 기능을 켜 실제 사용 중일 때만 I/O 공간을 점유하고 `->close()`에서 다시 끄는 방식을 고려합니다. `->open()`에서 후보 주소를 선택하면 일부 주소가 다른 gameport에 점유돼도 다른 주소로 열 수 있습니다.

Classic gameport 활성화
충돌 가능성이 가장 낮은 지원 주소 선택Gameport 전체 I/O 범위에 `request_region()``->open()`에서 hardware와 선택 주소 활성화사용 중 raw I/O 수행`->close()`에서 hardware 비활성화와 자원 해제

주소 선택부터 사용 종료까지의 자원 생명주기입니다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Programming gameport drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A basic classic gameport
~~~~~~~~~~~~~~~~~~~~~~~~

If the gameport doesn't provide more than the inb()/outb() functionality,
the code needed to register it with the joystick drivers is simple::

        struct gameport gameport;

        gameport.io = MY_IO_ADDRESS;
        gameport_register_port(&gameport);

Make sure struct gameport is initialized to 0 in all other fields. The
gameport generic code will take care of the rest.

If your hardware supports more than one io address, and your driver can
choose which one to program the hardware to, starting from the more exotic
addresses is preferred, because the likelihood of clashing with the standard
0x201 address is smaller.

E.g. if your driver supports addresses 0x200, 0x208, 0x210 and 0x218, then
0x218 would be the address of first choice.

If your hardware supports a gameport address that is not mapped to ISA io
space (is above 0x1000), use that one, and don't map the ISA mirror.

Also, always request_region() on the whole io space occupied by the
gameport. Although only one ioport is really used, the gameport usually
occupies from one to sixteen addresses in the io space.

Please also consider enabling the gameport on the card in the ->open()
callback if the io is mapped to ISA space - this way it'll occupy the io
space only when something really is using it. Disable it again in the
->close() callback. You also can select the io address in the ->open()
callback, so that it doesn't fail if some of the possible addresses are
already occupied by other gameports.

Memory-mapped gameport

41-65

MMIO로 접근할 수 있는 gameport는 초당 더 많은 read가 가능해 더 빠르므로 이 방식을 우선합니다. 기본 I/O 방식보다 callback 설정이 더 필요하지만 `read`와 `trigger`를 제공하면 등록할 수 있습니다.

예제의 `my_trigger()`는 MMIO register에 `0xff`를 써 one-shot 측정을 시작하고, `my_read()`는 register 값을 반환합니다. 두 함수를 `gameport.trigger`와 `gameport.read`에 넣은 뒤 `gameport_register_port()`를 호출합니다.

MMIO callback
필드예제 함수역할
`gameport.trigger``my_trigger()`MMIO에 `0xff`를 써 측정 시작
`gameport.read``my_read()`MMIO의 button·one-shot 값 반환
등록`gameport_register_port()`Gameport core에 port 공개

Port I/O 기본 동작을 memory access 함수로 대체합니다.

MMIO gameport read
Gameport core가 `trigger()` 호출Driver가 MMIO register에 `0xff` 기록Hardware one-shot 진행Core가 `read()` 호출Driver가 현재 MMIO 값을 반환

Trigger와 read callback이 raw port 동작을 대신합니다.

Memory mapped gameport
~~~~~~~~~~~~~~~~~~~~~~

When a gameport can be accessed through MMIO, this way is preferred, because
it is faster, allowing more reads per second. Registering such a gameport
isn't as easy as a basic IO one, but not so much complex::

        struct gameport gameport;

        void my_trigger(struct gameport *gameport)
        {
                my_mmio = 0xff;
        }

        unsigned char my_read(struct gameport *gameport)
        {
                return my_mmio;
        }

        gameport.read = my_read;
        gameport.trigger = my_trigger;
        gameport_register_port(&gameport);

.. _gameport_pgm_cooked_mode:

Cooked mode와 ADC noise

66-100

일부 gameport는 ADC를 내장해 driver가 옛 방식으로 시간을 측정하지 않아도 axis 값을 숫자로 직접 보고합니다. 이런 장치는 `cooked_read` callback에서 `axes[0..3]`과 button bits를 채우고 `open`에서 `GAMEPORT_MODE_COOKED`만 허용합니다.

예제 `my_cooked_read()`는 MMIO의 네 axis 값을 `axes[]`에, button 값을 `buttons[0]`에 넣습니다. `my_open()`은 mode가 cooked가 아니면 오류를 반환합니다. `cooked_read`, `open`, `fuzz`를 설정한 뒤 port를 등록합니다.

Cooked mode 설정
필드설정의미
`cooked_read``my_cooked_read`Axis 네 값과 button bits 반환
`open``my_open``GAMEPORT_MODE_COOKED` 허용
`fuzz`예: 8ADC noise에 맞춘 filter window
등록`gameport_register_port()`Cooked port 공개

ADC 값을 직접 제공하는 gameport의 필수 callback과 보정값입니다.

`fuzz`는 ADC data의 noise 양이며 실험으로 결정하는 것이 가장 좋습니다. 완벽한 gameport는 0, 일반적인 장치는 8~32 정도입니다. `analog.c`와 `input.c`에서처럼 이 값은 noise 제거용 Gaussian filter window 크기를 결정합니다.

Cooked sample 처리
`cooked_read()`에서 네 axis와 button bits 수집`fuzz` 값으로 예상 noise 범위 지정Input layer가 Gaussian filter window 적용Noise가 줄어든 axis 값 생성Joystick driver에 cooked data 전달

ADC sample을 input 값으로 안정화하는 경로입니다.

Cooked mode gameport
~~~~~~~~~~~~~~~~~~~~

There are gameports that can report the axis values as numbers, that means
the driver doesn't have to measure them the old way - an ADC is built into
the gameport. To register a cooked gameport::

        struct gameport gameport;

        int my_cooked_read(struct gameport *gameport, int *axes, int *buttons)
        {
                int i;

                for (i = 0; i < 4; i++)
                        axes[i] = my_mmio[i];
                buttons[0] = my_mmio[4];
        }

        int my_open(struct gameport *gameport, int mode)
        {
                return -(mode != GAMEPORT_MODE_COOKED);
        }

        gameport.cooked_read = my_cooked_read;
        gameport.open = my_open;
        gameport.fuzz = 8;
        gameport_register_port(&gameport);

The only confusing thing here is the fuzz value. Best determined by
experimentation, it is the amount of noise in the ADC data. Perfect
gameports can set this to zero, most common have fuzz between 8 and 32.
See analog.c and input.c for handling of fuzz - the fuzz value determines
the size of a gaussian filter window that is used to eliminate the noise
in the data.

복합 모드, calibration과 등록 해제

101-116

Gameport는 raw와 cooked mode를 함께 지원할 수 있습니다. 이 경우 classic 예제와 MMIO 또는 cooked 예제를 결합합니다. 내부 calibration도 지원할 수 있으며 동작 방식은 아래 설명과 `lightning.c`, `analog.c`를 참고합니다.

Driver가 여러 gameport instance를 동시에 지원하면 각 `struct gameport`의 `->private` 계열 private pointer를 사용해 instance별 data를 연결합니다.

Gameport 등록을 해제할 때는 `gameport_unregister_port(&gameport)`를 호출합니다.

복합 gameport 구성
지원 기능필요 구성
Raw port I/O`io` 또는 `read`·`trigger`
Cooked ADC`cooked_read`, `fuzz`
Raw + cookedClassic + MMIO/cooked 예제 결합
Calibration`calibrate` callback
여러 instance각 port의 private data
해제`gameport_unregister_port()`

지원 기능별로 결합할 요소를 정리했습니다.

Driver 제거
새 open 요청 중단활성 사용자와 poll 작업 정리`gameport_unregister_port(&gameport)` 호출Port와 연결된 driver 관계 해제Driver private 자원 반환

등록한 gameport를 core에서 안전하게 분리합니다.

More complex gameports
~~~~~~~~~~~~~~~~~~~~~~

Gameports can support both raw and cooked modes. In that case combine either
examples 1+2 or 1+3. Gameports can support internal calibration - see below,
and also lightning.c and analog.c on how that works. If your driver supports
more than one gameport instance simultaneously, use the ->private member of
the gameport struct to point to your data.

Unregistering a gameport
~~~~~~~~~~~~~~~~~~~~~~~~

Simple::

    gameport_unregister_port(&gameport);

`struct gameport`의 공개 필드와 callback

117-196

`port_data`는 gameport driver가 자유롭게 사용하는 private pointer이며 joystick driver용이 아닙니다. `name[32]`는 `gameport_set_name()`으로 설정하는 driver 이름, `phys[32]`는 `gameport_set_phys()`로 설정하는 물리적 이름 또는 설명으로 둘 다 정보 제공용입니다.

`io`는 raw mode의 I/O 주소입니다. Raw mode를 지원하려면 `io` 또는 `->read()` 중 하나를 유효하게 설정해야 합니다. `speed`는 초당 천 회 단위로 나타낸 raw read 속도입니다.

`fuzz`는 cooked mode ADC data의 noise 양을 나타냅니다. `trigger` callback은 ns558 one-shot을 시작하며 `NULL`이면 core가 `outb(0xff, io)`를 사용합니다. `read` callback은 button과 ns558 one-shot bits를 읽으며 `NULL`이면 `inb(io)`를 사용합니다.

`cooked_read`는 `axes[0..3]`에 네 joystick axis 값을, `buttons[0]`에 네 button bit를 채웁니다. `calibrate`는 caller가 미리 채운 cooked `axes[0..3]`와 예상 최대값 `max[0..3]`을 받아 ADC sensitivity를 범위에 맞게 조정하고 새 sensitivity에 맞는 유효 axis 값을 다시 계산하거나 읽어야 합니다.

`struct gameport` 주요 필드
필드용도기본 동작 또는 조건
`port_data`Driver private pointerJoystick driver용이 아님
`name[32]`Driver 이름`gameport_set_name()`
`phys[32]`물리 이름·설명`gameport_set_phys()`
`io`Raw I/O 주소`read`가 없으면 필수
`speed`Raw read 속도천 reads/second 단위
`fuzz`Cooked ADC noiseGaussian filter 크기에 영향
`trigger`ns558 one-shot 시작`NULL`이면 `outb(0xff, io)`
`read`Button·one-shot bit 읽기`NULL`이면 `inb(io)`
`cooked_read`네 axis와 button bitsCooked mode에서 설정
`calibrate`ADC sensitivity 보정Axis와 maximum 재계산

Gameport driver가 설정하는 데이터와 callback입니다.

ADC calibration
Caller가 cooked `axes[0..3]` 준비Caller가 예상 `max[0..3]` 준비Driver가 ADC sensitivity 선택예상 maximum이 hardware range에 들어오는지 확인Axis 값을 재계산하거나 hardware에서 다시 읽기

`calibrate()`가 기존 sample과 예상 최대값을 새 sensitivity에 맞춥니다.

The gameport structure
~~~~~~~~~~~~~~~~~~~~~~

::

    struct gameport {

        void *port_data;

A private pointer for free use in the gameport driver. (Not the joystick
driver!)

::

        char name[32];

Driver's name as set by driver calling gameport_set_name(). Informational
purpose only.

::

        char phys[32];

gameport's physical name/description as set by driver calling gameport_set_phys().
Informational purpose only.

::

        int io;

I/O address for use with raw mode. You have to either set this, or ->read()
to some value if your gameport supports raw mode.

::

        int speed;

Raw mode speed of the gameport reads in thousands of reads per second.

::

        int fuzz;

If the gameport supports cooked mode, this should be set to a value that
represents the amount of noise in the data. See
:ref:`gameport_pgm_cooked_mode`.

::

        void (*trigger)(struct gameport *);

Trigger. This function should trigger the ns558 oneshots. If set to NULL,
outb(0xff, io) will be used.

::

        unsigned char (*read)(struct gameport *);

Read the buttons and ns558 oneshot bits. If set to NULL, inb(io) will be
used instead.

::

        int (*cooked_read)(struct gameport *, int *axes, int *buttons);

If the gameport supports cooked mode, it should point this to its cooked
read function. It should fill axes[0..3] with four values of the joystick axes
and buttons[0] with four bits representing the buttons.

::

        int (*calibrate)(struct gameport *, int *axes, int *max);

Function for calibrating the ADC hardware. When called, axes[0..3] should be
pre-filled by cooked data by the caller, max[0..3] should be pre-filled with
expected maximums for each axis. The calibrate() function should set the
sensitivity of the ADC hardware so that the maximums fit in its range and
recompute the axes[] values to match the new sensitivity or re-read them from
the hardware so that they give valid values.

`open`, `close`와 gameport core 내부 필드

197-233

`open(struct gameport *, int mode)`은 두 역할을 합니다. 먼저 raw 또는 cooked mode 요청을 받아 지원 여부를 결정하고, 이어 자원을 할당하거나 port를 활성화할 수 있습니다. 이 호출 전에는 `io`를 포함한 다른 `struct gameport` 필드가 유효하지 않아도 됩니다.

`close(struct gameport *)`는 `open`이 할당한 자원을 해제하고 필요하면 gameport를 비활성화해야 합니다.

Open과 close 계약
Callback입력책임
`open`Gameport와 requested modeMode 지원 판정
`open`Raw 또는 cooked request자원 할당과 port 활성화
`close`Gameport`open` 자원 해제
`close`Gameport필요 시 port 비활성화

Mode 선택과 자원 관리를 callback 경계에 묶습니다.

`poll_timer`, `poll_interval`, `timer_lock`, `poll_cnt`, `poll_handler`, `parent`, `child`, `drv`, `drv_mutex`, `dev`, `node`는 gameport layer 내부에서 사용합니다. Driver는 이 내부 관리 필드를 직접 운용하지 않습니다.

Gameport layer 내부 필드
그룹필드
Polling`poll_timer`, `poll_interval`, `poll_cnt`, `poll_handler`
Synchronization`timer_lock`, `drv_mutex`
Topology`parent`, `child`
Binding`drv`
Device model`dev`, `node`

Polling, 계층 관계, driver binding과 device model 상태를 보관합니다.

Gameport 사용 생명주기
Joystick driver가 raw 또는 cooked mode 요청Core가 gameport `open()` 호출Driver가 mode 확인 후 자원 할당·port 활성화Read 또는 polling callback으로 입력 처리Core가 `close()` 호출Driver가 자원 해제·port 비활성화

Core가 mode를 열고 닫는 동안 driver 자원을 관리합니다.

::

        int (*open)(struct gameport *, int mode);

Open() serves two purposes. First a driver either opens the port in raw or
in cooked mode, the open() callback can decide which modes are supported.
Second, resource allocation can happen here. The port can also be enabled
here. Prior to this call, other fields of the gameport struct (namely the io
member) need not to be valid.

::

        void (*close)(struct gameport *);

Close() should free the resources allocated by open, possibly disabling the
gameport.

::

        struct timer_list poll_timer;
        unsigned int poll_interval;     /* in msecs */
        spinlock_t timer_lock;
        unsigned int poll_cnt;
        void (*poll_handler)(struct gameport *);
        struct gameport *parent, *child;
        struct gameport_driver *drv;
        struct mutex drv_mutex;                /* protects serio->drv so attributes can pin driver */
        struct device dev;
        struct list_head node;

For internal use by the gameport layer.

::

    };

Enjoy!