diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/zorro/zorro.c | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff) |
o Merge with Linux 2.1.116.
o New Newport console code.
o New G364 console code.
Diffstat (limited to 'drivers/zorro/zorro.c')
-rw-r--r-- | drivers/zorro/zorro.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c new file mode 100644 index 000000000..108bd6700 --- /dev/null +++ b/drivers/zorro/zorro.c @@ -0,0 +1,229 @@ +/* + * $Id: zorro.c,v 1.1.2.1 1998/06/07 23:21:02 geert Exp $ + * + * Zorro Bus Services + * + * Copyright (C) 1995-1998 Geert Uytterhoeven + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + + +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/zorro.h> +#include <asm/setup.h> +#include <asm/bitops.h> +#include <asm/amigahw.h> + + + /* + * Expansion Devices + */ + +u_int zorro_num_autocon = 0; +struct ConfigDev zorro_autocon[ZORRO_NUM_AUTO]; +static u32 zorro_autocon_parts[ZORRO_NUM_AUTO] = { 0, }; + + + /* + * Find the key for the next unconfigured expansion device of a specific + * type. + * + * Part is a device specific number (0 <= part <= 31) to allow for the + * independent configuration of independent parts of an expansion board. + * Thanks to Jes Soerensen for this idea! + * + * Index is used to specify the first board in the autocon list + * to be tested. It was inserted in order to solve the problem + * with the GVP boards that use the same product code, but + * it should help if there are other companies which use the same + * method as GVP. Drivers for boards which are not using this + * method do not need to think of this - just set index = 0. + * + * Example: + * + * while ((key = zorro_find(ZORRO_PROD_MY_BOARD, MY_PART, 0))) { + * cd = zorro_get_board(key); + * initialise_this_board; + * zorro_config_board(key, MY_PART); + * } + */ + +u_int zorro_find(zorro_id id, u_int part, u_int index) +{ + u16 manuf = ZORRO_MANUF(id); + u8 prod = ZORRO_PROD(id); + u8 epc = ZORRO_EPC(id); + u_int key; + const struct ConfigDev *cd; + u32 addr; + + if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) + return 0; + + if (part > 31) { + printk("zorro_find: bad part %d\n", part); + return 0; + } + + for (key = index+1; key <= zorro_num_autocon; key++) { + cd = &zorro_autocon[key-1]; + addr = (u32)cd->cd_BoardAddr; + if ((cd->cd_Rom.er_Manufacturer == manuf) && + (cd->cd_Rom.er_Product == prod) && + !(zorro_autocon_parts[key-1] & (1<<part)) && + (manuf != ZORRO_MANUF(ZORRO_PROD_GVP_EPC_BASE) || + prod != ZORRO_PROD(ZORRO_PROD_GVP_EPC_BASE) || /* GVP quirk */ + (*(u16 *)ZTWO_VADDR(addr+0x8000) & GVP_PRODMASK) == epc)) + return key; + } + return 0; +} + + + /* + * Get the board corresponding to a specific key + */ + +const struct ConfigDev *zorro_get_board(u_int key) +{ + if ((key < 1) || (key > zorro_num_autocon)) { + printk("zorro_get_board: bad key %d\n", key); + return NULL; + } + return &zorro_autocon[key-1]; +} + + + /* + * Mark a part of a board as configured + */ + +void zorro_config_board(u_int key, u_int part) +{ + if ((key < 1) || (key > zorro_num_autocon)) + printk("zorro_config_board: bad key %d\n", key); + else if (part > 31) + printk("zorro_config_board: bad part %d\n", part); + else if (zorro_autocon_parts[key-1] & (1<<part)) + printk("zorro_config_board: key %d part %d is already configured\n", + key, part); + else + zorro_autocon_parts[key-1] |= 1<<part; +} + + + /* + * Mark a part of a board as unconfigured + * + * This function is mainly intended for the unloading of LKMs + */ + +void zorro_unconfig_board(u_int key, u_int part) +{ + if ((key < 1) || (key > zorro_num_autocon)) + printk("zorro_unconfig_board: bad key %d\n", key); + else if (part > 31) + printk("zorro_unconfig_board: bad part %d\n", part); + else if (!(zorro_autocon_parts[key-1] & (1<<part))) + printk("zorro_config_board: key %d part %d is not yet configured\n", + key, part); + else + zorro_autocon_parts[key-1] &= ~(1<<part); +} + + + /* + * Bitmask indicating portions of available Zorro II RAM that are unused + * by the system. Every bit represents a 64K chunk, for a maximum of 8MB + * (128 chunks, physical 0x00200000-0x009fffff). + * + * If you want to use (= allocate) portions of this RAM, you should clear + * the corresponding bits. + * + * Possible uses: + * - z2ram device + * - SCSI DMA bounce buffers + */ + +u32 zorro_unused_z2ram[4] = { 0, 0, 0, 0 }; + + +__initfunc(static void mark_region(u32 addr, u_int size, int flag)) +{ + u32 start, end; + + if (flag) { + start = (addr+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK; + end = (addr+size) & ~Z2RAM_CHUNKMASK; + } else { + start = addr & ~Z2RAM_CHUNKMASK; + end = (addr+size+Z2RAM_CHUNKMASK) & ~Z2RAM_CHUNKMASK; + } + if (end <= Z2RAM_START || start >= Z2RAM_END) + return; + start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START; + end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START; + while (start < end) { + u32 chunk = start>>Z2RAM_CHUNKSHIFT; + if (flag) + set_bit(chunk, zorro_unused_z2ram); + else + clear_bit(chunk, zorro_unused_z2ram); + start += Z2RAM_CHUNKSIZE; + } +} + + + /* + * Initialization + */ + +__initfunc(void zorro_init(void)) +{ + u_int i, j; + u32 disabled_z2mem = 0; + + if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO)) { + printk("Zorro: No Zorro bus detected\n"); + return; + } + + printk("Zorro: Probing AutoConfig expansion devices: %d device%s\n", + zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); + + /* Mark all available Zorro II memory */ + for (i = 0; i < zorro_num_autocon; i++) { + const struct ConfigDev *cd = &zorro_autocon[i]; + if (cd->cd_Rom.er_Type & ERTF_MEMLIST) + mark_region((u32)cd->cd_BoardAddr, cd->cd_BoardSize, 1); + } + + /* Unmark all used Zorro II memory */ + for (i = 0; i < m68k_num_memory; i++) + if (m68k_memory[i].addr < 16*1024*1024) { + if (AMIGAHW_PRESENT(ZORRO3)) { + /* don't use Zorro II RAM as system memory on Zorro III */ + /* capable machines */ + if (i == 0) { + /* don't cut off the branch we're sitting on */ + printk("Warning: kernel runs in Zorro II memory\n"); + } else { + disabled_z2mem += m68k_memory[i].size; + m68k_num_memory--; + for (j = i; j < m68k_num_memory; j++) + m68k_memory[j] = m68k_memory[j+1]; + i--; + continue; + } + } + mark_region(m68k_memory[i].addr, m68k_memory[i].size, 0); + } + if (disabled_z2mem) + printk("%dK of Zorro II memory will not be used as system memory\n", + disabled_z2mem>>10); +} |