ide: refactor tf_read() method
[linux-2.6] / drivers / nubus / nubus.c
1 /*
2  *      Macintosh Nubus Interface Code
3  *
4  *      Originally by Alan Cox
5  *
6  *      Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
7  *      and others.
8  */
9
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/string.h>
13 #include <linux/nubus.h>
14 #include <linux/errno.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/module.h>
18 #include <asm/setup.h>
19 #include <asm/system.h>
20 #include <asm/page.h>
21 #include <asm/hwtest.h>
22 #include <linux/proc_fs.h>
23 #include <asm/mac_via.h>
24 #include <asm/mac_oss.h>
25
26 extern void via_nubus_init(void);
27 extern void oss_nubus_init(void);
28
29 /* Constants */
30
31 /* This is, of course, the size in bytelanes, rather than the size in
32    actual bytes */
33 #define FORMAT_BLOCK_SIZE 20
34 #define ROM_DIR_OFFSET 0x24
35
36 #define NUBUS_TEST_PATTERN 0x5A932BC7
37
38 /* Define this if you like to live dangerously - it is known not to
39    work on pretty much every machine except the Quadra 630 and the LC
40    III. */
41 #undef I_WANT_TO_PROBE_SLOT_ZERO
42
43 /* This sometimes helps combat failure to boot */
44 #undef TRY_TO_DODGE_WSOD
45
46 /* Globals */
47
48 struct nubus_dev*   nubus_devices;
49 struct nubus_board* nubus_boards;
50
51 /* Meaning of "bytelanes":
52
53    The card ROM may appear on any or all bytes of each long word in
54    NuBus memory.  The low 4 bits of the "map" value found in the
55    format block (at the top of the slot address space, as well as at
56    the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
57    offsets within each longword, are valid.  Thus:
58
59    A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
60    are valid.
61
62    A map of 0xf0 means that no bytelanes are valid (We pray that we
63    will never encounter this, but stranger things have happened)
64
65    A map of 0xe1 means that only the MSB of each long word is actually
66    part of the card ROM.  (We hope to never encounter NuBus on a
67    little-endian machine.  Again, stranger things have happened)
68
69    A map of 0x78 means that only the LSB of each long word is valid.
70
71    Etcetera, etcetera.  Hopefully this clears up some confusion over
72    what the following code actually does.  */
73  
74 static inline int not_useful(void *p, int map)
75 {
76         unsigned long pv=(unsigned long)p;
77         pv &= 3;
78         if(map & (1<<pv))
79                 return 0;
80         return 1;
81 }
82  
83 static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map)
84 {
85         /* This will hold the result */
86         unsigned long v = 0;
87         unsigned char *p = *ptr;
88
89         while(len)
90         {
91                 v <<= 8;
92                 while(not_useful(p,map))
93                         p++;
94                 v |= *p++;
95                 len--;
96         }
97         *ptr = p;
98         return v;
99 }
100
101 static void nubus_rewind(unsigned char **ptr, int len, int map)
102 {
103         unsigned char *p=*ptr;
104
105         /* Sanity check */
106         if(len > 65536)
107                 printk(KERN_ERR "rewind of 0x%08x!\n", len);
108         while(len)
109         {
110                 do
111                 {
112                         p--;
113                 }
114                 while(not_useful(p, map));
115                 len--;
116         }
117         *ptr=p;
118 }
119
120 static void nubus_advance(unsigned char **ptr, int len, int map)
121 {
122         unsigned char *p = *ptr;
123         if(len>65536)
124                 printk(KERN_ERR "advance of 0x%08x!\n", len);
125         while(len)
126         {
127                 while(not_useful(p,map))
128                         p++;
129                 p++;
130                 len--;
131         }
132         *ptr = p;
133 }
134
135 static void nubus_move(unsigned char **ptr, int len, int map)
136 {
137         if(len > 0)
138                 nubus_advance(ptr, len, map);
139         else if(len < 0)
140                 nubus_rewind(ptr, -len, map);
141 }
142
143 /* Now, functions to read the sResource tree */
144
145 /* Each sResource entry consists of a 1-byte ID and a 3-byte data
146    field.  If that data field contains an offset, then obviously we
147    have to expand it from a 24-bit signed number to a 32-bit signed
148    number. */
149
150 static inline long nubus_expand32(long foo)
151 {
152         if(foo & 0x00800000)    /* 24bit negative */
153                 foo |= 0xFF000000;
154         return foo;
155 }
156
157 static inline void *nubus_rom_addr(int slot)
158 {       
159         /*
160          *      Returns the first byte after the card. We then walk
161          *      backwards to get the lane register and the config
162          */
163         return (void *)(0xF1000000+(slot<<24));
164 }
165
166 static unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
167 {
168         unsigned char *p = nd->base;
169         /* Essentially, just step over the bytelanes using whatever
170            offset we might have found */
171         nubus_move(&p, nubus_expand32(nd->data), nd->mask);
172         /* And return the value */
173         return p;
174 }
175
176 /* These two are for pulling resource data blocks (i.e. stuff that's
177    pointed to with offsets) out of the card ROM. */
178
179 void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent* dirent,
180                         int len)
181 {
182         unsigned char *t = (unsigned char *)dest;
183         unsigned char *p = nubus_dirptr(dirent);
184         while(len)
185         {
186                 *t++ = nubus_get_rom(&p, 1, dirent->mask);
187                 len--;
188         }
189 }
190 EXPORT_SYMBOL(nubus_get_rsrc_mem);
191
192 void nubus_get_rsrc_str(void *dest, const struct nubus_dirent* dirent,
193                         int len)
194 {
195         unsigned char *t=(unsigned char *)dest;
196         unsigned char *p = nubus_dirptr(dirent);
197         while(len)
198         {
199                 *t = nubus_get_rom(&p, 1, dirent->mask);
200                 if(!*t++)
201                         break;
202                 len--;
203         }
204 }
205 EXPORT_SYMBOL(nubus_get_rsrc_str);
206
207 int nubus_get_root_dir(const struct nubus_board* board,
208                        struct nubus_dir* dir)
209 {
210         dir->ptr = dir->base = board->directory;
211         dir->done = 0;
212         dir->mask = board->lanes;
213         return 0;
214 }
215 EXPORT_SYMBOL(nubus_get_root_dir);
216
217 /* This is a slyly renamed version of the above */
218 int nubus_get_func_dir(const struct nubus_dev* dev,
219                        struct nubus_dir* dir)
220 {
221         dir->ptr = dir->base = dev->directory;
222         dir->done = 0;
223         dir->mask = dev->board->lanes;
224         return 0;
225 }
226 EXPORT_SYMBOL(nubus_get_func_dir);
227
228 int nubus_get_board_dir(const struct nubus_board* board,
229                         struct nubus_dir* dir)
230 {
231         struct nubus_dirent ent;
232         
233         dir->ptr = dir->base = board->directory;
234         dir->done = 0;
235         dir->mask = board->lanes;
236
237         /* Now dereference it (the first directory is always the board
238            directory) */
239         if (nubus_readdir(dir, &ent) == -1)
240                 return -1;
241         if (nubus_get_subdir(&ent, dir) == -1)
242                 return -1;
243         return 0;
244 }
245 EXPORT_SYMBOL(nubus_get_board_dir);
246
247 int nubus_get_subdir(const struct nubus_dirent *ent,
248                      struct nubus_dir *dir)
249 {
250         dir->ptr = dir->base = nubus_dirptr(ent);
251         dir->done = 0;
252         dir->mask = ent->mask;
253         return 0;
254 }
255 EXPORT_SYMBOL(nubus_get_subdir);
256
257 int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
258 {
259         u32 resid;
260         if (nd->done)
261                 return -1;
262
263         /* Do this first, otherwise nubus_rewind & co are off by 4 */
264         ent->base = nd->ptr;
265
266         /* This moves nd->ptr forward */
267         resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
268
269         /* EOL marker, as per the Apple docs */
270         if((resid&0xff000000) == 0xff000000)
271         {
272                 /* Mark it as done */
273                 nd->done = 1;
274                 return -1;
275         }
276
277         /* First byte is the resource ID */
278         ent->type  = resid >> 24;
279         /* Low 3 bytes might contain data (or might not) */
280         ent->data = resid & 0xffffff;
281         ent->mask  = nd->mask;
282         return 0;
283 }
284 EXPORT_SYMBOL(nubus_readdir);
285
286 int nubus_rewinddir(struct nubus_dir* dir)
287 {
288         dir->ptr = dir->base;
289         return 0;
290 }
291 EXPORT_SYMBOL(nubus_rewinddir);
292
293 /* Driver interface functions, more or less like in pci.c */
294
295 struct nubus_dev*
296 nubus_find_device(unsigned short category,
297                   unsigned short type,
298                   unsigned short dr_hw,
299                   unsigned short dr_sw,
300                   const struct nubus_dev* from)
301 {
302         struct nubus_dev* itor =
303                 from ? from->next : nubus_devices;
304
305         while (itor) {
306                 if (itor->category == category
307                     && itor->type == type
308                     && itor->dr_hw == dr_hw
309                     && itor->dr_sw == dr_sw)
310                         return itor;
311                 itor = itor->next;
312         }
313         return NULL;
314 }
315 EXPORT_SYMBOL(nubus_find_device);
316
317 struct nubus_dev*
318 nubus_find_type(unsigned short category,
319                 unsigned short type,
320                 const struct nubus_dev* from)
321 {
322         struct nubus_dev* itor =
323                 from ? from->next : nubus_devices;
324
325         while (itor) {
326                 if (itor->category == category
327                     && itor->type == type)
328                         return itor;
329                 itor = itor->next;
330         }
331         return NULL;
332 }
333 EXPORT_SYMBOL(nubus_find_type);
334
335 struct nubus_dev*
336 nubus_find_slot(unsigned int slot,
337                 const struct nubus_dev* from)
338 {
339         struct nubus_dev* itor =
340                 from ? from->next : nubus_devices;
341         
342         while (itor) {
343                 if (itor->board->slot == slot)
344                         return itor;
345                 itor = itor->next;
346         }
347         return NULL;
348 }
349 EXPORT_SYMBOL(nubus_find_slot);
350
351 int
352 nubus_find_rsrc(struct nubus_dir* dir, unsigned char rsrc_type,
353                 struct nubus_dirent* ent)
354 {
355         while (nubus_readdir(dir, ent) != -1) {
356                 if (ent->type == rsrc_type)
357                         return 0;
358         }       
359         return -1;
360 }
361 EXPORT_SYMBOL(nubus_find_rsrc);
362
363 /* Initialization functions - decide which slots contain stuff worth
364    looking at, and print out lots and lots of information from the
365    resource blocks. */
366
367 /* FIXME: A lot of this stuff will eventually be useful after
368    initialization, for intelligently probing Ethernet and video chips,
369    among other things.  The rest of it should go in the /proc code.
370    For now, we just use it to give verbose boot logs. */
371
372 static int __init nubus_show_display_resource(struct nubus_dev* dev,
373                                               const struct nubus_dirent* ent)
374 {
375         switch (ent->type) {
376         case NUBUS_RESID_GAMMADIR:
377                 printk(KERN_INFO "    gamma directory offset: 0x%06x\n", ent->data);
378                 break;
379         case 0x0080 ... 0x0085:
380                 printk(KERN_INFO "    mode %02X info offset: 0x%06x\n",
381                        ent->type, ent->data);
382                 break;
383         default:
384                 printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
385                        ent->type, ent->data);
386         }
387         return 0;
388 }
389
390 static int __init nubus_show_network_resource(struct nubus_dev* dev,
391                                               const struct nubus_dirent* ent)
392 {
393         switch (ent->type) {
394         case NUBUS_RESID_MAC_ADDRESS:
395         {
396                 char addr[6];
397                 int i;
398                 
399                 nubus_get_rsrc_mem(addr, ent, 6);
400                 printk(KERN_INFO "    MAC address: ");
401                 for (i = 0; i < 6; i++)
402                         printk("%02x%s", addr[i] & 0xff,
403                                i == 5 ? "" : ":");
404                 printk("\n");
405                 break;
406         }
407         default:
408                 printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
409                        ent->type, ent->data);
410         }
411         return 0;
412 }
413
414 static int __init nubus_show_cpu_resource(struct nubus_dev* dev,
415                                           const struct nubus_dirent* ent)
416 {
417         switch (ent->type) {
418         case NUBUS_RESID_MEMINFO:
419         {
420                 unsigned long meminfo[2];
421                 nubus_get_rsrc_mem(&meminfo, ent, 8);
422                 printk(KERN_INFO "    memory: [ 0x%08lx 0x%08lx ]\n",
423                        meminfo[0], meminfo[1]);
424                 break;
425         }
426         case NUBUS_RESID_ROMINFO:
427         {
428                 unsigned long rominfo[2];
429                 nubus_get_rsrc_mem(&rominfo, ent, 8);
430                 printk(KERN_INFO "    ROM:    [ 0x%08lx 0x%08lx ]\n",
431                        rominfo[0], rominfo[1]);
432                 break;
433         }
434         default:
435                 printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
436                        ent->type, ent->data);
437         }
438         return 0;
439 }
440
441 static int __init nubus_show_private_resource(struct nubus_dev* dev,
442                                               const struct nubus_dirent* ent)
443 {
444         switch (dev->category) {
445         case NUBUS_CAT_DISPLAY:
446                 nubus_show_display_resource(dev, ent);
447                 break;
448         case NUBUS_CAT_NETWORK:
449                 nubus_show_network_resource(dev, ent);
450                 break;
451         case NUBUS_CAT_CPU:
452                 nubus_show_cpu_resource(dev, ent);
453                 break;
454         default:
455                 printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
456                        ent->type, ent->data);
457         }
458         return 0;
459 }
460
461 static struct nubus_dev* __init
462            nubus_get_functional_resource(struct nubus_board* board,
463                                          int slot,
464                                          const struct nubus_dirent* parent)
465 {
466         struct nubus_dir    dir;
467         struct nubus_dirent ent;
468         struct nubus_dev*   dev;
469         
470         printk(KERN_INFO "  Function 0x%02x:\n", parent->type);
471         nubus_get_subdir(parent, &dir);
472
473         /* Apple seems to have botched the ROM on the IIx */
474         if (slot == 0 && (unsigned long)dir.base % 2)
475                 dir.base += 1;
476         
477         if (console_loglevel >= 10)
478                 printk(KERN_DEBUG "nubus_get_functional_resource: parent is 0x%p, dir is 0x%p\n",
479                        parent->base, dir.base);
480
481         /* Actually we should probably panic if this fails */
482         if ((dev = kzalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
483                 return NULL;    
484         dev->resid = parent->type;
485         dev->directory = dir.base;
486         dev->board = board;
487         
488         while (nubus_readdir(&dir, &ent) != -1)
489         {
490                 switch(ent.type)
491                 {
492                 case NUBUS_RESID_TYPE:
493                 {
494                         unsigned short nbtdata[4];
495                         nubus_get_rsrc_mem(nbtdata, &ent, 8);
496                         dev->category = nbtdata[0];
497                         dev->type     = nbtdata[1];
498                         dev->dr_sw    = nbtdata[2];
499                         dev->dr_hw    = nbtdata[3];
500                         printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
501                                nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
502                         break;
503                 }
504                 case NUBUS_RESID_NAME:
505                 {
506                         nubus_get_rsrc_str(dev->name, &ent, 64);
507                         printk(KERN_INFO "    name: %s\n", dev->name);
508                         break;
509                 }
510                 case NUBUS_RESID_DRVRDIR:
511                 {
512                         /* MacOS driver.  If we were NetBSD we might
513                            use this :-) */
514                         struct nubus_dir drvr_dir;
515                         struct nubus_dirent drvr_ent;
516                         nubus_get_subdir(&ent, &drvr_dir);
517                         nubus_readdir(&drvr_dir, &drvr_ent);
518                         dev->driver = nubus_dirptr(&drvr_ent);
519                         printk(KERN_INFO "    driver at: 0x%p\n",
520                                dev->driver);
521                         break;
522                 }
523                 case NUBUS_RESID_MINOR_BASEOS:
524                         /* We will need this in order to support
525                            multiple framebuffers.  It might be handy
526                            for Ethernet as well */
527                         nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
528                         printk(KERN_INFO "    memory offset: 0x%08lx\n",
529                                dev->iobase);
530                         break;
531                 case NUBUS_RESID_MINOR_LENGTH:
532                         /* Ditto */
533                         nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
534                         printk(KERN_INFO "    memory length: 0x%08lx\n",
535                                dev->iosize);
536                         break;                  
537                 case NUBUS_RESID_FLAGS:
538                         dev->flags = ent.data;
539                         printk(KERN_INFO "    flags: 0x%06x\n", dev->flags);
540                         break;
541                 case NUBUS_RESID_HWDEVID:
542                         dev->hwdevid = ent.data;
543                         printk(KERN_INFO "    hwdevid: 0x%06x\n", dev->hwdevid);
544                         break;
545                 default:
546                         /* Local/Private resources have their own
547                            function */
548                         nubus_show_private_resource(dev, &ent);
549                 }
550         }
551                 
552         return dev;
553 }
554
555 /* This is cool. */
556 static int __init nubus_get_vidnames(struct nubus_board* board,
557                                      const struct nubus_dirent* parent)
558 {
559         struct nubus_dir    dir;
560         struct nubus_dirent ent;
561         /* FIXME: obviously we want to put this in a header file soon */
562         struct vidmode {
563                 u32 size;
564                 /* Don't know what this is yet */
565                 u16 id;
566                 /* Longest one I've seen so far is 26 characters */
567                 char name[32];
568         };
569
570         printk(KERN_INFO "    video modes supported:\n");
571         nubus_get_subdir(parent, &dir);
572         if (console_loglevel >= 10)
573                 printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",
574                        parent->base, dir.base);
575
576         while(nubus_readdir(&dir, &ent) != -1)
577         {
578                 struct vidmode mode;
579                 u32 size;
580
581                 /* First get the length */
582                 nubus_get_rsrc_mem(&size, &ent, 4);
583                 
584                 /* Now clobber the whole thing */
585                 if (size > sizeof(mode) - 1)
586                         size = sizeof(mode) - 1;
587                 memset(&mode, 0, sizeof(mode));
588                 nubus_get_rsrc_mem(&mode, &ent, size);
589                 printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,
590                         mode.id, mode.name);
591         }
592         return 0;
593 }
594
595 /* This is *really* cool. */
596 static int __init nubus_get_icon(struct nubus_board* board,
597                                  const struct nubus_dirent* ent)
598 {
599         /* Should be 32x32 if my memory serves me correctly */
600         unsigned char icon[128];
601         int x, y;
602         
603         nubus_get_rsrc_mem(&icon, ent, 128);
604         printk(KERN_INFO "    icon:\n");
605
606         /* We should actually plot these somewhere in the framebuffer
607            init.  This is just to demonstrate that they do, in fact,
608            exist */
609         for (y = 0; y < 32; y++) {
610                 printk(KERN_INFO "      ");
611                 for (x = 0; x < 32; x++) {
612                         if (icon[y*4 + x/8]
613                             & (0x80 >> (x%8)))
614                                 printk("*");
615                         else
616                                 printk(" ");
617                 }
618                 printk("\n");
619         }
620         return 0;
621 }
622
623 static int __init nubus_get_vendorinfo(struct nubus_board* board,
624                                        const struct nubus_dirent* parent)
625 {
626         struct nubus_dir    dir;
627         struct nubus_dirent ent;
628         static char* vendor_fields[6] = {"ID", "serial", "revision",
629                                          "part", "date", "unknown field"};
630
631         printk(KERN_INFO "    vendor info:\n");
632         nubus_get_subdir(parent, &dir);
633         if (console_loglevel >= 10)
634                 printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",
635                        parent->base, dir.base);
636
637         while(nubus_readdir(&dir, &ent) != -1)
638         {
639                 char name[64];
640                 
641                 /* These are all strings, we think */
642                 nubus_get_rsrc_str(name, &ent, 64);
643                 if (ent.type > 5)
644                         ent.type = 5;
645                 printk(KERN_INFO "    %s: %s\n",
646                        vendor_fields[ent.type-1], name);
647         }
648         return 0;
649 }
650
651 static int __init nubus_get_board_resource(struct nubus_board* board, int slot,
652                                            const struct nubus_dirent* parent)
653 {
654         struct nubus_dir    dir;
655         struct nubus_dirent ent;
656         
657         nubus_get_subdir(parent, &dir);
658         if (console_loglevel >= 10)
659                 printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
660                        parent->base, dir.base);
661
662         while(nubus_readdir(&dir, &ent) != -1)
663         {
664                 switch (ent.type) {
665                 case NUBUS_RESID_TYPE:
666                 {
667                         unsigned short nbtdata[4];
668                         /* This type is always the same, and is not
669                            useful except insofar as it tells us that
670                            we really are looking at a board resource. */
671                         nubus_get_rsrc_mem(nbtdata, &ent, 8);
672                         printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
673                                nbtdata[0], nbtdata[1], nbtdata[2],
674                                nbtdata[3]);
675                         if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
676                             nbtdata[2] != 0 || nbtdata[3] != 0)
677                                 printk(KERN_ERR "this sResource is not a board resource!\n");
678                         break;
679                 }
680                 case NUBUS_RESID_NAME:
681                         nubus_get_rsrc_str(board->name, &ent, 64);
682                         printk(KERN_INFO "    name: %s\n", board->name);
683                         break;
684                 case NUBUS_RESID_ICON:
685                         nubus_get_icon(board, &ent);
686                         break;
687                 case NUBUS_RESID_BOARDID:
688                         printk(KERN_INFO "    board id: 0x%x\n", ent.data);
689                         break;
690                 case NUBUS_RESID_PRIMARYINIT:
691                         printk(KERN_INFO "    primary init offset: 0x%06x\n", ent.data);
692                         break;
693                 case NUBUS_RESID_VENDORINFO:
694                         nubus_get_vendorinfo(board, &ent);
695                         break;
696                 case NUBUS_RESID_FLAGS:
697                         printk(KERN_INFO "    flags: 0x%06x\n", ent.data);
698                         break;
699                 case NUBUS_RESID_HWDEVID:
700                         printk(KERN_INFO "    hwdevid: 0x%06x\n", ent.data);
701                         break;
702                 case NUBUS_RESID_SECONDINIT:
703                         printk(KERN_INFO "    secondary init offset: 0x%06x\n", ent.data);
704                         break;
705                         /* WTF isn't this in the functional resources? */ 
706                 case NUBUS_RESID_VIDNAMES:
707                         nubus_get_vidnames(board, &ent);
708                         break;
709                         /* Same goes for this */
710                 case NUBUS_RESID_VIDMODES:
711                         printk(KERN_INFO "    video mode parameter directory offset: 0x%06x\n",
712                                ent.data);
713                         break;                  
714                 default:
715                         printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
716                                ent.type, ent.data);
717                 }
718         }
719         return 0;
720 }
721
722 /* Attempt to bypass the somewhat non-obvious arrangement of
723    sResources in the motherboard ROM */
724 static void __init nubus_find_rom_dir(struct nubus_board* board)
725 {
726         unsigned char* rp;
727         unsigned char* romdir;
728         struct nubus_dir dir;
729         struct nubus_dirent ent;
730
731         /* Check for the extra directory just under the format block */
732         rp = board->fblock;
733         nubus_rewind(&rp, 4, board->lanes);
734         if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {
735                 /* OK, the ROM was telling the truth */
736                 board->directory = board->fblock;
737                 nubus_move(&board->directory,
738                            nubus_expand32(board->doffset),
739                            board->lanes);
740                 return;
741         }
742
743         /* On "slot zero", you have to walk down a few more
744            directories to get to the equivalent of a real card's root
745            directory.  We don't know what they were smoking when they
746            came up with this. */
747         romdir = nubus_rom_addr(board->slot);
748         nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);
749         dir.base = dir.ptr = romdir;
750         dir.done = 0;
751         dir.mask = board->lanes;
752
753         /* This one points to an "Unknown Macintosh" directory */
754         if (nubus_readdir(&dir, &ent) == -1)
755                 goto badrom;
756
757         if (console_loglevel >= 10)
758                 printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
759         /* This one takes us to where we want to go. */
760         if (nubus_readdir(&dir, &ent) == -1) 
761                 goto badrom;
762         if (console_loglevel >= 10)
763                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
764         nubus_get_subdir(&ent, &dir);
765
766         /* Resource ID 01, also an "Unknown Macintosh" */
767         if (nubus_readdir(&dir, &ent) == -1) 
768                 goto badrom;
769         if (console_loglevel >= 10)
770                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
771
772         /* FIXME: the first one is *not* always the right one.  We
773            suspect this has something to do with the ROM revision.
774            "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR
775            Continues" (Q630) uses 0x7b.  The DAFB Macs evidently use
776            something else.  Please run "Slots" on your Mac (see
777            include/linux/nubus.h for where to get this program) and
778            tell us where the 'SiDirPtr' for Slot 0 is.  If you feel
779            brave, you should also use MacsBug to walk down the ROM
780            directories like this function does and try to find the
781            path to that address... */
782         if (nubus_readdir(&dir, &ent) == -1)
783                 goto badrom;
784         if (console_loglevel >= 10)
785                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
786         
787         /* Bwahahahaha... */
788         nubus_get_subdir(&ent, &dir);
789         board->directory = dir.base;
790         return;
791         
792         /* Even more evil laughter... */
793  badrom:
794         board->directory = board->fblock;
795         nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);
796         printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness!  Notify the developers...\n");
797 }
798
799 /* Add a board (might be many devices) to the list */
800 static struct nubus_board* __init nubus_add_board(int slot, int bytelanes)
801 {
802         struct nubus_board* board;
803         struct nubus_board** boardp;
804
805         unsigned char *rp;
806         unsigned long dpat;
807         struct nubus_dir dir;
808         struct nubus_dirent ent;
809
810         /* Move to the start of the format block */
811         rp = nubus_rom_addr(slot);              
812         nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
813
814         /* Actually we should probably panic if this fails */
815         if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
816                 return NULL;    
817         board->fblock = rp;
818
819         /* Dump the format block for debugging purposes */
820         if (console_loglevel >= 10) {
821                 int i;
822                 printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",
823                        slot, rp);
824                 printk(KERN_DEBUG "Format block: ");
825                 for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {
826                         unsigned short foo, bar;
827                         foo = nubus_get_rom(&rp, 2, bytelanes);
828                         bar = nubus_get_rom(&rp, 2, bytelanes);
829                         printk("%04x %04x  ", foo, bar);
830                 }
831                 printk("\n");
832                 rp = board->fblock;
833         }
834         
835         board->slot = slot;
836         board->slot_addr = (unsigned long) nubus_slot_addr(slot);
837         board->doffset = nubus_get_rom(&rp, 4, bytelanes);
838         /* rom_length is *supposed* to be the total length of the
839          * ROM.  In practice it is the "amount of ROM used to compute
840          * the CRC."  So some jokers decide to set it to zero and
841          * set the crc to zero so they don't have to do any math.
842          * See the Performa 460 ROM, for example.  Those Apple "engineers".
843          */
844         board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
845         board->crc = nubus_get_rom(&rp, 4, bytelanes);
846         board->rev = nubus_get_rom(&rp, 1, bytelanes);
847         board->format = nubus_get_rom(&rp,1, bytelanes);
848         board->lanes = bytelanes;
849
850         /* Directory offset should be small and negative... */
851         if(!(board->doffset & 0x00FF0000))
852                 printk(KERN_WARNING "Dodgy doffset!\n");
853         dpat = nubus_get_rom(&rp, 4, bytelanes);
854         if(dpat != NUBUS_TEST_PATTERN)
855                 printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);
856                 
857         /*
858          *      I wonder how the CRC is meant to work -
859          *              any takers ?
860          * CSA: According to MAC docs, not all cards pass the CRC anyway,
861          * since the initial Macintosh ROM releases skipped the check.
862          */
863
864         /* Attempt to work around slot zero weirdness */
865         nubus_find_rom_dir(board);
866         nubus_get_root_dir(board, &dir);        
867
868         /* We're ready to rock */
869         printk(KERN_INFO "Slot %X:\n", slot);
870
871         /* Each slot should have one board resource and any number of
872            functional resources.  So we'll fill in some fields in the
873            struct nubus_board from the board resource, then walk down
874            the list of functional resources, spinning out a nubus_dev
875            for each of them. */
876         if (nubus_readdir(&dir, &ent) == -1) {
877                 /* We can't have this! */
878                 printk(KERN_ERR "Board resource not found!\n");
879                 return NULL;
880         } else {
881                 printk(KERN_INFO "  Board resource:\n");
882                 nubus_get_board_resource(board, slot, &ent);
883         }
884
885         /* Aaaarrrrgghh!  The LC III motherboard has *two* board
886            resources.  I have no idea WTF to do about this. */
887
888         while (nubus_readdir(&dir, &ent) != -1) {
889                 struct nubus_dev*  dev;
890                 struct nubus_dev** devp;
891                 dev = nubus_get_functional_resource(board, slot, &ent);
892                 if (dev == NULL)
893                         continue;
894
895                 /* We zeroed this out above */
896                 if (board->first_dev == NULL)
897                         board->first_dev = dev;
898                 
899                 /* Put it on the global NuBus device chain. Keep entries in order. */
900                 for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))
901                         /* spin */;
902                 *devp = dev;
903                 dev->next = NULL;               
904         }
905
906         /* Put it on the global NuBus board chain. Keep entries in order. */
907         for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))
908                 /* spin */;
909         *boardp = board;
910         board->next = NULL;
911         
912         return board;
913 }
914
915 void __init nubus_probe_slot(int slot)
916 {
917         unsigned char dp;
918         unsigned char* rp;
919         int i;
920
921         rp = nubus_rom_addr(slot);      
922         for(i = 4; i; i--)
923         {
924                 unsigned long flags;
925                 int card_present;
926
927                 rp--;
928                 local_irq_save(flags);
929                 card_present = hwreg_present(rp);
930                 local_irq_restore(flags);
931                
932                 if (!card_present)
933                         continue;
934
935                 printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);
936                 dp = *rp;
937                 if(dp == 0)
938                         continue;
939
940                 /* The last byte of the format block consists of two
941                    nybbles which are "mirror images" of each other.
942                    These show us the valid bytelanes */
943                 if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
944                         continue;
945                 /* Check that this value is actually *on* one of the
946                    bytelanes it claims are valid! */
947                 if ((dp & 0x0F) >= (1<<i))
948                         continue;
949
950                 /* Looks promising.  Let's put it on the list. */
951                 nubus_add_board(slot, dp);
952
953                 return;
954         }
955 }
956
957 #if defined(CONFIG_PROC_FS)
958
959 /* /proc/nubus stuff */
960
961 static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
962 {
963         if(len < 100)
964                 return -1;
965         
966         sprintf(ptr, "Slot %X: %s\n",
967                 board->slot, board->name);
968         
969         return strlen(ptr);
970 }
971
972 static int nubus_read_proc(char *page, char **start, off_t off,
973                                 int count, int *eof, void *data)
974 {
975         int nprinted, len, begin = 0;
976         int size = PAGE_SIZE;
977         struct nubus_board* board;
978         
979         len   = sprintf(page, "Nubus devices found:\n");
980         /* Walk the list of NuBus boards */
981         for (board = nubus_boards; board != NULL; board = board->next)
982         {
983                 nprinted = sprint_nubus_board(board, page + len, size - len);
984                 if (nprinted < 0)
985                         break;
986                 len += nprinted;
987                 if (len+begin < off) {
988                         begin += len;
989                         len = 0;
990                 }
991                 if (len+begin >= off+count)
992                         break;
993         }
994         if (len+begin < off)
995                 *eof = 1;
996         off -= begin;
997         *start = page + off;
998         len -= off;
999         if (len>count)
1000                 len = count;
1001         if (len<0)
1002                 len = 0;
1003         return len;
1004 }
1005 #endif
1006
1007 void __init nubus_scan_bus(void)
1008 {
1009         int slot;
1010         /* This might not work on your machine */
1011 #ifdef I_WANT_TO_PROBE_SLOT_ZERO
1012         nubus_probe_slot(0);
1013 #endif
1014         for(slot = 9; slot < 15; slot++)
1015         {
1016                 nubus_probe_slot(slot);
1017         }
1018 }
1019
1020 static int __init nubus_init(void)
1021 {
1022         if (!MACH_IS_MAC) 
1023                 return 0;
1024
1025         /* Initialize the NuBus interrupts */
1026         if (oss_present) {
1027                 oss_nubus_init();
1028         } else {
1029                 via_nubus_init();
1030         }
1031
1032 #ifdef TRY_TO_DODGE_WSOD
1033         /* Rogue Ethernet interrupts can kill the machine if we don't
1034            do this.  Obviously this is bogus.  Hopefully the local VIA
1035            gurus can fix the real cause of the problem. */
1036         mdelay(1000);
1037 #endif
1038         
1039         /* And probe */
1040         printk("NuBus: Scanning NuBus slots.\n");
1041         nubus_devices = NULL;
1042         nubus_boards  = NULL;
1043         nubus_scan_bus();
1044
1045 #ifdef CONFIG_PROC_FS
1046         create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
1047         nubus_proc_init();
1048 #endif
1049         return 0;
1050 }
1051
1052 subsys_initcall(nubus_init);