1 // SPDX-License-Identifier: GPL-2.0
3 * Macintosh Nubus Interface Code
5 * Originally by Alan Cox
7 * Mostly rewritten by David Huggins-Daines, C. Scott Ananian,
11 #include <linux/types.h>
12 #include <linux/kernel.h>
13 #include <linux/string.h>
14 #include <linux/nubus.h>
15 #include <linux/errno.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/seq_file.h>
19 #include <linux/slab.h>
20 #include <asm/setup.h>
22 #include <asm/hwtest.h>
26 /* This is, of course, the size in bytelanes, rather than the size in
28 #define FORMAT_BLOCK_SIZE 20
29 #define ROM_DIR_OFFSET 0x24
31 #define NUBUS_TEST_PATTERN 0x5A932BC7
35 LIST_HEAD(nubus_func_rsrcs
);
37 /* Meaning of "bytelanes":
39 The card ROM may appear on any or all bytes of each long word in
40 NuBus memory. The low 4 bits of the "map" value found in the
41 format block (at the top of the slot address space, as well as at
42 the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
43 offsets within each longword, are valid. Thus:
45 A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
48 A map of 0xf0 means that no bytelanes are valid (We pray that we
49 will never encounter this, but stranger things have happened)
51 A map of 0xe1 means that only the MSB of each long word is actually
52 part of the card ROM. (We hope to never encounter NuBus on a
53 little-endian machine. Again, stranger things have happened)
55 A map of 0x78 means that only the LSB of each long word is valid.
57 Etcetera, etcetera. Hopefully this clears up some confusion over
58 what the following code actually does. */
60 static inline int not_useful(void *p
, int map
)
62 unsigned long pv
= (unsigned long)p
;
70 static unsigned long nubus_get_rom(unsigned char **ptr
, int len
, int map
)
72 /* This will hold the result */
74 unsigned char *p
= *ptr
;
78 while (not_useful(p
, map
))
87 static void nubus_rewind(unsigned char **ptr
, int len
, int map
)
89 unsigned char *p
= *ptr
;
94 } while (not_useful(p
, map
));
100 static void nubus_advance(unsigned char **ptr
, int len
, int map
)
102 unsigned char *p
= *ptr
;
105 while (not_useful(p
, map
))
113 static void nubus_move(unsigned char **ptr
, int len
, int map
)
115 unsigned long slot_space
= (unsigned long)*ptr
& 0xFF000000;
118 nubus_advance(ptr
, len
, map
);
120 nubus_rewind(ptr
, -len
, map
);
122 if (((unsigned long)*ptr
& 0xFF000000) != slot_space
)
123 pr_err("%s: moved out of slot address space!\n", __func__
);
126 /* Now, functions to read the sResource tree */
128 /* Each sResource entry consists of a 1-byte ID and a 3-byte data
129 field. If that data field contains an offset, then obviously we
130 have to expand it from a 24-bit signed number to a 32-bit signed
133 static inline long nubus_expand32(long foo
)
135 if (foo
& 0x00800000) /* 24bit negative */
140 static inline void *nubus_rom_addr(int slot
)
143 * Returns the first byte after the card. We then walk
144 * backwards to get the lane register and the config
146 return (void *)(0xF1000000 + (slot
<< 24));
149 unsigned char *nubus_dirptr(const struct nubus_dirent
*nd
)
151 unsigned char *p
= nd
->base
;
153 /* Essentially, just step over the bytelanes using whatever
154 offset we might have found */
155 nubus_move(&p
, nubus_expand32(nd
->data
), nd
->mask
);
156 /* And return the value */
160 /* These two are for pulling resource data blocks (i.e. stuff that's
161 pointed to with offsets) out of the card ROM. */
163 void nubus_get_rsrc_mem(void *dest
, const struct nubus_dirent
*dirent
,
166 unsigned char *t
= (unsigned char *)dest
;
167 unsigned char *p
= nubus_dirptr(dirent
);
170 *t
++ = nubus_get_rom(&p
, 1, dirent
->mask
);
174 EXPORT_SYMBOL(nubus_get_rsrc_mem
);
176 unsigned int nubus_get_rsrc_str(char *dest
, const struct nubus_dirent
*dirent
,
180 unsigned char *p
= nubus_dirptr(dirent
);
183 unsigned char c
= nubus_get_rom(&p
, 1, dirent
->mask
);
194 EXPORT_SYMBOL(nubus_get_rsrc_str
);
196 void nubus_seq_write_rsrc_mem(struct seq_file
*m
,
197 const struct nubus_dirent
*dirent
,
200 unsigned long buf
[32];
201 unsigned int buf_size
= sizeof(buf
);
202 unsigned char *p
= nubus_dirptr(dirent
);
204 /* If possible, write out full buffers */
205 while (len
>= buf_size
) {
208 for (i
= 0; i
< ARRAY_SIZE(buf
); i
++)
209 buf
[i
] = nubus_get_rom(&p
, sizeof(buf
[0]),
211 seq_write(m
, buf
, buf_size
);
214 /* If not, write out individual bytes */
216 seq_putc(m
, nubus_get_rom(&p
, 1, dirent
->mask
));
219 int nubus_get_root_dir(const struct nubus_board
*board
,
220 struct nubus_dir
*dir
)
222 dir
->ptr
= dir
->base
= board
->directory
;
224 dir
->mask
= board
->lanes
;
227 EXPORT_SYMBOL(nubus_get_root_dir
);
229 /* This is a slyly renamed version of the above */
230 int nubus_get_func_dir(const struct nubus_rsrc
*fres
, struct nubus_dir
*dir
)
232 dir
->ptr
= dir
->base
= fres
->directory
;
234 dir
->mask
= fres
->board
->lanes
;
237 EXPORT_SYMBOL(nubus_get_func_dir
);
239 int nubus_get_board_dir(const struct nubus_board
*board
,
240 struct nubus_dir
*dir
)
242 struct nubus_dirent ent
;
244 dir
->ptr
= dir
->base
= board
->directory
;
246 dir
->mask
= board
->lanes
;
248 /* Now dereference it (the first directory is always the board
250 if (nubus_readdir(dir
, &ent
) == -1)
252 if (nubus_get_subdir(&ent
, dir
) == -1)
256 EXPORT_SYMBOL(nubus_get_board_dir
);
258 int nubus_get_subdir(const struct nubus_dirent
*ent
,
259 struct nubus_dir
*dir
)
261 dir
->ptr
= dir
->base
= nubus_dirptr(ent
);
263 dir
->mask
= ent
->mask
;
266 EXPORT_SYMBOL(nubus_get_subdir
);
268 int nubus_readdir(struct nubus_dir
*nd
, struct nubus_dirent
*ent
)
275 /* Do this first, otherwise nubus_rewind & co are off by 4 */
278 /* This moves nd->ptr forward */
279 resid
= nubus_get_rom(&nd
->ptr
, 4, nd
->mask
);
281 /* EOL marker, as per the Apple docs */
282 if ((resid
& 0xff000000) == 0xff000000) {
283 /* Mark it as done */
288 /* First byte is the resource ID */
289 ent
->type
= resid
>> 24;
290 /* Low 3 bytes might contain data (or might not) */
291 ent
->data
= resid
& 0xffffff;
292 ent
->mask
= nd
->mask
;
295 EXPORT_SYMBOL(nubus_readdir
);
297 int nubus_rewinddir(struct nubus_dir
*dir
)
299 dir
->ptr
= dir
->base
;
303 EXPORT_SYMBOL(nubus_rewinddir
);
305 /* Driver interface functions, more or less like in pci.c */
307 struct nubus_rsrc
*nubus_first_rsrc_or_null(void)
309 return list_first_entry_or_null(&nubus_func_rsrcs
, struct nubus_rsrc
,
312 EXPORT_SYMBOL(nubus_first_rsrc_or_null
);
314 struct nubus_rsrc
*nubus_next_rsrc_or_null(struct nubus_rsrc
*from
)
316 if (list_is_last(&from
->list
, &nubus_func_rsrcs
))
318 return list_next_entry(from
, list
);
320 EXPORT_SYMBOL(nubus_next_rsrc_or_null
);
323 nubus_find_rsrc(struct nubus_dir
*dir
, unsigned char rsrc_type
,
324 struct nubus_dirent
*ent
)
326 while (nubus_readdir(dir
, ent
) != -1) {
327 if (ent
->type
== rsrc_type
)
332 EXPORT_SYMBOL(nubus_find_rsrc
);
334 /* Initialization functions - decide which slots contain stuff worth
335 looking at, and print out lots and lots of information from the
338 static int __init
nubus_get_block_rsrc_dir(struct nubus_board
*board
,
339 struct proc_dir_entry
*procdir
,
340 const struct nubus_dirent
*parent
)
342 struct nubus_dir dir
;
343 struct nubus_dirent ent
;
345 nubus_get_subdir(parent
, &dir
);
346 dir
.procdir
= nubus_proc_add_rsrc_dir(procdir
, parent
, board
);
348 while (nubus_readdir(&dir
, &ent
) != -1) {
351 nubus_get_rsrc_mem(&size
, &ent
, 4);
352 pr_debug(" block (0x%x), size %d\n", ent
.type
, size
);
353 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, size
);
358 static int __init
nubus_get_display_vidmode(struct nubus_board
*board
,
359 struct proc_dir_entry
*procdir
,
360 const struct nubus_dirent
*parent
)
362 struct nubus_dir dir
;
363 struct nubus_dirent ent
;
365 nubus_get_subdir(parent
, &dir
);
366 dir
.procdir
= nubus_proc_add_rsrc_dir(procdir
, parent
, board
);
368 while (nubus_readdir(&dir
, &ent
) != -1) {
370 case 1: /* mVidParams */
375 nubus_get_rsrc_mem(&size
, &ent
, 4);
376 pr_debug(" block (0x%x), size %d\n", ent
.type
,
378 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, size
);
382 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
384 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 0);
390 static int __init
nubus_get_display_resource(struct nubus_rsrc
*fres
,
391 struct proc_dir_entry
*procdir
,
392 const struct nubus_dirent
*ent
)
395 case NUBUS_RESID_GAMMADIR
:
396 pr_debug(" gamma directory offset: 0x%06x\n", ent
->data
);
397 nubus_get_block_rsrc_dir(fres
->board
, procdir
, ent
);
399 case 0x0080 ... 0x0085:
400 pr_debug(" mode 0x%02x info offset: 0x%06x\n",
401 ent
->type
, ent
->data
);
402 nubus_get_display_vidmode(fres
->board
, procdir
, ent
);
405 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
406 ent
->type
, ent
->data
);
407 nubus_proc_add_rsrc_mem(procdir
, ent
, 0);
412 static int __init
nubus_get_network_resource(struct nubus_rsrc
*fres
,
413 struct proc_dir_entry
*procdir
,
414 const struct nubus_dirent
*ent
)
417 case NUBUS_RESID_MAC_ADDRESS
:
421 nubus_get_rsrc_mem(addr
, ent
, 6);
422 pr_debug(" MAC address: %pM\n", addr
);
423 nubus_proc_add_rsrc_mem(procdir
, ent
, 6);
427 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
428 ent
->type
, ent
->data
);
429 nubus_proc_add_rsrc_mem(procdir
, ent
, 0);
434 static int __init
nubus_get_cpu_resource(struct nubus_rsrc
*fres
,
435 struct proc_dir_entry
*procdir
,
436 const struct nubus_dirent
*ent
)
439 case NUBUS_RESID_MEMINFO
:
441 unsigned long meminfo
[2];
443 nubus_get_rsrc_mem(&meminfo
, ent
, 8);
444 pr_debug(" memory: [ 0x%08lx 0x%08lx ]\n",
445 meminfo
[0], meminfo
[1]);
446 nubus_proc_add_rsrc_mem(procdir
, ent
, 8);
449 case NUBUS_RESID_ROMINFO
:
451 unsigned long rominfo
[2];
453 nubus_get_rsrc_mem(&rominfo
, ent
, 8);
454 pr_debug(" ROM: [ 0x%08lx 0x%08lx ]\n",
455 rominfo
[0], rominfo
[1]);
456 nubus_proc_add_rsrc_mem(procdir
, ent
, 8);
460 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
461 ent
->type
, ent
->data
);
462 nubus_proc_add_rsrc_mem(procdir
, ent
, 0);
467 static int __init
nubus_get_private_resource(struct nubus_rsrc
*fres
,
468 struct proc_dir_entry
*procdir
,
469 const struct nubus_dirent
*ent
)
471 switch (fres
->category
) {
472 case NUBUS_CAT_DISPLAY
:
473 nubus_get_display_resource(fres
, procdir
, ent
);
475 case NUBUS_CAT_NETWORK
:
476 nubus_get_network_resource(fres
, procdir
, ent
);
479 nubus_get_cpu_resource(fres
, procdir
, ent
);
482 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
483 ent
->type
, ent
->data
);
484 nubus_proc_add_rsrc_mem(procdir
, ent
, 0);
489 static struct nubus_rsrc
* __init
490 nubus_get_functional_resource(struct nubus_board
*board
, int slot
,
491 const struct nubus_dirent
*parent
)
493 struct nubus_dir dir
;
494 struct nubus_dirent ent
;
495 struct nubus_rsrc
*fres
;
497 pr_debug(" Functional resource 0x%02x:\n", parent
->type
);
498 nubus_get_subdir(parent
, &dir
);
499 dir
.procdir
= nubus_proc_add_rsrc_dir(board
->procdir
, parent
, board
);
501 /* Actually we should probably panic if this fails */
502 fres
= kzalloc(sizeof(*fres
), GFP_ATOMIC
);
505 fres
->resid
= parent
->type
;
506 fres
->directory
= dir
.base
;
509 while (nubus_readdir(&dir
, &ent
) != -1) {
511 case NUBUS_RESID_TYPE
:
513 unsigned short nbtdata
[4];
515 nubus_get_rsrc_mem(nbtdata
, &ent
, 8);
516 fres
->category
= nbtdata
[0];
517 fres
->type
= nbtdata
[1];
518 fres
->dr_sw
= nbtdata
[2];
519 fres
->dr_hw
= nbtdata
[3];
520 pr_debug(" type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
521 nbtdata
[0], nbtdata
[1], nbtdata
[2], nbtdata
[3]);
522 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 8);
525 case NUBUS_RESID_NAME
:
530 len
= nubus_get_rsrc_str(name
, &ent
, sizeof(name
));
531 pr_debug(" name: %s\n", name
);
532 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, len
+ 1);
535 case NUBUS_RESID_DRVRDIR
:
537 /* MacOS driver. If we were NetBSD we might
539 pr_debug(" driver directory offset: 0x%06x\n",
541 nubus_get_block_rsrc_dir(board
, dir
.procdir
, &ent
);
544 case NUBUS_RESID_MINOR_BASEOS
:
546 /* We will need this in order to support
547 multiple framebuffers. It might be handy
548 for Ethernet as well */
551 nubus_get_rsrc_mem(&base_offset
, &ent
, 4);
552 pr_debug(" memory offset: 0x%08x\n", base_offset
);
553 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 4);
556 case NUBUS_RESID_MINOR_LENGTH
:
561 nubus_get_rsrc_mem(&length
, &ent
, 4);
562 pr_debug(" memory length: 0x%08x\n", length
);
563 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 4);
566 case NUBUS_RESID_FLAGS
:
567 pr_debug(" flags: 0x%06x\n", ent
.data
);
568 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
570 case NUBUS_RESID_HWDEVID
:
571 pr_debug(" hwdevid: 0x%06x\n", ent
.data
);
572 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
575 /* Local/Private resources have their own
577 nubus_get_private_resource(fres
, dir
.procdir
, &ent
);
584 /* This is *really* cool. */
585 static int __init
nubus_get_icon(struct nubus_board
*board
,
586 struct proc_dir_entry
*procdir
,
587 const struct nubus_dirent
*ent
)
589 /* Should be 32x32 if my memory serves me correctly */
593 nubus_get_rsrc_mem(&icon
, ent
, 128);
594 pr_debug(" icon:\n");
595 for (i
= 0; i
< 8; i
++)
596 pr_debug(" %08x %08x %08x %08x\n",
597 icon
[i
* 4 + 0], icon
[i
* 4 + 1],
598 icon
[i
* 4 + 2], icon
[i
* 4 + 3]);
599 nubus_proc_add_rsrc_mem(procdir
, ent
, 128);
604 static int __init
nubus_get_vendorinfo(struct nubus_board
*board
,
605 struct proc_dir_entry
*procdir
,
606 const struct nubus_dirent
*parent
)
608 struct nubus_dir dir
;
609 struct nubus_dirent ent
;
610 static char *vendor_fields
[6] = { "ID", "serial", "revision",
611 "part", "date", "unknown field" };
613 pr_debug(" vendor info:\n");
614 nubus_get_subdir(parent
, &dir
);
615 dir
.procdir
= nubus_proc_add_rsrc_dir(procdir
, parent
, board
);
617 while (nubus_readdir(&dir
, &ent
) != -1) {
621 /* These are all strings, we think */
622 len
= nubus_get_rsrc_str(name
, &ent
, sizeof(name
));
623 if (ent
.type
< 1 || ent
.type
> 5)
625 pr_debug(" %s: %s\n", vendor_fields
[ent
.type
- 1], name
);
626 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, len
+ 1);
631 static int __init
nubus_get_board_resource(struct nubus_board
*board
, int slot
,
632 const struct nubus_dirent
*parent
)
634 struct nubus_dir dir
;
635 struct nubus_dirent ent
;
637 pr_debug(" Board resource 0x%02x:\n", parent
->type
);
638 nubus_get_subdir(parent
, &dir
);
639 dir
.procdir
= nubus_proc_add_rsrc_dir(board
->procdir
, parent
, board
);
641 while (nubus_readdir(&dir
, &ent
) != -1) {
643 case NUBUS_RESID_TYPE
:
645 unsigned short nbtdata
[4];
646 /* This type is always the same, and is not
647 useful except insofar as it tells us that
648 we really are looking at a board resource. */
649 nubus_get_rsrc_mem(nbtdata
, &ent
, 8);
650 pr_debug(" type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
651 nbtdata
[0], nbtdata
[1], nbtdata
[2], nbtdata
[3]);
652 if (nbtdata
[0] != 1 || nbtdata
[1] != 0 ||
653 nbtdata
[2] != 0 || nbtdata
[3] != 0)
654 pr_err("Slot %X: sResource is not a board resource!\n",
656 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 8);
659 case NUBUS_RESID_NAME
:
663 len
= nubus_get_rsrc_str(board
->name
, &ent
,
664 sizeof(board
->name
));
665 pr_debug(" name: %s\n", board
->name
);
666 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, len
+ 1);
669 case NUBUS_RESID_ICON
:
670 nubus_get_icon(board
, dir
.procdir
, &ent
);
672 case NUBUS_RESID_BOARDID
:
673 pr_debug(" board id: 0x%x\n", ent
.data
);
674 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
676 case NUBUS_RESID_PRIMARYINIT
:
677 pr_debug(" primary init offset: 0x%06x\n", ent
.data
);
678 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
680 case NUBUS_RESID_VENDORINFO
:
681 nubus_get_vendorinfo(board
, dir
.procdir
, &ent
);
683 case NUBUS_RESID_FLAGS
:
684 pr_debug(" flags: 0x%06x\n", ent
.data
);
685 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
687 case NUBUS_RESID_HWDEVID
:
688 pr_debug(" hwdevid: 0x%06x\n", ent
.data
);
689 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
691 case NUBUS_RESID_SECONDINIT
:
692 pr_debug(" secondary init offset: 0x%06x\n",
694 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
696 /* WTF isn't this in the functional resources? */
697 case NUBUS_RESID_VIDNAMES
:
698 pr_debug(" vidnames directory offset: 0x%06x\n",
700 nubus_get_block_rsrc_dir(board
, dir
.procdir
, &ent
);
702 /* Same goes for this */
703 case NUBUS_RESID_VIDMODES
:
704 pr_debug(" video mode parameter directory offset: 0x%06x\n",
706 nubus_proc_add_rsrc(dir
.procdir
, &ent
);
709 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
711 nubus_proc_add_rsrc_mem(dir
.procdir
, &ent
, 0);
717 static void __init
nubus_add_board(int slot
, int bytelanes
)
719 struct nubus_board
*board
;
722 struct nubus_dir dir
;
723 struct nubus_dirent ent
;
726 /* Move to the start of the format block */
727 rp
= nubus_rom_addr(slot
);
728 nubus_rewind(&rp
, FORMAT_BLOCK_SIZE
, bytelanes
);
730 /* Actually we should probably panic if this fails */
731 if ((board
= kzalloc(sizeof(*board
), GFP_ATOMIC
)) == NULL
)
735 /* Dump the format block for debugging purposes */
736 pr_debug("Slot %X, format block at 0x%p:\n", slot
, rp
);
737 pr_debug("%08lx\n", nubus_get_rom(&rp
, 4, bytelanes
));
738 pr_debug("%08lx\n", nubus_get_rom(&rp
, 4, bytelanes
));
739 pr_debug("%08lx\n", nubus_get_rom(&rp
, 4, bytelanes
));
740 pr_debug("%02lx\n", nubus_get_rom(&rp
, 1, bytelanes
));
741 pr_debug("%02lx\n", nubus_get_rom(&rp
, 1, bytelanes
));
742 pr_debug("%08lx\n", nubus_get_rom(&rp
, 4, bytelanes
));
743 pr_debug("%02lx\n", nubus_get_rom(&rp
, 1, bytelanes
));
744 pr_debug("%02lx\n", nubus_get_rom(&rp
, 1, bytelanes
));
748 board
->slot_addr
= (unsigned long)nubus_slot_addr(slot
);
749 board
->doffset
= nubus_get_rom(&rp
, 4, bytelanes
);
750 /* rom_length is *supposed* to be the total length of the
751 * ROM. In practice it is the "amount of ROM used to compute
752 * the CRC." So some jokers decide to set it to zero and
753 * set the crc to zero so they don't have to do any math.
754 * See the Performa 460 ROM, for example. Those Apple "engineers".
756 board
->rom_length
= nubus_get_rom(&rp
, 4, bytelanes
);
757 board
->crc
= nubus_get_rom(&rp
, 4, bytelanes
);
758 board
->rev
= nubus_get_rom(&rp
, 1, bytelanes
);
759 board
->format
= nubus_get_rom(&rp
, 1, bytelanes
);
760 board
->lanes
= bytelanes
;
762 /* Directory offset should be small and negative... */
763 if (!(board
->doffset
& 0x00FF0000))
764 pr_warn("Slot %X: Dodgy doffset!\n", slot
);
765 dpat
= nubus_get_rom(&rp
, 4, bytelanes
);
766 if (dpat
!= NUBUS_TEST_PATTERN
)
767 pr_warn("Slot %X: Wrong test pattern %08lx!\n", slot
, dpat
);
770 * I wonder how the CRC is meant to work -
772 * CSA: According to MAC docs, not all cards pass the CRC anyway,
773 * since the initial Macintosh ROM releases skipped the check.
776 /* Set up the directory pointer */
777 board
->directory
= board
->fblock
;
778 nubus_move(&board
->directory
, nubus_expand32(board
->doffset
),
781 nubus_get_root_dir(board
, &dir
);
783 /* We're ready to rock */
784 pr_debug("Slot %X resources:\n", slot
);
786 /* Each slot should have one board resource and any number of
787 * functional resources. So we'll fill in some fields in the
788 * struct nubus_board from the board resource, then walk down
789 * the list of functional resources, spinning out a nubus_rsrc
792 if (nubus_readdir(&dir
, &ent
) == -1) {
793 /* We can't have this! */
794 pr_err("Slot %X: Board resource not found!\n", slot
);
799 if (ent
.type
< 1 || ent
.type
> 127)
800 pr_warn("Slot %X: Board resource ID is invalid!\n", slot
);
802 board
->procdir
= nubus_proc_add_board(board
);
804 nubus_get_board_resource(board
, slot
, &ent
);
806 while (nubus_readdir(&dir
, &ent
) != -1) {
807 struct nubus_rsrc
*fres
;
809 fres
= nubus_get_functional_resource(board
, slot
, &ent
);
813 /* Resources should appear in ascending ID order. This sanity
814 * check prevents duplicate resource IDs.
816 if (fres
->resid
<= prev_resid
) {
820 prev_resid
= fres
->resid
;
822 list_add_tail(&fres
->list
, &nubus_func_rsrcs
);
825 if (nubus_device_register(board
))
826 put_device(&board
->dev
);
829 static void __init
nubus_probe_slot(int slot
)
835 rp
= nubus_rom_addr(slot
);
836 for (i
= 4; i
; i
--) {
838 if (!hwreg_present(rp
))
843 /* The last byte of the format block consists of two
844 nybbles which are "mirror images" of each other.
845 These show us the valid bytelanes */
846 if ((((dp
>> 4) ^ dp
) & 0x0F) != 0x0F)
848 /* Check that this value is actually *on* one of the
849 bytelanes it claims are valid! */
850 if (not_useful(rp
, dp
))
853 /* Looks promising. Let's put it on the list. */
854 nubus_add_board(slot
, dp
);
860 static void __init
nubus_scan_bus(void)
864 pr_info("NuBus: Scanning NuBus slots.\n");
865 for (slot
= 9; slot
< 15; slot
++) {
866 nubus_probe_slot(slot
);
870 static int __init
nubus_init(void)
878 err
= nubus_parent_device_register();
885 subsys_initcall(nubus_init
);