diff options
| -rw-r--r-- | common/Makefile | 2 | ||||
| -rw-r--r-- | common/cmd_mgdisk.c | 76 | ||||
| -rw-r--r-- | common/cmd_nvedit.c | 8 | ||||
| -rw-r--r-- | common/env_mgdisk.c | 92 | ||||
| -rw-r--r-- | disk/part.c | 8 | ||||
| -rw-r--r-- | disk/part_amiga.c | 5 | ||||
| -rw-r--r-- | disk/part_dos.c | 1 | ||||
| -rw-r--r-- | disk/part_efi.c | 1 | ||||
| -rw-r--r-- | disk/part_iso.c | 1 | ||||
| -rw-r--r-- | disk/part_mac.c | 1 | ||||
| -rw-r--r-- | doc/README.mflash | 94 | ||||
| -rw-r--r-- | drivers/block/Makefile | 5 | ||||
| -rw-r--r-- | drivers/block/mg_disk.c | 582 | ||||
| -rw-r--r-- | drivers/block/mg_disk_prv.h | 145 | ||||
| -rw-r--r-- | fs/fat/fat.c | 2 | ||||
| -rw-r--r-- | include/config_cmd_all.h | 1 | ||||
| -rw-r--r-- | include/environment.h | 12 | ||||
| -rw-r--r-- | include/mg_disk.h | 51 | ||||
| -rw-r--r-- | include/part.h | 1 | 
19 files changed, 1080 insertions, 8 deletions
| diff --git a/common/Makefile b/common/Makefile index eb8e283a6..9a71302f9 100644 --- a/common/Makefile +++ b/common/Makefile @@ -53,6 +53,7 @@ COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o  COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o  COBJS-y += env_embedded.o  COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o +COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o  COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o  COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o  COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o @@ -104,6 +105,7 @@ COBJS-$(CONFIG_LOGBUFFER) += cmd_log.o  COBJS-$(CONFIG_ID_EEPROM) += cmd_mac.o  COBJS-$(CONFIG_CMD_MEMORY) += cmd_mem.o  COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o +COBJS-$(CONFIG_CMD_MG_DISK) += cmd_mgdisk.o  COBJS-$(CONFIG_MII) += miiphyutil.o  COBJS-$(CONFIG_CMD_MII) += miiphyutil.o  COBJS-$(CONFIG_CMD_MII) += cmd_mii.o diff --git a/common/cmd_mgdisk.c b/common/cmd_mgdisk.c new file mode 100644 index 000000000..48323d45b --- /dev/null +++ b/common/cmd_mgdisk.c @@ -0,0 +1,76 @@ +/* + * (C) Copyright 2009 mGine co. + * unsik Kim <donari75@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 <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 5: +		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 95eebb576..163765a8a 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 diff --git a/common/env_mgdisk.c b/common/env_mgdisk.c new file mode 100644 index 000000000..363ee68c2 --- /dev/null +++ b/common/env_mgdisk.c @@ -0,0 +1,92 @@ +/* + * (C) Copyright 2009 mGine co. + * unsik Kim <donari75@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 <command.h> +#include <environment.h> +#include <linux/stddef.h> +#include <mg_disk.h> + +/* references to names in env_common.c */ +extern uchar default_environment[]; +extern int default_environment_size; + +char * env_name_spec = "MG_DISK"; + +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; + +	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"); + +	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 fdc49d339..c7774930b 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 c2daf6a60..50efe39b1 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 4ab0b4060..93bf3dd4e 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 70f62cc9a..626f022f9 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 719b9495c..8fe6148c2 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 c1afc8c20..bebe415d6 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 000000000..50133b461 --- /dev/null +++ b/doc/README.mflash @@ -0,0 +1,94 @@ + +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 +#define CONFIG_LIBATA + +* 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 unit is KB. 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	10240 + +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 59388d9d4..eccefc1e5 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  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 000000000..b74307ab6 --- /dev/null +++ b/drivers/block/mg_disk.c @@ -0,0 +1,582 @@ +/* + * (C) Copyright 2009 mGine co. + * unsik Kim <donari75@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" + +#ifndef CONFIG_MG_DISK_RES +#define CONFIG_MG_DISK_RES	0 +#endif + +#define MG_RES_SEC ((CONFIG_MG_DISK_RES) << 1) + +static struct mg_host host; + +static inline u32 mg_base(void) +{ +	return host.drv_data->base; +} + +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"); +	} +} + +static unsigned int mg_wait (u32 expect, u32 msec) +{ +	u8 status; +	u32 from, cur, err; + +	err = MG_ERR_NONE; +	reset_timer(); +	from = get_timer(0); + +	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 < msec); + +	if (cur >= msec) +		err = MG_ERR_TIMEOUT; + +	return err; +} + +static int mg_get_disk_id (void) +{ +	u16 id[(MG_SECTOR_SIZE / sizeof(u16))]; +	hd_driveid_t *iop = (hd_driveid_t *)id; +	u32 i, err, res; + +	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(u16)); i++) +		id[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; + +	ata_swap_buf_le16(id, MG_SECTOR_SIZE / sizeof(u16)); + +	if((iop->field_valid & 1) == 0) +		return MG_ERR_TRANSLATION; + +	ata_id_c_string(id, (unsigned char *)mg_disk_dev.revision, +			ATA_ID_FW_REV, sizeof(mg_disk_dev.revision)); +	ata_id_c_string(id, (unsigned char *)mg_disk_dev.vendor, +			ATA_ID_PROD, sizeof(mg_disk_dev.vendor)); +	ata_id_c_string(id, (unsigned char *)mg_disk_dev.product, +			ATA_ID_SERNO, sizeof(mg_disk_dev.product)); + +#ifdef __BIG_ENDIAN +	iop->lba_capacity = (iop->lba_capacity << 16) | +		(iop->lba_capacity >> 16); +#endif /* __BIG_ENDIAN */ + +	if (MG_RES_SEC) { +		MG_DBG("MG_RES_SEC=%d\n", MG_RES_SEC); +		iop->cyls = (iop->lba_capacity - MG_RES_SEC) / +			iop->sectors / iop->heads; +		res = iop->lba_capacity - +			iop->cyls * iop->heads * iop->sectors; +		iop->lba_capacity -= res; +		printf("mg_disk: %d sectors reserved\n", res); +	} + +	mg_disk_dev.lba = iop->lba_capacity; +	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; + +	err = mg_wait(MG_STAT_READY, 3000); +	if (err) +		return err; + +	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); + +	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; +	union mg_uniwb uniwb; + +	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; + +		if ((u32)buff_ptr & 1) { +			for (j = 0; j < MG_SECTOR_SIZE >> 1; j++) { +				uniwb.w = readw(mg_base() + MG_BUFF_OFFSET +						+ (j << 1)); +				*buff_ptr++ = uniwb.b[0]; +				*buff_ptr++ = uniwb.b[1]; +			} +		} else { +			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); +		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_RES_SEC; +	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; +		cnt = ((end_addr & ~MG_SECTOR_SIZE_MASK) - cur_addr) >> +			MG_SECTOR_SIZE_SHIFT; + +		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; +	union mg_uniwb uniwb; + +	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; + +		if ((u32)buff_ptr & 1) { +			uniwb.b[0] = *buff_ptr++; +			uniwb.b[1] = *buff_ptr++; +			writew(uniwb.w, mg_base() + MG_BUFF_OFFSET + (j << 1)); +		} else { +			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_RES_SEC; +	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; +		cnt = ((end_addr & ~MG_SECTOR_SIZE_MASK) - cur_addr) >> +			MG_SECTOR_SIZE_SHIFT; + +		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; +} + +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; +	} + +	/* disk reset */ +	err = mg_disk_reset(); +	if (err) { +		printf("%s:%d fail (err code : %d)\n", __func__, __LINE__, err); +		return err; +	} + +	/* get disk id */ +	err = mg_get_disk_id(); +	if (err) { +		printf("%s:%d fail (err code : %d)\n", __func__, __LINE__, err); +		return err; +	} + +	mg_disk_dev.block_read = mg_block_read; +	mg_disk_dev.block_write = mg_block_write; + +	init_part(&mg_disk_dev); + +	dev_print(&mg_disk_dev); + +	return err; +} diff --git a/drivers/block/mg_disk_prv.h b/drivers/block/mg_disk_prv.h new file mode 100644 index 000000000..8f22e280b --- /dev/null +++ b/drivers/block/mg_disk_prv.h @@ -0,0 +1,145 @@ +/* + * (C) Copyright 2009 mGine co. + * unsik Kim <donari75@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 + */ + +#ifndef __MG_DISK_PRV_H__ +#define __MG_DISK_PRV_H__ + +#include <mg_disk.h> + +/* name for block device */ +#define MG_DISK_NAME "mgd" +/* name for platform device */ +#define MG_DEV_NAME "mg_disk" + +#define MG_DISK_MAJ 240 +#define MG_DISK_MAX_PART 16 +#define MG_SECTOR_SIZE 512 +#define MG_SECTOR_SIZE_MASK (512 - 1) +#define MG_SECTOR_SIZE_SHIFT (9) +#define MG_MAX_SECTS 256 + +/* Register offsets */ +#define MG_BUFF_OFFSET			0x8000 +#define MG_STORAGE_BUFFER_SIZE		0x200 +#define MG_REG_OFFSET			0xC000 +#define MG_REG_FEATURE			(MG_REG_OFFSET + 2)	/* write case */ +#define MG_REG_ERROR			(MG_REG_OFFSET + 2)	/* read case */ +#define MG_REG_SECT_CNT			(MG_REG_OFFSET + 4) +#define MG_REG_SECT_NUM			(MG_REG_OFFSET + 6) +#define MG_REG_CYL_LOW			(MG_REG_OFFSET + 8) +#define MG_REG_CYL_HIGH			(MG_REG_OFFSET + 0xA) +#define MG_REG_DRV_HEAD			(MG_REG_OFFSET + 0xC) +#define MG_REG_COMMAND			(MG_REG_OFFSET + 0xE)	/* write case */ +#define MG_REG_STATUS			(MG_REG_OFFSET + 0xE)	/* read  case */ +#define MG_REG_DRV_CTRL			(MG_REG_OFFSET + 0x10) +#define MG_REG_BURST_CTRL		(MG_REG_OFFSET + 0x12) + +/* "Drive Select/Head Register" bit values */ +#define MG_REG_HEAD_MUST_BE_ON		0xA0 /* These 2 bits are always on */ +#define MG_REG_HEAD_DRIVE_MASTER	(0x00 | MG_REG_HEAD_MUST_BE_ON) +#define MG_REG_HEAD_DRIVE_SLAVE		(0x10 | MG_REG_HEAD_MUST_BE_ON) +#define MG_REG_HEAD_LBA_MODE		(0x40 | MG_REG_HEAD_MUST_BE_ON) + + +/* "Device Control Register" bit values */ +#define MG_REG_CTRL_INTR_ENABLE			0x0 +#define MG_REG_CTRL_INTR_DISABLE		(0x1 << 1) +#define MG_REG_CTRL_RESET			(0x1 << 2) +#define MG_REG_CTRL_INTR_POLA_ACTIVE_HIGH	0x0 +#define MG_REG_CTRL_INTR_POLA_ACTIVE_LOW	(0x1 << 4) +#define MG_REG_CTRL_DPD_POLA_ACTIVE_LOW		0x0 +#define MG_REG_CTRL_DPD_POLA_ACTIVE_HIGH	(0x1 << 5) +#define MG_REG_CTRL_DPD_DISABLE			0x0 +#define MG_REG_CTRL_DPD_ENABLE			(0x1 << 6) + +/* Status register bit */ + /* error bit in status register */ +#define MG_REG_STATUS_BIT_ERROR			0x01 + /* corrected error in status register */ +#define MG_REG_STATUS_BIT_CORRECTED_ERROR	0x04 + /* data request bit in status register */ +#define MG_REG_STATUS_BIT_DATA_REQ		0x08 + /* DSC - Drive Seek Complete */ +#define MG_REG_STATUS_BIT_SEEK_DONE		0x10 + /* DWF - Drive Write Fault */ +#define MG_REG_STATUS_BIT_WRITE_FAULT		0x20 +#define MG_REG_STATUS_BIT_READY			0x40 +#define MG_REG_STATUS_BIT_BUSY			0x80 + +/* handy status */ +#define MG_STAT_READY	(MG_REG_STATUS_BIT_READY | MG_REG_STATUS_BIT_SEEK_DONE) +#define MG_READY_OK(s)	(((s) & (MG_STAT_READY | \ +				(MG_REG_STATUS_BIT_BUSY | \ +				 MG_REG_STATUS_BIT_WRITE_FAULT | \ +				 MG_REG_STATUS_BIT_ERROR))) == MG_STAT_READY) + +/* Error register */ +#define MG_REG_ERR_AMNF		0x01 +#define MG_REG_ERR_ABRT		0x04 +#define MG_REG_ERR_IDNF		0x10 +#define MG_REG_ERR_UNC		0x40 +#define MG_REG_ERR_BBK		0x80 + +/* error code for others */ +#define MG_ERR_NONE		0 +#define MG_ERR_TIMEOUT		0x100 +#define MG_ERR_INIT_STAT	0x101 +#define MG_ERR_TRANSLATION	0x102 +#define MG_ERR_CTRL_RST		0x103 +#define MG_ERR_NO_DRV_DATA	0x104 + +#define MG_MAX_ERRORS	16	/* Max read/write errors/sector */ +#define MG_RESET_FREQ	4	/* Reset controller every 4th retry */ + +/* command */ +#define MG_CMD_RD	0x20 +#define MG_CMD_WR	0x30 +#define MG_CMD_SLEEP	0x99 +#define MG_CMD_WAKEUP	0xC3 +#define MG_CMD_ID	0xEC +#define MG_CMD_WR_CONF	0x3C +#define MG_CMD_RD_CONF	0x40 + +union mg_uniwb{ +	u16 w; +	u8 b[2]; +}; + +/* main structure for mflash driver */ +struct mg_host { +	struct mg_drv_data *drv_data; +	/* for future use */ +}; + +/* + * Debugging macro and defines + */ +#undef DO_MG_DEBUG +#ifdef DO_MG_DEBUG +# define MG_DBG(fmt, args...) printf("%s:%d "fmt"\n", __func__, __LINE__,##args) +#else /* CONFIG_MG_DEBUG */ +# define MG_DBG(fmt, args...) do { } while(0) +#endif /* CONFIG_MG_DEBUG */ + +#endif + diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 8081ee7a8..602edae6b 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -84,6 +84,7 @@ fat_register_device(block_dev_desc_t *dev_desc, int part_no)  		return -1;  	}  #if (defined(CONFIG_CMD_IDE) || \ +     defined(CONFIG_CMD_MG_DISK) || \       defined(CONFIG_CMD_SATA) || \       defined(CONFIG_CMD_SCSI) || \       defined(CONFIG_CMD_USB) || \ @@ -987,6 +988,7 @@ file_fat_detectfs(void)  		return 1;  	}  #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/include/config_cmd_all.h b/include/config_cmd_all.h index c5e0d268e..c747b4baa 100644 --- a/include/config_cmd_all.h +++ b/include/config_cmd_all.h @@ -84,5 +84,6 @@  #define CONFIG_CMD_VFD		/* VFD support (TRAB)		*/  #define CONFIG_CMD_XIMG		/* Load part of Multi Image	*/  #define CONFIG_CMD_AT91_SPIMUX	/* AT91 MMC/SPI Mux Support     */ +#define CONFIG_CMD_MG_DISK	/* mGine m(g)flash IO node support */  #endif	/* _CONFIG_CMD_ALL_H */ diff --git a/include/environment.h b/include/environment.h index ea6b4d12e..507e8326a 100644 --- a/include/environment.h +++ b/include/environment.h @@ -84,6 +84,18 @@  # endif  #endif /* CONFIG_ENV_IS_IN_NAND */ +#if defined(CONFIG_ENV_IS_IN_MG_DISK) +# ifndef CONFIG_ENV_ADDR +#  error "Need to define CONFIG_ENV_ADDR when using CONFIG_ENV_IS_IN_MG_DISK" +# endif +# ifndef CONFIG_ENV_SIZE +#  error "Need to define CONFIG_ENV_SIZE when using CONFIG_ENV_IS_IN_MG_DISK" +# endif +# ifdef CONFIG_ENV_IS_EMBEDDED +#  error "CONFIG_ENV_IS_EMBEDDED not supported when using CONFIG_ENV_IS_IN_MG_DISK" +# endif +#endif /* CONFIG_ENV_IS_IN_MG_DISK */ +  #ifdef USE_HOSTCC  # include <stdint.h>  #else diff --git a/include/mg_disk.h b/include/mg_disk.h new file mode 100644 index 000000000..bd767a115 --- /dev/null +++ b/include/mg_disk.h @@ -0,0 +1,51 @@ +/* + * (C) Copyright 2009 mGine co. + * unsik Kim <donari75@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 + */ + +#ifndef MG_DISK_H_ +#define MG_DISK_H_ + +#include <asm/types.h> + +/* private driver data */ +struct mg_drv_data { +	/* base address of mflash */ +	u32 base; +	/* Initialize hard reset, write protect, deep power down pins. +	 * Set these pins to GPIO and output high +	 */ +	void (*mg_ctrl_pin_init) (void); +	/* Set hard reset pin for given level +	 * level : logical level of hard reset pin (0 or 1) +	 */ +	void (*mg_hdrst_pin) (u8 level); +}; + +struct mg_drv_data* mg_get_drv_data (void); + +unsigned int mg_disk_init (void); +unsigned int mg_disk_read (u32 addr, u8 *buff, u32 len); +unsigned int mg_disk_write(u32 addr, u8 *buff, u32 len); +unsigned int mg_disk_write_sects(void *buff, u32 sect_num, u32 sect_cnt); +unsigned int mg_disk_read_sects(void *buff, u32 sect_num, u32 sect_cnt); + +#endif /*MG_DISK_H_*/ diff --git a/include/part.h b/include/part.h index 980fd0435..3cdae0214 100644 --- a/include/part.h +++ b/include/part.h @@ -100,6 +100,7 @@ block_dev_desc_t* scsi_get_dev(int dev);  block_dev_desc_t* usb_stor_get_dev(int dev);  block_dev_desc_t* mmc_get_dev(int dev);  block_dev_desc_t* systemace_get_dev(int dev); +block_dev_desc_t* mg_disk_get_dev(int dev);  /* disk/part.c */  int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); |