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