Documentation/driver-api/eisa.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

EISA bus support

EISA bus/root/driver 구조, device ID·resource API, kernel parameter와 비동기 probing을 설명합니다.

Source pathDocumentation/driver-api/eisa.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

eisa.rst:1-230

새 EISA API는 card detection과 I/O resource 할당을 generic bus core로 옮기고, platform별 root driver가 hardware bridge를 등록하며 개별 driver는 ID table과 probe/remove callback에 집중하게 합니다.

전환의 핵심은 ISA와 공유하던 legacy probing code를 조심스럽게 분리하고, `eisa_driver_register()` 반환과 실제 device discovery가 동기화되어 있다고 가정하지 않는 것입니다. device는 boot 후반의 root bus probing 뒤 hotplug model로 bind될 수 있습니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 ================
2 EISA bus support
3 ================
4
5 :Author: Marc Zyngier <[email protected]>
6
7 This document groups random notes about porting EISA drivers to the
8 new EISA/sysfs API.
9
10 Starting from version 2.5.59, the EISA bus is almost given the same
11 status as other much more mainstream buses such as PCI or USB. This
12 has been possible through sysfs, which defines a nice enough set of
13 abstractions to manage buses, devices and drivers.
14
15 Although the new API is quite simple to use, converting existing
16 drivers to the new infrastructure is not an easy task (mostly because
17 detection code is generally also used to probe ISA cards). Moreover,
18 most EISA drivers are among the oldest Linux drivers so, as you can
19 imagine, some dust has settled here over the years.
20
21 The EISA infrastructure is made up of three parts:
22
23 - The bus code implements most of the generic code. It is shared
24 among all the architectures that the EISA code runs on. It
25 implements bus probing (detecting EISA cards available on the bus),
26 allocates I/O resources, allows fancy naming through sysfs, and
27 offers interfaces for driver to register.
28
29 - The bus root driver implements the glue between the bus hardware
30 and the generic bus code. It is responsible for discovering the
31 device implementing the bus, and setting it up to be latter probed
32 by the bus code. This can go from something as simple as reserving
33 an I/O region on x86, to the rather more complex, like the hppa
34 EISA code. This is the part to implement in order to have EISA
35 running on an "new" platform.
36
37 - The driver offers the bus a list of devices that it manages, and
38 implements the necessary callbacks to probe and release devices
39 whenever told to.
40
41 Every function/structure below lives in <linux/eisa.h>, which depends
42 heavily on <linux/device.h>.
43
44 Bus root driver
45 ===============
46
47 ::
48
49 int eisa_root_register (struct eisa_root_device *root);
50
51 The eisa_root_register function is used to declare a device as the
52 root of an EISA bus. The eisa_root_device structure holds a reference
53 to this device, as well as some parameters for probing purposes::
54
55 struct eisa_root_device {
56 struct device *dev; /* Pointer to bridge device */
57 struct resource *res;
58 unsigned long bus_base_addr;
59 int slots; /* Max slot number */
60 int force_probe; /* Probe even when no slot 0 */
61 u64 dma_mask; /* from bridge device */
62 int bus_nr; /* Set by eisa_root_register */
63 struct resource eisa_root_res; /* ditto */
64 };
65
66 ============= ======================================================
67 node used for eisa_root_register internal purpose
68 dev pointer to the root device
69 res root device I/O resource
70 bus_base_addr slot 0 address on this bus
71 slots max slot number to probe
72 force_probe Probe even when slot 0 is empty (no EISA mainboard)
73 dma_mask Default DMA mask. Usually the bridge device dma_mask.
74 bus_nr unique bus id, set by eisa_root_register
75 ============= ======================================================
76
77 Driver
78 ======
79
80 ::
81
82 int eisa_driver_register (struct eisa_driver *edrv);
83 void eisa_driver_unregister (struct eisa_driver *edrv);
84
85 Clear enough ?
86
87 ::
88
89 struct eisa_device_id {
90 char sig[EISA_SIG_LEN];
91 unsigned long driver_data;
92 };
93
94 struct eisa_driver {
95 const struct eisa_device_id *id_table;
96 struct device_driver driver;
97 };
98
99 =============== ====================================================
100 id_table an array of NULL terminated EISA id strings,
101 followed by an empty string. Each string can
102 optionally be paired with a driver-dependent value
103 (driver_data).
104
105 driver a generic driver, such as described in
106 Documentation/driver-api/driver-model/driver.rst. Only .name,
107 .probe and .remove members are mandatory.
108 =============== ====================================================
109
110 An example is the 3c59x driver::
111
112 static struct eisa_device_id vortex_eisa_ids[] = {
113 { "TCM5920", EISA_3C592_OFFSET },
114 { "TCM5970", EISA_3C597_OFFSET },
115 { "" }
116 };
117
118 static struct eisa_driver vortex_eisa_driver = {
119 .id_table = vortex_eisa_ids,
120 .driver = {
121 .name = "3c59x",
122 .probe = vortex_eisa_probe,
123 .remove = vortex_eisa_remove
124 }
125 };
126
127 Device
128 ======
129
130 The sysfs framework calls .probe and .remove functions upon device
131 discovery and removal (note that the .remove function is only called
132 when driver is built as a module).
133
134 Both functions are passed a pointer to a 'struct device', which is
135 encapsulated in a 'struct eisa_device' described as follows::
136
137 struct eisa_device {
138 struct eisa_device_id id;
139 int slot;
140 int state;
141 unsigned long base_addr;
142 struct resource res[EISA_MAX_RESOURCES];
143 u64 dma_mask;
144 struct device dev; /* generic device */
145 };
146
147 ======== ============================================================
148 id EISA id, as read from device. id.driver_data is set from the
149 matching driver EISA id.
150 slot slot number which the device was detected on
151 state set of flags indicating the state of the device. Current
152 flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
153 res set of four 256 bytes I/O regions allocated to this device
154 dma_mask DMA mask set from the parent device.
155 dev generic device (see Documentation/driver-api/driver-model/device.rst)
156 ======== ============================================================
157
158 You can get the 'struct eisa_device' from 'struct device' using the
159 'to_eisa_device' macro.
160
161 Misc stuff
162 ==========
163
164 ::
165
166 void eisa_set_drvdata (struct eisa_device *edev, void *data);
167
168 Stores data into the device's driver_data area.
169
170 ::
171
172 void *eisa_get_drvdata (struct eisa_device *edev):
173
174 Gets the pointer previously stored into the device's driver_data area.
175
176 ::
177
178 int eisa_get_region_index (void *addr);
179
180 Returns the region number (0 <= x < EISA_MAX_RESOURCES) of a given
181 address.
182
183 Kernel parameters
184 =================
185
186 eisa_bus.enable_dev
187 A comma-separated list of slots to be enabled, even if the firmware
188 set the card as disabled. The driver must be able to properly
189 initialize the device in such conditions.
190
191 eisa_bus.disable_dev
192 A comma-separated list of slots to be disabled, even if the firmware
193 set the card as enabled. The driver won't be called to handle this
194 device.
195
196 virtual_root.force_probe
197 Force the probing code to probe EISA slots even when it cannot find an
198 EISA compliant mainboard (nothing appears on slot 0). Defaults to 0
199 (don't force), and set to 1 (force probing) when
200 CONFIG_EISA_VLB_PRIMING is set.
201
202 Random notes
203 ============
204
205 Converting an EISA driver to the new API mostly involves *deleting*
206 code (since probing is now in the core EISA code). Unfortunately, most
207 drivers share their probing routine between ISA, and EISA. Special
208 care must be taken when ripping out the EISA code, so other buses
209 won't suffer from these surgical strikes...
210
211 You *must not* expect any EISA device to be detected when returning
212 from eisa_driver_register, since the chances are that the bus has not
213 yet been probed. In fact, that's what happens most of the time (the
214 bus root driver usually kicks in rather late in the boot process).
215 Unfortunately, most drivers are doing the probing by themselves, and
216 expect to have explored the whole machine when they exit their probe
217 routine.
218
219 For example, switching your favorite EISA SCSI card to the "hotplug"
220 model is "the right thing"(tm).
221
222 Thanks
223 ======
224
225 I'd like to thank the following people for their help:
226
227 - Xavier Benigni for lending me a wonderful Alpha Jensen,
228 - James Bottomley, Jeff Garzik for getting this stuff into the kernel,
229 - Andries Brouwer for contributing numerous EISA ids,
230 - Catrin Jones for coping with far too many machines at home.
231

