Commit 518e2e1a authored by wdenk's avatar wdenk
Browse files

* Patch by Pavel Bartusek, 21 Mar 2004

  Add Reiserfs support

* Patch by Hinko Kocevar, 20 Mar 2004
  - Add auto-release for SMSC LAN91c111 driver
  - Add save/restore of PTR and PNR regs as suggested in datasheet
parent 6fb6af6d
......@@ -2,6 +2,13 @@
Changes for U-Boot 1.0.2:
======================================================================
* Patch by Pavel Bartusek, 21 Mar 2004
Add Reiserfs support
* Patch by Hinko Kocevar, 20 Mar 2004
- Add auto-release for SMSC LAN91c111 driver
- Add save/restore of PTR and PNR regs as suggested in datasheet
* Patch by Stephen Williams, 19 March 2004
Increase speed of sector reads from SystemACE,
shorten poll timeout and remove a useless reset
......
......@@ -38,6 +38,11 @@ N: Jerry van Baren
E: <vanbaren@cideas.com>
D: BedBug port to 603e core (MPC82xx). Code for enhanced memory test.
N: Pavel Bartusek
E: <pba@sysgo.com>
D: Reiserfs support
W: http://www.elinos.com
N: Andre Beaudin
E: <andre.beaudin@colubris.com>
D: PCMCIA, Ethernet, TFTP
......
......@@ -99,7 +99,8 @@ LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a
LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \
fs/reiserfs/libreiserfs.a
LIBS += net/libnet.a
LIBS += disk/libdisk.a
LIBS += rtc/librtc.a
......
......@@ -39,7 +39,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.o \
cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
cmd_nand.o cmd_net.o cmd_nvedit.o \
cmd_pci.o cmd_pcmcia.o cmd_portio.o \
cmd_reginfo.o cmd_scsi.o cmd_spi.o cmd_usb.o cmd_vfd.o \
cmd_reginfo.o cmd_reiser.o cmd_scsi.o cmd_spi.o cmd_usb.o cmd_vfd.o \
command.o console.o devices.o dlmalloc.o docecc.o \
environment.o env_common.o \
env_dataflash.o env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
......
/*
* (C) Copyright 2003 - 2004
* Sysgo Real-Time Solutions, AG <www.elinos.com>
* Pavel Bartusek <pba@sysgo.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
*
*/
/*
* Reiserfs support
*/
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_REISER)
#include <config.h>
#include <command.h>
#include <image.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <reiserfs.h>
#ifndef CONFIG_DOS_PARTITION
#error DOS partition support must be selected
#endif
/* #define REISER_DEBUG */
#ifdef REISER_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
static block_dev_desc_t *get_dev (char* ifname, int dev)
{
#if (CONFIG_COMMANDS & CFG_CMD_IDE)
if (strncmp(ifname,"ide",3)==0) {
extern block_dev_desc_t * ide_get_dev(int dev);
return((dev >= CFG_IDE_MAXDEVICE) ? NULL : ide_get_dev(dev));
}
#endif
#if (CONFIG_COMMANDS & CFG_CMD_SCSI)
if (strncmp(ifname,"scsi",4)==0) {
extern block_dev_desc_t * scsi_get_dev(int dev);
return((dev >= CFG_SCSI_MAXDEVICE) ? NULL : scsi_get_dev(dev));
}
#endif
#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE))
if (strncmp(ifname,"usb",3)==0) {
extern block_dev_desc_t * usb_stor_get_dev(int dev);
return((dev >= USB_MAX_STOR_DEV) ? NULL : usb_stor_get_dev(dev));
}
#endif
#if defined(CONFIG_MMC)
if (strncmp(ifname,"mmc",3)==0) {
extern block_dev_desc_t * mmc_get_dev(int dev);
return((dev >= 1) ? NULL : mmc_get_dev(dev));
}
#endif
#if defined(CONFIG_SYSTEMACE)
if (strcmp(ifname,"ace")==0) {
extern block_dev_desc_t * systemace_get_dev(int dev);
return((dev >= 1) ? NULL : systemace_get_dev(dev));
}
#endif
return NULL;
}
int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = "/";
int dev=0;
int part=1;
char *ep;
block_dev_desc_t *dev_desc=NULL;
int part_length;
if (argc < 3) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc=get_dev(argv[1],dev);
if (dev_desc == NULL) {
printf ("\n** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (*ep) {
if (*ep != ':') {
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
return 1;
}
part = (int)simple_strtoul(++ep, NULL, 16);
}
if (argc == 4) {
filename = argv[3];
}
PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) {
printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
return 1;
}
if (!reiserfs_mount(part_length)) {
printf ("** Bad Reisefs partition or disk - %s %d:%d **\n", argv[1], dev, part);
return 1;
}
if (reiserfs_ls (filename)) {
printf ("** Error reiserfs_ls() **\n");
return 1;
};
return 0;
}
U_BOOT_CMD(
reiserls, 4, 1, do_reiserls,
"reiserls- list files in a directory (default /)\n",
"<interface> <dev[:part]> [directory]\n"
" - list files from 'dev' on 'interface' in a 'directory'\n"
);
/******************************************************************************
* Reiserfs boot command intepreter. Derived from diskboot
*/
int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
char *filename = NULL;
char *ep;
int dev, part = 0;
ulong addr = 0, part_length, filelen;
disk_partition_t info;
block_dev_desc_t *dev_desc = NULL;
char buf [12];
unsigned long count;
char *addr_str;
switch (argc) {
case 3:
addr_str = getenv("loadaddr");
if (addr_str != NULL) {
addr = simple_strtoul (addr_str, NULL, 16);
} else {
addr = CFG_LOAD_ADDR;
}
filename = getenv ("bootfile");
count = 0;
break;
case 4:
addr = simple_strtoul (argv[3], NULL, 16);
filename = getenv ("bootfile");
count = 0;
break;
case 5:
addr = simple_strtoul (argv[3], NULL, 16);
filename = argv[4];
count = 0;
break;
case 6:
addr = simple_strtoul (argv[3], NULL, 16);
filename = argv[4];
count = simple_strtoul (argv[5], NULL, 16);
break;
default:
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
}
if (!filename) {
puts ("\n** No boot file defined **\n");
return 1;
}
dev = (int)simple_strtoul (argv[2], &ep, 16);
dev_desc=get_dev(argv[1],dev);
if (dev_desc==NULL) {
printf ("\n** Block device %s %d not supported\n", argv[1], dev);
return 1;
}
if (*ep) {
if (*ep != ':') {
puts ("\n** Invalid boot device, use `dev[:part]' **\n");
return 1;
}
part = (int)simple_strtoul(++ep, NULL, 16);
}
PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
if (part != 0) {
if (get_partition_info (&dev_desc[dev], part, &info)) {
printf ("** Bad partition %d **\n", part);
return 1;
}
if (strncmp(info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
printf ("\n** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info.type);
return 1;
}
PRINTF ("\nLoading from block device %s device %d, partition %d: "
"Name: %.32s Type: %.32s File:%s\n",
argv[1], dev, part, info.name, info.type, filename);
} else {
PRINTF ("\nLoading from block device %s device %d, File:%s\n",
argv[1], dev, filename);
}
if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) {
printf ("** Bad partition - %s %d:%d **\n", argv[1], dev, part);
return 1;
}
if (!reiserfs_mount(part_length)) {
printf ("** Bad Reisefs partition or disk - %s %d:%d **\n", argv[1], dev, part);
return 1;
}
filelen = reiserfs_open(filename);
if (filelen < 0) {
printf("** File not found %s\n", filename);
return 1;
}
if ((count < filelen) && (count != 0)) {
filelen = count;
}
if (reiserfs_read((char *)addr, filelen) != filelen) {
printf("\n** Unable to read \"%s\" from %s %d:%d **\n", filename, argv[1], dev, part);
return 1;
}
/* Loading ok, update default load address */
load_addr = addr;
printf ("\n%ld bytes read\n", filelen);
sprintf(buf, "%lX", filelen);
setenv("filesize", buf);
return filelen;
}
U_BOOT_CMD(
reiserload, 6, 0, do_reiserload,
"reiserload- load binary file from a Reiser filesystem\n",
"<interface> <dev[:part]> [addr] [filename] [bytes]\n"
" - load binary file 'filename' from 'dev' on 'interface'\n"
" to address 'addr' from dos filesystem\n"
);
#endif /* CONFIG_COMMANDS & CFG_CMD_REISER */
......@@ -481,7 +481,13 @@ static int smc_send_packet (volatile void *packet, int packet_length)
int try = 0;
int time_out;
byte status;
byte saved_pnr;
word saved_ptr;
/* save PTR and PNR registers before manipulation */
SMC_SELECT_BANK (2);
saved_pnr = SMC_inb( PN_REG );
saved_ptr = SMC_inw( PTR_REG );
PRINTK3 ("%s:smc_hardware_send_packet\n", SMC_DEV_NAME);
......@@ -559,6 +565,10 @@ again:
/* we have a packet address, so tell the card to use it */
SMC_outb (packet_no, PN_REG);
/* do not write new ptr value if Write data fifo not empty */
while ( saved_ptr & PTR_NOTEMPTY )
printf ("Write data fifo not empty!\n");
/* point to the beginning of the packet */
SMC_outw (PTR_AUTOINC, PTR_REG);
......@@ -607,12 +617,15 @@ again:
SMC_outw (MC_ENQUEUE, MMU_CMD_REG);
/* poll for TX INT */
if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) {
/* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
/* poll for TX_EMPTY INT - autorelease enabled */
if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
/* sending failed */
PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
/* release packet */
SMC_outw (MC_FREEPKT, MMU_CMD_REG);
/* no need to release, MMU does that now */
/* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */
/* wait for MMU getting ready (low) */
while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
......@@ -625,12 +638,14 @@ again:
return 0;
} else {
/* ack. int */
SMC_outb (IM_TX_INT, SMC91111_INT_REG);
SMC_outb (IM_TX_EMPTY_INT, SMC91111_INT_REG);
/* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
length);
/* release packet */
SMC_outw (MC_FREEPKT, MMU_CMD_REG);
/* no need to release, MMU does that now */
/* SMC_outw (MC_FREEPKT, MMU_CMD_REG); */
/* wait for MMU getting ready (low) */
while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
......@@ -642,6 +657,10 @@ again:
}
/* restore previously saved registers */
SMC_outb( saved_pnr, PN_REG );
SMC_outw( saved_ptr, PTR_REG );
return length;
}
......@@ -730,8 +749,14 @@ static int smc_rcv()
#ifdef USE_32_BIT
dword stat_len;
#endif
byte saved_pnr;
word saved_ptr;
SMC_SELECT_BANK(2);
/* save PTR and PTR registers */
saved_pnr = SMC_inb( PN_REG );
saved_ptr = SMC_inw( PTR_REG );
packet_number = SMC_inw( RXFIFO_REG );
if ( packet_number & RXFIFO_REMPTY ) {
......@@ -810,6 +835,10 @@ static int smc_rcv()
while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
udelay(1); /* Wait until not busy */
/* restore saved registers */
SMC_outb( saved_pnr, PN_REG );
SMC_outw( saved_ptr, PTR_REG );
if (!is_error) {
/* Pass the packet up to the protocol layers. */
NetReceive(NetRxPackets[0], packet_length);
......@@ -1252,6 +1281,11 @@ static void smc_phy_configure ()
/* Update our Auto-Neg Advertisement Register */
smc_write_phy_register (PHY_AD_REG, my_ad_caps);
/* Read the register back. Without this, it appears that when */
/* auto-negotiation is restarted, sometimes it isn't ready and */
/* the link does not come up. */
smc_read_phy_register(PHY_AD_REG);
PRINTK2 ("%s:phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
PRINTK2 ("%s:phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);
......
......@@ -378,7 +378,7 @@ typedef unsigned long int dword;
#define CTL_EEPROM_SELECT 0x0004 /* Controls EEPROM reload & store */
#define CTL_RELOAD 0x0002 /* When set reads EEPROM into registers */
#define CTL_STORE 0x0001 /* When set stores registers into EEPROM */
#define CTL_DEFAULT (0x1210)
#define CTL_DEFAULT (0x1A10) /* Autorelease enabled*/
/* MMU Command Register */
/* BANK 2 */
......@@ -423,6 +423,7 @@ typedef unsigned long int dword;
#define PTR_RCV 0x8000 /* 1=Receive area, 0=Transmit area */
#define PTR_AUTOINC 0x4000 /* Auto increment the pointer on each access */
#define PTR_READ 0x2000 /* When 1 the operation is a read */
#define PTR_NOTEMPTY 0x0800 /* When 1 _do not_ write fifo DATA REG */
/* Data Register */
......
......@@ -22,7 +22,7 @@
#
#
SUBDIRS := jffs2 cramfs fdos fat
SUBDIRS := jffs2 cramfs fdos fat reiserfs
.depend all:
@for dir in $(SUBDIRS) ; do \
......
#
# (C) Copyright 2003
# Pavel Bartusek, Sysgo Real-Time Solutions AG, pba@sysgo.de
#
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = libreiserfs.a
AOBJS =
COBJS = reiserfs.o dev.o mode_string.o
OBJS = $(AOBJS) $(COBJS)
#CPPFLAGS +=
all: $(LIB) $(AOBJS)
$(LIB): .depend $(OBJS)
$(AR) crv $@ $(OBJS)
#########################################################################
.depend: Makefile $(AOBJS:.o=.S) $(COBJS:.o=.c)
$(CC) -M $(CFLAGS) $(AOBJS:.o=.S) $(COBJS:.o=.c) > $@
sinclude .depend
#########################################################################
/*
* (C) Copyright 2003 - 2004
* Sysgo AG, <www.elinos.com>, Pavel Bartusek <pba@sysgo.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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <common.h>
#if (CONFIG_COMMANDS & CFG_CMD_REISER)
#include <config.h>
#include <reiserfs.h>
#include "reiserfs_private.h"
static block_dev_desc_t *reiserfs_block_dev_desc;
static disk_partition_t part_info;
int reiserfs_set_blk_dev(block_dev_desc_t *rbdd, int part)
{
reiserfs_block_dev_desc = rbdd;
if (part == 0) {
/* disk doesn't use partition table */
part_info.start = 0;
part_info.size = rbdd->lba;
part_info.blksz = rbdd->blksz;
} else {
if (get_partition_info (reiserfs_block_dev_desc, part, &part_info)) {
return 0;
}
}
return (part_info.size);
}
int reiserfs_devread (int sector, int byte_offset, int byte_len, char *buf)
{
char sec_buf[SECTOR_SIZE];
unsigned block_len;
/*
unsigned len = byte_len;
u8 *start = buf;
*/
/*
* Check partition boundaries
*/
if (sector < 0
|| ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
>= part_info.size)) {
// errnum = ERR_OUTSIDE_PART;
printf (" ** reiserfs_devread() read outside partition\n");
return 0;
}
/*
* Get the read to the beginning of a partition.
*/
sector += byte_offset >> SECTOR_BITS;
byte_offset &= SECTOR_SIZE - 1;
#if defined(DEBUG)
printf (" <%d, %d, %d> ", sector, byte_offset, byte_len);
#endif
if (reiserfs_block_dev_desc == NULL)
return 0;
if (byte_offset != 0) {
/* read first part which isn't aligned with start of sector */
if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) {
printf (" ** reiserfs_devread() read error\n");
return 0;
}
memcpy(buf, sec_buf+byte_offset, min(SECTOR_SIZE-byte_offset, byte_len));
buf+=min(SECTOR_SIZE-byte_offset, byte_len);
byte_len-=min(SECTOR_SIZE-byte_offset, byte_len);
sector++;
}
/* read sector aligned part */
block_len = byte_len & ~(SECTOR_SIZE-1);
if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
part_info.start+sector, block_len/SECTOR_SIZE, (unsigned long *)buf) !=
block_len/SECTOR_SIZE) {
printf (" ** reiserfs_devread() read error - block\n");
return 0;
}
buf+=block_len;
byte_len-=block_len;
sector+= block_len/SECTOR_SIZE;
if ( byte_len != 0 ) {
/* read rest of data which are not in whole sector */
if (reiserfs_block_dev_desc->block_read(reiserfs_block_dev_desc->dev,
part_info.start+sector, 1, (unsigned long *)sec_buf) != 1) {
printf (" ** reiserfs_devread() read error - last part\n");
return 0;
}
memcpy(buf, sec_buf, byte_len);
}
return 1;
}
#endif /* CFG_CMD_REISERFS */