diff options
-rw-r--r-- | drivers/acpi/bus.c | 16 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 35 | ||||
-rw-r--r-- | drivers/pnp/pnpacpi/core.c | 6 |
3 files changed, 38 insertions, 19 deletions
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 945cd2f2807d..e9b116d2b56d 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -112,21 +112,21 @@ int acpi_bus_get_status(struct acpi_device *device) | |||
112 | } | 112 | } |
113 | 113 | ||
114 | /* | 114 | /* |
115 | * Otherwise we assume the status of our parent (unless we don't | 115 | * According to ACPI spec some device can be present and functional |
116 | * have one, in which case status is implied). | 116 | * even if the parent is not present but functional. |
117 | * In such conditions the child device should not inherit the status | ||
118 | * from the parent. | ||
117 | */ | 119 | */ |
118 | else if (device->parent) | ||
119 | device->status = device->parent->status; | ||
120 | else | 120 | else |
121 | STRUCT_TO_INT(device->status) = | 121 | STRUCT_TO_INT(device->status) = |
122 | ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | | 122 | ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | |
123 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; | 123 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING; |
124 | 124 | ||
125 | if (device->status.functional && !device->status.present) { | 125 | if (device->status.functional && !device->status.present) { |
126 | printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: " | 126 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: " |
127 | "functional but not present; setting present\n", | 127 | "functional but not present;\n", |
128 | device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status)); | 128 | device->pnp.bus_id, |
129 | device->status.present = 1; | 129 | (u32) STRUCT_TO_INT(device->status))); |
130 | } | 130 | } |
131 | 131 | ||
132 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", | 132 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n", |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index ad0679843bd5..89c112ef9e14 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device, | |||
276 | { | 276 | { |
277 | const struct acpi_device_id *id; | 277 | const struct acpi_device_id *id; |
278 | 278 | ||
279 | /* | ||
280 | * If the device is not present, it is unnecessary to load device | ||
281 | * driver for it. | ||
282 | */ | ||
283 | if (!device->status.present) | ||
284 | return -ENODEV; | ||
285 | |||
279 | if (device->flags.hardware_id) { | 286 | if (device->flags.hardware_id) { |
280 | for (id = ids; id->id[0]; id++) { | 287 | for (id = ids; id->id[0]; id++) { |
281 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) | 288 | if (!strcmp((char*)id->id, device->pnp.hardware_id)) |
@@ -1222,15 +1229,18 @@ acpi_add_single_object(struct acpi_device **child, | |||
1222 | result = -ENODEV; | 1229 | result = -ENODEV; |
1223 | goto end; | 1230 | goto end; |
1224 | } | 1231 | } |
1225 | if (!device->status.present) { | 1232 | /* |
1226 | /* Bay and dock should be handled even if absent */ | 1233 | * When the device is neither present nor functional, the |
1227 | if (!ACPI_SUCCESS( | 1234 | * device should not be added to Linux ACPI device tree. |
1228 | acpi_is_child_device(device, acpi_bay_match)) && | 1235 | * When the status of the device is not present but functinal, |
1229 | !ACPI_SUCCESS( | 1236 | * it should be added to Linux ACPI tree. For example : bay |
1230 | acpi_is_child_device(device, acpi_dock_match))) { | 1237 | * device , dock device. |
1231 | result = -ENODEV; | 1238 | * In such conditions it is unncessary to check whether it is |
1232 | goto end; | 1239 | * bay device or dock device. |
1233 | } | 1240 | */ |
1241 | if (!device->status.present && !device->status.functional) { | ||
1242 | result = -ENODEV; | ||
1243 | goto end; | ||
1234 | } | 1244 | } |
1235 | break; | 1245 | break; |
1236 | default: | 1246 | default: |
@@ -1411,7 +1421,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops) | |||
1411 | * TBD: Need notifications and other detection mechanisms | 1421 | * TBD: Need notifications and other detection mechanisms |
1412 | * in place before we can fully implement this. | 1422 | * in place before we can fully implement this. |
1413 | */ | 1423 | */ |
1414 | if (child->status.present) { | 1424 | /* |
1425 | * When the device is not present but functional, it is also | ||
1426 | * necessary to scan the children of this device. | ||
1427 | */ | ||
1428 | if (child->status.present || (!child->status.present && | ||
1429 | child->status.functional)) { | ||
1415 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, | 1430 | status = acpi_get_next_object(ACPI_TYPE_ANY, chandle, |
1416 | NULL, NULL); | 1431 | NULL, NULL); |
1417 | if (ACPI_SUCCESS(status)) { | 1432 | if (ACPI_SUCCESS(status)) { |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index c1b9ea34977b..98b9df7776e9 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device) | |||
148 | acpi_status status; | 148 | acpi_status status; |
149 | struct pnp_dev *dev; | 149 | struct pnp_dev *dev; |
150 | 150 | ||
151 | /* | ||
152 | * If a PnPacpi device is not present , the device | ||
153 | * driver should not be loaded. | ||
154 | */ | ||
151 | status = acpi_get_handle(device->handle, "_CRS", &temp); | 155 | status = acpi_get_handle(device->handle, "_CRS", &temp); |
152 | if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || | 156 | if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || |
153 | is_exclusive_device(device)) | 157 | is_exclusive_device(device) || (!device->status.present)) |
154 | return 0; | 158 | return 0; |
155 | 159 | ||
156 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); | 160 | dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); |