2 * Macintosh Nubus Interface Code
4 * Originally by Alan Cox
6 * Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
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>
21 #include <asm/hwtest.h>
22 #include <linux/proc_fs.h>
23 #include <asm/mac_via.h>
24 #include <asm/mac_oss.h>
26 extern void via_nubus_init(void);
27 extern void oss_nubus_init(void);
31 /* This is, of course, the size in bytelanes, rather than the size in
33 #define FORMAT_BLOCK_SIZE 20
34 #define ROM_DIR_OFFSET 0x24
36 #define NUBUS_TEST_PATTERN 0x5A932BC7
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
41 #undef I_WANT_TO_PROBE_SLOT_ZERO
43 /* This sometimes helps combat failure to boot */
44 #undef TRY_TO_DODGE_WSOD
48 struct nubus_dev
* nubus_devices
;
49 struct nubus_board
* nubus_boards
;
51 /* Meaning of "bytelanes":
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:
59 A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
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)
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)
69 A map of 0x78 means that only the LSB of each long word is valid.
71 Etcetera, etcetera. Hopefully this clears up some confusion over
72 what the following code actually does. */
74 static inline int not_useful(void *p
, int map
)
76 unsigned long pv
=(unsigned long)p
;
83 static unsigned long nubus_get_rom(unsigned char **ptr
, int len
, int map
)
85 /* This will hold the result */
87 unsigned char *p
= *ptr
;
92 while(not_useful(p
,map
))
101 static void nubus_rewind(unsigned char **ptr
, int len
, int map
)
103 unsigned char *p
=*ptr
;
107 printk(KERN_ERR
"rewind of 0x%08x!\n", len
);
114 while(not_useful(p
, map
));
120 static void nubus_advance(unsigned char **ptr
, int len
, int map
)
122 unsigned char *p
= *ptr
;
124 printk(KERN_ERR
"advance of 0x%08x!\n", len
);
127 while(not_useful(p
,map
))
135 static void nubus_move(unsigned char **ptr
, int len
, int map
)
138 nubus_advance(ptr
, len
, map
);
140 nubus_rewind(ptr
, -len
, map
);
143 /* Now, functions to read the sResource tree */
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
150 static inline long nubus_expand32(long foo
)
152 if(foo
& 0x00800000) /* 24bit negative */
157 static inline void *nubus_rom_addr(int slot
)
160 * Returns the first byte after the card. We then walk
161 * backwards to get the lane register and the config
163 return (void *)(0xF1000000+(slot
<<24));
166 static unsigned char *nubus_dirptr(const struct nubus_dirent
*nd
)
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 */
176 /* These two are for pulling resource data blocks (i.e. stuff that's
177 pointed to with offsets) out of the card ROM. */
179 void nubus_get_rsrc_mem(void *dest
, const struct nubus_dirent
* dirent
,
182 unsigned char *t
= (unsigned char *)dest
;
183 unsigned char *p
= nubus_dirptr(dirent
);
186 *t
++ = nubus_get_rom(&p
, 1, dirent
->mask
);
190 EXPORT_SYMBOL(nubus_get_rsrc_mem
);
192 void nubus_get_rsrc_str(void *dest
, const struct nubus_dirent
* dirent
,
195 unsigned char *t
=(unsigned char *)dest
;
196 unsigned char *p
= nubus_dirptr(dirent
);
199 *t
= nubus_get_rom(&p
, 1, dirent
->mask
);
205 EXPORT_SYMBOL(nubus_get_rsrc_str
);
207 int nubus_get_root_dir(const struct nubus_board
* board
,
208 struct nubus_dir
* dir
)
210 dir
->ptr
= dir
->base
= board
->directory
;
212 dir
->mask
= board
->lanes
;
215 EXPORT_SYMBOL(nubus_get_root_dir
);
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
)
221 dir
->ptr
= dir
->base
= dev
->directory
;
223 dir
->mask
= dev
->board
->lanes
;
226 EXPORT_SYMBOL(nubus_get_func_dir
);
228 int nubus_get_board_dir(const struct nubus_board
* board
,
229 struct nubus_dir
* dir
)
231 struct nubus_dirent ent
;
233 dir
->ptr
= dir
->base
= board
->directory
;
235 dir
->mask
= board
->lanes
;
237 /* Now dereference it (the first directory is always the board
239 if (nubus_readdir(dir
, &ent
) == -1)
241 if (nubus_get_subdir(&ent
, dir
) == -1)
245 EXPORT_SYMBOL(nubus_get_board_dir
);
247 int nubus_get_subdir(const struct nubus_dirent
*ent
,
248 struct nubus_dir
*dir
)
250 dir
->ptr
= dir
->base
= nubus_dirptr(ent
);
252 dir
->mask
= ent
->mask
;
255 EXPORT_SYMBOL(nubus_get_subdir
);
257 int nubus_readdir(struct nubus_dir
*nd
, struct nubus_dirent
*ent
)
263 /* Do this first, otherwise nubus_rewind & co are off by 4 */
266 /* This moves nd->ptr forward */
267 resid
= nubus_get_rom(&nd
->ptr
, 4, nd
->mask
);
269 /* EOL marker, as per the Apple docs */
270 if((resid
&0xff000000) == 0xff000000)
272 /* Mark it as done */
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
;
284 EXPORT_SYMBOL(nubus_readdir
);
286 int nubus_rewinddir(struct nubus_dir
* dir
)
288 dir
->ptr
= dir
->base
;
291 EXPORT_SYMBOL(nubus_rewinddir
);
293 /* Driver interface functions, more or less like in pci.c */
296 nubus_find_device(unsigned short category
,
298 unsigned short dr_hw
,
299 unsigned short dr_sw
,
300 const struct nubus_dev
* from
)
302 struct nubus_dev
* itor
=
303 from
? from
->next
: nubus_devices
;
306 if (itor
->category
== category
307 && itor
->type
== type
308 && itor
->dr_hw
== dr_hw
309 && itor
->dr_sw
== dr_sw
)
315 EXPORT_SYMBOL(nubus_find_device
);
318 nubus_find_type(unsigned short category
,
320 const struct nubus_dev
* from
)
322 struct nubus_dev
* itor
=
323 from
? from
->next
: nubus_devices
;
326 if (itor
->category
== category
327 && itor
->type
== type
)
333 EXPORT_SYMBOL(nubus_find_type
);
336 nubus_find_slot(unsigned int slot
,
337 const struct nubus_dev
* from
)
339 struct nubus_dev
* itor
=
340 from
? from
->next
: nubus_devices
;
343 if (itor
->board
->slot
== slot
)
349 EXPORT_SYMBOL(nubus_find_slot
);
352 nubus_find_rsrc(struct nubus_dir
* dir
, unsigned char rsrc_type
,
353 struct nubus_dirent
* ent
)
355 while (nubus_readdir(dir
, ent
) != -1) {
356 if (ent
->type
== rsrc_type
)
361 EXPORT_SYMBOL(nubus_find_rsrc
);
363 /* Initialization functions - decide which slots contain stuff worth
364 looking at, and print out lots and lots of information from the
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. */
372 static int __init
nubus_show_display_resource(struct nubus_dev
* dev
,
373 const struct nubus_dirent
* ent
)
376 case NUBUS_RESID_GAMMADIR
:
377 printk(KERN_INFO
" gamma directory offset: 0x%06x\n", ent
->data
);
379 case 0x0080 ... 0x0085:
380 printk(KERN_INFO
" mode %02X info offset: 0x%06x\n",
381 ent
->type
, ent
->data
);
384 printk(KERN_INFO
" unknown resource %02X, data 0x%06x\n",
385 ent
->type
, ent
->data
);
390 static int __init
nubus_show_network_resource(struct nubus_dev
* dev
,
391 const struct nubus_dirent
* ent
)
394 case NUBUS_RESID_MAC_ADDRESS
:
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,
408 printk(KERN_INFO
" unknown resource %02X, data 0x%06x\n",
409 ent
->type
, ent
->data
);
414 static int __init
nubus_show_cpu_resource(struct nubus_dev
* dev
,
415 const struct nubus_dirent
* ent
)
418 case NUBUS_RESID_MEMINFO
:
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]);
426 case NUBUS_RESID_ROMINFO
:
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]);
435 printk(KERN_INFO
" unknown resource %02X, data 0x%06x\n",
436 ent
->type
, ent
->data
);
441 static int __init
nubus_show_private_resource(struct nubus_dev
* dev
,
442 const struct nubus_dirent
* ent
)
444 switch (dev
->category
) {
445 case NUBUS_CAT_DISPLAY
:
446 nubus_show_display_resource(dev
, ent
);
448 case NUBUS_CAT_NETWORK
:
449 nubus_show_network_resource(dev
, ent
);
452 nubus_show_cpu_resource(dev
, ent
);
455 printk(KERN_INFO
" unknown resource %02X, data 0x%06x\n",
456 ent
->type
, ent
->data
);
461 static struct nubus_dev
* __init
462 nubus_get_functional_resource(struct nubus_board
* board
,
464 const struct nubus_dirent
* parent
)
466 struct nubus_dir dir
;
467 struct nubus_dirent ent
;
468 struct nubus_dev
* dev
;
470 printk(KERN_INFO
" Function 0x%02x:\n", parent
->type
);
471 nubus_get_subdir(parent
, &dir
);
473 /* Apple seems to have botched the ROM on the IIx */
474 if (slot
== 0 && (unsigned long)dir
.base
% 2)
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
);
481 /* Actually we should probably panic if this fails */
482 if ((dev
= kzalloc(sizeof(*dev
), GFP_ATOMIC
)) == NULL
)
484 dev
->resid
= parent
->type
;
485 dev
->directory
= dir
.base
;
488 while (nubus_readdir(&dir
, &ent
) != -1)
492 case NUBUS_RESID_TYPE
:
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]);
504 case NUBUS_RESID_NAME
:
506 nubus_get_rsrc_str(dev
->name
, &ent
, 64);
507 printk(KERN_INFO
" name: %s\n", dev
->name
);
510 case NUBUS_RESID_DRVRDIR
:
512 /* MacOS driver. If we were NetBSD we might
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",
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",
531 case NUBUS_RESID_MINOR_LENGTH
:
533 nubus_get_rsrc_mem(&dev
->iosize
, &ent
, 4);
534 printk(KERN_INFO
" memory length: 0x%08lx\n",
537 case NUBUS_RESID_FLAGS
:
538 dev
->flags
= ent
.data
;
539 printk(KERN_INFO
" flags: 0x%06x\n", dev
->flags
);
541 case NUBUS_RESID_HWDEVID
:
542 dev
->hwdevid
= ent
.data
;
543 printk(KERN_INFO
" hwdevid: 0x%06x\n", dev
->hwdevid
);
546 /* Local/Private resources have their own
548 nubus_show_private_resource(dev
, &ent
);
556 static int __init
nubus_get_vidnames(struct nubus_board
* board
,
557 const struct nubus_dirent
* parent
)
559 struct nubus_dir dir
;
560 struct nubus_dirent ent
;
561 /* FIXME: obviously we want to put this in a header file soon */
564 /* Don't know what this is yet */
566 /* Longest one I've seen so far is 26 characters */
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
);
576 while(nubus_readdir(&dir
, &ent
) != -1)
581 /* First get the length */
582 nubus_get_rsrc_mem(&size
, &ent
, 4);
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
,
595 /* This is *really* cool. */
596 static int __init
nubus_get_icon(struct nubus_board
* board
,
597 const struct nubus_dirent
* ent
)
599 /* Should be 32x32 if my memory serves me correctly */
600 unsigned char icon
[128];
603 nubus_get_rsrc_mem(&icon
, ent
, 128);
604 printk(KERN_INFO
" icon:\n");
606 /* We should actually plot these somewhere in the framebuffer
607 init. This is just to demonstrate that they do, in fact,
609 for (y
= 0; y
< 32; y
++) {
610 printk(KERN_INFO
" ");
611 for (x
= 0; x
< 32; x
++) {
623 static int __init
nubus_get_vendorinfo(struct nubus_board
* board
,
624 const struct nubus_dirent
* parent
)
626 struct nubus_dir dir
;
627 struct nubus_dirent ent
;
628 static char* vendor_fields
[6] = {"ID", "serial", "revision",
629 "part", "date", "unknown field"};
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
);
637 while(nubus_readdir(&dir
, &ent
) != -1)
641 /* These are all strings, we think */
642 nubus_get_rsrc_str(name
, &ent
, 64);
645 printk(KERN_INFO
" %s: %s\n",
646 vendor_fields
[ent
.type
-1], name
);
651 static int __init
nubus_get_board_resource(struct nubus_board
* board
, int slot
,
652 const struct nubus_dirent
* parent
)
654 struct nubus_dir dir
;
655 struct nubus_dirent ent
;
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
);
662 while(nubus_readdir(&dir
, &ent
) != -1)
665 case NUBUS_RESID_TYPE
:
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],
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");
680 case NUBUS_RESID_NAME
:
681 nubus_get_rsrc_str(board
->name
, &ent
, 64);
682 printk(KERN_INFO
" name: %s\n", board
->name
);
684 case NUBUS_RESID_ICON
:
685 nubus_get_icon(board
, &ent
);
687 case NUBUS_RESID_BOARDID
:
688 printk(KERN_INFO
" board id: 0x%x\n", ent
.data
);
690 case NUBUS_RESID_PRIMARYINIT
:
691 printk(KERN_INFO
" primary init offset: 0x%06x\n", ent
.data
);
693 case NUBUS_RESID_VENDORINFO
:
694 nubus_get_vendorinfo(board
, &ent
);
696 case NUBUS_RESID_FLAGS
:
697 printk(KERN_INFO
" flags: 0x%06x\n", ent
.data
);
699 case NUBUS_RESID_HWDEVID
:
700 printk(KERN_INFO
" hwdevid: 0x%06x\n", ent
.data
);
702 case NUBUS_RESID_SECONDINIT
:
703 printk(KERN_INFO
" secondary init offset: 0x%06x\n", ent
.data
);
705 /* WTF isn't this in the functional resources? */
706 case NUBUS_RESID_VIDNAMES
:
707 nubus_get_vidnames(board
, &ent
);
709 /* Same goes for this */
710 case NUBUS_RESID_VIDMODES
:
711 printk(KERN_INFO
" video mode parameter directory offset: 0x%06x\n",
715 printk(KERN_INFO
" unknown resource %02X, data 0x%06x\n",
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
)
727 unsigned char* romdir
;
728 struct nubus_dir dir
;
729 struct nubus_dirent ent
;
731 /* Check for the extra directory just under the format block */
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
),
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
;
751 dir
.mask
= board
->lanes
;
753 /* This one points to an "Unknown Macintosh" directory */
754 if (nubus_readdir(&dir
, &ent
) == -1)
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)
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
);
766 /* Resource ID 01, also an "Unknown Macintosh" */
767 if (nubus_readdir(&dir
, &ent
) == -1)
769 if (console_loglevel
>= 10)
770 printk(KERN_DEBUG
"nubus_get_rom_dir: entry %02x %06x\n", ent
.type
, ent
.data
);
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)
784 if (console_loglevel
>= 10)
785 printk(KERN_DEBUG
"nubus_get_rom_dir: entry %02x %06x\n", ent
.type
, ent
.data
);
788 nubus_get_subdir(&ent
, &dir
);
789 board
->directory
= dir
.base
;
792 /* Even more evil laughter... */
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");
799 /* Add a board (might be many devices) to the list */
800 static struct nubus_board
* __init
nubus_add_board(int slot
, int bytelanes
)
802 struct nubus_board
* board
;
803 struct nubus_board
** boardp
;
807 struct nubus_dir dir
;
808 struct nubus_dirent ent
;
810 /* Move to the start of the format block */
811 rp
= nubus_rom_addr(slot
);
812 nubus_rewind(&rp
, FORMAT_BLOCK_SIZE
, bytelanes
);
814 /* Actually we should probably panic if this fails */
815 if ((board
= kzalloc(sizeof(*board
), GFP_ATOMIC
)) == NULL
)
819 /* Dump the format block for debugging purposes */
820 if (console_loglevel
>= 10) {
822 printk(KERN_DEBUG
"Slot %X, format block at 0x%p\n",
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
);
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".
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
;
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
);
858 * I wonder how the CRC is meant to work -
860 * CSA: According to MAC docs, not all cards pass the CRC anyway,
861 * since the initial Macintosh ROM releases skipped the check.
864 /* Attempt to work around slot zero weirdness */
865 nubus_find_rom_dir(board
);
866 nubus_get_root_dir(board
, &dir
);
868 /* We're ready to rock */
869 printk(KERN_INFO
"Slot %X:\n", slot
);
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
876 if (nubus_readdir(&dir
, &ent
) == -1) {
877 /* We can't have this! */
878 printk(KERN_ERR
"Board resource not found!\n");
881 printk(KERN_INFO
" Board resource:\n");
882 nubus_get_board_resource(board
, slot
, &ent
);
885 /* Aaaarrrrgghh! The LC III motherboard has *two* board
886 resources. I have no idea WTF to do about this. */
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
);
895 /* We zeroed this out above */
896 if (board
->first_dev
== NULL
)
897 board
->first_dev
= dev
;
899 /* Put it on the global NuBus device chain. Keep entries in order. */
900 for (devp
=&nubus_devices
; *devp
!=NULL
; devp
=&((*devp
)->next
))
906 /* Put it on the global NuBus board chain. Keep entries in order. */
907 for (boardp
=&nubus_boards
; *boardp
!=NULL
; boardp
=&((*boardp
)->next
))
915 void __init
nubus_probe_slot(int slot
)
921 rp
= nubus_rom_addr(slot
);
928 local_irq_save(flags
);
929 card_present
= hwreg_present(rp
);
930 local_irq_restore(flags
);
935 printk(KERN_DEBUG
"Now probing slot %X at %p\n", slot
, rp
);
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)
945 /* Check that this value is actually *on* one of the
946 bytelanes it claims are valid! */
947 if ((dp
& 0x0F) >= (1<<i
))
950 /* Looks promising. Let's put it on the list. */
951 nubus_add_board(slot
, dp
);
957 #if defined(CONFIG_PROC_FS)
959 /* /proc/nubus stuff */
961 static int sprint_nubus_board(struct nubus_board
* board
, char* ptr
, int len
)
966 sprintf(ptr
, "Slot %X: %s\n",
967 board
->slot
, board
->name
);
972 static int nubus_read_proc(char *page
, char **start
, off_t off
,
973 int count
, int *eof
, void *data
)
975 int nprinted
, len
, begin
= 0;
976 int size
= PAGE_SIZE
;
977 struct nubus_board
* board
;
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
)
983 nprinted
= sprint_nubus_board(board
, page
+ len
, size
- len
);
987 if (len
+begin
< off
) {
991 if (len
+begin
>= off
+count
)
1007 void __init
nubus_scan_bus(void)
1010 /* This might not work on your machine */
1011 #ifdef I_WANT_TO_PROBE_SLOT_ZERO
1012 nubus_probe_slot(0);
1014 for(slot
= 9; slot
< 15; slot
++)
1016 nubus_probe_slot(slot
);
1020 static int __init
nubus_init(void)
1025 /* Initialize the NuBus interrupts */
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. */
1040 printk("NuBus: Scanning NuBus slots.\n");
1041 nubus_devices
= NULL
;
1042 nubus_boards
= NULL
;
1045 #ifdef CONFIG_PROC_FS
1046 create_proc_read_entry("nubus", 0, NULL
, nubus_read_proc
, NULL
);
1052 subsys_initcall(nubus_init
);