X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fcmd_ide.c;h=97a873d1c96a517f3e96db09038f44f1ea421083;hb=7f9f4347cf325c63a39fe30910f3fb211ae2cc15;hp=b8e0bef574289e6fd112fff5ba1e27519bb6f618;hpb=cd172b710822fe170db04fa1e78c08adea56425a;p=oweals%2Fu-boot.git diff --git a/common/cmd_ide.c b/common/cmd_ide.c index b8e0bef574..97a873d1c9 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2000-2004 + * (C) Copyright 2000-2005 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this @@ -31,52 +31,39 @@ #include #include #include +#include + #if defined(CONFIG_IDE_8xx_DIRECT) || defined(CONFIG_IDE_PCMCIA) # include #endif + #ifdef CONFIG_8xx # include #endif + #ifdef CONFIG_MPC5xxx #include #endif + #include #include + #ifdef CONFIG_STATUS_LED # include #endif -#ifndef __PPC__ -#include -#ifdef __MIPS__ -/* Macros depend on this variable */ -static unsigned long mips_io_port_base = 0; -#endif -#endif -#ifdef CONFIG_SHOW_BOOT_PROGRESS -# include -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) -#else -# define SHOW_BOOT_PROGRESS(arg) +#ifdef CONFIG_IDE_8xx_DIRECT +DECLARE_GLOBAL_DATA_PTR; #endif #ifdef __PPC__ # define EIEIO __asm__ volatile ("eieio") +# define SYNC __asm__ volatile ("sync") #else # define EIEIO /* nothing */ +# define SYNC /* nothing */ #endif -#undef IDE_DEBUG - - -#ifdef IDE_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#endif - -#if (CONFIG_COMMANDS & CFG_CMD_IDE) - #ifdef CONFIG_IDE_8xx_DIRECT /* Timings for IDE Interface * @@ -132,12 +119,10 @@ ulong ide_bus_offset[CFG_IDE_MAXBUS] = { }; -#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)]) - #ifndef CONFIG_AMIGAONEG3SE -static int ide_bus_ok[CFG_IDE_MAXBUS]; +static int ide_bus_ok[CFG_IDE_MAXBUS]; #else -static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,}; +static int ide_bus_ok[CFG_IDE_MAXBUS] = {0,}; #endif block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE]; @@ -176,16 +161,19 @@ static uchar ide_wait (int dev, ulong t); #define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ -static void __inline__ ide_outb(int dev, int port, unsigned char val); -static unsigned char __inline__ ide_inb(int dev, int port); +void inline ide_outb(int dev, int port, unsigned char val); +unsigned char inline ide_inb(int dev, int port); static void input_data(int dev, ulong *sect_buf, int words); static void output_data(int dev, ulong *sect_buf, int words); static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); +#ifndef CFG_ATA_PORT_ADDR +#define CFG_ATA_PORT_ADDR(port) (port) +#endif #ifdef CONFIG_ATAPI static void atapi_inquiry(block_dev_desc_t *dev_desc); -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer); +ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer); #endif @@ -374,12 +362,15 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *boot_device = NULL; char *ep; int dev, part = 0; - ulong cnt; - ulong addr; + ulong addr, cnt; disk_partition_t info; image_header_t *hdr; int rcode = 0; +#if defined(CONFIG_FIT) + const void *fit_hdr = NULL; +#endif + show_boot_progress (41); switch (argc) { case 1: addr = CFG_LOAD_ADDR; @@ -395,81 +386,120 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) break; default: printf ("Usage:\n%s\n", cmdtp->usage); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-42); return 1; } + show_boot_progress (42); if (!boot_device) { puts ("\n** No boot device **\n"); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-43); return 1; } + show_boot_progress (43); dev = simple_strtoul(boot_device, &ep, 16); if (ide_dev_desc[dev].type==DEV_TYPE_UNKNOWN) { printf ("\n** Device %d not available\n", dev); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-44); return 1; } + show_boot_progress (44); if (*ep) { if (*ep != ':') { puts ("\n** Invalid boot device, use `dev[:part]' **\n"); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-45); return 1; } part = simple_strtoul(++ep, NULL, 16); } + show_boot_progress (45); if (get_partition_info (&ide_dev_desc[dev], part, &info)) { - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-46); return 1; } - if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && - (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { + show_boot_progress (46); + if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) && + (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) { printf ("\n** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info.type); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-47); return 1; } + show_boot_progress (47); printf ("\nLoading from IDE device %d, partition %d: " "Name: %.32s Type: %.32s\n", dev, part, info.name, info.type); - PRINTF ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", + debug ("First Block: %ld, # of blocks: %ld, Block Size: %ld\n", info.start, info.size, info.blksz); if (ide_dev_desc[dev].block_read (dev, info.start, 1, (ulong *)addr) != 1) { printf ("** Read error on %d:%d\n", dev, part); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-48); return 1; } + show_boot_progress (48); - hdr = (image_header_t *)addr; + switch (genimg_get_format ((void *)addr)) { + case IMAGE_FORMAT_LEGACY: + hdr = (image_header_t *)addr; - if (ntohl(hdr->ih_magic) == IH_MAGIC) { + show_boot_progress (49); - print_image_hdr (hdr); + if (!image_check_hcrc (hdr)) { + puts ("\n** Bad Header Checksum **\n"); + show_boot_progress (-50); + return 1; + } + show_boot_progress (50); - cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t)); - cnt += info.blksz - 1; - cnt /= info.blksz; - cnt -= 1; - } else { - printf("\n** Bad Magic Number **\n"); - SHOW_BOOT_PROGRESS (-1); + image_print_contents (hdr); + + cnt = image_get_image_size (hdr); + break; +#if defined(CONFIG_FIT) + case IMAGE_FORMAT_FIT: + fit_hdr = (const void *)addr; + puts ("Fit image detected...\n"); + + cnt = fit_get_size (fit_hdr); + break; +#endif + default: + show_boot_progress (-49); + puts ("** Unknown image type\n"); return 1; } + cnt += info.blksz - 1; + cnt /= info.blksz; + cnt -= 1; + if (ide_dev_desc[dev].block_read (dev, info.start+1, cnt, (ulong *)(addr+info.blksz)) != cnt) { printf ("** Read error on %d:%d\n", dev, part); - SHOW_BOOT_PROGRESS (-1); + show_boot_progress (-51); return 1; } + show_boot_progress (51); +#if defined(CONFIG_FIT) + /* This cannot be done earlier, we need complete FIT image in RAM first */ + if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { + if (!fit_check_format (fit_hdr)) { + show_boot_progress (-140); + puts ("** Bad FIT image format\n"); + return 1; + } + show_boot_progress (141); + fit_print_contents (fit_hdr); + } +#endif /* Loading ok, update default load address */ @@ -497,16 +527,17 @@ void ide_init (void) { #ifdef CONFIG_IDE_8xx_DIRECT - DECLARE_GLOBAL_DATA_PTR; volatile immap_t *immr = (immap_t *)CFG_IMMR; volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); #endif unsigned char c; int i, bus; +#if defined(CONFIG_AMIGAONEG3SE) || defined(CONFIG_SC3) + unsigned int ata_reset_time = ATA_RESET_TIME; + char *s; +#endif #ifdef CONFIG_AMIGAONEG3SE unsigned int max_bus_scan; - unsigned int ata_reset_time; - char *s; #endif #ifdef CONFIG_IDE_8xx_PCCARD extern int pcmcia_on (void); @@ -542,19 +573,19 @@ void ide_init (void) #ifdef CONFIG_IDE_8xx_DIRECT /* Initialize PIO timing tables */ for (i=0; i <= IDE_MAX_PIO_MODE; ++i) { - pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup, - gd->bus_clk); - pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length, - gd->bus_clk); - pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, - gd->bus_clk); - 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); + pio_config_clk[i].t_setup = PCMCIA_MK_CLKS(pio_config_ns[i].t_setup, + gd->bus_clk); + pio_config_clk[i].t_length = PCMCIA_MK_CLKS(pio_config_ns[i].t_length, + gd->bus_clk); + pio_config_clk[i].t_hold = PCMCIA_MK_CLKS(pio_config_ns[i].t_hold, + gd->bus_clk); + debug ( "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); } #endif /* CONFIG_IDE_8xx_DIRECT */ @@ -583,9 +614,9 @@ void ide_init (void) #else s = getenv("ide_maxbus"); if (s) - max_bus_scan = simple_strtol(s, NULL, 10); + max_bus_scan = simple_strtol(s, NULL, 10); else - max_bus_scan = CFG_IDE_MAXBUS; + max_bus_scan = CFG_IDE_MAXBUS; for (bus=0; bus (ata_reset_time * 100)) { #else if (i > (ATA_RESET_TIME * 100)) { @@ -628,8 +658,8 @@ void ide_init (void) #ifdef CONFIG_AMIGAONEG3SE /* If this is the second bus, the first one was OK */ if (bus != 0) { - ide_bus_ok[bus] = 0; - goto skip_bus; + ide_bus_ok[bus] = 0; + goto skip_bus; } #endif return; @@ -641,11 +671,11 @@ void ide_init (void) if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { puts ("not available "); - PRINTF ("Status = 0x%02X ", c); + debug ("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); + debug ("Status = 0x%02X ", c); #endif } else { puts ("OK "); @@ -693,7 +723,7 @@ void ide_init (void) block_dev_desc_t * ide_get_dev(int dev) { - return ((block_dev_desc_t *)&ide_dev_desc[dev]); + return (dev < CFG_IDE_MAXDEVICE) ? &ide_dev_desc[dev] : NULL; } @@ -706,7 +736,7 @@ set_pcmcia_timing (int pmode) volatile pcmconf8xx_t *pcmp = &(immr->im_pcmcia); ulong timings; - PRINTF ("Set timing for PIO Mode %d\n", pmode); + debug ("Set timing for PIO Mode %d\n", pmode); timings = PCMCIA_SHT(pio_config_clk[pmode].t_hold) | PCMCIA_SST(pio_config_clk[pmode].t_setup) @@ -721,7 +751,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); + debug ("PBR0: %08x POR0: %08x\n", pcmp->pcmc_pbr0, pcmp->pcmc_por0); pcmp->pcmc_pbr1 = CFG_PCMCIA_PBR1; pcmp->pcmc_por1 = CFG_PCMCIA_POR1 @@ -729,7 +759,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); + debug ("PBR1: %08x POR1: %08x\n", pcmp->pcmc_pbr1, pcmp->pcmc_por1); pcmp->pcmc_pbr2 = CFG_PCMCIA_PBR2; pcmp->pcmc_por2 = CFG_PCMCIA_POR2 @@ -737,7 +767,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); + debug ("PBR2: %08x POR2: %08x\n", pcmp->pcmc_pbr2, pcmp->pcmc_por2); pcmp->pcmc_pbr3 = CFG_PCMCIA_PBR3; pcmp->pcmc_por3 = CFG_PCMCIA_POR3 @@ -745,7 +775,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); + debug ("PBR3: %08x POR3: %08x\n", pcmp->pcmc_pbr3, pcmp->pcmc_por3); /* IDE 1 */ @@ -755,7 +785,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); + debug ("PBR4: %08x POR4: %08x\n", pcmp->pcmc_pbr4, pcmp->pcmc_por4); pcmp->pcmc_pbr5 = CFG_PCMCIA_PBR5; pcmp->pcmc_por5 = CFG_PCMCIA_POR5 @@ -763,7 +793,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); + debug ("PBR5: %08x POR5: %08x\n", pcmp->pcmc_pbr5, pcmp->pcmc_por5); pcmp->pcmc_pbr6 = CFG_PCMCIA_PBR6; pcmp->pcmc_por6 = CFG_PCMCIA_POR6 @@ -771,7 +801,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); + debug ("PBR6: %08x POR6: %08x\n", pcmp->pcmc_pbr6, pcmp->pcmc_por6); pcmp->pcmc_pbr7 = CFG_PCMCIA_PBR7; pcmp->pcmc_por7 = CFG_PCMCIA_POR7 @@ -779,7 +809,7 @@ set_pcmcia_timing (int pmode) | timings #endif ; - PRINTF ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7); + debug ("PBR7: %08x POR7: %08x\n", pcmp->pcmc_pbr7, pcmp->pcmc_por7); } @@ -787,45 +817,27 @@ set_pcmcia_timing (int pmode) /* ------------------------------------------------------------------------- */ -#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= 0x%x, val= 0x%02x) : @ 0x%08lx\n", - dev, port, val, (ATA_CURR_BASE(dev)+port)); - - /* Ensure I/O operations complete */ - EIEIO; - *((uchar *)(ATA_CURR_BASE(dev)+port)) = val; -} -#else /* ! __PPC__ */ -static void __inline__ -ide_outb(int dev, int port, unsigned char val) +void inline +__ide_outb(int dev, int port, unsigned char val) { - outb(val, ATA_CURR_BASE(dev)+port); + debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", + dev, port, val, (ATA_CURR_BASE(dev)+CFG_ATA_PORT_ADDR(port))); + outb(val, (ATA_CURR_BASE(dev)+CFG_ATA_PORT_ADDR(port))); } -#endif /* __PPC__ */ - +void inline ide_outb (int dev, int port, unsigned char val) + __attribute__((weak, alias("__ide_outb"))); -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) -static unsigned char __inline__ -ide_inb(int dev, int port) +unsigned char inline +__ide_inb(int dev, int port) { uchar val; - /* Ensure I/O operations complete */ - EIEIO; - val = *((uchar *)(ATA_CURR_BASE(dev)+port)); - PRINTF ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", - dev, port, (ATA_CURR_BASE(dev)+port), val); - return (val); + val = inb((ATA_CURR_BASE(dev)+CFG_ATA_PORT_ADDR(port))); + debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", + dev, port, (ATA_CURR_BASE(dev)+CFG_ATA_PORT_ADDR(port)), val); + return val; } -#else /* ! __PPC__ */ -static unsigned char __inline__ -ide_inb(int dev, int port) -{ - return inb(ATA_CURR_BASE(dev)+port); -} -#endif /* __PPC__ */ +unsigned char inline ide_inb(int dev, int port) + __attribute__((weak, alias("__ide_inb"))); #ifdef __PPC__ # ifdef CONFIG_AMIGAONEG3SE @@ -844,30 +856,20 @@ output_data_short(int dev, ulong *sect_buf, int words) } if (words&1) - *pbuf = 0; + *pbuf = 0; } # endif /* CONFIG_AMIGAONEG3SE */ #endif /* __PPC_ */ /* We only need to swap data if we are running on a big endian cpu. */ /* But Au1x00 cpu:s already swaps data in big endian mode! */ -#if defined(__LITTLE_ENDIAN) || defined(CONFIG_AU1X00) +#if defined(__LITTLE_ENDIAN) || ( defined(CONFIG_AU1X00) && !defined(CONFIG_GTH2) ) #define input_swap_data(x,y,z) input_data(x,y,z) #else static void input_swap_data(int dev, ulong *sect_buf, int words) { -#ifndef CONFIG_HMI10 - 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); - } -#else /* CONFIG_HMI10 */ +#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) uchar i; volatile uchar *pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); volatile uchar *pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); @@ -880,28 +882,34 @@ input_swap_data(int dev, ulong *sect_buf, int words) dbuf+=1; } } -#endif /* CONFIG_HMI10 */ +#else + volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + ushort *dbuf = (ushort *)sect_buf; + + debug("in input swap data base for read is %lx\n", (unsigned long) pbuf); + + while (words--) { +#ifdef __MIPS__ + *dbuf++ = swab16p((u16*)pbuf); + *dbuf++ = swab16p((u16*)pbuf); +#elif defined(CONFIG_PCS440EP) + *dbuf++ = *pbuf; + *dbuf++ = *pbuf; +#else + *dbuf++ = ld_le16(pbuf); + *dbuf++ = ld_le16(pbuf); +#endif /* !MIPS */ + } +#endif } #endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */ -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH) static void output_data(int dev, ulong *sect_buf, int words) { -#ifndef CONFIG_HMI10 - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - while (words--) { - EIEIO; - *pbuf = *dbuf++; - EIEIO; - *pbuf = *dbuf++; - } -#else /* CONFIG_HMI10 */ +#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -919,7 +927,27 @@ output_data(int dev, ulong *sect_buf, int words) EIEIO; *pbuf_odd = *dbuf++; } -#endif /* CONFIG_HMI10 */ +#else + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + while (words--) { +#if defined(CONFIG_PCS440EP) + /* not tested, because CF was write protected */ + EIEIO; + *pbuf = ld_le16(dbuf++); + EIEIO; + *pbuf = ld_le16(dbuf++); +#else + EIEIO; + *pbuf = *dbuf++; + EIEIO; + *pbuf = *dbuf++; +#endif + } +#endif } #else /* ! __PPC__ */ static void @@ -929,26 +957,11 @@ output_data(int dev, ulong *sect_buf, int words) } #endif /* __PPC__ */ -#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) +#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) || defined(CONFIG_SH) static void input_data(int dev, ulong *sect_buf, int words) { -#ifndef CONFIG_HMI10 - ushort *dbuf; - volatile ushort *pbuf; - - 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--) { - EIEIO; - *dbuf++ = *pbuf; - EIEIO; - *dbuf++ = *pbuf; - } -#else /* CONFIG_HMI10 */ +#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -957,20 +970,42 @@ 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--) { + *dbuf++ = *pbuf_even; EIEIO; + SYNC; + *dbuf++ = *pbuf_odd; EIEIO; + SYNC; *dbuf++ = *pbuf_even; EIEIO; - EIEIO; + SYNC; *dbuf++ = *pbuf_odd; EIEIO; + SYNC; + } +#else + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + + debug("in input data base for read is %lx\n", (unsigned long) pbuf); + + while (words--) { +#if defined(CONFIG_PCS440EP) EIEIO; - *dbuf++ = *pbuf_even; + *dbuf++ = ld_le16(pbuf); + EIEIO; + *dbuf++ = ld_le16(pbuf); +#else EIEIO; + *dbuf++ = *pbuf; EIEIO; - *dbuf++ = *pbuf_odd; + *dbuf++ = *pbuf; +#endif } -#endif /* CONFIG_HMI10 */ +#endif } #else /* ! __PPC__ */ static void @@ -997,8 +1032,8 @@ input_data_short(int dev, ulong *sect_buf, int words) } if (words&1) { - ushort dummy; - dummy = *pbuf; + ushort dummy; + dummy = *pbuf; } } #endif @@ -1087,14 +1122,14 @@ static void ide_ident (block_dev_desc_t *dev_desc) 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 */ - } + { + /* Need to soft reset the device in case it's an ATAPI... */ + debug ("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)); @@ -1114,9 +1149,9 @@ static void ide_ident (block_dev_desc_t *dev_desc) 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)); + ident_cpy ((unsigned char*)dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision)); + ident_cpy ((unsigned char*)dev_desc->vendor, iop->model, sizeof(dev_desc->vendor)); + ident_cpy ((unsigned char*)dev_desc->product, iop->serial_no, sizeof(dev_desc->product)); #ifdef __LITTLE_ENDIAN /* * firmware revision and model number have Big Endian Byte @@ -1144,16 +1179,16 @@ static void ide_ident (block_dev_desc_t *dev_desc) printf ("tPIO = 0x%02x = %d\n",mode, mode); if (mode > 2) { /* 2 is maximum allowed tPIO value */ mode = 2; - PRINTF ("Override tPIO -> 2\n"); + debug ("Override tPIO -> 2\n"); } if (iop->field_valid & 2) { /* drive implements ATA2? */ - PRINTF ("Drive implements ATA2\n"); + debug ("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); + debug ("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 */ @@ -1199,7 +1234,7 @@ static void ide_ident (block_dev_desc_t *dev_desc) dev_desc->blksz=ATA_BLOCKSIZE; dev_desc->lun=0; /* just to fill something in... */ -#if 0 /* only used to test the powersaving mode, +#if 0 /* only used to test the powersaving mode, * if enabled, the drive goes after 5 sec * in standby mode */ ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); @@ -1208,8 +1243,7 @@ static void ide_ident (block_dev_desc_t *dev_desc) ide_outb (device, ATA_LBA_LOW, 0); ide_outb (device, ATA_LBA_MID, 0); ide_outb (device, ATA_LBA_HIGH, 0); - ide_outb (device, ATA_DEV_HD, ATA_LBA | - ATA_DEVICE(device)); + ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); ide_outb (device, ATA_COMMAND, 0xe3); udelay (50); c = ide_wait (device, IDE_TIME_OUT); /* can't take over 500 ms */ @@ -1219,7 +1253,7 @@ static void ide_ident (block_dev_desc_t *dev_desc) /* ------------------------------------------------------------------------- */ -ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char c; @@ -1227,12 +1261,12 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) #ifdef CONFIG_LBA48 unsigned char lba48 = 0; - if (blknr & 0x0000fffff0000000) { + if (blknr & 0x0000fffff0000000ULL) { /* more than 28 bits used, use 48bit mode */ lba48 = 1; } #endif - PRINTF ("ide_read dev %d start %qX, blocks %lX buffer at %lX\n", + debug ("ide_read dev %d start %qX, blocks %lX buffer at %lX\n", device, blknr, blkcnt, (ulong)buffer); ide_led (DEVICE_LED(device), 1); /* LED on */ @@ -1262,7 +1296,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) printf ("No Powersaving mode %X\n", c); } else { c = ide_inb(device,ATA_SECT_CNT); - PRINTF("Powersaving %02X\n",c); + debug ("Powersaving %02X\n",c); if(c==0) pwrsave=1; } @@ -1281,8 +1315,13 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) /* write high bits */ ide_outb (device, ATA_SECT_CNT, 0); ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); +#ifdef CFG_64BIT_LBA ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF); ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); +#else + ide_outb (device, ATA_LBA_MID, 0); + ide_outb (device, ATA_LBA_HIGH, 0); +#endif } #endif ide_outb (device, ATA_SECT_CNT, 1); @@ -1329,7 +1368,7 @@ ulong ide_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) ++n; ++blknr; - buffer += ATA_SECTORWORDS; + buffer += ATA_BLOCKSIZE; } IDE_READ_E: ide_led (DEVICE_LED(device), 0); /* LED off */ @@ -1339,14 +1378,14 @@ IDE_READ_E: /* ------------------------------------------------------------------------- */ -ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char c; #ifdef CONFIG_LBA48 unsigned char lba48 = 0; - if (blknr & 0x0000fffff0000000) { + if (blknr & 0x0000fffff0000000ULL) { /* more than 28 bits used, use 48bit mode */ lba48 = 1; } @@ -1371,8 +1410,13 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) /* write high bits */ ide_outb (device, ATA_SECT_CNT, 0); ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); +#ifdef CFG_64BIT_LBA ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF); ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); +#else + ide_outb (device, ATA_LBA_MID, 0); + ide_outb (device, ATA_LBA_HIGH, 0); +#endif } #endif ide_outb (device, ATA_SECT_CNT, 1); @@ -1413,7 +1457,7 @@ ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) c = ide_inb (device, ATA_STATUS); /* clear IRQ */ ++n; ++blknr; - buffer += ATA_SECTORWORDS; + buffer += ATA_BLOCKSIZE; } WR_OUT: ide_led (DEVICE_LED(device), 0); /* LED off */ @@ -1492,6 +1536,9 @@ static void ide_reset (void) ide_set_reset (1); /* assert reset */ + /* the reset signal shall be asserted for et least 25 us */ + udelay(25); + WATCHDOG_RESET(); #ifdef CFG_PB_12V_ENABLE @@ -1583,34 +1630,13 @@ static void ide_led (uchar led, uchar status) * ATAPI Support */ -#undef ATAPI_DEBUG - -#ifdef ATAPI_DEBUG -#define AT_PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define AT_PRINTF(fmt,args...) -#endif - #if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA) /* since ATAPI may use commands with not 4 bytes alligned length * we have our own transfer functions, 2 bytes alligned */ static void output_data_shorts(int dev, ushort *sect_buf, int shorts) { -#ifndef CONFIG_HMI10 - ushort *dbuf; - volatile ushort *pbuf; - - pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); - dbuf = (ushort *)sect_buf; - - PRINTF("in output data shorts base for read is %lx\n", (unsigned long) pbuf); - - while (shorts--) { - EIEIO; - *pbuf = *dbuf++; - } -#else /* CONFIG_HMI10 */ +#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -1623,26 +1649,26 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *pbuf_odd = *dbuf++; } -#endif /* CONFIG_HMI10 */ -} - -static void -input_data_shorts(int dev, ushort *sect_buf, int shorts) -{ -#ifndef CONFIG_HMI10 +#else ushort *dbuf; volatile ushort *pbuf; pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; - PRINTF("in input data shorts base for read is %lx\n", (unsigned long) pbuf); + debug ("in output data shorts base for read is %lx\n", (unsigned long) pbuf); while (shorts--) { EIEIO; - *dbuf++ = *pbuf; + *pbuf = *dbuf++; } -#else /* CONFIG_HMI10 */ +#endif +} + +static void +input_data_shorts(int dev, ushort *sect_buf, int shorts) +{ +#if defined(CONFIG_HMI10) || defined(CONFIG_CPC45) uchar *dbuf; volatile uchar *pbuf_even; volatile uchar *pbuf_odd; @@ -1655,7 +1681,20 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *dbuf++ = *pbuf_odd; } -#endif /* CONFIG_HMI10 */ +#else + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + + debug("in input data shorts base for read is %lx\n", (unsigned long) pbuf); + + while (shorts--) { + EIEIO; + *dbuf++ = *pbuf; + } +#endif } #else /* ! __PPC__ */ @@ -1745,7 +1784,7 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha } output_data_shorts (device, (unsigned short *)ccb,ccblen/2); /* write command block */ - /* ATAPI Command written wait for completition */ + /* ATAPI Command written wait for completition */ udelay (5000); /* device must set bsy */ mask = ATA_STAT_DRQ|ATA_STAT_BUSY|ATA_STAT_ERR; @@ -1758,7 +1797,7 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha if ((c & mask) != res ) { if (c & ATA_STAT_ERR) { err=(ide_inb(device,ATA_ERROR_REG))>>4; - AT_PRINTF("atapi_issue 1 returned sense key %X status %02X\n",err,c); + debug ("atapi_issue 1 returned sense key %X status %02X\n",err,c); } else { printf ("ATTAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", ccb[0],c); err=0xFF; @@ -1779,18 +1818,18 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha goto AI_OUT; } if(n!=buflen) { - AT_PRINTF("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen); + debug ("WARNING, transfer bytes %d not equal with requested %d\n",n,buflen); } if(n!=0) { /* data transfer */ - AT_PRINTF("ATAPI_ISSUE: %d Bytes to transfer\n",n); + debug ("ATAPI_ISSUE: %d Bytes to transfer\n",n); /* we transfer shorts */ n>>=1; /* ok now decide if it is an in or output */ if ((ide_inb(device, ATA_SECT_CNT)&0x02)==0) { - AT_PRINTF("Write to device\n"); + debug ("Write to device\n"); output_data_shorts(device,(unsigned short *)buffer,n); } else { - AT_PRINTF("Read from device @ %p shorts %d\n",buffer,n); + debug ("Read from device @ %p shorts %d\n",buffer,n); input_data_shorts(device,(unsigned short *)buffer,n); } } @@ -1800,7 +1839,7 @@ unsigned char atapi_issue(int device,unsigned char* ccb,int ccblen, unsigned cha c = atapi_wait_mask(device,ATAPI_TIME_OUT,mask,res); if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { err=(ide_inb(device,ATA_ERROR_REG) >> 4); - AT_PRINTF("atapi_issue 2 returned sense key %X status %X\n",err,c); + debug ("atapi_issue 2 returned sense key %X status %X\n",err,c); } else { err = 0; } @@ -1814,7 +1853,7 @@ AI_OUT: * returns, an request_sense will be issued */ -#define ATAPI_DRIVE_NOT_READY 100 +#define ATAPI_DRIVE_NOT_READY 100 #define ATAPI_UNIT_ATTN 10 unsigned char atapi_issue_autoreq (int device, @@ -1848,7 +1887,7 @@ retry: if (res==0xFF) return (0xFF); /* error */ - AT_PRINTF("(auto_req)atapi_issue returned sense key %X\n",res); + debug ("(auto_req)atapi_issue returned sense key %X\n",res); memset(sense_ccb,0,sizeof(sense_ccb)); memset(sense_data,0,sizeof(sense_data)); @@ -1860,8 +1899,8 @@ retry: asc=(sense_data[12]); ascq=(sense_data[13]); - AT_PRINTF("ATAPI_CMD_REQ_SENSE returned %x\n",res); - AT_PRINTF(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", + debug ("ATAPI_CMD_REQ_SENSE returned %x\n",res); + debug (" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", sense_data[0], key, asc, @@ -1887,13 +1926,13 @@ retry: goto error; } if(asc==0x3a) { - AT_PRINTF("Media not present\n"); + debug ("Media not present\n"); goto error; } #ifdef CONFIG_AMIGAONEG3SE if ((sense_data[2]&0xF)==0x0B) { - AT_PRINTF("ABORTED COMMAND...retry\n"); + debug ("ABORTED COMMAND...retry\n"); if (retrycnt++ < 4) goto retry; return (0xFF); @@ -1902,7 +1941,7 @@ retry: if ((sense_data[2]&0xf) == 0x02 && sense_data[12] == 0x04 && sense_data[13] == 0x01 ) { - AT_PRINTF("Waiting for unit to become active\n"); + debug ("Waiting for unit to become active\n"); udelay(timeout); if (retrycnt++ < 4) goto retry; @@ -1912,7 +1951,7 @@ retry: printf ("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); error: - AT_PRINTF ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); + debug ("ERROR Sense key %02X ASC %02X ASCQ %02X\n",key,asc,ascq); return (0xFF); } @@ -1935,14 +1974,14 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) ccb[4]=40; /* allocation Legnth */ c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,40); - AT_PRINTF("ATAPI_CMD_INQUIRY returned %x\n",c); + debug ("ATAPI_CMD_INQUIRY returned %x\n",c); if (c!=0) return; /* copy device ident strings */ - ident_cpy(dev_desc->vendor,&iobuf[8],8); - ident_cpy(dev_desc->product,&iobuf[16],16); - ident_cpy(dev_desc->revision,&iobuf[32],5); + ident_cpy((unsigned char*)dev_desc->vendor,&iobuf[8],8); + ident_cpy((unsigned char*)dev_desc->product,&iobuf[16],16); + ident_cpy((unsigned char*)dev_desc->revision,&iobuf[32],5); dev_desc->lun=0; dev_desc->lba=0; @@ -1961,7 +2000,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0); - AT_PRINTF("ATAPI_CMD_START_STOP returned %x\n",c); + debug ("ATAPI_CMD_START_STOP returned %x\n",c); if (c!=0) return; @@ -1969,7 +2008,7 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) memset(iobuf,0,sizeof(iobuf)); c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,0); - AT_PRINTF("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c); + debug ("ATAPI_CMD_UNIT_TEST_READY returned %x\n",c); if (c!=0) return; @@ -1977,11 +2016,11 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) memset(iobuf,0,sizeof(iobuf)); ccb[0]=ATAPI_CMD_READ_CAP; c=atapi_issue_autoreq(device,ccb,12,(unsigned char *)iobuf,8); - AT_PRINTF("ATAPI_CMD_READ_CAP returned %x\n",c); + debug ("ATAPI_CMD_READ_CAP returned %x\n",c); if (c!=0) return; - AT_PRINTF("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", + debug ("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", iobuf[0],iobuf[1],iobuf[2],iobuf[3], iobuf[4],iobuf[5],iobuf[6],iobuf[7]); @@ -2009,13 +2048,13 @@ static void atapi_inquiry(block_dev_desc_t * dev_desc) #define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ #define ATAPI_READ_MAX_BLOCK ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE /* max blocks */ -ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) +ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer) { ulong n = 0; unsigned char ccb[12]; /* Command descriptor block */ ulong cnt; - AT_PRINTF("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n", + debug ("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n", device, blknr, blkcnt, (ulong)buffer); do { @@ -2045,7 +2084,7 @@ ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer) n+=cnt; blkcnt-=cnt; blknr+=cnt; - buffer+=cnt*(ATAPI_READ_BLOCK_SIZE/4); /* ulong blocksize in ulong */ + buffer+=(cnt*ATAPI_READ_BLOCK_SIZE); } while (blkcnt > 0); return (n); } @@ -2072,5 +2111,3 @@ U_BOOT_CMD( "diskboot- boot from IDE device\n", "loadAddr dev:part\n" ); - -#endif /* CONFIG_COMMANDS & CFG_CMD_IDE */