xref: /openbmc/linux/drivers/nubus/nubus.c (revision 2f7dd07e)
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_dev *nubus_devices;
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_dev *dev,
232 		       struct nubus_dir *dir)
233 {
234 	dir->ptr = dir->base = dev->directory;
235 	dir->done = 0;
236 	dir->mask = dev->board->lanes;
237 	return 0;
238 }
239 EXPORT_SYMBOL(nubus_get_func_dir);
240 
241 int nubus_get_board_dir(const struct nubus_board *board,
242 			struct nubus_dir *dir)
243 {
244 	struct nubus_dirent ent;
245 
246 	dir->ptr = dir->base = board->directory;
247 	dir->done = 0;
248 	dir->mask = board->lanes;
249 
250 	/* Now dereference it (the first directory is always the board
251 	   directory) */
252 	if (nubus_readdir(dir, &ent) == -1)
253 		return -1;
254 	if (nubus_get_subdir(&ent, dir) == -1)
255 		return -1;
256 	return 0;
257 }
258 EXPORT_SYMBOL(nubus_get_board_dir);
259 
260 int nubus_get_subdir(const struct nubus_dirent *ent,
261 		     struct nubus_dir *dir)
262 {
263 	dir->ptr = dir->base = nubus_dirptr(ent);
264 	dir->done = 0;
265 	dir->mask = ent->mask;
266 	return 0;
267 }
268 EXPORT_SYMBOL(nubus_get_subdir);
269 
270 int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
271 {
272 	u32 resid;
273 
274 	if (nd->done)
275 		return -1;
276 
277 	/* Do this first, otherwise nubus_rewind & co are off by 4 */
278 	ent->base = nd->ptr;
279 
280 	/* This moves nd->ptr forward */
281 	resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
282 
283 	/* EOL marker, as per the Apple docs */
284 	if ((resid & 0xff000000) == 0xff000000) {
285 		/* Mark it as done */
286 		nd->done = 1;
287 		return -1;
288 	}
289 
290 	/* First byte is the resource ID */
291 	ent->type = resid >> 24;
292 	/* Low 3 bytes might contain data (or might not) */
293 	ent->data = resid & 0xffffff;
294 	ent->mask = nd->mask;
295 	return 0;
296 }
297 EXPORT_SYMBOL(nubus_readdir);
298 
299 int nubus_rewinddir(struct nubus_dir *dir)
300 {
301 	dir->ptr = dir->base;
302 	dir->done = 0;
303 	return 0;
304 }
305 EXPORT_SYMBOL(nubus_rewinddir);
306 
307 /* Driver interface functions, more or less like in pci.c */
308 
309 struct nubus_dev*
310 nubus_find_type(unsigned short category, unsigned short type,
311 		const struct nubus_dev *from)
312 {
313 	struct nubus_dev *itor = from ? from->next : nubus_devices;
314 
315 	while (itor) {
316 		if (itor->category == category && itor->type == type)
317 			return itor;
318 		itor = itor->next;
319 	}
320 	return NULL;
321 }
322 EXPORT_SYMBOL(nubus_find_type);
323 
324 struct nubus_dev*
325 nubus_find_slot(unsigned int slot, const struct nubus_dev *from)
326 {
327 	struct nubus_dev *itor = from ? from->next : nubus_devices;
328 
329 	while (itor) {
330 		if (itor->board->slot == slot)
331 			return itor;
332 		itor = itor->next;
333 	}
334 	return NULL;
335 }
336 EXPORT_SYMBOL(nubus_find_slot);
337 
338 int
339 nubus_find_rsrc(struct nubus_dir *dir, unsigned char rsrc_type,
340 		struct nubus_dirent *ent)
341 {
342 	while (nubus_readdir(dir, ent) != -1) {
343 		if (ent->type == rsrc_type)
344 			return 0;
345 	}
346 	return -1;
347 }
348 EXPORT_SYMBOL(nubus_find_rsrc);
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 static int __init nubus_get_block_rsrc_dir(struct nubus_board *board,
355 					   struct proc_dir_entry *procdir,
356 					   const struct nubus_dirent *parent)
357 {
358 	struct nubus_dir dir;
359 	struct nubus_dirent ent;
360 
361 	nubus_get_subdir(parent, &dir);
362 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
363 
364 	while (nubus_readdir(&dir, &ent) != -1) {
365 		u32 size;
366 
367 		nubus_get_rsrc_mem(&size, &ent, 4);
368 		pr_debug("        block (0x%x), size %d\n", ent.type, size);
369 		nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
370 	}
371 	return 0;
372 }
373 
374 static int __init nubus_get_display_vidmode(struct nubus_board *board,
375 					    struct proc_dir_entry *procdir,
376 					    const struct nubus_dirent *parent)
377 {
378 	struct nubus_dir dir;
379 	struct nubus_dirent ent;
380 
381 	nubus_get_subdir(parent, &dir);
382 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
383 
384 	while (nubus_readdir(&dir, &ent) != -1) {
385 		switch (ent.type) {
386 		case 1: /* mVidParams */
387 		case 2: /* mTable */
388 		{
389 			u32 size;
390 
391 			nubus_get_rsrc_mem(&size, &ent, 4);
392 			pr_debug("        block (0x%x), size %d\n", ent.type,
393 				size);
394 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
395 			break;
396 		}
397 		default:
398 			pr_debug("        unknown resource 0x%02x, data 0x%06x\n",
399 				ent.type, ent.data);
400 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
401 		}
402 	}
403 	return 0;
404 }
405 
406 static int __init nubus_get_display_resource(struct nubus_dev *dev,
407 					     struct proc_dir_entry *procdir,
408 					     const struct nubus_dirent *ent)
409 {
410 	switch (ent->type) {
411 	case NUBUS_RESID_GAMMADIR:
412 		pr_debug("    gamma directory offset: 0x%06x\n", ent->data);
413 		nubus_get_block_rsrc_dir(dev->board, procdir, ent);
414 		break;
415 	case 0x0080 ... 0x0085:
416 		pr_debug("    mode 0x%02x info offset: 0x%06x\n",
417 			ent->type, ent->data);
418 		nubus_get_display_vidmode(dev->board, procdir, ent);
419 		break;
420 	default:
421 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
422 			ent->type, ent->data);
423 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
424 	}
425 	return 0;
426 }
427 
428 static int __init nubus_get_network_resource(struct nubus_dev *dev,
429 					     struct proc_dir_entry *procdir,
430 					     const struct nubus_dirent *ent)
431 {
432 	switch (ent->type) {
433 	case NUBUS_RESID_MAC_ADDRESS:
434 	{
435 		char addr[6];
436 
437 		nubus_get_rsrc_mem(addr, ent, 6);
438 		pr_debug("    MAC address: %pM\n", addr);
439 		nubus_proc_add_rsrc_mem(procdir, ent, 6);
440 		break;
441 	}
442 	default:
443 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
444 			ent->type, ent->data);
445 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
446 	}
447 	return 0;
448 }
449 
450 static int __init nubus_get_cpu_resource(struct nubus_dev *dev,
451 					 struct proc_dir_entry *procdir,
452 					 const struct nubus_dirent *ent)
453 {
454 	switch (ent->type) {
455 	case NUBUS_RESID_MEMINFO:
456 	{
457 		unsigned long meminfo[2];
458 
459 		nubus_get_rsrc_mem(&meminfo, ent, 8);
460 		pr_debug("    memory: [ 0x%08lx 0x%08lx ]\n",
461 			meminfo[0], meminfo[1]);
462 		nubus_proc_add_rsrc_mem(procdir, ent, 8);
463 		break;
464 	}
465 	case NUBUS_RESID_ROMINFO:
466 	{
467 		unsigned long rominfo[2];
468 
469 		nubus_get_rsrc_mem(&rominfo, ent, 8);
470 		pr_debug("    ROM:    [ 0x%08lx 0x%08lx ]\n",
471 			rominfo[0], rominfo[1]);
472 		nubus_proc_add_rsrc_mem(procdir, ent, 8);
473 		break;
474 	}
475 	default:
476 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
477 			ent->type, ent->data);
478 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
479 	}
480 	return 0;
481 }
482 
483 static int __init nubus_get_private_resource(struct nubus_dev *dev,
484 					     struct proc_dir_entry *procdir,
485 					     const struct nubus_dirent *ent)
486 {
487 	switch (dev->category) {
488 	case NUBUS_CAT_DISPLAY:
489 		nubus_get_display_resource(dev, procdir, ent);
490 		break;
491 	case NUBUS_CAT_NETWORK:
492 		nubus_get_network_resource(dev, procdir, ent);
493 		break;
494 	case NUBUS_CAT_CPU:
495 		nubus_get_cpu_resource(dev, procdir, ent);
496 		break;
497 	default:
498 		pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
499 			ent->type, ent->data);
500 		nubus_proc_add_rsrc_mem(procdir, ent, 0);
501 	}
502 	return 0;
503 }
504 
505 static struct nubus_dev * __init
506 nubus_get_functional_resource(struct nubus_board *board, int slot,
507 			      const struct nubus_dirent *parent)
508 {
509 	struct nubus_dir dir;
510 	struct nubus_dirent ent;
511 	struct nubus_dev *dev;
512 
513 	pr_debug("  Functional resource 0x%02x:\n", parent->type);
514 	nubus_get_subdir(parent, &dir);
515 	dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
516 
517 	/* Actually we should probably panic if this fails */
518 	if ((dev = kzalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
519 		return NULL;
520 	dev->resid = parent->type;
521 	dev->directory = dir.base;
522 	dev->board = board;
523 
524 	while (nubus_readdir(&dir, &ent) != -1) {
525 		switch (ent.type) {
526 		case NUBUS_RESID_TYPE:
527 		{
528 			unsigned short nbtdata[4];
529 
530 			nubus_get_rsrc_mem(nbtdata, &ent, 8);
531 			dev->category = nbtdata[0];
532 			dev->type     = nbtdata[1];
533 			dev->dr_sw    = nbtdata[2];
534 			dev->dr_hw    = nbtdata[3];
535 			pr_debug("    type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
536 				nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
537 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
538 			break;
539 		}
540 		case NUBUS_RESID_NAME:
541 		{
542 			char name[64];
543 			unsigned int len;
544 
545 			len = nubus_get_rsrc_str(name, &ent, sizeof(name));
546 			pr_debug("    name: %s\n", name);
547 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
548 			break;
549 		}
550 		case NUBUS_RESID_DRVRDIR:
551 		{
552 			/* MacOS driver.  If we were NetBSD we might
553 			   use this :-) */
554 			pr_debug("    driver directory offset: 0x%06x\n",
555 				ent.data);
556 			nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
557 			break;
558 		}
559 		case NUBUS_RESID_MINOR_BASEOS:
560 		{
561 			/* We will need this in order to support
562 			   multiple framebuffers.  It might be handy
563 			   for Ethernet as well */
564 			u32 base_offset;
565 
566 			nubus_get_rsrc_mem(&base_offset, &ent, 4);
567 			pr_debug("    memory offset: 0x%08x\n", base_offset);
568 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
569 			break;
570 		}
571 		case NUBUS_RESID_MINOR_LENGTH:
572 		{
573 			/* Ditto */
574 			u32 length;
575 
576 			nubus_get_rsrc_mem(&length, &ent, 4);
577 			pr_debug("    memory length: 0x%08x\n", length);
578 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
579 			break;
580 		}
581 		case NUBUS_RESID_FLAGS:
582 			pr_debug("    flags: 0x%06x\n", ent.data);
583 			nubus_proc_add_rsrc(dir.procdir, &ent);
584 			break;
585 		case NUBUS_RESID_HWDEVID:
586 			pr_debug("    hwdevid: 0x%06x\n", ent.data);
587 			nubus_proc_add_rsrc(dir.procdir, &ent);
588 			break;
589 		default:
590 			/* Local/Private resources have their own
591 			   function */
592 			nubus_get_private_resource(dev, dir.procdir, &ent);
593 		}
594 	}
595 
596 	return dev;
597 }
598 
599 /* This is *really* cool. */
600 static int __init nubus_get_icon(struct nubus_board *board,
601 				 struct proc_dir_entry *procdir,
602 				 const struct nubus_dirent *ent)
603 {
604 	/* Should be 32x32 if my memory serves me correctly */
605 	u32 icon[32];
606 	int i;
607 
608 	nubus_get_rsrc_mem(&icon, ent, 128);
609 	pr_debug("    icon:\n");
610 	for (i = 0; i < 8; i++)
611 		pr_debug("        %08x %08x %08x %08x\n",
612 			icon[i * 4 + 0], icon[i * 4 + 1],
613 			icon[i * 4 + 2], icon[i * 4 + 3]);
614 	nubus_proc_add_rsrc_mem(procdir, ent, 128);
615 
616 	return 0;
617 }
618 
619 static int __init nubus_get_vendorinfo(struct nubus_board *board,
620 				       struct proc_dir_entry *procdir,
621 				       const struct nubus_dirent *parent)
622 {
623 	struct nubus_dir dir;
624 	struct nubus_dirent ent;
625 	static char *vendor_fields[6] = { "ID", "serial", "revision",
626 	                                  "part", "date", "unknown field" };
627 
628 	pr_debug("    vendor info:\n");
629 	nubus_get_subdir(parent, &dir);
630 	dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
631 
632 	while (nubus_readdir(&dir, &ent) != -1) {
633 		char name[64];
634 		unsigned int len;
635 
636 		/* These are all strings, we think */
637 		len = nubus_get_rsrc_str(name, &ent, sizeof(name));
638 		if (ent.type < 1 || ent.type > 5)
639 			ent.type = 5;
640 		pr_debug("    %s: %s\n", vendor_fields[ent.type - 1], name);
641 		nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
642 	}
643 	return 0;
644 }
645 
646 static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
647 					   const struct nubus_dirent *parent)
648 {
649 	struct nubus_dir dir;
650 	struct nubus_dirent ent;
651 
652 	pr_debug("  Board resource 0x%02x:\n", parent->type);
653 	nubus_get_subdir(parent, &dir);
654 	dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
655 
656 	while (nubus_readdir(&dir, &ent) != -1) {
657 		switch (ent.type) {
658 		case NUBUS_RESID_TYPE:
659 		{
660 			unsigned short nbtdata[4];
661 			/* This type is always the same, and is not
662 			   useful except insofar as it tells us that
663 			   we really are looking at a board resource. */
664 			nubus_get_rsrc_mem(nbtdata, &ent, 8);
665 			pr_debug("    type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
666 				nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
667 			if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
668 			    nbtdata[2] != 0 || nbtdata[3] != 0)
669 				pr_err("Slot %X: sResource is not a board resource!\n",
670 				       slot);
671 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
672 			break;
673 		}
674 		case NUBUS_RESID_NAME:
675 		{
676 			unsigned int len;
677 
678 			len = nubus_get_rsrc_str(board->name, &ent,
679 						 sizeof(board->name));
680 			pr_debug("    name: %s\n", board->name);
681 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
682 			break;
683 		}
684 		case NUBUS_RESID_ICON:
685 			nubus_get_icon(board, dir.procdir, &ent);
686 			break;
687 		case NUBUS_RESID_BOARDID:
688 			pr_debug("    board id: 0x%x\n", ent.data);
689 			nubus_proc_add_rsrc(dir.procdir, &ent);
690 			break;
691 		case NUBUS_RESID_PRIMARYINIT:
692 			pr_debug("    primary init offset: 0x%06x\n", ent.data);
693 			nubus_proc_add_rsrc(dir.procdir, &ent);
694 			break;
695 		case NUBUS_RESID_VENDORINFO:
696 			nubus_get_vendorinfo(board, dir.procdir, &ent);
697 			break;
698 		case NUBUS_RESID_FLAGS:
699 			pr_debug("    flags: 0x%06x\n", ent.data);
700 			nubus_proc_add_rsrc(dir.procdir, &ent);
701 			break;
702 		case NUBUS_RESID_HWDEVID:
703 			pr_debug("    hwdevid: 0x%06x\n", ent.data);
704 			nubus_proc_add_rsrc(dir.procdir, &ent);
705 			break;
706 		case NUBUS_RESID_SECONDINIT:
707 			pr_debug("    secondary init offset: 0x%06x\n",
708 				 ent.data);
709 			nubus_proc_add_rsrc(dir.procdir, &ent);
710 			break;
711 			/* WTF isn't this in the functional resources? */
712 		case NUBUS_RESID_VIDNAMES:
713 			pr_debug("    vidnames directory offset: 0x%06x\n",
714 				ent.data);
715 			nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
716 			break;
717 			/* Same goes for this */
718 		case NUBUS_RESID_VIDMODES:
719 			pr_debug("    video mode parameter directory offset: 0x%06x\n",
720 				ent.data);
721 			nubus_proc_add_rsrc(dir.procdir, &ent);
722 			break;
723 		default:
724 			pr_debug("    unknown resource 0x%02x, data 0x%06x\n",
725 				ent.type, ent.data);
726 			nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
727 		}
728 	}
729 	return 0;
730 }
731 
732 /* Add a board (might be many devices) to the list */
733 static struct nubus_board * __init nubus_add_board(int slot, int bytelanes)
734 {
735 	struct nubus_board *board;
736 	struct nubus_board **boardp;
737 	unsigned char *rp;
738 	unsigned long dpat;
739 	struct nubus_dir dir;
740 	struct nubus_dirent ent;
741 	int prev_resid = -1;
742 
743 	/* Move to the start of the format block */
744 	rp = nubus_rom_addr(slot);
745 	nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
746 
747 	/* Actually we should probably panic if this fails */
748 	if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
749 		return NULL;
750 	board->fblock = rp;
751 
752 	/* Dump the format block for debugging purposes */
753 	pr_debug("Slot %X, format block at 0x%p:\n", slot, rp);
754 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
755 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
756 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
757 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
758 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
759 	pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
760 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
761 	pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
762 	rp = board->fblock;
763 
764 	board->slot = slot;
765 	board->slot_addr = (unsigned long)nubus_slot_addr(slot);
766 	board->doffset = nubus_get_rom(&rp, 4, bytelanes);
767 	/* rom_length is *supposed* to be the total length of the
768 	 * ROM.  In practice it is the "amount of ROM used to compute
769 	 * the CRC."  So some jokers decide to set it to zero and
770 	 * set the crc to zero so they don't have to do any math.
771 	 * See the Performa 460 ROM, for example.  Those Apple "engineers".
772 	 */
773 	board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
774 	board->crc = nubus_get_rom(&rp, 4, bytelanes);
775 	board->rev = nubus_get_rom(&rp, 1, bytelanes);
776 	board->format = nubus_get_rom(&rp, 1, bytelanes);
777 	board->lanes = bytelanes;
778 
779 	/* Directory offset should be small and negative... */
780 	if (!(board->doffset & 0x00FF0000))
781 		pr_warn("Slot %X: Dodgy doffset!\n", slot);
782 	dpat = nubus_get_rom(&rp, 4, bytelanes);
783 	if (dpat != NUBUS_TEST_PATTERN)
784 		pr_warn("Slot %X: Wrong test pattern %08lx!\n", slot, dpat);
785 
786 	/*
787 	 *	I wonder how the CRC is meant to work -
788 	 *		any takers ?
789 	 * CSA: According to MAC docs, not all cards pass the CRC anyway,
790 	 * since the initial Macintosh ROM releases skipped the check.
791 	 */
792 
793 	/* Set up the directory pointer */
794 	board->directory = board->fblock;
795 	nubus_move(&board->directory, nubus_expand32(board->doffset),
796 	           board->lanes);
797 
798 	nubus_get_root_dir(board, &dir);
799 
800 	/* We're ready to rock */
801 	pr_debug("Slot %X resources:\n", slot);
802 
803 	/* Each slot should have one board resource and any number of
804 	   functional resources.  So we'll fill in some fields in the
805 	   struct nubus_board from the board resource, then walk down
806 	   the list of functional resources, spinning out a nubus_dev
807 	   for each of them. */
808 	if (nubus_readdir(&dir, &ent) == -1) {
809 		/* We can't have this! */
810 		pr_err("Slot %X: Board resource not found!\n", slot);
811 		return NULL;
812 	}
813 
814 	if (ent.type < 1 || ent.type > 127)
815 		pr_warn("Slot %X: Board resource ID is invalid!\n", slot);
816 
817 	board->procdir = nubus_proc_add_board(board);
818 
819 	nubus_get_board_resource(board, slot, &ent);
820 
821 	while (nubus_readdir(&dir, &ent) != -1) {
822 		struct nubus_dev *dev;
823 		struct nubus_dev **devp;
824 
825 		dev = nubus_get_functional_resource(board, slot, &ent);
826 		if (dev == NULL)
827 			continue;
828 
829 		/* Resources should appear in ascending ID order. This sanity
830 		 * check prevents duplicate resource IDs.
831 		 */
832 		if (dev->resid <= prev_resid) {
833 			kfree(dev);
834 			continue;
835 		}
836 		prev_resid = dev->resid;
837 
838 		/* We zeroed this out above */
839 		if (board->first_dev == NULL)
840 			board->first_dev = dev;
841 
842 		/* Put it on the global NuBus device chain. Keep entries in order. */
843 		for (devp = &nubus_devices; *devp != NULL;
844 		     devp = &((*devp)->next))
845 			/* spin */;
846 		*devp = dev;
847 		dev->next = NULL;
848 	}
849 
850 	/* Put it on the global NuBus board chain. Keep entries in order. */
851 	for (boardp = &nubus_boards; *boardp != NULL;
852 	     boardp = &((*boardp)->next))
853 		/* spin */;
854 	*boardp = board;
855 	board->next = NULL;
856 
857 	return board;
858 }
859 
860 static void __init nubus_probe_slot(int slot)
861 {
862 	unsigned char dp;
863 	unsigned char *rp;
864 	int i;
865 
866 	rp = nubus_rom_addr(slot);
867 	for (i = 4; i; i--) {
868 		rp--;
869 		if (!hwreg_present(rp))
870 			continue;
871 
872 		dp = *rp;
873 
874 		/* The last byte of the format block consists of two
875 		   nybbles which are "mirror images" of each other.
876 		   These show us the valid bytelanes */
877 		if ((((dp >> 4) ^ dp) & 0x0F) != 0x0F)
878 			continue;
879 		/* Check that this value is actually *on* one of the
880 		   bytelanes it claims are valid! */
881 		if (not_useful(rp, dp))
882 			continue;
883 
884 		/* Looks promising.  Let's put it on the list. */
885 		nubus_add_board(slot, dp);
886 
887 		return;
888 	}
889 }
890 
891 static void __init nubus_scan_bus(void)
892 {
893 	int slot;
894 
895 	pr_info("NuBus: Scanning NuBus slots.\n");
896 	for (slot = 9; slot < 15; slot++) {
897 		nubus_probe_slot(slot);
898 	}
899 }
900 
901 static int __init nubus_init(void)
902 {
903 	if (!MACH_IS_MAC)
904 		return 0;
905 
906 	nubus_proc_init();
907 	nubus_scan_bus();
908 	return 0;
909 }
910 
911 subsys_initcall(nubus_init);
912