3. 한국어 전문 번역

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

EISA/sysfs API 개요

1-43

문서 제목은 `EISA bus support`이며 저자는 Marc Zyngier `<[email protected]>`입니다. 기존 EISA driver를 새 EISA/sysfs API로 porting할 때 필요한 여러 note를 모았습니다.

kernel 2.5.59부터 EISA bus는 PCI나 USB 같은 mainstream bus와 거의 같은 지위를 갖게 되었습니다. sysfs가 bus, device, driver를 관리하는 충분한 abstraction을 정의한 덕분입니다.

새 API 자체는 단순하지만 기존 driver 전환은 쉽지 않습니다. detection code를 ISA card probing에도 함께 사용하는 경우가 많고, EISA driver 대부분이 오래된 Linux driver라 누적된 legacy code가 많기 때문입니다.

EISA infrastructure는 세 부분으로 구성됩니다.

  • `bus code`: EISA가 동작하는 모든 architecture가 공유하는 generic code입니다. bus probing으로 사용 가능한 EISA card를 검출하고, I/O resource를 할당하며, sysfs를 통한 이름 지정과 driver registration interface를 제공합니다.
  • `bus root driver`: bus hardware와 generic bus code를 잇는 glue입니다. bus를 구현하는 device를 찾고 generic bus code가 나중에 probe할 수 있도록 setup합니다. x86의 단순한 I/O region reserve부터 hppa EISA의 복잡한 처리까지 platform마다 다르며, 새 platform에서 EISA를 지원하려면 이 부분을 구현합니다.
  • `driver`: 자신이 관리하는 device 목록을 bus에 제공하고, 요청받을 때 device를 probe하고 release하는 callback을 구현합니다.

