f struct board_info {
void __iomem *io_addr; /* Register I/O base address *///虚拟的通过IO映射的
void __iomem *io_data; /* Data I/O address */
u16 irq; /* IRQ */
/**********************************都通过映射后的**********************************************************************************************************/
u16 tx_pkt_cnt;
u16 queue_pkt_len;
u16 queue_start_addr;
u16 queue_ip_summed;
u16 dbug_cnt;
u8 io_mode; /* 0:word, 2:byte */
u8 phy_addr;
u8 imr_all;
unsigned int flags;
unsigned int in_suspend :1;
unsigned int wake_supported :1;
int debug_level;
enum dm9000_type type;
//IO模式
void (*inblk)(void __iomem *port, void *data, int length);
void (*outblk)(void __iomem *port, void *data, int length);
void (*dumpblk)(void __iomem *port, int length);
struct device *dev; /* parent device */
//平台设备资源
struct resource *addr_res; /* 地址资源resources found */
struct resource *data_res; /**IO数据资源**/
struct resource *addr_req; /* 分配后的地址内存资源*/
struct resource *data_req; /* 分配后的数据资源*/
struct resource *irq_res; /**中断资源***/
int irq_wake;
struct mutex addr_lock; /* phy and eeprom access lock */
struct delayed_work phy_poll;
struct net_device *ndev;
spinlock_t lock;
struct mii_if_info mii;
u32 msg_enable;
u32 wake_state;
int rx_csum;
int can_csum;
int ip_summed;
} board_info_t;
/**************************************************************************************************************************************************************/
2.1、 注册平台驱动。
将驱动添加到总线上,完成驱动和设备的匹配,并执行驱动的probe函数。
static struct platform_driver dm9000_driver = {
.driver = {
.name = "dm9000",
.owner = THIS_MODULE,
.pm = &dm9000_drv_pm_ops,
},
.probe = dm9000_probe,
.remove = __devexit_p(dm9000_drv_remove),
};
static int __init dm9000_init(void)
{
printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
return platform_driver_register(&dm9000_driver);
}
2.2、dm9000_probe探测函数的分析
static int __devinit dm9000_probe(struct platform_device *pdev)
{
//定义局部变量用来保存数据
struct dm9000_plat_data *pdata = pdev->dev.platform_data;
struct board_info *db; /* Point a board information structure */
struct net_device *ndev;
const unsigned char *mac_src;
int ret = 0;
int iosize;
int i;
u32 id_val;
/**内核用net_device结构来描述一个网络设备并使用alloc_etherdev或者alloc_netdev函数来分配一个net_device结构
/* Init network device */
ndev = alloc_etherdev(sizeof(struct board_info));
if (!ndev) {
dev_err(&pdev->dev, "could not allocate device.\n");
return -ENOMEM;
}
//platform_device与net_device关联起来
SET_NETDEV_DEV(ndev, &pdev->dev);//通过这一步网络设备和平台设备即关联起来了
dev_dbg(&pdev->dev, "dm9000_probe()\n");
/* setup board info structure */
db = netdev_priv(ndev);/**获取net_device结构的私有成员保存到struct board_info *db中**/
db->dev = &pdev->dev;
db->ndev = ndev;
spin_lock_init(&db->lock);/**初始化自旋锁**/
mutex_init(&db->addr_lock);
//初始化延迟等待队列并传入dm9000_poll_work该函数将在设备被打开的时候被调度
INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);
//获取平台资源 从