* (C) Copyright 2000-2011
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
+ * SPDX-License-Identifier: GPL-2.0+
*/
/*
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
-static ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt,
+static ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt,
void *buffer);
#endif
/* ------------------------------------------------------------------------- */
-void __ide_led(uchar led, uchar status)
+__weak void ide_led(uchar led, uchar status)
{
#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
static uchar led_buffer; /* Buffer for current LED status */
#endif
}
-void ide_led(uchar led, uchar status)
- __attribute__ ((weak, alias("__ide_led")));
-
#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
# define DEVICE_LED(x) 0
# define LED_IDE1 1
/* ------------------------------------------------------------------------- */
-inline void __ide_outb(int dev, int port, unsigned char val)
+__weak void ide_outb(int dev, int port, unsigned char val)
{
debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
dev, port, val,
#endif
}
-void ide_outb(int dev, int port, unsigned char val)
- __attribute__ ((weak, alias("__ide_outb")));
-
-inline unsigned char __ide_inb(int dev, int port)
+__weak unsigned char ide_inb(int dev, int port)
{
uchar val;
return val;
}
-unsigned char ide_inb(int dev, int port)
- __attribute__ ((weak, alias("__ide_inb")));
-
-#ifdef CONFIG_TUNE_PIO
-inline int __ide_set_piomode(int pio_mode)
-{
- return 0;
-}
-
-inline int ide_set_piomode(int pio_mode)
- __attribute__ ((weak, alias("__ide_set_piomode")));
-#endif
-
void ide_init(void)
{
unsigned char c;
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].log2blksz =
+ LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
ide_dev_desc[i].lba = 0;
ide_dev_desc[i].block_read = ide_read;
ide_dev_desc[i].block_write = ide_write;
/* ------------------------------------------------------------------------- */
-void ide_input_swap_data(int dev, ulong *sect_buf, int words)
- __attribute__ ((weak, alias("__ide_input_swap_data")));
-
-void ide_input_data(int dev, ulong *sect_buf, int words)
- __attribute__ ((weak, alias("__ide_input_data")));
-
-void ide_output_data(int dev, const ulong *sect_buf, int words)
- __attribute__ ((weak, alias("__ide_output_data")));
-
/* We only need to swap data if we are running on a big endian cpu. */
#if defined(__LITTLE_ENDIAN)
-void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
{
ide_input_data(dev, sect_buf, words);
}
#else
-void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
+__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words)
{
volatile ushort *pbuf =
(ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
#if defined(CONFIG_IDE_SWAP_IO)
-void __ide_output_data(int dev, const ulong *sect_buf, int words)
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
{
ushort *dbuf;
volatile ushort *pbuf;
}
}
#else /* ! CONFIG_IDE_SWAP_IO */
-void __ide_output_data(int dev, const ulong *sect_buf, int words)
+__weak void ide_output_data(int dev, const ulong *sect_buf, int words)
{
#if defined(CONFIG_IDE_AHB)
ide_write_data(dev, sect_buf, words);
#endif /* CONFIG_IDE_SWAP_IO */
#if defined(CONFIG_IDE_SWAP_IO)
-void __ide_input_data(int dev, ulong *sect_buf, int words)
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
{
ushort *dbuf;
volatile ushort *pbuf;
}
}
#else /* ! CONFIG_IDE_SWAP_IO */
-void __ide_input_data(int dev, ulong *sect_buf, int words)
+__weak void ide_input_data(int dev, ulong *sect_buf, int words)
{
#if defined(CONFIG_IDE_AHB)
ide_read_data(dev, sect_buf, words);
#ifdef CONFIG_ATAPI
int retries = 0;
#endif
-
-#ifdef CONFIG_TUNE_PIO
- int pio_mode;
-#endif
-
-#if 0
- int mode, cycle_time;
-#endif
int device;
device = dev_desc->dev;
else
dev_desc->removable = 0;
-#ifdef CONFIG_TUNE_PIO
- /* Mode 0 - 2 only, are directly determined by word 51. */
- pio_mode = iop.tPIO;
- if (pio_mode > 2) {
- printf("WARNING: Invalid PIO (word 51 = %d).\n", pio_mode);
- /* Force it to dead slow, and hope for the best... */
- pio_mode = 0;
- }
-
- /* Any CompactFlash Storage Card that supports PIO mode 3 or above
- * shall set bit 1 of word 53 to one and support the fields contained
- * in words 64 through 70.
- */
- if (iop.field_valid & 0x02) {
- /*
- * Mode 3 and above are possible. Check in order from slow
- * to fast, so we wind up with the highest mode allowed.
- */
- if (iop.eide_pio_modes & 0x01)
- pio_mode = 3;
- if (iop.eide_pio_modes & 0x02)
- pio_mode = 4;
- if (ata_id_is_cfa((u16 *)&iop)) {
- if ((iop.cf_advanced_caps & 0x07) == 0x01)
- pio_mode = 5;
- if ((iop.cf_advanced_caps & 0x07) == 0x02)
- pio_mode = 6;
- }
- }
-
- /* System-specific, depends on bus speeds, etc. */
- ide_set_piomode(pio_mode);
-#endif /* CONFIG_TUNE_PIO */
-
-#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;
- debug("Override tPIO -> 2\n");
- }
- if (iop.field_valid & 2) { /* drive implements ATA2? */
- 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;
- }
- 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 */
- 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 /* 0 */
-
#ifdef CONFIG_ATAPI
if (dev_desc->if_type == IF_TYPE_ATAPI) {
atapi_inquiry(dev_desc);
/* assuming HD */
dev_desc->type = DEV_TYPE_HARDDISK;
dev_desc->blksz = ATA_BLOCKSIZE;
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
dev_desc->lun = 0; /* just to fill something in... */
#if 0 /* only used to test the powersaving mode,
/* ------------------------------------------------------------------------- */
-ulong ide_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
{
ulong n = 0;
unsigned char c;
lba48 = 1;
}
#endif
- debug("ide_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
+ debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
device, blknr, blkcnt, (ulong) buffer);
ide_led(DEVICE_LED(device), 1); /* LED on */
if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
ATA_STAT_DRQ) {
- printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
- device, blknr, c);
+ printf("Error (no IRQ) dev %d blk " LBAF ": status "
+ "%#02x\n", device, blknr, c);
break;
}
/* ------------------------------------------------------------------------- */
-ulong ide_write(int device, ulong blknr, lbaint_t blkcnt, const void *buffer)
+ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer)
{
ulong n = 0;
unsigned char c;
if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
ATA_STAT_DRQ) {
- printf("Error (no IRQ) dev %d blk %ld: status %#02x\n",
- device, blknr, c);
+ printf("Error (no IRQ) dev %d blk " LBAF ": status "
+ "%#02x\n", device, blknr, c);
goto WR_OUT;
}
* ATAPI Support
*/
-void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
- __attribute__ ((weak, alias("__ide_input_data_shorts")));
-
-void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
- __attribute__ ((weak, alias("__ide_output_data_shorts")));
-
-
#if defined(CONFIG_IDE_SWAP_IO)
/* since ATAPI may use commands with not 4 bytes alligned length
* we have our own transfer functions, 2 bytes alligned */
-void __ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
ushort *dbuf;
volatile ushort *pbuf;
}
}
-void __ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
ushort *dbuf;
volatile ushort *pbuf;
}
#else /* ! CONFIG_IDE_SWAP_IO */
-void __ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
{
outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
}
-void __ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
{
insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
}
dev_desc->lun = 0;
dev_desc->lba = 0;
dev_desc->blksz = 0;
+ dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
dev_desc->type = iobuf[0] & 0x1f;
if ((iobuf[1] & 0x80) == 0x80)
dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
((unsigned long) iobuf[5] << 16) +
((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+ dev_desc->log2blksz = LOG2(dev_desc->blksz);
#ifdef CONFIG_LBA48
/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
dev_desc->lba48 = 0;
#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */
#define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
-ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
+ulong atapi_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
{
ulong n = 0;
unsigned char ccb[12]; /* Command descriptor block */
ulong cnt;
- debug("atapi_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
+ debug("atapi_read dev %d start " LBAF " blocks " LBAF " buffer at %lX\n",
device, blknr, blkcnt, (ulong) buffer);
do {