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