📄 dm9000 network driver - linux_kernel google 网上论坛.htm
字号:
kfree(db->data_req); <BR>+
} <BR>+ <BR>+ if
(db->addr_res != NULL) { <BR>+
release_resource(db->data_req); <BR>+
kfree(db->addr_req); <BR>+
} <BR>+} <BR>+ <BR>+#define res_size(_r)
(((_r)->end - (_r)->start) + 1) <BR>+ <BR>+/* <BR>+ * Search
DM9000 board, allocate space and register it <BR>+ */ <BR>+static
int <BR>+dm9000_probe(struct device *dev) <BR>+{ <BR>+
struct platform_device *pdev = to_platform_device(dev); <BR>+
struct dm9000_plat_data *pdata =
pdev->dev.platform_data; <BR>+ struct
board_info *db; /* Point a board information structure */
<BR>+ struct net_device *ndev; <BR>+
unsigned long base; <BR>+ int ret
= 0; <BR>+ int iosize; <BR>+
int i; <BR>+ u32 id_val; <BR>+ <BR>+
printk(KERN_INFO "%s Ethernet Driver\n",
CARDNAME); <BR>+ <BR>+ /* Init network device
*/ <BR>+ ndev = alloc_etherdev(sizeof (struct
board_info)); <BR>+ if (!ndev) { <BR>+
printk("%s: could not
allocate device.\n", CARDNAME); <BR>+
return -ENOMEM; <BR>+ }
<BR>+ <BR>+ SET_MODULE_OWNER(ndev); <BR>+
SET_NETDEV_DEV(ndev, dev); <BR>+ <BR>+
PRINTK2("dm9000_probe()"); <BR>+ <BR>+
/* setup board info structure */ <BR>+
db = (struct board_info *) ndev->priv; <BR>+
memset(db, 0, sizeof (*db)); <BR>+ <BR>+ if
(pdev->num_resources < 2) { <BR>+
ret = -ENODEV; <BR>+
goto out; <BR>+ }
<BR>+ <BR>+ switch (pdev->num_resources) {
<BR>+ case 2: <BR>+
base = pdev->resource[0].start; <BR>+ <BR>+
if
(!request_mem_region(base, 4, ndev->name)) { <BR>+
ret =
-EBUSY; <BR>+
goto out; <BR>+
} <BR>+ <BR>+
ndev->base_addr = base; <BR>+
ndev->irq =
pdev->resource[1].start;
<BR>+
db->io_addr = (void *)base; <BR>+
db->io_data = (void *)(base + 4); <BR>+
<BR>+ break; <BR>+
<BR>+ case 3: <BR>+
db->addr_res = platform_get_resource(pdev,
IORESOURCE_MEM, 0); <BR>+
db->data_res = platform_get_resource(pdev, IORESOURCE_MEM,
1); <BR>+
db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ,
0); <BR>+ <BR>+ if
(db->addr_res == NULL || db->data_res == NULL) { <BR>+
printk(KERN_ERR PFX "insufficient resources\n"); <BR>+
ret = -ENOENT; <BR>+
goto out; <BR>+
} <BR>+ <BR>+
i =
res_size(db->addr_res); <BR>+
db->addr_req =
request_mem_region(db->addr_res->start, i, <BR>+
pdev->name); <BR>+ <BR>+
if (db->addr_req ==
NULL) { <BR>+
printk(KERN_ERR PFX "cannot claim
address reg area\n"); <BR>+
ret = -EIO; <BR>+
goto out; <BR>+
} <BR>+ <BR>+
db->io_addr = ioremap(db->addr_res->start, i); <BR>+
<BR>+ if
(db->io_addr == NULL) { <BR>+
printk(KERN_ERR "failed to
ioremap address reg\n"); <BR>+
ret = -EINVAL; <BR>+
goto out; <BR>+
} <BR>+ <BR>+
iosize = res_size(db->data_res); <BR>+
db->data_req =
request_mem_region(db->data_res->start, iosize, <BR>+
pdev->name); <BR>+ <BR>+
if (db->data_req
== NULL) { <BR>+
printk(KERN_ERR PFX "cannot claim data
reg area\n"); <BR>+
ret = -EIO; <BR>+
goto out;
<BR>+ } <BR>+ <BR>+
db->io_data =
ioremap(db->data_res->start, iosize); <BR>+ <BR>+
if (db->io_data ==
NULL) { <BR>+
printk(KERN_ERR "failed to ioremap data
reg\n"); <BR>+
ret = -EINVAL; <BR>+
goto
out; <BR>+ } <BR>+
<BR>+ /* fill in
parameters for net-dev structure */ <BR>+ <BR>+
ndev->base_addr = (unsigned
long)db->io_addr; <BR>+
ndev->irq = db->irq_res->start; <BR>+
<BR>+ /* ensure at
least we have a default set of IO routines */ <BR>+
dm9000_set_io(db, iosize); <BR>+
<BR>+ } <BR>+ <BR>+ /*
check to see if anything is being over-ridden */ <BR>+
if (pdata != NULL) { <BR>+
/* check to see if the driver wants to over-ride the
<BR>+ *
default IO width */ <BR>+ <BR>+
if (pdata->flags & DM9000_PLATF_8BITONLY) <BR>+
dm9000_set_io(db, 1); <BR>+ <BR>+
if (pdata->flags &
DM9000_PLATF_16BITONLY) <BR>+
dm9000_set_io(db, 2);
<BR>+ <BR>+ if
(pdata->flags & DM9000_PLATF_32BITONLY) <BR>+
dm9000_set_io(db, 4); <BR>+ <BR>+
/* check to see if there are any IO routine <BR>+
* over-rides
*/ <BR>+ <BR>+ if
(pdata->inblk != NULL) <BR>+
db->inblk =
pdata->inblk; <BR>+ <BR>+
if (pdata->outblk != NULL) <BR>+
db->outblk = pdata->outblk; <BR>+ <BR>+
if (pdata->dumpblk != NULL) <BR>+
db->dumpblk = pdata->dumpblk; <BR>+
} <BR>+ <BR>+ dm9000_reset(db);
<BR>+ <BR>+ /* try two times, DM9000 sometimes
gets the first read wrong */ <BR>+ for (i = 0;
i < 2; i++) { <BR>+
id_val = ior(db, DM9000_VIDL); <BR>+
id_val |= (u32)ior(db,
DM9000_VIDH) << 8; <BR>+
id_val |= (u32)ior(db, DM9000_PIDL) << 16; <BR>+
id_val |=
(u32)ior(db, DM9000_PIDH) << 24; <BR>+ <BR>+
if (id_val == DM9000_ID) <BR>+
break; <BR>+
printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val); <BR>+
} <BR>+ <BR>+ if (id_val
!= DM9000_ID) { <BR>+
printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val); <BR>+
goto release; <BR>+
} <BR>+ <BR>+ /* from this
point we assume that we have found a DM9000 */ <BR>+ <BR>+
/* driver system function */ <BR>+
ether_setup(ndev); <BR>+ <BR>+
ndev->open =
&dm9000_open; <BR>+
ndev->hard_start_xmit = &dm9000_start_xmit;
<BR>+ ndev->tx_timeout
= &dm9000_timeout; <BR>+
ndev->watchdog_timeo = msecs_to_jiffies(watchdog); <BR>+
ndev->stop
= &dm9000_stop; <BR>+
ndev->get_stats
= &dm9000_get_stats; <BR>+
ndev->set_multicast_list = &dm9000_hash_table; <BR>+
ndev->do_ioctl
= &dm9000_do_ioctl; <BR>+ <BR>+#ifdef
DM9000_PROGRAM_EEPROM <BR>+ program_eeprom(db);
<BR>+#endif <BR>+ db->msg_enable
= NETIF_MSG_LINK; <BR>+
db->mii.phy_id_mask = 0x1f; <BR>+
db->mii.reg_num_mask = 0x1f; <BR>+
db->mii.force_media = 0; <BR>+
db->mii.full_duplex = 0; <BR>+
db->mii.dev = ndev; <BR>+
db->mii.mdio_read = dm9000_phy_read; <BR>+
db->mii.mdio_write =
dm9000_phy_write; <BR>+ <BR>+ /* Read SROM
content */ <BR>+ for (i = 0; i < 64; i++)
<BR>+ ((u16 *)
db->srom)[i] = read_srom_word(db, i); <BR>+ <BR>+
/* Set Node Address */ <BR>+ for (i = 0;
i < 6; i++) <BR>+
ndev->dev_addr[i] = db->srom[i]; <BR>+ <BR>+
if (!is_valid_ether_addr(ndev->dev_addr)) <BR>+
printk("%s: Invalid
ethernet MAC address. Please " <BR>+
"set using
ifconfig\n", ndev->name); <BR>+ <BR>+
dev_set_drvdata(dev, ndev); <BR>+ ret =
register_netdev(ndev); <BR>+ <BR>+ if (ret ==
0) { <BR>+
printk("%s: dm9000 at %p,%p IRQ %d MAC: ", <BR>+
ndev->name, db->io_addr, db->io_data,
ndev->irq); <BR>+
for (i = 0; i < 5; i++) <BR>+
printk("%02x:",
ndev->dev_addr[i]); <BR>+ &nbs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -