?? cmd_ide.c
字號:
WE_DONT_HAVE_BD_BI_BUSFREQ); pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, WE_DONT_HAVE_BD_BI_BUSFREQ); PRINTF ("PIO Mode %d: setup=%2d ns/%d clk" " len=%3d ns/%d clk" " hold=%2d ns/%d clk\n", i, pio_config_ns[i].t_setup, pio_config_clk[i].t_setup, pio_config_ns[i].t_length, pio_config_clk[i].t_length, pio_config_ns[i].t_hold, pio_config_clk[i].t_hold); } /* Reset the IDE just to be sure. * Light LED's to show */ ide_led ((LED_IDE1 | LED_IDE2), 1); /* LED's on */ ide_reset (); /* ATAPI Drives seems to need a proper IDE Reset */#ifdef CONFIG_IDE_PCMCIA /* PCMCIA / IDE initialization for common mem space */ pcmp->pcmc_pgcrb = 0;#endif /* start in PIO mode 0 - most relaxed timings */ pio_mode = 0; set_pcmcia_timing (pio_mode); /* * Wait for IDE to get ready. * According to spec, this can take up to 31 seconds! */ for (bus=0; bus<CFG_IDE_MAXBUS; ++bus) { int dev = bus * (CFG_IDE_MAXDEVICE / CFG_IDE_MAXBUS); printf ("Bus %d: ", bus); ide_bus_ok[bus] = 0; /* Select device */#if defined(CONFIG_WATCHDOG) watchdog_reset ();#endif /* CONFIG_WATCHDOG */ udelay (100000); /* 100 ms */ outb (dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev));#if defined(CONFIG_WATCHDOG) watchdog_reset ();#endif /* CONFIG_WATCHDOG */ udelay (100000); /* 100 ms */ i = 0; do {#if defined(CONFIG_WATCHDOG) watchdog_reset ();#endif /* CONFIG_WATCHDOG */ udelay (10000); /* 10 ms */ c = inb (dev, ATA_STATUS); i++; if (i > (ATA_RESET_TIME * 100)) { puts ("** Timeout **\n"); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ return; } if ((i >= 100) && ((i%100)==0)) { putc ('.'); } } while (c & ATA_STAT_BUSY); if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { printf ("Status 0x%02x ", c);#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */ } else if ((c & ATA_STAT_READY) == 0) { puts ("not available "); PRINTF ("Status = 0x%02X ", c);#endif } else { puts ("OK "); ide_bus_ok[bus] = 1; }#if defined(CONFIG_WATCHDOG) watchdog_reset ();#endif /* CONFIG_WATCHDOG */ } putc ('\n'); ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */ curr_device = -1; for (i=0; i<CFG_IDE_MAXDEVICE; ++i) {#ifdef CONFIG_IDE_LED int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;#endif ide_dev_desc[i].if_type=IF_TYPE_IDE; ide_dev_desc[i].dev=i; ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz=0; ide_dev_desc[i].lba=0; ide_dev_desc[i].block_read=ide_read; if (!ide_bus_ok[IDE_BUS(i)]) continue; ide_led (led, 1); /* LED on */ ide_ident(&ide_dev_desc[i]); ide_led (led, 0); /* LED off */ dev_print(&ide_dev_desc[i]);/* ide_print (i); *//* if((ide_device[i].size > 0) && (ide_dev_desc[i].if_type==IF_TYPE_IDE)) */ if((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { init_part (&ide_dev_desc[i]); /* initialize partition type */ if(curr_device < 0) curr_device = i; } }#if defined(CONFIG_WATCHDOG) watchdog_reset ();#endif /* CONFIG_WATCHDOG */}/* ------------------------------------------------------------------------- */block_dev_desc_t * ide_get_dev(int dev){ return((block_dev_desc_t *)&ide_dev_desc[dev]);}#ifdef CONFIG_IDE_PCMCIAstatic voidset_pcmcia_timing (int pmode){ volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); ulong timings; timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold) | PCMCIA_SST(pio_config_clk[pmode].t_setup) | PCMCIA_SL (pio_config_clk[pmode].t_length) ; /* IDE 0 */ pcmp->pcmc_pbr0 = CFG_PCMCIA_PBR0; pcmp->pcmc_por0 = CFG_PCMCIA_POR0#if (CFG_PCMCIA_POR0 != 0) | timings#endif ; PRINTF ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1; pcmp->pcmc_por1 = CFG_PCMCIA_POR1#if (CFG_PCMCIA_POR1 != 0) | timings#endif ; PRINTF ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2; pcmp->pcmc_por2 = CFG_PCMCIA_POR2#if (CFG_PCMCIA_POR2 != 0) | timings#endif ; PRINTF ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3; pcmp->pcmc_por3 = CFG_PCMCIA_POR3#if (CFG_PCMCIA_POR3 != 0) | timings#endif ; PRINTF ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); /* IDE 1 */ pcmp->pcmc_pbr4 = CFG_PCMCIA_PBR4; pcmp->pcmc_por4 = CFG_PCMCIA_POR4#if (CFG_PCMCIA_POR4 != 0) | timings#endif ; PRINTF ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5; pcmp->pcmc_por5 = CFG_PCMCIA_POR5#if (CFG_PCMCIA_POR5 != 0) | timings#endif ; PRINTF ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6; pcmp->pcmc_por6 = CFG_PCMCIA_POR6#if (CFG_PCMCIA_POR6 != 0) | timings#endif ; PRINTF ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7; pcmp->pcmc_por7 = CFG_PCMCIA_POR7#if (CFG_PCMCIA_POR7 != 0) | timings#endif ; PRINTF ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7);}#endif /* CONFIG_IDE_PCMCIA *//* ------------------------------------------------------------------------- */static void __inline__outb(int dev, int port, unsigned char val){ /* Ensure I/O operations complete */ //__asm__ volatile("eieio");#if 0 printf ("OUTB on dev %d, 0x%08lx + 0x%08lx <== 0x%02x\n", dev, ATA_CURR_BASE(dev), port, val);#endif *((uchar *)(ATA_CURR_BASE(dev)+port)) = val;}static unsigned char __inline__inb(int dev, int port){ uchar val; /* Ensure I/O operations complete */ //__asm__ volatile("eieio");#if 0 printf ("INB: 0x%08lx", ATA_CURR_BASE(dev)+port);#endif val = *((uchar *)(ATA_CURR_BASE(dev)+port));// printf ("==> 0x%02x\n", val); return (val);}__inline__ unsigned ld_le16(const volatile unsigned short *addr){ //unsigned val; unsigned short *val; char buf[2], tmp; val = (unsigned short *)&buf;// printf("access on %p\n", addr); *val = *addr; tmp = buf[0]; buf[0] = buf[1]; buf[1] = tmp; return *val;}static voidinput_swap_data(int dev, ulong *sect_buf, int words){ volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); ushort *dbuf = (ushort *)sect_buf;// printf("input_swap_data on %p\n", sect_buf); while (words--) { *dbuf++ = ld_le16(pbuf); *dbuf++ = ld_le16(pbuf); }}static voidoutput_data(int dev, ulong *sect_buf, int words){ ushort *dbuf; volatile ushort *pbuf;// printf("output_data on %p\n", sect_buf); pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { //__asm__ volatile ("eieio"); *pbuf = *dbuf++; //__asm__ volatile ("eieio"); *pbuf = *dbuf++; }}static voidinput_data(int dev, ulong *sect_buf, int words){ ushort *dbuf; volatile ushort *pbuf;// printf("input_data on %p\n", sect_buf); pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { //__asm__ volatile ("eieio"); *dbuf++ = *pbuf; //__asm__ volatile ("eieio"); *dbuf++ = *pbuf; }}/* ------------------------------------------------------------------------- */static void ide_ident (block_dev_desc_t *dev_desc){ ulong iobuf[ATA_SECTORWORDS]; unsigned char c; hd_driveid_t *iop = (hd_driveid_t *)iobuf;#if 0 int mode, cycle_time;#endif int device; device=dev_desc->dev; printf (" Device %d: ", device); ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device */ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); dev_desc->if_type=IF_TYPE_IDE;#ifdef CONFIG_ATAPI /* check signature */ if((inb(device,ATA_SECT_CNT)==0x01) && (inb(device,ATA_SECT_NUM)==0x01) && (inb(device,ATA_CYL_LOW)==0x14) && (inb(device,ATA_CYL_HIGH)==0xEB)) { /* ATAPI Signature found */ dev_desc->if_type=IF_TYPE_ATAPI; /* Start Ident Command */ outb (device, ATA_COMMAND, ATAPI_CMD_IDENT); /* Wait for completion ATAPI devices need more time to become ready */ c = ide_wait (device, ATAPI_TIME_OUT); } else#endif { /* Start Ident Command */ outb (device, ATA_COMMAND, ATA_CMD_IDENT); /* Wait for completion */ c = ide_wait (device, IDE_TIME_OUT); } ide_led (DEVICE_LED(device), 0); /* LED off */ if (((c & ATA_STAT_READY) == 0) || ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { dev_desc->type=DEV_TYPE_UNKNOWN; return; } input_swap_data (device, iobuf, ATA_SECTORWORDS); ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision)); ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor)); ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product)); if((iop->config & 0x0080)==0x0080) dev_desc->removable = 1; else dev_desc->removable = 0;#if 0 /* * Drive PIO mode autoselection */ mode = iop->tPIO; printf ("tPIO = 0x%02x = %d\n",mode, mode); if (mode > 2) { /* 2 is maximum allowed tPIO value */ mode = 2; PRINTF ("Override tPIO -> 2\n"); } if (iop->field_valid & 2) { /* drive implements ATA2? */ PRINTF ("Drive implements ATA2\n"); if (iop->capability & 8) { /* drive supports use_iordy? */ cycle_time = iop->eide_pio_iordy; } else { cycle_time = iop->eide_pio; } PRINTF ("cycle time = %d\n", cycle_time); mode = 4; if (cycle_time > 120) mode = 3; /* 120 ns for PIO mode 4 */ if (cycle_time > 180) mode = 2; /* 180 ns for PIO mode 3 */ if (cycle_time > 240) mode = 1; /* 240 ns for PIO mode 4 */ if (cycle_time > 383) mode = 0; /* 383 ns for PIO mode 4 */ } printf ("PIO mode to use: PIO %d\n", mode);#endif#ifdef CONFIG_ATAPI if(dev_desc->if_type==IF_TYPE_ATAPI) { atapi_inquiry(dev_desc); return; } #endif /* swap shorts */ //dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16); dev_desc->lba = iop->lba_capacity; /* assuming HD */ dev_desc->type=DEV_TYPE_HARDDISK; dev_desc->blksz=ATA_BLOCKSIZE; dev_desc->lun=0; /* just to fill something in... */ }/* ------------------------------------------------------------------------- */ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer){ ulong n = 0; unsigned char c; PRINTF("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",device,blknr,blkcnt,(ulong)buffer); ide_led (DEVICE_LED(device), 1); /* LED on */ /* Select device */ outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); while (blkcnt-- > 0) { c = ide_wait (device, IDE_TIME_OUT); if (c & ATA_STAT_BUSY) { printf ("IDE read: device %d not ready\n", device); goto RD_OUT; } outb (device, ATA_SECT_CNT, 1); outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF); outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) | ((blknr >> 24) & 0xF) ); outb (device, ATA_COMMAND, ATA_CMD_READ); udelay (50); c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n", device, blknr, c); goto RD_OUT; } input_data (device, buffer, ATA_SECTORWORDS); (void) inb (device, ATA_STATUS); /* clear IRQ */ ++n; ++blknr; buffer += ATA_SECTORWORDS; }RD_OUT:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -