Example #1
0
static pfn_t slot_psize_compute(cnodeid_t node, int slot)
{
	nasid_t nasid;
	lboard_t *brd;
	klmembnk_t *banks;
	unsigned long size;

	nasid = COMPACT_TO_NASID_NODEID(node);
	/* Find the node board */
	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);
	if (!brd)
		return 0;

	/* Get the memory bank structure */
	banks = (klmembnk_t *)find_first_component(brd, KLSTRUCT_MEMBNK);
	if (!banks)
		return 0;

	/* Size in _Megabytes_ */
	size = (unsigned long)banks->membnk_bnksz[slot/4];

	/* hack for 128 dimm banks */
	if (size <= 128) {
		if (slot%4 == 0) {
			size <<= 20;		/* size in bytes */
			return(size >> PAGE_SHIFT);
		} else {
			return 0;
Example #2
0
File: module.c Project: nhanh0/hah
void
io_module_init(void)
{
    cnodeid_t		node;
    lboard_t	       *board;
    nasid_t		nasid;
    int			nserial;
    module_t	       *m;

    DPRINTF("*******module_init\n");

    nserial = 0;

    for (node = 0; node < numnodes; node++) {
	nasid = COMPACT_TO_NASID_NODEID(node);

	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
			    KLTYPE_IP27);
	ASSERT(board);

	m = module_add_node(board->brd_module, node);

	if (! m->snum_valid && module_probe_snum(m, nasid))
	    nserial++;
    }

    DPRINTF("********found total of %d serial numbers in the system\n",
	    nserial);

    if (nserial == 0)
	PRINT_WARNING("io_module_init: No serial number found.\n");
}
Example #3
0
static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
{
	static int tot_cpus_found = 0;
	lboard_t *brd;
	klcpu_t *acpu;
	int cpus_found = 0;
	cpuid_t cpuid;

	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);

	do {
		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
		while (acpu) {
			cpuid = acpu->cpu_info.virtid;
			/* cnode is not valid for completely disabled brds */
			if (get_actual_nasid(brd) == brd->brd_nasid)
				cpuid_to_compact_node[cpuid] = cnode;
			if (cpuid > highest)
				highest = cpuid;
			/* Only let it join in if it's marked enabled */
			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
			    (tot_cpus_found != NR_CPUS)) {
<<<<<<< HEAD
				set_cpu_possible(cpuid, true);
=======
<<<<<<< HEAD
				set_cpu_possible(cpuid, true);
=======
				cpu_set(cpuid, cpu_possible_map);
>>>>>>> 58a75b6a81be54a8b491263ca1af243e9d8617b9
>>>>>>> ae1773bb70f3d7cf73324ce8fba787e01d8fa9f2
Example #4
0
static int __cpuinit xbow_probe(nasid_t nasid)
{
	lboard_t *brd;
	klxbow_t *xbow_p;
	unsigned masterwid, i;

	printk("is xbow\n");

	/*
	 * found xbow, so may have multiple bridges
	 * need to probe xbow
	 */
	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_MIDPLANE8);
	if (!brd)
		return -ENODEV;

	xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW);
	if (!xbow_p)
		return -ENODEV;

	/*
	 * Okay, here's a xbow. Lets arbitrate and find
	 * out if we should initialize it. Set enabled
	 * hub connected at highest or lowest widget as
	 * master.
	 */
#ifdef WIDGET_A
	i = HUB_WIDGET_ID_MAX + 1;
	do {
		i--;
	} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
		 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
#else
	i = HUB_WIDGET_ID_MIN - 1;
	do {
		i++;
	} while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
		 (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
#endif

	masterwid = i;
	if (nasid != XBOW_PORT_NASID(xbow_p, i))
		return 1;

	for (i = HUB_WIDGET_ID_MIN; i <= HUB_WIDGET_ID_MAX; i++) {
		if (XBOW_PORT_IS_ENABLED(xbow_p, i) &&
		    XBOW_PORT_TYPE_IO(xbow_p, i))
			probe_one_port(nasid, i, masterwid);
	}

	return 0;
}
Example #5
0
static int do_cpumask(cnodeid_t cnode, nasid_t nasid, int highest)
{
	static int tot_cpus_found = 0;
	lboard_t *brd;
	klcpu_t *acpu;
	int cpus_found = 0;
	cpuid_t cpuid;

	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27);

	do {
		acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU);
		while (acpu) {
			cpuid = acpu->cpu_info.virtid;
			/* cnode is not valid for completely disabled brds */
			if (get_actual_nasid(brd) == brd->brd_nasid)
				cpuid_to_compact_node[cpuid] = cnode;
			if (cpuid > highest)
				highest = cpuid;
			/* Only let it join in if it's marked enabled */
			if ((acpu->cpu_info.flags & KLINFO_ENABLE) &&
			    (tot_cpus_found != NR_CPUS)) {
				cpu_set(cpuid, phys_cpu_present_map);
				alloc_cpupda(cpuid, tot_cpus_found);
				cpus_found++;
				tot_cpus_found++;
			}
			acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
								KLSTRUCT_CPU);
		}
		brd = KLCF_NEXT(brd);
		if (!brd)
			break;

		brd = find_lboard(brd, KLTYPE_IP27);
	} while (brd);

	return highest;
}
Example #6
0
int module_probe_snum(module_t *m, nasid_t nasid)
{
    lboard_t	       *board;
    klmod_serial_num_t *comp;

    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
			KLTYPE_MIDPLANE8);

    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
	return 0;

    comp = GET_SNUM_COMP(board);

    if (comp) {
#if LDEBUG
	    int i;

	    printf("********found module with id %x and string", m->id);

	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
		printf(" %x ", comp->snum.snum_str[i]);

	    printf("\n");	/* Fudged string is not ASCII */
#endif

	    if (comp->snum.snum_str[0] != '\0') {
		bcopy(comp->snum.snum_str,
		      m->snum.snum_str,
		      MAX_SERIAL_NUM_SIZE);
		m->snum_valid = 1;
	    }
    }

    if (m->snum_valid)
	return 1;
    else {
#ifndef CONFIG_IA64_SGI_IO
	cmn_err(CE_WARN | CE_MAINTENANCE,
		"Invalid serial number for module %d, "
		"possible missing or invalid NIC.", m->id);
#else
	printk("Invalid serial number for module %d, "
		"possible missing or invalid NIC.", m->id);
#endif
	return 0;
    }
}
Example #7
0
klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
{
	lboard_t *brd;
	klcpu_t *acpu;

	if (!(brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IP27)))
		return (klcpu_t *)NULL;

	if (!(acpu = (klcpu_t *)find_first_component(brd, KLSTRUCT_CPU)))
		return (klcpu_t *)NULL;

	do {
		if ((acpu->cpu_info.physid) == slice)
			return acpu;
	} while ((acpu = (klcpu_t *)find_component(brd, (klinfo_t *)acpu,
								KLSTRUCT_CPU)));
	return (klcpu_t *)NULL;
}
Example #8
0
void __init cpu_time_init(void)
{
	lboard_t *board;
	klcpu_t *cpu;
	int cpuid;

	/* Don't use ARCS.  ARCS is fragile.  Klconfig is simple and sane.  */
	board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
	if (!board)
		panic("Can't find board info for myself.");

	cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
	cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
	if (!cpu)
		panic("No information about myself?");

	printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);

	set_c0_status(SRB_TIMOCLK);
}
void
io_xswitch_widget_init(vertex_hdl_t  	xswitchv,
		       vertex_hdl_t	hubv,
		       xwidgetnum_t	widgetnum)
{
	xswitch_info_t		xswitch_info;
	xwidgetnum_t		hub_widgetid;
	vertex_hdl_t		widgetv;
	cnodeid_t		cnode;
	widgetreg_t		widget_id;
	nasid_t			nasid, peer_nasid;
	struct xwidget_hwid_s 	hwid;
	hubinfo_t		hubinfo;
	/*REFERENCED*/
	int			rc;
	char 			pathname[128];
	lboard_t		*board = NULL;
	char			buffer[16];
	char			bt;
	moduleid_t		io_module;
	slotid_t get_widget_slotnum(int xbow, int widget);
	
	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);

	/*
	 * Verify that xswitchv is indeed an attached xswitch.
	 */
	xswitch_info = xswitch_info_get(xswitchv);
	ASSERT(xswitch_info != NULL);

	hubinfo_get(hubv, &hubinfo);
	nasid = hubinfo->h_nasid;
	cnode = NASID_TO_COMPACT_NODEID(nasid);
	hub_widgetid = hubinfo->h_widgetid;

	/*
	 * Check that the widget is an io widget and is enabled
	 * on this nasid or the `peer' nasid.  The peer nasid
	 * is the other hub/bedrock connected to the xbow.
	 */
	peer_nasid = NODEPDA(cnode)->xbow_peer;
	if (peer_nasid == INVALID_NASID)
		/* If I don't have a peer, use myself. */
		peer_nasid = nasid;
	if (!xbow_port_io_enabled(nasid, widgetnum) &&
	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
		return;
	}

	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
		char			name[4];
		lboard_t dummy;


		/*
		 * If the current hub is not supposed to be the master 
		 * for this widgetnum, then skip this widget.
		 */

		if (xswitch_info_master_assignment_get(xswitch_info, widgetnum) != hubv) {
			return;
		}

		board = find_lboard_class(
				(lboard_t *)KL_CONFIG_INFO(nasid),
				KLCLASS_IOBRICK);
		if (!board && NODEPDA(cnode)->xbow_peer != INVALID_NASID) {
		    	board = find_lboard_class(
					(lboard_t *)KL_CONFIG_INFO( NODEPDA(cnode)->xbow_peer),
						KLCLASS_IOBRICK);
		}

		if (board) {
			DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
		} else {
			DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
			board = &dummy;
		}


		/* Copy over the nodes' geoid info */
		{
			lboard_t *brd;

			brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
			if ( brd != (lboard_t *)0 ) {
				board->brd_geoid = brd->brd_geoid;
			}
		}

		/*
 		 * Make sure we really want to say xbrick, pbrick,
		 * etc. rather than XIO, graphics, etc.
 		 */

		memset(buffer, 0, 16);
		format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);

		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d",
			buffer,
			geo_slab(board->brd_geoid),
			(board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK :
			(board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK :
			(board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK :
			(board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK :
			(board->brd_type == KLTYPE_CGBRICK) ? EDGE_LBL_CGBRICK :
			(board->brd_type == KLTYPE_OPUSBRICK) ? EDGE_LBL_OPUSBRICK :
			(board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick",
			EDGE_LBL_XTALK, widgetnum);
		
		DBG("io_xswitch_widget_init: path= %s\n", pathname);
		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
		
		ASSERT(rc == GRAPH_SUCCESS);

		/* This is needed to let the user programs to map the
		 * module,slot numbers to the corresponding widget numbers
		 * on the crossbow.
		 */
		device_master_set(hwgraph_connectpt_get(widgetv), hubv);
		sprintf(name, "%d", widgetnum);
		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
		rc = hwgraph_edge_add(xswitchv, widgetv, name);
		
		/*
		 * crosstalk switch code tracks which
		 * widget is attached to each link.
		 */
		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
		
		/*
		 * Peek at the widget to get its crosstalk part and
		 * mfgr numbers, then present it to the generic xtalk
		 * bus provider to have its driver attach routine
		 * called (or not).
		 */
		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
		hwid.part_num = XWIDGET_PART_NUM(widget_id);
		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
		/* Store some inventory information about
		 * the xwidget in the hardware graph.
		 */
		xwidget_inventory_add(widgetv,board,hwid);

		(void)xwidget_register(&hwid, widgetv, widgetnum,
				       hubv, hub_widgetid);

		ia64_sn_sysctl_iobrick_module_get(nasid, &io_module);
		if (io_module >= 0) {
			char			buffer[16];
			vertex_hdl_t		to, from;
			char           		*brick_name;
			extern char *iobrick_L1bricktype_to_name(int type);


			memset(buffer, 0, 16);
			format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);

			if ( isupper(MODULE_GET_BTCHAR(io_module)) ) {
				bt = tolower(MODULE_GET_BTCHAR(io_module));
			}
			else {
				bt = MODULE_GET_BTCHAR(io_module);
			}

			brick_name = iobrick_L1bricktype_to_name(bt);

			/* Add a helper vertex so xbow monitoring
			* can identify the brick type. It's simply
			* an edge from the widget 0 vertex to the
			*  brick vertex.
			*/

			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
				EDGE_LBL_SLAB "/%d/"
				EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/"
				"0",
				buffer, geo_slab(board->brd_geoid));
			DBG("io_xswitch_widget_init: FROM path '%s'\n", pathname);

			from = hwgraph_path_to_vertex(pathname);
			ASSERT_ALWAYS(from);

			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
				EDGE_LBL_SLAB "/%d/"
				"%s",
				buffer, geo_slab(board->brd_geoid), brick_name);
			DBG("io_xswitch_widget_init: TO path '%s'\n", pathname);
			to = hwgraph_path_to_vertex(pathname);
			ASSERT_ALWAYS(to);
			rc = hwgraph_edge_add(from, to,
				EDGE_LBL_INTERCONNECT);
			if (rc == -EEXIST)
				goto link_done;
			if (rc != GRAPH_SUCCESS) {
				printk("%s: Unable to establish link"
					" for xbmon.", pathname);
			}
link_done:
		}

#ifdef	SN0_USE_BTE
		bte_bpush_war(cnode, (void *)board);
#endif
	}
}
Example #10
0
void __init pcibr_setup(cnodeid_t nid)
{
    int 			i, start, num;
    unsigned long		masterwid;
    bridge_t 		*bridge;
    volatile u64 		hubreg;
    nasid_t	 		nasid, masternasid;
    xwidget_part_num_t	partnum;
    widgetreg_t 		widget_id;
    static spinlock_t	pcibr_setup_lock = SPIN_LOCK_UNLOCKED;

    /*
     * If the master is doing this for headless node, nothing to do.
     * This is because currently we require at least one of the hubs
     * (master hub) connected to the xbow to have at least one enabled
     * cpu to receive intrs. Else we need an array bus_to_intrnasid[]
     * that bridge_startup() needs to use to target intrs. All dma is
     * routed thru the widget of the master hub. The master hub wid
     * is selectable by WIDGET_A below.
     */
    if (nid != get_compact_nodeid())
        return;
    /*
     * find what's on our local node
     */
    spin_lock(&pcibr_setup_lock);
    start = num_bridges;		/* Remember where we start from */
    nasid = COMPACT_TO_NASID_NODEID(nid);
    hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
    if (hubreg & IIO_LLP_CSR_IS_UP) {
        /* link is up */
        widget_id = *(volatile widgetreg_t *)
                    (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
        partnum = XWIDGET_PART_NUM(widget_id);
        printk("Cpu %d, Nasid 0x%x, pcibr_setup(): found partnum= 0x%x",
               smp_processor_id(), nasid, partnum);
        if (partnum == BRIDGE_WIDGET_PART_NUM) {
            /*
             * found direct connected bridge so must be Origin200
             */
            printk("...is bridge\n");
            num_bridges = 1;
            bus_to_wid[0] = 0x8;
            bus_to_nid[0] = 0;
            masterwid = 0xa;
            bus_to_baddr[0] = 0xa100000000000000UL;
        } else if (partnum == XBOW_WIDGET_PART_NUM) {
            lboard_t *brd;
            klxbow_t *xbow_p;
            /*
             * found xbow, so may have multiple bridges
             * need to probe xbow
             */
            printk("...is xbow\n");

            if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid),
                                   KLTYPE_MIDPLANE8)) == NULL)
                printk("argh\n");
            else
                printk("brd = 0x%lx\n", (unsigned long) brd);
            if ((xbow_p = (klxbow_t *)
                          find_component(brd, NULL, KLSTRUCT_XBOW)) == NULL)
                printk("argh\n");
            else {
                /*
                 * Okay, here's a xbow. Lets arbitrate and find
                 * out if we should initialize it. Set enabled
                 * hub connected at highest or lowest widget as
                 * master.
                 */
#ifdef WIDGET_A
                i = HUB_WIDGET_ID_MAX + 1;
                do {
                    i--;
                } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
                         (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
#else
                i = HUB_WIDGET_ID_MIN - 1;
                do {
                    i++;
                } while ((!XBOW_PORT_TYPE_HUB(xbow_p, i)) ||
                         (!XBOW_PORT_IS_ENABLED(xbow_p, i)));
#endif
                masterwid = i;
                masternasid = XBOW_PORT_NASID(xbow_p, i);
                if (nasid == masternasid)
                    for (i=HUB_WIDGET_ID_MIN; i<=HUB_WIDGET_ID_MAX; i++) {
                        if (!XBOW_PORT_IS_ENABLED(xbow_p, i))
                            continue;
                        if (XBOW_PORT_TYPE_IO(xbow_p, i)) {
                            widget_id = *(volatile widgetreg_t *)
                                        (RAW_NODE_SWIN_BASE(nasid, i) + WIDGET_ID);
                            partnum = XWIDGET_PART_NUM(widget_id);
                            if (partnum == BRIDGE_WIDGET_PART_NUM) {
                                printk("widget 0x%x is a bridge\n", i);
                                bus_to_wid[num_bridges] = i;
                                bus_to_nid[num_bridges] = nasid;
                                bus_to_baddr[num_bridges] = ((masterwid << 60) | (1UL << 56));	/* Barrier set */
                                num_bridges++;
                            }
                        }
                    }
            }
        } else if (partnum == XXBOW_WIDGET_PART_NUM) {
            /*
             * found xbridge, assume ibrick for now
             */
            printk("...is xbridge\n");
            bus_to_wid[0] = 0xb;
            bus_to_wid[1] = 0xe;
            bus_to_wid[2] = 0xf;

            bus_to_nid[0] = 0;
            bus_to_nid[1] = 0;
            bus_to_nid[2] = 0;

            bus_to_baddr[0] = 0xa100000000000000UL;
            bus_to_baddr[1] = 0xa100000000000000UL;
            bus_to_baddr[2] = 0xa100000000000000UL;
            masterwid = 0xa;
            num_bridges = 3;
        }
    }
    num = num_bridges - start;
    spin_unlock(&pcibr_setup_lock);
    /*
         * set bridge registers
         */
    for (i = start; i < (start + num); i++) {

        DBG("pcibr_setup: bus= %d  bus_to_wid[%2d]= %d  bus_to_nid[%2d]= %d\n",
            i, i, bus_to_wid[i], i, bus_to_nid[i]);

        bus_to_cpu[i] = smp_processor_id();
        /*
         * point to this bridge
         */
        bridge = (bridge_t *) NODE_SWIN_BASE(bus_to_nid[i],bus_to_wid[i]);
        /*
         * Clear all pending interrupts.
         */
        bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
        /*
         * Until otherwise set up, assume all interrupts are from slot 0
         */
        bridge->b_int_device = (u32) 0x0;
        /*
         * swap pio's to pci mem and io space (big windows)
         */
        bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP;
        bridge->b_wid_control |= BRIDGE_CTRL_MEM_SWAP;

        /*
         * Hmm...  IRIX sets additional bits in the address which
         * are documented as reserved in the bridge docs.
         */
        bridge->b_int_mode = 0x0;		/* Don't clear ints */
        bridge->b_wid_int_upper = 0x8000 | (masterwid << 16);
        bridge->b_wid_int_lower = 0x01800090;	/* PI_INT_PEND_MOD off*/
        bridge->b_dir_map = (masterwid << 20);	/* DMA */
        bridge->b_int_enable = 0;

        bridge->b_wid_tflush;     /* wait until Bridge PIO complete */
    }
}
Example #11
0
int module_probe_snum(module_t *m, nasid_t nasid)
{
    lboard_t	       *board;
    klmod_serial_num_t *comp;
    char * bcopy(const char * src, char * dest, int count);
    char serial_number[16];

    /*
     * record brick serial number
     */
    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);

    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
    {
#if	LDEBUG
	printf ("module_probe_snum: no IP35 board found!\n");
#endif
	return 0;
    }

    board_serial_number_get( board, serial_number );
    if( serial_number[0] != '\0' ) {
	encode_str_serial( serial_number, m->snum.snum_str );
	m->snum_valid = 1;
    }
#if	LDEBUG
    else {
	printf("module_probe_snum: brick serial number is null!\n");
    }
    printf("module_probe_snum: brick serial number == %s\n", serial_number);
#endif /* DEBUG */

    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
			KLTYPE_IOBRICK_XBOW);

    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
	return 0;

    comp = GET_SNUM_COMP(board);

    if (comp) {
#if LDEBUG
	    int i;

	    printf("********found module with id %x and string", m->id);

	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
		printf(" %x ", comp->snum.snum_str[i]);

	    printf("\n");	/* Fudged string is not ASCII */
#endif

	    if (comp->snum.snum_str[0] != '\0') {
		bcopy(comp->snum.snum_str,
		      m->sys_snum,
		      MAX_SERIAL_NUM_SIZE);
		m->sys_snum_valid = 1;
	    }
    }

    if (m->sys_snum_valid)
	return 1;
    else {
	DPRINTF("Invalid serial number for module %d, "
		"possible missing or invalid NIC.", m->id);
	return 0;
    }
}