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