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