X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fcmd_ide.c;h=04a6d9b39833cf6efe876b44239ec2af0accca4b;hb=dbdb5abd070163f59901884c672b49c25b1aeea9;hp=6b4813e4a9e3b64c18dd0ffd95585c825a723f8d;hpb=e4148c1165d11807e51a9587716e6a513ce1c021;p=oweals%2Fu-boot.git diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 6b4813e4a9..04a6d9b398 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -2,24 +2,7 @@ * (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+ */ /* @@ -38,14 +21,6 @@ # include #endif -#ifdef CONFIG_8xx -# include -#endif - -#ifdef CONFIG_MPC5xxx -#include -#endif - #include #include @@ -81,19 +56,6 @@ static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; /* ------------------------------------------------------------------------- */ -#ifdef CONFIG_IDE_LED -# if !defined(CONFIG_BMS2003) && \ - !defined(CONFIG_CPC45) && \ - !defined(CONFIG_KUP4K) && \ - !defined(CONFIG_KUP4X) -static void ide_led (uchar led, uchar status); -#else -extern void ide_led (uchar led, uchar status); -#endif -#else -#define ide_led(a,b) /* dummy */ -#endif - #ifdef CONFIG_IDE_RESET static void ide_reset (void); #else @@ -109,8 +71,6 @@ static uchar ide_wait (int dev, ulong t); #define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ -static void input_data(int dev, ulong *sect_buf, int words); -static void output_data(int dev, const ulong *sect_buf, int words); static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len); #ifndef CONFIG_SYS_ATA_PORT_ADDR @@ -119,7 +79,8 @@ 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, lbaint_t blknr, ulong blkcnt, void *buffer); +static ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt, + void *buffer); #endif @@ -292,7 +253,31 @@ int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) /* ------------------------------------------------------------------------- */ -inline void __ide_outb(int dev, int port, unsigned char val) +__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 */ + + uchar *led_port = LED_PORT; + + if (status) /* switch LED on */ + led_buffer |= led; + else /* switch LED off */ + led_buffer &= ~led; + + *led_port = led_buffer; +#endif +} + +#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */ +# define DEVICE_LED(x) 0 +# define LED_IDE1 1 +# define LED_IDE2 2 +#endif + +/* ------------------------------------------------------------------------- */ + +__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, @@ -311,10 +296,7 @@ inline void __ide_outb(int dev, int port, unsigned char 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; @@ -330,19 +312,6 @@ inline unsigned char __ide_inb(int dev, int port) 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; @@ -444,14 +413,14 @@ void ide_init(void) curr_device = -1; for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { -#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; 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; @@ -484,28 +453,14 @@ block_dev_desc_t *ide_get_dev(int dev) /* ------------------------------------------------------------------------- */ /* 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_SOC_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) +#if defined(__LITTLE_ENDIAN) +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) { -#if 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); - ushort *dbuf = (ushort *) sect_buf; - - while (words--) { - for (i = 0; i < 2; i++) { - *(((uchar *) (dbuf)) + 1) = *pbuf_even; - *(uchar *) dbuf = *pbuf_odd; - dbuf += 1; - } - } + ide_input_data(dev, sect_buf, words); +} #else +__weak void ide_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; @@ -517,64 +472,32 @@ static void input_swap_data(int dev, ulong *sect_buf, int 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 */ +#endif /* __LITTLE_ENDIAN */ #if defined(CONFIG_IDE_SWAP_IO) -static void 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_CPC45) - 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--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#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 /* ! CONFIG_IDE_SWAP_IO */ -static void 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); @@ -585,31 +508,8 @@ static void output_data(int dev, const ulong *sect_buf, int words) #endif /* CONFIG_IDE_SWAP_IO */ #if defined(CONFIG_IDE_SWAP_IO) -static void input_data(int dev, ulong *sect_buf, int words) +__weak void ide_input_data(int dev, ulong *sect_buf, int words) { -#if defined(CONFIG_CPC45) - 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--) { - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - *dbuf++ = *pbuf_even; - EIEIO; - SYNC; - *dbuf++ = *pbuf_odd; - EIEIO; - SYNC; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -619,22 +519,14 @@ static void input_data(int dev, ulong *sect_buf, int words) debug("in input data base for read is %lx\n", (unsigned long) pbuf); while (words--) { -#if defined(CONFIG_PCS440EP) - EIEIO; - *dbuf++ = ld_le16(pbuf); - EIEIO; - *dbuf++ = ld_le16(pbuf); -#else EIEIO; *dbuf++ = *pbuf; EIEIO; *dbuf++ = *pbuf; -#endif } -#endif } #else /* ! CONFIG_IDE_SWAP_IO */ -static void 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); @@ -655,14 +547,6 @@ static void ide_ident(block_dev_desc_t *dev_desc) #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; @@ -744,7 +628,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) return; #endif - input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); + ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev, sizeof(dev_desc->revision)); @@ -771,72 +655,6 @@ static void ide_ident(block_dev_desc_t *dev_desc) 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); @@ -871,6 +689,7 @@ static void ide_ident(block_dev_desc_t *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, @@ -892,7 +711,7 @@ static void ide_ident(block_dev_desc_t *dev_desc) /* ------------------------------------------------------------------------- */ -ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) +ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer) { ulong n = 0; unsigned char c; @@ -906,7 +725,7 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) lba48 = 1; } #endif - debug("ide_read dev %d start %lX, blocks %lX 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 */ @@ -996,17 +815,12 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CONFIG_SYS_64BIT_LBA) - printf("Error (no IRQ) dev %d blk %lld: 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 + printf("Error (no IRQ) dev %d blk " LBAF ": status " + "%#02x\n", device, blknr, c); break; } - input_data(device, buffer, ATA_SECTORWORDS); + ide_input_data(device, buffer, ATA_SECTORWORDS); (void) ide_inb(device, ATA_STATUS); /* clear IRQ */ ++n; @@ -1021,7 +835,7 @@ IDE_READ_E: /* ------------------------------------------------------------------------- */ -ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer) +ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer) { ulong n = 0; unsigned char c; @@ -1089,17 +903,12 @@ ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer) if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != ATA_STAT_DRQ) { -#if defined(CONFIG_SYS_64BIT_LBA) - printf("Error (no IRQ) dev %d blk %lld: 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 + printf("Error (no IRQ) dev %d blk " LBAF ": status " + "%#02x\n", device, blknr, c); goto WR_OUT; } - output_data(device, buffer, ATA_SECTORWORDS); + ide_output_data(device, buffer, ATA_SECTORWORDS); c = ide_inb(device, ATA_STATUS); /* clear IRQ */ ++n; ++blknr; @@ -1196,27 +1005,6 @@ static void ide_reset(void) /* ------------------------------------------------------------------------- */ -#if defined(CONFIG_IDE_LED) && \ - !defined(CONFIG_CPC45) && \ - !defined(CONFIG_KUP4K) && \ - !defined(CONFIG_KUP4X) - -static uchar led_buffer; /* Buffer for current LED status */ - -static void ide_led(uchar led, uchar status) -{ - uchar *led_port = LED_PORT; - - if (status) /* switch LED on */ - led_buffer |= led; - else /* switch LED off */ - led_buffer &= ~led; - - *led_port = led_buffer; -} - -#endif /* CONFIG_IDE_LED */ - #if defined(CONFIG_OF_IDE_FIXUP) int ide_device_present(int dev) { @@ -1235,22 +1023,8 @@ int ide_device_present(int dev) #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 */ -static void output_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_CPC45) - 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--) { - EIEIO; - *pbuf_even = *dbuf++; - EIEIO; - *pbuf_odd = *dbuf++; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -1264,25 +1038,10 @@ static void output_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *pbuf = *dbuf++; } -#endif } -static void input_data_shorts(int dev, ushort *sect_buf, int shorts) +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) { -#if defined(CONFIG_CPC45) - 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--) { - EIEIO; - *dbuf++ = *pbuf_even; - EIEIO; - *dbuf++ = *pbuf_odd; - } -#else ushort *dbuf; volatile ushort *pbuf; @@ -1296,16 +1055,15 @@ static void input_data_shorts(int dev, ushort *sect_buf, int shorts) EIEIO; *dbuf++ = *pbuf; } -#endif } #else /* ! CONFIG_IDE_SWAP_IO */ -static void 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); } -static void 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); } @@ -1384,7 +1142,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, } /* write command block */ - output_data_shorts(device, (unsigned short *) ccb, ccblen / 2); + ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2); /* ATAPI Command written wait for completition */ udelay(5000); /* device must set bsy */ @@ -1435,12 +1193,12 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, /* ok now decide if it is an in or output */ if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) { debug("Write to device\n"); - output_data_shorts(device, (unsigned short *) buffer, - n); + ide_output_data_shorts(device, + (unsigned short *) buffer, n); } else { debug("Read from device @ %p shorts %d\n", buffer, n); - input_data_shorts(device, (unsigned short *) buffer, - n); + ide_input_data_shorts(device, + (unsigned short *) buffer, n); } } udelay(5000); /* seems that some CD ROMs need this... */ @@ -1567,6 +1325,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) 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) @@ -1611,6 +1370,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc) 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; @@ -1628,13 +1388,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) -ulong atapi_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer) +ulong atapi_read(int device, ulong 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 %lX buffer at %lX\n", + debug("atapi_read dev %d start %lX, blocks " LBAF " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); do {