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 /* The "nubus.populate_procfs" parameter makes slot resources available in
36 * procfs. It's deprecated and disabled by default because procfs is no longer
37 * thought to be suitable for that and some board ROMs make it too expensive.
39 bool nubus_populate_procfs;
40 module_param_named(populate_procfs, nubus_populate_procfs, bool, 0);
42 LIST_HEAD(nubus_func_rsrcs);
44 /* Meaning of "bytelanes":
46 The card ROM may appear on any or all bytes of each long word in
47 NuBus memory. The low 4 bits of the "map" value found in the
48 format block (at the top of the slot address space, as well as at
49 the top of the MacOS ROM) tells us which bytelanes, i.e. which byte
50 offsets within each longword, are valid. Thus:
52 A map of 0x0f, as found in the MacOS ROM, means that all bytelanes
55 A map of 0xf0 means that no bytelanes are valid (We pray that we
56 will never encounter this, but stranger things have happened)
58 A map of 0xe1 means that only the MSB of each long word is actually
59 part of the card ROM. (We hope to never encounter NuBus on a
60 little-endian machine. Again, stranger things have happened)
62 A map of 0x78 means that only the LSB of each long word is valid.
64 Etcetera, etcetera. Hopefully this clears up some confusion over
65 what the following code actually does. */
67 static inline int not_useful(void *p, int map)
69 unsigned long pv = (unsigned long)p;
77 static unsigned long nubus_get_rom(unsigned char **ptr, int len, int map)
79 /* This will hold the result */
81 unsigned char *p = *ptr;
85 while (not_useful(p, map))
94 static void nubus_rewind(unsigned char **ptr, int len, int map)
96 unsigned char *p = *ptr;
101 } while (not_useful(p, map));
107 static void nubus_advance(unsigned char **ptr, int len, int map)
109 unsigned char *p = *ptr;
112 while (not_useful(p, map))
120 static void nubus_move(unsigned char **ptr, int len, int map)
122 unsigned long slot_space = (unsigned long)*ptr & 0xFF000000;
125 nubus_advance(ptr, len, map);
127 nubus_rewind(ptr, -len, map);
129 if (((unsigned long)*ptr & 0xFF000000) != slot_space)
130 pr_err("%s: moved out of slot address space!\n", __func__);
133 /* Now, functions to read the sResource tree */
135 /* Each sResource entry consists of a 1-byte ID and a 3-byte data
136 field. If that data field contains an offset, then obviously we
137 have to expand it from a 24-bit signed number to a 32-bit signed
140 static inline long nubus_expand32(long foo)
142 if (foo & 0x00800000) /* 24bit negative */
147 static inline void *nubus_rom_addr(int slot)
150 * Returns the first byte after the card. We then walk
151 * backwards to get the lane register and the config
153 return (void *)(0xF1000000 + (slot << 24));
156 unsigned char *nubus_dirptr(const struct nubus_dirent *nd)
158 unsigned char *p = nd->base;
160 /* Essentially, just step over the bytelanes using whatever
161 offset we might have found */
162 nubus_move(&p, nubus_expand32(nd->data), nd->mask);
163 /* And return the value */
167 /* These two are for pulling resource data blocks (i.e. stuff that's
168 pointed to with offsets) out of the card ROM. */
170 void nubus_get_rsrc_mem(void *dest, const struct nubus_dirent *dirent,
173 unsigned char *t = dest;
174 unsigned char *p = nubus_dirptr(dirent);
177 *t++ = nubus_get_rom(&p, 1, dirent->mask);
181 EXPORT_SYMBOL(nubus_get_rsrc_mem);
183 unsigned int nubus_get_rsrc_str(char *dest, const struct nubus_dirent *dirent,
187 unsigned char *p = nubus_dirptr(dirent);
190 unsigned char c = nubus_get_rom(&p, 1, dirent->mask);
201 EXPORT_SYMBOL(nubus_get_rsrc_str);
203 void nubus_seq_write_rsrc_mem(struct seq_file *m,
204 const struct nubus_dirent *dirent,
207 unsigned long buf[32];
208 unsigned int buf_size = sizeof(buf);
209 unsigned char *p = nubus_dirptr(dirent);
211 /* If possible, write out full buffers */
212 while (len >= buf_size) {
215 for (i = 0; i < ARRAY_SIZE(buf); i++)
216 buf[i] = nubus_get_rom(&p, sizeof(buf[0]),
218 seq_write(m, buf, buf_size);
221 /* If not, write out individual bytes */
223 seq_putc(m, nubus_get_rom(&p, 1, dirent->mask));
226 int nubus_get_root_dir(const struct nubus_board *board,
227 struct nubus_dir *dir)
229 dir->ptr = dir->base = board->directory;
231 dir->mask = board->lanes;
234 EXPORT_SYMBOL(nubus_get_root_dir);
236 /* This is a slyly renamed version of the above */
237 int nubus_get_func_dir(const struct nubus_rsrc *fres, struct nubus_dir *dir)
239 dir->ptr = dir->base = fres->directory;
241 dir->mask = fres->board->lanes;
244 EXPORT_SYMBOL(nubus_get_func_dir);
246 int nubus_get_board_dir(const struct nubus_board *board,
247 struct nubus_dir *dir)
249 struct nubus_dirent ent;
251 dir->ptr = dir->base = board->directory;
253 dir->mask = board->lanes;
255 /* Now dereference it (the first directory is always the board
257 if (nubus_readdir(dir, &ent) == -1)
259 if (nubus_get_subdir(&ent, dir) == -1)
263 EXPORT_SYMBOL(nubus_get_board_dir);
265 int nubus_get_subdir(const struct nubus_dirent *ent,
266 struct nubus_dir *dir)
268 dir->ptr = dir->base = nubus_dirptr(ent);
270 dir->mask = ent->mask;
273 EXPORT_SYMBOL(nubus_get_subdir);
275 int nubus_readdir(struct nubus_dir *nd, struct nubus_dirent *ent)
282 /* Do this first, otherwise nubus_rewind & co are off by 4 */
285 /* This moves nd->ptr forward */
286 resid = nubus_get_rom(&nd->ptr, 4, nd->mask);
288 /* EOL marker, as per the Apple docs */
289 if ((resid & 0xff000000) == 0xff000000) {
290 /* Mark it as done */
295 /* First byte is the resource ID */
296 ent->type = resid >> 24;
297 /* Low 3 bytes might contain data (or might not) */
298 ent->data = resid & 0xffffff;
299 ent->mask = nd->mask;
302 EXPORT_SYMBOL(nubus_readdir);
304 int nubus_rewinddir(struct nubus_dir *dir)
306 dir->ptr = dir->base;
310 EXPORT_SYMBOL(nubus_rewinddir);
312 /* Driver interface functions, more or less like in pci.c */
314 struct nubus_rsrc *nubus_first_rsrc_or_null(void)
316 return list_first_entry_or_null(&nubus_func_rsrcs, struct nubus_rsrc,
319 EXPORT_SYMBOL(nubus_first_rsrc_or_null);
321 struct nubus_rsrc *nubus_next_rsrc_or_null(struct nubus_rsrc *from)
323 if (list_is_last(&from->list, &nubus_func_rsrcs))
325 return list_next_entry(from, list);
327 EXPORT_SYMBOL(nubus_next_rsrc_or_null);
330 nubus_find_rsrc(struct nubus_dir *dir, unsigned char rsrc_type,
331 struct nubus_dirent *ent)
333 while (nubus_readdir(dir, ent) != -1) {
334 if (ent->type == rsrc_type)
339 EXPORT_SYMBOL(nubus_find_rsrc);
341 /* Initialization functions - decide which slots contain stuff worth
342 looking at, and print out lots and lots of information from the
345 static int __init nubus_get_block_rsrc_dir(struct nubus_board *board,
346 struct proc_dir_entry *procdir,
347 const struct nubus_dirent *parent)
349 struct nubus_dir dir;
350 struct nubus_dirent ent;
352 nubus_get_subdir(parent, &dir);
353 dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
355 while (nubus_readdir(&dir, &ent) != -1) {
358 nubus_get_rsrc_mem(&size, &ent, 4);
359 pr_debug(" block (0x%x), size %d\n", ent.type, size);
360 nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
365 static int __init nubus_get_display_vidmode(struct nubus_board *board,
366 struct proc_dir_entry *procdir,
367 const struct nubus_dirent *parent)
369 struct nubus_dir dir;
370 struct nubus_dirent ent;
372 nubus_get_subdir(parent, &dir);
373 dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
375 while (nubus_readdir(&dir, &ent) != -1) {
377 case 1: /* mVidParams */
382 nubus_get_rsrc_mem(&size, &ent, 4);
383 pr_debug(" block (0x%x), size %d\n", ent.type,
385 nubus_proc_add_rsrc_mem(dir.procdir, &ent, size);
389 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
391 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
397 static int __init nubus_get_display_resource(struct nubus_rsrc *fres,
398 struct proc_dir_entry *procdir,
399 const struct nubus_dirent *ent)
402 case NUBUS_RESID_GAMMADIR:
403 pr_debug(" gamma directory offset: 0x%06x\n", ent->data);
404 nubus_get_block_rsrc_dir(fres->board, procdir, ent);
406 case 0x0080 ... 0x0085:
407 pr_debug(" mode 0x%02x info offset: 0x%06x\n",
408 ent->type, ent->data);
409 nubus_get_display_vidmode(fres->board, procdir, ent);
412 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
413 ent->type, ent->data);
414 nubus_proc_add_rsrc_mem(procdir, ent, 0);
419 static int __init nubus_get_network_resource(struct nubus_rsrc *fres,
420 struct proc_dir_entry *procdir,
421 const struct nubus_dirent *ent)
424 case NUBUS_RESID_MAC_ADDRESS:
428 nubus_get_rsrc_mem(addr, ent, 6);
429 pr_debug(" MAC address: %pM\n", addr);
430 nubus_proc_add_rsrc_mem(procdir, ent, 6);
434 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
435 ent->type, ent->data);
436 nubus_proc_add_rsrc_mem(procdir, ent, 0);
441 static int __init nubus_get_cpu_resource(struct nubus_rsrc *fres,
442 struct proc_dir_entry *procdir,
443 const struct nubus_dirent *ent)
446 case NUBUS_RESID_MEMINFO:
448 unsigned long meminfo[2];
450 nubus_get_rsrc_mem(&meminfo, ent, 8);
451 pr_debug(" memory: [ 0x%08lx 0x%08lx ]\n",
452 meminfo[0], meminfo[1]);
453 nubus_proc_add_rsrc_mem(procdir, ent, 8);
456 case NUBUS_RESID_ROMINFO:
458 unsigned long rominfo[2];
460 nubus_get_rsrc_mem(&rominfo, ent, 8);
461 pr_debug(" ROM: [ 0x%08lx 0x%08lx ]\n",
462 rominfo[0], rominfo[1]);
463 nubus_proc_add_rsrc_mem(procdir, ent, 8);
467 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
468 ent->type, ent->data);
469 nubus_proc_add_rsrc_mem(procdir, ent, 0);
474 static int __init nubus_get_private_resource(struct nubus_rsrc *fres,
475 struct proc_dir_entry *procdir,
476 const struct nubus_dirent *ent)
478 switch (fres->category) {
479 case NUBUS_CAT_DISPLAY:
480 nubus_get_display_resource(fres, procdir, ent);
482 case NUBUS_CAT_NETWORK:
483 nubus_get_network_resource(fres, procdir, ent);
486 nubus_get_cpu_resource(fres, procdir, ent);
489 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
490 ent->type, ent->data);
491 nubus_proc_add_rsrc_mem(procdir, ent, 0);
496 static struct nubus_rsrc * __init
497 nubus_get_functional_resource(struct nubus_board *board, int slot,
498 const struct nubus_dirent *parent)
500 struct nubus_dir dir;
501 struct nubus_dirent ent;
502 struct nubus_rsrc *fres;
504 pr_debug(" Functional resource 0x%02x:\n", parent->type);
505 nubus_get_subdir(parent, &dir);
506 dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
508 /* Actually we should probably panic if this fails */
509 fres = kzalloc(sizeof(*fres), GFP_ATOMIC);
512 fres->resid = parent->type;
513 fres->directory = dir.base;
516 while (nubus_readdir(&dir, &ent) != -1) {
518 case NUBUS_RESID_TYPE:
520 unsigned short nbtdata[4];
522 nubus_get_rsrc_mem(nbtdata, &ent, 8);
523 fres->category = nbtdata[0];
524 fres->type = nbtdata[1];
525 fres->dr_sw = nbtdata[2];
526 fres->dr_hw = nbtdata[3];
527 pr_debug(" type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
528 nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
529 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
532 case NUBUS_RESID_NAME:
537 len = nubus_get_rsrc_str(name, &ent, sizeof(name));
538 pr_debug(" name: %s\n", name);
539 nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
542 case NUBUS_RESID_DRVRDIR:
544 /* MacOS driver. If we were NetBSD we might
546 pr_debug(" driver directory offset: 0x%06x\n",
548 nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
551 case NUBUS_RESID_MINOR_BASEOS:
553 /* We will need this in order to support
554 multiple framebuffers. It might be handy
555 for Ethernet as well */
558 nubus_get_rsrc_mem(&base_offset, &ent, 4);
559 pr_debug(" memory offset: 0x%08x\n", base_offset);
560 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
563 case NUBUS_RESID_MINOR_LENGTH:
568 nubus_get_rsrc_mem(&length, &ent, 4);
569 pr_debug(" memory length: 0x%08x\n", length);
570 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 4);
573 case NUBUS_RESID_FLAGS:
574 pr_debug(" flags: 0x%06x\n", ent.data);
575 nubus_proc_add_rsrc(dir.procdir, &ent);
577 case NUBUS_RESID_HWDEVID:
578 pr_debug(" hwdevid: 0x%06x\n", ent.data);
579 nubus_proc_add_rsrc(dir.procdir, &ent);
582 if (nubus_populate_procfs)
583 nubus_get_private_resource(fres, dir.procdir,
591 /* This is *really* cool. */
592 static int __init nubus_get_icon(struct nubus_board *board,
593 struct proc_dir_entry *procdir,
594 const struct nubus_dirent *ent)
596 /* Should be 32x32 if my memory serves me correctly */
600 nubus_get_rsrc_mem(&icon, ent, 128);
601 pr_debug(" icon:\n");
602 for (i = 0; i < 8; i++)
603 pr_debug(" %08x %08x %08x %08x\n",
604 icon[i * 4 + 0], icon[i * 4 + 1],
605 icon[i * 4 + 2], icon[i * 4 + 3]);
606 nubus_proc_add_rsrc_mem(procdir, ent, 128);
611 static int __init nubus_get_vendorinfo(struct nubus_board *board,
612 struct proc_dir_entry *procdir,
613 const struct nubus_dirent *parent)
615 struct nubus_dir dir;
616 struct nubus_dirent ent;
617 static char *vendor_fields[6] = { "ID", "serial", "revision",
618 "part", "date", "unknown field" };
620 pr_debug(" vendor info:\n");
621 nubus_get_subdir(parent, &dir);
622 dir.procdir = nubus_proc_add_rsrc_dir(procdir, parent, board);
624 while (nubus_readdir(&dir, &ent) != -1) {
628 /* These are all strings, we think */
629 len = nubus_get_rsrc_str(name, &ent, sizeof(name));
630 if (ent.type < 1 || ent.type > 5)
632 pr_debug(" %s: %s\n", vendor_fields[ent.type - 1], name);
633 nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
638 static int __init nubus_get_board_resource(struct nubus_board *board, int slot,
639 const struct nubus_dirent *parent)
641 struct nubus_dir dir;
642 struct nubus_dirent ent;
644 pr_debug(" Board resource 0x%02x:\n", parent->type);
645 nubus_get_subdir(parent, &dir);
646 dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board);
648 while (nubus_readdir(&dir, &ent) != -1) {
650 case NUBUS_RESID_TYPE:
652 unsigned short nbtdata[4];
653 /* This type is always the same, and is not
654 useful except insofar as it tells us that
655 we really are looking at a board resource. */
656 nubus_get_rsrc_mem(nbtdata, &ent, 8);
657 pr_debug(" type: [cat 0x%x type 0x%x sw 0x%x hw 0x%x]\n",
658 nbtdata[0], nbtdata[1], nbtdata[2], nbtdata[3]);
659 if (nbtdata[0] != 1 || nbtdata[1] != 0 ||
660 nbtdata[2] != 0 || nbtdata[3] != 0)
661 pr_err("Slot %X: sResource is not a board resource!\n",
663 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 8);
666 case NUBUS_RESID_NAME:
670 len = nubus_get_rsrc_str(board->name, &ent,
671 sizeof(board->name));
672 pr_debug(" name: %s\n", board->name);
673 nubus_proc_add_rsrc_mem(dir.procdir, &ent, len + 1);
676 case NUBUS_RESID_ICON:
677 nubus_get_icon(board, dir.procdir, &ent);
679 case NUBUS_RESID_BOARDID:
680 pr_debug(" board id: 0x%x\n", ent.data);
681 nubus_proc_add_rsrc(dir.procdir, &ent);
683 case NUBUS_RESID_PRIMARYINIT:
684 pr_debug(" primary init offset: 0x%06x\n", ent.data);
685 nubus_proc_add_rsrc(dir.procdir, &ent);
687 case NUBUS_RESID_VENDORINFO:
688 nubus_get_vendorinfo(board, dir.procdir, &ent);
690 case NUBUS_RESID_FLAGS:
691 pr_debug(" flags: 0x%06x\n", ent.data);
692 nubus_proc_add_rsrc(dir.procdir, &ent);
694 case NUBUS_RESID_HWDEVID:
695 pr_debug(" hwdevid: 0x%06x\n", ent.data);
696 nubus_proc_add_rsrc(dir.procdir, &ent);
698 case NUBUS_RESID_SECONDINIT:
699 pr_debug(" secondary init offset: 0x%06x\n",
701 nubus_proc_add_rsrc(dir.procdir, &ent);
703 /* WTF isn't this in the functional resources? */
704 case NUBUS_RESID_VIDNAMES:
705 pr_debug(" vidnames directory offset: 0x%06x\n",
707 nubus_get_block_rsrc_dir(board, dir.procdir, &ent);
709 /* Same goes for this */
710 case NUBUS_RESID_VIDMODES:
711 pr_debug(" video mode parameter directory offset: 0x%06x\n",
713 nubus_proc_add_rsrc(dir.procdir, &ent);
716 pr_debug(" unknown resource 0x%02x, data 0x%06x\n",
718 nubus_proc_add_rsrc_mem(dir.procdir, &ent, 0);
724 static void __init nubus_add_board(int slot, int bytelanes)
726 struct nubus_board *board;
729 struct nubus_dir dir;
730 struct nubus_dirent ent;
733 /* Move to the start of the format block */
734 rp = nubus_rom_addr(slot);
735 nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes);
737 /* Actually we should probably panic if this fails */
738 if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL)
742 /* Dump the format block for debugging purposes */
743 pr_debug("Slot %X, format block at 0x%p:\n", slot, rp);
744 pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
745 pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
746 pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
747 pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
748 pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
749 pr_debug("%08lx\n", nubus_get_rom(&rp, 4, bytelanes));
750 pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
751 pr_debug("%02lx\n", nubus_get_rom(&rp, 1, bytelanes));
755 board->slot_addr = (unsigned long)nubus_slot_addr(slot);
756 board->doffset = nubus_get_rom(&rp, 4, bytelanes);
757 /* rom_length is *supposed* to be the total length of the
758 * ROM. In practice it is the "amount of ROM used to compute
759 * the CRC." So some jokers decide to set it to zero and
760 * set the crc to zero so they don't have to do any math.
761 * See the Performa 460 ROM, for example. Those Apple "engineers".
763 board->rom_length = nubus_get_rom(&rp, 4, bytelanes);
764 board->crc = nubus_get_rom(&rp, 4, bytelanes);
765 board->rev = nubus_get_rom(&rp, 1, bytelanes);
766 board->format = nubus_get_rom(&rp, 1, bytelanes);
767 board->lanes = bytelanes;
769 /* Directory offset should be small and negative... */
770 if (!(board->doffset & 0x00FF0000))
771 pr_warn("Slot %X: Dodgy doffset!\n", slot);
772 dpat = nubus_get_rom(&rp, 4, bytelanes);
773 if (dpat != NUBUS_TEST_PATTERN)
774 pr_warn("Slot %X: Wrong test pattern %08lx!\n", slot, dpat);
777 * I wonder how the CRC is meant to work -
779 * CSA: According to MAC docs, not all cards pass the CRC anyway,
780 * since the initial Macintosh ROM releases skipped the check.
783 /* Set up the directory pointer */
784 board->directory = board->fblock;
785 nubus_move(&board->directory, nubus_expand32(board->doffset),
788 nubus_get_root_dir(board, &dir);
790 /* We're ready to rock */
791 pr_debug("Slot %X resources:\n", slot);
793 /* Each slot should have one board resource and any number of
794 * functional resources. So we'll fill in some fields in the
795 * struct nubus_board from the board resource, then walk down
796 * the list of functional resources, spinning out a nubus_rsrc
799 if (nubus_readdir(&dir, &ent) == -1) {
800 /* We can't have this! */
801 pr_err("Slot %X: Board resource not found!\n", slot);
806 if (ent.type < 1 || ent.type > 127)
807 pr_warn("Slot %X: Board resource ID is invalid!\n", slot);
809 board->procdir = nubus_proc_add_board(board);
811 nubus_get_board_resource(board, slot, &ent);
813 while (nubus_readdir(&dir, &ent) != -1) {
814 struct nubus_rsrc *fres;
816 fres = nubus_get_functional_resource(board, slot, &ent);
820 /* Resources should appear in ascending ID order. This sanity
821 * check prevents duplicate resource IDs.
823 if (fres->resid <= prev_resid) {
827 prev_resid = fres->resid;
829 list_add_tail(&fres->list, &nubus_func_rsrcs);
832 if (nubus_device_register(board))
833 put_device(&board->dev);
836 static void __init nubus_probe_slot(int slot)
842 rp = nubus_rom_addr(slot);
843 for (i = 4; i; i--) {
845 if (!hwreg_present(rp))
850 /* The last byte of the format block consists of two
851 nybbles which are "mirror images" of each other.
852 These show us the valid bytelanes */
853 if ((((dp >> 4) ^ dp) & 0x0F) != 0x0F)
855 /* Check that this value is actually *on* one of the
856 bytelanes it claims are valid! */
857 if (not_useful(rp, dp))
860 /* Looks promising. Let's put it on the list. */
861 nubus_add_board(slot, dp);
867 static void __init nubus_scan_bus(void)
871 pr_info("NuBus: Scanning NuBus slots.\n");
872 for (slot = 9; slot < 15; slot++) {
873 nubus_probe_slot(slot);
877 static int __init nubus_init(void)
885 err = nubus_parent_device_register();
892 subsys_initcall(nubus_init);