#ifdef CONFIG_8xx
# include <mpc8xx.h>
#endif
+#ifdef CONFIG_MPC5xxx
+#include <mpc5xxx.h>
+#endif
#include <ide.h>
#include <ata.h>
-#include <cmd_ide.h>
-#include <cmd_disk.h>
#ifdef CONFIG_STATUS_LED
# include <status_led.h>
#endif
-#ifdef __I386__
+#ifndef __PPC__
#include <asm/io.h>
+#ifdef __MIPS__
+/* Macros depend on this variable */
+static unsigned long mips_io_port_base = 0;
+#endif
#endif
#ifdef CONFIG_SHOW_BOOT_PROGRESS
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
+#ifdef CONFIG_IDE_8xx_DIRECT
/* Timings for IDE Interface
*
* SETUP / LENGTH / HOLD - cycles valid for 50 MHz clk
#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
+#endif /* CONFIG_IDE_8xx_DIRECT */
+
/* ------------------------------------------------------------------------- */
/* Current I/O Device */
#endif
};
-#ifdef __PPC__
+
#define ATA_CURR_BASE(dev) (CFG_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
-#endif
#ifndef CONFIG_AMIGAONEG3SE
static int ide_bus_ok[CFG_IDE_MAXBUS];
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_IDE_LED
+#if !defined(CONFIG_KUP4K) && !defined(CONFIG_HMI10)
static void ide_led (uchar led, uchar status);
#else
+extern void ide_led (uchar led, uchar status);
+#endif
+#else
#ifndef CONFIG_AMIGAONEG3SE
#define ide_led(a,b) /* dummy */
#else
static void __inline__ ide_outb(int dev, int port, unsigned char val);
static unsigned char __inline__ ide_inb(int dev, int port);
-#ifdef __PPC__
-static void input_swap_data(int dev, ulong *sect_buf, int words);
-#endif
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);
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
-ulong atapi_read (int device, ulong blknr, ulong blkcnt, ulong *buffer);
+ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer);
#endif
#ifdef CONFIG_IDE_8xx_DIRECT
static void set_pcmcia_timing (int pmode);
-#else
-#define set_pcmcia_timing(a) /* dummy */
#endif
/* ------------------------------------------------------------------------- */
if (strcmp(argv[1],"read") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
- ulong blk = simple_strtoul(argv[3], 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;
- printf ("\nIDE read: device %d block # %ld, count %ld ... ",
+ printf ("\nIDE read: device %d block # %qd, count %ld ... ",
curr_device, blk, cnt);
n = ide_dev_desc[curr_device].block_read (curr_device,
}
} else if (strcmp(argv[1],"write") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
- ulong blk = simple_strtoul(argv[3], 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;
- printf ("\nIDE write: device %d block # %ld, count %ld ... ",
+ printf ("\nIDE write: device %d block # %qd, count %ld ... ",
curr_device, blk, cnt);
n = ide_write (curr_device, blk, cnt, (ulong *)addr);
SHOW_BOOT_PROGRESS (-1);
return 1;
}
- if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
+ if ((strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) &&
+ (strncmp(info.type, BOOT_PART_COMP, sizeof(info.type)) != 0)) {
printf ("\n** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info.type);
void ide_init (void)
{
- DECLARE_GLOBAL_DATA_PTR;
#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 int ata_reset_time;
char *s;
#endif
+#ifdef CONFIG_IDE_8xx_PCCARD
+ extern int pcmcia_on (void);
+ extern int ide_devices_found; /* Initialized in check_ide_device() */
+#endif /* CONFIG_IDE_8xx_PCCARD */
+
+#ifdef CONFIG_IDE_PREINIT
+ WATCHDOG_RESET();
+
+ if (ide_preinit ()) {
+ puts ("ide_preinit failed\n");
+ return;
+ }
+#endif /* CONFIG_IDE_PREINIT */
#ifdef CONFIG_IDE_8xx_PCCARD
extern int pcmcia_on (void);
+ extern int ide_devices_found; /* Initialized in check_ide_device() */
WATCHDOG_RESET();
+ ide_devices_found = 0;
/* initialize the PCMCIA IDE adapter card */
- if (pcmcia_on())
+ pcmcia_on();
+ if (!ide_devices_found)
return;
udelay (1000000); /* 1 s */
#endif /* CONFIG_IDE_8xx_PCCARD */
WATCHDOG_RESET();
+#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,
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 */
/* Reset the IDE just to be sure.
* Light LED's to show
#ifdef CONFIG_IDE_8xx_DIRECT
/* 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);
+#endif /* CONFIG_IDE_8xx_DIRECT */
/*
* Wait for IDE to get ready.
int dev = bus * (CFG_IDE_MAXDEVICE / max_bus_scan);
#endif
+#ifdef CONFIG_IDE_8xx_PCCARD
+ /* Skip non-ide devices from probing */
+ if ((ide_devices_found & (1 << bus)) == 0) {
+ ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
+ continue;
+ }
+#endif
printf ("Bus %d: ", bus);
ide_bus_ok[bus] = 0;
ide_led ((LED_IDE1 | LED_IDE2), 0); /* LED's off */
#ifdef CONFIG_AMIGAONEG3SE
/* If this is the second bus, the first one was OK */
- if (bus != 0)
- {
+ if (bus != 0) {
ide_bus_ok[bus] = 0;
goto skip_bus;
}
#ifdef CONFIG_IDE_LED
int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
#endif
+ ide_dev_desc[i].type=DEV_TYPE_UNKNOWN;
ide_dev_desc[i].if_type=IF_TYPE_IDE;
ide_dev_desc[i].dev=i;
ide_dev_desc[i].part_type=PART_TYPE_UNKNOWN;
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",
+ dev, port, val, (ATA_CURR_BASE(dev)+port));
+
/* Ensure I/O operations complete */
__asm__ volatile("eieio");
*((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
-#if 0
- printf ("ide_outb: 0x%08lx <== 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
-#endif
}
#else /* ! __PPC__ */
static void __inline__
ide_outb(int dev, int port, unsigned char val)
{
- outb(val, port);
+ outb(val, ATA_CURR_BASE(dev)+port);
}
#endif /* __PPC__ */
/* Ensure I/O operations complete */
__asm__ volatile("eieio");
val = *((uchar *)(ATA_CURR_BASE(dev)+port));
-#if 0
- printf ("ide_inb: 0x%08lx ==> 0x%02x\n", ATA_CURR_BASE(dev)+port, val);
-#endif
+ PRINTF ("ide_inb (dev= %d, port= %d) : @ 0x%08lx -> 0x%02x\n",
+ dev, port, (ATA_CURR_BASE(dev)+port), val);
return (val);
}
#else /* ! __PPC__ */
static unsigned char __inline__
ide_inb(int dev, int port)
{
- return inb(port);
+ return inb(ATA_CURR_BASE(dev)+port);
}
#endif /* __PPC__ */
#ifdef __PPC__
-__inline__ unsigned ld_le16(const volatile unsigned short *addr)
-{
- unsigned val;
-
- __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r"(val) : "r"(addr), "m"(*addr));
- return val;
-}
-
-#ifdef CONFIG_AMIGAONEG3SE
+# ifdef CONFIG_AMIGAONEG3SE
static void
output_data_short(int dev, ulong *sect_buf, int words)
{
ushort *dbuf;
volatile ushort *pbuf;
-
+
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
if (words&1)
*pbuf = 0;
}
-#endif
+# 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)
+#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;
*dbuf++ = ld_le16(pbuf);
*dbuf++ = ld_le16(pbuf);
}
-}
-#else /* ! __PPC__ */
-#define input_swap_data(x,y,z) input_data(x,y,z)
-#endif /* __PPC__ */
-
+#else /* CONFIG_HMI10 */
+ 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);
+ ushort *dbuf = (ushort *)sect_buf;
+ while (words--) {
+ for (i=0; i<2; i++) {
+ *(((uchar *)(dbuf)) + 1) = *pbuf_even;
+ *(uchar *)dbuf = *pbuf_odd;
+ dbuf+=1;
+ }
+ }
+#endif /* CONFIG_HMI10 */
+}
+#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */
#ifdef __PPC__
static void
output_data(int dev, ulong *sect_buf, int words)
{
+#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
__asm__ volatile ("eieio");
*pbuf = *dbuf++;
}
+#else /* CONFIG_HMI10 */
+ uchar *dbuf;
+ volatile uchar *pbuf_even;
+ volatile uchar *pbuf_odd;
+
+ pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
+ pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
+ dbuf = (uchar *)sect_buf;
+ while (words--) {
+ __asm__ volatile ("eieio");
+ *pbuf_even = *dbuf++;
+ __asm__ volatile ("eieio");
+ *pbuf_odd = *dbuf++;
+ __asm__ volatile ("eieio");
+ *pbuf_even = *dbuf++;
+ __asm__ volatile ("eieio");
+ *pbuf_odd = *dbuf++;
+ }
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
static void
output_data(int dev, ulong *sect_buf, int words)
{
- outsw(ATA_DATA_REG, sect_buf, words<<1);
+ outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1);
}
#endif /* __PPC__ */
static void
input_data(int dev, ulong *sect_buf, int words)
{
+#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
__asm__ volatile ("eieio");
*dbuf++ = *pbuf;
}
+#else /* CONFIG_HMI10 */
+ uchar *dbuf;
+ volatile uchar *pbuf_even;
+ volatile uchar *pbuf_odd;
+
+ pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
+ pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
+ dbuf = (uchar *)sect_buf;
+ while (words--) {
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_even;
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_odd;
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_even;
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_odd;
+ }
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
static void
input_data(int dev, ulong *sect_buf, int words)
{
- insw(ATA_DATA_REG, sect_buf, words << 1);
+ insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
}
#endif /* __PPC__ */
__asm__ volatile ("eieio");
}
- if (words&1)
- {
+ if (words&1) {
ushort dummy;
dummy = *pbuf;
}
retries = 0;
/* Warning: This will be tricky to read */
- while (retries <= 1)
- {
+ while (retries <= 1) {
#endif /* CONFIG_AMIGAONEG3SE */
/* check signature */
* to become ready
*/
c = ide_wait (device, ATAPI_TIME_OUT);
- }
- else
+ } else
#endif
{
/* Start Ident Command
if (retries == 0) {
do_retry = 1;
} else {
- dev_desc->type=DEV_TYPE_UNKNOWN;
return;
}
#else
- dev_desc->type=DEV_TYPE_UNKNOWN;
return;
#endif /* CONFIG_AMIGAONEG3SE */
}
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;
}
#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
+ if (iop->command_set_2 & 0x0400) { /* LBA 48 support */
+ dev_desc->lba48support = 1;
+ dev_desc->lba48 = (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 */
/* assuming HD */
dev_desc->type=DEV_TYPE_HARDDISK;
dev_desc->blksz=ATA_BLOCKSIZE;
/* ------------------------------------------------------------------------- */
-ulong ide_read (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+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
+ unsigned char lba48 = 0;
- PRINTF ("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",
+ if (blknr & 0x0000fffff0000000) {
+ /* more than 28 bits used, use 48bit mode */
+ lba48 = 1;
+ }
+#endif
+ PRINTF ("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 */
printf ("IDE read: device %d not ready\n", device);
break;
}
-
+#if CONFIG_LBA48
+ if (lba48) {
+ /* write high bits */
+ ide_outb (device, ATA_SECT_CNT, 0);
+ ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+ ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+ ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+ }
+#endif
ide_outb (device, ATA_SECT_CNT, 1);
ide_outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
- ide_outb (device, ATA_DEV_HD, ATA_LBA |
- ATA_DEVICE(device) |
- ((blknr >> 24) & 0xF) );
- ide_outb (device, ATA_COMMAND, ATA_CMD_READ);
+
+#if CONFIG_LBA48
+ if (lba48) {
+ ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) );
+ ide_outb (device, ATA_COMMAND, ATA_CMD_READ_EXT);
+
+ } else
+#endif
+ {
+ ide_outb (device, ATA_DEV_HD, ATA_LBA |
+ ATA_DEVICE(device) |
+ ((blknr >> 24) & 0xF) );
+ ide_outb (device, ATA_COMMAND, ATA_CMD_READ);
+ }
udelay (50);
}
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",
+#if CFG_64BIT_LBA && CFG_64BIT_VSPRINTF
+ printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n",
device, blknr, c);
+#else
+ printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+ device, (ulong)blknr, c);
+#endif
break;
}
/* ------------------------------------------------------------------------- */
-ulong ide_write (int device, ulong blknr, ulong blkcnt, ulong *buffer)
+ulong ide_write (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
{
ulong n = 0;
unsigned char c;
+#if CONFIG_LBA48
+ unsigned char lba48 = 0;
+
+ if (blknr & 0x0000fffff0000000) {
+ /* more than 28 bits used, use 48bit mode */
+ lba48 = 1;
+ }
+#endif
ide_led (DEVICE_LED(device), 1); /* LED on */
printf ("IDE read: device %d not ready\n", device);
goto WR_OUT;
}
-
+#if CONFIG_LBA48
+ if (lba48) {
+ /* write high bits */
+ ide_outb (device, ATA_SECT_CNT, 0);
+ ide_outb (device, ATA_LBA_LOW, (blknr >> 24) & 0xFF);
+ ide_outb (device, ATA_LBA_MID, (blknr >> 32) & 0xFF);
+ ide_outb (device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF);
+ }
+#endif
ide_outb (device, ATA_SECT_CNT, 1);
ide_outb (device, ATA_LBA_LOW, (blknr >> 0) & 0xFF);
ide_outb (device, ATA_LBA_MID, (blknr >> 8) & 0xFF);
ide_outb (device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF);
- ide_outb (device, ATA_DEV_HD, ATA_LBA |
- ATA_DEVICE(device) |
- ((blknr >> 24) & 0xF) );
- ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE);
+
+#if CONFIG_LBA48
+ if (lba48) {
+ ide_outb (device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device) );
+ ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE_EXT);
+
+ } else
+#endif
+ {
+ ide_outb (device, ATA_DEV_HD, ATA_LBA |
+ ATA_DEVICE(device) |
+ ((blknr >> 24) & 0xF) );
+ ide_outb (device, ATA_COMMAND, ATA_CMD_WRITE);
+ }
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",
+#if CFG_64BIT_LBA && CFG_64BIT_VSPRINTF
+ printf ("Error (no IRQ) dev %d blk %qd: status 0x%02x\n",
device, blknr, c);
+#else
+ printf ("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
+ device, (ulong)blknr, c);
+#endif
goto WR_OUT;
}
/* ------------------------------------------------------------------------- */
-#if defined(CONFIG_IDE_LED) && !defined(CONFIG_AMIGAONEG3SE)
+#if defined(CONFIG_IDE_LED) && !defined(CONFIG_AMIGAONEG3SE) && !defined(CONFIG_KUP4K) && !defined(CONFIG_HMI10)
static uchar led_buffer = 0; /* Buffer for current LED status */
*/
-
#undef ATAPI_DEBUG
#ifdef ATAPI_DEBUG
static void
output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
+#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
__asm__ volatile ("eieio");
*pbuf = *dbuf++;
}
+#else /* CONFIG_HMI10 */
+ uchar *dbuf;
+ volatile uchar *pbuf_even;
+ volatile uchar *pbuf_odd;
+
+ pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
+ pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
+ while (shorts--) {
+ __asm__ volatile ("eieio");
+ *pbuf_even = *dbuf++;
+ __asm__ volatile ("eieio");
+ *pbuf_odd = *dbuf++;
+ }
+#endif /* CONFIG_HMI10 */
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
+#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
__asm__ volatile ("eieio");
*dbuf++ = *pbuf;
}
+#else /* CONFIG_HMI10 */
+ uchar *dbuf;
+ volatile uchar *pbuf_even;
+ volatile uchar *pbuf_odd;
+
+ pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN);
+ pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD);
+ while (shorts--) {
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_even;
+ __asm__ volatile ("eieio");
+ *dbuf++ = *pbuf_odd;
+ }
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
static void
output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
- outsw(ATA_DATA_REG, sect_buf, shorts);
+ outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
- insw(ATA_DATA_REG, sect_buf, shorts);
+ insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
}
#endif /* __PPC__ */
}
-
static void atapi_inquiry(block_dev_desc_t * dev_desc)
{
unsigned char ccb[12]; /* Command descriptor block */
((unsigned long)iobuf[5]<<16) +
((unsigned long)iobuf[6]<< 8) +
((unsigned long)iobuf[7]);
+ dev_desc->lba48 = 0; /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
return;
}
#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, ulong blknr, ulong blkcnt, ulong *buffer)
+ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, ulong *buffer)
{
ulong n = 0;
unsigned char ccb[12]; /* Command descriptor block */
#endif /* CONFIG_ATAPI */
+U_BOOT_CMD(
+ ide, 5, 1, do_ide,
+ "ide - IDE sub-system\n",
+ "reset - reset IDE controller\n"
+ "ide info - show available IDE devices\n"
+ "ide device [dev] - show or set current device\n"
+ "ide part [dev] - print partition table of one or all IDE devices\n"
+ "ide read addr blk# cnt\n"
+ "ide write addr blk# cnt - read/write `cnt'"
+ " blocks starting at block `blk#'\n"
+ " to/from memory address `addr'\n"
+);
+
+U_BOOT_CMD(
+ diskboot, 3, 1, do_diskboot,
+ "diskboot- boot from IDE device\n",
+ "loadAddr dev:part\n"
+);
+
#endif /* CONFIG_COMMANDS & CFG_CMD_IDE */