[VLAN]: Avoid a 4-order allocation.
[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 = kmalloc(sizeof(*dev), GFP_ATOMIC)) == NULL)
470                 return NULL;    
471         memset(dev, 0, sizeof(*dev));
472         dev->resid = parent->type;
473         dev->directory = dir.base;
474         dev->board = board;
475         
476         while (nubus_readdir(&dir, &ent) != -1)
477         {
478                 switch(ent.type)
479                 {
480                 case NUBUS_RESID_TYPE:
481                 {
482                         unsigned short nbtdata[4];
483                         nubus_get_rsrc_mem(nbtdata, &ent, 8);
484                         dev->category = nbtdata[0];
485                         dev->type     = nbtdata[1];
486                         dev->dr_sw    = nbtdata[2];
487                         dev->dr_hw    = nbtdata[3];
488                         printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
489                                nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
490                         break;
491                 }
492                 case NUBUS_RESID_NAME:
493                 {
494                         nubus_get_rsrc_str(dev->name, &ent, 64);
495                         printk(KERN_INFO "    name: %s\n", dev->name);
496                         break;
497                 }
498                 case NUBUS_RESID_DRVRDIR:
499                 {
500                         /* MacOS driver.  If we were NetBSD we might
501                            use this :-) */
502                         struct nubus_dir drvr_dir;
503                         struct nubus_dirent drvr_ent;
504                         nubus_get_subdir(&ent, &drvr_dir);
505                         nubus_readdir(&drvr_dir, &drvr_ent);
506                         dev->driver = nubus_dirptr(&drvr_ent);
507                         printk(KERN_INFO "    driver at: 0x%p\n",
508                                dev->driver);
509                         break;
510                 }
511                 case NUBUS_RESID_MINOR_BASEOS:
512                         /* We will need this in order to support
513                            multiple framebuffers.  It might be handy
514                            for Ethernet as well */
515                         nubus_get_rsrc_mem(&dev->iobase, &ent, 4);
516                         printk(KERN_INFO "    memory offset: 0x%08lx\n",
517                                dev->iobase);
518                         break;
519                 case NUBUS_RESID_MINOR_LENGTH:
520                         /* Ditto */
521                         nubus_get_rsrc_mem(&dev->iosize, &ent, 4);
522                         printk(KERN_INFO "    memory length: 0x%08lx\n",
523                                dev->iosize);
524                         break;                  
525                 case NUBUS_RESID_FLAGS:
526                         dev->flags = ent.data;
527                         printk(KERN_INFO "    flags: 0x%06x\n", dev->flags);
528                         break;
529                 case NUBUS_RESID_HWDEVID:
530                         dev->hwdevid = ent.data;
531                         printk(KERN_INFO "    hwdevid: 0x%06x\n", dev->hwdevid);
532                         break;
533                 default:
534                         /* Local/Private resources have their own
535                            function */
536                         nubus_show_private_resource(dev, &ent);
537                 }
538         }
539                 
540         return dev;
541 }
542
543 /* This is cool. */
544 static int __init nubus_get_vidnames(struct nubus_board* board,
545                                      const struct nubus_dirent* parent)
546 {
547         struct nubus_dir    dir;
548         struct nubus_dirent ent;
549         /* FIXME: obviously we want to put this in a header file soon */
550         struct vidmode {
551                 u32 size;
552                 /* Don't know what this is yet */
553                 u16 id;
554                 /* Longest one I've seen so far is 26 characters */
555                 char name[32];
556         };
557
558         printk(KERN_INFO "    video modes supported:\n");
559         nubus_get_subdir(parent, &dir);
560         if (console_loglevel >= 10)
561                 printk(KERN_DEBUG "nubus_get_vidnames: parent is 0x%p, dir is 0x%p\n",
562                        parent->base, dir.base);
563
564         while(nubus_readdir(&dir, &ent) != -1)
565         {
566                 struct vidmode mode;
567                 u32 size;
568
569                 /* First get the length */
570                 nubus_get_rsrc_mem(&size, &ent, 4);
571                 
572                 /* Now clobber the whole thing */
573                 if (size > sizeof(mode) - 1)
574                         size = sizeof(mode) - 1;
575                 memset(&mode, 0, sizeof(mode));
576                 nubus_get_rsrc_mem(&mode, &ent, size);
577                 printk (KERN_INFO "      %02X: (%02X) %s\n", ent.type,
578                         mode.id, mode.name);
579         }
580         return 0;
581 }
582
583 /* This is *really* cool. */
584 static int __init nubus_get_icon(struct nubus_board* board,
585                                  const struct nubus_dirent* ent)
586 {
587         /* Should be 32x32 if my memory serves me correctly */
588         unsigned char icon[128];
589         int x, y;
590         
591         nubus_get_rsrc_mem(&icon, ent, 128);
592         printk(KERN_INFO "    icon:\n");
593
594         /* We should actually plot these somewhere in the framebuffer
595            init.  This is just to demonstrate that they do, in fact,
596            exist */
597         for (y = 0; y < 32; y++) {
598                 printk(KERN_INFO "      ");
599                 for (x = 0; x < 32; x++) {
600                         if (icon[y*4 + x/8]
601                             & (0x80 >> (x%8)))
602                                 printk("*");
603                         else
604                                 printk(" ");
605                 }
606                 printk("\n");
607         }
608         return 0;
609 }
610
611 static int __init nubus_get_vendorinfo(struct nubus_board* board,
612                                        const struct nubus_dirent* parent)
613 {
614         struct nubus_dir    dir;
615         struct nubus_dirent ent;
616         static char* vendor_fields[6] = {"ID", "serial", "revision",
617                                          "part", "date", "unknown field"};
618
619         printk(KERN_INFO "    vendor info:\n");
620         nubus_get_subdir(parent, &dir);
621         if (console_loglevel >= 10)
622                 printk(KERN_DEBUG "nubus_get_vendorinfo: parent is 0x%p, dir is 0x%p\n",
623                        parent->base, dir.base);
624
625         while(nubus_readdir(&dir, &ent) != -1)
626         {
627                 char name[64];
628                 
629                 /* These are all strings, we think */
630                 nubus_get_rsrc_str(name, &ent, 64);
631                 if (ent.type > 5)
632                         ent.type = 5;
633                 printk(KERN_INFO "    %s: %s\n",
634                        vendor_fields[ent.type-1], name);
635         }
636         return 0;
637 }
638
639 static int __init nubus_get_board_resource(struct nubus_board* board, int slot,
640                                            const struct nubus_dirent* parent)
641 {
642         struct nubus_dir    dir;
643         struct nubus_dirent ent;
644         
645         nubus_get_subdir(parent, &dir);
646         if (console_loglevel >= 10)
647                 printk(KERN_DEBUG "nubus_get_board_resource: parent is 0x%p, dir is 0x%p\n",
648                        parent->base, dir.base);
649
650         while(nubus_readdir(&dir, &ent) != -1)
651         {
652                 switch (ent.type) {
653                 case NUBUS_RESID_TYPE:
654                 {
655                         unsigned short nbtdata[4];
656                         /* This type is always the same, and is not
657                            useful except insofar as it tells us that
658                            we really are looking at a board resource. */
659                         nubus_get_rsrc_mem(nbtdata, &ent, 8);
660                         printk(KERN_INFO "    type: [cat 0x%x type 0x%x hw 0x%x sw 0x%x]\n",
661                                nbtdata[0], nbtdata[1], nbtdata[2],
662                                nbtdata[3]);
663                         if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
664                             nbtdata[2] != 0 || nbtdata[3] != 0)
665                                 printk(KERN_ERR "this sResource is not a board resource!\n");
666                         break;
667                 }
668                 case NUBUS_RESID_NAME:
669                         nubus_get_rsrc_str(board->name, &ent, 64);
670                         printk(KERN_INFO "    name: %s\n", board->name);
671                         break;
672                 case NUBUS_RESID_ICON:
673                         nubus_get_icon(board, &ent);
674                         break;
675                 case NUBUS_RESID_BOARDID:
676                         printk(KERN_INFO "    board id: 0x%x\n", ent.data);
677                         break;
678                 case NUBUS_RESID_PRIMARYINIT:
679                         printk(KERN_INFO "    primary init offset: 0x%06x\n", ent.data);
680                         break;
681                 case NUBUS_RESID_VENDORINFO:
682                         nubus_get_vendorinfo(board, &ent);
683                         break;
684                 case NUBUS_RESID_FLAGS:
685                         printk(KERN_INFO "    flags: 0x%06x\n", ent.data);
686                         break;
687                 case NUBUS_RESID_HWDEVID:
688                         printk(KERN_INFO "    hwdevid: 0x%06x\n", ent.data);
689                         break;
690                 case NUBUS_RESID_SECONDINIT:
691                         printk(KERN_INFO "    secondary init offset: 0x%06x\n", ent.data);
692                         break;
693                         /* WTF isn't this in the functional resources? */ 
694                 case NUBUS_RESID_VIDNAMES:
695                         nubus_get_vidnames(board, &ent);
696                         break;
697                         /* Same goes for this */
698                 case NUBUS_RESID_VIDMODES:
699                         printk(KERN_INFO "    video mode parameter directory offset: 0x%06x\n",
700                                ent.data);
701                         break;                  
702                 default:
703                         printk(KERN_INFO "    unknown resource %02X, data 0x%06x\n",
704                                ent.type, ent.data);
705                 }
706         }
707         return 0;
708 }
709
710 /* Attempt to bypass the somewhat non-obvious arrangement of
711    sResources in the motherboard ROM */
712 static void __init nubus_find_rom_dir(struct nubus_board* board)
713 {
714         unsigned char* rp;
715         unsigned char* romdir;
716         struct nubus_dir dir;
717         struct nubus_dirent ent;
718
719         /* Check for the extra directory just under the format block */
720         rp = board->fblock;
721         nubus_rewind(&rp, 4, board->lanes);
722         if (nubus_get_rom(&rp, 4, board->lanes) != NUBUS_TEST_PATTERN) {
723                 /* OK, the ROM was telling the truth */
724                 board->directory = board->fblock;
725                 nubus_move(&board->directory,
726                            nubus_expand32(board->doffset),
727                            board->lanes);
728                 return;
729         }
730
731         /* On "slot zero", you have to walk down a few more
732            directories to get to the equivalent of a real card's root
733            directory.  We don't know what they were smoking when they
734            came up with this. */
735         romdir = nubus_rom_addr(board->slot);
736         nubus_rewind(&romdir, ROM_DIR_OFFSET, board->lanes);
737         dir.base = dir.ptr = romdir;
738         dir.done = 0;
739         dir.mask = board->lanes;
740
741         /* This one points to an "Unknown Macintosh" directory */
742         if (nubus_readdir(&dir, &ent) == -1)
743                 goto badrom;
744
745         if (console_loglevel >= 10)
746                 printk(KERN_INFO "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
747         /* This one takes us to where we want to go. */
748         if (nubus_readdir(&dir, &ent) == -1) 
749                 goto badrom;
750         if (console_loglevel >= 10)
751                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
752         nubus_get_subdir(&ent, &dir);
753
754         /* Resource ID 01, also an "Unknown Macintosh" */
755         if (nubus_readdir(&dir, &ent) == -1) 
756                 goto badrom;
757         if (console_loglevel >= 10)
758                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
759
760         /* FIXME: the first one is *not* always the right one.  We
761            suspect this has something to do with the ROM revision.
762            "The HORROR ROM" (LC-series) uses 0x7e, while "The HORROR
763            Continues" (Q630) uses 0x7b.  The DAFB Macs evidently use
764            something else.  Please run "Slots" on your Mac (see
765            include/linux/nubus.h for where to get this program) and
766            tell us where the 'SiDirPtr' for Slot 0 is.  If you feel
767            brave, you should also use MacsBug to walk down the ROM
768            directories like this function does and try to find the
769            path to that address... */
770         if (nubus_readdir(&dir, &ent) == -1)
771                 goto badrom;
772         if (console_loglevel >= 10)
773                 printk(KERN_DEBUG "nubus_get_rom_dir: entry %02x %06x\n", ent.type, ent.data);
774         
775         /* Bwahahahaha... */
776         nubus_get_subdir(&ent, &dir);
777         board->directory = dir.base;
778         return;
779         
780         /* Even more evil laughter... */
781  badrom:
782         board->directory = board->fblock;
783         nubus_move(&board->directory, nubus_expand32(board->doffset), board->lanes);
784         printk(KERN_ERR "nubus_get_rom_dir: ROM weirdness!  Notify the developers...\n");
785 }
786
787 /* Add a board (might be many devices) to the list */
788 static struct nubus_board* __init nubus_add_board(int slot, int bytelanes)
789 {
790         struct nubus_board* board;
791         struct nubus_board** boardp;
792
793         unsigned char *rp;
794         unsigned long dpat;
795         struct nubus_dir dir;
796         struct nubus_dirent ent;
797
798         /* Move to the start of the format block */
799         rp = nubus_rom_addr(slot);              
800         nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
801
802         /* Actually we should probably panic if this fails */
803         if ((board = kmalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
804                 return NULL;    
805         memset(board, 0, sizeof(*board));
806         board->fblock = rp;
807
808         /* Dump the format block for debugging purposes */
809         if (console_loglevel >= 10) {
810                 int i;
811                 printk(KERN_DEBUG "Slot %X, format block at 0x%p\n",
812                        slot, rp);
813                 printk(KERN_DEBUG "Format block: ");
814                 for (i = 0; i < FORMAT_BLOCK_SIZE; i += 4) {
815                         unsigned short foo, bar;
816                         foo = nubus_get_rom(&rp, 2, bytelanes);
817                         bar = nubus_get_rom(&rp, 2, bytelanes);
818                         printk("%04x %04x  ", foo, bar);
819                 }
820                 printk("\n");
821                 rp = board->fblock;
822         }
823         
824         board->slot = slot;
825         board->slot_addr = (unsigned long) nubus_slot_addr(slot);
826         board->doffset = nubus_get_rom(&rp, 4, bytelanes);
827         /* rom_length is *supposed* to be the total length of the
828          * ROM.  In practice it is the "amount of ROM used to compute
829          * the CRC."  So some jokers decide to set it to zero and
830          * set the crc to zero so they don't have to do any math.
831          * See the Performa 460 ROM, for example.  Those Apple "engineers".
832          */
833         board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
834         board->crc = nubus_get_rom(&rp, 4, bytelanes);
835         board->rev = nubus_get_rom(&rp, 1, bytelanes);
836         board->format = nubus_get_rom(&rp,1, bytelanes);
837         board->lanes = bytelanes;
838
839         /* Directory offset should be small and negative... */
840         if(!(board->doffset & 0x00FF0000))
841                 printk(KERN_WARNING "Dodgy doffset!\n");
842         dpat = nubus_get_rom(&rp, 4, bytelanes);
843         if(dpat != NUBUS_TEST_PATTERN)
844                 printk(KERN_WARNING "Wrong test pattern %08lx!\n", dpat);
845                 
846         /*
847          *      I wonder how the CRC is meant to work -
848          *              any takers ?
849          * CSA: According to MAC docs, not all cards pass the CRC anyway,
850          * since the initial Macintosh ROM releases skipped the check.
851          */
852
853         /* Attempt to work around slot zero weirdness */
854         nubus_find_rom_dir(board);
855         nubus_get_root_dir(board, &dir);        
856
857         /* We're ready to rock */
858         printk(KERN_INFO "Slot %X:\n", slot);
859
860         /* Each slot should have one board resource and any number of
861            functional resources.  So we'll fill in some fields in the
862            struct nubus_board from the board resource, then walk down
863            the list of functional resources, spinning out a nubus_dev
864            for each of them. */
865         if (nubus_readdir(&dir, &ent) == -1) {
866                 /* We can't have this! */
867                 printk(KERN_ERR "Board resource not found!\n");
868                 return NULL;
869         } else {
870                 printk(KERN_INFO "  Board resource:\n");
871                 nubus_get_board_resource(board, slot, &ent);
872         }
873
874         /* Aaaarrrrgghh!  The LC III motherboard has *two* board
875            resources.  I have no idea WTF to do about this. */
876
877         while (nubus_readdir(&dir, &ent) != -1) {
878                 struct nubus_dev*  dev;
879                 struct nubus_dev** devp;
880                 dev = nubus_get_functional_resource(board, slot, &ent);
881                 if (dev == NULL)
882                         continue;
883
884                 /* We zeroed this out above */
885                 if (board->first_dev == NULL)
886                         board->first_dev = dev;
887                 
888                 /* Put it on the global NuBus device chain. Keep entries in order. */
889                 for (devp=&nubus_devices; *devp!=NULL; devp=&((*devp)->next))
890                         /* spin */;
891                 *devp = dev;
892                 dev->next = NULL;               
893         }
894
895         /* Put it on the global NuBus board chain. Keep entries in order. */
896         for (boardp=&nubus_boards; *boardp!=NULL; boardp=&((*boardp)->next))
897                 /* spin */;
898         *boardp = board;
899         board->next = NULL;
900         
901         return board;
902 }
903
904 void __init nubus_probe_slot(int slot)
905 {
906         unsigned char dp;
907         unsigned char* rp;
908         int i;
909
910         rp = nubus_rom_addr(slot);      
911         for(i = 4; i; i--)
912         {
913                 unsigned long flags;
914                 int card_present;
915
916                 rp--;
917                 local_irq_save(flags);
918                 card_present = hwreg_present(rp);
919                 local_irq_restore(flags);
920                
921                 if (!card_present)
922                         continue;
923
924                 printk(KERN_DEBUG "Now probing slot %X at %p\n", slot, rp);
925                 dp = *rp;
926                 if(dp == 0)
927                         continue;
928
929                 /* The last byte of the format block consists of two
930                    nybbles which are "mirror images" of each other.
931                    These show us the valid bytelanes */
932                 if ((((dp>>4) ^ dp) & 0x0F) != 0x0F)
933                         continue;
934                 /* Check that this value is actually *on* one of the
935                    bytelanes it claims are valid! */
936                 if ((dp & 0x0F) >= (1<<i))
937                         continue;
938
939                 /* Looks promising.  Let's put it on the list. */
940                 nubus_add_board(slot, dp);
941
942                 return;
943         }
944 }
945
946 #if defined(CONFIG_PROC_FS)
947
948 /* /proc/nubus stuff */
949
950 static int sprint_nubus_board(struct nubus_board* board, char* ptr, int len)
951 {
952         if(len < 100)
953                 return -1;
954         
955         sprintf(ptr, "Slot %X: %s\n",
956                 board->slot, board->name);
957         
958         return strlen(ptr);
959 }
960
961 static int nubus_read_proc(char *page, char **start, off_t off,
962                                 int count, int *eof, void *data)
963 {
964         int nprinted, len, begin = 0;
965         int size = PAGE_SIZE;
966         struct nubus_board* board;
967         
968         len   = sprintf(page, "Nubus devices found:\n");
969         /* Walk the list of NuBus boards */
970         for (board = nubus_boards; board != NULL; board = board->next)
971         {
972                 nprinted = sprint_nubus_board(board, page + len, size - len);
973                 if (nprinted < 0)
974                         break;
975                 len += nprinted;
976                 if (len+begin < off) {
977                         begin += len;
978                         len = 0;
979                 }
980                 if (len+begin >= off+count)
981                         break;
982         }
983         if (len+begin < off)
984                 *eof = 1;
985         off -= begin;
986         *start = page + off;
987         len -= off;
988         if (len>count)
989                 len = count;
990         if (len<0)
991                 len = 0;
992         return len;
993 }
994 #endif
995
996 void __init nubus_scan_bus(void)
997 {
998         int slot;
999         /* This might not work on your machine */
1000 #ifdef I_WANT_TO_PROBE_SLOT_ZERO
1001         nubus_probe_slot(0);
1002 #endif
1003         for(slot = 9; slot < 15; slot++)
1004         {
1005                 nubus_probe_slot(slot);
1006         }
1007 }
1008
1009 static int __init nubus_init(void)
1010 {
1011         if (!MACH_IS_MAC) 
1012                 return 0;
1013
1014         /* Initialize the NuBus interrupts */
1015         if (oss_present) {
1016                 oss_nubus_init();
1017         } else {
1018                 via_nubus_init();
1019         }
1020
1021 #ifdef TRY_TO_DODGE_WSOD
1022         /* Rogue Ethernet interrupts can kill the machine if we don't
1023            do this.  Obviously this is bogus.  Hopefully the local VIA
1024            gurus can fix the real cause of the problem. */
1025         mdelay(1000);
1026 #endif
1027         
1028         /* And probe */
1029         printk("NuBus: Scanning NuBus slots.\n");
1030         nubus_devices = NULL;
1031         nubus_boards  = NULL;
1032         nubus_scan_bus();
1033
1034 #ifdef CONFIG_PROC_FS
1035         create_proc_read_entry("nubus", 0, NULL, nubus_read_proc, NULL);
1036         nubus_proc_init();
1037 #endif
1038         return 0;
1039 }
1040
1041 subsys_initcall(nubus_init);