Exemplo n.º 1
0
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 */                                                     
Exemplo n.º 2
0
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;
}