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