/* ------------------------------------------------------------------------- */
#ifdef CONFIG_IDE_LED
-#if !defined(CONFIG_KUP4K) && !defined(CONFIG_BMS2003)
+#if !defined(CONFIG_KUP4K) && !defined(CONFIG_KUP4X) &&!defined(CONFIG_BMS2003)
static void ide_led (uchar led, uchar status);
#else
extern void ide_led (uchar led, uchar status);
#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
if (strcmp(argv[1],"read") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
- ulong blk = simple_strtoul(argv[3], NULL, 16);
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,
}
} else if (strcmp(argv[1],"write") == 0) {
ulong addr = simple_strtoul(argv[2], NULL, 16);
- ulong blk = simple_strtoul(argv[3], NULL, 16);
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);
#endif /* CONFIG_IDE_8xx_PCCARD */
#ifdef CONFIG_IDE_PREINIT
+ extern int ide_preinit (void);
WATCHDOG_RESET();
if (ide_preinit ()) {
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 __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 */
+#ifdef __PPC__
__asm__ volatile("eieio");
+#endif
*((uchar *)(ATA_CURR_BASE(dev)+port)) = val;
}
#else /* ! __PPC__ */
#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 */
+#ifdef __PPC__
__asm__ volatile("eieio");
+#endif
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);
}
static void
input_swap_data(int dev, ulong *sect_buf, int words)
{
-#ifndef CONFIG_BMS2003
+#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_BMS2003 */
+#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);
dbuf+=1;
}
}
-#endif /* CONFIG_BMS2003 */
+#endif /* CONFIG_HMI10 */
}
#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)
{
-#ifndef CONFIG_BMS2003
+#ifndef CONFIG_HMI10
ushort *dbuf;
volatile ushort *pbuf;
pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
dbuf = (ushort *)sect_buf;
while (words--) {
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*pbuf = *dbuf++;
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*pbuf = *dbuf++;
}
-#else /* CONFIG_BMS2003 */
+#else /* CONFIG_HMI10 */
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
__asm__ volatile ("eieio");
*pbuf_odd = *dbuf++;
}
-#endif /* CONFIG_BMS2003 */
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
static void
}
#endif /* __PPC__ */
-#ifdef __PPC__
+#if defined(__PPC__) || defined(CONFIG_PXA_PCMCIA)
static void
input_data(int dev, ulong *sect_buf, int words)
{
-#ifndef CONFIG_BMS2003
+#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--) {
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*dbuf++ = *pbuf;
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*dbuf++ = *pbuf;
}
-#else /* CONFIG_BMS2003 */
+#else /* CONFIG_HMI10 */
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
__asm__ volatile ("eieio");
*dbuf++ = *pbuf_odd;
}
-#endif /* CONFIG_BMS2003 */
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
static void
__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
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 */
+
+#ifdef CONFIG_LBA48
+ if (iop->command_set_2 & 0x0400) { /* LBA 48 support */
+ 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->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 */
+#ifdef 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;
}
-
+#ifdef 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);
+
+#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);
+
+ } 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 defined(CFG_64BIT_LBA) && defined(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;
+#ifdef 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;
}
-
+#ifdef 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);
+
+#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);
+
+ } 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 defined(CFG_64BIT_LBA) && defined(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;
}
/*
* 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 (start<len) {
- if (src[start]!=' ')
- break;
- start++;
- }
- end=len-1;
- while (end>start) {
- 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) && (src<end) && (*src==' '))
+ ++src;
+
+ /* copy string, omitting trailing white space */
+ while ((*src) && (src<end)) {
+ *dst++ = *src;
+ if (*src++ != ' ')
+ last = dst;
}
- *dest='\0';
+OUT:
+ *last = '\0';
}
/* ------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------- */
-#if defined(CONFIG_IDE_LED) && !defined(CONFIG_AMIGAONEG3SE) && !defined(CONFIG_KUP4K) && !defined(CONFIG_BMS2003)
+#if defined(CONFIG_IDE_LED) && \
+ !defined(CONFIG_AMIGAONEG3SE) && \
+ !defined(CONFIG_KUP4K) && \
+ !defined(CONFIG_KUP4X) && \
+ !defined(CONFIG_HMI10)
static uchar led_buffer = 0; /* Buffer for current LED status */
#define AT_PRINTF(fmt,args...)
#endif
-#ifdef __PPC__
+#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_BMS2003
+#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--) {
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*pbuf = *dbuf++;
}
-#else /* CONFIG_BMS2003 */
+#else /* CONFIG_HMI10 */
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
__asm__ volatile ("eieio");
*pbuf_odd = *dbuf++;
}
-#endif /* CONFIG_BMS2003 */
+#endif /* CONFIG_HMI10 */
}
static void
input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
-#ifndef CONFIG_BMS2003
+#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 shorts base for read is %lx\n", (unsigned long) pbuf);
+
while (shorts--) {
+#ifdef __PPC__
__asm__ volatile ("eieio");
+#endif
*dbuf++ = *pbuf;
}
-#else /* CONFIG_BMS2003 */
+#else /* CONFIG_HMI10 */
uchar *dbuf;
volatile uchar *pbuf_even;
volatile uchar *pbuf_odd;
__asm__ volatile ("eieio");
*dbuf++ = *pbuf_odd;
}
-#endif /* CONFIG_BMS2003 */
+#endif /* CONFIG_HMI10 */
}
#else /* ! __PPC__ */
((unsigned long)iobuf[5]<<16) +
((unsigned long)iobuf[6]<< 8) +
((unsigned long)iobuf[7]);
+#ifdef CONFIG_LBA48
+ dev_desc->lba48 = 0; /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
+#endif
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 */