📄 ide.c
字号:
outl( inl(GPIO_PADR) & ~0x8, GPIO_PADR ); //Power on delay (300000); ulTemp = inl(SMC_PCMCIACtrl) | PCCONT_WEN | PCCONT_PC1EN | PCCONT_PC1RST; outl( ulTemp, SMC_PCMCIACtrl ); ulTemp = (inl(SMC_PCMCIACtrl) | PCCONT_WEN | PCCONT_PC1EN) & ~PCCONT_PC1RST; delay (10); outl( ulTemp, SMC_PCMCIACtrl ); ulTemp = inl(SMC_PCMCIACtrl); delay (500000); if (pcmcia_check_ide_device (PCMCIA_ADDR_ATTR)) { outl( inl(GPIO_PADR) | 0x8, GPIO_PADR ); //Power off delay (300000); return -1; } outb(0x02, PCMCIA_ADDR_IO + 0xe); return 0;}static unsigned char pcmcia_inb (unsigned int addr){ return inb(addr);}static unsigned short pcmcia_inw (unsigned int addr){ return inw(addr);}static void pcmcia_outb (unsigned char b, unsigned int addr){ outb (b, addr);}static void pcmcia_outw (unsigned short w, unsigned int addr){ outb (w, addr);}static unsigned int ide_data_port;static unsigned int ide_ctrl_port;#define IDE_DATA (ide_data_port + 0x00)#define IDE_ERROR (ide_data_port + 0x01)#define IDE_FEAUTURES (ide_data_port + 0x01)#define IDE_SECTOR_COUNT (ide_data_port + 0x02)#define IDE_SECTOR_NUMBER (ide_data_port + 0x03)#define IDE_SECTOR_CYLINDER_LOW (ide_data_port + 0x04)#define IDE_SECTOR_CYLINDER_HIGH (ide_data_port + 0x05)#define IDE_DEVICE_HEAD (ide_data_port + 0x06)#define IDE_STATUS (ide_data_port + 0x07)#define IDE_COMMAND (ide_data_port + 0x07)#define IDE_ALTERNATE_STATUS (ide_ctrl_port + 0x00)#define IDE_DEVICE_CONTROL (ide_ctrl_port + 0x00)#define IDE_STATUS_BUSY 0x80#define IDE_STATUS_DRDY 0x40#define IDE_STATUS_DRQ 0x08#define IDE_STATUS_ERR 0x01#define IDE_COMMAND_READ_SECTORS 0x20#define IDE_COMMAND_IDLE 0xe3#define IDE_COMMAND_IDENTIFY 0xec#define IDE_DEVICE_CONTROL_SRST 0x04#define IDE_DEVICE_CONTROL_NIEN 0x02#define IDE_LBA 0x40static int wait_nbusy_ndrq (void){ int i; for (i = 0; i < TIMEOUT && (ide_inb (IDE_ALTERNATE_STATUS) & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)); i++) { delay (100); } if (i >= TIMEOUT) { return -1; } return 0;}static int wait_nbusy (void){ int i; for (i = 0; i < TIMEOUT && (ide_inb (IDE_ALTERNATE_STATUS) & IDE_STATUS_BUSY); i++) { delay (100); } if (i >= TIMEOUT) { return -1; } return 0;}static int wait_ready (void){ int i; for (i = 0; i < TIMEOUT && !(ide_inb (IDE_ALTERNATE_STATUS) & IDE_STATUS_DRDY); i++) { delay (100); } if (i >= TIMEOUT) { return -1; } return 0;}static int ide_reset (int device){ int ret; unsigned char error; switch (device) { case 0: ide_init = _ide_init; ide_inb = _ide_inb; ide_inw = _ide_inw; ide_outb = _ide_outb; ide_outw = _ide_outw; ide_data_port = 0x800; ide_ctrl_port = 0x406; break; case 1: ide_init = pcmcia_ide_init; ide_inb = pcmcia_inb; ide_inw = pcmcia_inw; ide_outb = pcmcia_outb; ide_outw = pcmcia_outw; ide_data_port = PCMCIA_ADDR_IO; ide_ctrl_port = PCMCIA_ADDR_IO + 0xe; break; default: return -1; } ret = ide_init (); if (ret) { return ret; } ide_outb (IDE_DEVICE_CONTROL_SRST | IDE_DEVICE_CONTROL_NIEN, IDE_DEVICE_CONTROL); delay (40000); ide_outb (IDE_DEVICE_CONTROL_NIEN, IDE_DEVICE_CONTROL); delay (40000); ret = wait_nbusy (); if (ret) { return ret; } error = ide_inb (IDE_ERROR); if (error != 0 && error != 1) { return -1; } return 0;}static int ide_device_selection (int dev){ int ret; ret = wait_nbusy_ndrq (); if (ret) { return ret; } ide_outb (IDE_DEVICE_CONTROL_NIEN, IDE_DEVICE_CONTROL); ide_outb (dev << 4, IDE_DEVICE_HEAD); delay (100); return wait_nbusy_ndrq ();}static int ide_register_check (void){ ide_outb (0x55, IDE_SECTOR_CYLINDER_LOW); ide_outb (0xaa, IDE_SECTOR_CYLINDER_HIGH); if (ide_inb (IDE_SECTOR_CYLINDER_LOW) != 0x55) { return -1; } if (ide_inb (IDE_SECTOR_CYLINDER_HIGH) != 0xaa) { return -1; } return 0;}static int ide_get_data (unsigned char *buf, int count){ int ret, i; unsigned short data; while (count--) { ret = wait_nbusy (); if (ret) { return ret; } if (ide_inb (IDE_ALTERNATE_STATUS) & IDE_STATUS_ERR) { return -1; } for (i = 0; i < 256; i++) { data = ide_inw (IDE_DATA); *buf++ = data & 0xff; *buf++ = data >> 8; } } return 0;}static void ide_fix_string (unsigned char *dest, unsigned char *src, int num){ int i; for (i = 0; i < num; i+= 2) { *dest++ = *(src + 1); *dest++ = *src; src += 2; } while (*--dest == (' ')) ; ++dest; *dest++ = ' '; *dest++ = '\0';}static int ide_identify_device (int dev){ int ret; unsigned short buf[256]; unsigned char name[42]; ret = ide_device_selection (dev); if (ret) { return ret; } ret = wait_ready (); if (ret) { return ret; } ide_outb (IDE_COMMAND_IDENTIFY, IDE_COMMAND); delay (100); ret = ide_get_data ((unsigned char *)buf, 1); if (ret) { return ret; } if (*buf & 0x04) { return -1; } hprintf ("Disk drive detected: "); ide_fix_string (name, (unsigned char *)&buf[27], 40); hprintf ("%s", name); ide_fix_string (name, (unsigned char *)&buf[23], 8); hprintf ("%s", name); ide_fix_string (name, (unsigned char *)&buf[10], 20); hprintf ("%s", name); hprintf ("\n"); return 0;}static int ide_idle (int dev){ int ret; ret = ide_device_selection (0); if (ret) { return ret; } ret = wait_ready (); if (ret) { return ret; } ide_outb (0x00, IDE_SECTOR_COUNT); ide_outb (IDE_COMMAND_IDLE, IDE_COMMAND); delay (100); return wait_nbusy_ndrq ();}int ide_detect_devices (int device){ int ret; ret = ide_reset (device); if (ret) { return ret; } ret = ide_device_selection (0); if (ret) { return ret; } ret = ide_register_check (); if (ret) { return ret; } return ide_identify_device (0);}int ide_startup_devices (void){ return ide_idle (0);}int ide_read_sectors (int dev, unsigned long lba, unsigned char *buf, int count){ int ret; ret = ide_device_selection (dev); if (ret) { return ret; } ret = wait_ready (); if (ret) { return ret; } ide_outb (count, IDE_SECTOR_COUNT); ide_outb (lba & 0xff, IDE_SECTOR_NUMBER); ide_outb ((lba & 0xff00) >> 8, IDE_SECTOR_CYLINDER_LOW); ide_outb ((lba & 0xff0000) >> 16, IDE_SECTOR_CYLINDER_HIGH); ide_outb (IDE_LBA | (dev << 4) | ((lba & 0xf000000) >> 24), IDE_DEVICE_HEAD); ide_outb (IDE_COMMAND_READ_SECTORS, IDE_COMMAND); delay (100); return ide_get_data (buf, count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -