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