Linux Audio

Check our new training course

Loading...
v3.1
   1/*
   2 *	Macintosh Nubus Interface Code
   3 *
   4 *      Originally by Alan Cox
   5 *
   6 *      Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
   7 *      and others.
   8 */
   9
  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>
  15#include <linux/init.h>
  16#include <linux/delay.h>
  17#include <linux/module.h>
  18#include <linux/slab.h>
  19#include <asm/setup.h>
  20#include <asm/system.h>
  21#include <asm/page.h>
  22#include <asm/hwtest.h>
  23#include <linux/proc_fs.h>
  24#include <asm/mac_via.h>
  25#include <asm/mac_oss.h>
  26
  27extern void via_nubus_init(void);
  28extern void oss_nubus_init(void);
  29
  30/* Constants */
  31
  32/* This is, of course, the size in bytelanes, rather than the size in
  33   actual bytes */
  34#define FORMAT_BLOCK_SIZE 20
  35#define ROM_DIR_OFFSET 0x24
  36
  37#define NUBUS_TEST_PATTERN 0x5A932BC7
  38
  39/* Define this if you like to live dangerously - it is known not to
  40   work on pretty much every machine except the Quadra 630 and the LC
  41   III. */
  42#undef I_WANT_TO_PROBE_SLOT_ZERO
  43
  44/* This sometimes helps combat failure to boot */
  45#undef TRY_TO_DODGE_WSOD
  46
  47/* Globals */
  48
  49struct nubus_dev*   nubus_devices;
  50struct nubus_board* nubus_boards;
  51
  52/* Meaning of "bytelanes":
  53
  54   The card ROM may appear on any or all bytes of each long word in
  55   NuBus memory.  The low 4 bits of the "map" value found in the
  56   format block (at the top of the slot address space, as well as at
  57   the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
  58   offsets within each longword, are valid.  Thus:
  59
  60   A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
  61   are valid.
  62
  63   A map of 0xf0 means that no bytelanes are valid (We pray that we
  64   will never encounter this, but stranger things have happened)
  65
  66   A map of 0xe1 means that only the MSB of each long word is actually
  67   part of the card ROM.  (We hope to never encounter NuBus on a
  68   little-endian machine.  Again, stranger things have happened)
  69
  70   A map of 0x78 means that only the LSB of each long word is valid.
  71
  72   Etcetera, etcetera.  Hopefully this clears up some confusion over
  73   what the following code actually does.  */
  74 
  75static inline int not_useful(void *p, int map)
  76{
  77	unsigned long pv=(unsigned long)p;
  78	pv &= 3;
  79	if(map & (1<<pv))
  80		return 0;
  81	return 1;
  82}
  83 
  84static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map)
  85{
  86	/* This will hold the result */
  87	unsigned long v = 0;
  88	unsigned char *p = *ptr;
  89
  90	while(len)
  91	{
  92		v <<= 8;
  93		while(not_useful(p,map))
  94			p++;
  95		v |= *p++;
  96		len--;
  97	}
  98	*ptr = p;
  99	return v;
 100}
 101
 102static void nubus_rewind(unsigned char **ptr, int len, int map)
 103{
 104	unsigned char *p=*ptr;
 105
 106	/* Sanity check */
 107	if(len > 65536)
 108		printk(KERN_ERR "rewind of 0x%08x!\n", len);
 109	while(len)
 110	{
 111		do
 112		{
 113			p--;
 114		}
 115		while(not_useful(p, map));
 116		len--;
 117	}
 118	*ptr=p;
 119}
 120
 121static void nubus_advance(unsigned char **ptr, int len, int map)
 122{
 123	unsigned char *p = *ptr;
 124	if(len>65536)
 125		printk(KERN_ERR "advance of 0x%08x!\n", len);
 126	while(len)
 127	{
 128		while(not_useful(p,map))
 129			p++;
 130		p++;
 131		len--;
 132	}
 133	*ptr = p;
 134}
 135
 136static void nubus_move(unsigned char **ptr, int len, int map)
 137{
 138	if(len > 0)
 139		nubus_advance(ptr, len, map);
 140	else if(len < 0)
 141		nubus_rewind(ptr, -len, map);
 142}
 143
 144/* Now, functions to read the sResource tree */
 145
 146/* Each sResource entry consists of a 1-byte ID and a 3-byte data
 147   field.  If that data field contains an offset, then obviously we
 148   have to expand it from a 24-bit signed number to a 32-bit signed
 149   number. */
 150
 151static inline long nubus_expand32(long foo)
 152{
 153	if(foo & 0x00800000)	/* 24bit negative */
 154		foo |= 0xFF000000;
 155	return foo;
 156}
 157
 158static inline void *nubus_rom_addr(int slot)
 159{	
 160	/*
 161	 *	Returns the first byte after the card. We then walk
 162	 *	backwards to get the lane register and the config
 163	 */
 164	return (void *)(0xF1000000+(slot<<24));
 165}
 166
 167static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
 168{
 169	unsigned char *p = nd->base;
 170	/* Essentially, just step over the bytelanes using whatever
 171	   offset we might have found */
 172	nubus_move(&p, nubus_expand32(nd->data), nd->mask);
 173	/* And return the value */
 174	return p;
 175}
 176
 177/* These two are for pulling resource data blocks (i.e. stuff that's
 178   pointed to with offsets) out of the card ROM. */
 179
 180void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent* dirent,
 181			int len)
 182{
 183	unsigned char *t = (unsigned char *)dest;
 184	unsigned char *p = nubus_dirptr(dirent);
 185	while(len)
 186	{
 187		*t++ = nubus_get_rom(&p, 1, dirent->mask);
 188		len--;
 189	}
 190}
 191EXPORT_SYMBOL(nubus_get_rsrc_mem);
 192
 193void nubus_get_rsrc_str(void *dest, const struct nubus_dirent* dirent,
 194			int len)
 195{
 196	unsigned char *t=(unsigned char *)dest;
 197	unsigned char *p = nubus_dirptr(dirent);
 198	while(len)
 199	{
 200		*t = nubus_get_rom(&p, 1, dirent->mask);
 201		if(!*t++)
 202			break;
 203		len--;
 204	}
 205}
 206EXPORT_SYMBOL(nubus_get_rsrc_str);
 207
 208int nubus_get_root_dir(const struct nubus_board* board,
 209		       struct nubus_dir* dir)
 210{
 211	dir->ptr = dir->base = board->directory;
 212	dir->done = 0;
 213	dir->mask = board->lanes;
 214	return 0;
 215}
 216EXPORT_SYMBOL(nubus_get_root_dir);
 217
 218/* This is a slyly renamed version of the above */
 219int nubus_get_func_dir(const struct nubus_dev* dev,
 220		       struct nubus_dir* dir)
 221{
 222	dir->ptr = dir->base = dev->directory;
 223	dir->done = 0;
 224	dir->mask = dev->board->lanes;
 225	return 0;
 226}
 227EXPORT_SYMBOL(nubus_get_func_dir);
 228
 229int nubus_get_board_dir(const struct nubus_board* board,
 230			struct nubus_dir* dir)
 231{
 232	struct nubus_dirent ent;
 233	
 234	dir->ptr = dir->base = board->directory;
 235	dir->done = 0;
 236	dir->mask = board->lanes;
 237
 238	/* Now dereference it (the first directory is always the board
 239	   directory) */
 240	if (nubus_readdir(dir, &ent) == -1)
 241		return -1;
 242	if (nubus_get_subdir(&ent, dir) == -1)
 243		return -1;
 244	return 0;
 245}
 246EXPORT_SYMBOL(nubus_get_board_dir);
 247
 248int nubus_get_subdir(const struct nubus_dirent *ent,
 249		     struct nubus_dir *dir)
 250{
 251	dir->ptr = dir->base = nubus_dirptr(ent);
 252	dir->done = 0;
 253	dir->mask = ent->mask;
 254	return 0;
 255}
 256EXPORT_SYMBOL(nubus_get_subdir);
 257
 258int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
 259{
 260	u32 resid;
 261	if (nd->done)
 262		return -1;
 263
 264	/* Do this first, otherwise nubus_rewind & co are off by 4 */
 265	ent->base = nd->ptr;
 266
 267	/* This moves nd->ptr forward */
 268	resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
 269
 270	/* EOL marker, as per the Apple docs */
 271	if((resid&0xff000000) == 0xff000000)
 272	{
 273		/* Mark it as done */
 274		nd->done = 1;
 275		return -1;
 276	}
 277
 278	/* First byte is the resource ID */
 279	ent->type  = resid >> 24;
 280	/* Low 3 bytes might contain data (or might not) */
 281	ent->data = resid & 0xffffff;
 282	ent->mask  = nd->mask;
 283	return 0;
 284}
 285EXPORT_SYMBOL(nubus_readdir);
 286
 287int nubus_rewinddir(struct nubus_dir* dir)
 288{
 289	dir->ptr = dir->base;
 290	return 0;
 291}
 292EXPORT_SYMBOL(nubus_rewinddir);
 293
 294/* Driver interface functions, more or less like in pci.c */
 295
 296struct nubus_dev*
 297nubus_find_device(unsigned short category,
 298		  unsigned short type,
 299		  unsigned short dr_hw,
 300		  unsigned short dr_sw,
 301		  const struct nubus_dev* from)
 302{
 303	struct nubus_dev* itor =
 304		from ? from->next : nubus_devices;
 305
 306	while (itor) {
 307		if (itor->category == category
 308		    && itor->type == type
 309		    && itor->dr_hw == dr_hw
 310		    && itor->dr_sw == dr_sw)
 311			return itor;
 312		itor = itor->next;
 313	}
 314	return NULL;
 315}
 316EXPORT_SYMBOL(nubus_find_device);
 317
 318struct nubus_dev*
 319nubus_find_type(unsigned short category,
 320		unsigned short type,
 321		const struct nubus_dev* from)
 322{
 323	struct nubus_dev* itor =
 324		from ? from->next : nubus_devices;
 325
 326	while (itor) {
 327		if (itor->category == category
 328		    && itor->type == type)
 329			return itor;
 330		itor = itor->next;
 331	}
 332	return NULL;
 333}
 334EXPORT_SYMBOL(nubus_find_type);
 335
 336struct nubus_dev*
 337nubus_find_slot(unsigned int slot,
 338		const struct nubus_dev* from)
 339{
 340	struct nubus_dev* itor =
 341		from ? from->next : nubus_devices;
 342	
 343	while (itor) {
 344		if (itor->board->slot == slot)
 345			return itor;
 346		itor = itor->next;
 347	}
 348	return NULL;
 349}
 350EXPORT_SYMBOL(nubus_find_slot);
 351
 352int
 353nubus_find_rsrc(struct nubus_dir* dir, unsigned char rsrc_type,
 354		struct nubus_dirent* ent)
 355{
 356	while (nubus_readdir(dir, ent) != -1) {
 357		if (ent->type == rsrc_type)
 358			return 0;
 359	}	
 360	return -1;
 361}
 362EXPORT_SYMBOL(nubus_find_rsrc);
 363
 364/* Initialization functions - decide which slots contain stuff worth
 365   looking at, and print out lots and lots of information from the
 366   resource blocks. */
 367
 368/* FIXME: A lot of this stuff will eventually be useful after
 369   initialization, for intelligently probing Ethernet and video chips,
 370   among other things.  The rest of it should go in the /proc code.
 371   For now, we just use it to give verbose boot logs. */
 372
 373static int __init nubus_show_display_resource(struct nubus_dev* dev,
 374					      const struct nubus_dirent* ent)
 375{
 376	switch (ent->type) {
 377	case NUBUS_RESID_GAMMADIR:
 378		printk(KERN_INFO "    gamma directory offset: 0x%06x\n", ent->data);
 379		break;
 380	case 0x0080 ... 0x0085:
 381		printk(KERN_INFO "    mode %02X info offset: 0x%06x\n",
 382		       ent->type, ent->data);
 383		break;
 384	default:
 385		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 386		       ent->type, ent->data);
 387	}
 388	return 0;
 389}
 390
 391static int __init nubus_show_network_resource(struct nubus_dev* dev,
 392					      const struct nubus_dirent* ent)
 393{
 394	switch (ent->type) {
 395	case NUBUS_RESID_MAC_ADDRESS:
 396	{
 397		char addr[6];
 398		int i;
 399		
 400		nubus_get_rsrc_mem(addr, ent, 6);
 401		printk(KERN_INFO "    MAC address: ");
 402		for (i = 0; i < 6; i++)
 403			printk("%02x%s", addr[i] & 0xff,
 404			       i == 5 ? "" : ":");
 405		printk("\n");
 406		break;
 407	}
 408	default:
 409		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 410		       ent->type, ent->data);
 411	}
 412	return 0;
 413}
 414
 415static int __init nubus_show_cpu_resource(struct nubus_dev* dev,
 416					  const struct nubus_dirent* ent)
 417{
 418	switch (ent->type) {
 419	case NUBUS_RESID_MEMINFO:
 420	{
 421		unsigned long meminfo[2];
 422		nubus_get_rsrc_mem(&meminfo, ent, 8);
 423		printk(KERN_INFO "    memory: [ 0x%08lx 0x%08lx ]\n",
 424		       meminfo[0], meminfo[1]);
 425		break;
 426	}
 427	case NUBUS_RESID_ROMINFO:
 428	{
 429		unsigned long rominfo[2];
 430		nubus_get_rsrc_mem(&rominfo, ent, 8);
 431		printk(KERN_INFO "    ROM:    [ 0x%08lx 0x%08lx ]\n",
 432		       rominfo[0], rominfo[1]);
 433		break;
 434	}
 435	default:
 436		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 437		       ent->type, ent->data);
 438	}
 439	return 0;
 440}
 441
 442static int __init nubus_show_private_resource(struct nubus_dev* dev,
 443					      const struct nubus_dirent* ent)
 444{
 445	switch (dev->category) {
 446	case NUBUS_CAT_DISPLAY:
 447		nubus_show_display_resource(dev, ent);
 448		break;
 449	case NUBUS_CAT_NETWORK:
 450		nubus_show_network_resource(dev, ent);
 451		break;
 452	case NUBUS_CAT_CPU:
 453		nubus_show_cpu_resource(dev, ent);
 454		break;
 455	default:
 456		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 457		       ent->type, ent->data);
 458	}
 459	return 0;
 460}
 461
 462static struct nubus_dev* __init
 463	   nubus_get_functional_resource(struct nubus_board* board,
 464					 int slot,
 465					 const struct nubus_dirent* parent)
 466{
 467	struct nubus_dir    dir;
 468	struct nubus_dirent ent;
 469	struct nubus_dev*   dev;
 470	
 471	printk(KERN_INFO "  Function 0x%02x:\n", parent->type);
 472	nubus_get_subdir(parent, &dir);
 473
 474	/* Apple seems to have botched the ROM on the IIx */
 475	if (slot == 0 && (unsigned long)dir.base % 2)
 476		dir.base += 1;
 477	
 478	if (console_loglevel >= 10)
 479		printk(KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n",
 480		       parent->base, dir.base);
 481
 482	/* Actually we should probably panic if this fails */
 483	if ((dev = kzalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
 484		return NULL;	
 485	dev->resid = parent->type;
 486	dev->directory = dir.base;
 487	dev->board = board;
 488	
 489	while (nubus_readdir(&dir, &ent) != -1)
 490	{
 491		switch(ent.type)
 492		{
 493		case NUBUS_RESID_TYPE:
 494		{
 495			unsigned short nbtdata[4];
 496			nubus_get_rsrc_mem(nbtdata, &ent, 8);
 497			dev->category = nbtdata[0];
 498			dev->type     = nbtdata[1];
 499			dev->dr_sw    = nbtdata[2];
 500			dev->dr_hw    = nbtdata[3];
 501			printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
 502			       nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
 503			break;
 504		}
 505		case NUBUS_RESID_NAME:
 506		{
 507			nubus_get_rsrc_str(dev->name, &ent, 64);
 508			printk(KERN_INFO "    name: %s\n", dev->name);
 509			break;
 510		}
 511		case NUBUS_RESID_DRVRDIR:
 512		{
 513			/* MacOS driver.  If we were NetBSD we might
 514			   use this :-) */
 515			struct nubus_dir drvr_dir;
 516			struct nubus_dirent drvr_ent;
 517			nubus_get_subdir(&ent, &drvr_dir);
 518			nubus_readdir(&drvr_dir, &drvr_ent);
 519			dev->driver = nubus_dirptr(&drvr_ent);
 520			printk(KERN_INFO "    driver at: 0x%p\n",
 521			       dev->driver);
 522			break;
 523		}
 524		case NUBUS_RESID_MINOR_BASEOS:
 525			/* We will need this in order to support
 526			   multiple framebuffers.  It might be handy
 527			   for Ethernet as well */
 528			nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
 529			printk(KERN_INFO "    memory offset: 0x%08lx\n",
 530			       dev->iobase);
 531			break;
 532		case NUBUS_RESID_MINOR_LENGTH:
 533			/* Ditto */
 534			nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
 535			printk(KERN_INFO "    memory length: 0x%08lx\n",
 536			       dev->iosize);
 537			break;			
 538		case NUBUS_RESID_FLAGS:
 539			dev->flags = ent.data;
 540			printk(KERN_INFO "    flags: 0x%06x\n", dev->flags);
 541			break;
 542		case NUBUS_RESID_HWDEVID:
 543			dev->hwdevid = ent.data;
 544			printk(KERN_INFO "    hwdevid: 0x%06x\n", dev->hwdevid);
 545			break;
 546		default:
 547			/* Local/Private resources have their own
 548			   function */
 549			nubus_show_private_resource(dev, &ent);
 550		}
 551	}
 552		
 553	return dev;
 554}
 555
 556/* This is cool. */
 557static int __init nubus_get_vidnames(struct nubus_board* board,
 558				     const struct nubus_dirent* parent)
 559{
 560	struct nubus_dir    dir;
 561	struct nubus_dirent ent;
 562	/* FIXME: obviously we want to put this in a header file soon */
 563	struct vidmode {
 564		u32 size;
 565		/* Don't know what this is yet */
 566		u16 id;
 567		/* Longest one I've seen so far is 26 characters */
 568		char name[32];
 569	};
 570
 571	printk(KERN_INFO "    video modes supported:\n");
 572	nubus_get_subdir(parent, &dir);
 573	if (console_loglevel >= 10)
 574		printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",
 575		       parent->base, dir.base);
 576
 577	while(nubus_readdir(&dir, &ent) != -1)
 578	{
 579		struct vidmode mode;
 580		u32 size;
 581
 582		/* First get the length */
 583		nubus_get_rsrc_mem(&size, &ent, 4);
 584		
 585		/* Now clobber the whole thing */
 586		if (size > sizeof(mode) - 1)
 587			size = sizeof(mode) - 1;
 588		memset(&mode, 0, sizeof(mode));
 589		nubus_get_rsrc_mem(&mode, &ent, size);
 590		printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,
 591			mode.id, mode.name);
 592	}
 593	return 0;
 594}
 595
 596/* This is *really* cool. */
 597static int __init nubus_get_icon(struct nubus_board* board,
 598				 const struct nubus_dirent* ent)
 599{
 600	/* Should be 32x32 if my memory serves me correctly */
 601	unsigned char icon[128];
 602	int x, y;
 603	
 604	nubus_get_rsrc_mem(&icon, ent, 128);
 605	printk(KERN_INFO "    icon:\n");
 606
 607	/* We should actually plot these somewhere in the framebuffer
 608	   init.  This is just to demonstrate that they do, in fact,
 609	   exist */
 610	for (y = 0; y < 32; y++) {
 611		printk(KERN_INFO "      ");
 612		for (x = 0; x < 32; x++) {
 613			if (icon[y*4 + x/8]
 614			    & (0x80 >> (x%8)))
 615				printk("*");
 616			else
 617				printk(" ");
 618		}
 619		printk("\n");
 620	}
 621	return 0;
 622}
 623
 624static int __init nubus_get_vendorinfo(struct nubus_board* board,
 625				       const struct nubus_dirent* parent)
 626{
 627	struct nubus_dir    dir;
 628	struct nubus_dirent ent;
 629	static char* vendor_fields[6] = {"ID", "serial", "revision",
 630					 "part", "date", "unknown field"};
 631
 632	printk(KERN_INFO "    vendor info:\n");
 633	nubus_get_subdir(parent, &dir);
 634	if (console_loglevel >= 10)
 635		printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",
 636		       parent->base, dir.base);
 637
 638	while(nubus_readdir(&dir, &ent) != -1)
 639	{
 640		char name[64];
 641		
 642		/* These are all strings, we think */
 643		nubus_get_rsrc_str(name, &ent, 64);
 644		if (ent.type > 5)
 645			ent.type = 5;
 646		printk(KERN_INFO "    %s: %s\n",
 647		       vendor_fields[ent.type-1], name);
 648	}
 649	return 0;
 650}
 651
 652static int __init nubus_get_board_resource(struct nubus_board* board, int slot,
 653					   const struct nubus_dirent* parent)
 654{
 655	struct nubus_dir    dir;
 656	struct nubus_dirent ent;
 657	
 658	nubus_get_subdir(parent, &dir);
 659	if (console_loglevel >= 10)
 660		printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
 661		       parent->base, dir.base);
 662
 663	while(nubus_readdir(&dir, &ent) != -1)
 664	{
 665		switch (ent.type) {
 666		case NUBUS_RESID_TYPE:
 667		{
 668			unsigned short nbtdata[4];
 669			/* This type is always the same, and is not
 670			   useful except insofar as it tells us that
 671			   we really are looking at a board resource. */
 672			nubus_get_rsrc_mem(nbtdata, &ent, 8);
 673			printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
 674			       nbtdata[0], nbtdata[1], nbtdata[2],
 675			       nbtdata[3]);
 676			if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
 677			    nbtdata[2] != 0 || nbtdata[3] != 0)
 678				printk(KERN_ERR "this sResource is not a board resource!\n");
 679			break;
 680		}
 681		case NUBUS_RESID_NAME:
 682			nubus_get_rsrc_str(board->name, &ent, 64);
 683			printk(KERN_INFO "    name: %s\n", board->name);
 684			break;
 685		case NUBUS_RESID_ICON:
 686			nubus_get_icon(board, &ent);
 687			break;
 688		case NUBUS_RESID_BOARDID:
 689			printk(KERN_INFO "    board id: 0x%x\n", ent.data);
 690			break;
 691		case NUBUS_RESID_PRIMARYINIT:
 692			printk(KERN_INFO "    primary init offset: 0x%06x\n", ent.data);
 693			break;
 694		case NUBUS_RESID_VENDORINFO:
 695			nubus_get_vendorinfo(board, &ent);
 696			break;
 697		case NUBUS_RESID_FLAGS:
 698			printk(KERN_INFO "    flags: 0x%06x\n", ent.data);
 699			break;
 700		case NUBUS_RESID_HWDEVID:
 701			printk(KERN_INFO "    hwdevid: 0x%06x\n", ent.data);
 702			break;
 703		case NUBUS_RESID_SECONDINIT:
 704			printk(KERN_INFO "    secondary init offset: 0x%06x\n", ent.data);
 705			break;
 706			/* WTF isn't this in the functional resources? */ 
 707		case NUBUS_RESID_VIDNAMES:
 708			nubus_get_vidnames(board, &ent);
 709			break;
 710			/* Same goes for this */
 711		case NUBUS_RESID_VIDMODES:
 712			printk(KERN_INFO "    video mode parameter directory offset: 0x%06x\n",
 713			       ent.data);
 714			break;			
 715		default:
 716			printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 717			       ent.type, ent.data);
 718		}
 719	}
 720	return 0;
 721}
 722
 723/* Attempt to bypass the somewhat non-obvious arrangement of
 724   sResources in the motherboard ROM */
 725static void __init nubus_find_rom_dir(struct nubus_board* board)
 726{
 727	unsigned char* rp;
 728	unsigned char* romdir;
 729	struct nubus_dir dir;
 730	struct nubus_dirent ent;
 731
 732	/* Check for the extra directory just under the format block */
 733	rp = board->fblock;
 734	nubus_rewind(&rp, 4, board->lanes);
 735	if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {
 736		/* OK, the ROM was telling the truth */
 737		board->directory = board->fblock;
 738		nubus_move(&board->directory,
 739			   nubus_expand32(board->doffset),
 740			   board->lanes);
 741		return;
 742	}
 743
 744	/* On "slot zero", you have to walk down a few more
 745	   directories to get to the equivalent of a real card's root
 746	   directory.  We don't know what they were smoking when they
 747	   came up with this. */
 748	romdir = nubus_rom_addr(board->slot);
 749	nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);
 750	dir.base = dir.ptr = romdir;
 751	dir.done = 0;
 752	dir.mask = board->lanes;
 753
 754	/* This one points to an "Unknown Macintosh" directory */
 755	if (nubus_readdir(&dir, &ent) == -1)
 756		goto badrom;
 757
 758	if (console_loglevel >= 10)
 759		printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 760	/* This one takes us to where we want to go. */
 761	if (nubus_readdir(&dir, &ent) == -1) 
 762		goto badrom;
 763	if (console_loglevel >= 10)
 764		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 765	nubus_get_subdir(&ent, &dir);
 766
 767	/* Resource ID 01, also an "Unknown Macintosh" */
 768	if (nubus_readdir(&dir, &ent) == -1) 
 769		goto badrom;
 770	if (console_loglevel >= 10)
 771		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 772
 773	/* FIXME: the first one is *not* always the right one.  We
 774	   suspect this has something to do with the ROM revision.
 775	   "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR
 776	   Continues" (Q630) uses 0x7b.  The DAFB Macs evidently use
 777	   something else.  Please run "Slots" on your Mac (see
 778	   include/linux/nubus.h for where to get this program) and
 779	   tell us where the 'SiDirPtr' for Slot 0 is.  If you feel
 780	   brave, you should also use MacsBug to walk down the ROM
 781	   directories like this function does and try to find the
 782	   path to that address... */
 783	if (nubus_readdir(&dir, &ent) == -1)
 784		goto badrom;
 785	if (console_loglevel >= 10)
 786		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 787	
 788	/* Bwahahahaha... */
 789	nubus_get_subdir(&ent, &dir);
 790	board->directory = dir.base;
 791	return;
 792	
 793	/* Even more evil laughter... */
 794 badrom:
 795	board->directory = board->fblock;
 796	nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);
 797	printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness!  Notify the developers...\n");
 798}
 799
 800/* Add a board (might be many devices) to the list */
 801static struct nubus_board* __init nubus_add_board(int slot, int bytelanes)
 802{
 803	struct nubus_board* board;
 804	struct nubus_board** boardp;
 805
 806	unsigned char *rp;
 807	unsigned long dpat;
 808	struct nubus_dir dir;
 809	struct nubus_dirent ent;
 810
 811	/* Move to the start of the format block */
 812	rp = nubus_rom_addr(slot);		
 813	nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
 814
 815	/* Actually we should probably panic if this fails */
 816	if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
 817		return NULL;	
 818	board->fblock = rp;
 819
 820	/* Dump the format block for debugging purposes */
 821	if (console_loglevel >= 10) {
 822		int i;
 823		printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",
 824		       slot, rp);
 825		printk(KERN_DEBUG "Format block: ");
 826		for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {
 827			unsigned short foo, bar;
 828			foo = nubus_get_rom(&rp, 2, bytelanes);
 829			bar = nubus_get_rom(&rp, 2, bytelanes);
 830			printk("%04x %04x  ", foo, bar);
 831		}
 832		printk("\n");
 833		rp = board->fblock;
 834	}
 835	
 836	board->slot = slot;
 837	board->slot_addr = (unsigned long) nubus_slot_addr(slot);
 838	board->doffset = nubus_get_rom(&rp, 4, bytelanes);
 839	/* rom_length is *supposed* to be the total length of the
 840	 * ROM.  In practice it is the "amount of ROM used to compute
 841	 * the CRC."  So some jokers decide to set it to zero and
 842	 * set the crc to zero so they don't have to do any math.
 843	 * See the Performa 460 ROM, for example.  Those Apple "engineers".
 844	 */
 845	board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
 846	board->crc = nubus_get_rom(&rp, 4, bytelanes);
 847	board->rev = nubus_get_rom(&rp, 1, bytelanes);
 848	board->format = nubus_get_rom(&rp,1, bytelanes);
 849	board->lanes = bytelanes;
 850
 851	/* Directory offset should be small and negative... */
 852	if(!(board->doffset & 0x00FF0000))
 853		printk(KERN_WARNING "Dodgy doffset!\n");
 854	dpat = nubus_get_rom(&rp, 4, bytelanes);
 855	if(dpat != NUBUS_TEST_PATTERN)
 856		printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);
 857		
 858	/*
 859	 *	I wonder how the CRC is meant to work -
 860	 *		any takers ?
 861	 * CSA: According to MAC docs, not all cards pass the CRC anyway,
 862	 * since the initial Macintosh ROM releases skipped the check.
 863	 */
 864
 865	/* Attempt to work around slot zero weirdness */
 866	nubus_find_rom_dir(board);
 867	nubus_get_root_dir(board, &dir);	
 868
 869	/* We're ready to rock */
 870	printk(KERN_INFO "Slot %X:\n", slot);
 871
 872	/* Each slot should have one board resource and any number of
 873	   functional resources.  So we'll fill in some fields in the
 874	   struct nubus_board from the board resource, then walk down
 875	   the list of functional resources, spinning out a nubus_dev
 876	   for each of them. */
 877	if (nubus_readdir(&dir, &ent) == -1) {
 878		/* We can't have this! */
 879		printk(KERN_ERR "Board resource not found!\n");
 880		return NULL;
 881	} else {
 882		printk(KERN_INFO "  Board resource:\n");
 883		nubus_get_board_resource(board, slot, &ent);
 884	}
 885
 886	/* Aaaarrrrgghh!  The LC III motherboard has *two* board
 887	   resources.  I have no idea WTF to do about this. */
 888
 889	while (nubus_readdir(&dir, &ent) != -1) {
 890		struct nubus_dev*  dev;
 891		struct nubus_dev** devp;
 892		dev = nubus_get_functional_resource(board, slot, &ent);
 893		if (dev == NULL)
 894			continue;
 895
 896		/* We zeroed this out above */
 897		if (board->first_dev == NULL)
 898			board->first_dev = dev;
 899		
 900		/* Put it on the global NuBus device chain. Keep entries in order. */
 901		for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))
 902			/* spin */;
 903		*devp = dev;
 904		dev->next = NULL;		
 905	}
 906
 907	/* Put it on the global NuBus board chain. Keep entries in order. */
 908	for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))
 909		/* spin */;
 910	*boardp = board;
 911	board->next = NULL;
 912	
 913	return board;
 914}
 915
 916void __init nubus_probe_slot(int slot)
 917{
 918	unsigned char dp;
 919	unsigned char* rp;
 920	int i;
 921
 922	rp = nubus_rom_addr(slot);	
 923	for(i = 4; i; i--)
 924	{
 925		unsigned long flags;
 926		int card_present;
 927
 928		rp--;
 929		local_irq_save(flags);
 930		card_present = hwreg_present(rp);
 931		local_irq_restore(flags);
 932	       
 933		if (!card_present)
 934			continue;
 935
 936		printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);
 937		dp = *rp;
 938		if(dp == 0)
 939			continue;
 940
 941		/* The last byte of the format block consists of two
 942		   nybbles which are "mirror images" of each other.
 943		   These show us the valid bytelanes */
 944		if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
 945			continue;
 946		/* Check that this value is actually *on* one of the
 947		   bytelanes it claims are valid! */
 948		if ((dp & 0x0F) >= (1<<i))
 949			continue;
 950
 951		/* Looks promising.  Let's put it on the list. */
 952		nubus_add_board(slot, dp);
 953
 954		return;
 955	}
 956}
 957
 958#if defined(CONFIG_PROC_FS)
 959
 960/* /proc/nubus stuff */
 961
 962static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
 963{
 964	if(len < 100)
 965		return -1;
 966	
 967	sprintf(ptr, "Slot %X: %s\n",
 968		board->slot, board->name);
 969	
 970	return strlen(ptr);
 971}
 972
 973static int nubus_read_proc(char *page, char **start, off_t off,
 974				int count, int *eof, void *data)
 975{
 976	int nprinted, len, begin = 0;
 977	int size = PAGE_SIZE;
 978	struct nubus_board* board;
 979	
 980	len   = sprintf(page, "Nubus devices found:\n");
 981	/* Walk the list of NuBus boards */
 982	for (board = nubus_boards; board != NULL; board = board->next)
 983	{
 984		nprinted = sprint_nubus_board(board, page + len, size - len);
 985		if (nprinted < 0)
 986			break;
 987		len += nprinted;
 988		if (len+begin < off) {
 989			begin += len;
 990			len = 0;
 991		}
 992		if (len+begin >= off+count)
 993			break;
 994	}
 995	if (len+begin < off)
 996		*eof = 1;
 997	off -= begin;
 998	*start = page + off;
 999	len -= off;
1000	if (len>count)
1001		len = count;
1002	if (len<0)
1003		len = 0;
1004	return len;
1005}
1006#endif
1007
1008void __init nubus_scan_bus(void)
1009{
1010	int slot;
1011	/* This might not work on your machine */
1012#ifdef I_WANT_TO_PROBE_SLOT_ZERO
1013	nubus_probe_slot(0);
1014#endif
1015	for(slot = 9; slot < 15; slot++)
1016	{
1017		nubus_probe_slot(slot);
1018	}
1019}
1020
1021static int __init nubus_init(void)
1022{
1023	if (!MACH_IS_MAC) 
1024		return 0;
1025
1026	/* Initialize the NuBus interrupts */
1027	if (oss_present) {
1028		oss_nubus_init();
1029	} else {
1030		via_nubus_init();
1031	}
1032
1033#ifdef TRY_TO_DODGE_WSOD
1034	/* Rogue Ethernet interrupts can kill the machine if we don't
1035	   do this.  Obviously this is bogus.  Hopefully the local VIA
1036	   gurus can fix the real cause of the problem. */
1037	mdelay(1000);
1038#endif
1039	
1040	/* And probe */
1041	printk("NuBus: Scanning NuBus slots.\n");
1042	nubus_devices = NULL;
1043	nubus_boards  = NULL;
1044	nubus_scan_bus();
1045
1046#ifdef CONFIG_PROC_FS
1047	create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
1048	nubus_proc_init();
1049#endif
1050	return 0;
1051}
1052
1053subsys_initcall(nubus_init);
v3.1
   1/*
   2 *	Macintosh Nubus Interface Code
   3 *
   4 *      Originally by Alan Cox
   5 *
   6 *      Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
   7 *      and others.
   8 */
   9
  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>
  15#include <linux/init.h>
  16#include <linux/delay.h>
  17#include <linux/module.h>
  18#include <linux/slab.h>
  19#include <asm/setup.h>
  20#include <asm/system.h>
  21#include <asm/page.h>
  22#include <asm/hwtest.h>
  23#include <linux/proc_fs.h>
  24#include <asm/mac_via.h>
  25#include <asm/mac_oss.h>
  26
  27extern void via_nubus_init(void);
  28extern void oss_nubus_init(void);
  29
  30/* Constants */
  31
  32/* This is, of course, the size in bytelanes, rather than the size in
  33   actual bytes */
  34#define FORMAT_BLOCK_SIZE 20
  35#define ROM_DIR_OFFSET 0x24
  36
  37#define NUBUS_TEST_PATTERN 0x5A932BC7
  38
  39/* Define this if you like to live dangerously - it is known not to
  40   work on pretty much every machine except the Quadra 630 and the LC
  41   III. */
  42#undef I_WANT_TO_PROBE_SLOT_ZERO
  43
  44/* This sometimes helps combat failure to boot */
  45#undef TRY_TO_DODGE_WSOD
  46
  47/* Globals */
  48
  49struct nubus_dev*   nubus_devices;
  50struct nubus_board* nubus_boards;
  51
  52/* Meaning of "bytelanes":
  53
  54   The card ROM may appear on any or all bytes of each long word in
  55   NuBus memory.  The low 4 bits of the "map" value found in the
  56   format block (at the top of the slot address space, as well as at
  57   the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
  58   offsets within each longword, are valid.  Thus:
  59
  60   A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
  61   are valid.
  62
  63   A map of 0xf0 means that no bytelanes are valid (We pray that we
  64   will never encounter this, but stranger things have happened)
  65
  66   A map of 0xe1 means that only the MSB of each long word is actually
  67   part of the card ROM.  (We hope to never encounter NuBus on a
  68   little-endian machine.  Again, stranger things have happened)
  69
  70   A map of 0x78 means that only the LSB of each long word is valid.
  71
  72   Etcetera, etcetera.  Hopefully this clears up some confusion over
  73   what the following code actually does.  */
  74 
  75static inline int not_useful(void *p, int map)
  76{
  77	unsigned long pv=(unsigned long)p;
  78	pv &= 3;
  79	if(map & (1<<pv))
  80		return 0;
  81	return 1;
  82}
  83 
  84static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map)
  85{
  86	/* This will hold the result */
  87	unsigned long v = 0;
  88	unsigned char *p = *ptr;
  89
  90	while(len)
  91	{
  92		v <<= 8;
  93		while(not_useful(p,map))
  94			p++;
  95		v |= *p++;
  96		len--;
  97	}
  98	*ptr = p;
  99	return v;
 100}
 101
 102static void nubus_rewind(unsigned char **ptr, int len, int map)
 103{
 104	unsigned char *p=*ptr;
 105
 106	/* Sanity check */
 107	if(len > 65536)
 108		printk(KERN_ERR "rewind of 0x%08x!\n", len);
 109	while(len)
 110	{
 111		do
 112		{
 113			p--;
 114		}
 115		while(not_useful(p, map));
 116		len--;
 117	}
 118	*ptr=p;
 119}
 120
 121static void nubus_advance(unsigned char **ptr, int len, int map)
 122{
 123	unsigned char *p = *ptr;
 124	if(len>65536)
 125		printk(KERN_ERR "advance of 0x%08x!\n", len);
 126	while(len)
 127	{
 128		while(not_useful(p,map))
 129			p++;
 130		p++;
 131		len--;
 132	}
 133	*ptr = p;
 134}
 135
 136static void nubus_move(unsigned char **ptr, int len, int map)
 137{
 138	if(len > 0)
 139		nubus_advance(ptr, len, map);
 140	else if(len < 0)
 141		nubus_rewind(ptr, -len, map);
 142}
 143
 144/* Now, functions to read the sResource tree */
 145
 146/* Each sResource entry consists of a 1-byte ID and a 3-byte data
 147   field.  If that data field contains an offset, then obviously we
 148   have to expand it from a 24-bit signed number to a 32-bit signed
 149   number. */
 150
 151static inline long nubus_expand32(long foo)
 152{
 153	if(foo & 0x00800000)	/* 24bit negative */
 154		foo |= 0xFF000000;
 155	return foo;
 156}
 157
 158static inline void *nubus_rom_addr(int slot)
 159{	
 160	/*
 161	 *	Returns the first byte after the card. We then walk
 162	 *	backwards to get the lane register and the config
 163	 */
 164	return (void *)(0xF1000000+(slot<<24));
 165}
 166
 167static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
 168{
 169	unsigned char *p = nd->base;
 170	/* Essentially, just step over the bytelanes using whatever
 171	   offset we might have found */
 172	nubus_move(&p, nubus_expand32(nd->data), nd->mask);
 173	/* And return the value */
 174	return p;
 175}
 176
 177/* These two are for pulling resource data blocks (i.e. stuff that's
 178   pointed to with offsets) out of the card ROM. */
 179
 180void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent* dirent,
 181			int len)
 182{
 183	unsigned char *t = (unsigned char *)dest;
 184	unsigned char *p = nubus_dirptr(dirent);
 185	while(len)
 186	{
 187		*t++ = nubus_get_rom(&p, 1, dirent->mask);
 188		len--;
 189	}
 190}
 191EXPORT_SYMBOL(nubus_get_rsrc_mem);
 192
 193void nubus_get_rsrc_str(void *dest, const struct nubus_dirent* dirent,
 194			int len)
 195{
 196	unsigned char *t=(unsigned char *)dest;
 197	unsigned char *p = nubus_dirptr(dirent);
 198	while(len)
 199	{
 200		*t = nubus_get_rom(&p, 1, dirent->mask);
 201		if(!*t++)
 202			break;
 203		len--;
 204	}
 205}
 206EXPORT_SYMBOL(nubus_get_rsrc_str);
 207
 208int nubus_get_root_dir(const struct nubus_board* board,
 209		       struct nubus_dir* dir)
 210{
 211	dir->ptr = dir->base = board->directory;
 212	dir->done = 0;
 213	dir->mask = board->lanes;
 214	return 0;
 215}
 216EXPORT_SYMBOL(nubus_get_root_dir);
 217
 218/* This is a slyly renamed version of the above */
 219int nubus_get_func_dir(const struct nubus_dev* dev,
 220		       struct nubus_dir* dir)
 221{
 222	dir->ptr = dir->base = dev->directory;
 223	dir->done = 0;
 224	dir->mask = dev->board->lanes;
 225	return 0;
 226}
 227EXPORT_SYMBOL(nubus_get_func_dir);
 228
 229int nubus_get_board_dir(const struct nubus_board* board,
 230			struct nubus_dir* dir)
 231{
 232	struct nubus_dirent ent;
 233	
 234	dir->ptr = dir->base = board->directory;
 235	dir->done = 0;
 236	dir->mask = board->lanes;
 237
 238	/* Now dereference it (the first directory is always the board
 239	   directory) */
 240	if (nubus_readdir(dir, &ent) == -1)
 241		return -1;
 242	if (nubus_get_subdir(&ent, dir) == -1)
 243		return -1;
 244	return 0;
 245}
 246EXPORT_SYMBOL(nubus_get_board_dir);
 247
 248int nubus_get_subdir(const struct nubus_dirent *ent,
 249		     struct nubus_dir *dir)
 250{
 251	dir->ptr = dir->base = nubus_dirptr(ent);
 252	dir->done = 0;
 253	dir->mask = ent->mask;
 254	return 0;
 255}
 256EXPORT_SYMBOL(nubus_get_subdir);
 257
 258int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
 259{
 260	u32 resid;
 261	if (nd->done)
 262		return -1;
 263
 264	/* Do this first, otherwise nubus_rewind & co are off by 4 */
 265	ent->base = nd->ptr;
 266
 267	/* This moves nd->ptr forward */
 268	resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
 269
 270	/* EOL marker, as per the Apple docs */
 271	if((resid&0xff000000) == 0xff000000)
 272	{
 273		/* Mark it as done */
 274		nd->done = 1;
 275		return -1;
 276	}
 277
 278	/* First byte is the resource ID */
 279	ent->type  = resid >> 24;
 280	/* Low 3 bytes might contain data (or might not) */
 281	ent->data = resid & 0xffffff;
 282	ent->mask  = nd->mask;
 283	return 0;
 284}
 285EXPORT_SYMBOL(nubus_readdir);
 286
 287int nubus_rewinddir(struct nubus_dir* dir)
 288{
 289	dir->ptr = dir->base;
 290	return 0;
 291}
 292EXPORT_SYMBOL(nubus_rewinddir);
 293
 294/* Driver interface functions, more or less like in pci.c */
 295
 296struct nubus_dev*
 297nubus_find_device(unsigned short category,
 298		  unsigned short type,
 299		  unsigned short dr_hw,
 300		  unsigned short dr_sw,
 301		  const struct nubus_dev* from)
 302{
 303	struct nubus_dev* itor =
 304		from ? from->next : nubus_devices;
 305
 306	while (itor) {
 307		if (itor->category == category
 308		    && itor->type == type
 309		    && itor->dr_hw == dr_hw
 310		    && itor->dr_sw == dr_sw)
 311			return itor;
 312		itor = itor->next;
 313	}
 314	return NULL;
 315}
 316EXPORT_SYMBOL(nubus_find_device);
 317
 318struct nubus_dev*
 319nubus_find_type(unsigned short category,
 320		unsigned short type,
 321		const struct nubus_dev* from)
 322{
 323	struct nubus_dev* itor =
 324		from ? from->next : nubus_devices;
 325
 326	while (itor) {
 327		if (itor->category == category
 328		    && itor->type == type)
 329			return itor;
 330		itor = itor->next;
 331	}
 332	return NULL;
 333}
 334EXPORT_SYMBOL(nubus_find_type);
 335
 336struct nubus_dev*
 337nubus_find_slot(unsigned int slot,
 338		const struct nubus_dev* from)
 339{
 340	struct nubus_dev* itor =
 341		from ? from->next : nubus_devices;
 342	
 343	while (itor) {
 344		if (itor->board->slot == slot)
 345			return itor;
 346		itor = itor->next;
 347	}
 348	return NULL;
 349}
 350EXPORT_SYMBOL(nubus_find_slot);
 351
 352int
 353nubus_find_rsrc(struct nubus_dir* dir, unsigned char rsrc_type,
 354		struct nubus_dirent* ent)
 355{
 356	while (nubus_readdir(dir, ent) != -1) {
 357		if (ent->type == rsrc_type)
 358			return 0;
 359	}	
 360	return -1;
 361}
 362EXPORT_SYMBOL(nubus_find_rsrc);
 363
 364/* Initialization functions - decide which slots contain stuff worth
 365   looking at, and print out lots and lots of information from the
 366   resource blocks. */
 367
 368/* FIXME: A lot of this stuff will eventually be useful after
 369   initialization, for intelligently probing Ethernet and video chips,
 370   among other things.  The rest of it should go in the /proc code.
 371   For now, we just use it to give verbose boot logs. */
 372
 373static int __init nubus_show_display_resource(struct nubus_dev* dev,
 374					      const struct nubus_dirent* ent)
 375{
 376	switch (ent->type) {
 377	case NUBUS_RESID_GAMMADIR:
 378		printk(KERN_INFO "    gamma directory offset: 0x%06x\n", ent->data);
 379		break;
 380	case 0x0080 ... 0x0085:
 381		printk(KERN_INFO "    mode %02X info offset: 0x%06x\n",
 382		       ent->type, ent->data);
 383		break;
 384	default:
 385		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 386		       ent->type, ent->data);
 387	}
 388	return 0;
 389}
 390
 391static int __init nubus_show_network_resource(struct nubus_dev* dev,
 392					      const struct nubus_dirent* ent)
 393{
 394	switch (ent->type) {
 395	case NUBUS_RESID_MAC_ADDRESS:
 396	{
 397		char addr[6];
 398		int i;
 399		
 400		nubus_get_rsrc_mem(addr, ent, 6);
 401		printk(KERN_INFO "    MAC address: ");
 402		for (i = 0; i < 6; i++)
 403			printk("%02x%s", addr[i] & 0xff,
 404			       i == 5 ? "" : ":");
 405		printk("\n");
 406		break;
 407	}
 408	default:
 409		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 410		       ent->type, ent->data);
 411	}
 412	return 0;
 413}
 414
 415static int __init nubus_show_cpu_resource(struct nubus_dev* dev,
 416					  const struct nubus_dirent* ent)
 417{
 418	switch (ent->type) {
 419	case NUBUS_RESID_MEMINFO:
 420	{
 421		unsigned long meminfo[2];
 422		nubus_get_rsrc_mem(&meminfo, ent, 8);
 423		printk(KERN_INFO "    memory: [ 0x%08lx 0x%08lx ]\n",
 424		       meminfo[0], meminfo[1]);
 425		break;
 426	}
 427	case NUBUS_RESID_ROMINFO:
 428	{
 429		unsigned long rominfo[2];
 430		nubus_get_rsrc_mem(&rominfo, ent, 8);
 431		printk(KERN_INFO "    ROM:    [ 0x%08lx 0x%08lx ]\n",
 432		       rominfo[0], rominfo[1]);
 433		break;
 434	}
 435	default:
 436		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 437		       ent->type, ent->data);
 438	}
 439	return 0;
 440}
 441
 442static int __init nubus_show_private_resource(struct nubus_dev* dev,
 443					      const struct nubus_dirent* ent)
 444{
 445	switch (dev->category) {
 446	case NUBUS_CAT_DISPLAY:
 447		nubus_show_display_resource(dev, ent);
 448		break;
 449	case NUBUS_CAT_NETWORK:
 450		nubus_show_network_resource(dev, ent);
 451		break;
 452	case NUBUS_CAT_CPU:
 453		nubus_show_cpu_resource(dev, ent);
 454		break;
 455	default:
 456		printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 457		       ent->type, ent->data);
 458	}
 459	return 0;
 460}
 461
 462static struct nubus_dev* __init
 463	   nubus_get_functional_resource(struct nubus_board* board,
 464					 int slot,
 465					 const struct nubus_dirent* parent)
 466{
 467	struct nubus_dir    dir;
 468	struct nubus_dirent ent;
 469	struct nubus_dev*   dev;
 470	
 471	printk(KERN_INFO "  Function 0x%02x:\n", parent->type);
 472	nubus_get_subdir(parent, &dir);
 473
 474	/* Apple seems to have botched the ROM on the IIx */
 475	if (slot == 0 && (unsigned long)dir.base % 2)
 476		dir.base += 1;
 477	
 478	if (console_loglevel >= 10)
 479		printk(KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n",
 480		       parent->base, dir.base);
 481
 482	/* Actually we should probably panic if this fails */
 483	if ((dev = kzalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
 484		return NULL;	
 485	dev->resid = parent->type;
 486	dev->directory = dir.base;
 487	dev->board = board;
 488	
 489	while (nubus_readdir(&dir, &ent) != -1)
 490	{
 491		switch(ent.type)
 492		{
 493		case NUBUS_RESID_TYPE:
 494		{
 495			unsigned short nbtdata[4];
 496			nubus_get_rsrc_mem(nbtdata, &ent, 8);
 497			dev->category = nbtdata[0];
 498			dev->type     = nbtdata[1];
 499			dev->dr_sw    = nbtdata[2];
 500			dev->dr_hw    = nbtdata[3];
 501			printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
 502			       nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
 503			break;
 504		}
 505		case NUBUS_RESID_NAME:
 506		{
 507			nubus_get_rsrc_str(dev->name, &ent, 64);
 508			printk(KERN_INFO "    name: %s\n", dev->name);
 509			break;
 510		}
 511		case NUBUS_RESID_DRVRDIR:
 512		{
 513			/* MacOS driver.  If we were NetBSD we might
 514			   use this :-) */
 515			struct nubus_dir drvr_dir;
 516			struct nubus_dirent drvr_ent;
 517			nubus_get_subdir(&ent, &drvr_dir);
 518			nubus_readdir(&drvr_dir, &drvr_ent);
 519			dev->driver = nubus_dirptr(&drvr_ent);
 520			printk(KERN_INFO "    driver at: 0x%p\n",
 521			       dev->driver);
 522			break;
 523		}
 524		case NUBUS_RESID_MINOR_BASEOS:
 525			/* We will need this in order to support
 526			   multiple framebuffers.  It might be handy
 527			   for Ethernet as well */
 528			nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
 529			printk(KERN_INFO "    memory offset: 0x%08lx\n",
 530			       dev->iobase);
 531			break;
 532		case NUBUS_RESID_MINOR_LENGTH:
 533			/* Ditto */
 534			nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
 535			printk(KERN_INFO "    memory length: 0x%08lx\n",
 536			       dev->iosize);
 537			break;			
 538		case NUBUS_RESID_FLAGS:
 539			dev->flags = ent.data;
 540			printk(KERN_INFO "    flags: 0x%06x\n", dev->flags);
 541			break;
 542		case NUBUS_RESID_HWDEVID:
 543			dev->hwdevid = ent.data;
 544			printk(KERN_INFO "    hwdevid: 0x%06x\n", dev->hwdevid);
 545			break;
 546		default:
 547			/* Local/Private resources have their own
 548			   function */
 549			nubus_show_private_resource(dev, &ent);
 550		}
 551	}
 552		
 553	return dev;
 554}
 555
 556/* This is cool. */
 557static int __init nubus_get_vidnames(struct nubus_board* board,
 558				     const struct nubus_dirent* parent)
 559{
 560	struct nubus_dir    dir;
 561	struct nubus_dirent ent;
 562	/* FIXME: obviously we want to put this in a header file soon */
 563	struct vidmode {
 564		u32 size;
 565		/* Don't know what this is yet */
 566		u16 id;
 567		/* Longest one I've seen so far is 26 characters */
 568		char name[32];
 569	};
 570
 571	printk(KERN_INFO "    video modes supported:\n");
 572	nubus_get_subdir(parent, &dir);
 573	if (console_loglevel >= 10)
 574		printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",
 575		       parent->base, dir.base);
 576
 577	while(nubus_readdir(&dir, &ent) != -1)
 578	{
 579		struct vidmode mode;
 580		u32 size;
 581
 582		/* First get the length */
 583		nubus_get_rsrc_mem(&size, &ent, 4);
 584		
 585		/* Now clobber the whole thing */
 586		if (size > sizeof(mode) - 1)
 587			size = sizeof(mode) - 1;
 588		memset(&mode, 0, sizeof(mode));
 589		nubus_get_rsrc_mem(&mode, &ent, size);
 590		printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,
 591			mode.id, mode.name);
 592	}
 593	return 0;
 594}
 595
 596/* This is *really* cool. */
 597static int __init nubus_get_icon(struct nubus_board* board,
 598				 const struct nubus_dirent* ent)
 599{
 600	/* Should be 32x32 if my memory serves me correctly */
 601	unsigned char icon[128];
 602	int x, y;
 603	
 604	nubus_get_rsrc_mem(&icon, ent, 128);
 605	printk(KERN_INFO "    icon:\n");
 606
 607	/* We should actually plot these somewhere in the framebuffer
 608	   init.  This is just to demonstrate that they do, in fact,
 609	   exist */
 610	for (y = 0; y < 32; y++) {
 611		printk(KERN_INFO "      ");
 612		for (x = 0; x < 32; x++) {
 613			if (icon[y*4 + x/8]
 614			    & (0x80 >> (x%8)))
 615				printk("*");
 616			else
 617				printk(" ");
 618		}
 619		printk("\n");
 620	}
 621	return 0;
 622}
 623
 624static int __init nubus_get_vendorinfo(struct nubus_board* board,
 625				       const struct nubus_dirent* parent)
 626{
 627	struct nubus_dir    dir;
 628	struct nubus_dirent ent;
 629	static char* vendor_fields[6] = {"ID", "serial", "revision",
 630					 "part", "date", "unknown field"};
 631
 632	printk(KERN_INFO "    vendor info:\n");
 633	nubus_get_subdir(parent, &dir);
 634	if (console_loglevel >= 10)
 635		printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",
 636		       parent->base, dir.base);
 637
 638	while(nubus_readdir(&dir, &ent) != -1)
 639	{
 640		char name[64];
 641		
 642		/* These are all strings, we think */
 643		nubus_get_rsrc_str(name, &ent, 64);
 644		if (ent.type > 5)
 645			ent.type = 5;
 646		printk(KERN_INFO "    %s: %s\n",
 647		       vendor_fields[ent.type-1], name);
 648	}
 649	return 0;
 650}
 651
 652static int __init nubus_get_board_resource(struct nubus_board* board, int slot,
 653					   const struct nubus_dirent* parent)
 654{
 655	struct nubus_dir    dir;
 656	struct nubus_dirent ent;
 657	
 658	nubus_get_subdir(parent, &dir);
 659	if (console_loglevel >= 10)
 660		printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
 661		       parent->base, dir.base);
 662
 663	while(nubus_readdir(&dir, &ent) != -1)
 664	{
 665		switch (ent.type) {
 666		case NUBUS_RESID_TYPE:
 667		{
 668			unsigned short nbtdata[4];
 669			/* This type is always the same, and is not
 670			   useful except insofar as it tells us that
 671			   we really are looking at a board resource. */
 672			nubus_get_rsrc_mem(nbtdata, &ent, 8);
 673			printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
 674			       nbtdata[0], nbtdata[1], nbtdata[2],
 675			       nbtdata[3]);
 676			if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
 677			    nbtdata[2] != 0 || nbtdata[3] != 0)
 678				printk(KERN_ERR "this sResource is not a board resource!\n");
 679			break;
 680		}
 681		case NUBUS_RESID_NAME:
 682			nubus_get_rsrc_str(board->name, &ent, 64);
 683			printk(KERN_INFO "    name: %s\n", board->name);
 684			break;
 685		case NUBUS_RESID_ICON:
 686			nubus_get_icon(board, &ent);
 687			break;
 688		case NUBUS_RESID_BOARDID:
 689			printk(KERN_INFO "    board id: 0x%x\n", ent.data);
 690			break;
 691		case NUBUS_RESID_PRIMARYINIT:
 692			printk(KERN_INFO "    primary init offset: 0x%06x\n", ent.data);
 693			break;
 694		case NUBUS_RESID_VENDORINFO:
 695			nubus_get_vendorinfo(board, &ent);
 696			break;
 697		case NUBUS_RESID_FLAGS:
 698			printk(KERN_INFO "    flags: 0x%06x\n", ent.data);
 699			break;
 700		case NUBUS_RESID_HWDEVID:
 701			printk(KERN_INFO "    hwdevid: 0x%06x\n", ent.data);
 702			break;
 703		case NUBUS_RESID_SECONDINIT:
 704			printk(KERN_INFO "    secondary init offset: 0x%06x\n", ent.data);
 705			break;
 706			/* WTF isn't this in the functional resources? */ 
 707		case NUBUS_RESID_VIDNAMES:
 708			nubus_get_vidnames(board, &ent);
 709			break;
 710			/* Same goes for this */
 711		case NUBUS_RESID_VIDMODES:
 712			printk(KERN_INFO "    video mode parameter directory offset: 0x%06x\n",
 713			       ent.data);
 714			break;			
 715		default:
 716			printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
 717			       ent.type, ent.data);
 718		}
 719	}
 720	return 0;
 721}
 722
 723/* Attempt to bypass the somewhat non-obvious arrangement of
 724   sResources in the motherboard ROM */
 725static void __init nubus_find_rom_dir(struct nubus_board* board)
 726{
 727	unsigned char* rp;
 728	unsigned char* romdir;
 729	struct nubus_dir dir;
 730	struct nubus_dirent ent;
 731
 732	/* Check for the extra directory just under the format block */
 733	rp = board->fblock;
 734	nubus_rewind(&rp, 4, board->lanes);
 735	if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {
 736		/* OK, the ROM was telling the truth */
 737		board->directory = board->fblock;
 738		nubus_move(&board->directory,
 739			   nubus_expand32(board->doffset),
 740			   board->lanes);
 741		return;
 742	}
 743
 744	/* On "slot zero", you have to walk down a few more
 745	   directories to get to the equivalent of a real card's root
 746	   directory.  We don't know what they were smoking when they
 747	   came up with this. */
 748	romdir = nubus_rom_addr(board->slot);
 749	nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);
 750	dir.base = dir.ptr = romdir;
 751	dir.done = 0;
 752	dir.mask = board->lanes;
 753
 754	/* This one points to an "Unknown Macintosh" directory */
 755	if (nubus_readdir(&dir, &ent) == -1)
 756		goto badrom;
 757
 758	if (console_loglevel >= 10)
 759		printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 760	/* This one takes us to where we want to go. */
 761	if (nubus_readdir(&dir, &ent) == -1) 
 762		goto badrom;
 763	if (console_loglevel >= 10)
 764		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 765	nubus_get_subdir(&ent, &dir);
 766
 767	/* Resource ID 01, also an "Unknown Macintosh" */
 768	if (nubus_readdir(&dir, &ent) == -1) 
 769		goto badrom;
 770	if (console_loglevel >= 10)
 771		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 772
 773	/* FIXME: the first one is *not* always the right one.  We
 774	   suspect this has something to do with the ROM revision.
 775	   "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR
 776	   Continues" (Q630) uses 0x7b.  The DAFB Macs evidently use
 777	   something else.  Please run "Slots" on your Mac (see
 778	   include/linux/nubus.h for where to get this program) and
 779	   tell us where the 'SiDirPtr' for Slot 0 is.  If you feel
 780	   brave, you should also use MacsBug to walk down the ROM
 781	   directories like this function does and try to find the
 782	   path to that address... */
 783	if (nubus_readdir(&dir, &ent) == -1)
 784		goto badrom;
 785	if (console_loglevel >= 10)
 786		printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
 787	
 788	/* Bwahahahaha... */
 789	nubus_get_subdir(&ent, &dir);
 790	board->directory = dir.base;
 791	return;
 792	
 793	/* Even more evil laughter... */
 794 badrom:
 795	board->directory = board->fblock;
 796	nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);
 797	printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness!  Notify the developers...\n");
 798}
 799
 800/* Add a board (might be many devices) to the list */
 801static struct nubus_board* __init nubus_add_board(int slot, int bytelanes)
 802{
 803	struct nubus_board* board;
 804	struct nubus_board** boardp;
 805
 806	unsigned char *rp;
 807	unsigned long dpat;
 808	struct nubus_dir dir;
 809	struct nubus_dirent ent;
 810
 811	/* Move to the start of the format block */
 812	rp = nubus_rom_addr(slot);		
 813	nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
 814
 815	/* Actually we should probably panic if this fails */
 816	if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
 817		return NULL;	
 818	board->fblock = rp;
 819
 820	/* Dump the format block for debugging purposes */
 821	if (console_loglevel >= 10) {
 822		int i;
 823		printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",
 824		       slot, rp);
 825		printk(KERN_DEBUG "Format block: ");
 826		for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {
 827			unsigned short foo, bar;
 828			foo = nubus_get_rom(&rp, 2, bytelanes);
 829			bar = nubus_get_rom(&rp, 2, bytelanes);
 830			printk("%04x %04x  ", foo, bar);
 831		}
 832		printk("\n");
 833		rp = board->fblock;
 834	}
 835	
 836	board->slot = slot;
 837	board->slot_addr = (unsigned long) nubus_slot_addr(slot);
 838	board->doffset = nubus_get_rom(&rp, 4, bytelanes);
 839	/* rom_length is *supposed* to be the total length of the
 840	 * ROM.  In practice it is the "amount of ROM used to compute
 841	 * the CRC."  So some jokers decide to set it to zero and
 842	 * set the crc to zero so they don't have to do any math.
 843	 * See the Performa 460 ROM, for example.  Those Apple "engineers".
 844	 */
 845	board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
 846	board->crc = nubus_get_rom(&rp, 4, bytelanes);
 847	board->rev = nubus_get_rom(&rp, 1, bytelanes);
 848	board->format = nubus_get_rom(&rp,1, bytelanes);
 849	board->lanes = bytelanes;
 850
 851	/* Directory offset should be small and negative... */
 852	if(!(board->doffset & 0x00FF0000))
 853		printk(KERN_WARNING "Dodgy doffset!\n");
 854	dpat = nubus_get_rom(&rp, 4, bytelanes);
 855	if(dpat != NUBUS_TEST_PATTERN)
 856		printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);
 857		
 858	/*
 859	 *	I wonder how the CRC is meant to work -
 860	 *		any takers ?
 861	 * CSA: According to MAC docs, not all cards pass the CRC anyway,
 862	 * since the initial Macintosh ROM releases skipped the check.
 863	 */
 864
 865	/* Attempt to work around slot zero weirdness */
 866	nubus_find_rom_dir(board);
 867	nubus_get_root_dir(board, &dir);	
 868
 869	/* We're ready to rock */
 870	printk(KERN_INFO "Slot %X:\n", slot);
 871
 872	/* Each slot should have one board resource and any number of
 873	   functional resources.  So we'll fill in some fields in the
 874	   struct nubus_board from the board resource, then walk down
 875	   the list of functional resources, spinning out a nubus_dev
 876	   for each of them. */
 877	if (nubus_readdir(&dir, &ent) == -1) {
 878		/* We can't have this! */
 879		printk(KERN_ERR "Board resource not found!\n");
 880		return NULL;
 881	} else {
 882		printk(KERN_INFO "  Board resource:\n");
 883		nubus_get_board_resource(board, slot, &ent);
 884	}
 885
 886	/* Aaaarrrrgghh!  The LC III motherboard has *two* board
 887	   resources.  I have no idea WTF to do about this. */
 888
 889	while (nubus_readdir(&dir, &ent) != -1) {
 890		struct nubus_dev*  dev;
 891		struct nubus_dev** devp;
 892		dev = nubus_get_functional_resource(board, slot, &ent);
 893		if (dev == NULL)
 894			continue;
 895
 896		/* We zeroed this out above */
 897		if (board->first_dev == NULL)
 898			board->first_dev = dev;
 899		
 900		/* Put it on the global NuBus device chain. Keep entries in order. */
 901		for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))
 902			/* spin */;
 903		*devp = dev;
 904		dev->next = NULL;		
 905	}
 906
 907	/* Put it on the global NuBus board chain. Keep entries in order. */
 908	for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))
 909		/* spin */;
 910	*boardp = board;
 911	board->next = NULL;
 912	
 913	return board;
 914}
 915
 916void __init nubus_probe_slot(int slot)
 917{
 918	unsigned char dp;
 919	unsigned char* rp;
 920	int i;
 921
 922	rp = nubus_rom_addr(slot);	
 923	for(i = 4; i; i--)
 924	{
 925		unsigned long flags;
 926		int card_present;
 927
 928		rp--;
 929		local_irq_save(flags);
 930		card_present = hwreg_present(rp);
 931		local_irq_restore(flags);
 932	       
 933		if (!card_present)
 934			continue;
 935
 936		printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);
 937		dp = *rp;
 938		if(dp == 0)
 939			continue;
 940
 941		/* The last byte of the format block consists of two
 942		   nybbles which are "mirror images" of each other.
 943		   These show us the valid bytelanes */
 944		if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
 945			continue;
 946		/* Check that this value is actually *on* one of the
 947		   bytelanes it claims are valid! */
 948		if ((dp & 0x0F) >= (1<<i))
 949			continue;
 950
 951		/* Looks promising.  Let's put it on the list. */
 952		nubus_add_board(slot, dp);
 953
 954		return;
 955	}
 956}
 957
 958#if defined(CONFIG_PROC_FS)
 959
 960/* /proc/nubus stuff */
 961
 962static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
 963{
 964	if(len < 100)
 965		return -1;
 966	
 967	sprintf(ptr, "Slot %X: %s\n",
 968		board->slot, board->name);
 969	
 970	return strlen(ptr);
 971}
 972
 973static int nubus_read_proc(char *page, char **start, off_t off,
 974				int count, int *eof, void *data)
 975{
 976	int nprinted, len, begin = 0;
 977	int size = PAGE_SIZE;
 978	struct nubus_board* board;
 979	
 980	len   = sprintf(page, "Nubus devices found:\n");
 981	/* Walk the list of NuBus boards */
 982	for (board = nubus_boards; board != NULL; board = board->next)
 983	{
 984		nprinted = sprint_nubus_board(board, page + len, size - len);
 985		if (nprinted < 0)
 986			break;
 987		len += nprinted;
 988		if (len+begin < off) {
 989			begin += len;
 990			len = 0;
 991		}
 992		if (len+begin >= off+count)
 993			break;
 994	}
 995	if (len+begin < off)
 996		*eof = 1;
 997	off -= begin;
 998	*start = page + off;
 999	len -= off;
1000	if (len>count)
1001		len = count;
1002	if (len<0)
1003		len = 0;
1004	return len;
1005}
1006#endif
1007
1008void __init nubus_scan_bus(void)
1009{
1010	int slot;
1011	/* This might not work on your machine */
1012#ifdef I_WANT_TO_PROBE_SLOT_ZERO
1013	nubus_probe_slot(0);
1014#endif
1015	for(slot = 9; slot < 15; slot++)
1016	{
1017		nubus_probe_slot(slot);
1018	}
1019}
1020
1021static int __init nubus_init(void)
1022{
1023	if (!MACH_IS_MAC) 
1024		return 0;
1025
1026	/* Initialize the NuBus interrupts */
1027	if (oss_present) {
1028		oss_nubus_init();
1029	} else {
1030		via_nubus_init();
1031	}
1032
1033#ifdef TRY_TO_DODGE_WSOD
1034	/* Rogue Ethernet interrupts can kill the machine if we don't
1035	   do this.  Obviously this is bogus.  Hopefully the local VIA
1036	   gurus can fix the real cause of the problem. */
1037	mdelay(1000);
1038#endif
1039	
1040	/* And probe */
1041	printk("NuBus: Scanning NuBus slots.\n");
1042	nubus_devices = NULL;
1043	nubus_boards  = NULL;
1044	nubus_scan_bus();
1045
1046#ifdef CONFIG_PROC_FS
1047	create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
1048	nubus_proc_init();
1049#endif
1050	return 0;
1051}
1052
1053subsys_initcall(nubus_init);