xref: /linux/drivers/nubus/nubus.c (revision f16a9577b7d3643456c68621325eb594142a3506)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *	Macintosh Nubus Interface Code
4  *
5  *      Originally by Alan Cox
6  *
7  *      Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
8  *      and others.
9  */
10 
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/string.h>
14 #include <linux/nubus.h>
15 #include <linux/errno.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/seq_file.h>
19 #include <linux/slab.h>
20 #include <asm/setup.h>
21 #include <asm/page.h>
22 #include <asm/hwtest.h>
23 
24 /* Constants */
25 
26 /* This is, of course, the size in bytelanes, rather than the size in
27    actual bytes */
28 #define FORMAT_BLOCK_SIZE 20
29 #define ROM_DIR_OFFSET 0x24
30 
31 #define NUBUS_TEST_PATTERN 0x5A932BC7
32 
33 /* Globals */
34 
35 /* The "nubus.populate_procfs" parameter makes slot resources available in
36  * procfs. It's deprecated and disabled by default because procfs is no longer
37  * thought to be suitable for that and some board ROMs make it too expensive.
38  */
39 bool nubus_populate_procfs;
40 module_param_named(populate_procfs, nubus_populate_procfs, bool, 0);
41 
42 LIST_HEAD(nubus_func_rsrcs);
43 
44 static struct device nubus_parent = {
45 	.init_name	= "nubus",
46 };
47 
48 /* Meaning of "bytelanes":
49 
50    The card ROM may appear on any or all bytes of each long word in
51    NuBus memory.  The low 4 bits of the "map" value found in the
52    format block (at the top of the slot address space, as well as at
53    the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
54    offsets within each longword, are valid.  Thus:
55 
56    A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
57    are valid.
58 
59    A map of 0xf0 means that no bytelanes are valid (We pray that we
60    will never encounter this, but stranger things have happened)
61 
62    A map of 0xe1 means that only the MSB of each long word is actually
63    part of the card ROM.  (We hope to never encounter NuBus on a
64    little-endian machine.  Again, stranger things have happened)
65 
66    A map of 0x78 means that only the LSB of each long word is valid.
67 
68    Etcetera, etcetera.  Hopefully this clears up some confusion over
69    what the following code actually does.  */
70 
71 static inline int not_useful(void *p, int map)
72 {
73 	unsigned long pv = (unsigned long)p;
74 
75 	pv &= 3;
76 	if (map & (1 << pv))
77 		return 0;
78 	return 1;
79 }
80 
81 static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map)
82 {
83 	/* This will hold the result */
84 	unsigned long v = 0;
85 	unsigned char *p = *ptr;
86 
87 	while (len) {
88 		v <<= 8;
89 		while (not_useful(p, map))
90 			p++;
91 		v |= *p++;
92 		len--;
93 	}
94 	*ptr = p;
95 	return v;
96 }
97 
98 static void nubus_rewind(unsigned char **ptr, int len, int map)
99 {
100 	unsigned char *p = *ptr;
101 
102 	while (len) {
103 		do {
104 			p--;
105 		} while (not_useful(p, map));
106 		len--;
107 	}
108 	*ptr = p;
109 }
110 
111 static void nubus_advance(unsigned char **ptr, int len, int map)
112 {
113 	unsigned char *p = *ptr;
114 
115 	while (len) {
116 		while (not_useful(p, map))
117 			p++;
118 		p++;
119 		len--;
120 	}
121 	*ptr = p;
122 }
123 
124 static void nubus_move(unsigned char **ptr, int len, int map)
125 {
126 	unsigned long slot_space = (unsigned long)*ptr & 0xFF000000;
127 
128 	if (len > 0)
129 		nubus_advance(ptr, len, map);
130 	else if (len < 0)
131 		nubus_rewind(ptr, -len, map);
132 
133 	if (((unsigned long)*ptr & 0xFF000000) != slot_space)
134 		pr_err("%s: moved out of slot address space!\n", __func__);
135 }
136 
137 /* Now, functions to read the sResource tree */
138 
139 /* Each sResource entry consists of a 1-byte ID and a 3-byte data
140    field.  If that data field contains an offset, then obviously we
141    have to expand it from a 24-bit signed number to a 32-bit signed
142    number. */
143 
144 static inline long nubus_expand32(long foo)
145 {
146 	if (foo & 0x00800000)	/* 24bit negative */
147 		foo |= 0xFF000000;
148 	return foo;
149 }
150 
151 static inline void *nubus_rom_addr(int slot)
152 {
153 	/*
154 	 *	Returns the first byte after the card. We then walk
155 	 *	backwards to get the lane register and the config
156 	 */
157 	return (void *)(0xF1000000 + (slot << 24));
158 }
159 
160 unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
161 {
162 	unsigned char *p = nd->base;
163 
164 	/* Essentially, just step over the bytelanes using whatever
165 	   offset we might have found */
166 	nubus_move(&p, nubus_expand32(nd->data), nd->mask);
167 	/* And return the value */
168 	return p;
169 }
170 
171 /* These two are for pulling resource data blocks (i.e. stuff that's
172    pointed to with offsets) out of the card ROM. */
173 
174 void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
175 			unsigned int len)
176 {
177 	unsigned char *t = dest;
178 	unsigned char *p = nubus_dirptr(dirent);
179 
180 	while (len) {
181 		*t++ = nubus_get_rom(&p, 1, dirent->mask);
182 		len--;
183 	}
184 }
185 EXPORT_SYMBOL(nubus_get_rsrc_mem);
186 
187 unsigned int nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
188 				unsigned int len)
189 {
190 	char *t = dest;
191 	unsigned char *p = nubus_dirptr(dirent);
192 
193 	while (len > 1) {
194 		unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
195 
196 		if (!c)
197 			break;
198 		*t++ = c;
199 		len--;
200 	}
201 	if (len > 0)
202 		*t = '\0';
203 	return t - dest;
204 }
205 EXPORT_SYMBOL(nubus_get_rsrc_str);
206 
207 void nubus_seq_write_rsrc_mem(struct seq_file *m,
208 			      const struct nubus_dirent *dirent,
209 			      unsigned int len)
210 {
211 	unsigned long buf[32];
212 	unsigned int buf_size = sizeof(buf);
213 	unsigned char *p = nubus_dirptr(dirent);
214 
215 	/* If possible, write out full buffers */
216 	while (len >= buf_size) {
217 		unsigned int i;
218 
219 		for (i = 0; i < ARRAY_SIZE(buf); i++)
220 			buf[i] = nubus_get_rom(&p, sizeof(buf[0]),
221 					       dirent->mask);
222 		seq_write(m, buf, buf_size);
223 		len -= buf_size;
224 	}
225 	/* If not, write out individual bytes */
226 	while (len--)
227 		seq_putc(m, nubus_get_rom(&p, 1, dirent->mask));
228 }
229 
230 int nubus_get_root_dir(const struct nubus_board *board,
231 		       struct nubus_dir *dir)
232 {
233 	dir->ptr = dir->base = board->directory;
234 	dir->done = 0;
235 	dir->mask = board->lanes;
236 	return 0;
237 }
238 EXPORT_SYMBOL(nubus_get_root_dir);
239 
240 /* This is a slyly renamed version of the above */
241 int nubus_get_func_dir(const struct nubus_rsrc *fres, struct nubus_dir *dir)
242 {
243 	dir->ptr = dir->base = fres->directory;
244 	dir->done = 0;
245 	dir->mask = fres->board->lanes;
246 	return 0;
247 }
248 EXPORT_SYMBOL(nubus_get_func_dir);
249 
250 int nubus_get_board_dir(const struct nubus_board *board,
251 			struct nubus_dir *dir)
252 {
253 	struct nubus_dirent ent;
254 
255 	dir->ptr = dir->base = board->directory;
256 	dir->done = 0;
257 	dir->mask = board->lanes;
258 
259 	/* Now dereference it (the first directory is always the board
260 	   directory) */
261 	if (nubus_readdir(dir, &ent) == -1)
262 		return -1;
263 	if (nubus_get_subdir(&ent, dir) == -1)
264 		return -1;
265 	return 0;
266 }
267 EXPORT_SYMBOL(nubus_get_board_dir);
268 
269 int nubus_get_subdir(const struct nubus_dirent *ent,
270 		     struct nubus_dir *dir)
271 {
272 	dir->ptr = dir->base = nubus_dirptr(ent);
273 	dir->done = 0;
274 	dir->mask = ent->mask;
275 	return 0;
276 }
277 EXPORT_SYMBOL(nubus_get_subdir);
278 
279 int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
280 {
281 	u32 resid;
282 
283 	if (nd->done)
284 		return -1;
285 
286 	/* Do this first, otherwise nubus_rewind & co are off by 4 */
287 	ent->base = nd->ptr;
288 
289 	/* This moves nd->ptr forward */
290 	resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
291 
292 	/* EOL marker, as per the Apple docs */
293 	if ((resid & 0xff000000) == 0xff000000) {
294 		/* Mark it as done */
295 		nd->done = 1;
296 		return -1;
297 	}
298 
299 	/* First byte is the resource ID */
300 	ent->type = resid >> 24;
301 	/* Low 3 bytes might contain data (or might not) */
302 	ent->data = resid & 0xffffff;
303 	ent->mask = nd->mask;
304 	return 0;
305 }
306 EXPORT_SYMBOL(nubus_readdir);
307 
308 int nubus_rewinddir(struct nubus_dir *dir)
309 {
310 	dir->ptr = dir->base;
311 	dir->done = 0;
312 	return 0;
313 }
314 EXPORT_SYMBOL(nubus_rewinddir);
315 
316 /* Driver interface functions, more or less like in pci.c */
317 
318 struct nubus_rsrc *nubus_first_rsrc_or_null(void)
319 {
320 	return list_first_entry_or_null(&nubus_func_rsrcs, struct nubus_rsrc,
321 					list);
322 }
323 EXPORT_SYMBOL(nubus_first_rsrc_or_null);
324 
325 struct nubus_rsrc *nubus_next_rsrc_or_null(struct nubus_rsrc *from)
326 {
327 	if (list_is_last(&from->list, &nubus_func_rsrcs))
328 		return NULL;
329 	return list_next_entry(from, list);
330 }
331 EXPORT_SYMBOL(nubus_next_rsrc_or_null);
332 
333 int
334 nubus_find_rsrc(struct nubus_dir *dir, unsigned char rsrc_type,
335 		struct nubus_dirent *ent)
336 {
337 	while (nubus_readdir(dir, ent) != -1) {
338 		if (ent->type == rsrc_type)
339 			return 0;
340 	}
341 	return -1;
342 }
343 EXPORT_SYMBOL(nubus_find_rsrc);
344 
345 /* Initialization functions - decide which slots contain stuff worth
346    looking at, and print out lots and lots of information from the
347    resource blocks. */
348 
349 static int __init nubus_get_block_rsrc_dir(struct nubus_board *board,
350 					   struct proc_dir_entry *procdir,
351 					   const struct nubus_dirent *parent)
352 {
353 	struct nubus_dir dir;
354 	struct nubus_dirent ent;
355 
356 	nubus_get_subdir(parent, &dir);
357 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
358 
359 	while (nubus_readdir(&dir, &ent) != -1) {
360 		u32 size;
361 
362 		nubus_get_rsrc_mem(&size, &ent, 4);
363 		pr_debug("        block (0x%x), size %d\n", ent.type, size);
364 		nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
365 	}
366 	return 0;
367 }
368 
369 static int __init nubus_get_display_vidmode(struct nubus_board *board,
370 					    struct proc_dir_entry *procdir,
371 					    const struct nubus_dirent *parent)
372 {
373 	struct nubus_dir dir;
374 	struct nubus_dirent ent;
375 
376 	nubus_get_subdir(parent, &dir);
377 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
378 
379 	while (nubus_readdir(&dir, &ent) != -1) {
380 		switch (ent.type) {
381 		case 1: /* mVidParams */
382 		case 2: /* mTable */
383 		{
384 			u32 size;
385 
386 			nubus_get_rsrc_mem(&size, &ent, 4);
387 			pr_debug("        block (0x%x), size %d\n", ent.type,
388 				size);
389 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
390 			break;
391 		}
392 		default:
393 			pr_debug("        unknown resource 0x%02x, data 0x%06x\n",
394 				ent.type, ent.data);
395 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
396 		}
397 	}
398 	return 0;
399 }
400 
401 static int __init nubus_get_display_resource(struct nubus_rsrc *fres,
402 					     struct proc_dir_entry *procdir,
403 					     const struct nubus_dirent *ent)
404 {
405 	switch (ent->type) {
406 	case NUBUS_RESID_GAMMADIR:
407 		pr_debug("    gamma directory offset: 0x%06x\n", ent->data);
408 		nubus_get_block_rsrc_dir(fres->board, procdir, ent);
409 		break;
410 	case 0x0080 ... 0x0085:
411 		pr_debug("    mode 0x%02x info offset: 0x%06x\n",
412 			ent->type, ent->data);
413 		nubus_get_display_vidmode(fres->board, procdir, ent);
414 		break;
415 	default:
416 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
417 			ent->type, ent->data);
418 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
419 	}
420 	return 0;
421 }
422 
423 static int __init nubus_get_network_resource(struct nubus_rsrc *fres,
424 					     struct proc_dir_entry *procdir,
425 					     const struct nubus_dirent *ent)
426 {
427 	switch (ent->type) {
428 	case NUBUS_RESID_MAC_ADDRESS:
429 	{
430 		char addr[6];
431 
432 		nubus_get_rsrc_mem(addr, ent, 6);
433 		pr_debug("    MAC address: %pM\n", addr);
434 		nubus_proc_add_rsrc_mem(procdir, ent, 6);
435 		break;
436 	}
437 	default:
438 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
439 			ent->type, ent->data);
440 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
441 	}
442 	return 0;
443 }
444 
445 static int __init nubus_get_cpu_resource(struct nubus_rsrc *fres,
446 					 struct proc_dir_entry *procdir,
447 					 const struct nubus_dirent *ent)
448 {
449 	switch (ent->type) {
450 	case NUBUS_RESID_MEMINFO:
451 	{
452 		unsigned long meminfo[2];
453 
454 		nubus_get_rsrc_mem(&meminfo, ent, 8);
455 		pr_debug("    memory: [ 0x%08lx 0x%08lx ]\n",
456 			meminfo[0], meminfo[1]);
457 		nubus_proc_add_rsrc_mem(procdir, ent, 8);
458 		break;
459 	}
460 	case NUBUS_RESID_ROMINFO:
461 	{
462 		unsigned long rominfo[2];
463 
464 		nubus_get_rsrc_mem(&rominfo, ent, 8);
465 		pr_debug("    ROM:    [ 0x%08lx 0x%08lx ]\n",
466 			rominfo[0], rominfo[1]);
467 		nubus_proc_add_rsrc_mem(procdir, ent, 8);
468 		break;
469 	}
470 	default:
471 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
472 			ent->type, ent->data);
473 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
474 	}
475 	return 0;
476 }
477 
478 static int __init nubus_get_private_resource(struct nubus_rsrc *fres,
479 					     struct proc_dir_entry *procdir,
480 					     const struct nubus_dirent *ent)
481 {
482 	switch (fres->category) {
483 	case NUBUS_CAT_DISPLAY:
484 		nubus_get_display_resource(fres, procdir, ent);
485 		break;
486 	case NUBUS_CAT_NETWORK:
487 		nubus_get_network_resource(fres, procdir, ent);
488 		break;
489 	case NUBUS_CAT_CPU:
490 		nubus_get_cpu_resource(fres, procdir, ent);
491 		break;
492 	default:
493 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
494 			ent->type, ent->data);
495 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
496 	}
497 	return 0;
498 }
499 
500 static struct nubus_rsrc * __init
501 nubus_get_functional_resource(struct nubus_board *board, int slot,
502 			      const struct nubus_dirent *parent)
503 {
504 	struct nubus_dir dir;
505 	struct nubus_dirent ent;
506 	struct nubus_rsrc *fres;
507 
508 	pr_debug("  Functional resource 0x%02x:\n", parent->type);
509 	nubus_get_subdir(parent, &dir);
510 	dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
511 
512 	/* Actually we should probably panic if this fails */
513 	fres = kzalloc(sizeof(*fres), GFP_ATOMIC);
514 	if (!fres)
515 		return NULL;
516 	fres->resid = parent->type;
517 	fres->directory = dir.base;
518 	fres->board = board;
519 
520 	while (nubus_readdir(&dir, &ent) != -1) {
521 		switch (ent.type) {
522 		case NUBUS_RESID_TYPE:
523 		{
524 			unsigned short nbtdata[4];
525 
526 			nubus_get_rsrc_mem(nbtdata, &ent, 8);
527 			fres->category = nbtdata[0];
528 			fres->type     = nbtdata[1];
529 			fres->dr_sw    = nbtdata[2];
530 			fres->dr_hw    = nbtdata[3];
531 			pr_debug("    type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
532 				nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
533 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
534 			break;
535 		}
536 		case NUBUS_RESID_NAME:
537 		{
538 			char name[64];
539 			unsigned int len;
540 
541 			len = nubus_get_rsrc_str(name, &ent, sizeof(name));
542 			pr_debug("    name: %s\n", name);
543 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
544 			break;
545 		}
546 		case NUBUS_RESID_DRVRDIR:
547 		{
548 			/* MacOS driver.  If we were NetBSD we might
549 			   use this :-) */
550 			pr_debug("    driver directory offset: 0x%06x\n",
551 				ent.data);
552 			nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
553 			break;
554 		}
555 		case NUBUS_RESID_MINOR_BASEOS:
556 		{
557 			/* We will need this in order to support
558 			   multiple framebuffers.  It might be handy
559 			   for Ethernet as well */
560 			u32 base_offset;
561 
562 			nubus_get_rsrc_mem(&base_offset, &ent, 4);
563 			pr_debug("    memory offset: 0x%08x\n", base_offset);
564 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
565 			break;
566 		}
567 		case NUBUS_RESID_MINOR_LENGTH:
568 		{
569 			/* Ditto */
570 			u32 length;
571 
572 			nubus_get_rsrc_mem(&length, &ent, 4);
573 			pr_debug("    memory length: 0x%08x\n", length);
574 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
575 			break;
576 		}
577 		case NUBUS_RESID_FLAGS:
578 			pr_debug("    flags: 0x%06x\n", ent.data);
579 			nubus_proc_add_rsrc(dir.procdir, &ent);
580 			break;
581 		case NUBUS_RESID_HWDEVID:
582 			pr_debug("    hwdevid: 0x%06x\n", ent.data);
583 			nubus_proc_add_rsrc(dir.procdir, &ent);
584 			break;
585 		default:
586 			if (nubus_populate_procfs)
587 				nubus_get_private_resource(fres, dir.procdir,
588 							   &ent);
589 		}
590 	}
591 
592 	return fres;
593 }
594 
595 /* This is *really* cool. */
596 static int __init nubus_get_icon(struct nubus_board *board,
597 				 struct proc_dir_entry *procdir,
598 				 const struct nubus_dirent *ent)
599 {
600 	/* Should be 32x32 if my memory serves me correctly */
601 	u32 icon[32];
602 	int i;
603 
604 	nubus_get_rsrc_mem(&icon, ent, 128);
605 	pr_debug("    icon:\n");
606 	for (i = 0; i < 8; i++)
607 		pr_debug("        %08x %08x %08x %08x\n",
608 			icon[i * 4 + 0], icon[i * 4 + 1],
609 			icon[i * 4 + 2], icon[i * 4 + 3]);
610 	nubus_proc_add_rsrc_mem(procdir, ent, 128);
611 
612 	return 0;
613 }
614 
615 static int __init nubus_get_vendorinfo(struct nubus_board *board,
616 				       struct proc_dir_entry *procdir,
617 				       const struct nubus_dirent *parent)
618 {
619 	struct nubus_dir dir;
620 	struct nubus_dirent ent;
621 	static char *vendor_fields[6] = { "ID", "serial", "revision",
622 	                                  "part", "date", "unknown field" };
623 
624 	pr_debug("    vendor info:\n");
625 	nubus_get_subdir(parent, &dir);
626 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
627 
628 	while (nubus_readdir(&dir, &ent) != -1) {
629 		char name[64];
630 		unsigned int len;
631 
632 		/* These are all strings, we think */
633 		len = nubus_get_rsrc_str(name, &ent, sizeof(name));
634 		if (ent.type < 1 || ent.type > 5)
635 			ent.type = 5;
636 		pr_debug("    %s: %s\n", vendor_fields[ent.type - 1], name);
637 		nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
638 	}
639 	return 0;
640 }
641 
642 static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
643 					   const struct nubus_dirent *parent)
644 {
645 	struct nubus_dir dir;
646 	struct nubus_dirent ent;
647 
648 	pr_debug("  Board resource 0x%02x:\n", parent->type);
649 	nubus_get_subdir(parent, &dir);
650 	dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
651 
652 	while (nubus_readdir(&dir, &ent) != -1) {
653 		switch (ent.type) {
654 		case NUBUS_RESID_TYPE:
655 		{
656 			unsigned short nbtdata[4];
657 			/* This type is always the same, and is not
658 			   useful except insofar as it tells us that
659 			   we really are looking at a board resource. */
660 			nubus_get_rsrc_mem(nbtdata, &ent, 8);
661 			pr_debug("    type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
662 				nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
663 			if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
664 			    nbtdata[2] != 0 || nbtdata[3] != 0)
665 				pr_err("Slot %X: sResource is not a board resource!\n",
666 				       slot);
667 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
668 			break;
669 		}
670 		case NUBUS_RESID_NAME:
671 		{
672 			unsigned int len;
673 
674 			len = nubus_get_rsrc_str(board->name, &ent,
675 						 sizeof(board->name));
676 			pr_debug("    name: %s\n", board->name);
677 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
678 			break;
679 		}
680 		case NUBUS_RESID_ICON:
681 			nubus_get_icon(board, dir.procdir, &ent);
682 			break;
683 		case NUBUS_RESID_BOARDID:
684 			pr_debug("    board id: 0x%x\n", ent.data);
685 			nubus_proc_add_rsrc(dir.procdir, &ent);
686 			break;
687 		case NUBUS_RESID_PRIMARYINIT:
688 			pr_debug("    primary init offset: 0x%06x\n", ent.data);
689 			nubus_proc_add_rsrc(dir.procdir, &ent);
690 			break;
691 		case NUBUS_RESID_VENDORINFO:
692 			nubus_get_vendorinfo(board, dir.procdir, &ent);
693 			break;
694 		case NUBUS_RESID_FLAGS:
695 			pr_debug("    flags: 0x%06x\n", ent.data);
696 			nubus_proc_add_rsrc(dir.procdir, &ent);
697 			break;
698 		case NUBUS_RESID_HWDEVID:
699 			pr_debug("    hwdevid: 0x%06x\n", ent.data);
700 			nubus_proc_add_rsrc(dir.procdir, &ent);
701 			break;
702 		case NUBUS_RESID_SECONDINIT:
703 			pr_debug("    secondary init offset: 0x%06x\n",
704 				 ent.data);
705 			nubus_proc_add_rsrc(dir.procdir, &ent);
706 			break;
707 			/* WTF isn't this in the functional resources? */
708 		case NUBUS_RESID_VIDNAMES:
709 			pr_debug("    vidnames directory offset: 0x%06x\n",
710 				ent.data);
711 			nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
712 			break;
713 			/* Same goes for this */
714 		case NUBUS_RESID_VIDMODES:
715 			pr_debug("    video mode parameter directory offset: 0x%06x\n",
716 				ent.data);
717 			nubus_proc_add_rsrc(dir.procdir, &ent);
718 			break;
719 		default:
720 			pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
721 				ent.type, ent.data);
722 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
723 		}
724 	}
725 	return 0;
726 }
727 
728 static void __init nubus_add_board(int slot, int bytelanes)
729 {
730 	struct nubus_board *board;
731 	unsigned char *rp;
732 	unsigned long dpat;
733 	struct nubus_dir dir;
734 	struct nubus_dirent ent;
735 	int prev_resid = -1;
736 
737 	/* Move to the start of the format block */
738 	rp = nubus_rom_addr(slot);
739 	nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
740 
741 	/* Actually we should probably panic if this fails */
742 	if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
743 		return;
744 	board->fblock = rp;
745 
746 	/* Dump the format block for debugging purposes */
747 	pr_debug("Slot %X, format block at 0x%p:\n", slot, rp);
748 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
749 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
750 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
751 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
752 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
753 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
754 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
755 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
756 	rp = board->fblock;
757 
758 	board->slot = slot;
759 	board->slot_addr = (unsigned long)nubus_slot_addr(slot);
760 	board->doffset = nubus_get_rom(&rp, 4, bytelanes);
761 	/* rom_length is *supposed* to be the total length of the
762 	 * ROM.  In practice it is the "amount of ROM used to compute
763 	 * the CRC."  So some jokers decide to set it to zero and
764 	 * set the crc to zero so they don't have to do any math.
765 	 * See the Performa 460 ROM, for example.  Those Apple "engineers".
766 	 */
767 	board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
768 	board->crc = nubus_get_rom(&rp, 4, bytelanes);
769 	board->rev = nubus_get_rom(&rp, 1, bytelanes);
770 	board->format = nubus_get_rom(&rp, 1, bytelanes);
771 	board->lanes = bytelanes;
772 
773 	/* Directory offset should be small and negative... */
774 	if (!(board->doffset & 0x00FF0000))
775 		pr_warn("Slot %X: Dodgy doffset!\n", slot);
776 	dpat = nubus_get_rom(&rp, 4, bytelanes);
777 	if (dpat != NUBUS_TEST_PATTERN)
778 		pr_warn("Slot %X: Wrong test pattern %08lx!\n", slot, dpat);
779 
780 	/*
781 	 *	I wonder how the CRC is meant to work -
782 	 *		any takers ?
783 	 * CSA: According to MAC docs, not all cards pass the CRC anyway,
784 	 * since the initial Macintosh ROM releases skipped the check.
785 	 */
786 
787 	/* Set up the directory pointer */
788 	board->directory = board->fblock;
789 	nubus_move(&board->directory, nubus_expand32(board->doffset),
790 	           board->lanes);
791 
792 	nubus_get_root_dir(board, &dir);
793 
794 	/* We're ready to rock */
795 	pr_debug("Slot %X resources:\n", slot);
796 
797 	/* Each slot should have one board resource and any number of
798 	 * functional resources.  So we'll fill in some fields in the
799 	 * struct nubus_board from the board resource, then walk down
800 	 * the list of functional resources, spinning out a nubus_rsrc
801 	 * for each of them.
802 	 */
803 	if (nubus_readdir(&dir, &ent) == -1) {
804 		/* We can't have this! */
805 		pr_err("Slot %X: Board resource not found!\n", slot);
806 		kfree(board);
807 		return;
808 	}
809 
810 	if (ent.type < 1 || ent.type > 127)
811 		pr_warn("Slot %X: Board resource ID is invalid!\n", slot);
812 
813 	board->procdir = nubus_proc_add_board(board);
814 
815 	nubus_get_board_resource(board, slot, &ent);
816 
817 	while (nubus_readdir(&dir, &ent) != -1) {
818 		struct nubus_rsrc *fres;
819 
820 		fres = nubus_get_functional_resource(board, slot, &ent);
821 		if (fres == NULL)
822 			continue;
823 
824 		/* Resources should appear in ascending ID order. This sanity
825 		 * check prevents duplicate resource IDs.
826 		 */
827 		if (fres->resid <= prev_resid) {
828 			kfree(fres);
829 			continue;
830 		}
831 		prev_resid = fres->resid;
832 
833 		list_add_tail(&fres->list, &nubus_func_rsrcs);
834 	}
835 
836 	if (nubus_device_register(&nubus_parent, board))
837 		put_device(&board->dev);
838 }
839 
840 static void __init nubus_probe_slot(int slot)
841 {
842 	unsigned char dp;
843 	unsigned char *rp;
844 	int i;
845 
846 	rp = nubus_rom_addr(slot);
847 	for (i = 4; i; i--) {
848 		rp--;
849 		if (!hwreg_present(rp))
850 			continue;
851 
852 		dp = *rp;
853 
854 		/* The last byte of the format block consists of two
855 		   nybbles which are "mirror images" of each other.
856 		   These show us the valid bytelanes */
857 		if ((((dp >> 4) ^ dp) & 0x0F) != 0x0F)
858 			continue;
859 		/* Check that this value is actually *on* one of the
860 		   bytelanes it claims are valid! */
861 		if (not_useful(rp, dp))
862 			continue;
863 
864 		/* Looks promising.  Let's put it on the list. */
865 		nubus_add_board(slot, dp);
866 
867 		return;
868 	}
869 }
870 
871 static void __init nubus_scan_bus(void)
872 {
873 	int slot;
874 
875 	pr_info("NuBus: Scanning NuBus slots.\n");
876 	for (slot = 9; slot < 15; slot++) {
877 		nubus_probe_slot(slot);
878 	}
879 }
880 
881 static int __init nubus_init(void)
882 {
883 	int err;
884 
885 	if (!MACH_IS_MAC)
886 		return 0;
887 
888 	nubus_proc_init();
889 	err = device_register(&nubus_parent);
890 	if (err) {
891 		put_device(&nubus_parent);
892 		return err;
893 	}
894 	nubus_scan_bus();
895 	return 0;
896 }
897 
898 subsys_initcall(nubus_init);
899