/** An UNDI NIC */
struct undi_nic {
+ /** Device supports IRQs */
+ int irq_supported;
/** Assigned IRQ number */
unsigned int irq;
/** Currently processing ISR */
int rc;
if ( ! undinic->isr_processing ) {
- /* Do nothing unless ISR has been triggered */
- if ( ! undinet_isr_triggered() ) {
+ /* If interrupts are supported, then do nothing unless
+ * the ISR has been triggered.
+ */
+ if ( undinic->irq_supported && ( ! undinet_isr_triggered() ) ){
/* Allow interrupt to occur */
__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
"nop\n\t"
struct s_PXENV_UNDI_OPEN undi_open;
int rc;
- /* Hook interrupt service routine and enable interrupt */
- undinet_hook_isr ( undinic->irq );
- enable_irq ( undinic->irq );
- send_eoi ( undinic->irq );
+ /* Hook interrupt service routine and enable interrupt if supported */
+ if ( undinic->irq_supported ) {
+ undinet_hook_isr ( undinic->irq );
+ enable_irq ( undinic->irq );
+ send_eoi ( undinic->irq );
+ }
/* Set station address. Required for some PXE stacks; will
* spuriously fail on others. Ignore failures. We only ever
pxeparent_call ( undinet_entry, PXENV_UNDI_CLOSE,
&undi_close, sizeof ( undi_close ) );
- /* Disable interrupt and unhook ISR */
- disable_irq ( undinic->irq );
- undinet_unhook_isr ( undinic->irq );
+ /* Disable interrupt and unhook ISR if supported */
+ if ( undinic->irq_supported ) {
+ disable_irq ( undinic->irq );
+ undinet_unhook_isr ( undinic->irq );
+ }
DBGC ( undinic, "UNDINIC %p closed\n", undinic );
}
goto err_undi_get_information;
memcpy ( netdev->hw_addr, undi_info.PermNodeAddress, ETH_ALEN );
undinic->irq = undi_info.IntNumber;
- if ( undinic->irq > IRQ_MAX ) {
- DBGC ( undinic, "UNDINIC %p invalid IRQ %d\n",
- undinic, undinic->irq );
- goto err_bad_irq;
- }
- DBGC ( undinic, "UNDINIC %p is %s on IRQ %d\n",
- undinic, eth_ntoa ( netdev->hw_addr ), undinic->irq );
+ DBGC ( undinic, "UNDINIC %p has MAC address %s\n",
+ undinic, eth_ntoa ( netdev->hw_addr ) );
/* Get interface information */
memset ( &undi_iface, 0, sizeof ( undi_iface ) );
DBGC ( undinic, "UNDINIC %p has type %s, speed %d, flags %08x\n",
undinic, undi_iface.IfaceType, undi_iface.LinkSpeed,
undi_iface.ServiceFlags );
+ if ( undi_iface.ServiceFlags & SUPPORTED_IRQ ) {
+ if ( undinic->irq > IRQ_MAX ) {
+ DBGC ( undinic, "UNDINIC %p has invalid IRQ %d\n",
+ undinic, undinic->irq );
+ rc = -EINVAL;
+ goto err_bad_irq;
+ }
+ undinic->irq_supported = 1;
+ DBGC ( undinic, "UNDINIC %p uses IRQ %d\n",
+ undinic, undinic->irq );
+ }
if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",
sizeof ( undi_iface.IfaceType ) ) == 0 ) {
DBGC ( undinic, "UNDINIC %p Etherboot 5.4 workaround enabled\n",
return 0;
err_register:
- err_undi_get_iface_info:
err_bad_irq:
+ err_undi_get_iface_info:
err_undi_get_information:
err_undi_initialize:
/* Shut down UNDI stack */