{"record":{"id":"0f2bf0f244265cae","repo":"rust-embedded/rust-raspberrypi-OS-tutorials","slug":"error-during-driver-interrupt-handler-registration","errorCode":null,"errorMessage":"Error during driver interrupt handler registration: {}: {}","messagePattern":"Error during driver interrupt handler registration: (.+?): (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"20_timer_callbacks/kernel/src/driver.rs","lineNumber":159,"sourceCode":"                    if let Err(x) = callback() {\n                        panic!(\n                            \"Error during driver post-init callback: {}: {}\",\n                            descriptor.device_driver.compatible(),\n                            x\n                        );\n                    }\n                }\n            }\n\n            // 3. After all post-init callbacks were done, the interrupt controller should be\n            //    registered and functional. So let drivers register with it now.\n            for descriptor in descriptors {\n                if let Some(irq_number) = &descriptor.irq_number {\n                    if let Err(x) = descriptor\n                        .device_driver\n                        .register_and_enable_irq_handler(irq_number)\n                    {\n                        panic!(\n                            \"Error during driver interrupt handler registration: {}: {}\",\n                            descriptor.device_driver.compatible(),\n                            x\n                        );\n                    }\n                }\n            }\n        })\n    }\n\n    /// Enumerate all registered device drivers.\n    pub fn enumerate(&self) {\n        self.descriptors.read(|descriptors| {\n            for (i, desc) in descriptors.iter().enumerate() {\n                info!(\"      {}. {}\", i + 1, desc.device_driver.compatible());\n            }\n        });\n    }","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/644474cc09f755249f9c55d99a5d1e07a2562fc7/20_timer_callbacks/kernel/src/driver.rs#L141-L177","documentation":"In the IRQ phase of init_drivers_and_irqs, every descriptor carrying an irq_number gets register_and_enable_irq_handler called on its driver; if that returns Err the manager panics with the driver's compatible name and the error string. This is the final step of wiring a driver's interrupt into the system, so failure is fatal.","triggerScenarios":"A descriptor has Some(irq_number) and its device_driver's register_and_enable_irq_handler returns Err — e.g. the underlying IRQ manager registration or the handler registration fails, or the default panicking trait stub returns via a driver that reports errors.","commonSituations":"The IRQ number in the descriptor does not match what the driver/IRQ manager expects; the driver's handler registration returns Err because the IRQ manager is not registered or the line is already claimed; copy-pasted descriptor gives one driver another driver's IRQ number.","solutions":["Check the panic message for the compatible name and error to find the failing driver and reason.","Verify the irq_number on the descriptor matches the hardware's interrupt line for that device.","Ensure the real IRQ manager is registered before init_drivers_and_irqs runs (otherwise the null manager or error paths trigger).","Confirm the driver's register_and_enable_irq_handler implementation returns Ok on success and only errors on genuine failures."],"exampleFix":"// before\nlet desc = DeviceDriverDescriptor::new(driver, Some(post_init))\n    .with_irq_number(IRQNumber::new(99)); // wrong line for this device\n\n// after\nlet desc = DeviceDriverDescriptor::new(driver, Some(post_init))\n    .with_irq_number(IRQNumber::new(1)); // correct IRQ line","handlingStrategy":"validation","validationCode":"// cross-check IRQ numbers against a board table before bring-up:\nlet expected = board_irq_for(driver.compatible());\nassert_eq!(descriptor.irq_number.map(|n| n.get()), expected, \"IRQ number mismatch for {}\", driver.compatible());","typeGuard":null,"tryCatchPattern":"// make registration failures non-fatal when appropriate:\nif let Err(x) = descriptor.device_driver.register_and_enable_irq_handler(irq_number) {\n    log_warn(\"IRQ registration failed for {}: {}\", descriptor.device_driver.compatible(), x);\n}","preventionTips":["Define each device's IRQ line once in a board-level constant table and reference it.","Register the real IRQ manager before calling init_drivers_and_irqs.","Guard against duplicate IRQ line assignment across drivers in a unit test."],"tags":["rust","driver","irq","panic","interrupt"],"backgroundTag":"unsupported-operation","analyzedSha":"644474cc09f755249f9c55d99a5d1e07a2562fc7","analyzedAt":"2026-09-06T09:25:56.584Z","contentChangedAt":"2026-09-06T09:25:56.584Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}