아래 모든 function과 structure는 `<linux/eisa.h>`에 있으며 이 header는 `<linux/device.h>`에 크게 의존합니다.

EISA infrastructure 역할
구성 요소책임platform 의존성
Bus codecard 검출, I/O 할당, sysfs, driver APIarchitecture 간 공유
Bus root driverbus device 발견과 root setupx86/hppa 등 platform별 구현
EISA driverID 목록, probe/remove callback지원 device별 구현

generic bus, platform glue와 device driver의 책임을 구분했습니다.

Bus root driver

44-76

`eisa_root_register()`는 device를 EISA bus의 root로 선언합니다.

int eisa_root_register (struct eisa_root_device *root);

`struct eisa_root_device`는 bridge/root device reference와 probing에 필요한 parameter를 보관합니다.

struct eisa_root_device {
        struct device   *dev;         /* Pointer to bridge device */
        struct resource *res;
        unsigned long    bus_base_addr;
        int                 slots;  /* Max slot number */
        int                 force_probe; /* Probe even when no slot 0 */
        u64                 dma_mask; /* from bridge device */
        int              bus_nr; /* Set by eisa_root_register */
        struct resource  eisa_root_res;        /* ditto */
};

원문의 field 설명 표는 다음과 같습니다. `node`는 `eisa_root_register` 내부 용도이고, `dev`는 root device pointer, `res`는 root I/O resource, `bus_base_addr`는 해당 bus의 slot 0 address입니다. `slots`는 probe할 최대 slot number, `force_probe`는 slot 0이 비어 있어 EISA mainboard가 보이지 않아도 probe할지 여부입니다. `dma_mask`는 보통 bridge device에서 가져온 기본 DMA mask이고 `bus_nr`는 register 함수가 설정하는 unique bus ID입니다.

============= ======================================================
node          used for eisa_root_register internal purpose
dev           pointer to the root device
res           root device I/O resource
bus_base_addr slot 0 address on this bus
slots              max slot number to probe
force_probe   Probe even when slot 0 is empty (no EISA mainboard)
dma_mask      Default DMA mask. Usually the bridge device dma_mask.
bus_nr              unique bus id, set by eisa_root_register
============= ======================================================

structure의 `eisa_root_res` 역시 `eisa_root_register()`가 설정하는 root resource입니다.

eisa_root_device field
Field입력/출력의미
dev입력bridge/root device pointer
res입력root device I/O resource
bus_base_addr입력slot 0 base address
slots입력probe할 최대 slot
force_probe입력slot 0이 없어도 probe
dma_mask입력bridge에서 가져온 기본 DMA mask
bus_nr출력unique bus ID
eisa_root_res출력등록된 EISA root resource

