# 드라이버 초기화: 코드를 등록하는 것과 장치를 찾는 것

v6.6 / drivers/base/driver.c

부팅 중 driver_init은 장치 모델의 공통 기반을 준비합니다. 그 위에서 각 드라이버는 자신이 속한 버스와 연산을 등록하며, 버스는 이미 존재하거나 새로 나타난 장치와 연결을 시도합니다. 아래 driver_register 전체는 개별 드라이버 등록을 설명합니다. 공통 기반을 만드는 초기화 함수와 개별 하드웨어 probe를 같은 단계로 부르지 않는 것이 출발점입니다.

## driver_register

```c

int driver_register(struct device_driver *drv)
{
	int ret;
	struct device_driver *other;

	if (!bus_is_registered(drv->bus)) {
		pr_err("Driver '%s' was unable to register with bus_type '%s' because the bus was not initialized.\n",
			   drv->name, drv->bus->name);
		return -EINVAL;
	}

	if ((drv->bus->probe && drv->probe) ||
	    (drv->bus->remove && drv->remove) ||
	    (drv->bus->shutdown && drv->shutdown))
		pr_warn("Driver '%s' needs updating - please use "
			"bus_type methods\n", drv->name);

	other = driver_find(drv->name, drv->bus);
	if (other) {
		pr_err("Error: Driver '%s' is already registered, "
			"aborting...\n", drv->name);
		return -EBUSY;
	}

	ret = bus_add_driver(drv);
	if (ret)
		return ret;
	ret = driver_add_groups(drv, drv->groups);
	if (ret) {
		bus_remove_driver(drv);
		return ret;
	}
	kobject_uevent(&drv->p->kobj, KOBJ_ADD);
	deferred_probe_extend_timeout();

	return ret;
}

```

### 222행

```c

int driver_register(struct device_driver *drv)

```

등록할 device_driver를 받아 공통 장치 모델에 연결합니다.

### 224행

```c

	int ret;

```

단계별 반환 상태를 저장합니다.

### 225행

```c

	struct device_driver *other;

```

이름이 중복되는 다른 드라이버를 찾을 때 사용할 포인터입니다.

### 227행

```c

	if (!bus_is_registered(drv->bus)) {

```

이 드라이버가 지정한 버스가 먼저 등록됐는지 확인합니다.

### 228행

```c

		pr_err("Driver '%s' was unable to register with bus_type '%s' because the bus was not initialized.\n",

```

버스 기반이 준비되지 않았다는 오류 문구를 출력합니다.

### 229행

```c

			   drv->name, drv->bus->name);

```

어떤 드라이버와 버스 조합이 문제인지 이름을 전달합니다.

### 230행

```c

		return -EINVAL;

```

기반 없는 버스에 드라이버를 등록하지 않고 오류를 반환합니다.

### 233행

```c

	if ((drv->bus->probe && drv->probe) ||

```

버스와 드라이버가 probe 메서드를 동시에 지정한 경우를 검사합니다.

### 234행

```c

	    (drv->bus->remove && drv->remove) ||

```

remove 메서드도 두 곳에 중복 지정됐는지 검사합니다.

### 235행

```c

	    (drv->bus->shutdown && drv->shutdown))

```

shutdown 중복까지 OR로 묶어 하나라도 해당하면 경고합니다.

### 236행

```c

		pr_warn("Driver '%s' needs updating - please use "

```

오래된 메서드 사용 방식을 갱신하라는 경고를 시작합니다.

### 237행

```c

			"bus_type methods\n", drv->name);

```

버스 메서드를 사용하라는 설명과 드라이버 이름을 출력합니다. 경고만 하고 아래 검사는 계속합니다.

### 239행

```c

	other = driver_find(drv->name, drv->bus);

```

동일 버스에 같은 이름의 드라이버가 이미 등록됐는지 찾습니다.

### 240행

```c

	if (other) {

```

중복 드라이버를 찾았는지 확인합니다.

### 241행

```c

		pr_err("Error: Driver '%s' is already registered, "

```

같은 이름으로 이중 등록하려 했다는 오류를 출력합니다.

### 242행

```c

			"aborting...\n", drv->name);

```

문제의 드라이버 이름과 중단 문구를 완성합니다.

### 243행

```c

		return -EBUSY;

```

이름 충돌 때문에 -EBUSY를 반환합니다.

### 246행

```c

	ret = bus_add_driver(drv);

```

드라이버를 버스 관리에 추가합니다. 매칭과 연결 작업은 버스 계층으로 이어집니다.

### 247행

```c

	if (ret)

```

버스 등록 실패를 검사합니다.

### 248행

```c

		return ret;

```

실패했으면 속성 그룹을 추가하지 않고 오류를 반환합니다.

### 249행

```c

	ret = driver_add_groups(drv, drv->groups);

```

드라이버가 제공한 sysfs 속성 그룹을 추가합니다.

### 250행

```c

	if (ret) {

```

속성 그룹 등록에 실패했는지 확인합니다.

### 251행

```c

		bus_remove_driver(drv);

```

부분 등록 상태를 남기지 않도록 앞서 한 버스 등록을 되돌립니다.

### 252행

```c

		return ret;

```

속성 그룹 단계의 오류를 반환합니다.

### 254행

```c

	kobject_uevent(&drv->p->kobj, KOBJ_ADD);

```

드라이버 추가를 KOBJ_ADD 이벤트로 사용자 공간에 알립니다.

### 255행

```c

	deferred_probe_extend_timeout();

```

새 드라이버가 의존 자원을 제공할 수 있으므로 지연된 probe의 시간 정책을 갱신합니다.

### 257행

```c

	return ret;

```

정상 등록 결과를 반환합니다.

