diff options
-rw-r--r-- | board/evb64260/zuma_pbb.c | 6 | ||||
-rw-r--r-- | board/evb64260/zuma_pbb_mbox.c | 4 | ||||
-rw-r--r-- | common/cmd_jffs2.c | 20 | ||||
-rw-r--r-- | cpu/i386/sc520.c | 2 | ||||
-rw-r--r-- | cpu/mpc8xx/cpu.c | 2 | ||||
-rw-r--r-- | cpu/mpc8xx/video.c | 2 | ||||
-rw-r--r-- | doc/README.NetConsole | 18 | ||||
-rw-r--r-- | drivers/pci/fsl_pci_init.c | 2 | ||||
-rw-r--r-- | drivers/serial/Makefile | 1 | ||||
-rw-r--r-- | drivers/serial/usbtty.c | 6 | ||||
-rw-r--r-- | drivers/serial/usbtty.h | 31 | ||||
-rwxr-xr-x | drivers/serial/vcth.c | 121 | ||||
-rw-r--r-- | drivers/usb/usbdcore_omap1510.c | 4 | ||||
-rw-r--r-- | examples/82559_eeprom.c | 1 | ||||
-rw-r--r-- | fs/fat/fat.c | 3 | ||||
-rw-r--r-- | fs/jffs2/jffs2_1pass.c | 520 | ||||
-rw-r--r-- | fs/jffs2/jffs2_private.h | 3 | ||||
-rw-r--r-- | fs/jffs2/summary.h | 163 | ||||
-rw-r--r-- | include/asm-i386/ic/pci.h | 49 | ||||
-rw-r--r-- | include/asm-i386/ic/sc520.h | 22 | ||||
-rw-r--r-- | include/jffs2/jffs2.h | 19 | ||||
-rw-r--r-- | include/jffs2/load_kernel.h | 1 | ||||
-rw-r--r-- | include/libfdt_env.h | 2 | ||||
-rw-r--r-- | include/usb.h | 2 | ||||
-rw-r--r-- | include/usbdcore_omap1510.h | 6 | ||||
-rwxr-xr-x | tools/netconsole | 42 |
26 files changed, 890 insertions, 162 deletions
diff --git a/board/evb64260/zuma_pbb.c b/board/evb64260/zuma_pbb.c index 296e461..1d03570 100644 --- a/board/evb64260/zuma_pbb.c +++ b/board/evb64260/zuma_pbb.c @@ -149,8 +149,10 @@ void zuma_init_pbb (void) pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &iobase); - zuma_pbb_reg = - (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + + zuma_pbb_reg = (PBB_DMA_REG_MAP *)iobase; + if (!zuma_pbb_reg) { printf ("zuma pbb bar none! (hah hah, get it?)\n"); diff --git a/board/evb64260/zuma_pbb_mbox.c b/board/evb64260/zuma_pbb_mbox.c index 6f5df6e..8e38102 100644 --- a/board/evb64260/zuma_pbb_mbox.c +++ b/board/evb64260/zuma_pbb_mbox.c @@ -165,7 +165,9 @@ int zuma_mbox_init(void) pci_read_config_dword(zuma_mbox_dev.dev, PCI_BASE_ADDRESS_0, &iobase); - zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *) (iobase & PCI_BASE_ADDRESS_MEM_MASK); + iobase &= PCI_BASE_ADDRESS_MEM_MASK; + + zuma_mbox_dev.sip = (PBB_DMA_REG_MAP *)iobase; zuma_mbox_dev.sip->int_mask.word=0; diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index c2caade..7866c80 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -339,11 +339,15 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) extern flash_info_t flash_info[]; flash_info_t *flash; int offset_aligned; - u32 end_offset; + u32 end_offset, sector_size = 0; int i; flash = &flash_info[id->num]; + /* size of last sector */ + part->sector_size = flash->size - + (flash->start[flash->sector_count-1] - flash->start[0]); + offset_aligned = 0; for (i = 0; i < flash->sector_count; i++) { if ((flash->start[i] - flash->start[0]) == part->offset) { @@ -358,12 +362,18 @@ static int part_validate_nor(struct mtdids *id, struct part_info *part) } end_offset = part->offset + part->size; + offset_aligned = 0; for (i = 0; i < flash->sector_count; i++) { + if (i) { + sector_size = flash->start[i] - flash->start[i-1]; + if (part->sector_size < sector_size) + part->sector_size = sector_size; + } if ((flash->start[i] - flash->start[0]) == end_offset) - return 0; + offset_aligned = 1; } - if (flash->size == end_offset) + if (offset_aligned || flash->size == end_offset) return 0; printf("%s%d: partition (%s) size alignment incorrect\n", @@ -389,6 +399,8 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part) nand = &nand_info[id->num]; + part->sector_size = nand->erasesize; + if ((unsigned long)(part->offset) % nand->erasesize) { printf("%s%d: partition (%s) start offset alignment incorrect\n", MTD_DEV_TYPE(id->type), id->num, part->name); @@ -424,6 +436,8 @@ static int part_validate_onenand(struct mtdids *id, struct part_info *part) mtd = &onenand_mtd; + part->sector_size = mtd->erasesize; + if ((unsigned long)(part->offset) % mtd->erasesize) { printf("%s%d: partition (%s) start offset" "alignment incorrect\n", diff --git a/cpu/i386/sc520.c b/cpu/i386/sc520.c index 8bcb979..cb6bc03 100644 --- a/cpu/i386/sc520.c +++ b/cpu/i386/sc520.c @@ -32,7 +32,7 @@ #include <config.h> #include <pci.h> #ifdef CONFIG_SC520_SSI -#include <ssi.h> +#include <asm/ic/ssi.h> #endif #include <asm/io.h> #include <asm/pci.h> diff --git a/cpu/mpc8xx/cpu.c b/cpu/mpc8xx/cpu.c index 40f81ef..2eb848b 100644 --- a/cpu/mpc8xx/cpu.c +++ b/cpu/mpc8xx/cpu.c @@ -644,7 +644,7 @@ void reset_8xx_watchdog (volatile immap_t * immr) */ int cpu_eth_init(bd_t *bis) { -#if defined(SCC_ENET) +#if defined(SCC_ENET) && defined(CONFIG_CMD_NET) scc_initialize(bis); #endif #if defined(FEC_ENET) diff --git a/cpu/mpc8xx/video.c b/cpu/mpc8xx/video.c index 5479644..4a59927 100644 --- a/cpu/mpc8xx/video.c +++ b/cpu/mpc8xx/video.c @@ -32,10 +32,8 @@ #include <stdarg.h> #include <common.h> #include <config.h> -#ifdef VIDEO_INFO #include <version.h> #include <timestamp.h> -#endif #include <i2c.h> #include <linux/types.h> #include <devices.h> diff --git a/doc/README.NetConsole b/doc/README.NetConsole index fea8e33..94c8816 100644 --- a/doc/README.NetConsole +++ b/doc/README.NetConsole @@ -22,21 +22,11 @@ For example, if your server IP is 192.168.1.1, you could use: On the host side, please use this script to access the console: -+++++++++++++++++++++++++++++++++++++++++++ -#! /bin/bash - -[ $# = 1 ] || { echo "Usage: $0 target_ip" >&2 ; exit 1 ; } -TARGET_IP=$1 + tools/netconsole <ip> [port] -stty -icanon -echo intr ^T -nc -u -l -p 6666 < /dev/null & -nc -u ${TARGET_IP} 6666 -stty icanon echo intr ^C -+++++++++++++++++++++++++++++++++++++++++++ - -The script expects exactly one argument, which is interpreted as the -target IP address (or host name, assuming DNS is working). The script -can be interrupted by pressing ^T (CTRL-T). +The script uses netcat to talk to the board over UDP. It requires you to +specify the target IP address (or host name, assuming DNS is working). The +script can be interrupted by pressing ^T (CTRL-T). Be aware that in some distributives (Fedora Core 5 at least) usage of nc has been changed and -l and -p options are considered diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index e57acba..1db42fd 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -119,9 +119,11 @@ int fsl_pci_setup_inbound_windows(struct pci_region *r) } #endif +#ifdef CONFIG_PHYS_64BIT if (sz && (((u64)gd->ram_size) < (1ull << 32))) printf("Was not able to map all of memory via " "inbound windows -- %lld remaining\n", sz); +#endif return r - rgn_base; } diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index eafe543..17235ff 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -38,6 +38,7 @@ COBJS-$(CONFIG_PL011_SERIAL) += serial_pl01x.o COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o COBJS-$(CONFIG_USB_TTY) += usbtty.o +COBJS-$(CONFIG_VCTH_SERIAL) += vcth.o COBJS := $(sort $(COBJS-y)) SRCS := $(COBJS:.o=.c) diff --git a/drivers/serial/usbtty.c b/drivers/serial/usbtty.c index e738c56..7eba470 100644 --- a/drivers/serial/usbtty.c +++ b/drivers/serial/usbtty.c @@ -22,16 +22,14 @@ */ #include <common.h> - +#include <config.h> #include <circbuf.h> #include <devices.h> #include "usbtty.h" #include "usb_cdc_acm.h" #include "usbdescriptors.h" -#include <config.h> /* If defined, override Linux identifiers with - * vendor specific ones */ -#if 0 +#ifdef DEBUG #define TTYDBG(fmt,args...)\ serial_printf("[%s] %s %d: "fmt, __FILE__,__FUNCTION__,__LINE__,##args) #else diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index 71c47bc..ecefde5 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -24,11 +24,11 @@ #ifndef __USB_TTY_H__ #define __USB_TTY_H__ -#include "usbdcore.h" +#include <usbdcore.h> #if defined(CONFIG_PPC) -#include "usbdcore_mpc8xx.h" +#include <usbdcore_mpc8xx.h> #elif defined(CONFIG_ARM) -#include "usbdcore_omap1510.h" +#include <usbdcore_omap1510.h> #endif #include <version_autogenerated.h> @@ -36,14 +36,25 @@ /* If no VendorID/ProductID is defined in config.h, pretend to be Linux * DO NOT Reuse this Vendor/Product setup with protocol incompatible devices */ -#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ -#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ -#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ -#define CONFIG_USBD_MANUFACTURER "Das U-Boot" -#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION - +#ifndef CONFIG_USBD_VENDORID +#define CONFIG_USBD_VENDORID 0x0525 /* Linux/NetChip */ +#endif +#ifndef CONFIG_USBD_PRODUCTID_GSERIAL +#define CONFIG_USBD_PRODUCTID_GSERIAL 0xa4a6 /* gserial */ +#endif +#ifndef CONFIG_USBD_PRODUCTID_CDCACM +#define CONFIG_USBD_PRODUCTID_CDCACM 0xa4a7 /* CDC ACM */ +#endif +#ifndef CONFIG_USBD_MANUFACTURER +#define CONFIG_USBD_MANUFACTURER "Das U-Boot" +#endif +#ifndef CONFIG_USBD_PRODUCT_NAME +#define CONFIG_USBD_PRODUCT_NAME U_BOOT_VERSION +#endif -#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" +#ifndef CONFIG_USBD_CONFIGURATION_STR +#define CONFIG_USBD_CONFIGURATION_STR "TTY via USB" +#endif #define CONFIG_USBD_SERIAL_OUT_ENDPOINT UDC_OUT_ENDPOINT #define CONFIG_USBD_SERIAL_OUT_PKTSIZE UDC_OUT_PACKET_SIZE diff --git a/drivers/serial/vcth.c b/drivers/serial/vcth.c new file mode 100755 index 0000000..2c847d0 --- /dev/null +++ b/drivers/serial/vcth.c @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2008 Stefan Roese <sr@denx.de>, DENX Software Engineering + * + * 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 <config.h> +#include <common.h> +#include <asm/io.h> + +#define UART_1_BASE 0xBF89C000 + +#define UART_RBR_OFF 0x00 /* receiver buffer reg */ +#define UART_THR_OFF 0x00 /* transmit holding reg */ +#define UART_DLL_OFF 0x00 /* divisor latch low reg */ +#define UART_IER_OFF 0x04 /* interrupt enable reg */ +#define UART_DLH_OFF 0x04 /* receiver buffer reg */ +#define UART_FCR_OFF 0x08 /* fifo control register */ +#define UART_LCR_OFF 0x0c /* line control register */ +#define UART_MCR_OFF 0x10 /* modem control register */ +#define UART_LSR_OFF 0x14 /* line status register */ +#define UART_MSR_OFF 0x18 /* modem status register */ +#define UART_SCR_OFF 0x1c /* scratch pad register */ + +#define UART_RCV_DATA_RDY 0x01 /* Data Received */ +#define UART_XMT_HOLD_EMPTY 0x20 +#define UART_TRANSMIT_EMPTY 0x40 + +/* 7 bit on line control reg. enalbing rw to dll and dlh */ +#define UART_LCR_DLAB 0x0080 + +#define UART___9600_BDR 0x84 +#define UART__19200_BDR 0x42 +#define UART_115200_BDR 0x08 + +#define UART_DIS_ALL_INTER 0x00 /* disable all interrupts */ + +#define UART_5DATA_BITS 0x0000 /* 5 [bits] 1.5 bits 2 */ +#define UART_6DATA_BITS 0x0001 /* 6 [bits] 1 bits 2 */ +#define UART_7DATA_BITS 0x0002 /* 7 [bits] 1 bits 2 */ +#define UART_8DATA_BITS 0x0003 /* 8 [bits] 1 bits 2 */ + +static void vcth_uart_set_baud_rate(u32 address, u32 dh, u32 dl) +{ + u32 val = __raw_readl(UART_1_BASE + UART_LCR_OFF); + + /* set 7 bit on 1 */ + val |= UART_LCR_DLAB; + __raw_writel(val, UART_1_BASE + UART_LCR_OFF); + + __raw_writel(dl, UART_1_BASE + UART_DLL_OFF); + __raw_writel(dh, UART_1_BASE + UART_DLH_OFF); + + /* set 7 bit on 0 */ + val &= ~UART_LCR_DLAB; + __raw_writel(val, UART_1_BASE + UART_LCR_OFF); + + return; +} + +int serial_init(void) +{ + __raw_writel(UART_DIS_ALL_INTER, UART_1_BASE + UART_IER_OFF); + vcth_uart_set_baud_rate(UART_1_BASE, 0, UART_115200_BDR); + __raw_writel(UART_8DATA_BITS, UART_1_BASE + UART_LCR_OFF); + + return 0; +} + +void serial_setbrg(void) +{ + /* + * Baudrate change not supported currently, fixed to 115200 baud + */ +} + +void serial_putc(const char c) +{ + if (c == '\n') + serial_putc('\r'); + + while (!(UART_XMT_HOLD_EMPTY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + ; + + __raw_writel(c, UART_1_BASE + UART_THR_OFF); +} + +void serial_puts(const char *s) +{ + while (*s) + serial_putc(*s++); +} + +int serial_getc(void) +{ + while (!(UART_RCV_DATA_RDY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + ; + + return __raw_readl(UART_1_BASE + UART_RBR_OFF) & 0xff; +} + +int serial_tstc(void) +{ + if (!(UART_RCV_DATA_RDY & __raw_readl(UART_1_BASE + UART_LSR_OFF))) + return 0; + + return 1; +} diff --git a/drivers/usb/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c index cb9dc44..6b7b61b 100644 --- a/drivers/usb/usbdcore_omap1510.c +++ b/drivers/usb/usbdcore_omap1510.c @@ -1061,7 +1061,7 @@ void omap1510_udc_noniso_irq (void) */ /* Called to start packet transmission. */ -void udc_endpoint_write (struct usb_endpoint_instance *endpoint) +int udc_endpoint_write (struct usb_endpoint_instance *endpoint) { unsigned short epnum = endpoint->endpoint_address & USB_ENDPOINT_NUMBER_MASK; @@ -1078,6 +1078,8 @@ void udc_endpoint_write (struct usb_endpoint_instance *endpoint) /* deselect the endpoint FIFO */ outw (UDC_EP_Dir | epnum, UDC_EP_NUM); } + + return 0; } /* Start to initialize h/w stuff */ diff --git a/examples/82559_eeprom.c b/examples/82559_eeprom.c index d99af26..5e2eee9 100644 --- a/examples/82559_eeprom.c +++ b/examples/82559_eeprom.c @@ -19,7 +19,6 @@ */ #define _PPC_STRING_H_ /* avoid unnecessary str/mem functions */ -#define _LINUX_STRING_H_ /* avoid unnecessary str/mem functions */ #include <common.h> #include <exports.h> diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 06eabc3..a9dde7d 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -84,6 +84,7 @@ fat_register_device(block_dev_desc_t *dev_desc, int part_no) return -1; } #if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ @@ -980,12 +981,14 @@ file_fat_detectfs(void) return 1; } #if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) printf("Interface: "); switch(cur_dev->if_type) { case IF_TYPE_IDE : printf("IDE"); break; + case IF_TYPE_SATA : printf("SATA"); break; case IF_TYPE_SCSI : printf("SCSI"); break; case IF_TYPE_ATAPI : printf("ATAPI"); break; case IF_TYPE_USB : printf("USB"); break; diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 920d2fd..be7c1a1 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -138,6 +138,8 @@ # define DEBUGF(fmt,args...) #endif +#include "summary.h" + /* keeps pointer to currentlu processed partition */ static struct part_info *current_part; @@ -245,7 +247,7 @@ static void *get_fl_mem_nand(u32 off, u32 size, void *ext_buf) return buf; } -static void *get_node_mem_nand(u32 off) +static void *get_node_mem_nand(u32 off, void *ext_buf) { struct jffs2_unknown_node node; void *ret = NULL; @@ -255,7 +257,7 @@ static void *get_node_mem_nand(u32 off) if (!(ret = get_fl_mem_nand(off, node.magic == JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), - NULL))) { + ext_buf))) { printf("off = %#x magic %#x type %#x node.totlen = %d\n", off, node.magic, node.nodetype, node.totlen); } @@ -344,7 +346,7 @@ static void *get_fl_mem_onenand(u32 off, u32 size, void *ext_buf) return buf; } -static void *get_node_mem_onenand(u32 off) +static void *get_node_mem_onenand(u32 off, void *ext_buf) { struct jffs2_unknown_node node; void *ret = NULL; @@ -354,7 +356,7 @@ static void *get_node_mem_onenand(u32 off) ret = get_fl_mem_onenand(off, node.magic == JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node), - NULL); + ext_buf); if (!ret) { printf("off = %#x magic %#x type %#x node.totlen = %d\n", off, node.magic, node.nodetype, node.totlen); @@ -377,7 +379,7 @@ static void put_fl_mem_onenand(void *buf) * NOR flash memory is mapped in processor's address space, * just return address. */ -static inline void *get_fl_mem_nor(u32 off) +static inline void *get_fl_mem_nor(u32 off, u32 size, void *ext_buf) { u32 addr = off; struct mtdids *id = current_part->dev->id; @@ -386,12 +388,22 @@ static inline void *get_fl_mem_nor(u32 off) flash_info_t *flash = &flash_info[id->num]; addr += flash->start[0]; + if (ext_buf) { + memcpy(ext_buf, (void *)addr, size); + return ext_buf; + } return (void*)addr; } -static inline void *get_node_mem_nor(u32 off) +static inline void *get_node_mem_nor(u32 off, void *ext_buf) { - return (void*)get_fl_mem_nor(off); + struct jffs2_unknown_node *pNode; + + /* pNode will point directly to flash - don't provide external buffer + and don't care about size */ + pNode = get_fl_mem_nor(off, 0, NULL); + return (void *)get_fl_mem_nor(off, pNode->magic == JFFS2_MAGIC_BITMASK ? + pNode->totlen : sizeof(*pNode), ext_buf); } #endif @@ -405,8 +417,9 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) struct mtdids *id = current_part->dev->id; #if defined(CONFIG_CMD_FLASH) - if (id->type == MTD_DEV_TYPE_NOR) - return get_fl_mem_nor(off); + if (id->type == MTD_DEV_TYPE_NOR) { + return get_fl_mem_nor(off, size, ext_buf); + } #endif #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) @@ -423,34 +436,38 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf) return (void*)off; } -static inline void *get_node_mem(u32 off) +static inline void *get_node_mem(u32 off, void *ext_buf) { struct mtdids *id = current_part->dev->id; #if defined(CONFIG_CMD_FLASH) if (id->type == MTD_DEV_TYPE_NOR) - return get_node_mem_nor(off); + return get_node_mem_nor(off, ext_buf); #endif #if defined(CONFIG_JFFS2_NAND) && \ defined(CONFIG_CMD_NAND) if (id->type == MTD_DEV_TYPE_NAND) - return get_node_mem_nand(off); + return get_node_mem_nand(off, ext_buf); #endif #if defined(CONFIG_CMD_ONENAND) if (id->type == MTD_DEV_TYPE_ONENAND) - return get_node_mem_onenand(off); + return get_node_mem_onenand(off, ext_buf); #endif printf("get_node_mem: unknown device type, using raw offset!\n"); return (void*)off; } -static inline void put_fl_mem(void *buf) +static inline void put_fl_mem(void *buf, void *ext_buf) { struct mtdids *id = current_part->dev->id; + /* If buf is the same as ext_buf, it was provided by the caller - + we shouldn't free it then. */ + if (buf == ext_buf) + return; switch (id->type) { #if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND) case MTD_DEV_TYPE_NAND: @@ -478,9 +495,6 @@ static char *compr_names[] = { #endif }; -/* Spinning wheel */ -static char spinner[] = { '|', '/', '-', '\\' }; - /* Memory management */ struct mem_block { u32 index; @@ -651,23 +665,6 @@ static int compare_dirents(struct b_node *new, struct b_node *old) } #endif -static u32 -jffs2_scan_empty(u32 start_offset, struct part_info *part) -{ - char *max = (char *)(part->offset + part->size - sizeof(struct jffs2_raw_inode)); - char *offset = (char *)(part->offset + start_offset); - u32 off; - - while (offset < max && - *(u32*)get_fl_mem((u32)offset, sizeof(u32), &off) == 0xFFFFFFFF) { - offset += sizeof(u32); - /* return if spinning is due */ - if (((u32)offset & ((1 << SPIN_BLKSIZE)-1)) == 0) break; - } - - return (u32)offset - part->offset; -} - void jffs2_free_cache(struct part_info *part) { @@ -677,6 +674,7 @@ jffs2_free_cache(struct part_info *part) pL = (struct b_lists *)part->jffs2_priv; free_nodes(&pL->frag); free_nodes(&pL->dir); + free(pL->readbuf); free(pL); } } @@ -723,7 +721,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) */ for (b = pL->frag.listHead; b != NULL; b = b->next) { jNode = (struct jffs2_raw_inode *) get_fl_mem(b->offset, - sizeof(struct jffs2_raw_inode), NULL); + sizeof(struct jffs2_raw_inode), pL->readbuf); if ((inode == jNode->ino)) { /* get actual file length from the newest node */ if (jNode->version >= latestVersion) { @@ -731,12 +729,13 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) latestVersion = jNode->version; } } - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } #endif for (b = pL->frag.listHead; b != NULL; b = b->next) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset); + jNode = (struct jffs2_raw_inode *) get_node_mem(b->offset, + pL->readbuf); if ((inode == jNode->ino)) { #if 0 putLabeledWord("\r\n\r\nread_inode: totlen = ", jNode->totlen); @@ -763,7 +762,14 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) src = ((uchar *) jNode) + sizeof(struct jffs2_raw_inode); /* ignore data behind latest known EOF */ if (jNode->offset > totalSize) { - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); + continue; + } + if (b->datacrc == CRC_UNKNOWN) + b->datacrc = data_crc(jNode) ? + CRC_OK : CRC_BAD; + if (b->datacrc == CRC_BAD) { + put_fl_mem(jNode, pL->readbuf); continue; } @@ -804,7 +810,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) default: /* unknown */ putLabeledWord("UNKOWN COMPRESSION METHOD = ", jNode->compr); - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); return -1; break; } @@ -816,7 +822,7 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest) #endif } counter++; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } #if 0 @@ -842,12 +848,13 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) counter = 0; /* we need to search all and return the inode with the highest version */ for(b = pL->dir.listHead; b; b = b->next, counter++) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if ((pino == jDir->pino) && (len == jDir->nsize) && (jDir->ino) && /* 0 for unlink */ (!strncmp((char *)jDir->name, name, len))) { /* a match */ if (jDir->version < version) { - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); continue; } @@ -869,7 +876,7 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino) putLabeledWord("b = ", (u32) b); putLabeledWord("counter = ", counter); #endif - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } return inode; } @@ -940,9 +947,7 @@ static inline u32 dump_inode(struct b_lists * pL, struct jffs2_raw_dirent *d, st st.st_mtime = i->mtime; st.st_mode = i->mode; st.st_ino = i->ino; - - /* neither dsize nor isize help us.. do it the long way */ - st.st_size = jffs2_1pass_read_inode(pL, i->ino, NULL); + st.st_size = i->isize; dump_stat(&st, fname); @@ -965,7 +970,8 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) struct jffs2_raw_dirent *jDir; for (b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if ((pino == jDir->pino) && (jDir->ino)) { /* ino=0 -> unlink */ u32 i_version = 0; struct jffs2_raw_inode ojNode; @@ -976,21 +982,25 @@ jffs2_1pass_list_inodes(struct b_lists * pL, u32 pino) jNode = (struct jffs2_raw_inode *) get_fl_mem(b2->offset, sizeof(ojNode), &ojNode); if (jNode->ino == jDir->ino && jNode->version >= i_version) { + i_version = jNode->version; if (i) - put_fl_mem(i); + put_fl_mem(i, NULL); if (jDir->type == DT_LNK) - i = get_node_mem(b2->offset); + i = get_node_mem(b2->offset, + NULL); else - i = get_fl_mem(b2->offset, sizeof(*i), NULL); + i = get_fl_mem(b2->offset, + sizeof(*i), + NULL); } b2 = b2->next; } dump_inode(pL, jDir, i); - put_fl_mem(i); + put_fl_mem(i, NULL); } - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } return pino; } @@ -1068,10 +1078,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) /* we need to search all and return the inode with the highest version */ for(b = pL->dir.listHead; b; b = b->next) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); if (ino == jDir->ino) { if (jDir->version < version) { - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); continue; } @@ -1088,7 +1099,7 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) jDirFoundPino = jDir->pino; version = jDir->version; } - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } /* now we found the right entry again. (shoulda returned inode*) */ if (jDirFoundType != DT_LNK) @@ -1097,7 +1108,8 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) /* it's a soft link so we follow it again. */ b2 = pL->frag.listHead; while (b2) { - jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset); + jNode = (struct jffs2_raw_inode *) get_node_mem(b2->offset, + pL->readbuf); if (jNode->ino == jDirFoundIno) { src = (unsigned char *)jNode + sizeof(struct jffs2_raw_inode); @@ -1109,11 +1121,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino) #endif strncpy(tmp, (char *)src, jNode->dsize); tmp[jNode->dsize] = '\0'; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); break; } b2 = b2->next; - put_fl_mem(jNode); + put_fl_mem(jNode, pL->readbuf); } /* ok so the name of the new file to find is in tmp */ /* if it starts with a slash it is root based else shared dirs */ @@ -1207,6 +1219,132 @@ jffs2_1pass_rescan_needed(struct part_info *part) return 0; } +#define dbg_summary(...) do {} while (0); +/* Process the stored summary information - helper function for + * jffs2_sum_scan_sumnode() + */ + +static int jffs2_sum_process_sum_data(struct part_info *part, uint32_t offset, + struct jffs2_raw_summary *summary, + struct b_lists *pL) +{ + void *sp; + int i; + + sp = summary->sum; + + for (i = 0; i < summary->sum_num; i++) { + dbg_summary("processing summary index %d\n", i); + + switch (((struct jffs2_sum_unknown_flash *)sp)->nodetype) { + case JFFS2_NODETYPE_INODE: { + struct jffs2_sum_inode_flash *spi; + spi = sp; + + dbg_summary("Inode at 0x%08x-0x%08x\n", + offset + spi->offset, + offset + spi->offset + spi->totlen); + + if (insert_node(&pL->frag, (u32) part->offset + + offset + spi->offset) == NULL) + return -1; + + sp += JFFS2_SUMMARY_INODE_SIZE; + + break; + } + + case JFFS2_NODETYPE_DIRENT: { + struct jffs2_sum_dirent_flash *spd; + spd = sp; + + dbg_summary("Dirent at 0x%08x-0x%08x\n", + offset + spd->offset, + offset + spd->offset + spd->totlen); + + if (insert_node(&pL->dir, (u32) part->offset + + offset + spd->offset) == NULL) + return -1; + + sp += JFFS2_SUMMARY_DIRENT_SIZE(spd->nsize); + + break; + } + default : { + uint16_t nodetype = + ((struct jffs2_sum_unknown_flash *) + sp)->nodetype; + printf("Unsupported node type %x found in " + "summary!\n", nodetype); + break; + } + } + } + return 0; +} + +/* Process the summary node - called from jffs2_scan_eraseblock() */ +int jffs2_sum_scan_sumnode(struct part_info *part, uint32_t offset, + struct jffs2_raw_summary *summary, uint32_t sumsize, + struct b_lists *pL) +{ + struct jffs2_unknown_node crcnode; + int ret, ofs; + uint32_t crc; + + ofs = part->sector_size - sumsize; + + dbg_summary("summary found for 0x%08x at 0x%08x (0x%x bytes)\n", + offset, offset + ofs, sumsize); + + /* OK, now check for node validity and CRC */ + crcnode.magic = JFFS2_MAGIC_BITMASK; + crcnode.nodetype = JFFS2_NODETYPE_SUMMARY; + crcnode.totlen = summary->totlen; + crc = crc32_no_comp(0, (uchar *)&crcnode, sizeof(crcnode)-4); + + if (summary->hdr_crc != crc) { + dbg_summary("Summary node header is corrupt (bad CRC or " + "no summary at all)\n"); + goto crc_err; + } + + if (summary->totlen != sumsize) { + dbg_summary("Summary node is corrupt (wrong erasesize?)\n"); + goto crc_err; + } + + crc = crc32_no_comp(0, (uchar *)summary, + sizeof(struct jffs2_raw_summary)-8); + + if (summary->node_crc != crc) { + dbg_summary("Summary node is corrupt (bad CRC)\n"); + goto crc_err; + } + + crc = crc32_no_comp(0, (uchar *)summary->sum, + sumsize - sizeof(struct jffs2_raw_summary)); + + if (summary->sum_crc != crc) { + dbg_summary("Summary node data is corrupt (bad CRC)\n"); + goto crc_err; + } + + if (summary->cln_mkr) + dbg_summary("Summary : CLEANMARKER node \n"); + + ret = jffs2_sum_process_sum_data(part, offset, summary, pL); + if (ret) + return ret; /* real error */ + + return 1; + +crc_err: + putstr("Summary node crc error, skipping summary information.\n"); + + return 0; +} + #ifdef DEBUG_FRAGMENTS static void dump_fragments(struct b_lists *pL) @@ -1248,7 +1386,8 @@ dump_dirents(struct b_lists *pL) putstr("\r\n\r\n******The directory Entries******\r\n"); b = pL->dir.listHead; while (b) { - jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset); + jDir = (struct jffs2_raw_dirent *) get_node_mem(b->offset, + pL->readbuf); putstr("\r\n"); putnstr(jDir->name, jDir->nsize); putLabeledWord("\r\n\tbuild_list: magic = ", jDir->magic); @@ -1264,22 +1403,39 @@ dump_dirents(struct b_lists *pL) putLabeledWord("\tbuild_list: name_crc = ", jDir->name_crc); putLabeledWord("\tbuild_list: offset = ", b->offset); /* FIXME: ? [RS] */ b = b->next; - put_fl_mem(jDir); + put_fl_mem(jDir, pL->readbuf); } } #endif +#define min_t(type, x, y) ({ \ + type __min1 = (x); \ + type __min2 = (y); \ + __min1 < __min2 ? __min1: __min2; }) + +#define DEFAULT_EMPTY_SCAN_SIZE 4096 + +static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) +{ + if (sector_size < DEFAULT_EMPTY_SCAN_SIZE) + return sector_size; + else + return DEFAULT_EMPTY_SCAN_SIZE; +} + static u32 jffs2_1pass_build_lists(struct part_info * part) { struct b_lists *pL; struct jffs2_unknown_node *node; - u32 offset, oldoffset = 0; - u32 max = part->size - sizeof(struct jffs2_raw_inode); - u32 counter = 0; + u32 nr_sectors = part->size/part->sector_size; + u32 i; u32 counter4 = 0; u32 counterF = 0; u32 counterN = 0; + u32 max_totlen = 0; + u32 buf_size = DEFAULT_EMPTY_SCAN_SIZE; + char *buf; /* turn off the lcd. Refreshing the lcd adds 50% overhead to the */ /* jffs2 list building enterprise nope. in newer versions the overhead is */ @@ -1289,71 +1445,245 @@ jffs2_1pass_build_lists(struct part_info * part) /* if we are building a list we need to refresh the cache. */ jffs_init_1pass_list(part); pL = (struct b_lists *)part->jffs2_priv; - offset = 0; + buf = malloc(buf_size); puts ("Scanning JFFS2 FS: "); /* start at the beginning of the partition */ - while (offset < max) { - if ((oldoffset >> SPIN_BLKSIZE) != (offset >> SPIN_BLKSIZE)) { - printf("\b\b%c ", spinner[counter++ % sizeof(spinner)]); - oldoffset = offset; - } + for (i = 0; i < nr_sectors; i++) { + uint32_t sector_ofs = i * part->sector_size; + uint32_t buf_ofs = sector_ofs; + uint32_t buf_len; + uint32_t ofs, prevofs; + struct jffs2_sum_marker *sm; + void *sumptr = NULL; + uint32_t sumlen; + int ret; WATCHDOG_RESET(); - node = (struct jffs2_unknown_node *) get_node_mem((u32)part->offset + offset); - if (node->magic == JFFS2_MAGIC_BITMASK && hdr_crc(node)) { + buf_len = sizeof(*sm); + + /* Read as much as we want into the _end_ of the preallocated + * buffer + */ + get_fl_mem(part->offset + sector_ofs + part->sector_size - + buf_len, buf_len, buf + buf_size - buf_len); + + sm = (void *)buf + buf_size - sizeof(*sm); + if (sm->magic == JFFS2_SUM_MAGIC) { + sumlen = part->sector_size - sm->offset; + sumptr = buf + buf_size - sumlen; + + /* Now, make sure the summary itself is available */ + if (sumlen > buf_size) { + /* Need to kmalloc for this. */ + sumptr = malloc(sumlen); + if (!sumptr) { + putstr("Can't get memory for summary " + "node!\n"); + return 0; + } + memcpy(sumptr + sumlen - buf_len, buf + + buf_size - buf_len, buf_len); + } + if (buf_len < sumlen) { + /* Need to read more so that the entire summary + * node is present + */ + get_fl_mem(part->offset + sector_ofs + + part->sector_size - sumlen, + sumlen - buf_len, sumptr); + } + } + + if (sumptr) { + ret = jffs2_sum_scan_sumnode(part, sector_ofs, sumptr, + sumlen, pL); + + if (buf_size && sumlen > buf_size) + free(sumptr); + if (ret < 0) + return 0; + if (ret) + continue; + + } + + buf_len = EMPTY_SCAN_SIZE(part->sector_size); + + get_fl_mem((u32)part->offset + buf_ofs, buf_len, buf); + + /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ + ofs = 0; + + /* Scan only 4KiB of 0xFF before declaring it's empty */ + while (ofs < EMPTY_SCAN_SIZE(part->sector_size) && + *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) + ofs += 4; + + if (ofs == EMPTY_SCAN_SIZE(part->sector_size)) + continue; + + ofs += sector_ofs; + prevofs = ofs - 1; + + scan_more: + while (ofs < sector_ofs + part->sector_size) { + if (ofs == prevofs) { + printf("offset %08x already seen, skip\n", ofs); + ofs += 4; + counter4++; + continue; + } + prevofs = ofs; + if (sector_ofs + part->sector_size < + ofs + sizeof(*node)) + break; + if (buf_ofs + buf_len < ofs + sizeof(*node)) { + buf_len = min_t(uint32_t, buf_size, sector_ofs + + part->sector_size - ofs); + get_fl_mem((u32)part->offset + ofs, buf_len, + buf); + buf_ofs = ofs; + } + + node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; + + if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { + uint32_t inbuf_ofs; + uint32_t empty_start, scan_end; + + empty_start = ofs; + ofs += 4; + scan_end = min_t(uint32_t, EMPTY_SCAN_SIZE( + part->sector_size)/8, + buf_len); + more_empty: + inbuf_ofs = ofs - buf_ofs; + while (inbuf_ofs < scan_end) { + if (*(uint32_t *)(&buf[inbuf_ofs]) != + 0xffffffff) + goto scan_more; + + inbuf_ofs += 4; + ofs += 4; + } + /* Ran off end. */ + + /* See how much more there is to read in this + * eraseblock... + */ + buf_len = min_t(uint32_t, buf_size, + sector_ofs + + part->sector_size - ofs); + if (!buf_len) { + /* No more to read. Break out of main + * loop without marking this range of + * empty space as dirty (because it's + * not) + */ + break; + } + scan_end = buf_len; + get_fl_mem((u32)part->offset + ofs, buf_len, + buf); + buf_ofs = ofs; + goto more_empty; + } + if (node->magic != JFFS2_MAGIC_BITMASK || + !hdr_crc(node)) { + ofs += 4; + counter4++; + continue; + } + if (ofs + node->totlen > + sector_ofs + part->sector_size) { + ofs += 4; + counter4++; + continue; + } /* if its a fragment add it */ - if (node->nodetype == JFFS2_NODETYPE_INODE && - inode_crc((struct jffs2_raw_inode *) node) && - data_crc((struct jffs2_raw_inode *) node)) { + switch (node->nodetype) { + case JFFS2_NODETYPE_INODE: + if (buf_ofs + buf_len < ofs + sizeof(struct + jffs2_raw_inode)) { + get_fl_mem((u32)part->offset + ofs, + buf_len, buf); + buf_ofs = ofs; + node = (void *)buf; + } + if (!inode_crc((struct jffs2_raw_inode *) node)) + break; + if (insert_node(&pL->frag, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); + ofs) == NULL) return 0; + if (max_totlen < node->totlen) + max_totlen = node->totlen; + break; + case JFFS2_NODETYPE_DIRENT: + if (buf_ofs + buf_len < ofs + sizeof(struct + jffs2_raw_dirent) + + ((struct + jffs2_raw_dirent *) + node)->nsize) { + get_fl_mem((u32)part->offset + ofs, + buf_len, buf); + buf_ofs = ofs; + node = (void *)buf; } - } else if (node->nodetype == JFFS2_NODETYPE_DIRENT && - dirent_crc((struct jffs2_raw_dirent *) node) && - dirent_name_crc((struct jffs2_raw_dirent *) node)) { + + if (!dirent_crc((struct jffs2_raw_dirent *) + node) || + !dirent_name_crc( + (struct + jffs2_raw_dirent *) + node)) + break; if (! (counterN%100)) puts ("\b\b. "); if (insert_node(&pL->dir, (u32) part->offset + - offset) == NULL) { - put_fl_mem(node); + ofs) == NULL) return 0; - } + if (max_totlen < node->totlen) + max_totlen = node->totlen; counterN++; - } else if (node->nodetype == JFFS2_NODETYPE_CLEANMARKER) { + break; + case JFFS2_NODETYPE_CLEANMARKER: if (node->totlen != sizeof(struct jffs2_unknown_node)) printf("OOPS Cleanmarker has bad size " "%d != %zu\n", node->totlen, sizeof(struct jffs2_unknown_node)); - } else if (node->nodetype == JFFS2_NODETYPE_PADDING) { + break; + case JFFS2_NODETYPE_PADDING: if (node->totlen < sizeof(struct jffs2_unknown_node)) printf("OOPS Padding has bad size " "%d < %zu\n", node->totlen, sizeof(struct jffs2_unknown_node)); - } else { + break; + case JFFS2_NODETYPE_SUMMARY: + break; + default: printf("Unknown node type: %x len %d offset 0x%x\n", node->nodetype, - node->totlen, offset); + node->totlen, ofs); } - offset += ((node->totlen + 3) & ~3); + ofs += ((node->totlen + 3) & ~3); counterF++; - } else if (node->magic == JFFS2_EMPTY_BITMASK && - node->nodetype == JFFS2_EMPTY_BITMASK) { - offset = jffs2_scan_empty(offset, part); - } else { /* if we know nothing, we just step and look. */ - offset += 4; - counter4++; } -/* printf("unknown node magic %4.4x %4.4x @ %lx\n", node->magic, node->nodetype, (unsigned long)node); */ - put_fl_mem(node); } + free(buf); putstr("\b\b done.\r\n"); /* close off the dots */ + + /* We don't care if malloc failed - then each read operation will + * allocate its own buffer as necessary (NAND) or will read directly + * from flash (NOR). + */ + pL->readbuf = malloc(max_totlen); + /* turn the lcd back on. */ /* splash(); */ diff --git a/fs/jffs2/jffs2_private.h b/fs/jffs2/jffs2_private.h index 9745762..658b325 100644 --- a/fs/jffs2/jffs2_private.h +++ b/fs/jffs2/jffs2_private.h @@ -7,6 +7,7 @@ struct b_node { u32 offset; struct b_node *next; + enum { CRC_UNKNOWN = 0, CRC_OK, CRC_BAD } datacrc; }; struct b_list { @@ -24,7 +25,7 @@ struct b_list { struct b_lists { struct b_list dir; struct b_list frag; - + void *readbuf; }; struct b_compr_info { diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h new file mode 100644 index 0000000..834933c --- /dev/null +++ b/fs/jffs2/summary.h @@ -0,0 +1,163 @@ +/* + * JFFS2 -- Journalling Flash File System, Version 2. + * + * Copyright © 2004 Ferenc Havasi <havasi@inf.u-szeged.hu>, + * Zoltan Sogor <weth@inf.u-szeged.hu>, + * Patrik Kluba <pajko@halom.u-szeged.hu>, + * University of Szeged, Hungary + * + * For licensing information, see the file 'LICENCE' in this directory. + * + */ + +#ifndef JFFS2_SUMMARY_H +#define JFFS2_SUMMARY_H + +#define BLK_STATE_ALLFF 0 +#define BLK_STATE_CLEAN 1 +#define BLK_STATE_PARTDIRTY 2 +#define BLK_STATE_CLEANMARKER 3 +#define BLK_STATE_ALLDIRTY 4 +#define BLK_STATE_BADBLOCK 5 + +#define JFFS2_SUMMARY_NOSUM_SIZE 0xffffffff +#define JFFS2_SUMMARY_INODE_SIZE (sizeof(struct jffs2_sum_inode_flash)) +#define JFFS2_SUMMARY_DIRENT_SIZE(x) (sizeof(struct jffs2_sum_dirent_flash) + (x)) +#define JFFS2_SUMMARY_XATTR_SIZE (sizeof(struct jffs2_sum_xattr_flash)) +#define JFFS2_SUMMARY_XREF_SIZE (sizeof(struct jffs2_sum_xref_flash)) + +/* Summary structures used on flash */ + +struct jffs2_sum_unknown_flash +{ + __u16 nodetype; /* node type */ +}; + +struct jffs2_sum_inode_flash +{ + __u16 nodetype; /* node type */ + __u32 inode; /* inode number */ + __u32 version; /* inode version */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_flash +{ + __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ + __u32 totlen; /* record length */ + __u32 offset; /* offset on jeb */ + __u32 pino; /* parent inode */ + __u32 version; /* dirent version */ + __u32 ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_flash +{ + __u16 nodetype; /* == JFFS2_NODETYPE_XATR */ + __u32 xid; /* xattr identifier */ + __u32 version; /* version number */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* node length */ +} __attribute__((packed)); + +struct jffs2_sum_xref_flash +{ + __u16 nodetype; /* == JFFS2_NODETYPE_XREF */ + __u32 offset; /* offset on jeb */ +} __attribute__((packed)); + +union jffs2_sum_flash +{ + struct jffs2_sum_unknown_flash u; + struct jffs2_sum_inode_flash i; + struct jffs2_sum_dirent_flash d; + struct jffs2_sum_xattr_flash x; + struct jffs2_sum_xref_flash r; +}; + +/* Summary structures used in the memory */ + +struct jffs2_sum_unknown_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* node type */ +}; + +struct jffs2_sum_inode_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* node type */ + __u32 inode; /* inode number */ + __u32 version; /* inode version */ + __u32 offset; /* offset on jeb */ + __u32 totlen; /* record length */ +} __attribute__((packed)); + +struct jffs2_sum_dirent_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */ + __u32 totlen; /* record length */ + __u32 offset; /* ofset on jeb */ + __u32 pino; /* parent inode */ + __u32 version; /* dirent version */ + __u32 ino; /* == zero for unlink */ + uint8_t nsize; /* dirent name size */ + uint8_t type; /* dirent type */ + uint8_t name[0]; /* dirent name */ +} __attribute__((packed)); + +struct jffs2_sum_xattr_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; + __u32 xid; + __u32 version; + __u32 offset; + __u32 totlen; +} __attribute__((packed)); + +struct jffs2_sum_xref_mem +{ + union jffs2_sum_mem *next; + __u16 nodetype; + __u32 offset; +} __attribute__((packed)); + +union jffs2_sum_mem +{ + struct jffs2_sum_unknown_mem u; + struct jffs2_sum_inode_mem i; + struct jffs2_sum_dirent_mem d; + struct jffs2_sum_xattr_mem x; + struct jffs2_sum_xref_mem r; +}; + +/* Summary related information stored in superblock */ + +struct jffs2_summary +{ + uint32_t sum_size; /* collected summary information for nextblock */ + uint32_t sum_num; + uint32_t sum_padded; + union jffs2_sum_mem *sum_list_head; + union jffs2_sum_mem *sum_list_tail; + + __u32 *sum_buf; /* buffer for writing out summary */ +}; + +/* Summary marker is stored at the end of every sumarized erase block */ + +struct jffs2_sum_marker +{ + __u32 offset; /* offset of the summary node in the jeb */ + __u32 magic; /* == JFFS2_SUM_MAGIC */ +}; + +#define JFFS2_SUMMARY_FRAME_SIZE (sizeof(struct jffs2_raw_summary) + sizeof(struct jffs2_sum_marker)) + +#endif /* JFFS2_SUMMARY_H */ diff --git a/include/asm-i386/ic/pci.h b/include/asm-i386/ic/pci.h new file mode 100644 index 0000000..bcccdbe --- /dev/null +++ b/include/asm-i386/ic/pci.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB <daniel@omicron.se>. + * + * 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 _ASM_IC_SC520_PCI_H_ +#define _ASM_IC_SC520_PCI_H_ 1 + +/* pin number used for PCI interrupt mappings */ +#define SC520_PCI_INTA 0 +#define SC520_PCI_INTB 1 +#define SC520_PCI_INTC 2 +#define SC520_PCI_INTD 3 +#define SC520_PCI_GPIRQ0 4 +#define SC520_PCI_GPIRQ1 5 +#define SC520_PCI_GPIRQ2 6 +#define SC520_PCI_GPIRQ3 7 +#define SC520_PCI_GPIRQ4 8 +#define SC520_PCI_GPIRQ5 9 +#define SC520_PCI_GPIRQ6 10 +#define SC520_PCI_GPIRQ7 11 +#define SC520_PCI_GPIRQ8 12 +#define SC520_PCI_GPIRQ9 13 +#define SC520_PCI_GPIRQ10 14 + +extern int sc520_pci_ints[]; + +void pci_sc520_init(struct pci_controller *hose); +int pci_sc520_set_irq(int pci_pin, int irq); + +#endif diff --git a/include/asm-i386/ic/sc520.h b/include/asm-i386/ic/sc520.h index 0f7e7a5..bf39516 100644 --- a/include/asm-i386/ic/sc520.h +++ b/include/asm-i386/ic/sc520.h @@ -282,24 +282,6 @@ #define SC520_IRQ14 9 #define SC520_IRQ15 10 - -/* pin number used for PCI interrupt mappings */ -#define SC520_PCI_INTA 0 -#define SC520_PCI_INTB 1 -#define SC520_PCI_INTC 2 -#define SC520_PCI_INTD 3 -#define SC520_PCI_GPIRQ0 4 -#define SC520_PCI_GPIRQ1 5 -#define SC520_PCI_GPIRQ2 6 -#define SC520_PCI_GPIRQ3 7 -#define SC520_PCI_GPIRQ4 8 -#define SC520_PCI_GPIRQ5 9 -#define SC520_PCI_GPIRQ6 10 -#define SC520_PCI_GPIRQ7 11 -#define SC520_PCI_GPIRQ8 12 -#define SC520_PCI_GPIRQ9 13 -#define SC520_PCI_GPIRQ10 14 - /* utility functions */ void write_mmcr_byte(u16 mmcr, u8 data); void write_mmcr_word(u16 mmcr, u16 data); @@ -308,11 +290,7 @@ u8 read_mmcr_byte(u16 mmcr); u16 read_mmcr_word(u16 mmcr); u32 read_mmcr_long(u16 mmcr); -extern int sc520_pci_ints[]; - void init_sc520(void); unsigned long init_sc520_dram(void); -void pci_sc520_init(struct pci_controller *hose); -int pci_sc520_set_irq(int pci_pin, int irq); #endif diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h index d142cd1..ed96bab 100644 --- a/include/jffs2/jffs2.h +++ b/include/jffs2/jffs2.h @@ -50,6 +50,9 @@ #define JFFS2_EMPTY_BITMASK 0xffff #define JFFS2_DIRTY_BITMASK 0x0000 +/* Summary node MAGIC marker */ +#define JFFS2_SUM_MAGIC 0x02851885 + /* We only allow a single char for length, and 0xFF is empty flash so we don't want it confused with a real length. Hence max 254. */ @@ -89,6 +92,7 @@ #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) #define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) +#define JFFS2_NODETYPE_SUMMARY (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 6) /* Maybe later... */ /*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */ @@ -166,9 +170,24 @@ struct jffs2_raw_inode /* __u8 data[dsize]; */ } __attribute__((packed)); +struct jffs2_raw_summary +{ + __u16 magic; + __u16 nodetype; /* = JFFS2_NODETYPE_SUMMARY */ + __u32 totlen; + __u32 hdr_crc; + __u32 sum_num; /* number of sum entries*/ + __u32 cln_mkr; /* clean marker size, 0 = no cleanmarker */ + __u32 padded; /* sum of the size of padding nodes */ + __u32 sum_crc; /* summary information crc */ + __u32 node_crc; /* node crc */ + __u32 sum[0]; /* inode summary info */ +}; + union jffs2_node_union { struct jffs2_raw_inode i; struct jffs2_raw_dirent d; + struct jffs2_raw_summary s; struct jffs2_unknown_node u; } __attribute__((packed)); diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h index e9b7d6e..8b2720e 100644 --- a/include/jffs2/load_kernel.h +++ b/include/jffs2/load_kernel.h @@ -50,6 +50,7 @@ struct part_info { u32 offset; /* offset within device */ void *jffs2_priv; /* used internaly by jffs2 */ u32 mask_flags; /* kernel MTD mask flags */ + u32 sector_size; /* size of sector */ struct mtd_device *dev; /* parent device */ }; diff --git a/include/libfdt_env.h b/include/libfdt_env.h index 355ebf2..ea474a5 100644 --- a/include/libfdt_env.h +++ b/include/libfdt_env.h @@ -47,6 +47,7 @@ extern struct fdt_header *working_fdt; /* Pointer to the working fdt */ #define cpu_to_fdt64(x) (x) #endif +#ifndef USE_HOSTCC /* * Types for `void *' pointers. * @@ -58,5 +59,6 @@ typedef unsigned long int uintptr_t; #else typedef unsigned int uintptr_t; #endif +#endif /* not USE_HOSTCC */ #endif /* _LIBFDT_ENV_H */ diff --git a/include/usb.h b/include/usb.h index 84a77b2..510df95 100644 --- a/include/usb.h +++ b/include/usb.h @@ -91,7 +91,7 @@ struct usb_endpoint_descriptor { unsigned char bInterval; unsigned char bRefresh; unsigned char bSynchAddress; -} __attribute__ ((packed)); +} __attribute__ ((packed)) __attribute__ ((aligned(2))); /* Interface descriptor */ struct usb_interface_descriptor { diff --git a/include/usbdcore_omap1510.h b/include/usbdcore_omap1510.h index 526fcd9..ece0e95 100644 --- a/include/usbdcore_omap1510.h +++ b/include/usbdcore_omap1510.h @@ -168,8 +168,8 @@ #define UDC_IN_ENDPOINT 1 #define UDC_IN_PACKET_SIZE 64 #define UDC_INT_ENDPOINT 5 -#define UDC_INT_PKTSIZE 16 -#define UDC_BULK_PKTSIZE 16 +#define UDC_INT_PACKET_SIZE 16 +#define UDC_BULK_PACKET_SIZE 16 void udc_irq (void); /* Flow control */ @@ -177,7 +177,7 @@ void udc_set_nak(int epid); void udc_unset_nak (int epid); /* Higher level functions for abstracting away from specific device */ -void udc_endpoint_write(struct usb_endpoint_instance *endpoint); +int udc_endpoint_write(struct usb_endpoint_instance *endpoint); int udc_init (void); diff --git a/tools/netconsole b/tools/netconsole new file mode 100755 index 0000000..09c8981 --- /dev/null +++ b/tools/netconsole @@ -0,0 +1,42 @@ +#!/bin/sh + +usage() { + ( + echo "Usage: $0 <board IP> [board port]" + echo "" + echo "If port is not specified, '6666' will be used" + [ -z "$*" ] && exit 0 + echo "" + echo "ERROR: $*" + exit 1 + ) 1>&2 + exit $? +} + +while [ -n "$1" ] ; do + case $1 in + -h|--help) usage;; + --) break;; + -*) usage "Invalid option $1";; + *) break;; + esac + shift +done + +ip=$1 +port=${2:-6666} + +if [ -z "${ip}" ] || [ -n "$3" ] ; then + usage "Invalid number of arguments" +fi + +for nc in netcat nc ; do + type ${nc} >/dev/null && break +done + +trap "stty icanon echo intr ^C" 0 2 3 5 10 13 15 +echo "NOTE: the interrupt signal (normally ^C) has been remapped to ^T" + +stty -icanon -echo intr ^T +${nc} -u -l -p ${port} < /dev/null & +exec ${nc} -u ${ip} ${port} |