static void mca_handle_nmi_slot( int slot, int check_flag ) { if( slot < MCA_MAX_SLOT_NR ) { printk( "NMI: caused by MCA adapter in slot %d (%s)\n", slot+1, mca_info->slot[slot].name ); } else if( slot == MCA_INTEGSCSI ) { printk( "NMI: caused by MCA integrated SCSI adapter (%s)\n", mca_info->slot[slot].name ); } else if( slot == MCA_INTEGVIDEO ) { printk( "NMI: caused by MCA integrated video adapter (%s)\n", mca_info->slot[slot].name ); } /* more info available in pos 6 and 7? */ if( check_flag ) { unsigned char pos6, pos7; pos6 = mca_read_pos( slot, 6 ); pos7 = mca_read_pos( slot, 7 ); printk( "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7 ); } } /* mca_handle_nmi_slot */
void mca_handle_nmi( void ) { int i; unsigned char pos5; /* First try - scan the various adapters and see if a specific * adapter was responsible for the error */ for( i = 0; i < MCA_NUMADAPTERS; i += 1 ) { /* bit 7 of POS 5 is reset when this adapter has a hardware * error. bit 7 it reset if there's error information * available in pos 6 and 7. */ pos5 = mca_read_pos( i, 5 ); if( !(pos5 & 0x80) ) { mca_handle_nmi_slot( i, !(pos5 & 0x40) ); return; } } /* if I recall correctly, there's a whole bunch of other things that * we can do to check for NMI problems, but that's all I know about * at the moment. */ printk( "NMI generated from unknown source!\n" ); } /* mca_handle_nmi */
static int __init mc32_probe1(struct net_device *dev, int slot) { static unsigned version_printed; int i, err; u8 POS; u32 base; struct mc32_local *lp = netdev_priv(dev); static u16 mca_io_bases[]= { 0x7280,0x7290, 0x7680,0x7690, 0x7A80,0x7A90, 0x7E80,0x7E90 }; static u32 mca_mem_bases[]= { 0x00C0000, 0x00C4000, 0x00C8000, 0x00CC000, 0x00D0000, 0x00D4000, 0x00D8000, 0x00DC000 }; static char *failures[]= { "Processor instruction", "Processor data bus", "Processor data bus", "Processor data bus", "Adapter bus", "ROM checksum", "Base RAM", "Extended RAM", "82586 internal loopback", "82586 initialisation failure", "Adapter list configuration error" }; /* Time to play MCA games */ if (mc32_debug && version_printed++ == 0) printk(KERN_DEBUG "%s", version); printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot); POS = mca_read_stored_pos(slot, 2); if(!(POS&1)) { printk(" disabled.\n"); return -ENODEV; } /* Fill in the 'dev' fields. */ dev->base_addr = mca_io_bases[(POS>>1)&7]; dev->mem_start = mca_mem_bases[(POS>>4)&7]; POS = mca_read_stored_pos(slot, 4); if(!(POS&1)) { printk("memory window disabled.\n"); return -ENODEV; } POS = mca_read_stored_pos(slot, 5); i=(POS>>4)&3; if(i==3) { printk("invalid memory window.\n"); return -ENODEV; } i*=16384; i+=16384; dev->mem_end=dev->mem_start + i; dev->irq = ((POS>>2)&3)+9; if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname)) { printk("io 0x%3lX, which is busy.\n", dev->base_addr); return -EBUSY; } printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n", dev->base_addr, dev->irq, dev->mem_start, i/1024); /* We ought to set the cache line size here.. */ /* * Go PROM browsing */ /* Retrieve and print the ethernet address. */ for (i = 0; i < 6; i++) { mca_write_pos(slot, 6, i+12); mca_write_pos(slot, 7, 0); dev->dev_addr[i] = mca_read_pos(slot,3); } printk("%s: Address %pM", dev->name, dev->dev_addr); mca_write_pos(slot, 6, 0); mca_write_pos(slot, 7, 0); POS = mca_read_stored_pos(slot, 4); if(POS&2) printk(" : BNC port selected.\n"); else printk(" : AUI port selected.\n"); POS=inb(dev->base_addr+HOST_CTRL); POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET; POS&=~HOST_CTRL_INTE; outb(POS, dev->base_addr+HOST_CTRL); /* Reset adapter */ udelay(100); /* Reset off */ POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET); outb(POS, dev->base_addr+HOST_CTRL); udelay(300); /* * Grab the IRQ */ err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev); if (err) { release_region(dev->base_addr, MC32_IO_EXTENT); printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); goto err_exit_ports; } memset(lp, 0, sizeof(struct mc32_local)); lp->slot = slot; i=0; base = inb(dev->base_addr); while(base == 0xFF) { i++; if(i == 1000) { printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name); err = -ENODEV; goto err_exit_irq; } udelay(1000); if(inb(dev->base_addr+2)&(1<<5)) base = inb(dev->base_addr); } if(base>0) { if(base < 0x0C) printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1], base<0x0A?" test failure":""); else printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base); err = -ENODEV; goto err_exit_irq; } base=0; for(i=0; i<4; i++) { int n=0; while(!(inb(dev->base_addr+2)&(1<<5))) { n++; udelay(50); if(n>100) { printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i); err = -ENODEV; goto err_exit_irq; } } base|=(inb(dev->base_addr)<<(8*i)); } lp->exec_box=isa_bus_to_virt(dev->mem_start+base); base=lp->exec_box->data[1]<<16|lp->exec_box->data[0]; lp->base = dev->mem_start+base; lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]); lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]); lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]); /* * Descriptor chains (card relative) */ lp->tx_chain = lp->exec_box->data[8]; /* Transmit list start offset */ lp->rx_chain = lp->exec_box->data[10]; /* Receive list start offset */ lp->tx_len = lp->exec_box->data[9]; /* Transmit list count */ lp->rx_len = lp->exec_box->data[11]; /* Receive list count */ init_MUTEX_LOCKED(&lp->cmd_mutex); init_completion(&lp->execution_cmd); init_completion(&lp->xceiver_cmd); printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n", dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base); dev->open = mc32_open; dev->stop = mc32_close; dev->hard_start_xmit = mc32_send_packet; dev->get_stats = mc32_get_stats; dev->set_multicast_list = mc32_set_multicast_list; dev->tx_timeout = mc32_timeout; dev->watchdog_timeo = HZ*5; /* Board does all the work */ dev->ethtool_ops = &netdev_ethtool_ops; return 0; err_exit_irq: free_irq(dev->irq, dev); err_exit_ports: release_region(dev->base_addr, MC32_IO_EXTENT); return err; }