附上probe 和open两个函数 ,希望有高手给解答一下
/*
Search DM9000 board, allocate space and register it
*/
static unsigned char eth1_mac_addr[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x89};
static unsigned char eth2_mac_addr[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x90};
static unsigned char eth3_mac_addr[6] = {0x00, 0x13, 0xf6, 0x6c, 0x87, 0x91};
int __init dmfe_probe(struct DEVICE *dev)
{
////////////////////////////////////////
//i2c_data add by zy
//unsigned int rd_adr=0x0;
//unsigned int rd_num=0x06;
//unsigned char * get_data;
//unsigned char buff[64];
static char sEthernet[5];
struct board_info *db; /* Point a board information structure */
u32 id_val;
u32 iobase; // = DM9000_MIN_IO;
u16 i, dm9000_count = 0;
u8 irqline;
//printk("BWSCON=%x\n",BWSCON);
BANKCON1=0xffff;
BWSCON &= 0xffffff0f;
BWSCON|=0xd0;
//printk("BWSCON2=%x\n",BWSCON);
GPFCON = 0xaaaa; //EINT0 from PORT F control register
EXTINT0 |= 0x40000000; //EINT0 Rising edge triggered
INTMSK &= 0xffffffef; //EINT0 Enable
EINTMASK &= 0x00ffff70;
printk("BANKCON1 = 0x%x\nBWSCON = 0x%x\nGPFCON = 0x%x\nEXTINT0 = 0x%x\nINTMSK = 0x%x\n EINTMASK = 0x%x\n",BANKCON1, BWSCON, GPFCON, EXTINT0, INTMSK, EINTMASK);
//INTPND |= 0x1;
//set_external_irq (IRQ_EINT7, EXT_RISING_EDGE, GPIO_PULLUP_DIS);
//printk("******** dm9000 probe dev->name=%s\n",dev->name);
if(strcmp(dev->name,sEthernet)!=0)strcpy(sEthernet,dev->name);
else return 0;
if(strcmp(dev->name,"eth0")==0)
{
printk("eth0 network interface found ");
iobase = ioremap(DM9000_MIN_IO_ETH1,0x400);
//printk("iobase=%x\n",iobase);
dev->irq = IRQ_EINT7; //EINT0
printk("eth0 dev->irq = %d\n", dev->irq);
for (i=0; i<6; i++)
{
dev->dev_addr = eth1_mac_addr;//db->srom;
// printk("%02X:",dev->dev_addr);
}
//printk("\n");
}else
if(strcmp(dev->name,"eth1")==0)
{
//printk("eth2 network interface found ");
iobase = DM9000_MIN_IO_ETH2;
dev->irq = 90; //INT5
for (i=0; i<6; i++)
{
dev->dev_addr = eth2_mac_addr;//db->srom;
// printk("%02X:",dev->dev_addr);
}
//printk("\n");
}else
if(strcmp(dev->name,"eth3")==0)
{
//printk("eth3 network interface found ");
iobase = DM9000_MIN_IO_ETH3;
dev->irq = 91; //INT6
for (i=0; i<6; i++)
{
dev->dev_addr = eth3_mac_addr;//db->srom;
// printk("%02X:",dev->dev_addr);
}
//printk("\n");
}else
return 0;
//printk("HHTech I/O: %x, VID: succ\n", iobase);
//return;
//printk("Device Name=%s,name=%s\n",dev->name,dev->priv);
//DMFE_DBUG(0, "dmfe_probe()",0);
//iow(db, 0xfe, 0x0f); /* Clear interrupt status */
//printk("222\n");
/* Disable all interrupt */
//iow(db, 0xff, 0x80);
/////////////////////////////////////////////////////////////////////////
/* Search All DM9000 NIC */
//{
//printk("iobase=%x,value=%x\n",iobase,DM9000_VID_L);
outb(DM9000_VID_L, iobase);
id_val = inb(iobase + 4);
outb(DM9000_VID_H, iobase);
id_val |= inb(iobase + 4) << 8;
outb(DM9000_PID_L, iobase);
id_val |= inb(iobase + 4) << 16;
outb(DM9000_PID_H, iobase);
id_val |= inb(iobase + 4) << 24;
if (id_val == DM9000_ID) {
printk("HHTech DM9000 %s I/O: %x,VID: %x,MAC: ", dev->name,iobase, id_val);
dm9000_count++;
/* Init network device */
dev = init_etherdev(dev, 0);
/* Allocated board information structure */
irqline = 3;
db = (void *)(kmalloc(sizeof(*db), GFP_KERNEL|GFP_DMA));
memset(db, 0, sizeof(*db));
dev->priv = db; /* link device and board info */
db->next_dev = dmfe_root_dev;
dmfe_root_dev = dev;
db->ioaddr = iobase;
db->io_data = iobase + 4;
/* driver system function */
dev->base_addr = iobase;
//dev->irq = 68; //INT4 166;//irqline;
dev->open = &dmfe_open;
dev->hard_start_xmit = &dmfe_start_xmit;
dev->stop = &dmfe_stop;
dev->get_stats = &dmfe_get_stats;
dev->set_multicast_list = &dm9000_hash_table;
dev->do_ioctl = &dmfe_do_ioctl;
/* Read SROM content */
/*for (i=0; i<64; i++)
((u16 *)db->srom) = read_srom_word(db, i);*/
/* Set Node Address */
//add by zy
//i2c_read(0x7a,buff,6);
//we set lan-switch data to first 24 bytes,then put mac data to the last 6 bytes.
//printk("MAC set to ");
for (i=0; i<6; i++){
// dev->dev_addr = eth_mac_addr;//db->srom;
printk("%02X:",dev->dev_addr);
}
printk("\n");
}
if (dm9000_count) {
//request_irq(db->irq, &dmfe_interrupt,0,"DM9000 device",dev);
/* Enable interrupts for GPIO6 */
//L-->H
//HHTECH
//*((volatile unsigned long *) (MCF_MBAR2+MCFSIM2_GPIOINTENABLE)) |=0x00000040;
/* Enable interrupt level for GPIO6 - VEC38 */
//*((volatile unsigned long *) (MCF_MBAR2+MCFSIM2_INTLEVEL5)) |=0x04000000;
}
//printk("**** request_irq=%x\n",dev->irq);
//if(request_irq(dev->irq, &dmfe_interrupt,SA_SHIRQ,"DM9000 device",dev))
// return -EAGAIN;
// printk(" ****** success rquest_irq\n");
/* Re-enable interrupt mask */
//iow(db, 0xff, 0x83);
return dm9000_count ? 0:-ENODEV;
}
/*
Open the interface.
The interface is opened whenever "ifconfig" actives it.
*/
static int dmfe_open(struct DEVICE *dev)
{
board_info_t * db = (board_info_t *)dev->priv;
int rc;
DMFE_DBUG(0, "dmfe_open", 0);
//minor = MINOR(dev->priv);
//printk("minor=%x\n",dev->minor);
//if (request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev))
printk("request_irq, irq=%x\n",dev->irq);
rc = request_irq(dev->irq, &dmfe_interrupt,SA_INTERRUPT/*SA_SHIRQ*/,"DM9000 device",dev);
//if(request_irq(dev->irq, &dmfe_interrupt,SA_INTERRUPT/*SA_SHIRQ*/,"DM9000 device",dev))
if (rc < 0)
{
printk("request_irq failure, irq=%x, error = %d\n",dev->irq, rc);
return -EAGAIN;
}
printk("request_irq ok, irq=%x\n",dev->irq);
/* Initilize DM910X board */
dmfe_init_dm9000(dev);
// printk("end init\n");
/* Init driver variable */
db->dbug_cnt = 0;
db->runt_length_counter = 0;
db->long_length_counter = 0;
db->reset_counter = 0;
/* Active System Interface */
//dev->tbusy = 0; /* Can transmit packet */
//dev->start = 1; /* interface ready */
//mark above for kernel 2.4
netif_wake_queue(dev); //add by simon 2001.9.4 for kernel 2.4
MOD_INC_USE_COUNT;
// printk("init timer\n");
/* set and active a timer process */
init_timer(&db->timer);
// printk("end timer\n");
db->timer.expires = DMFE_TIMER_WUT * 2;
db->timer.data = (unsigned long)dev;
db->timer.function = &dmfe_timer;
add_timer(&db->timer);
return 0;
}