10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/nubus.h>
14 #include <linux/errno.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
19 #include <asm/setup.h>
33 #define FORMAT_BLOCK_SIZE 20
34 #define ROM_DIR_OFFSET 0x24
36 #define NUBUS_TEST_PATTERN 0x5A932BC7
41 #undef I_WANT_TO_PROBE_SLOT_ZERO
44 #undef TRY_TO_DODGE_WSOD
74 static inline int not_useful(
void *
p,
int map)
76 unsigned long pv=(
unsigned long)p;
83 static unsigned long nubus_get_rom(
unsigned char **
ptr,
int len,
int map)
87 unsigned char *
p = *
ptr;
92 while(not_useful(p,map))
101 static void nubus_rewind(
unsigned char **ptr,
int len,
int map)
103 unsigned char *p=*
ptr;
114 while(not_useful(p, map));
120 static void nubus_advance(
unsigned char **ptr,
int len,
int map)
122 unsigned char *p = *
ptr;
127 while(not_useful(p,map))
135 static void nubus_move(
unsigned char **ptr,
int len,
int map)
138 nubus_advance(ptr, len, map);
140 nubus_rewind(ptr, -len, map);
150 static inline long nubus_expand32(
long foo)
157 static inline void *nubus_rom_addr(
int slot)
163 return (
void *)(0xF1000000+(slot<<24));
166 static unsigned char *nubus_dirptr(
const struct nubus_dirent *nd)
168 unsigned char *p = nd->
base;
171 nubus_move(&p, nubus_expand32(nd->
data), nd->
mask);
182 unsigned char *
t = (
unsigned char *)dest;
183 unsigned char *p = nubus_dirptr(dirent);
186 *t++ = nubus_get_rom(&p, 1, dirent->
mask);
195 unsigned char *
t=(
unsigned char *)dest;
196 unsigned char *p = nubus_dirptr(dirent);
199 *t = nubus_get_rom(&p, 1, dirent->
mask);
250 dir->
ptr = dir->
base = nubus_dirptr(ent);
267 resid = nubus_get_rom(&nd->
ptr, 4, nd->
mask);
270 if((resid&0xff000000) == 0xff000000)
278 ent->
type = resid >> 24;
280 ent->
data = resid & 0xffffff;
298 unsigned short dr_hw,
299 unsigned short dr_sw,
307 && itor->
type == type
308 && itor->
dr_hw == dr_hw
309 && itor->
dr_sw == dr_sw)
327 && itor->
type == type)
343 if (itor->
board->slot == slot)
356 if (ent->
type == rsrc_type)
379 case 0x0080 ... 0x0085:
401 for (i = 0; i < 6; i++)
402 printk(
"%02x%s", addr[i] & 0xff,
423 meminfo[0], meminfo[1]);
428 unsigned long rominfo[2];
431 rominfo[0], rominfo[1]);
446 nubus_show_display_resource(dev, ent);
449 nubus_show_network_resource(dev, ent);
452 nubus_show_cpu_resource(dev, ent);
474 if (slot == 0 && (
unsigned long)
dir.base % 2)
478 printk(
KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n",
494 unsigned short nbtdata[4];
497 dev->
type = nbtdata[1];
498 dev->
dr_sw = nbtdata[2];
499 dev->
dr_hw = nbtdata[3];
501 nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
518 dev->
driver = nubus_dirptr(&drvr_ent);
548 nubus_show_private_resource(dev, &ent);
585 if (size >
sizeof(
mode) - 1)
586 size =
sizeof(
mode) - 1;
600 unsigned char icon[128];
609 for (y = 0; y < 32; y++) {
611 for (x = 0; x < 32; x++) {
628 static char* vendor_fields[6] = {
"ID",
"serial",
"revision",
629 "part",
"date",
"unknown field"};
646 vendor_fields[ent.
type-1], name);
659 printk(
KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
667 unsigned short nbtdata[4];
673 nbtdata[0], nbtdata[1], nbtdata[2],
675 if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
676 nbtdata[2] != 0 || nbtdata[3] != 0)
685 nubus_get_icon(board, &ent);
694 nubus_get_vendorinfo(board, &ent);
707 nubus_get_vidnames(board, &ent);
727 unsigned char* romdir;
733 nubus_rewind(&rp, 4, board->
lanes);
738 nubus_expand32(board->
doffset),
747 romdir = nubus_rom_addr(board->
slot);
749 dir.base =
dir.ptr = romdir;
796 printk(
KERN_ERR "nubus_get_rom_dir: ROM weirdness! Notify the developers...\n");
811 rp = nubus_rom_addr(slot);
826 unsigned short foo, bar;
827 foo = nubus_get_rom(&rp, 2, bytelanes);
828 bar = nubus_get_rom(&rp, 2, bytelanes);
829 printk(
"%04x %04x ", foo, bar);
837 board->
doffset = nubus_get_rom(&rp, 4, bytelanes);
844 board->
rom_length = nubus_get_rom(&rp, 4, bytelanes);
845 board->
crc = nubus_get_rom(&rp, 4, bytelanes);
846 board->
rev = nubus_get_rom(&rp, 1, bytelanes);
847 board->
format = nubus_get_rom(&rp,1, bytelanes);
848 board->
lanes = bytelanes;
851 if(!(board->
doffset & 0x00FF0000))
853 dpat = nubus_get_rom(&rp, 4, bytelanes);
865 nubus_find_rom_dir(board);
882 nubus_get_board_resource(board, slot, &ent);
891 dev = nubus_get_functional_resource(board, slot, &ent);
900 for (devp=&nubus_devices; *devp!=
NULL; devp=&((*devp)->next))
907 for (boardp=&nubus_boards; *boardp!=
NULL; boardp=&((*boardp)->next))
921 rp = nubus_rom_addr(slot);
943 if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
947 if ((dp & 0x0F) >= (1<<i))
951 nubus_add_board(slot, dp);
957 #if defined(CONFIG_PROC_FS)
961 static int sprint_nubus_board(
struct nubus_board* board,
char* ptr,
int len)
975 int nprinted, len, begin = 0;
979 len =
sprintf(page,
"Nubus devices found:\n");
981 for (board = nubus_boards; board !=
NULL; board = board->
next)
983 nprinted = sprint_nubus_board(board, page + len, size - len);
987 if (len+begin < off) {
991 if (len+begin >= off+count)
1011 #ifdef I_WANT_TO_PROBE_SLOT_ZERO
1014 for(slot = 9; slot < 15; slot++)
1020 static int __init nubus_init(
void)
1032 #ifdef TRY_TO_DODGE_WSOD
1040 printk(
"NuBus: Scanning NuBus slots.\n");
1041 nubus_devices =
NULL;
1042 nubus_boards =
NULL;
1045 #ifdef CONFIG_PROC_FS
1046 create_proc_read_entry(
"nubus", 0,
NULL, nubus_read_proc,
NULL);