U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
February 2009
- 181 participants
- 548 discussions
This patch does some minor fixing of the Xilinx Spartan III
FPGA boot code:
- Fixed call order of post configuration callback and
success message printing (result of copy-paste?)
- remove obsolete comment
- minor coding style cleanup
Signed-off-by: Matthias Fuchs <matthias.fuchs(a)esd-electronics.com>
---
drivers/fpga/spartan3.c | 22 +++++++---------------
1 files changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/fpga/spartan3.c b/drivers/fpga/spartan3.c
index 9ce41f1..8bb2449 100644
--- a/drivers/fpga/spartan3.c
+++ b/drivers/fpga/spartan3.c
@@ -281,23 +281,18 @@ static int Spartan3_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
}
}
- if (ret_val == FPGA_SUCCESS) {
-#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- puts ("Done.\n");
-#endif
- }
/*
* Run the post configuration function if there is one.
*/
- if (*fn->post) {
+ if (*fn->post)
(*fn->post) (cookie);
- }
- else {
#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
+ if (ret_val == FPGA_SUCCESS)
+ puts ("Done.\n");
+ else
puts ("Fail.\n");
#endif
- }
} else {
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
@@ -567,17 +562,14 @@ static int Spartan3_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
/*
* Run the post configuration function if there is one.
*/
- if (*fn->post) {
+ if (*fn->post)
(*fn->post) (cookie);
- }
#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- if (ret_val == FPGA_SUCCESS) {
+ if (ret_val == FPGA_SUCCESS)
puts ("Done.\n");
- }
- else {
+ else
puts ("Fail.\n");
- }
#endif
} else {
--
1.5.6.3
2
1
This patch does some minor fixing of the Xilinx Spartan II
FPGA boot code:
- Fixed call order of post configuration callback and
success message printing (result of copy-paste?)
- relocate post configuration callback only when it
is implemented
- remove obsolete comment
- minor coding style cleanup
Signed-off-by: Matthias Fuchs <matthias.fuchs(a)esd-electronics.com>
---
drivers/fpga/spartan2.c | 32 +++++++++++---------------------
1 files changed, 11 insertions(+), 21 deletions(-)
diff --git a/drivers/fpga/spartan2.c b/drivers/fpga/spartan2.c
index f5ba7fc..d745334 100644
--- a/drivers/fpga/spartan2.c
+++ b/drivers/fpga/spartan2.c
@@ -260,8 +260,6 @@ static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
ts = get_timer (0); /* get current time */
ret_val = FPGA_SUCCESS;
while ((*fn->done) (cookie) == FPGA_FAIL) {
- /* XXX - we should have a check in here somewhere to
- * make sure we aren't busy forever... */
CONFIG_FPGA_DELAY ();
(*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
@@ -276,23 +274,18 @@ static int Spartan2_sp_load (Xilinx_desc * desc, void *buf, size_t bsize)
}
}
- if (ret_val == FPGA_SUCCESS) {
-#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- puts ("Done.\n");
-#endif
- }
/*
* Run the post configuration function if there is one.
*/
- if (*fn->post) {
+ if (*fn->post)
(*fn->post) (cookie);
- }
- else {
#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
+ if (ret_val == FPGA_SUCCESS)
+ puts ("Done.\n");
+ else
puts ("Fail.\n");
#endif
- }
} else {
printf ("%s: NULL Interface function table!\n", __FUNCTION__);
@@ -412,8 +405,10 @@ static int Spartan2_sp_reloc (Xilinx_desc * desc, ulong reloc_offset)
addr = (ulong) (fn->abort) + reloc_offset;
fn_r->abort = (Xilinx_abort_fn) addr;
- addr = (ulong) (fn->post) + reloc_offset;
- fn_r->post = (Xilinx_post_fn) addr;
+ if (fn->post) {
+ addr = (ulong) (fn->post) + reloc_offset;
+ fn_r->post = (Xilinx_post_fn) addr;
+ }
fn_r->relocated = TRUE;
@@ -541,8 +536,6 @@ static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
(*fn->wr) (TRUE, TRUE, cookie);
while (! (*fn->done) (cookie)) {
- /* XXX - we should have a check in here somewhere to
- * make sure we aren't busy forever... */
CONFIG_FPGA_DELAY ();
(*fn->clk) (FALSE, TRUE, cookie); /* Deassert the clock pin */
@@ -562,17 +555,14 @@ static int Spartan2_ss_load (Xilinx_desc * desc, void *buf, size_t bsize)
/*
* Run the post configuration function if there is one.
*/
- if (*fn->post) {
+ if (*fn->post)
(*fn->post) (cookie);
- }
#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
- if (ret_val == FPGA_SUCCESS) {
+ if (ret_val == FPGA_SUCCESS)
puts ("Done.\n");
- }
- else {
+ else
puts ("Fail.\n");
- }
#endif
} else {
--
1.5.6.3
2
1

[U-Boot] [PATCH v2] drivers/serial/ns16550: move ifdef into Makefile COBJS-$(...)
by Mike Frysinger 21 Feb '09
by Mike Frysinger 21 Feb '09
21 Feb '09
Signed-off-by: Mike Frysinger <vapier(a)gentoo.org>
---
v2
- rebased against master
drivers/serial/Makefile | 4 ++--
drivers/serial/ns16550.c | 5 -----
drivers/serial/serial.c | 4 ----
3 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index b6fd0d7..0f980ab 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -28,10 +28,10 @@ LIB := $(obj)libserial.a
COBJS-$(CONFIG_ATMEL_USART) += atmel_usart.o
COBJS-$(CONFIG_MCFUART) += mcfuart.o
COBJS-$(CONFIG_NS9750_UART) += ns9750_serial.o
-COBJS-y += ns16550.o
+COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
-COBJS-y += serial.o
+COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o
COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 93c2243..a9391c7 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -5,9 +5,6 @@
*/
#include <config.h>
-
-#ifdef CONFIG_SYS_NS16550
-
#include <ns16550.h>
#define LCRVAL LCR_8N1 /* 8 data, 1 stop, no parity */
@@ -75,5 +72,3 @@ int NS16550_tstc (NS16550_t com_port)
{
return ((com_port->lsr & LSR_DR) != 0);
}
-
-#endif
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index bce7548..966df9a 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -23,8 +23,6 @@
#include <common.h>
-#ifdef CONFIG_SYS_NS16550_SERIAL
-
#include <ns16550.h>
#ifdef CONFIG_NS87308
#include <ns87308.h>
@@ -328,5 +326,3 @@ DECLARE_ESERIAL_FUNCTIONS(4);
struct serial_device eserial4_device =
INIT_ESERIAL_STRUCTURE(4,"eserial3","EUART4");
#endif /* CONFIG_SERIAL_MULTI */
-
-#endif
--
1.6.1.2
2
1
Signed-off-by: Derek Ou <dou(a)siconix.com>
---
common/lcd.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/common/lcd.c b/common/lcd.c
index 5f73247..2bcdba2 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -187,7 +187,7 @@ void lcd_putc (const char c)
return;
case '\t': /* Tab (8 chars alignment) */
- console_col |= 8;
+ console_col += 8;
console_col &= ~7;
if (console_col >= CONSOLE_COLS) {
--
1.5.4.3
2
1
Hello, all?
I wrote mflash IO mode block device driver for U-Boot.
Brief desciption of mflash is following.
mflash is fusion memory device mainly targeted consumer eletronic and
mobile phone.
Internally, it have nand flash and other hardware logics and supports
some different operation (ATA, IO, XIP) modes.
IO mode is custom mode for the host that doesn't have IDE interface.
(many mobile targeted SoC doesn't have IDE bus)
This driver support mflash IO mode.
Followings are brief descriptions about IO mode.
1. IO mode based on ATA protocol and uses some custom command. (read
confirm, write confirm)
2. IO mode uses SRAM bus interface.
This driver tested some ARM platform. (pxa270, s3c2440, ...)
Any comments, help would be very appreciated. ^^
unsik Kim
Signed-off-by: unsik Kim <donari75(a)gmail.com>
---
2 0 common/Makefile
83 0 common/cmd_mgdisk.c
2 1 common/cmd_nvedit.c
78 0 common/env_mgdisk.c
9 3 disk/part.c
4 1 disk/part_amiga.c
2 1 disk/part_dos.c
2 1 disk/part_efi.c
2 1 disk/part_iso.c
2 1 disk/part_mac.c
1 0 drivers/block/Makefile
595 0 drivers/block/mg_disk.c
135 0 drivers/block/mg_disk_prv.h
1 0 include/config_cmd_all.h
48 0 include/mg_disk.h
1 0 include/part.h
5 0 lib_arm/board.c
common/Makefile | 2 +
common/cmd_mgdisk.c | 83 ++++++
common/cmd_nvedit.c | 3 +-
common/env_mgdisk.c | 78 ++++++
disk/part.c | 12 +-
disk/part_amiga.c | 5 +-
disk/part_dos.c | 3 +-
disk/part_efi.c | 3 +-
disk/part_iso.c | 3 +-
disk/part_mac.c | 3 +-
drivers/block/Makefile | 1 +
drivers/block/mg_disk.c | 595 +++++++++++++++++++++++++++++++++++++++++++
drivers/block/mg_disk_prv.h | 135 ++++++++++
include/config_cmd_all.h | 1 +
include/mg_disk.h | 48 ++++
include/part.h | 1 +
lib_arm/board.c | 5 +
17 files changed, 972 insertions(+), 9 deletions(-)
diff --git a/common/Makefile b/common/Makefile
index 93e3963..f93e575 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -57,6 +57,7 @@ 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
COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o
+COBJS-$(CONFIG_ENV_IS_IN_MG_DISK) += env_mgdisk.o
COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
# command
@@ -138,6 +139,7 @@ endif
COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
COBJS-$(CONFIG_VFD) += cmd_vfd.o
+COBJS-$(CONFIG_CMD_MG_DISK) += cmd_mgdisk.o
# others
COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
diff --git a/common/cmd_mgdisk.c b/common/cmd_mgdisk.c
new file mode 100644
index 0000000..77bf074
--- /dev/null
+++ b/common/cmd_mgdisk.c
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2009 mGine co.
+ * unsik Kim <donari75(a)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 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"
+ "\t- initialize : mgd init\n"
+ "\t- random read : mgd read [from] [to] [size]\n"
+ "\t\tbelow example read 256 bytes from 0x300000 of mflash\n"
+ "\t\tto 0xA0100000 of host memory\n"
+ "\t\tex) mgd read 0x300000 0xA0100000 256\n"
+ "\t- random write : mgd write [from] [to] [size]\n"
+ "\t\tex) mgd write 0xA0100000 0x300000 256\n"
+ "\t- sector read : mgd readsec [sector] [to] [counts]\n"
+ "\t\tbelow example read 10 sectors starts from 400 sector\n"
+ "\t\tto 0xA0100000\n"
+ "\t\tex) mgd readsec 400 0xA0100000 10\n"
+ "\t- sector write : mgd writesec [from] [sector] [counts]\n"
+);
+
+#endif
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 85025da..4945aeb 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -59,8 +59,9 @@ DECLARE_GLOBAL_DATA_PTR;
!defined(CONFIG_ENV_IS_IN_NAND) && \
!defined(CONFIG_ENV_IS_IN_ONENAND) && \
!defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \
+ !defined(CONFIG_ENV_IS_IN_MG_DISK) && \
!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_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|MG_DISK|NOWHERE}
#endif
#define XMK_STR(x) #x
diff --git a/common/env_mgdisk.c b/common/env_mgdisk.c
new file mode 100644
index 0000000..dd6dee5
--- /dev/null
+++ b/common/env_mgdisk.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2009 mGine co.
+ * unsik Kim <donari75(a)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> /* TODO */
+#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_read(CONFIG_ENV_ADDR, (u_char *) env_ptr, CONFIG_ENV_SIZE);
+ if (err) {
+ puts ("*** Warning - mg_disk_read error, using default environment\n\n");
+ set_default_env();
+ return;
+ }
+
+ if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) {
+ puts ("*** Warning - CRC error, 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 (int)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..c007060 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -39,7 +39,8 @@
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) )
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK))
struct block_drvr {
char *name;
@@ -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 = "mgdisk", .get_dev = mg_disk_get_dev, },
+#endif
{ },
};
@@ -95,7 +99,8 @@ block_dev_desc_t *get_dev(char* ifname, int dev)
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) )
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK))
/* ------------------------------------------------------------------------- */
/*
@@ -207,7 +212,8 @@ void dev_print (block_dev_desc_t *dev_desc)
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) )
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK))
#if defined(CONFIG_MAC_PARTITION) || \
defined(CONFIG_DOS_PARTITION) || \
diff --git a/disk/part_amiga.c b/disk/part_amiga.c
index 6c3d748..b4c2820 100644
--- a/disk/part_amiga.c
+++ b/disk/part_amiga.c
@@ -30,7 +30,8 @@
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_AMIGA_PARTITION)
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK)) && defined(CONFIG_AMIGA_PARTITION)
#undef AMIGA_DEBUG
@@ -40,6 +41,8 @@
#define PRINTF(fmt, args...)
#endif
+#define atoi(x) simple_strtoul(x,NULL,10)
+
struct block_header
{
u32 id;
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 4d778ec..30dc39f 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -40,7 +40,8 @@
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_DOS_PARTITION)
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK)) && defined(CONFIG_DOS_PARTITION)
/* Convert char[4] in little endian format to the host format integer
*/
diff --git a/disk/part_efi.c b/disk/part_efi.c
index cc188ee..e7ff4af 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -41,7 +41,8 @@
defined(CONFIG_CMD_SCSI) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_EFI_PARTITION)
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK)) && defined(CONFIG_EFI_PARTITION)
/* Convert char[2] in little endian format to the host format integer
*/
diff --git a/disk/part_iso.c b/disk/part_iso.c
index 72ff868..95468c9 100644
--- a/disk/part_iso.c
+++ b/disk/part_iso.c
@@ -30,7 +30,8 @@
defined(CONFIG_CMD_SATA) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_ISO_PARTITION)
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK)) && defined(CONFIG_ISO_PARTITION)
/* #define ISO_PART_DEBUG */
diff --git a/disk/part_mac.c b/disk/part_mac.c
index 1922fe5..fefcfdd 100644
--- a/disk/part_mac.c
+++ b/disk/part_mac.c
@@ -39,7 +39,8 @@
defined(CONFIG_CMD_SATA) || \
defined(CONFIG_CMD_USB) || \
defined(CONFIG_MMC) || \
- defined(CONFIG_SYSTEMACE) ) && defined(CONFIG_MAC_PARTITION)
+ defined(CONFIG_SYSTEMACE) || \
+ defined(CONFIG_CMD_MG_DISK)) && defined(CONFIG_MAC_PARTITION)
/* stdlib.h causes some compatibility problems; should fixe these! -- wd */
#ifndef __ldiv_t_defined
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 642582b..87c6e53 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -33,6 +33,7 @@ COBJS-$(CONFIG_SATA_SIL3114) += sata_sil3114.o
COBJS-$(CONFIG_IDE_SIL680) += sil680.o
COBJS-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o
COBJS-$(CONFIG_SYSTEMACE) += systemace.o
+COBJS-$(CONFIG_CMD_MG_DISK) += mg_disk.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
new file mode 100644
index 0000000..06c9bd8
--- /dev/null
+++ b/drivers/block/mg_disk.c
@@ -0,0 +1,595 @@
+/*
+ * (C) Copyright 2009 mGine co.
+ * unsik Kim <donari75(a)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 "mg_disk_prv.h"
+
+#ifdef CONFIG_CMD_MG_DISK
+
+#undef printk
+#define printk printf
+
+#undef KERN_ERR
+#define KERN_ERR
+#undef KERN_DEBUG
+#define KERN_DEBUG
+#undef KERN_INFO
+#define KERN_INFO
+
+#undef inb
+#undef inw
+#undef outb
+#undef outw
+
+#define inb(a) (*(volatile unsigned char *)(a))
+#define inw(a) (*(volatile unsigned short *)(a))
+#define outb(v, a) (*(volatile unsigned char *)(a) = (v))
+#define outw(v, a) (*(volatile unsigned short *)(a) = (v))
+
+#define MG_BASE (host.drv_data->base)
+
+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 };
+
+#define MG_HOST ((struct mg_host *)mg_disk_dev.priv)
+
+static void mg_dump_status (const char *msg, unsigned int stat, unsigned err)
+{
+ char *name = MG_DEV_NAME;
+
+ printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
+ if (stat & MG_REG_STATUS_BIT_BUSY) printk("Busy ");
+ if (stat & MG_REG_STATUS_BIT_READY) printk("DriveReady ");
+ if (stat & MG_REG_STATUS_BIT_WRITE_FAULT) printk("WriteFault ");
+ if (stat & MG_REG_STATUS_BIT_SEEK_DONE) printk("SeekComplete ");
+ if (stat & MG_REG_STATUS_BIT_DATA_REQ) printk("DataRequest ");
+ if (stat & MG_REG_STATUS_BIT_CORRECTED_ERROR) printk("CorrectedError ");
+ if (stat & MG_REG_STATUS_BIT_ERROR) printk("Error ");
+ printk("}\n");
+ if ((stat & MG_REG_STATUS_BIT_ERROR)) {
+ printk("%s: %s: error=0x%02x { ", name, msg, err & 0xff);
+ if (err & MG_REG_ERR_BBK) printk("BadSector ");
+ if (err & MG_REG_ERR_UNC) printk("UncorrectableError ");
+ if (err & MG_REG_ERR_IDNF) printk("SectorIdNotFound ");
+ if (err & MG_REG_ERR_ABRT) printk("DriveStatusError ");
+ if (err & MG_REG_ERR_AMNF) printk("AddrMarkNotFound ");
+ printk("}\n");
+ }
+}
+
+static unsigned int msecs_to_hz (u32 msec)
+{
+ u32 hz = CONFIG_SYS_HZ / 1000 * msec;
+
+ if (!hz)
+ hz = 1;
+
+ return hz;
+}
+
+/*
+ * 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==' '))
+ ++src;
+
+ /* copy string, omitting trailing white space */
+ while ((*src) && (src<end)) {
+ *dst++ = *src;
+ if (*src++ != ' ')
+ last = dst;
+ }
+OUT:
+ *last = '\0';
+}
+
+/* port done */
+static unsigned int mg_wait (u32 expect, u32 msec)
+{
+ u8 status;
+ u32 from, cur, expire, err;
+
+ err = MG_ERR_NONE;
+ from = get_timer(0);
+ expire = from + msecs_to_hz(msec);
+
+ status = inb(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 = inb(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 = inb(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;
+
+ outb(MG_CMD_ID, MG_BASE + MG_REG_COMMAND);
+ err = mg_wait(MG_REG_STATUS_BIT_DATA_REQ, 3000);
+ if (! err) {
+ for(i = 0; i < ((MG_SECTOR_SIZE / sizeof(unsigned long)) >> 1); i++) {
+ buff[i] = inw(MG_BASE + MG_BUFF_OFFSET + i * 2);
+ }
+
+ outb(MG_CMD_RD_CONF, MG_BASE + MG_REG_COMMAND);
+ err = mg_wait(MG_STAT_READY, 3000);
+ if (!err) {
+ if((iop->field_valid & 1) == 0) {
+ err = MG_ERR_TRANSLATION;
+ } else {
+ 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
+ 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 err;
+}
+
+static int mg_disk_reset (void)
+{
+ struct mg_drv_data *prv_data = MG_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 */
+ outb(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 */
+ outb(MG_REG_CTRL_INTR_DISABLE, MG_BASE + MG_REG_DRV_CTRL);
+ err = mg_wait(MG_STAT_READY, 3000);
+ if(err) return err;
+
+ init_status = inb(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;
+ }
+
+ outb((u8)sect_cnt, MG_BASE + MG_REG_SECT_CNT);
+ outb((u8)sect_num, MG_BASE + MG_REG_SECT_NUM);
+ outb((u8)(sect_num >> 8), MG_BASE + MG_REG_CYL_LOW);
+ outb((u8)(sect_num >> 16), MG_BASE + MG_REG_CYL_HIGH);
+ outb((u8)((sect_num >> 24) | MG_REG_HEAD_LBA_MODE), MG_BASE +
MG_REG_DRV_HEAD);
+ outb(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;
+
+ if ((err = mg_out(sect_num, sect_cnt, MG_CMD_RD))) {
+ return err;
+ }
+
+ for (i = 0; i < sect_cnt; i++) {
+ if ((err = mg_wait(MG_REG_STATUS_BIT_DATA_REQ, 3000))) {
+ return err;
+ }
+
+ /* TODO : u16 unaligned case */
+ for(j = 0; j < MG_SECTOR_SIZE >> 1; j++) {
+ *(u16 *)buff_ptr = inw(MG_BASE + MG_BUFF_OFFSET + (j << 1));
+ buff_ptr += 2;
+ }
+
+ outb(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)
+{
+ 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;
+ }
+
+ 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++) {
+ outw(*(u16 *)buff_ptr, MG_BASE + MG_BUFF_OFFSET + (j << 1));
+ buff_ptr += 2;
+ }
+
+ outb(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)
+{
+ 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;
+ }
+
+ 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) {
+ printk(KERN_ERR "%s:%d fail (no driver_data)\n", __func__, __LINE__);
+ err = MG_ERR_NO_DRV_DATA;
+ return err;
+ }
+
+ MG_HOST->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) {
+ printk(KERN_ERR "%s:%d fail (err code : %d)\n", __func__, __LINE__, err);
+ return err;
+ }
+
+ /* get disk id */
+ err = mg_get_disk_id();
+ if (err) {
+ printk(KERN_ERR "%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);
+
+ ((struct mg_host *)mg_disk_dev.priv)->inited = 1;
+
+ return err;
+}
+
+#endif /* CONFIG_CMD_MG_DISK */
diff --git a/drivers/block/mg_disk_prv.h b/drivers/block/mg_disk_prv.h
new file mode 100644
index 0000000..678d652
--- /dev/null
+++ b/drivers/block/mg_disk_prv.h
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2009 mGine co.
+ * unsik Kim <donari75(a)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 */
+#define MG_REG_STATUS_BIT_ERROR 0x01 /* error bit in status register */
+#define MG_REG_STATUS_BIT_CORRECTED_ERROR 0x04 /* corrected error in
status register */
+#define MG_REG_STATUS_BIT_DATA_REQ 0x08 /* data request bit in
status register */
+#define MG_REG_STATUS_BIT_SEEK_DONE 0x10 /* DSC - Drive Seek Complete */
+#define MG_REG_STATUS_BIT_WRITE_FAULT 0x20 /* DWF - Drive Write Fault */
+#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
+
+/* main structure for mflash driver */
+struct mg_host {
+ struct mg_drv_data *drv_data;
+ u32 inited;
+ /* for future use */
+};
+
+/*
+ * Debugging macro and defines
+ */
+#undef DO_MG_DEBUG
+#ifdef DO_MG_DEBUG
+# define MG_DBG(fmt, args...) printk(KERN_DEBUG "%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/include/config_cmd_all.h b/include/config_cmd_all.h
index d771696..0ee2b58 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -83,5 +83,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/mg_disk.h b/include/mg_disk.h
new file mode 100644
index 0000000..3705729
--- /dev/null
+++ b/include/mg_disk.h
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2009 mGine co.
+ * unsik Kim <donari75(a)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 {
+ u32 base;
+
+ /* control pin resource */
+ void (*mg_ctrl_pin_init) (void); /* initialize hdrst, wd, dpd pin to
GPIO and output high */
+ void (*mg_hdrst_pin) (u8 level);
+ void (*mg_wp_pin) (u8 level);
+ void (*mg_dpd_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 980fd04..3cdae02 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);
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 2358beb..6a26bd2 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -48,6 +48,7 @@
#include <serial.h>
#include <nand.h>
#include <onenand_uboot.h>
+#include <mg_disk.h>
#ifdef CONFIG_DRIVER_SMC91111
#include "../drivers/net/smc91111.h"
@@ -348,6 +349,10 @@ void start_armboot (void)
onenand_init();
#endif
+#if defined(CONFIG_CMD_MG_DISK)
+ mg_disk_init();
+#endif
+
#ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
2
3

21 Feb '09
In the commit 79b51ff8205f0354d5300570614c1d2db499679c ([MIPS] cpu/mips/
Makefile: Split [CS]OBJS onto separate lines), I wrongly deleted a START
line. This patch puts it back.
Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi(a)necel.com>
---
cpu/mips/Makefile | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/cpu/mips/Makefile b/cpu/mips/Makefile
index 5091781..28a1cbb 100644
--- a/cpu/mips/Makefile
+++ b/cpu/mips/Makefile
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
+START = start.o
SOBJS-y = cache.o
COBJS-y = cpu.o interrupts.o
2
1

21 Feb '09
Signed-off-by: Wolfgang Denk <wd(a)denx.de>
---
include/configs/TQM823L.h | 1 +
include/configs/TQM823M.h | 1 +
include/configs/TQM850L.h | 1 +
include/configs/TQM850M.h | 1 +
include/configs/TQM855L.h | 1 +
include/configs/TQM855M.h | 1 +
include/configs/TQM860L.h | 1 +
include/configs/TQM860M.h | 1 +
include/configs/TQM862L.h | 1 +
include/configs/TQM862M.h | 1 +
include/configs/TQM866M.h | 1 +
include/configs/TQM885D.h | 1 +
include/configs/virtlab2.h | 1 +
13 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/include/configs/TQM823L.h b/include/configs/TQM823L.h
index 223269f..8934d51 100644
--- a/include/configs/TQM823L.h
+++ b/include/configs/TQM823L.h
@@ -123,6 +123,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM823M.h b/include/configs/TQM823M.h
index aed5d5b..fd41573 100644
--- a/include/configs/TQM823M.h
+++ b/include/configs/TQM823M.h
@@ -121,6 +121,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM850L.h b/include/configs/TQM850L.h
index 4aa8db8..77eb5a9 100644
--- a/include/configs/TQM850L.h
+++ b/include/configs/TQM850L.h
@@ -112,6 +112,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM850M.h b/include/configs/TQM850M.h
index ce5dcc1..bb8825b 100644
--- a/include/configs/TQM850M.h
+++ b/include/configs/TQM850M.h
@@ -110,6 +110,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM855L.h b/include/configs/TQM855L.h
index 012e203..2ccbaf8 100644
--- a/include/configs/TQM855L.h
+++ b/include/configs/TQM855L.h
@@ -116,6 +116,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM855M.h b/include/configs/TQM855M.h
index 84889ea..8a65183 100644
--- a/include/configs/TQM855M.h
+++ b/include/configs/TQM855M.h
@@ -149,6 +149,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
diff --git a/include/configs/TQM860L.h b/include/configs/TQM860L.h
index b67cdcd..8bd1fe0 100644
--- a/include/configs/TQM860L.h
+++ b/include/configs/TQM860L.h
@@ -116,6 +116,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM860M.h b/include/configs/TQM860M.h
index 46852dd..ad2c71c 100644
--- a/include/configs/TQM860M.h
+++ b/include/configs/TQM860M.h
@@ -116,6 +116,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM862L.h b/include/configs/TQM862L.h
index a7fcb1a..0a5180e 100644
--- a/include/configs/TQM862L.h
+++ b/include/configs/TQM862L.h
@@ -119,6 +119,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM862M.h b/include/configs/TQM862M.h
index bcf37d9..ee6980c 100644
--- a/include/configs/TQM862M.h
+++ b/include/configs/TQM862M.h
@@ -119,6 +119,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM866M.h b/include/configs/TQM866M.h
index 87dc264..421a2d8 100644
--- a/include/configs/TQM866M.h
+++ b/include/configs/TQM866M.h
@@ -160,6 +160,7 @@
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_ELF
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
diff --git a/include/configs/TQM885D.h b/include/configs/TQM885D.h
index 942bbf6..4c80bad 100644
--- a/include/configs/TQM885D.h
+++ b/include/configs/TQM885D.h
@@ -157,6 +157,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_EEPROM
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_I2C
#define CONFIG_CMD_IDE
#define CONFIG_CMD_MII
diff --git a/include/configs/virtlab2.h b/include/configs/virtlab2.h
index 38b0a4e..7b61c82 100644
--- a/include/configs/virtlab2.h
+++ b/include/configs/virtlab2.h
@@ -117,6 +117,7 @@
#define CONFIG_CMD_ASKENV
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EXT2
#define CONFIG_CMD_IDE
#define CONFIG_CMD_JFFS2
#define CONFIG_CMD_NFS
--
1.6.0.6
1
0
Hello, all?
Currently ext2ls, ext2load not working (I think sometimes it will work.)
The reason is incorrect operations of ext2fs_read_inode and ext2fs_blockgroup.
I fix miscalculated block number(blkno) and offset (blkoff), and some
hard coded values.
unsik Kim
Signed-off-by: unsik Kim <donari75(a)gmail.com>
---
diff --git a/Makefile b/Makefile
index d26a004..9e9ba36 100644
--- a/Makefile
+++ b/Makefile
@@ -403,6 +403,7 @@ TAG_SUBDIRS += fs/fat
TAG_SUBDIRS += fs/fdos
TAG_SUBDIRS += fs/jffs2
TAG_SUBDIRS += fs/yaffs2
+TAG_SUBDIRS += fs/ext2
TAG_SUBDIRS += net
TAG_SUBDIRS += disk
TAG_SUBDIRS += common
diff --git a/fs/ext2/ext2fs.c b/fs/ext2/ext2fs.c
index 436f4a4..4ac2bdd 100644
--- a/fs/ext2/ext2fs.c
+++ b/fs/ext2/ext2fs.c
@@ -110,6 +110,7 @@ struct ext2_block_group {
uint32_t inode_table_id;
uint16_t free_blocks;
uint16_t free_inodes;
+ uint16_t used_dir_cnt;
uint16_t pad;
uint32_t reserved[3];
};
@@ -182,14 +183,22 @@ int indir2_blkno = -1;
static int ext2fs_blockgroup
(struct ext2_data *data, int group, struct ext2_block_group *blkgrp) {
+ unsigned int blkno;
+ unsigned int blkoff;
+ unsigned int desc_per_blk;
+
+ desc_per_blk = EXT2_BLOCK_SIZE(data) / sizeof(struct ext2_block_group);
+
+ blkno = __le32_to_cpu(data->sblock.first_data_block) + 1 +
+ group / desc_per_blk;
+ blkoff = (group % desc_per_blk) * sizeof(struct ext2_block_group);
#ifdef DEBUG
- printf ("ext2fs read blockgroup\n");
+ printf ("ext2fs read %d group descriptor (blkno %d blkoff %d)\n",
+ group, blkno, blkoff);
#endif
return (ext2fs_devread
- (((__le32_to_cpu (data->sblock.first_data_block) +
- 1) << LOG2_EXT2_BLOCK_SIZE (data)),
- group * sizeof (struct ext2_block_group),
- sizeof (struct ext2_block_group), (char *) blkgrp));
+ (blkno << LOG2_EXT2_BLOCK_SIZE(data),
+ blkoff, sizeof(struct ext2_block_group), (char *)blkgrp));
}
@@ -203,11 +212,11 @@ static int ext2fs_read_inode
unsigned int blkno;
unsigned int blkoff;
- /* It is easier to calculate if the first inode is 0. */
- ino--;
#ifdef DEBUG
printf ("ext2fs read inode %d\n", ino);
#endif
+ /* It is easier to calculate if the first inode is 0. */
+ ino--;
status = ext2fs_blockgroup (data,
ino /
__le32_to_cpu (sblock->inodes_per_group),
@@ -215,19 +224,16 @@ static int ext2fs_read_inode
if (status == 0) {
return (0);
}
- inodes_per_block = EXT2_BLOCK_SIZE (data) / 128;
- blkno = (ino % __le32_to_cpu (sblock->inodes_per_group)) /
- inodes_per_block;
- blkoff = (ino % __le32_to_cpu (sblock->inodes_per_group)) %
- inodes_per_block;
+ inodes_per_block = EXT2_BLOCK_SIZE(data) / __le32_to_cpu(sblock->inode_size);
+ blkno = blkgrp.inode_table_id +
+ (ino % __le32_to_cpu(sblock->inodes_per_group)) / inodes_per_block;
+ blkoff = (ino % inodes_per_block) * __le32_to_cpu(sblock->inode_size);
#ifdef DEBUG
printf ("ext2fs read inode blkno %d blkoff %d\n", blkno, blkoff);
#endif
/* Read the inode. */
- status = ext2fs_devread (((__le32_to_cpu (blkgrp.inode_table_id) +
- blkno) << LOG2_EXT2_BLOCK_SIZE (data)),
- sizeof (struct ext2_inode) * blkoff,
- sizeof (struct ext2_inode), (char *) inode);
+ status = ext2fs_devread (blkno << LOG2_EXT2_BLOCK_SIZE (data), blkoff,
+ sizeof (struct ext2_inode), (char *) inode);
if (status == 0) {
return (0);
}
2
1

21 Feb '09
Hello ksi,
ksi(a)koi8.net wrote:
> Signed-off-by: Sergey Kubushyn <ksi(a)koi8.net>
> ---
> diff -purN u-boot-i2c.orig/drivers/i2c/soft_i2c.c u-boot-i2c/drivers/i2c/soft_i2c.c
> --- u-boot-i2c.orig/drivers/i2c/soft_i2c.c 2009-02-12 10:43:41.000000000 -0800
> +++ u-boot-i2c/drivers/i2c/soft_i2c.c 2009-02-12 10:46:00.000000000 -0800
> @@ -1,4 +1,8 @@
> /*
> + * Copyright (c) 2009 Sergey Kubushyn <ksi(a)koi8.net>
> + *
> + * Changes for multibus/multiadapter I2C support.
> + *
> * (C) Copyright 2001, 2002
> * Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
[...]
The following patch is based on your patches without 7/12 and
adds multibus support for the soft_i2c driver without doing such
a big change as you did. Maybe it is not yet perfect, because
it is just a fast try, but I think we should go this way. What
do you/others think?
Also it is compatible with existing board ports.
I tried this on an 8xx based board (mgsuvd) with success.
>From 4f47e858059d02ca9a9a38b35bef55b69c98c3d3 Mon Sep 17 00:00:00 2001
From: Heiko Schocher <hs(a)denx.de>
Date: Fri, 13 Feb 2009 11:10:54 +0100
Subject: [PATCH] soft_i2c: add multibus support
Signed-off-by: Heiko Schocher <hs(a)denx.de>
---
drivers/i2c/i2c_core.c | 3 +
drivers/i2c/soft_i2c.c | 129 ++++++++++++++++++++++++++++------------------
include/configs/mgsuvd.h | 3 +
include/i2c.h | 8 +++-
4 files changed, 91 insertions(+), 52 deletions(-)
diff --git a/drivers/i2c/i2c_core.c b/drivers/i2c/i2c_core.c
index 4466908..e0afd10 100644
--- a/drivers/i2c/i2c_core.c
+++ b/drivers/i2c/i2c_core.c
@@ -39,6 +39,7 @@ extern i2c_adap_t tsi108_i2c_adap;
#endif
i2c_adap_t *i2c_adap[CONFIG_SYS_NUM_I2C_ADAPTERS] = CONFIG_SYS_I2C_ADAPTERS;
+i2c_adap_t *cur_adap_nr = NULL;
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
i2c_bus_t i2c_bus[CONFIG_SYS_NUM_I2C_BUSSES] = CONFIG_SYS_I2C_BUSSES;
#endif
@@ -208,6 +209,7 @@ int i2c_set_bus_num(unsigned int bus)
#endif
i2c_cur_bus = bus;
+ cur_adap_nr = (i2c_adap_t *)&ADAP(bus);
return(0);
}
@@ -243,6 +245,7 @@ void i2c_init_all(void)
{
int i;
+ cur_adap_nr = (i2c_adap_t *)&ADAP(0);
for (i = 0; i < CONFIG_SYS_NUM_I2C_ADAPTERS; i++) {
if ((i2c_adap[i]->speed != 0) && (i2c_adap[i]->init != NULL)) {
i2c_adap[i]->init(i2c_adap[i]->speed, i2c_adap[i]->slaveaddr);
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index da6cec1..b5302a4 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -55,7 +55,6 @@ DECLARE_GLOBAL_DATA_PTR;
/*-----------------------------------------------------------------------
* Definitions
*/
-
#define RETRIES 0
@@ -216,52 +215,6 @@ static int write_byte(uchar data)
return(nack); /* not a nack is an ack */
}
-#if defined(CONFIG_I2C_MULTI_BUS)
-/*
- * Functions for multiple I2C bus handling
- */
-unsigned int i2c_get_bus_num(void)
-{
- return i2c_bus_num;
-}
-
-int i2c_set_bus_num(unsigned int bus)
-{
-#if defined(CONFIG_I2C_MUX)
- if (bus < CONFIG_SYS_MAX_I2C_BUS) {
- i2c_bus_num = bus;
- } else {
- int ret;
-
- ret = i2x_mux_select_mux(bus);
- if (ret == 0)
- i2c_bus_num = bus;
- else
- return ret;
- }
-#else
- if (bus >= CONFIG_SYS_MAX_I2C_BUS)
- return -1;
- i2c_bus_num = bus;
-#endif
- return 0;
-}
-
-/* TODO: add 100/400k switching */
-unsigned int i2c_get_bus_speed(void)
-{
- return CONFIG_SYS_I2C_SPEED;
-}
-
-int i2c_set_bus_speed(unsigned int speed)
-{
- if (speed != CONFIG_SYS_I2C_SPEED)
- return -1;
-
- return 0;
-}
-#endif
-
/*-----------------------------------------------------------------------
* if ack == I2C_ACK, ACK the byte so can continue reading, else
* send I2C_NOACK to end the read.
@@ -299,7 +252,7 @@ static uchar read_byte(int ack)
/*-----------------------------------------------------------------------
* Initialization
*/
-void i2c_init (int speed, int slaveaddr)
+void soft_i2c_init (int speed, int slaveaddr)
{
#if defined(CONFIG_SYS_I2C_INIT_BOARD)
/* call board specific i2c bus reset routine before accessing the */
@@ -322,7 +275,7 @@ void i2c_init (int speed, int slaveaddr)
* completion of EEPROM writes since the chip stops responding until
* the write completes (typically 10mSec).
*/
-int i2c_probe(uchar addr)
+int soft_i2c_probe(u_int8_t addr)
{
int rc;
@@ -340,7 +293,7 @@ int i2c_probe(uchar addr)
/*-----------------------------------------------------------------------
* Read bytes
*/
-int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+int soft_i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int shift;
PRINTD("i2c_read: chip %02X addr %02X alen %d buffer %p len %d\n",
@@ -414,7 +367,7 @@ int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
/*-----------------------------------------------------------------------
* Write bytes
*/
-int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+int soft_i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
{
int shift, failures = 0;
@@ -444,3 +397,77 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
send_stop();
return(failures);
}
+
+static unsigned int soft_i2c_get_bus_speed(void)
+{
+ return cur_adap_nr->speed;
+}
+
+static unsigned int soft_i2c_set_bus_speed(unsigned int speed)
+{
+ if (speed != cur_adap_nr->speed)
+ return -1;
+ return(speed);
+}
+
+i2c_adap_t soft_i2c_adap[] = {
+ {
+ .init = soft_i2c_init,
+ .probe = soft_i2c_probe,
+ .read = soft_i2c_read,
+ .write = soft_i2c_write,
+ .set_bus_speed = soft_i2c_set_bus_speed,
+ .get_bus_speed = soft_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SOFT_I2C_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C_SLAVE,
+ .init_done = 0,
+ .hwadapnr = 0,
+ .name = "soft-i2c"
+ },
+#if defined(I2C_SOFT_DECLARATIONS2)
+ {
+ .init = soft_i2c_init,
+ .probe = soft_i2c_probe,
+ .read = soft_i2c_read,
+ .write = soft_i2c_write,
+ .set_bus_speed = soft_i2c_set_bus_speed,
+ .get_bus_speed = soft_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SOFT_I2C2_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C2_SLAVE,
+ .init_done = 0,
+ .hwadapnr = 1,
+ .name = "soft-i2c#2"
+ },
+#endif
+#if defined(I2C_SOFT_DECLARATIONS3)
+ {
+ .init = soft_i2c_init,
+ .probe = soft_i2c_probe,
+ .read = soft_i2c_read,
+ .write = soft_i2c_write,
+ .set_bus_speed = soft_i2c_set_bus_speed,
+ .get_bus_speed = soft_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SOFT_I2C3_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C3_SLAVE,
+ .init_done = 0,
+ .hwadapnr = 2,
+ .name = "soft-i2c#3"
+ },
+#endif
+#if defined(I2C_SOFT_DECLARATIONS4)
+ {
+ .init = soft_i2c_init,
+ .probe = soft_i2c_probe,
+ .read = soft_i2c_read,
+ .write = soft_i2c_write,
+ .set_bus_speed = soft_i2c_set_bus_speed,
+ .get_bus_speed = soft_i2c_get_bus_speed,
+ .speed = CONFIG_SYS_SOFT_I2C4_SPEED,
+ .slaveaddr = CONFIG_SYS_SOFT_I2C4_SLAVE,
+ .init_done = 0,
+ .hwadapnr = 3,
+ .name = "soft-i2c#4"
+ },
+#endif
+};
+
diff --git a/include/configs/mgsuvd.h b/include/configs/mgsuvd.h
index 3ea0725..b1debbc 100644
--- a/include/configs/mgsuvd.h
+++ b/include/configs/mgsuvd.h
@@ -270,6 +270,7 @@
#define CONFIG_SYS_NUM_I2C_BUSSES 3
#define CONFIG_SYS_I2C_MAX_HOPS 1
#define CONFIG_SOFT_I2C /* I2C bit-banged */
+#define I2C_SOFT_DEFS
#define I2C_SOFT_DECLARATIONS I2C_SOFT_DEFS
#define CONFIG_SYS_SOFT_I2C_SPEED 50000
#define CONFIG_SYS_SOFT_I2C_SLAVE 0x7F
@@ -277,6 +278,8 @@
#define CONFIG_SYS_I2C_BUSSES { {0, {I2C_NULL_HOP}}, \
{0, {{I2C_MUX_PCA9542, 0x70, 0}}}, \
{0, {{I2C_MUX_PCA9542, 0x70, 1}}}}
+
+#define CONFIG_I2C_CMD_TREE 1
/*
* Software (bit-bang) I2C driver configuration
*/
diff --git a/include/i2c.h b/include/i2c.h
index ea2c3b2..a3cc3ca 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -95,7 +95,8 @@ typedef struct i2c_adapter {
int speed;
int slaveaddr;
int init_done;
- char *name;
+ int hwadapnr;
+ char *name;
} i2c_adap_t;
#ifndef CONFIG_SYS_I2C_DIRECT_BUS
@@ -130,6 +131,7 @@ extern i2c_bus_t i2c_bus[];
#endif
extern i2c_adap_t *i2c_adap[];
+extern i2c_adap_t *cur_adap_nr;
/*
* i2c_get_bus_num:
@@ -226,7 +228,11 @@ void i2c_reloc_fixup(void);
# else
# define I2C_SOFT_DEFS
# endif
+#endif
+#ifndef CONFIG_SYS_I2C_SLAVE
+#define CONFIG_SYS_I2C_SLAVE 0x7f
+#endif
/*
* Initialization, must be called once on start up, may be called
* repeatedly to change the speed and slave addresses.
--
1.6.0.6
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
3
71
Hi all,
This is the patch for UDC support for PXA27X , it is based on a
patch previously submitted by Rodolfo Giometti.
--
Regards,
Vivek Kutal
From 081685ce3c5b80bc439485ec8e1847d85dc7ad70 Mon Sep 17 00:00:00 2001
From: Vivek Kutal <vivek.kutal(a)azingo.com>
Date: Thu, 19 Feb 2009 17:56:38 +0530
Subject: [PATCH] Support for PXA27X UDC.
Signed-off-by: Vivek Kutal <vivek.kutal(a)azingo.com>
---
drivers/usb/Makefile | 1 +
drivers/usb/pxa27x_udc_regs.h | 417 ++++++++++++++++++++++++
drivers/usb/usbdcore_pxa27x.c | 714
+++++++++++++++++++++++++++++++++++++++++
include/usbdcore_pxa2xx.h | 68 ++++
4 files changed, 1200 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/pxa27x_udc_regs.h
create mode 100644 drivers/usb/usbdcore_pxa27x.c
create mode 100644 include/usbdcore_pxa2xx.h
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index b306a65..0a1886a 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -47,6 +47,7 @@ COBJS-y += usbdcore_ep0.o
COBJS-$(CONFIG_OMAP1510) += usbdcore_omap1510.o
COBJS-$(CONFIG_OMAP1610) += usbdcore_omap1510.o
COBJS-$(CONFIG_MPC885_FAMILY) += usbdcore_mpc8xx.o
+COBJS-$(CONFIG_PXA27X) += usbdcore_pxa27x.o
endif
COBJS := $(COBJS-y)
diff --git a/drivers/usb/pxa27x_udc_regs.h b/drivers/usb/pxa27x_udc_regs.h
new file mode 100644
index 0000000..47bf66e
--- /dev/null
+++ b/drivers/usb/pxa27x_udc_regs.h
@@ -0,0 +1,417 @@
+/*
+ * Taken from linux kernel include/asm-arm/arch-pxa/pxa-regs.h
+ *
+ */
+
+
+#ifndef __PXA27X_UDC_REGS_H
+#define __PXA27X_UDC_REGS_H
+
+/*
+ * USB Device Controller
+ */
+#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented -
Reserved1 */
+#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented -
Reserved2 */
+#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented -
Reserved3 */
+
+#define UDCCONR_CN (0x03 << 25) /* Configuration Number */
+#define UDCCONR_CN_S (25)
+#define UDCCONR_IN (0x07 << 22) /* Interface Number */
+#define UDCCONR_IN_S (22)
+#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface
Number */
+#define UDCCONR_AISN_S (19)
+#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */
+#define UDCCONR_EN_S (15)
+#define UDCCONR_ET_S (13)
+#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */
+#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */
+#define UDCCONR_ET_NU (0x00 << 13) /* Not used */
+#define UDCCONR_ED (1 << 12) /* Endpoint Direction */
+#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */
+#define UDCCONR_MPS_S (2)
+#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */
+#define UDCCONR_EE (1 << 0) /* Endpoint Enable */
+#define GPDR1_B_USB_DEC_N (0x01 << 3)
+
+
+#define UDCCRA __REG(0x40600404) /* Configuration register EPA */
+#define UDCCRB __REG(0x40600408) /* Configuration register EPB */
+#define UP2OCR __REG(0x40600020)
+#define UDCWAKEUP __REG(0x40F00044)
+#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control
Register0 */
+#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control
Register1 */
+#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status
Register 0 */
+#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status
Register 1 */
+
+
+
+#define UDCCR __REG(0x40600000) /* UDC Control Register */
+#define UDCCR_UDE (1 << 0) /* UDC enable */
+#define UDCCR_UDA (1 << 1) /* UDC active */
+#define UDCCR_RSM (1 << 2) /* Device resume */
+#define UDCCR_RESIR (1 << 29) /* Resume interrupt request */
+#define UDCCR_SUSIR (1 << 28) /* Suspend interrupt request */
+#define UDCCR_SM (1 << 28) /* Suspend interrupt mask */
+#define UDCCR_RSTIR (1 << 27) /* Reset interrupt request */
+#define UDCCR_REM (1 << 27) /* Reset interrupt mask */
+#define UDCCR_RM (1 << 29) /* resume interrupt mask */
+#define UDCCR_SRM UDCCR_SM|UDCCR_RM
+
+#define UDCCS0 __REG(0x40600100) /* UDC Endpoint 0
Control/Status Register */
+#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
+#define UDCCS0_IPR (1 << 1) /* IN packet ready */
+#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS0_DRWF (1 << 16) /* Device remote wakeup feature */
+#define UDCCS0_SST (1 << 4) /* Sent stall */
+#define UDCCS0_FST (1 << 5) /* Force stall */
+#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
+#define UDCCS0_SA (1 << 7) /* Setup active */
+
+/* Bulk IN - Endpoint 1,6,11 */
+#define UDCCS1 __REG(0x40600104) /* UDC Endpoint 1 (IN)
Control/Status Register */
+#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN)
Control/Status Register */
+#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN)
Control/Status Register */
+
+#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_BI_FTF (1 << 8) /* Flush Tx FIFO */
+#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_BI_SST (1 << 4) /* Sent stall */
+#define UDCCS_BI_FST (1 << 5) /* Force stall */
+#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
+
+/* Bulk OUT - Endpoint 2,7,12 */
+#define UDCCS2 __REG(0x40600108) /* UDC Endpoint 2
(OUT) Control/Status Register */
+#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7
(OUT) Control/Status Register */
+#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12
(OUT) Control/Status Register */
+
+#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_BO_DME (1 << 3) /* DMA enable */
+#define UDCCS_BO_SST (1 << 4) /* Sent stall */
+#define UDCCS_BO_FST (1 << 5) /* Force stall */
+#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
+
+/* Isochronous IN - Endpoint 3,8,13 */
+#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN)
Control/Status Register */
+#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN)
Control/Status Register */
+#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN)
Control/Status Register */
+
+#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
+
+/* Isochronous OUT - Endpoint 4,9,14 */
+#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT)
Control/Status Register */
+#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT)
Control/Status Register */
+#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT)
Control/Status Register */
+
+#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
+#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
+#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
+#define UDCCS_IO_DME (1 << 3) /* DMA enable */
+#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
+#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
+
+/* Interrupt IN - Endpoint 5,10,15 */
+#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt)
Control/Status Register */
+#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10
(Interrupt) Control/Status Register */
+#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15
(Interrupt) Control/Status Register */
+
+#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
+#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
+#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
+#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
+#define UDCCS_INT_SST (1 << 4) /* Sent stall */
+#define UDCCS_INT_FST (1 << 5) /* Force stall */
+#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
+
+#define UFNRH __REG(0x40600060) /* UDC Frame Number Register
High */
+#define UFNRL __REG(0x40600014) /* UDC Frame Number Register Low */
+#define UBCR2 __REG(0x40600208) /* UDC Byte Count Reg 2 */
+#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */
+#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */
+#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */
+#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */
+#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */
+#define UDDR0 __REG(0x40600300) /* UDC Endpoint 0 Data Register */
+#define UDDR1 __REG(0x40600304) /* UDC Endpoint 1 Data Register */
+#define UDDR2 __REG(0x40600308) /* UDC Endpoint 2 Data Register */
+#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */
+#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */
+#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */
+#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */
+#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */
+#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */
+#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */
+#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data
Register */
+#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data
Register */
+#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data
Register */
+#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data
Register */
+#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data
Register */
+#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data
Register */
+
+#define UICR0 __REG(0x40600004) /* UDC Interrupt Control
Register 0 */
+
+#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
+#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
+#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
+#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
+#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
+#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
+#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
+#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
+
+#define UICR1 __REG(0x40600008) /* UDC Interrupt Control
Register 1 */
+
+#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
+#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
+#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
+#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
+#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
+#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
+#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
+#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
+
+#define USIR0 __REG(0x4060000C) /* UDC Status Interrupt
Register 0 */
+
+#define USIR0_IR0 (1 << 0) /* Interrup request ep 0 */
+#define USIR0_IR1 (1 << 2) /* Interrup request ep 1 */
+#define USIR0_IR2 (1 << 4) /* Interrup request ep 2 */
+#define USIR0_IR3 (1 << 3) /* Interrup request ep 3 */
+#define USIR0_IR4 (1 << 4) /* Interrup request ep 4 */
+#define USIR0_IR5 (1 << 5) /* Interrup request ep 5 */
+#define USIR0_IR6 (1 << 6) /* Interrup request ep 6 */
+#define USIR0_IR7 (1 << 7) /* Interrup request ep 7 */
+
+#define USIR1 __REG(0x40600010) /* UDC Status Interrupt
Register 1 */
+
+#define USIR1_IR8 (1 << 0) /* Interrup request ep 8 */
+#define USIR1_IR9 (1 << 1) /* Interrup request ep 9 */
+#define USIR1_IR10 (1 << 2) /* Interrup request ep 10 */
+#define USIR1_IR11 (1 << 3) /* Interrup request ep 11 */
+#define USIR1_IR12 (1 << 4) /* Interrup request ep 12 */
+#define USIR1_IR13 (1 << 5) /* Interrup request ep 13 */
+#define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */
+#define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */
+
+#define UDCCR __REG(0x40600000) /* UDC Control Register */
+#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
+#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host
Negotiation Protocol Port Support */
+#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation
Protocol Support */
+#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation
Protocol Enable */
+#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */
+#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration
Number */
+#define UDCCR_ACN_S 11
+#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */
+#define UDCCR_AIN_S 8
+#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate
Interface Setting Number */
+#define UDCCR_AAISN_S 5
+#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to
Active Configuration */
+#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration
Error */
+#define UDCCR_UDR (1 << 2) /* UDC Resume */
+#define UDCCR_UDA (1 << 1) /* UDC Active */
+#define UDCCR_UDE (1 << 0) /* UDC Enable */
+
+#define UDCICR0 __REG(0x40600004) /* UDC Interrupt Control
Register0 */
+#define UDCICR1 __REG(0x40600008) /* UDC Interrupt Control
Register1 */
+#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */
+#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */
+
+#define UDC_INT_FIFOERROR (0x2)
+#define UDC_INT_PACKETCMP (0x1)
+
+#define UDCICR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */
+#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */
+#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */
+#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */
+#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */
+
+#define UDCISR0 __REG(0x4060000C) /* UDC Interrupt Status
Register 0 */
+#define UDCISR1 __REG(0x40600010) /* UDC Interrupt Status
Register 1 */
+#define UDCISR_INT(n,intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCISR1_IRCC (1 << 31) /* IntEn - Configuration Change */
+#define UDCISR1_IRSOF (1 << 30) /* IntEn - Start of Frame */
+#define UDCISR1_IRRU (1 << 29) /* IntEn - Resume */
+#define UDCISR1_IRSU (1 << 28) /* IntEn - Suspend */
+#define UDCISR1_IRRS (1 << 27) /* IntEn - Reset */
+
+
+#define UDCFNR __REG(0x40600014) /* UDC Frame Number
Register */
+#define UDCOTGICR __REG(0x40600018) /* UDC On-The-Go
interrupt control */
+#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command
recvd */
+#define UDCOTGICR_IEXR (1 << 17) /* Extra Transciever
Interrupt Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16) /* Extra Transciever
Interrupt Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising
Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling
Edge Interrupt Enable */
+#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising
Edge Interrupt Enable */
+#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling
Edge Interrupt Enable */
+#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising
Edge Interrupt Enable */
+#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling
Edge Interrupt Enable */
+#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect
Rising Edge Interrupt Enable */
+#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect
Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge
Interrupt Enable */
+#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling
Edge Interrupt Enable */
+
+#define UDCCSN(x) __REG2(0x40600100, (x) << 2)
+#define UDCCSR0 __REG(0x40600100) /* UDC Control/Status
register - Endpoint 0 */
+
+#define UDCCSR0_SA (1 << 7) /* Setup Active */
+#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */
+#define UDCCSR0_FST (1 << 5) /* Force Stall */
+#define UDCCSR0_SST (1 << 4) /* Sent Stall */
+#define UDCCSR0_DME (1 << 3) /* DMA Enable */
+#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */
+#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */
+#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */
+
+#define UDCCSRA __REG(0x40600104) /* UDC Control/Status
register - Endpoint A */
+#define UDCCSRB __REG(0x40600108) /* UDC Control/Status
register - Endpoint B */
+#define UDCCSRC __REG(0x4060010C) /* UDC Control/Status
register - Endpoint C */
+#define UDCCSRD __REG(0x40600110) /* UDC Control/Status
register - Endpoint D */
+#define UDCCSRE __REG(0x40600114) /* UDC Control/Status
register - Endpoint E */
+#define UDCCSRF __REG(0x40600118) /* UDC Control/Status
register - Endpoint F */
+#define UDCCSRG __REG(0x4060011C) /* UDC Control/Status
register - Endpoint G */
+#define UDCCSRH __REG(0x40600120) /* UDC Control/Status
register - Endpoint H */
+#define UDCCSRI __REG(0x40600124) /* UDC Control/Status
register - Endpoint I */
+#define UDCCSRJ __REG(0x40600128) /* UDC Control/Status
register - Endpoint J */
+#define UDCCSRK __REG(0x4060012C) /* UDC Control/Status
register - Endpoint K */
+#define UDCCSRL __REG(0x40600130) /* UDC Control/Status
register - Endpoint L */
+#define UDCCSRM __REG(0x40600134) /* UDC Control/Status
register - Endpoint M */
+#define UDCCSRN __REG(0x40600138) /* UDC Control/Status
register - Endpoint N */
+#define UDCCSRP __REG(0x4060013C) /* UDC Control/Status
register - Endpoint P */
+#define UDCCSRQ __REG(0x40600140) /* UDC Control/Status
register - Endpoint Q */
+#define UDCCSRR __REG(0x40600144) /* UDC Control/Status
register - Endpoint R */
+#define UDCCSRS __REG(0x40600148) /* UDC Control/Status
register - Endpoint S */
+#define UDCCSRT __REG(0x4060014C) /* UDC Control/Status
register - Endpoint T */
+#define UDCCSRU __REG(0x40600150) /* UDC Control/Status
register - Endpoint U */
+#define UDCCSRV __REG(0x40600154) /* UDC Control/Status
register - Endpoint V */
+#define UDCCSRW __REG(0x40600158) /* UDC Control/Status
register - Endpoint W */
+#define UDCCSRX __REG(0x4060015C) /* UDC Control/Status
register - Endpoint X */
+
+#define UDCCSR_DPE (1 << 9) /* Data Packet Error */
+#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */
+#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */
+#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */
+#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */
+#define UDCCSR_FST (1 << 5) /* Force STALL */
+#define UDCCSR_SST (1 << 4) /* Sent STALL */
+#define UDCCSR_DME (1 << 3) /* DMA Enable */
+#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */
+#define UDCCSR_PC (1 << 1) /* Packet Complete */
+#define UDCCSR_FS (1 << 0) /* FIFO needs service */
+
+#define UDCBCN(x) __REG2(0x40600200, (x)<<2)
+#define UDCBCR0 __REG(0x40600200) /* Byte Count Register - EP0 */
+#define UDCBCRA __REG(0x40600204) /* Byte Count Register - EPA */
+#define UDCBCRB __REG(0x40600208) /* Byte Count Register - EPB */
+#define UDCBCRC __REG(0x4060020C) /* Byte Count Register - EPC */
+#define UDCBCRD __REG(0x40600210) /* Byte Count Register - EPD */
+#define UDCBCRE __REG(0x40600214) /* Byte Count Register - EPE */
+#define UDCBCRF __REG(0x40600218) /* Byte Count Register - EPF */
+#define UDCBCRG __REG(0x4060021C) /* Byte Count Register - EPG */
+#define UDCBCRH __REG(0x40600220) /* Byte Count Register - EPH */
+#define UDCBCRI __REG(0x40600224) /* Byte Count Register - EPI */
+#define UDCBCRJ __REG(0x40600228) /* Byte Count Register - EPJ */
+#define UDCBCRK __REG(0x4060022C) /* Byte Count Register - EPK */
+#define UDCBCRL __REG(0x40600230) /* Byte Count Register - EPL */
+#define UDCBCRM __REG(0x40600234) /* Byte Count Register - EPM */
+#define UDCBCRN __REG(0x40600238) /* Byte Count Register - EPN */
+#define UDCBCRP __REG(0x4060023C) /* Byte Count Register - EPP */
+#define UDCBCRQ __REG(0x40600240) /* Byte Count Register - EPQ */
+#define UDCBCRR __REG(0x40600244) /* Byte Count Register - EPR */
+#define UDCBCRS __REG(0x40600248) /* Byte Count Register - EPS */
+#define UDCBCRT __REG(0x4060024C) /* Byte Count Register - EPT */
+#define UDCBCRU __REG(0x40600250) /* Byte Count Register - EPU */
+#define UDCBCRV __REG(0x40600254) /* Byte Count Register - EPV */
+#define UDCBCRW __REG(0x40600258) /* Byte Count Register - EPW */
+#define UDCBCRX __REG(0x4060025C) /* Byte Count Register - EPX */
+
+#define UDCDN(x) __REG2(0x40600300, (x)<<2)
+#define PHYS_UDCDN(x) (0x40600300 + ((x)<<2))
+#define PUDCDN(x) (volatile u32 *)(io_p2v(PHYS_UDCDN((x))))
+#define UDCDR0 __REG(0x40600300) /* Data Register - EP0 */
+#define UDCDRA __REG(0x40600304) /* Data Register - EPA */
+#define UDCDRB __REG(0x40600308) /* Data Register - EPB */
+#define UDCDRC __REG(0x4060030C) /* Data Register - EPC */
+#define UDCDRD __REG(0x40600310) /* Data Register - EPD */
+#define UDCDRE __REG(0x40600314) /* Data Register - EPE */
+#define UDCDRF __REG(0x40600318) /* Data Register - EPF */
+#define UDCDRG __REG(0x4060031C) /* Data Register - EPG */
+#define UDCDRH __REG(0x40600320) /* Data Register - EPH */
+#define UDCDRI __REG(0x40600324) /* Data Register - EPI */
+#define UDCDRJ __REG(0x40600328) /* Data Register - EPJ */
+#define UDCDRK __REG(0x4060032C) /* Data Register - EPK */
+#define UDCDRL __REG(0x40600330) /* Data Register - EPL */
+#define UDCDRM __REG(0x40600334) /* Data Register - EPM */
+#define UDCDRN __REG(0x40600338) /* Data Register - EPN */
+#define UDCDRP __REG(0x4060033C) /* Data Register - EPP */
+#define UDCDRQ __REG(0x40600340) /* Data Register - EPQ */
+#define UDCDRR __REG(0x40600344) /* Data Register - EPR */
+#define UDCDRS __REG(0x40600348) /* Data Register - EPS */
+#define UDCDRT __REG(0x4060034C) /* Data Register - EPT */
+#define UDCDRU __REG(0x40600350) /* Data Register - EPU */
+#define UDCDRV __REG(0x40600354) /* Data Register - EPV */
+#define UDCDRW __REG(0x40600358) /* Data Register - EPW */
+#define UDCDRX __REG(0x4060035C) /* Data Register - EPX */
+
+#define UDCCN(x) __REG2(0x40600400, (x)<<2)
+#define UDCCRA __REG(0x40600404) /* Configuration register EPA */
+#define UDCCRB __REG(0x40600408) /* Configuration register EPB */
+#define UDCCRC __REG(0x4060040C) /* Configuration register EPC */
+#define UDCCRD __REG(0x40600410) /* Configuration register EPD */
+#define UDCCRE __REG(0x40600414) /* Configuration register EPE */
+#define UDCCRF __REG(0x40600418) /* Configuration register EPF */
+#define UDCCRG __REG(0x4060041C) /* Configuration register EPG */
+#define UDCCRH __REG(0x40600420) /* Configuration register EPH */
+#define UDCCRI __REG(0x40600424) /* Configuration register EPI */
+#define UDCCRJ __REG(0x40600428) /* Configuration register EPJ */
+#define UDCCRK __REG(0x4060042C) /* Configuration register EPK */
+#define UDCCRL __REG(0x40600430) /* Configuration register EPL */
+#define UDCCRM __REG(0x40600434) /* Configuration register EPM */
+#define UDCCRN __REG(0x40600438) /* Configuration register EPN */
+#define UDCCRP __REG(0x4060043C) /* Configuration register EPP */
+#define UDCCRQ __REG(0x40600440) /* Configuration register EPQ */
+#define UDCCRR __REG(0x40600444) /* Configuration register EPR */
+#define UDCCRS __REG(0x40600448) /* Configuration register EPS */
+#define UDCCRT __REG(0x4060044C) /* Configuration register EPT */
+#define UDCCRU __REG(0x40600450) /* Configuration register EPU */
+#define UDCCRV __REG(0x40600454) /* Configuration register EPV */
+#define UDCCRW __REG(0x40600458) /* Configuration register EPW */
+#define UDCCRX __REG(0x4060045C) /* Configuration register EPX */
+
+#define UDCCONR_CN (0x03 << 25) /* Configuration Number */
+#define UDCCONR_CN_S (25)
+#define UDCCONR_IN (0x07 << 22) /* Interface Number */
+#define UDCCONR_IN_S (22)
+#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */
+#define UDCCONR_AISN_S (19)
+#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */
+#define UDCCONR_EN_S (15)
+#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */
+#define UDCCONR_ET_S (13)
+#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */
+#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */
+#define UDCCONR_ET_NU (0x00 << 13) /* Not used */
+#define UDCCONR_ED (1 << 12) /* Endpoint Direction */
+#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */
+#define UDCCONR_MPS_S (2)
+#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */
+#define UDCCONR_EE (1 << 0) /* Endpoint Enable */
+
+
+#define UDC_INT_FIFOERROR (0x2)
+#define UDC_INT_PACKETCMP (0x1)
+
+#define UDC_FNR_MASK (0x7ff)
+
+#define UDCCSR_WR_MASK (UDCCSR_DME|UDCCSR_FST)
+#define UDC_BCR_MASK (0x3ff)
+
+#endif /* __PXA27X_UDC_REGS_H */
diff --git a/drivers/usb/usbdcore_pxa27x.c b/drivers/usb/usbdcore_pxa27x.c
new file mode 100644
index 0000000..db8708e
--- /dev/null
+++ b/drivers/usb/usbdcore_pxa27x.c
@@ -0,0 +1,714 @@
+/*
+ * PXA27x USB device driver for u-boot.
+ *
+ * Copyright (C) 2007 Rodolfo Giometti <giometti(a)linux.it>
+ * Copyright (C) 2007 Eurotech S.p.A. <info(a)eurotech.it>
+ * Copyright (C) 2008 Vivek Kutal <vivek.kutal(a)azingo.com>
+ *
+ * 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 <config.h>
+#include <asm/byteorder.h>
+#include <usbdcore.h>
+#include <usbdcore_ep0.h>
+#include <asm/arch/hardware.h>
+#include <usbdcore_pxa2xx.h>
+#include "pxa27x_udc_regs.h"
+
+#define UDC_MAX_ENDPOINTS 24 /* number of endpoints on this UDC */
+
+
+static struct urb *ep0_urb = NULL;
+static struct usb_device_instance *udc_device;
+static int ep0state = EP0_IDLE;
+
+#ifdef USBDDBG
+static void udc_dump_buffer(char *name, u8 *buf, int len)
+{
+ int i, p, flag = 1;
+
+ usbdbg("%s - buf %p, len %d", name, buf, len);
+ for (i = p = 0; i < len; i++, p++) {
+ if (p == 0) {
+ flag = 0;
+ usbdbg("\t");
+ }
+
+ usbdbg("%02x ", buf[i]);
+
+ if (p == 15) {
+ flag = 1;
+ usbdbg("\n");
+ p = -1;
+ }
+ }
+ if (!flag)
+ usbdbg("\n");
+}
+#else
+#define udc_dump_buffer(name, buf, len) /* void */
+#endif
+
+static inline void udc_ack_int_UDCCR(int mask)
+{
+ USIR1 = mask | USIR1;
+}
+
+/*
+ * If the endpoint has an active tx_urb, then the next packet of data
from the
+ * URB is written to the tx FIFO.
+ * The total amount of data in the urb is given by urb->actual_length.
+ * The maximum amount of data that can be sent in any one packet is
given by
+ * endpoint->tx_packetSize.
+ * The number of data bytes from this URB that have already been
transmitted
+ * is given by endpoint->sent.
+ * endpoint->last is updated by this routine with the number of data bytes
+ * transmitted in this packet.
+ */
+static int udc_write_urb(struct usb_endpoint_instance *endpoint)
+{
+ struct urb *urb = endpoint->tx_urb;
+ int ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
+
+ u32 *addr32 = (u32 *) &UDCDN(ep_num),
+ *data32 = (u32 *) urb->buffer;
+ u8 *addr8 = (u8 *) &UDCDN(ep_num),
+ *data8 = (u8 *) urb->buffer;
+ unsigned int i, n, w, b, is_short;
+ int timeout = 2000; /* 2ms */
+
+ if (!urb || !urb->actual_length)
+ return -1;
+
+ n = MIN(urb->actual_length - endpoint->sent, endpoint->tx_packetSize);
+ if (n <= 0)
+ return -1;
+
+ usbdbg("write urb on ep %d", ep_num);
+#if defined(USBDDBG) && defined(USBDPARANOIA)
+ usbdbg("urb: buf %p, buf_len %d, actual_len %d",
+ urb->buffer, urb->buffer_length, urb->actual_length);
+ usbdbg("endpoint: sent %d, tx_packetSize %d, last %d",
+ endpoint->sent, endpoint->tx_packetSize, endpoint->last);
+#endif
+
+ is_short = n != endpoint->tx_packetSize;
+ w = n / 4;
+ b = n % 4;
+ usbdbg("n %d%s w %d b %d", n, is_short ? "-s" : "", w, b);
+ udc_dump_buffer("urb write", data8 + endpoint->sent, n);
+ /* Prepare for data send */
+
+ if (ep_num)
+ UDCCSN(ep_num) = UDCCSR_PC;
+
+ for (i = 0; i < w; i++)
+ *addr32 = data32[endpoint->sent/4 + i];
+ for (i = 0; i < b; i++)
+ *addr8 = data8[endpoint->sent + w*4 + i];
+
+ /* Set "Packet Complete" if less data then tx_packetSize */
+ if (is_short)
+ UDCCSN(ep_num) = ep_num ? UDCCSR_SP : UDCCSR0_IPR;
+
+ /* Wait for data sent */
+ while (!(UDCCSN(ep_num) & (ep_num ? UDCCSR_PC : UDCCSR0_IPR))) {
+ if (ep_num) {
+ if (timeout-- == 0)
+ return -1;
+ else
+ udelay(1);
+ };
+ }
+ endpoint->last = n;
+
+ if(ep_num) {
+ usbd_tx_complete(endpoint);
+ } else {
+ endpoint->sent += n;
+ endpoint->last -= n;
+ }
+
+ if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
+ urb->actual_length = 0;
+ endpoint->sent = 0;
+ endpoint->last = 0;
+ }
+
+ if ((endpoint->sent >= urb->actual_length) && (!ep_num)) {
+ usbdbg("ep0 IN stage done");
+ if(is_short)
+ ep0state = EP0_IDLE;
+ else
+ ep0state = EP0_XFER_COMPLETE;
+ }
+
+ return 0;
+}
+
+static int udc_read_urb(struct usb_endpoint_instance *endpoint)
+{
+ struct urb *urb = endpoint->rcv_urb;
+ int ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
+ u32 *addr32 = (u32 *) &UDCDN(ep_num),
+ *data32 = (u32 *) urb->buffer;
+ unsigned int i, n, is_short ;
+
+ usbdbg("read urb on ep %d", ep_num);
+#if defined(USBDDBG) && defined(USBDPARANOIA)
+ usbdbg("urb: buf %p, buf_len %d, actual_len %d",
+ urb->buffer, urb->buffer_length, urb->actual_length);
+ usbdbg("endpoint: rcv_packetSize %d",
+ endpoint->rcv_packetSize);
+#endif
+
+ if (UDCCSN(ep_num) & UDCCSR_BNE)
+ n = UDCBCN(ep_num) & 0x3ff;
+ else /* zlp */
+ n = 0;
+ is_short = n != endpoint->rcv_packetSize;
+
+ usbdbg("n %d%s", n, is_short ? "-s" : "");
+ for (i = 0; i < n; i += 4)
+ data32[urb->actual_length/4 + i/4] = *addr32;
+
+ udc_dump_buffer("urb read", (u8 *) data32, urb->actual_length + n);
+
+ usbd_rcv_complete(endpoint, n, 0);
+
+ return 0;
+}
+
+static int udc_read_urb_ep0(void)
+{
+ u32 *addr32 = (u32 *) &UDCDN(0),
+ *data32 = (u32 *) ep0_urb->buffer;
+ u8 *addr8 = (u8 *) &UDCDN(0),
+ *data8 = (u8 *) ep0_urb->buffer;
+ unsigned int i, n, w, b;
+
+ n = UDCBCR0;
+ w = n / 4;
+ b = n % 4;
+
+ for (i = 0; i < w; i++) {
+ data32[ep0_urb->actual_length/4 + i] = *addr32;
+ ep0_urb->actual_length += 4;
+ }
+
+ for (i = 0; i < b; i++ ) {
+ data8[ep0_urb->actual_length + w*4 + i] = *addr8;
+ ep0_urb->actual_length++;
+ }
+
+ UDCCSR0 = UDCCSR0_OPC | UDCCSR0_IPR;
+ if(ep0_urb->actual_length == ep0_urb->device_request.wLength)
+ return 1;
+ return 0;
+}
+
+static void udc_handle_ep0(struct usb_endpoint_instance *endpoint)
+{
+ u32 udccsr0 = UDCCSR0;
+ u32 *data = (u32 *) &ep0_urb->device_request;
+ int i;
+
+ usbdbg("udccsr0 %x", udccsr0);
+
+ /* Clear stall status */
+ if (udccsr0 & UDCCSR0_SST) {
+ usberr("clear stall status");
+ UDCCSR0 = UDCCSR0_SST;
+ ep0state = EP0_IDLE;
+ }
+
+ /* previous request unfinished? non-error iff back-to-back ... */
+ if ((udccsr0 & UDCCSR0_SA) != 0 && ep0state != EP0_IDLE)
+ ep0state = EP0_IDLE;
+
+ switch (ep0state) {
+ case EP0_IDLE :
+
+ udccsr0 = UDCCSR0;
+ /* Start control request? */
+ if ((udccsr0 & (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE))
+ == (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE)) {
+
+ /* Read SETUP packet.
+ * SETUP packet size is 8 bytes (aka 2 words)
+ */
+ usbdbg("try reading SETUP packet");
+ for (i = 0; i < 2; i++) {
+ if ((UDCCSR0 & UDCCSR0_RNE) == 0) {
+ usberr("setup packet too short (%d)", i);
+ goto stall;
+ }
+ data[i] = UDCDR0;
+ }
+ UDCCSR0 |= (UDCCSR0_OPC | UDCCSR0_SA);
+ if ((UDCCSR0 & UDCCSR0_RNE) != 0) {
+ usberr("setup packet too long");
+ goto stall;
+ }
+
+ udc_dump_buffer("ep0 setup read", (u8 *) data, 8);
+
+ if(ep0_urb->device_request.wLength == 0) {
+
+ usbdbg("Zero Data control Packet\n");
+
+ if(ep0_recv_setup(ep0_urb)) {
+ usberr("Invalid Setup Packet\n");
+ udc_dump_buffer("ep0 setup read", (u8 *) data, 8);
+ goto stall;
+ }
+ UDCCSR0 = UDCCSR0_IPR;
+ ep0state = EP0_IDLE;
+ }
+ else {
+ /* Check direction */
+ if ((ep0_urb->device_request.bmRequestType
+ & USB_REQ_DIRECTION_MASK) == USB_REQ_HOST2DEVICE) {
+ ep0state = EP0_OUT_DATA;
+ ep0_urb->buffer = (u8 *)ep0_urb->buffer_data;
+ ep0_urb->buffer_length = sizeof(ep0_urb->buffer_data);
+ ep0_urb->actual_length = 0;
+ UDCCSR0 = UDCCSR0_IPR;
+ }
+ else {
+ /* The ep0_recv_setup function has already placed our
+ * response packet data in ep0_urb->buffer and the
+ * packet length in ep0_urb->actual_length.
+ */
+ if (ep0_recv_setup(ep0_urb)) {
+stall:
+ usberr("Invalid setup packet");
+ udc_dump_buffer("ep0 setup read", (u8 *) data, 8);
+ ep0state= EP0_IDLE;
+ UDCCSR0 = UDCCSR0_SA|UDCCSR0_OPC | UDCCSR0_FST
| UDCCS0_FTF;
+ return;
+ }
+
+ endpoint->tx_urb = ep0_urb;
+ endpoint->sent = 0;
+ usbdbg("EP0_IN_DATA");
+ ep0state = EP0_IN_DATA;
+ if(udc_write_urb(endpoint) < 0)
+ goto stall;
+
+ }
+ }
+ return;
+ }
+ else if ((udccsr0 & (UDCCSR0_OPC |UDCCSR0_SA))
+ == (UDCCSR0_OPC|UDCCSR0_SA)) {
+ usberr("Setup Active but no data. Stalling ....\n");
+ goto stall;
+ }
+ else {
+ usbdbg("random early IRQs");
+ /* Some random early IRQs:
+ * - we acked FST
+ * - IPR cleared
+ * - OPC got set, without SA (likely status stage)
+ */
+ UDCCSR0 = udccsr0 & (UDCCSR0_SA | UDCCSR0_OPC);
+
+ }
+ break;
+
+ case EP0_OUT_DATA :
+
+ if ((udccsr0 & UDCCSR0_OPC) && !(udccsr0 & UDCCSR0_SA)) {
+ if(udc_read_urb_ep0()) {
+read_complete:
+ ep0state = EP0_IDLE;
+ if (ep0_recv_setup(ep0_urb)) {
+ /* Not a setup packet, stall next EP0
transaction */
+ udc_dump_buffer("ep0 setup read", (u8 *) data, 8);
+ usberr("can't parse setup packet\n");
+ goto stall;
+ }
+ }
+ }
+ else if(!(udccsr0 & UDCCSR0_OPC) && !(udccsr0 & UDCCSR0_IPR)) {
+ if(ep0_urb->device_request.wLength ==
ep0_urb->actual_length)
+ goto read_complete;
+ usberr("Premature Status\n");
+ ep0state = EP0_IDLE;
+ }
+ break;
+
+ case EP0_IN_DATA :
+ /* GET_DESCRIPTOR etc */
+ if (udccsr0 & UDCCSR0_OPC) {
+ UDCCSR0 = UDCCSR0_OPC | UDCCSR0_FTF;
+ usberr("ep0in premature status");
+ ep0state = EP0_IDLE;
+ }
+ else {
+ /* irq was IPR clearing */
+ if(udc_write_urb(endpoint) < 0) {
+ usberr("ep0_write_error\n");
+ goto stall;
+ }
+ }
+ break;
+
+ case EP0_XFER_COMPLETE:
+ UDCCSR0 = UDCCSR0_IPR;
+ ep0state = EP0_IDLE;
+ break;
+
+ default:
+ usbdbg("Default\n");
+ }
+ USIR0 = USIR0_IR0;
+}
+
+static void udc_handle_ep(struct usb_endpoint_instance *endpoint)
+{
+ int ep_addr = endpoint->endpoint_address;
+ int ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+ int ep_isout = (ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
+
+ u32 flags = UDCCSN(ep_num) & (UDCCSR_SST | UDCCSR_TRN);
+ if (flags)
+ UDCCSN(ep_num) = flags;
+
+ if (ep_isout)
+ udc_read_urb(endpoint);
+ else
+ udc_write_urb(endpoint);
+
+ UDCCSN(ep_num) = UDCCSR_PC;
+}
+
+static void udc_state_changed(void)
+{
+ int config, interface, alternate;
+
+ UDCCR |= UDCCR_SMAC;
+
+ config = (UDCCR & UDCCR_ACN) >> UDCCR_ACN_S;
+ interface = (UDCCR & UDCCR_AIN) >> UDCCR_AIN_S;
+ alternate = (UDCCR & UDCCR_AAISN) >> UDCCR_AAISN_S;
+
+ usbdbg("New UDC settings are: conf %d - inter %d - alter %d",
+ config, interface, alternate);
+
+ usbd_device_event_irq (udc_device, DEVICE_CONFIGURED, 0);
+
+ UDCISR1 = UDCISR1_IRCC;
+}
+
+
+
+void udc_irq(void)
+{
+ int handled;
+ struct usb_endpoint_instance *endpoint;
+ int ep_num, i;
+ u32 udcisr0;
+
+ do {
+ handled = 0;
+ /* Suspend Interrupt Request */
+ if (USIR1 & UDCCR_SUSIR) {
+
+ usbdbg("Suspend\n");
+ udc_ack_int_UDCCR(UDCCR_SUSIR);
+ handled = 1;
+ ep0state = EP0_IDLE;
+ }
+
+ /* Resume Interrupt Request */
+ if (USIR1 & UDCCR_RESIR) {
+ udc_ack_int_UDCCR(UDCCR_RESIR);
+ handled = 1;
+ usbdbg( "USB resume\n");
+
+ }
+
+ if (USIR1 & (1<<31) ){
+ handled=1;
+ udc_state_changed();
+ }
+
+ /* Reset Interrupt Request */
+ if (USIR1 & UDCCR_RSTIR) {
+ udc_ack_int_UDCCR(UDCCR_RSTIR);
+ handled = 1;
+ usbdbg("Reset\n");
+ usbd_device_event_irq(udc_device, DEVICE_RESET, 0);
+ } else {
+ if(USIR0)
+ usbdbg("UISR0: %x \n",USIR0);
+
+ if (USIR0 & 0x2) USIR0 = 0x2;
+
+ /* Control traffic */
+ if (USIR0 & USIR0_IR0) {
+ handled = 1;
+ udc_handle_ep0(udc_device->bus->endpoint_array);
+ USIR0 = USIR0_IR0;
+ }
+
+ endpoint = udc_device->bus->endpoint_array;
+ for (i = 0; i < udc_device->bus->max_endpoints; i++) {
+ ep_num = (endpoint[i].endpoint_address) &
USB_ENDPOINT_NUMBER_MASK;
+ if (!ep_num)
+ continue;
+ udcisr0 = UDCISR0;
+ if (udcisr0 & UDCISR_INT(ep_num, UDC_INT_PACKETCMP)) {
+ UDCISR0 = UDCISR_INT(ep_num, UDC_INT_PACKETCMP);
+ udc_handle_ep(&endpoint[i]);
+
+ }
+ }
+
+ }
+
+ } while (handled);
+}
+
+/* The UDCCR reg contains mask and interrupt status bits,
+ * so using '|=' isn't safe as it may ack an interrupt.
+ */
+#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
+#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_UDE)
+
+static inline void udc_set_mask_UDCCR(int mask)
+{
+ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
+}
+
+static inline void udc_clear_mask_UDCCR(int mask)
+{
+ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
+}
+
+
+static void pio_irq_enable(int ep_num)
+{
+ if (ep_num < 16)
+ UDCICR0 |= 3 << (ep_num * 2);
+ else {
+ ep_num -= 16;
+ UDCICR1 |= 3 << (ep_num * 2);
+ }
+}
+
+/*
+ * udc_set_nak
+ *
+ * Allow upper layers to signal lower layers should not accept more RX data
+ */
+void udc_set_nak(int ep_num)
+{
+ /* TODO */
+}
+
+/*
+ * udc_unset_nak
+ *
+ * Suspend sending of NAK tokens for DATA OUT tokens on a given endpoint.
+ * Switch off NAKing on this endpoint to accept more data output from host.
+ */
+void udc_unset_nak(int ep_num)
+{
+ /* TODO */
+}
+
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint)
+{
+ return udc_write_urb(endpoint);
+}
+
+/* Associate a physical endpoint with endpoint instance */
+void udc_setup_ep(struct usb_device_instance *device, unsigned int id,
struct usb_endpoint_instance *endpoint)
+{
+ int ep_num, ep_addr, ep_isout, ep_type, ep_size;
+ int config, interface, alternate;
+ u32 tmp;
+
+ usbdbg("setting up endpoint id %d", id);
+
+ if (!endpoint) {
+ usberr("endpoint void!");
+ return;
+ }
+
+ ep_num = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK;
+ if (ep_num >= UDC_MAX_ENDPOINTS) {
+ usberr("unable to setup ep %d!",ep_num);
+ return;
+ }
+
+ pio_irq_enable(ep_num);
+ if (ep_num == 0) {
+ /* Done for ep0 */
+ return;
+ }
+
+ config = 1;
+ interface = 0;
+ alternate = 0;
+
+ usbdbg("config %d - interface %d - alternate %d",
+ config, interface, alternate);
+
+ ep_addr = endpoint->endpoint_address;
+ ep_num = ep_addr & USB_ENDPOINT_NUMBER_MASK;
+ ep_isout = (ep_addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT;
+ ep_type = ep_isout ? endpoint->rcv_attributes :
endpoint->tx_attributes;
+ ep_size = ep_isout ? endpoint->rcv_packetSize :
endpoint->tx_packetSize;
+
+ usbdbg("addr %x, num %d, dir %s, type %s, packet size %d",
+ ep_addr, ep_num,
+ ep_isout ? "out" : "in",
+ ep_type == USB_ENDPOINT_XFER_ISOC ? "isoc" :
+ ep_type == USB_ENDPOINT_XFER_BULK ? "bulk" :
+ ep_type == USB_ENDPOINT_XFER_INT ? "int" : "???",
+ ep_size
+ );
+
+ /* Configure UDCCRx */
+ tmp = 0;
+ tmp |= (config << UDCCONR_CN_S) & UDCCONR_CN;
+ tmp |= (interface << UDCCONR_IN_S) & UDCCONR_IN;
+ tmp |= (alternate << UDCCONR_AISN_S) & UDCCONR_AISN;
+ tmp |= (ep_num << UDCCONR_EN_S) & UDCCONR_EN;
+ tmp |= (ep_type << UDCCONR_ET_S) & UDCCONR_ET;
+ tmp |= ep_isout ? 0 : UDCCONR_ED;
+ tmp |= (ep_size << UDCCONR_MPS_S ) & UDCCONR_MPS;
+ tmp |= /* UDCCONR_DE | */ UDCCONR_EE;
+
+ UDCCN(ep_num) = tmp;
+
+ usbdbg("UDCCR%c = %x", 'A' + ep_num-1, UDCCN(ep_num));
+ usbdbg("UDCCSR%c = %x", 'A' + ep_num-1, UDCCSN(ep_num));
+}
+
+
+
+#define CONFIG_USB_DEV_PULLUP_GPIO 87
+
+/* Connect the USB device to the bus */
+void udc_connect(void)
+{
+ usbdbg("UDC connect");
+
+ /* Turn on the USB connection by enabling the pullup resistor */
+ set_GPIO_mode(CONFIG_USB_DEV_PULLUP_GPIO | GPIO_OUT);
+ GPSR(CONFIG_USB_DEV_PULLUP_GPIO) =
GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO);
+}
+
+/* Disconnect the USB device to the bus */
+void udc_disconnect(void)
+{
+ usbdbg("UDC disconnect");
+
+ /* Turn off the USB connection by disabling the pullup resistor */
+ GPCR(CONFIG_USB_DEV_PULLUP_GPIO) =
GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO);
+}
+
+/* Switch on the UDC */
+void udc_enable(struct usb_device_instance *device)
+{
+
+ ep0state = EP0_IDLE;
+ CKEN |= CKEN11_USB;
+
+ /* enable endpoint 0, A, B's Packet Complete Interrupt. */
+ UDCICR0 = 0x0000003f;
+ UDCICR1 = 0xa8000000;
+
+ /* clear the interrupt status/control registers */
+ UDCISR0 = 0xffffffff;
+ UDCISR1 = 0xffffffff;
+
+ /* set UDC-enable */
+ udc_set_mask_UDCCR( UDCCR_UDE);
+
+ udc_device = device;
+ if (!ep0_urb)
+ ep0_urb =
usbd_alloc_urb(udc_device,udc_device->bus->endpoint_array);
+ else
+ usbinfo("ep0_urb %p already allocated", ep0_urb);
+
+ usbdbg("UDC Enabled\n");
+}
+
+/* Need to check this again */
+void udc_disable(void)
+{
+ usbdbg("disable UDC");
+
+ udc_clear_mask_UDCCR(UDCCR_UDE);
+
+ /* Disable clock for USB device */
+ CKEN &= ~CKEN11_USB;
+
+ /* Free ep0 URB */
+ if (ep0_urb) {
+ usbd_dealloc_urb(ep0_urb);
+ ep0_urb = NULL;
+ }
+
+ /* Reset device pointer */
+ udc_device = NULL;
+}
+
+/* Allow udc code to do any additional startup */
+void udc_startup_events(struct usb_device_instance *device)
+{
+ /* The DEVICE_INIT event puts the USB device in the state STATE_INIT */
+ usbd_device_event_irq(device, DEVICE_INIT, 0);
+
+ /* The DEVICE_CREATE event puts the USB device in the state
+ * STATE_ATTACHED */
+ usbd_device_event_irq(device, DEVICE_CREATE, 0);
+
+ /* Some USB controller driver implementations signal
+ * DEVICE_HUB_CONFIGURED and DEVICE_RESET events here.
+ * DEVICE_HUB_CONFIGURED causes a transition to the state
STATE_POWERED,
+ * and DEVICE_RESET causes a transition to the state STATE_DEFAULT.
+ */
+ udc_enable(device);
+}
+
+/* Initialize h/w stuff */
+int udc_init(void)
+{
+ udc_device = NULL;
+ usbdbg("PXA27x usbd start");
+
+ /* Disable the UDC */
+ udc_clear_mask_UDCCR(UDCCR_UDE);
+
+ /* Disable clock for USB device */
+ CKEN &= ~CKEN11_USB;
+
+ /* Disable IRQs: we don't use them */
+ UDCICR0 = UDCICR1 = 0;
+
+ return 0;
+}
diff --git a/include/usbdcore_pxa2xx.h b/include/usbdcore_pxa2xx.h
new file mode 100644
index 0000000..3d04f18
--- /dev/null
+++ b/include/usbdcore_pxa2xx.h
@@ -0,0 +1,68 @@
+/*
+ * PXA27x register declarations and HCD data structures
+ *
+ * Copyright (C) 2007 Rodolfo Giometti <giometti(a)linux.it>
+ * Copyright (C) 2007 Eurotech S.p.A. <info(a)eurotech.it>
+ *
+ * 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 __USBDCORE_PXA270X_H__
+#define __USBDCORE_PXA270X_H__
+
+#include <asm/byteorder.h>
+
+/* Endpoint 0 states */
+#define EP0_IDLE 0
+#define EP0_IN_DATA 1
+#define EP0_OUT_DATA 2
+#define EP0_XFER_COMPLETE 3
+
+
+/* Endpoint parameters */
+#define MAX_ENDPOINTS 4
+#define EP_MAX_PACKET_SIZE 64
+
+#define EP0_MAX_PACKET_SIZE 16
+#define UDC_OUT_ENDPOINT 0x02
+#define UDC_OUT_PACKET_SIZE EP_MAX_PACKET_SIZE
+#define UDC_IN_ENDPOINT 0x03
+#define UDC_IN_PACKET_SIZE EP_MAX_PACKET_SIZE
+#define UDC_INT_ENDPOINT 0x01
+#define UDC_INT_PACKET_SIZE EP_MAX_PACKET_SIZE
+#define UDC_BULK_PACKET_SIZE EP_MAX_PACKET_SIZE
+
+void udc_irq (void);
+/* Flow control */
+void udc_set_nak(int epid);
+void udc_unset_nak (int epid);
+
+/* Higher level functions for abstracting away from specific device */
+int udc_endpoint_write(struct usb_endpoint_instance *endpoint);
+
+int udc_init (void);
+
+void udc_enable(struct usb_device_instance *device);
+void udc_disable(void);
+
+void udc_connect(void);
+void udc_disconnect(void);
+
+void udc_startup_events(struct usb_device_instance *device);
+void udc_setup_ep(struct usb_device_instance *device, unsigned int ep,
struct usb_endpoint_instance *endpoint);
+
+#endif
--
1.5.6.3
3
3