요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
==================
ACPI Scan Handlers
==================
:Copyright: |copy| 2012, Intel Corporation
:Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
During system initialization and ACPI-based device hot-add, the ACPI namespace
is scanned in search of device objects that generally represent various pieces
of hardware. This causes a struct acpi_device object to be created and
registered with the driver core for every device object in the ACPI namespace
and the hierarchy of those struct acpi_device objects reflects the namespace
layout (i.e. parent device objects in the namespace are represented by parent
struct acpi_device objects and analogously for their children). Those struct
acpi_device objects are referred to as "device nodes" in what follows, but they
should not be confused with struct device_node objects used by the Device Trees
parsing code (although their role is analogous to the role of those objects).
During ACPI-based device hot-remove device nodes representing pieces of hardware
being removed are unregistered and deleted.
The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic
initialization of device nodes, such as retrieving common configuration
information from the device objects represented by them and populating them with
appropriate data, but some of them require additional handling after they have
been registered. For example, if the given device node represents a PCI host
bridge, its registration should cause the PCI bus under that bridge to be
enumerated and PCI devices on that bus to be registered with the driver core.
Similarly, if the device node represents a PCI interrupt link, it is necessary
to configure that link so that the kernel can use it.
Those additional configuration tasks usually depend on the type of the hardware
component represented by the given device node which can be determined on the
basis of the device node's hardware ID (HID). They are performed by objects
called ACPI scan handlers represented by the following structure::
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
};
where ids is the list of IDs of device nodes the given handler is supposed to
take care of, list_node is the hook to the global list of ACPI scan handlers
maintained by the ACPI core and the .attach() and .detach() callbacks are
executed, respectively, after registration of new device nodes and before
unregistration of device nodes the handler attached to previously.
The namespace scanning function, acpi_bus_scan(), first registers all of the
device nodes in the given namespace scope with the driver core. Then, it tries
to match a scan handler against each of them using the ids arrays of the
available scan handlers. If a matching scan handler is found, its .attach()
callback is executed for the given device node. If that callback returns 1,
that means that the handler has claimed the device node and is now responsible
for carrying out any additional configuration tasks related to it. It also will
be responsible for preparing the device node for unregistration in that case.
The device node's handler field is then populated with the address of the scan
handler that has claimed it.
If the .attach() callback returns 0, it means that the device node is not
interesting to the given scan handler and may be matched against the next scan
handler in the list. If it returns a (negative) error code, that means that
the namespace scan should be terminated due to a serious error. The error code
returned should then reflect the type of the error.
The namespace trimming function, acpi_bus_trim(), first executes .detach()
callbacks from the scan handlers of all device nodes in the given namespace
scope (if they have scan handlers). Next, it unregisters all of the device
nodes in that scope.
ACPI scan handlers can be added to the list maintained by the ACPI core with the
help of the acpi_scan_add_handler() function taking a pointer to the new scan
handler as an argument. The order in which scan handlers are added to the list
is the order in which they are matched against device nodes during namespace
scans.
All scan handles must be added to the list before acpi_bus_scan() is run for the
first time and they cannot be removed from it.
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
ACPI 스캔 핸들러 문서 정보
1-11.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>
이 문서는 ACPI 스캔 핸들러를 설명합니다. 저작권은 2012 Intel Corporation에 있으며, 저자는 Rafael J. Wysocki `<rafael.j.wysocki@intel.com>`입니다.
ACPI 네임스페이스와 장치 노드
12-25시스템 초기화와 ACPI 기반 장치 hot-add 중에는 여러 하드웨어 구성 요소를 나타내는 장치 객체를 찾기 위해 ACPI 네임스페이스를 스캔합니다. 네임스페이스의 각 장치 객체마다 `struct acpi_device` 객체를 만들고 드라이버 코어에 등록합니다.
`struct acpi_device` 객체 계층은 네임스페이스 배치를 반영합니다. 네임스페이스의 부모 장치 객체는 부모 `struct acpi_device`로, 자식 객체도 같은 방식으로 표현합니다.
이하에서는 이 `struct acpi_device` 객체를 `device nodes`라고 부릅니다. 역할은 비슷하지만 Device Tree 구문 분석 코드가 사용하는 `struct device_node` 객체와 혼동해서는 안 됩니다.
ACPI 기반 장치 hot-remove 중에는 제거되는 하드웨어를 나타내는 장치 노드의 등록을 해제하고 삭제합니다.
추가 초기화와 스캔 핸들러 구조체
26-53`drivers/acpi/scan.c`의 핵심 ACPI 네임스페이스 스캔 코드는 장치 객체에서 공통 구성 정보를 읽고 적절한 데이터를 채우는 등 장치 노드의 기본 초기화를 수행합니다. 그러나 일부 장치 노드는 등록 후 추가 처리가 필요합니다.
예를 들어 장치 노드가 PCI 호스트 브리지를 나타내면, 등록할 때 해당 브리지 아래 PCI 버스를 열거하고 그 버스의 PCI 장치를 드라이버 코어에 등록해야 합니다. PCI 인터럽트 링크라면 커널이 사용할 수 있도록 링크를 구성해야 합니다.
이 추가 구성 작업은 보통 장치 노드의 하드웨어 ID(HID)로 판별하는 하드웨어 구성 요소 유형에 따라 달라집니다. 작업은 다음 `struct acpi_scan_handler`로 표현되는 ACPI 스캔 핸들러가 수행합니다.
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
};
`ids`는 핸들러가 담당할 장치 노드 ID 목록이고, `list_node`는 ACPI 코어가 관리하는 전역 ACPI 스캔 핸들러 목록에 연결하는 고리입니다.
`.attach()` 콜백은 새 장치 노드를 등록한 뒤 실행하고, `.detach()` 콜백은 핸들러가 이전에 연결한 장치 노드의 등록을 해제하기 전에 실행합니다.
네임스페이스 스캔과 attach 반환값
54-70네임스페이스 스캔 함수 `acpi_bus_scan()`은 먼저 지정된 네임스페이스 범위의 모든 장치 노드를 드라이버 코어에 등록합니다. 그런 다음 사용 가능한 스캔 핸들러의 `ids` 배열을 사용해 각 장치 노드에 맞는 핸들러를 찾습니다.
일치하는 핸들러를 찾으면 해당 장치 노드에 대해 `.attach()`를 실행합니다. 콜백이 `1`을 반환하면 핸들러가 장치 노드를 인수했음을 뜻하며, 이후 관련 추가 구성과 등록 해제 준비를 담당합니다. 장치 노드의 `handler` 필드에는 이를 인수한 스캔 핸들러 주소가 저장됩니다.
`.attach()`가 `0`을 반환하면 해당 장치 노드는 이 핸들러의 관심 대상이 아니므로 목록의 다음 핸들러와 대조할 수 있습니다. 음수 오류 코드를 반환하면 심각한 오류 때문에 네임스페이스 스캔을 중단해야 하며, 반환 코드는 오류 유형을 나타내야 합니다.
네임스페이스 정리와 핸들러 등록
71-83네임스페이스 정리 함수 `acpi_bus_trim()`은 지정된 범위의 장치 노드가 스캔 핸들러를 갖고 있다면 먼저 모든 `.detach()` 콜백을 실행합니다. 그 다음 범위의 모든 장치 노드 등록을 해제합니다.
`acpi_scan_add_handler()`에 새 스캔 핸들러 포인터를 전달하면 ACPI 코어가 관리하는 목록에 핸들러를 추가할 수 있습니다. 목록에 추가한 순서가 네임스페이스 스캔 중 장치 노드와 대조하는 순서입니다.
모든 스캔 핸들러는 `acpi_bus_scan()`을 처음 실행하기 전에 목록에 추가해야 하며, 일단 추가한 뒤에는 목록에서 제거할 수 없습니다.
요약과 해설
scan_handlers.rst:1-83ACPI 장치 노드 생성과 제거, 스캔 핸들러 구조체, attach 및 detach 처리와 등록 순서를 설명합니다. 영어 원문 전체와 한국어 전문 번역을 함께 제공하며, directive, C 구조체, 함수명, 심볼, 소스 경로와 원문 줄 좌표를 보존합니다.