{"record":{"id":"05220f9c816ceea6","repo":"rust-embedded/rust-raspberrypi-OS-tutorials","slug":"attempt-to-enable-irq-for-device-but-driver","errorCode":null,"errorMessage":"Attempt to enable IRQ {} for device {}, but driver does not support this","messagePattern":"Attempt to enable IRQ (.+?) for device (.+?), but driver does not support this","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"20_timer_callbacks/kernel/src/driver.rs","lineNumber":45,"sourceCode":"\n        /// Called by the kernel to bring up the device.\n        ///\n        /// # Safety\n        ///\n        /// - During init, drivers might do stuff with system-wide impact.\n        unsafe fn init(&self) -> Result<(), &'static str> {\n            Ok(())\n        }\n\n        /// Called by the kernel to register and enable the device's IRQ handler.\n        ///\n        /// Rust's type system will prevent a call to this function unless the calling instance\n        /// itself has static lifetime.\n        fn register_and_enable_irq_handler(\n            &'static self,\n            irq_number: &Self::IRQNumberType,\n        ) -> Result<(), &'static str> {\n            panic!(\n                \"Attempt to enable IRQ {} for device {}, but driver does not support this\",\n                irq_number,\n                self.compatible()\n            )\n        }\n    }\n}\n\n/// Tpye to be used as an optional callback after a driver's init() has run.\npub type DeviceDriverPostInitCallback = unsafe fn() -> Result<(), &'static str>;\n\n/// A descriptor for device drivers.\npub struct DeviceDriverDescriptor<T>\nwhere\n    T: 'static,\n{\n    device_driver: &'static (dyn interface::DeviceDriver<IRQNumberType = T> + Sync),\n    post_init_callback: Option<DeviceDriverPostInitCallback>,","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/rust-embedded/rust-raspberrypi-OS-tutorials/blob/644474cc09f755249f9c55d99a5d1e07a2562fc7/20_timer_callbacks/kernel/src/driver.rs#L27-L63","documentation":"This is a default trait-method implementation for the DeviceDriver trait that always panics. It exists so that drivers which have no interrupt support can inherit a stub instead of being forced to implement register_and_enable_irq_handler themselves. Hitting it means you called the IRQ-registration path on a driver that never opted into interrupts.","triggerScenarios":"Calling register_and_enable_irq_handler() on a DeviceDriver that only implements the default trait method (no interrupt capability), or registering an IRQ descriptor whose irq_number points at such a driver during init_drivers_and_irqs.","commonSituations":"Adding a new device driver without IRQ support but accidentally giving its descriptor an irq_number; refactoring driver traits so a previously interrupt-capable driver lost its custom register_and_enable_irq_handler; wiring a driver into the IRQ manager before implementing its handler.","solutions":["Do not set an irq_number on the driver's descriptor, since the driver declares no interrupt support.","Implement register_and_enable_irq_handler for the driver in its DeviceDriver impl if it actually supports interrupts.","Verify the driver instance is the intended concrete type, not a stub/null driver that only carries the default trait implementation."],"exampleFix":"// before\nimpl DeviceDriver for UartDriver {\n    // register_and_enable_irq_handler not implemented -> default panicking stub used\n}\n\n// after\nimpl DeviceDriver for UartDriver {\n    fn register_and_enable_irq_handler(\n        &'static self,\n        irq_number: &Self::IRQNumberType,\n    ) -> Result<(), &'static str> {\n        // real implementation: route IRQ to the handler\n        irq_manager.register_handler(irq_handler_descriptor(irq_number))\n    }\n}","handlingStrategy":"validation","validationCode":"// Rust: check driver declares IRQ support before asking it to register\nif driver.compatible().contains(\"no-irq\") {\n    return Err(\"driver does not support IRQ registration\");\n}\n// or check descriptor has no irq_number:\nif descriptor.irq_number.is_some() && !driver.supports_irqs() {\n    return Err(\"irq_number set on IRQ-incapable driver\");\n}","typeGuard":"fn supports_irqs<D: DeviceDriver>(_d: &D) -> bool { false } // specialize via const flag on the driver type","tryCatchPattern":null,"preventionTips":["Only attach irq_number to descriptors of drivers that implement register_and_enable_irq_handler.","Keep a compile-time capability flag (e.g. const HAS_IRQS: bool) per driver and assert on it in tests.","Add a boot-time self-check that no descriptor pairs an irq_number with the default trait stub."],"tags":["rust","driver","irq","unsupported-operation","panic"],"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"}