bridge reference, probing 범위와 register 결과를 구분했습니다.

EISA driver 등록과 ID table

77-126

EISA driver는 다음 API로 등록하고 unregister합니다.

int eisa_driver_register (struct eisa_driver *edrv);
void eisa_driver_unregister (struct eisa_driver *edrv);

`struct eisa_device_id`는 길이 `EISA_SIG_LEN`인 signature와 driver-specific `driver_data`를 가집니다. `struct eisa_driver`는 ID table과 generic `struct device_driver`를 포함합니다.

struct eisa_device_id {
        char sig[EISA_SIG_LEN];
        unsigned long driver_data;
};

struct eisa_driver {
        const struct eisa_device_id *id_table;
        struct device_driver         driver;
};

`id_table`은 NULL-terminated EISA ID string array이며 마지막에는 empty string entry가 옵니다. 각 string에는 선택적으로 driver-dependent value인 `driver_data`를 짝지을 수 있습니다.

`driver`는 `Documentation/driver-api/driver-model/driver.rst`가 설명하는 generic driver입니다. `.name`, `.probe`, `.remove` member만 필수입니다.

=============== ====================================================
id_table        an array of NULL terminated EISA id strings,
                followed by an empty string. Each string can
                optionally be paired with a driver-dependent value
                (driver_data).

driver                a generic driver, such as described in
                Documentation/driver-api/driver-model/driver.rst. Only .name,
                .probe and .remove members are mandatory.
=============== ====================================================

3c59x driver 예제는 `TCM5920`, `TCM5970` ID를 offset 값과 연결하고 empty entry로 table을 끝낸 뒤 `3c59x`라는 generic driver name과 probe/remove callback을 설정합니다.

static struct eisa_device_id vortex_eisa_ids[] = {
        { "TCM5920", EISA_3C592_OFFSET },
        { "TCM5970", EISA_3C597_OFFSET },
        { "" }
};

static struct eisa_driver vortex_eisa_driver = {
        .id_table = vortex_eisa_ids,
        .driver   = {
                .name    = "3c59x",
                .probe   = vortex_eisa_probe,
                .remove  = vortex_eisa_remove
        }
};
EISA driver matching과 callback
eisa_driver_register(edrv)bus가 id_table의 EISA signature 비교일치 entry의 driver_data를 device ID에 전달generic driver .probe 호출제거 시 .remove 호출

ID table 등록에서 generic callback 호출까지의 흐름입니다.

EISA device 표현

127-160

sysfs framework는 device를 발견하거나 제거할 때 `.probe`와 `.remove`를 호출합니다. `.remove`는 driver를 module로 build한 경우에만 호출된다는 점에 유의해야 합니다.

두 callback은 `struct device` pointer를 받으며, 이 generic device는 다음 `struct eisa_device` 안에 포함됩니다.

struct eisa_device {
        struct eisa_device_id id;
        int                   slot;
        int                   state;
        unsigned long         base_addr;
        struct resource       res[EISA_MAX_RESOURCES];
        u64                   dma_mask;
        struct device         dev; /* generic device */
};

`id`는 device에서 읽은 EISA ID이고 `id.driver_data`는 matching driver의 EISA ID entry에서 설정됩니다. `slot`은 device를 발견한 slot number입니다. `state`는 device 상태 flag 집합이며 현재 `EISA_CONFIG_ENABLED`와 `EISA_CONFIG_FORCED`가 있습니다.

`res`는 device에 할당된 256byte I/O region 네 개의 집합이고 `dma_mask`는 parent device에서 가져옵니다. `dev`는 `Documentation/driver-api/driver-model/device.rst`가 설명하는 generic device입니다.

======== ============================================================
id         EISA id, as read from device. id.driver_data is set from the
         matching driver EISA id.
slot         slot number which the device was detected on
state    set of flags indicating the state of the device. Current
         flags are EISA_CONFIG_ENABLED and EISA_CONFIG_FORCED.
res         set of four 256 bytes I/O regions allocated to this device
dma_mask DMA mask set from the parent device.
dev         generic device (see Documentation/driver-api/driver-model/device.rst)
======== ============================================================

generic `struct device`에서 enclosing `struct eisa_device`를 얻을 때는 `to_eisa_device` macro를 사용합니다.

