From 1a7cd6ddbdcce8a099f0bcbb8179e47aa185216d Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Mon, 14 Sep 2020 10:51:44 -0500 Subject: [PATCH] kernel: device: invert sense of ready bit The device status ready bit replaced the previous hack of clearing the device API pointer when initialization of the device failed. It inadvertently changed the behavior of device_get_binding() when invoked before the device was initialized: previously that succeeded for uninitialized devices, after the change it failed. Multiple driver initializations rely on being able to get a device pointer for something they're going to depend on in their init function, even if that device has not yet been initialized. Although this is wrong, and would cause faults if the device failed to initialize before use, in practice it has been working. It's not feasible to identify all the situations where this has occurred, nor to add code to diagnose such cases without changing the state associated with a device to distinguish initialized from initialization success/failure. Restore the previous behavior until a more holistic solution is developed. Signed-off-by: Peter Bigot --- kernel/device.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/kernel/device.c b/kernel/device.c index 2de2cee61bb..5e71542909e 100644 --- a/kernel/device.c +++ b/kernel/device.c @@ -64,9 +64,9 @@ void z_sys_init_run_level(int32_t level) z_object_init(dev); } - if ((entry->init(dev) == 0) && (dev != NULL)) { - /* Initialization was successful. - * Set the init status bit so device is declared ready. + if ((entry->init(dev) != 0) && (dev != NULL)) { + /* Initialization failed. + * Set the init status bit so device is not declared ready. */ sys_bitfield_set_bit( (mem_addr_t) __device_init_status_start, @@ -122,7 +122,8 @@ size_t z_device_get_all_static(struct device const **devices) bool z_device_ready(const struct device *dev) { - return !!(sys_bitfield_test_bit((mem_addr_t)__device_init_status_start, + /* Set bit indicates device failed initialization */ + return !(sys_bitfield_test_bit((mem_addr_t)__device_init_status_start, (dev - __device_start))); }