> + *
> + * 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
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +
> +#if defined (CONFIG_CMD_MG_DISK)
> +
> +#include <mg_disk.h>
> +
> +int do_mg_disk_cmd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
> +{
> +     u32 from, to, size;
> +
> +     switch (argc) {
> +     case 2:
> +             if (!strcmp(argv[1], "init"))
> +                     mg_disk_init();
> +             else
> +                     return 1;
> +             break;
> +     case 4:
> +             from = simple_strtoul(argv[2], NULL, 0);
> +             to = simple_strtoul(argv[3], NULL, 0);
> +             size = simple_strtoul(argv[4], NULL, 0);
> +
> +             if (!strcmp(argv[1], "read"))
> +                     mg_disk_read(from, (u8 *)to, size);
> +             else if (!strcmp(argv[1], "write"))
> +                     mg_disk_write(to, (u8 *)from, size);
> +             else if (!strcmp(argv[1], "readsec"))
> +                     mg_disk_read_sects((void *)to, from, size);
> +             else if (!strcmp(argv[1], "writesec"))
> +                     mg_disk_write_sects((void *)from, to, size);
> +             else
> +                     return 1;
> +             break;
> +     default:
> +             printf("Usage:\n%s\n", cmdtp->usage);
> +             return 1;
> +     }
> +     return 0;
> +}
> +
> +U_BOOT_CMD(
> +     mgd,    5,      0,      do_mg_disk_cmd,
> +     "mgd     - mgine m[g]flash command\n",
> +     ": mgine mflash IO mode (disk) command\n"
> +     "    - initialize : mgd init\n"
> +     "    - random read : mgd read [from] [to] [size]\n"
> +     "    - random write : mgd write [from] [to] [size]\n"
> +     "    - sector read : mgd readsec [sector] [to] [counts]\n"
> +     "    - sector write : mgd writesec [from] [sector] [counts]\n"
> +);
> +
> +#endif
> diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
> index 1fcb4c9..649b23d 100644
> --- a/common/cmd_nvedit.c
> +++ b/common/cmd_nvedit.c
> @@ -52,15 +52,17 @@
>  
>  DECLARE_GLOBAL_DATA_PTR;
>  
> -#if !defined(CONFIG_ENV_IS_IN_NVRAM) && \
> -    !defined(CONFIG_ENV_IS_IN_EEPROM)        && \
> +#if !defined(CONFIG_ENV_IS_IN_EEPROM)        && \
>      !defined(CONFIG_ENV_IS_IN_FLASH) && \
>      !defined(CONFIG_ENV_IS_IN_DATAFLASH)     && \
> +    !defined(CONFIG_ENV_IS_IN_MG_DISK)       && \
>      !defined(CONFIG_ENV_IS_IN_NAND)  && \
> +    !defined(CONFIG_ENV_IS_IN_NVRAM) && \
>      !defined(CONFIG_ENV_IS_IN_ONENAND)       && \
>      !defined(CONFIG_ENV_IS_IN_SPI_FLASH)     && \
>      !defined(CONFIG_ENV_IS_NOWHERE)
> -# error Define one of 
> CONFIG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|NOWHERE}
> +# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
> +SPI_FLASH|MG_DISK|NVRAM|NOWHERE}
>  #endif
>  
>  #define XMK_STR(x)   #x
> +env_t *env_ptr = 0;
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +uchar env_get_char_spec(int index)
> +{
> +     return (*((uchar *) (gd->env_addr + index)));
> +}
> +
> +void env_relocate_spec(void)
> +{
> +     unsigned int err;
> +
> +     err = mg_disk_init();
> +     if (err) {
> +             puts ("*** Warning - mg_disk_init error");
> +             goto OUT;
> +     }
> +     err = mg_disk_read(CONFIG_ENV_ADDR, (u_char *)env_ptr, CONFIG_ENV_SIZE);
> +     if (err) {
> +             puts ("*** Warning - mg_disk_read error");
> +             goto OUT;
> +     }
> +
> +     if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) {
> +             puts ("*** Warning - CRC error");
> +             goto OUT;
> +     }
> +
> +     return;
> +
> +OUT:
> +     printf (", using default environment\n\n");
> +     set_default_env();
> +}
> +
> +int saveenv(void)
> +{
> +     unsigned int err;
add an empty line
> +     env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE);
> +     err = mg_disk_write(CONFIG_ENV_ADDR, (u_char *)env_ptr,
> +                     CONFIG_ENV_SIZE);
> +     if (err)
> +             puts ("*** Warning - mg_disk_write error\n\n");
please add an empty line to be concistant with the function
> +     return err;
> +}
> +
> +int env_init(void)
> +{
> +     /* use default */
> +     gd->env_addr = (ulong) & default_environment[0];
> +     gd->env_valid = 1;
> +
> +     return 0;
> +}
> diff --git a/disk/part.c b/disk/part.c
> index e353cee..fe299c7 100644
> --- a/disk/part.c
> +++ b/disk/part.c
> @@ -35,6 +35,7 @@
>  #endif
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
> @@ -65,6 +66,9 @@ static const struct block_drvr block_drvr[] = {
>  #if defined(CONFIG_SYSTEMACE)
>       { .name = "ace", .get_dev = systemace_get_dev, },
>  #endif
> +#if defined(CONFIG_CMD_MG_DISK)
> +     { .name = "mgd", .get_dev = mg_disk_get_dev, },
> +#endif
>       { },
>  };
>  
> @@ -91,6 +95,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev)
>  #endif
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
> @@ -203,11 +208,12 @@ void dev_print (block_dev_desc_t *dev_desc)
>  #endif
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
>       defined(CONFIG_MMC)             || \
> -     defined(CONFIG_SYSTEMACE)          )
> +     defined(CONFIG_SYSTEMACE) )
>  
>  #if defined(CONFIG_MAC_PARTITION) || \
>      defined(CONFIG_DOS_PARTITION) || \
> diff --git a/disk/part_amiga.c b/disk/part_amiga.c
> index 6c3d748..6f25173 100644
> --- a/disk/part_amiga.c
> +++ b/disk/part_amiga.c
> @@ -27,6 +27,7 @@
>  #include "part_amiga.h"
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
>       defined(CONFIG_MMC) || \
> @@ -154,7 +155,7 @@ struct rigid_disk_block *get_rdisk(block_dev_desc_t 
> *dev_desc)
>  
>      s = getenv("amiga_scanlimit");
>      if (s)
> -     limit = atoi(s);
> +     limit = simple_strtoul(s, NULL, 10);
>      else
>       limit = AMIGA_BLOCK_LIMIT;
>  
> @@ -195,7 +196,7 @@ struct bootcode_block *get_bootcode(block_dev_desc_t 
> *dev_desc)
>  
>      s = getenv("amiga_scanlimit");
>      if (s)
> -     limit = atoi(s);
> +     limit = simple_strtoul(s, NULL, 10);
>      else
>       limit = AMIGA_BLOCK_LIMIT;
>  
> diff --git a/disk/part_dos.c b/disk/part_dos.c
> index 4d778ec..845cdb6 100644
> --- a/disk/part_dos.c
> +++ b/disk/part_dos.c
> @@ -36,6 +36,7 @@
>  #include "part_dos.h"
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
> diff --git a/disk/part_efi.c b/disk/part_efi.c
> index d8a8111..4cf79fb 100644
> --- a/disk/part_efi.c
> +++ b/disk/part_efi.c
> @@ -37,6 +37,7 @@
>  #include "part_efi.h"
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_USB) || \
> diff --git a/disk/part_iso.c b/disk/part_iso.c
> index 72ff868..8348ce8 100644
> --- a/disk/part_iso.c
> +++ b/disk/part_iso.c
> @@ -26,6 +26,7 @@
>  #include "part_iso.h"
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_USB) || \
> diff --git a/disk/part_mac.c b/disk/part_mac.c
> index 1922fe5..fce4cc7 100644
> --- a/disk/part_mac.c
> +++ b/disk/part_mac.c
> @@ -35,6 +35,7 @@
>  #include "part_mac.h"
>  
>  #if (defined(CONFIG_CMD_IDE) || \
> +     defined(CONFIG_CMD_MG_DISK) || \
>       defined(CONFIG_CMD_SCSI) || \
>       defined(CONFIG_CMD_SATA) || \
>       defined(CONFIG_CMD_USB) || \
> diff --git a/doc/README.mflash b/doc/README.mflash
> new file mode 100644
> index 0000000..fb74b90
> --- /dev/null
> +++ b/doc/README.mflash
> @@ -0,0 +1,93 @@
> +
> +This document describes m[g]flash support in u-boot.
> +
> +Contents
> +  1. Overview
> +  2. Porting mflash driver
> +  3. Mflash command
> +  4. Misc.
> +
> +1. Overview
> +Mflash and gflash are embedded flash drive. The only difference is mflash is
> +MCP(Multi Chip Package) device. These two device operate exactly same way.
> +So the rest mflash repersents mflash and gflash altogether.
> +
> +2. Porting mflash driver
> +
> +2-1. Board configuration
> +* Mflash driver support
> +#define CONFIG_CMD_MG_DISK
> +
> +* Environment variable support (optional)
> +#define CONFIG_ENV_IS_IN_MG_DISK
> +Also CONFIG_ENV_ADDR and CONFIG_ENV_SIZE should be defined.
> +CONFIG_ENV_ADDR is byte offset starting from 0.
> +
> +Following example sets environment variable location to 0x80000 (1024'th
> +sector) and size of 0x400 (1024 byte)
> +#define CONFIG_ENV_ADDR              0x80000
> +#define CONFIG_ENV_SIZE              0x400
> +
> +* Reserved size config (optional)
> +If you want to use some reserved area for bootloader, environment variable or
> +whatever, use CONFIG_MG_DISK_RES. The value should be multiple of
> +MG_SECTOR_SIZE (512Byte). Mflash's block operation method use this value as
> +start offset. So any u-boot's partition table parser and file system command
> +work consistently. You can access this area by using mflash command.
> +
> +Following example sets 10MB of reserved area.
> +#define CONFIG_MG_DISK_RES   10485760
> +
> +2-2. Porting mg_get_drv_data function
> +Mflash is active device and need some gpio control for proper operation.
> +This board dependency resolved by using mg_get_drv_data function.
> +Port this function at your board init file. See include/mg_disk.h
> +
> +Here is some pseudo example.
> +
> +static void custom_hdrst_pin (u8 level)
> +{
> +     if (level)
> +             /* set hard reset pin to high */
> +     else
> +             /* set hard reset pin to low */
> +}
> +
> +static void custom_ctrl_pin_init (void)
> +{
> +     /* Set hard reset, write protect, deep power down pins
> +      * to gpio.
> +      * Set these pins to output high
> +      */
> +}
> +
> +struct mg_drv_data* mg_get_drv_data (void)
> +{
> +     static struct mg_drv_data prv;
> +
> +     prv.base = /* base address of mflash */
> +     prv.mg_ctrl_pin_init = custom_ctrl_pin_init;
> +     prv.mg_hdrst_pin = custom_hdrst_pin;
> +
> +     return &prv;
> +}
> +
> +3. Mflash command
> +
> +* initialize : mgd init
> +* random read : mgd read [from] [to] [size]
> +  ex) read 256 bytes from 0x300000 of mflash to 0xA0100000 of host memory
> +      mgd read 0x300000 0xA0100000 256
> +* random write : mgd write [from] [to] [size]
> +* sector read : mgd readsec [sector] [to] [count]
> +  ex) read 10 sectors starts from 400 sector to 0xA0100000
> +      mgd readsec 400 0xA0100000 10
> +* sector write : mgd writesec [from] [sector] [count]
> +
> +4. Misc.
> +Mflash's device interface name for block driver is "mgd".
> +Here is ext2 file system access example.
> +
> + mgd init
> + ext2ls mgd 0:1 /boot
> + ext2load mgd 0:1 0xa0010000 /boot/uImage 1954156
> diff --git a/drivers/block/Makefile b/drivers/block/Makefile
> index 59388d9..eccefc1 100644
> --- a/drivers/block/Makefile
> +++ b/drivers/block/Makefile
> @@ -25,13 +25,14 @@ include $(TOPDIR)/config.mk
>  
>  LIB  := $(obj)libblock.a
>  
> -COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
why?
>  COBJS-$(CONFIG_ATA_PIIX) += ata_piix.o
> +COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o
>  COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o
> +COBJS-$(CONFIG_IDE_SIL680) += sil680.o
>  COBJS-$(CONFIG_LIBATA) += libata.o
>  COBJS-$(CONFIG_PATA_BFIN) += pata_bfin.o
>  COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
> -COBJS-$(CONFIG_IDE_SIL680) += sil680.o
> +COBJS-$(CONFIG_SCSI_AHCI) += ahci.o
>  COBJS-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
>  COBJS-$(CONFIG_SYSTEMACE) += systemace.o
>  
> diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
> new file mode 100644
> index 0000000..4454fca
> --- /dev/null
> +++ b/drivers/block/mg_disk.c
> @@ -0,0 +1,629 @@
> +/*
> + * (C) Copyright 2009 mGine co.
> + * unsik Kim <donar...@gmail.com>
> + *
> + * 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
> + */
> +
> +#include <common.h>
> +#include <malloc.h>
> +#include <part.h>
> +#include <ata.h>
> +#include <asm/io.h>
> +#include "mg_disk_prv.h"
> +
> +#ifdef CONFIG_CMD_MG_DISK
no need please remove
> +
> +#ifndef CONFIG_MG_DISK_RES
> +#define CONFIG_MG_DISK_RES   0
> +#endif
> +
> +#if (CONFIG_MG_DISK_RES % MG_SECTOR_SIZE != 0)
> +#error "CONFIG_MG_DISK_RES should be MG_SECTOR_SIZE algined"
> +#endif
> +
> +#define MG_DISK_RES ((CONFIG_MG_DISK_RES) / MG_SECTOR_SIZE)
> +
> +#define MG_BASE      (host.drv_data->base)
an inline function will be better
> +
> +static struct mg_host host;
> +
> +static block_dev_desc_t mg_disk_dev = {
> +     .if_type = IF_TYPE_ATAPI,
> +     .part_type = PART_TYPE_UNKNOWN,
> +     .type = DEV_TYPE_HARDDISK,
> +     .blksz = MG_SECTOR_SIZE,
> +     .priv = &host };
> +
> +static void mg_dump_status (const char *msg, unsigned int stat, unsigned err)
> +{
> +     char *name = MG_DEV_NAME;
> +
> +     printf("%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
> +     if (stat & MG_REG_STATUS_BIT_BUSY)
> +             printf("Busy ");
> +     if (stat & MG_REG_STATUS_BIT_READY)
> +             printf("DriveReady ");
> +     if (stat & MG_REG_STATUS_BIT_WRITE_FAULT)
> +             printf("WriteFault ");
> +     if (stat & MG_REG_STATUS_BIT_SEEK_DONE)
> +             printf("SeekComplete ");
> +     if (stat & MG_REG_STATUS_BIT_DATA_REQ)
> +             printf("DataRequest ");
> +     if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR)
> +             printf("CorrectedError ");
> +     if (stat & MG_REG_STATUS_BIT_ERROR)
> +             printf("Error ");
> +     printf("}\n");
> +
> +     if ((stat & MG_REG_STATUS_BIT_ERROR)) {
> +             printf("%s: %s: error=0x%02x { ", name, msg, err & 0xff);
> +             if (err & MG_REG_ERR_BBK)
> +                     printf("BadSector ");
> +             if (err & MG_REG_ERR_UNC)
> +                     printf("UncorrectableError ");
> +             if (err & MG_REG_ERR_IDNF)
> +                     printf("SectorIdNotFound ");
> +             if (err & MG_REG_ERR_ABRT)
> +                     printf("DriveStatusError ");
> +             if (err & MG_REG_ERR_AMNF)
> +                     printf("AddrMarkNotFound ");
> +             printf("}\n");
> +     }
> +}
> +
> +#if CONFIG_SYS_HZ == 1000
not supposed to append anymore
CONFIG_SYS_HZ supposed to be always 1000
if not thi smust be fix
> +#define msecs_to_hz(s) (s)
> +#else
> +static unsigned int msecs_to_hz (u32 msec)
> +{
> +     u32 hz = CONFIG_SYS_HZ / 1000 * msec;
> +
> +     if (!hz)
> +             hz = 1;
> +
> +     return hz;
> +}
> +#endif
> +
> +/*
> + * 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 mg_ident_cpy (unsigned char *dst, unsigned char *src,
> +             unsigned int len)
> +{
> +     unsigned char *end, *last;
> +
> +     last = dst;
> +     end  = src + len - 1;
> +
> +     /* reserve space for '\0' */
> +     if (len < 2)
> +             goto OUT;
> +
> +     /* skip leading white space */
> +     while ((*src) && (src<end) && (*src==' '))
please add a space before and after '<' '==' & co
> +             ++src;
> +
> +     /* copy string, omitting trailing white space */
> +     while ((*src) && (src<end)) {
> +             *dst++ = *src;
> +             if (*src++ != ' ')
> +                     last = dst;
> +     }
> +OUT:
> +     *last = '\0';
> +}
why do you need this?
> +
> +static unsigned int mg_wait (u32 expect, u32 msec)
> +{
> +     u8 status;
> +     u32 from, cur, expire, err;
> +
> +     err = MG_ERR_NONE;
> +     reset_timer();
> +     from = get_timer(0);
> +     expire = msecs_to_hz(msec);
> +
> +     status = readb(MG_BASE + MG_REG_STATUS);
> +     do {
> +             cur = get_timer(from);
> +             if (status & MG_REG_STATUS_BIT_BUSY) {
> +                     if (expect == MG_REG_STATUS_BIT_BUSY)
> +                             break;
> +             } else {
> +                     /* Check the error condition! */
> +                     if (status & MG_REG_STATUS_BIT_ERROR) {
> +                             err = readb(MG_BASE + MG_REG_ERROR);
> +                             mg_dump_status("mg_wait", status, err);
> +                             break;
> +                     }
> +
> +                     if (expect == MG_STAT_READY)
> +                             if (MG_READY_OK(status))
> +                                     break;
> +
> +                     if (expect == MG_REG_STATUS_BIT_DATA_REQ)
> +                             if (status & MG_REG_STATUS_BIT_DATA_REQ)
> +                                     break;
> +             }
> +             status = readb(MG_BASE + MG_REG_STATUS);
> +     } while (cur < expire);
> +
> +     if (cur >= expire)
> +             err = MG_ERR_TIMEOUT;
> +
> +     return err;
> +}
> +
> +static int mg_get_disk_id (void)
> +{
> +     u32 iobuf[(MG_SECTOR_SIZE / sizeof(u32))];
> +     hd_driveid_t *iop = (hd_driveid_t *)iobuf;
> +     u32 i, err;
> +     u16 *buff = (u16 *)iobuf;
> +
> +     writeb(MG_CMD_ID, MG_BASE + MG_REG_COMMAND);
> +     err = mg_wait(MG_REG_STATUS_BIT_DATA_REQ, 3000);
> +     if (err)
> +             return err;
> +
> +     for(i = 0; i < (MG_SECTOR_SIZE / sizeof(u32)) >> 1; i++)
> +             buff[i] = readw(MG_BASE + MG_BUFF_OFFSET + i * 2);
> +
> +     writeb(MG_CMD_RD_CONF, MG_BASE + MG_REG_COMMAND);
> +     err = mg_wait(MG_STAT_READY, 3000);
> +     if (err)
> +             return err;
> +
> +     if((iop->field_valid & 1) == 0)
> +             return MG_ERR_TRANSLATION;
> +
> +     mg_ident_cpy((unsigned char*)mg_disk_dev.revision, iop->fw_rev,
> +                     sizeof(mg_disk_dev.revision));
> +     mg_ident_cpy((unsigned char*)mg_disk_dev.vendor, iop->model,
> +                     sizeof(mg_disk_dev.vendor));
> +     mg_ident_cpy((unsigned char*)mg_disk_dev.product, iop->serial_no,
> +                     sizeof(mg_disk_dev.product));
> +#ifdef __LITTLE_ENDIAN
> +     /*
> +      * firmware revision, model, and serial number have Big Endian Byte
> +      * order in Word. Convert all three to little endian.
> +      *
> +      * See CF+ and CompactFlash Specification Revision 2.0:
> +      * 6.2.1.6: Identify Drive, Table 39 for more details
> +      */
> +
> +     strswab(mg_disk_dev.revision);
> +     strswab(mg_disk_dev.vendor);
> +     strswab(mg_disk_dev.product);
> +#endif /* __LITTLE_ENDIAN */
> +
> +#ifdef __BIG_ENDIAN
maybe use only one ifdef __LITTLE_ENDIAN?
> +     mg_disk_dev.lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
> +#else        /* ! __BIG_ENDIAN */
> +     mg_disk_dev.lba = iop->lba_capacity;
> +#endif /* __BIG_ENDIAN */
> +
> +     return MG_ERR_NONE;
> +}
> +
> +static int mg_disk_reset (void)
> +{
> +     struct mg_drv_data *prv_data = host.drv_data;
> +     s32 err;
> +     u8 init_status;
> +
> +     /* hdd rst low */
> +     prv_data->mg_hdrst_pin(0);
> +     err = mg_wait(MG_REG_STATUS_BIT_BUSY, 300);
> +     if(err)
> +             return err;
> +
> +     /* hdd rst high */
> +     prv_data->mg_hdrst_pin(1);
> +     err = mg_wait(MG_STAT_READY, 3000);
> +     if(err)
> +             return err;
> +
> +     /* soft reset on */
> +     writeb(MG_REG_CTRL_RESET | MG_REG_CTRL_INTR_DISABLE,
> +             MG_BASE + MG_REG_DRV_CTRL);
> +     err = mg_wait(MG_REG_STATUS_BIT_BUSY, 3000);
> +     if(err)
> +             return err;
> +
> +     /* soft reset off */
> +     writeb(MG_REG_CTRL_INTR_DISABLE, MG_BASE + MG_REG_DRV_CTRL);
> +     err = mg_wait(MG_STAT_READY, 3000);
> +     if(err)
> +             return err;
> +
> +     init_status = readb(MG_BASE + MG_REG_STATUS) & 0xf;
> +
> +     if (init_status == 0xf)
> +             return MG_ERR_INIT_STAT;
> +
> +     return err;
> +}
> +
> +
> +static unsigned int mg_out(unsigned int sect_num,
> +                     unsigned int sect_cnt,
> +                     unsigned int cmd)
> +{
> +     u32 err = MG_ERR_NONE;
> +
> +     if ((err = mg_wait(MG_STAT_READY, 3000))) {
> +             return err;
> +     }
maybe you could use the same coding style in the same file?
> +
> +     writeb((u8)sect_cnt, MG_BASE + MG_REG_SECT_CNT);
> +     writeb((u8)sect_num, MG_BASE + MG_REG_SECT_NUM);
> +     writeb((u8)(sect_num >> 8), MG_BASE + MG_REG_CYL_LOW);
> +     writeb((u8)(sect_num >> 16), MG_BASE + MG_REG_CYL_HIGH);
> +     writeb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE),
> +             MG_BASE + MG_REG_DRV_HEAD);
> +     writeb(cmd, MG_BASE + MG_REG_COMMAND);
please add an empty line
> +     return err;
> +}
> +
> +static unsigned int mg_do_read_sects(void *buff, u32 sect_num, u32 sect_cnt)
> +{
> +     u32 i, j, err;
> +     u8 *buff_ptr = buff;
> +
> +     err = mg_out(sect_num, sect_cnt, MG_CMD_RD);
> +     if (err)
> +             return err;
> +
> +     for (i = 0; i < sect_cnt; i++) {
> +             err = mg_wait(MG_REG_STATUS_BIT_DATA_REQ, 3000);
> +             if (err)
> +                     return err;
> +
> +             /* TODO : u16 unaligned case */
> +             for(j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
> +                     *(u16 *)buff_ptr =
> +                             readw(MG_BASE + MG_BUFF_OFFSET + (j << 1));
??
> +                     buff_ptr += 2;
> +             }
> +
> +             writeb(MG_CMD_RD_CONF, MG_BASE + MG_REG_COMMAND);
> +
> +             MG_DBG("%u (0x%8.8x) sector read", sect_num + i,
> +                     (sect_num + i) * MG_SECTOR_SIZE);
> +     }
> +
> +     return err;
> +}
> +
> +unsigned int mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt)
> +{
> +     u32 quotient, residue, i, err;
> +     u8 *buff_ptr = buff;
> +
> +     quotient = sect_cnt >> 8;
> +     residue = sect_cnt % 256;
> +
> +     for (i = 0; i < quotient; i++) {
> +             MG_DBG("sect num : %u buff : 0x%8.8x", sect_num, (u32)buff_ptr);
> +             err = mg_do_read_sects(buff_ptr, sect_num, 256);
> +             if (err)
> +                     return err;
> +             sect_num += 256;
> +             buff_ptr += 256 * MG_SECTOR_SIZE;
> +     }
> +
> +     if (residue) {
> +             MG_DBG("sect num : %u buff : %8.8x", sect_num, (u32)buff_ptr);
please use debug(x)
> +             err = mg_do_read_sects(buff_ptr, sect_num, residue);
> +     }
> +
> +     return err;
> +}
> +
> +unsigned long mg_block_read (int dev, unsigned long start,
> +             lbaint_t blkcnt, void *buffer)
> +{
> +     start += MG_DISK_RES;
> +     if (! mg_disk_read_sects(buffer, start, blkcnt))
> +             return blkcnt;
> +     else
> +             return 0;
> +}
> +
> +unsigned int mg_disk_read (u32 addr, u8 *buff, u32 len)
> +{
> +     u8 *sect_buff, *buff_ptr = buff;
> +     u32 cur_addr, next_sec_addr, end_addr, cnt, sect_num;
> +     u32 err = MG_ERR_NONE;
> +
> +     /* TODO : sanity chk */
> +     cnt = 0;
> +     cur_addr = addr;
> +     end_addr = addr + len;
> +
> +     sect_buff = malloc(MG_SECTOR_SIZE);
> +
> +     if (cur_addr & MG_SECTOR_SIZE_MASK) {
> +             next_sec_addr = (cur_addr + MG_SECTOR_SIZE) &
> +                             ~MG_SECTOR_SIZE_MASK;
> +             sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +             err = mg_disk_read_sects(sect_buff, sect_num, 1);
> +             if (err)
> +                     goto mg_read_exit;
> +
> +             if (end_addr < next_sec_addr) {
> +                     memcpy(buff_ptr,
> +                             sect_buff + (cur_addr & MG_SECTOR_SIZE_MASK),
> +                             end_addr - cur_addr);
> +                     MG_DBG("copies %u byte from sector offset 0x%8.8x",
> +                             end_addr - cur_addr, cur_addr);
> +                     cur_addr = end_addr;
> +             } else {
> +                     memcpy(buff_ptr,
> +                             sect_buff + (cur_addr & MG_SECTOR_SIZE_MASK),
> +                             next_sec_addr - cur_addr);
> +                     MG_DBG("copies %u byte from sector offset 0x%8.8x",
> +                             next_sec_addr - cur_addr, cur_addr);
> +                     buff_ptr += (next_sec_addr - cur_addr);
> +                     cur_addr = next_sec_addr;
> +             }
> +     }
> +
> +     if (cur_addr < end_addr) {
> +             sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +             next_sec_addr = cur_addr + MG_SECTOR_SIZE;
> +
> +             while (next_sec_addr <= end_addr) {
> +                     cnt++;
> +                     next_sec_addr += MG_SECTOR_SIZE;
> +             }
is there any better way to calculate it?
> +
> +             if (cnt)
> +                     err = mg_disk_read_sects(buff_ptr, sect_num, cnt);
> +             if (err)
> +                     goto mg_read_exit;
> +
> +             buff_ptr += cnt * MG_SECTOR_SIZE;
> +             cur_addr += cnt * MG_SECTOR_SIZE;
> +
> +             if (cur_addr < end_addr) {
> +                     sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +                     err = mg_disk_read_sects(sect_buff, sect_num, 1);
> +                     if (err)
> +                             goto mg_read_exit;
> +                     memcpy(buff_ptr, sect_buff, end_addr - cur_addr);
> +                     MG_DBG("copies %u byte", end_addr - cur_addr);
> +             }
> +     }
> +
> +mg_read_exit:
> +     free(sect_buff);
> +
> +     return err;
> +}
> +
> +static int mg_do_write_sects(void *buff, u32 sect_num, u32 sect_cnt)
> +{
> +     u32 i, j, err;
> +     u8 *buff_ptr = buff;
> +
> +     err = mg_out(sect_num, sect_cnt, MG_CMD_WR);
> +     if (err)
> +             return err;
> +
> +     for (i = 0; i < sect_cnt; i++) {
> +             err = mg_wait(MG_REG_STATUS_BIT_DATA_REQ, 3000);
> +             if (err)
> +                     return err;
> +
> +             /* TODO : u16 unaligned case */
> +             for(j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
> +                     writew(*(u16 *)buff_ptr,
> +                             MG_BASE + MG_BUFF_OFFSET + (j << 1));
??
> +                     buff_ptr += 2;
> +             }
> +
> +             writeb(MG_CMD_WR_CONF, MG_BASE + MG_REG_COMMAND);
> +
> +             MG_DBG("%u (0x%8.8x) sector write",
> +                     sect_num + i, (sect_num + i) * MG_SECTOR_SIZE);
> +     }
> +
> +     return err;
> +}
> +
> +unsigned int mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt)
> +{
> +     u32 quotient, residue, i;
> +     u32 err = MG_ERR_NONE;
> +     u8 *buff_ptr = buff;
> +
> +     quotient = sect_cnt >> 8;
> +     residue = sect_cnt % 256;
> +
> +     for (i = 0; i < quotient; i++) {
> +             MG_DBG("sect num : %u buff : %8.8x", sect_num, (u32)buff_ptr);
> +             err = mg_do_write_sects(buff_ptr, sect_num, 256);
> +             if (err)
> +                     return err;
> +             sect_num += 256;
> +             buff_ptr += 256 * MG_SECTOR_SIZE;
> +     }
> +
> +     if (residue) {
> +             MG_DBG("sect num : %u buff : %8.8x", sect_num, (u32)buff_ptr);
> +             err = mg_do_write_sects(buff_ptr, sect_num, residue);
> +     }
> +
> +     return err;
> +}
> +
> +unsigned long mg_block_write (int dev, unsigned long start,
> +             lbaint_t blkcnt, const void *buffer)
> +{
> +     start += MG_DISK_RES;
> +     if (!mg_disk_write_sects((void *)buffer, start, blkcnt))
> +             return blkcnt;
> +     else
> +             return 0;
> +}
> +
> +unsigned int mg_disk_write(u32 addr, u8 *buff, u32 len)
> +{
> +     u8 *sect_buff, *buff_ptr = buff;
> +     u32 cur_addr, next_sec_addr, end_addr, cnt, sect_num;
> +     u32 err = MG_ERR_NONE;
> +
> +     /* TODO : sanity chk */
> +     cnt = 0;
> +     cur_addr = addr;
> +     end_addr = addr + len;
> +
> +     sect_buff = malloc(MG_SECTOR_SIZE);
> +
> +     if (cur_addr & MG_SECTOR_SIZE_MASK) {
> +
> +             next_sec_addr = (cur_addr + MG_SECTOR_SIZE) &
> +                             ~MG_SECTOR_SIZE_MASK;
> +             sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +             err = mg_disk_read_sects(sect_buff, sect_num, 1);
> +             if (err)
> +                     goto mg_write_exit;
> +
> +             if (end_addr < next_sec_addr) {
> +                     memcpy(sect_buff + (cur_addr & MG_SECTOR_SIZE_MASK),
> +                             buff_ptr, end_addr - cur_addr);
> +                     MG_DBG("copies %u byte to sector offset 0x%8.8x",
> +                             end_addr - cur_addr, cur_addr);
> +                     cur_addr = end_addr;
> +             } else {
> +                     memcpy(sect_buff + (cur_addr & MG_SECTOR_SIZE_MASK),
> +                             buff_ptr, next_sec_addr - cur_addr);
> +                     MG_DBG("copies %u byte to sector offset 0x%8.8x",
> +                             next_sec_addr - cur_addr, cur_addr);
> +                     buff_ptr += (next_sec_addr - cur_addr);
> +                     cur_addr = next_sec_addr;
> +             }
> +
> +             err = mg_disk_write_sects(sect_buff, sect_num, 1);
> +             if (err)
> +                     goto mg_write_exit;
> +     }
> +
> +     if (cur_addr < end_addr) {
> +
> +             sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +             next_sec_addr = cur_addr + MG_SECTOR_SIZE;
> +
> +             while (next_sec_addr <= end_addr) {
> +                     cnt++;
> +                     next_sec_addr += MG_SECTOR_SIZE;
> +             }
plase do not duplicate it create common code
and as precedently is there any better way to calculate it?
> +
> +             if (cnt)
> +                     err = mg_disk_write_sects(buff_ptr, sect_num, cnt);
> +             if (err)
> +                     goto mg_write_exit;
> +
> +             buff_ptr += cnt * MG_SECTOR_SIZE;
> +             cur_addr += cnt * MG_SECTOR_SIZE;
> +
> +             if (cur_addr < end_addr) {
> +                     sect_num = cur_addr >> MG_SECTOR_SIZE_SHIFT;
> +                     err = mg_disk_read_sects(sect_buff, sect_num, 1);
> +                     if (err)
> +                             goto mg_write_exit;
> +                     memcpy(sect_buff, buff_ptr, end_addr - cur_addr);
> +                     MG_DBG("copies %u byte", end_addr - cur_addr);
> +                     err = mg_disk_write_sects(sect_buff, sect_num, 1);
> +             }
> +
> +     }
> +
> +mg_write_exit:
> +     free(sect_buff);
> +
> +     return err;
> +}
> +
> +block_dev_desc_t *mg_disk_get_dev(int dev)
> +{
> +     return ((block_dev_desc_t *) & mg_disk_dev);
> +}
> +
> +/* must override this function */
> +struct mg_drv_data * __attribute__((weak)) mg_get_drv_data (void)
> +{
> +     puts ("### WARNING ### port mg_get_drv_data function\n");
> +     return NULL;
> +}
please do an compile error not a run time error
> +
> +unsigned int mg_disk_init (void)
> +{
> +     struct mg_drv_data *prv_data;
> +     u32 err = MG_ERR_NONE;
> +
> +     prv_data = mg_get_drv_data();
> +     if (! prv_data) {
> +             printf("%s:%d fail (no driver_data)\n", __func__, __LINE__);
> +             err = MG_ERR_NO_DRV_DATA;
> +             return err;
> +     }
> +
> +     ((struct mg_host *)mg_disk_dev.priv)->drv_data = prv_data;
> +
> +     /* init ctrl pin */
> +     if (prv_data->mg_ctrl_pin_init)
> +             prv_data->mg_ctrl_pin_init();
> +
> +     if (! prv_data->mg_hdrst_pin) {
> +             err = MG_ERR_CTRL_RST;
> +             return err;

Best Regards,
J.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to