X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=common%2Fcmd_ide.c;h=b8e0bef574289e6fd112fff5ba1e27519bb6f618;hb=cd172b710822fe170db04fa1e78c08adea56425a;hp=1778b33d69bad2a600f47c711b0cf111d303ef2a;hpb=c40b29568232761e33400e58be86b15a167d3422;p=u-boot diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 1778b33d69..b8e0bef574 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2002 + * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -60,6 +60,11 @@ static unsigned long mips_io_port_base = 0; # define SHOW_BOOT_PROGRESS(arg) #endif +#ifdef __PPC__ +# define EIEIO __asm__ volatile ("eieio") +#else +# define EIEIO /* nothing */ +#endif #undef IDE_DEBUG @@ -135,11 +140,11 @@ static int ide_bus_ok[CFG_IDE_MAXBUS]; static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,}; #endif -static block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; +block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ #ifdef CONFIG_IDE_LED -#if !defined(CONFIG_KUP4K) && !defined(CONFIG_HMI10) +#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003) &&!defined(CONFIG_CPC45) static void ide_led (uchar led, uchar status); #else extern void ide_led (uchar led, uchar status); @@ -303,16 +308,19 @@ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) if (strcmp(argv[1],"read") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); -#if CFG_64BIT_STRTOUL - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); -#endif ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; +#ifdef CFG_64BIT_STRTOUL + lbaint_t blk = simple_strtoull(argv[3], NULL, 16); printf ("\nIDE read: device %d block # %qd, count %ld ... ", curr_device, blk, cnt); +#else + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + + printf ("\nIDE read: device %d block # %ld, count %ld ... ", + curr_device, blk, cnt); +#endif n = ide_dev_desc[curr_device].block_read (curr_device, blk, cnt, @@ -329,16 +337,19 @@ int do_ide (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } else if (strcmp(argv[1],"write") == 0) { ulong addr = simple_strtoul(argv[2], NULL, 16); -#if CFG_64BIT_STRTOUL - lbaint_t blk = simple_strtoull(argv[3], NULL, 16); -#else - lbaint_t blk = simple_strtoul(argv[3], NULL, 16); -#endif ulong cnt = simple_strtoul(argv[4], NULL, 16); ulong n; +#ifdef CFG_64BIT_STRTOUL + lbaint_t blk = simple_strtoull(argv[3], NULL, 16); printf ("\nIDE write: device %d block # %qd, count %ld ... ", curr_device, blk, cnt); +#else + lbaint_t blk = simple_strtoul(argv[3], NULL, 16); + + printf ("\nIDE write: device %d block # %ld, count %ld ... ", + curr_device, blk, cnt); +#endif n = ide_write (curr_device, blk, cnt, (ulong *)addr); @@ -503,6 +514,7 @@ void ide_init (void) #endif /* CONFIG_IDE_8xx_PCCARD */ #ifdef CONFIG_IDE_PREINIT + extern int ide_preinit (void); WATCHDOG_RESET(); if (ide_preinit ()) { @@ -775,15 +787,15 @@ set_pcmcia_timing (int pmode) /* ------------------------------------------------------------------------- */ -#ifdef __PPC__ +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) static void __inline__ ide_outb(int dev, int port, unsigned char val) { - PRINTF ("ide_outb (dev= %d, port= %d, val= 0x%02x) : @ 0x%08lx\n", + PRINTF ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", dev, port, val, (ATA_CURR_BASE(dev)+port)); /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); + EIEIO; *((uchar *)(ATA_CURR_BASE(dev)+port)) = val; } #else /* ! __PPC__ */ @@ -795,15 +807,15 @@ ide_outb(int dev, int port, unsigned char val) #endif /* __PPC__ */ -#ifdef __PPC__ +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) static unsigned char __inline__ ide_inb(int dev, int port) { uchar val; /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); + EIEIO; val = *((uchar *)(ATA_CURR_BASE(dev)+port)); - PRINTF ("ide_inb (dev= %d, port= %d) : @ 0x%08lx -> 0x%02x\n", + PRINTF ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", dev, port, (ATA_CURR_BASE(dev)+port), val); return (val); } @@ -826,9 +838,9 @@ output_data_short(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; } if (words&1) @@ -849,6 +861,8 @@ input_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("in input swap data base for read is %lx\n", (unsigned long) pbuf); + while (words--) { *dbuf++ = ld_le16(pbuf); *dbuf++ = ld_le16(pbuf); @@ -871,7 +885,7 @@ input_swap_data(int dev, ulong *sect_buf, int words) #endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */ -#ifdef __PPC__ +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) static void output_data(int dev, ulong *sect_buf, int words) { @@ -882,9 +896,9 @@ output_data(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf = *dbuf++; } #else /* CONFIG_HMI10 */ @@ -896,13 +910,13 @@ output_data(int dev, ulong *sect_buf, int words) pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); dbuf = (uchar *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf_even = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_odd = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_even = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_odd = *dbuf++; } #endif /* CONFIG_HMI10 */ @@ -915,7 +929,7 @@ output_data(int dev, ulong *sect_buf, int words) } #endif /* __PPC__ */ -#ifdef __PPC__ +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) static void input_data(int dev, ulong *sect_buf, int words) { @@ -925,10 +939,13 @@ input_data(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; + + PRINTF("in input data base for read is %lx\n", (unsigned long) pbuf); + while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf; - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf; } #else /* CONFIG_HMI10 */ @@ -940,13 +957,17 @@ input_data(int dev, ulong *sect_buf, int words) pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); dbuf = (uchar *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; + EIEIO; *dbuf++ = *pbuf_even; - __asm__ volatile ("eieio"); + EIEIO; + EIEIO; *dbuf++ = *pbuf_odd; - __asm__ volatile ("eieio"); + EIEIO; + EIEIO; *dbuf++ = *pbuf_even; - __asm__ volatile ("eieio"); + EIEIO; + EIEIO; *dbuf++ = *pbuf_odd; } #endif /* CONFIG_HMI10 */ @@ -970,9 +991,9 @@ input_data_short(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf; - __asm__ volatile ("eieio"); + EIEIO; } if (words&1) { @@ -992,8 +1013,10 @@ static void ide_ident (block_dev_desc_t *dev_desc) #ifdef CONFIG_AMIGAONEG3SE int max_bus_scan; - int retries = 0; char *s; +#endif +#ifdef CONFIG_ATAPI + int retries = 0; int do_retry = 0; #endif @@ -1024,14 +1047,11 @@ static void ide_ident (block_dev_desc_t *dev_desc) dev_desc->if_type=IF_TYPE_IDE; #ifdef CONFIG_ATAPI -#ifdef CONFIG_AMIGAONEG3SE do_retry = 0; retries = 0; /* Warning: This will be tricky to read */ while (retries <= 1) { -#endif /* CONFIG_AMIGAONEG3SE */ - /* check signature */ if ((ide_inb(device,ATA_SECT_CNT) == 0x01) && (ide_inb(device,ATA_SECT_NUM) == 0x01) && @@ -1062,38 +1082,53 @@ static void ide_ident (block_dev_desc_t *dev_desc) if (((c & ATA_STAT_DRQ) == 0) || ((c & (ATA_STAT_FAULT|ATA_STAT_ERR)) != 0) ) { +#ifdef CONFIG_ATAPI #ifdef CONFIG_AMIGAONEG3SE - if (retries == 0) { - do_retry = 1; - } else { - return; - } -#else - return; -#endif /* CONFIG_AMIGAONEG3SE */ - } - -#ifdef CONFIG_AMIGAONEG3SE - s = getenv("ide_doreset"); - if (s && strcmp(s, "on") == 0 && 1 == do_retry) { - /* Need to soft reset the device in case it's an ATAPI... */ - PRINTF("Retrying...\n"); + s = getenv("ide_doreset"); + if (s && strcmp(s, "on") == 0) +#endif + { + /* Need to soft reset the device in case it's an ATAPI... */ + PRINTF("Retrying...\n"); + ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + udelay(100000); + ide_outb (device, ATA_COMMAND, 0x08); + udelay (500000); /* 500 ms */ + } + /* Select device + */ ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - udelay(100000); - ide_outb (device, ATA_COMMAND, 0x08); - udelay (100000); /* 100 ms */ retries++; - } else { - retries = 100; +#else + return; +#endif } +#ifdef CONFIG_ATAPI + else + break; } /* see above - ugly to read */ -#endif /* CONFIG_AMIGAONEG3SE */ + + if (retries == 2) /* Not found */ + return; +#endif 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)); +#ifdef __LITTLE_ENDIAN + /* + * firmware revision and model number have Big Endian Byte + * order in Word. Convert both to little endian. + * + * See CF+ and CompactFlash Specification Revision 2.0: + * 6.2.1.6: Identfy Drive, Table 39 for more details + */ + + strswab (dev_desc->revision); + strswab (dev_desc->vendor); +#endif /* __LITTLE_ENDIAN */ if ((iop->config & 0x0080)==0x0080) dev_desc->removable = 1; @@ -1135,18 +1170,27 @@ static void ide_ident (block_dev_desc_t *dev_desc) } #endif /* CONFIG_ATAPI */ +#ifdef __BIG_ENDIAN /* swap shorts */ dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16); +#else /* ! __BIG_ENDIAN */ + /* + * do not swap shorts on little endian + * + * See CF+ and CompactFlash Specification Revision 2.0: + * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. + */ + dev_desc->lba = iop->lba_capacity; +#endif /* __BIG_ENDIAN */ -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 if (iop->command_set_2 & 0x0400) { /* LBA 48 support */ - dev_desc->lba48support = 1; - dev_desc->lba48 = (unsigned long long)iop->lba48_capacity[0] | + dev_desc->lba48 = 1; + dev_desc->lba = (unsigned long long)iop->lba48_capacity[0] | ((unsigned long long)iop->lba48_capacity[1] << 16) | ((unsigned long long)iop->lba48_capacity[2] << 32) | ((unsigned long long)iop->lba48_capacity[3] << 48); } else { - dev_desc->lba48support = 0; dev_desc->lba48 = 0; } #endif /* CONFIG_LBA48 */ @@ -1180,7 +1224,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) ulong n = 0; unsigned char c; unsigned char pwrsave=0; /* power save */ -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 unsigned char lba48 = 0; if (blknr & 0x0000fffff0000000) { @@ -1232,7 +1276,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) printf ("IDE read: device %d not ready\n", device); break; } -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 if (lba48) { /* write high bits */ ide_outb (device, ATA_SECT_CNT, 0); @@ -1246,7 +1290,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF); ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 if (lba48) { ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) ); ide_outb (device, ATA_COMMAND, ATA_CMD_READ_EXT); @@ -1270,7 +1314,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) } if ((c&(ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if CFG_64BIT_LBA && CFG_64BIT_VSPRINTF +#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n", device, blknr, c); #else @@ -1299,7 +1343,7 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) { ulong n = 0; unsigned char c; -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 unsigned char lba48 = 0; if (blknr & 0x0000fffff0000000) { @@ -1322,7 +1366,7 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) printf ("IDE read: device %d not ready\n", device); goto WR_OUT; } -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 if (lba48) { /* write high bits */ ide_outb (device, ATA_SECT_CNT, 0); @@ -1336,7 +1380,7 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF); ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); -#if CONFIG_LBA48 +#ifdef CONFIG_LBA48 if (lba48) { ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) ); ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE_EXT); @@ -1355,7 +1399,7 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) 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) { -#if CFG_64BIT_LBA && CFG_64BIT_VSPRINTF +#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n", device, blknr, c); #else @@ -1381,27 +1425,31 @@ WR_OUT: /* * copy src to dest, skipping leading and trailing blanks and null * terminate the string + * "len" is the size of available memory including the terminating '\0' */ -static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len) +static void ident_cpy (unsigned char *dst, unsigned char *src, unsigned int len) { - int start,end; + unsigned char *end, *last; - start=0; - while (startstart) { - if (src[end]!=' ') - break; - end--; - } - for ( ; start<=end; start++) { - *dest++=src[start]; + last = dst; + end = src + len - 1; + + /* reserve space for '\0' */ + if (len < 2) + goto OUT; + + /* skip leading white space */ + while ((*src) && (srclba48 = 0; /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ +#endif return; }