eisa_device state와 resource
Field내용출처
idsignature + driver_datadevice와 matching ID
slot검출 slot numberbus probing
stateENABLED/FORCED flagsfirmware·kernel parameter
base_addrdevice base addressslot/resource
res[4]각 256byte I/O regionbus resource allocation
dma_maskDMA address maskparent device
devgeneric struct devicedriver model

bus에서 검출한 identity, resource와 generic device 연결입니다.

Driver data와 region helper

161-182

`eisa_set_drvdata()`는 device의 `driver_data` area에 caller data를 저장합니다.

void eisa_set_drvdata (struct eisa_device *edev, void *data);

`eisa_get_drvdata()`는 앞서 device의 `driver_data` area에 저장한 pointer를 반환합니다. 원문의 declaration 끝에 있는 colon 표기를 그대로 보존했습니다.

void *eisa_get_drvdata (struct eisa_device *edev):

`eisa_get_region_index()`는 주어진 address가 속한 region number를 반환하며 범위는 `0 <= x < EISA_MAX_RESOURCES`입니다.

int eisa_get_region_index (void *addr);
EISA convenience helper
Helper동작결과
eisa_set_drvdatadriver-private pointer 저장device driver_data 갱신
eisa_get_drvdata저장된 pointer 조회void pointer 반환
eisa_get_region_indexaddress의 I/O region 검색0..EISA_MAX_RESOURCES-1

driver-private data와 resource index 접근 API입니다.

Kernel parameter

183-201

`eisa_bus.enable_dev`는 firmware가 disabled로 표시했어도 강제로 enable할 slot의 comma-separated list입니다. 이 조건에서도 driver가 device를 올바르게 initialize할 수 있어야 합니다.

`eisa_bus.disable_dev`는 firmware가 enabled로 표시했어도 disable할 slot의 comma-separated list입니다. 해당 device를 처리하도록 driver를 호출하지 않습니다.

`virtual_root.force_probe`는 EISA-compliant mainboard를 찾지 못해 slot 0에 아무것도 나타나지 않아도 EISA slot을 probe하도록 강제합니다. 기본값은 0으로 강제하지 않으며 `CONFIG_EISA_VLB_PRIMING`을 설정하면 1, 즉 force probing이 됩니다.

EISA kernel parameter
Parameter효과
eisa_bus.enable_devcomma-separated slotsfirmware disabled device 강제 enable
eisa_bus.disable_devcomma-separated slotsfirmware enabled device 강제 disable
virtual_root.force_probe0 또는 1slot 0이 없어도 probing

firmware 상태 override와 virtual root probing을 정리했습니다.

Driver porting과 probe 시점 주의

202-221

EISA driver를 새 API로 바꾸는 작업은 probing이 core EISA code로 이동했으므로 대체로 code를 삭제하는 일입니다. 하지만 대부분 driver가 ISA와 EISA 사이에 probing routine을 공유하므로 EISA code를 제거할 때 다른 bus 경로를 손상하지 않도록 특별히 주의해야 합니다.

`eisa_driver_register()`가 반환할 때 EISA device가 이미 검출되었을 것이라고 절대 기대하면 안 됩니다. bus가 아직 probe되지 않았을 가능성이 크고, bus root driver는 보통 boot process의 상당히 늦은 시점에 동작합니다.

기존 driver 대부분은 직접 probing하며 probe routine을 빠져나올 때 machine 전체를 탐색했다고 가정합니다. 이러한 전제를 버리고 EISA SCSI card 같은 device를 hotplug model로 전환하는 것이 올바른 방향입니다.

EISA 등록과 늦은 bus probing
eisa_driver_register() 호출driver object 등록 후 함수 반환boot 후반에 bus root driver 시작 가능EISA bus probing과 device discoveryID match 뒤 driver .probe 호출

driver 등록 반환과 실제 device discovery가 분리될 수 있음을 보여줍니다.

감사

222-230

저자는 도움을 준 다음 사람들에게 감사를 표합니다.

  • 멋진 Alpha Jensen을 빌려준 Xavier Benigni
  • 이 code를 kernel에 넣는 데 기여한 James Bottomley와 Jeff Garzik
  • 많은 EISA ID를 제공한 Andries Brouwer
  • 집의 너무 많은 machine을 감당한 Catrin Jones