分类:
2009-09-18 12:56:41
分享下硬盘的驱动调试经验。首先,打开先找到DAVINCI IDE的接口驱动文件/drivers/ide/davinci/palm_bk3710.c
第一步还是还是模块初的始化函数,linux还是Linux,模块还是那个模块
module_init(palm_bk3710_init);//万年不变的
下一步是看palm_bk3710_init,从代码里来,还是从代码开始吧。
int palm_bk3710_init(void)//DAVINCI ide驱动初始化
{
int ret = 0;
hw_regs_t ide_ctlr_info;
int index = 0;
int pribase = IO_ADDRESS(IDE_PALM_REG_MMAP_BASE) +
IDE_PALM_ATA_PRI_REG_OFFSET; //映射IDE寄存器
struct clk *clkp;
volatile unsigned int regAddr0 = IO_ADDRESS(0x
volatile unsigned int tmpData0 = *(unsigned int *)regAddr0;
printk("\nthe pinMux1 is:0x%x!\n\n\n", tmpData);
volatile unsigned int regAddr1 = IO_ADDRESS(0x
volatile unsigned int tmpData1 = *(unsigned int *)regAddr1;
printk("\nthe pinMux0 is:0x%x!\n\n\n", tmpData0);
printk("\nthe pinMux1 is:0x%x!\n\n\n", tmpData1);
tmpData0 |= 0x30000;
*(unsigned int *)regAddr0 = tmpData0;
tmpData0 = *(unsigned int *)regAddr0;
printk("\nthe pinMux0 set is:0x%x!\n\n\n", tmpData0);
clkp = clk_get (NULL, "IDECLK"); //取到IDE时钟
if (!IS_ERR(clkp)) //判断始终存在与否
{
ideclkp = clkp;
clk_use (ideclkp);
clk_enable (ideclkp); //使能时钟
ide_palm_clk = clk_get_rate(ideclkp)/100000;
ide_palm_clk = (10000/ide_palm_clk) + 1;
/* ATA_SEL is 1 -> Disable 0 -> Enable
* CF_SEL is 1 -> Disable 0 -> Enable
*
* Ensure both are not Enabled.
*/
{
#ifdef CONFIG_DAVINCI_BLK_DEV_CF //片选
//davinci_i
//davinci_i
//davinci_i
#else
//davinci_i
//davinci_i
#endif
}
/* Register the IDE interface with Linux ATA Interface */
memset(&ide_ctlr_info, 0, sizeof(ide_ctlr_info));
palm_bk3710_base =
(palm_bk3710_ideregs *) IO_ADDRESS(IDE_PALM_REG_MMAP_BASE);
/* Configure the Palm Chip controller */ //映射IDE的寄存器
palm_bk3710_chipinit();
for (index = 0; index < IDE_NR_PORTS - 2; index++) {
ide_ctlr_info.io_ports[index] = pribase + index;
}
ide_ctlr_info.io_ports[IDE_CONTROL_OFFSET] =
IO_ADDRESS(IDE_PALM_REG_MMAP_BASE)
+ IDE_PALM_ATA_PRI_CTL_OFFSET;
ide_ctlr_info.irq = IRQ_IDE; //中断号22
ide_ctlr_info.chipset = ide_palm3710;
ide_ctlr_info.ack_intr = NULL;
if (ide_register_hw(&ide_ctlr_info, &palm_bk3710_hwif) < 0) {//硬件注册IDE
printk("Palm Chip BK3710 IDE Register Fail\n");
return -1;
}
palm_bk3710_hwif->tuneproc = &palm_bk3710_tune_drive;
palm_bk3710_hwif->noprobe = 0;
#ifndef CONFIG_DAVINCI_BLK_DEV_CF
#ifdef CONFIG_BLK_DEV_IDEDMA
palm_bk3710_hwif->speedproc = &palm_bk3710_hostdma;
/* Just put this for using the ide-dma.c init code */
palm_bk3710_dummydata.extra = 0;
palm_bk3710_hwif->cds = &palm_bk3710_dummydata;
palm_bk3710_hwif->atapi_dma = 1;
/* Setup up the memory map base for this instance of hwif */
palm_bk3710_hwif->mmio = 0;
palm_bk3710_hwif->ide_dma_check = palm_bk3710_checkdma;
palm_bk3710_hwif->ultra_mask = 0x
/* Max (input clk 99MHz) */
palm_bk3710_hwif->mwdma_mask = 0x7;
palm_bk3710_hwif->swdma_mask = 0;
palm_bk3710_hwif->dma_command =
IO_ADDRESS(IDE_PALM_REG_MMAP_BASE);
palm_bk3710_hwif->dma_status =
IO_ADDRESS(IDE_PALM_REG_MMAP_BASE) + 2;
palm_bk3710_hwif->dma_prdtable =
IO_ADDRESS(IDE_PALM_REG_MMAP_BASE) + 4;
palm_bk3710_hwif->drives[0].autodma = 1;
palm_bk3710_hwif->drives[1].autodma = 1;
palm_bk3710_hwif->udma_four = 1;
ide_setup_dma(palm_bk3710_hwif,
IO_ADDRESS(IDE_PALM_REG_MMAP_BASE), 8); //建立DMA,挂上硬盘DMA的处理函数
palm_bk3710_checkdma (&palm_bk3710_hwif->drives[0]);//配置硬盘DMA模式
palm_bk3710_checkdma (&palm_bk3710_hwif->drives[1]);
#endif
#endif
ret = 0;
} else {
ret = -ENODEV;
}
return ret;
}
先说下ide_register_hw这个函数看代码:
int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp)
{
return ide_register_hw_with_fixup(hw, hwifp, NULL);
}
转手
int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, void(*fixup)(ide_hwif_t *hwif))
{
int index, retry = 1;
ide_hwif_t *hwif;
do {
for (index = 0; index < MAX_HWIFS; ++index) { //默认IDE有四个接口
hwif = &ide_hwifs[index];
if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
goto found;
}
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index];
if (hwif->hold)
continue;
if ((!hwif->present && !hwif->mate && !initializing) ||
(!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
goto found;
}
for (index = 0; index < MAX_HWIFS; index++)
ide_unregister(index);
} while (retry--);
return -1;
found:
if (hwif->present)
ide_unregister(index);
else if (!hwif->hold) {
init_hwif_data(hwif, index);
init_hwif_default(hwif, index);
}
if (hwif->present)
return -1;
memcpy(&hwif->hw, hw, sizeof(*hw));
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
hwif->irq = hw->irq;
hwif->noprobe = 0;
hwif->chipset = hw->chipset;
if (!initializing) { // initializing?哪来的我们后面再说
probe_hwif_init_with_fixup(hwif, fixup);//主要接这步初始化
create_proc_ide_interfaces();
}
if (hwifp)
*hwifp = hwif;
return (initializing || hwif->present) ? index : -1;
来看看probe_hwif_init_with_fixup
}