免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3544 | 回复: 3
打印 上一主题 下一主题

如何在内核直接读写一个ide 磁盘扇区 ? 不用中断,dma,定时器 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-10 18:56 |只看该作者 |倒序浏览
哥们搞了两天,发现状态寄存器总是返回0x7f, 读不出来,郁闷中, 谁解哥忧啊

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
2 [报告]
发表于 2011-06-10 22:03 |只看该作者
貌似很简单,见过这种代码,找找看。。。。。

论坛徽章:
2
CU十二周年纪念徽章
日期:2013-10-24 15:41:34处女座
日期:2013-12-27 22:22:41
3 [报告]
发表于 2011-06-10 22:04 |只看该作者
  1. void
  2. waitdisk(void)
  3. {
  4.         // wait for disk reaady
  5.         while ((inb(0x1F7) & 0xC0) != 0x40)
  6.                 /* do nothing */;
  7. }

  8. void
  9. readsect(void *dst, uint32_t offset)
  10. {
  11.         // wait for disk to be ready
  12.         waitdisk();

  13.         outb(0x1F2, 1);                // count = 1
  14.         outb(0x1F3, offset);
  15.         outb(0x1F4, offset >> 8);
  16.         outb(0x1F5, offset >> 16);
  17.         outb(0x1F6, (offset >> 24) | 0xE0);
  18.         outb(0x1F7, 0x20);        // cmd 0x20 - read sectors

  19.         // wait for disk to be ready
  20.         waitdisk();

  21.         // read a sector
  22.         insl(0x1F0, dst, SECTSIZE/4);
  23. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2011-06-11 11:53 |只看该作者
试了不行,擦的,读出来的全是ff


ide_drive_t * panic_log_driver;

static void rw_log_raw(ide_drive_t *drive, task_ioreg_t cmd, char *buf, int len, int write)
{
        unsigned long flags;
        u8 stat;
       
        int cnt=0;
        //ide_hwgroup_t *hwgroup = HWGROUP(drive);
        ide_hwif_t *hwif = HWIF(drive);
        int nsect = ((len % SECTOR_SIZE) == 0) ? len/SECTOR_SIZE : len/SECTOR_SIZE + 1 ;
        printk(KERN_INFO "nsect is %d \n", nsect);
        //spin_lock_irqsave(&ide_lock, flags);
#if 0
        BUG_ON(hwgroup->handler);
        hwgroup->handler        = handler;
        hwgroup->expiry                = expiry;
        hwgroup->timer.expires        = jiffies + timeout;
        add_timer(&hwgroup->timer);
#endif
        printk("write cmd to ide: 0x%02x \n", cmd);
        hwif->OUTBSYNC(drive, cmd, IDE_COMMAND_REG);
        /* Drive takes 400nS to respond, we must avoid the IRQ being
           serviced before that.
          
           FIXME: we could skip this delay with care on non shared
           devices
        */
        ndelay(1000);
        //spin_unlock_irqrestore(&ide_lock, flags);
       
judge:
        ndelay(1000);
        stat = hwif->INB(IDE_STATUS_REG);
        cnt++;
        /* new way for dealing with premature shared PCI interrupts */
        if ( (stat & 0xc0) != 0x40) {
               
                /* No data yet, so wait for another IRQ. */
                #if 0
                ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
                return ide_started;
                #endif
                if (cnt >= 1000) {
                        printk(KERN_INFO " error stat dont ok cnt > 1000,stat:%02x  force to read or write now\n",stat);
                        goto rwnow;
                }
                       
                goto judge;
        }
       
        printk(KERN_INFO " good state , now to read or write,stat:%02x  \n",stat);

rwnow:
                if (write){
                          
                          while (nsect--){
                                  printk("writeing \n";
                                 HWIF(drive)->ata_output_data(drive, buf, SECTOR_WORDS);
                                   buf +=SECTOR_WORDS;
                                 goto judge;
                          }
                        }
                else {
                       
                        while (nsect--){
                                 printk("reading \n";
                                 HWIF(drive)->ata_input_data(drive, buf, SECTOR_WORDS);
                                   buf +=SECTOR_WORDS;
                                 goto judge;
                          }

                }

        /* If it was the last datablock check status and finish transfer. */
        #if 0
        if (!hwif->nleft) {
                stat = wait_drive_not_busy(drive);
                if (!OK_STAT(stat, 0, BAD_R_STAT))
                        return task_error(drive, rq, __FUNCTION__, stat);
                task_end_request(drive, rq, stat);
                return ide_stopped;
        }
        #endif
        /* Still data left to transfer. */
        //ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);

        return ;

}




/**/
void ide_log_raw(ide_drive_t *drive, sector_t block, int cmd, char * buf, int len)
{
        ide_hwif_t *hwif        = HWIF(drive);
        unsigned int dma        = drive->using_dma;
        u8 lba48                = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command        = WIN_NOP;
        ata_nsector_t                nsectors;
        task_ioreg_t tasklets[10];
        u8 stat;
        int i=0;
        nsectors.all                = ((len % SECTOR_SIZE) == 0) ? len / SECTOR_SIZE : len / SECTOR_SIZE + 1;


        printk(KERN_INFO "%s %s dma:%d ! \n", __FUNCTION__, drive->name, dma);

        printk(KERN_INFO "%s %s first close other core   ! \n", __FUNCTION__, drive->name);

#ifdef CONFIG_SMP
        /*
         * Note smp_send_stop is the usual smp shutdown function, which
         * unfortunately means it may not be hardened to work in a panic
         * situation.
         */
        smp_send_other_cpu_stop();
#endif

        ndelay(1000);
        /*first reset drive*/
        printk(KERN_INFO "%s %s reset drive   ! \n", __FUNCTION__, drive->name, dma);

       
        //hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG);
        hwif->OUTBSYNC(drive, 0x04, IDE_CONTROL_REG);
        udelay(1000);
        hwif->OUTBSYNC(drive, WIN_SRST, IDE_COMMAND_REG);
       
checkstat:
        udelay(1000);
       
        if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) {
                printk("%s: ATAPI reset complete,stat: %02x\n", drive->name, stat);
        } else {
                if(i++ < 1000){
                        goto checkstat;
                }
                printk("after reset, 1000 cycles,  still busy ide,force to rw,stat:%02x\n", stat);
               
        }
       
       
       
        if (hwif->no_lba48_dma && lba48 && dma) {
                if (block + nsectors.all > 1ULL << 2
                        dma = 0;
                else
                        lba48 = 0;
        }

        if (!dma) {
                printk(KERN_INFO "%s %s don't use dma ! \n", __FUNCTION__, drive->name);
                //ide_init_sg_cmd(drive, rq);
                //ide_map_sg(drive, rq);
        } else
                printk(KERN_INFO "%s %s use dma ! \n", __FUNCTION__,  drive->name);

/*
        if (IDE_CONTROL_REG)
                hwif->OUTB(drive->ctl, IDE_CONTROL_REG);
*/

        tasklets[2] = 1;
        tasklets[3] = block;
        tasklets[4] = (task_ioreg_t) (block>>;
        tasklets[5] = (task_ioreg_t) (block>>16);
        tasklets[6] = (task_ioreg_t)( (block>>24) | 0xe0);

        printk("0-9 regist list: %lx %lx    %lx %lx %lx %lx %lx     %lx  %lx %lx \n",IDE_DATA_REG,IDE_ERROR_REG,
                IDE_NSECTOR_REG, IDE_SECTOR_REG, IDE_LCYL_REG, IDE_HCYL_REG, IDE_SELECT_REG,
                IDE_STATUS_REG,IDE_CONTROL_REG,IDE_IRQ_REG);
       
        printk("%s write register form 2->6 values: 0x%02x 0x%02x  0x%02x 0x%02x 0x%02x\n",
                drive->name, tasklets[2], tasklets[3],
                tasklets[4], tasklets[5], tasklets[6]);
        //hwif->OUTB(0x00, IDE_FEATURE_REG);
        hwif->OUTB(tasklets[2], IDE_NSECTOR_REG);
        hwif->OUTB(tasklets[3], IDE_SECTOR_REG);
        hwif->OUTB(tasklets[4], IDE_LCYL_REG);
        hwif->OUTB(tasklets[5], IDE_HCYL_REG);
        hwif->OUTB(tasklets[6], IDE_SELECT_REG);



        printk(KERN_INFO "%s drive->mult_count:%d  lba48:%d \n", drive->name,drive->mult_count,lba4;
        if (cmd == READ) {
                command =  WIN_READ;
                rw_log_raw(drive, command,  buf, len, 0);
                return ;
        } else {
                command = WIN_WRITE;
                rw_log_raw(drive, command,  buf, len, 1);
        }
        return;
}


/*cmd : READ or         WRITE*/
void panic_ide_log(sector_t block, int cmd, char * buf, int len)
{
        if(panic_log_driver){
                printk(KERN_INFO"%s find panic_log_driver then to rw \n",__FUNCTION__);
                ide_log_raw(panic_log_driver,  block,  cmd,  buf,  len);
        } else {
                printk(KERN_INFO"%s panic_log_driver NULL !!!\n",__FUNCTION__);
        }
}

结果:

begin run panic_ide_log
panic_ide_log find panic_log_driver then to rw
ide_log_raw hdd dma:0 !
ide_log_raw hdd first close other core   !
ide_log_raw hdd reset drive   !
hdd: ATAPI reset complete,stat: 7f
ide_log_raw hdd don't use dma !
0-9 regist list: 170 171    172 173 174 175 176     177  376 0
hdd write register form 2->6 values: 0x01 0x01  0x00 0x00 0xe0
hdd drive->mult_count:16  lba48:1
nsect is 1
write cmd to ide: 0x20
good state , now to read or write,stat:7f  
reading
good state , now to read or write,stat:7f  

ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <6>
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffff
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP