Esempio n. 1
0
/*
 * add_node
 *
 * This function adds a board node to the board structure where that
 * that node's physical component lives.
 */
void
add_node(Sys_tree *root, Prom_node *pnode)
{
	int	board	= -1;
	int	portid	= -1;

	void		*value	= NULL;
	Board_node	*bnode	= NULL;
	Prom_node	*p	= NULL;

	/* Get the board number of this board from the portid prop */
	value = get_prop_val(find_prop(pnode, "portid"));
	if (value != NULL) {
		portid = *(int *)value;
	}

	board	= LNECK_PORTID_TO_BOARD_NUM(portid);

	/* find the board node with the same board number */
	if ((bnode = littleneck_find_board(root, board)) == NULL) {
		bnode = littleneck_insert_board(root, board);
	}

	/* now attach this prom node to the board list */
	/* Insert this node at the end of the list */
	pnode->sibling = NULL;
	if (bnode->nodes == NULL)
		bnode->nodes = pnode;
	else {
		p = bnode->nodes;
		while (p->sibling != NULL)
			p = p->sibling;
		p->sibling = pnode;
	}
}
Esempio n. 2
0
/*
 * inParams - CCIMPropertyList pointer that dereferences to a list of not less
 * than 4 or more than 16 CCIMProperty values.  Number of CCIMProperty values
 * must be a multiple of 4.
 *
 * The fdisk file will contain at least one line and not more than four lines
 * in the following format:
 *	id:act:0:0:0:0:0:0:rsect:numsect.
 * Values for id, act, rsect and numsect are taken from inParams.
 */
static CIMBool
build_fdisk_file(char *fdisk_file, CCIMPropertyList *params)
{
	FILE	*fp;
	int	i;
	int	error;
	ulong_t	*vals;
	int	cnt = 0;

	if (params == NULL) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (cim_false);
	}

	vals = cim_decodeUint32Array(get_prop_val(params->mDataObject), &cnt);

	if (cnt == 0 || cnt > 16 || (cnt % 4) != 0) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (cim_false);
	}

	(void) tmpnam(fdisk_file);

	/* Open the temporary file for writing */
	if ((fp = util_openFile(fdisk_file, "w")) == NULL) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_FAILED, NULL,
		NULL, &error);
	    return (cim_false);
	}

	/*
	 * Build a fdisk_file using 4 input parameters at a time.
	 * Check for all possible NULL parameters, parameter lists
	 * greater than 16 or not a multiple of 4.
	 */
	for (i = 0; i < cnt; i += 4) {
	    char	line_buf[DATALEN];

	    (void) snprintf(line_buf, sizeof (line_buf),
		"%lu:%lu:0:0:0:0:0:0:%lu:%lu\n",
		vals[i], vals[i + 1], vals[i + 2], vals[i + 3]);

	    /* Write the line of parameters to the fdisk_file */
	    if ((fputs(line_buf, fp)) == EOF) {
		util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		    NULL, NULL, &error);
		(void) util_closeFile(fp, fdisk_file);
		return (cim_false);
	    }
	}

	if ((util_closeFile(fp, fdisk_file)) == 0) {
	    return (cim_false);
	}

	/* Caller must delete the temporary file */
	return (cim_true);
}
Esempio n. 3
0
static void
display_hw_revisions(Prom_node *root, Board_node *bdlist)
{
	Prom_node	*pnode;
	char		*value;

	log_printf(dgettext(TEXT_DOMAIN, "\n"
	    "========================= HW Revisions "
	    "=======================================\n\n"));

	log_printf(dgettext(TEXT_DOMAIN,
	    "System PROM revisions:\n"
	    "----------------------\n"));

	pnode = dev_find_node(root, "openprom");
	if (pnode != NULL) {
		value = (char *)get_prop_val(find_prop(pnode, "version"));
		log_printf(value);
	}

	log_printf(dgettext(TEXT_DOMAIN, "\n\n"
	    "IO ASIC revisions:\n"
	    "------------------\n"
	    "         Port\n"
	    "Model     ID  Status Version\n"
	    "-------- ---- ------ -------\n"));

	display_schizo_revisions(bdlist);
}
Esempio n. 4
0
/*
 * returns the size of the given processors external cache in
 * bytes. If the properties required to determine this are not
 * present, then the function returns 0.
 */
int
get_ecache_size(Prom_node *node)
{
	int *cache_size_p;	/* pointer to number of cache lines */

	/* find the properties */
	if (cache_size_p = (int *)get_prop_val(find_prop(node,
		"ecache-size"))) {
		return (*cache_size_p);
	}
	if (cache_size_p = (int *)get_prop_val(find_prop(node,
		"l3-cache-size"))) {
		return (*cache_size_p);
	}
	if (cache_size_p = (int *)get_prop_val(find_prop(node,
		"l2-cache-size"))) {
		return (*cache_size_p);
	}

	return (0);
}
Esempio n. 5
0
/*
 * Function:	writeVolumeName
 *
 * Parameters:	params - CCIMPropertyList pointer.  Property list
 *		containing the new disk label name.
 *		op - CCIMObjectPath pointer.  Object path containing
 *		the deviceId of the disk to label.
 *
 * Returns:	Returns a CCIMProperty pointer.  The CCIMProperty referenced
 *		by the pointer will contain an mValue of cim_true for
 *		success or cim_false on failure.
 *
 * Description:	Executes the fmthard -n volume_name command on the device
 *		pointed to by 'op'.
 */
CCIMProperty *
label_disk(CCIMPropertyList *params, CCIMObjectPath *op)
{
	char		devpath[MAXPATHLEN];
	char		command_line[CMDLEN];
	int		len;
	cimchar		*label;
	int		error;

	if (!check_rights("Solaris_Disk") ||
	    op == NULL || params == NULL) {
	    return (create_result(PROPFALSE));
	}

	if (get_devpath(op, devpath, sizeof (devpath)) == cim_false) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (create_result(PROPFALSE));
	}

	/* Extract the label from the input parameters */
	if ((label = get_prop_val(params->mDataObject)) == NULL) {
	    return (create_result(PROPFALSE));
	}
	if (strlen(label) > 8) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (create_result(PROPFALSE));
	}

	/* Build the command line to execute */

	len = snprintf(command_line, sizeof (command_line),
	    "/usr/sbin/fmthard -n '%s' %s 2> /dev/null", label, devpath);

	if (len < 0 || (len + 1) > sizeof (command_line)) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (create_result(PROPFALSE));
	}

	/* Execute the command. */
	if (!execute_cmd(command_line, "/dev/null")) {
	    return (create_result(PROPFALSE));
	}
	return (create_result(PROPTRUE));
}
Esempio n. 6
0
/*
 * Return the operating frequency of a processor in Hertz. This function
 * requires as input a legal prom node pointer. If a NULL
 * is passed in or the clock-frequency property does not exist, the
 * function returns 0.
 */
uint_t
get_cpu_freq(Prom_node *pnode)
{
	Prop *prop;
	uint_t *value;

	/* find the property */
	if ((prop = find_prop(pnode, "clock-frequency")) == NULL) {
		return (0);
	}

	if ((value = (uint_t *)get_prop_val(prop)) == NULL) {
		return (0);
	}

	return (*value);
}
Esempio n. 7
0
/*ARGSUSED*/
static void
sun4v_display_hw_revisions(Prom_node *root, picl_nodehdl_t plafh)
{
    Prom_node	*pnode;
    char		*value;
    char 		platbuf[MAXSTRLEN];
    char	*fmt = "%-20s %-40s %-30s %-9s";

    log_printf(dgettext(TEXT_DOMAIN, "\n"
                        "========================= HW Revisions "
                        "=======================================\n\n"));

    log_printf(dgettext(TEXT_DOMAIN,
                        "System PROM revisions:\n"
                        "----------------------\n"));

    pnode = dev_find_node(root, "openprom");
    if (pnode != NULL) {
        value = (char *)get_prop_val(find_prop(pnode, "version"));
        log_printf(value);
    }

    log_printf(dgettext(TEXT_DOMAIN, "\n\n"
                        "IO ASIC revisions:\n"
                        "------------------\n"));
    log_printf(fmt, "Location", "Path", "Device", "Revision\n", 0);
    log_printf(fmt, "--------------------",
               "----------------------------------------",
               "------------------------------",
               "---------\n", 0);

    /* Get platform name, if that fails, use montoya name by default */
    if (sysinfo(SI_PLATFORM, platbuf, sizeof (platbuf)) == -1) {
        (void) strcpy(platbuf, MONTOYA_PLATFORM);
    }

    (void) picl_walk_tree_by_class(plafh, PCIEX,
                                   PCIEX, montoya_hw_rev_callback);
    (void) picl_walk_tree_by_class(plafh, PCI,
                                   PCI, montoya_hw_rev_callback);
    (void) picl_walk_tree_by_class(plafh, NETWORK,
                                   NETWORK, montoya_hw_rev_callback);
    (void) picl_walk_tree_by_class(plafh, SCSI2, SCSI2,
                                   montoya_hw_rev_callback);
}
Esempio n. 8
0
/*
 * Do a depth-first walk of a device tree and
 * return the first node with the matching model.
 */
static Prom_node *
dev_find_node_by_compat(Prom_node *root, char *compat)
{
	Prom_node	*node;
	char		*compatible;
	char		*name;

	if (root == NULL)
		return (NULL);

	if (compat == NULL)
		return (NULL);

	name = get_node_name(root);
	if (name == NULL)
		name = "";

	compatible = (char *)get_prop_val(find_prop(root, "compatible"));

	if (compatible == NULL)
	    return (NULL);

	if ((strcmp(name, "pci") == 0) && (compatible != NULL) &&
	    (strcmp(compatible, compat) == 0)) {
		return (root); /* found a match */
	}

	/* look at your children first */
	if ((node = dev_find_node_by_compat(root->child, compat)) != NULL)
	    return (node);

	/* now look at your siblings */
	if ((node = dev_find_node_by_compat(root->sibling, compat)) != NULL)
	    return (node);

	return (NULL);  /* not found */
}
Esempio n. 9
0
/*
 * inParams - CCIMPropertyList pointer that dereferences to a list of not less
 * than 5 CCIMProperty values. The number of CCIMProperty values must be a
 * multiple of 5.
 *
 * The file will contain at least one line in the following format:
 *	part tag flag start_sect part_size
 * Values for partition, tag, flag, starting sector and partition size are
 * taken from inParams.
 */
static CIMBool
build_fmt_file(char *fmt_file, CCIMPropertyList *params)
{
	ulong_t	*vals;
	int	cnt = 0;
	FILE	*fp;
	int	error;
	int	i;

	if (params == NULL) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (cim_false);
	}

	vals = cim_decodeUint32Array(get_prop_val(params->mDataObject), &cnt);

	if (cnt == 0 || (cnt % 5) != 0) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		NULL, NULL, &error);
	    return (cim_false);
	}

	(void) tmpnam(fmt_file);

	/* Open the temporary file for writing */
	if ((fp = util_openFile(fmt_file, "w")) == NULL) {
	    util_handleError(INVOKE_METHOD, CIM_ERR_FAILED, NULL,
		NULL, &error);
	    return (cim_false);
	}

	/*
	 * Build a data file for the fmthard command.
	 * Each line of the file consists of:
	 *
	 * part_num tag flag start_sector partition_size
	 *
	 * The fmthard command requires the starting sector fall on
	 * a cylinder boundry.
	 */
	for (i = 0; i < cnt; i += 5) {
	    char	line_buf[DATALEN];
	    char	flag_buf[DATALEN];

	    convert_flag(vals[i + 2], flag_buf, sizeof (flag_buf));

	    (void) snprintf(line_buf, sizeof (line_buf),
		"%lu %lu %s %lu %lu\n",
		vals[i], vals[i + 1], flag_buf, vals[i + 3], vals[i + 4]);

	    /* Write the line of parameters to the fdisk_file */
	    if ((fputs(line_buf, fp)) == EOF) {
		util_handleError(INVOKE_METHOD, CIM_ERR_INVALID_PARAMETER,
		    NULL, NULL, &error);
		(void) util_closeFile(fp, fmt_file);
		return (cim_false);
	    }
	}

	if ((util_closeFile(fp, fmt_file)) == 0) {
	    return (cim_false);
	}

	/* Caller must delete the file */
	return (cim_true);
}
Esempio n. 10
0
/*
 * Display the CPUs present on this board.
 */
void
display_cpus(Board_node *board)
{
	Prom_node *cpu;

	/*
	 * display the CPUs' operating frequency, cache size, impl. field
	 * and mask revision.
	 */
	for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL;
	    cpu = dev_next_type(cpu, "cpu")) {
		int freq;	 /* CPU clock frequency */
		int ecache_size; /* External cache size */
		int *mid;
		int *impl;
		int *mask, decoded_mask;

		mid = (int *)get_prop_val(find_prop(cpu, "upa-portid"));
		if (mid == NULL) {
			mid = (int *)get_prop_val(find_prop(cpu, "portid"));
		}

		freq = (get_cpu_freq(cpu) + 500000) / 1000000;
		ecache_size = get_ecache_size(cpu);
		impl = (int *)get_prop_val(find_prop(cpu, "implementation#"));
		mask = (int *)get_prop_val(find_prop(cpu, "mask#"));

		/* Do not display a failed CPU node */
		if ((freq != 0) && (node_failed(cpu) == 0)) {
			/* Board number */
			display_boardnum(board->board_num);

			/* CPU MID */
			log_printf(" %2d  ", *mid, 0);

			/* Module number */
			display_mid(*mid);

			/* Running frequency */
			log_printf(" %3d   ", freq, 0);

			/* Ecache size */
			if (ecache_size == 0)
				log_printf(" %3s    ", "N/A", 0);
			else
				log_printf(" %4.1f   ",
					(float)ecache_size / (float)(1<<20),
					0);

			/* Implementation */
			if (impl == NULL) {
				log_printf("%6s  ", "N/A", 0);
			} else {
				switch (*impl) {
				case SPITFIRE_IMPL:
					log_printf("%-6s  ", "US-I", 0);
					break;
				case BLACKBIRD_IMPL:
					log_printf("%-6s  ", "US-II", 0);
					break;
				case CHEETAH_IMPL:
					log_printf("%-6s  ", "US-III", 0);
					break;
				case CHEETAH_PLUS_IMPL:
					log_printf("%-7s  ", "US-III+", 0);
					break;
				case JAGUAR_IMPL:
					log_printf("%-6s  ", "US-IV", 0);
					break;
				default:
					log_printf("%-6x  ", *impl, 0);
					break;
				}
			}

			/* CPU Mask */
			if (mask == NULL) {
				log_printf(" %3s", "N/A", 0);
			} else {
				if ((impl) && IS_CHEETAH(*impl))
					decoded_mask =
						REMAP_CHEETAH_MASK(*mask);
				else
					decoded_mask = *mask;

				log_printf(" %d.%d", (decoded_mask >> 4) & 0xf,
					decoded_mask & 0xf, 0);
			}

			log_printf("\n", 0);
		}
	}
Esempio n. 11
0
static void
display_schizo_revisions(Board_node *bdlist)
{
	Prom_node	*pnode;
	int		*int_val;
	int		portid;
	int		prev_portid = -1;
	char		*status_a = NULL;
	char		*status_b = NULL;
	int		revision;
#ifdef DEBUG
	uint32_t	a_notes, b_notes;
#endif
	int		pci_bus;
	Board_node	*bnode;
	bnode = bdlist;

	while (bnode != NULL) {
		/*
		 * search this board node for all Schizos
		 */

		for (pnode = dev_find_node_by_compat(bnode->nodes,
		    SCHIZO_COMPAT_PROP); pnode != NULL;
		    pnode = dev_next_node_by_compat(pnode,
		    SCHIZO_COMPAT_PROP)) {

			/*
			 * get the reg property to determine
			 * whether we are looking at side A or B
			 */

			int_val = (int *)get_prop_val
			    (find_prop(pnode, "reg"));
			if (int_val != NULL) {
				int_val ++; /* second integer in array */
				pci_bus = ((*int_val) & 0x7f0000);
			}

			/* get portid */
			int_val = (int *)get_prop_val
			    (find_prop(pnode, "portid"));
			if (int_val == NULL)
				continue;

			portid = *int_val;

			/*
			 * If this is a new portid and it is PCI bus B,
			 * we skip onto the PCI bus A.
			 */
			if ((portid != prev_portid) && (pci_bus == 0x700000)) {
				prev_portid = portid;
				/* status */
				status_b = (char *)get_prop_val
				    (find_prop(pnode, "status"));
#ifdef DEBUG
				b_notes = pci_bus;
#endif
				continue; /* skip to the next schizo */
			}

			/*
			 * This must be side A of the same Schizo.
			 * Gather all its props and display them.
			 */
#ifdef DEBUG
			a_notes = pci_bus;
#endif

			prev_portid = portid;

			int_val = (int *)get_prop_val
			    (find_prop(pnode, "version#"));
			if (int_val != NULL)
				revision = *int_val;
			else
				revision = -1;

			status_a = (char *)get_prop_val(find_prop
			    (pnode, "status"));

			log_printf(dgettext(TEXT_DOMAIN, "Schizo    "));

			log_printf(dgettext(TEXT_DOMAIN, "%-3d "), portid, 0);


			log_printf((status_a == NULL && status_b == NULL) ?
			    dgettext(TEXT_DOMAIN, "  ok  ") :
			    dgettext(TEXT_DOMAIN, " fail "));

			log_printf(dgettext(TEXT_DOMAIN, " %4d   "),
			    revision);
#ifdef DEBUG
			log_printf(" 0x%x 0x%x", a_notes, b_notes);
#endif
			log_printf("\n");
		}
		bnode = bnode->next;
	}
}
Esempio n. 12
0
/*
 * display_pci
 * Display all the PCI IO cards on this board.
 */
void
display_pci(Board_node *board)
{
	struct io_card	*card_list = NULL;
	struct io_card	card;
	void		*value;
	Prom_node	*pci;
	Prom_node	*card_node;
	static int	banner = FALSE;

	char		*slot_name_arr[NUM_PCI_SLOTS];
	int		i;

	if (board == NULL)
		return;

	(void) memset(&card, 0, sizeof (struct io_card));
	/* Initialize all the common information */
	card.display = TRUE;
	card.board = board->board_num;

	/*
	 * Search for each pci instance, then find/display all nodes under
	 * each instance node found.
	 */
	for (pci = dev_find_node_by_compat(board->nodes, SCHIZO_COMPAT_PROP);
	    pci != NULL;
	    pci = dev_next_node_by_compat(pci, SCHIZO_COMPAT_PROP)) {
		(void) snprintf(card.bus_type, MAXSTRLEN,
		    dgettext(TEXT_DOMAIN, "PCI"));
		/*
		 * Get slot-name properties from parent node and
		 * store them in an array.
		 */
		value = (char *)get_prop_val(
		    find_prop(pci, "slot-names"));

		if (value != NULL) {
			/* array starts after first int */
			slot_name_arr[0] = (char *)value + sizeof (int);
			for (i = 1; i < NUM_PCI_SLOTS; i++) {
				slot_name_arr[i] = (char *)slot_name_arr[i - 1]
				    + strlen(slot_name_arr[i - 1]) +1;
			}
		}
		/*
		 * Search for Children of this node ie. Cards.
		 * Note: any of these cards can be a pci-bridge
		 *	that itself has children. If we find a
		 *	pci-bridge we need to handle it specially.
		 */
		card_node = pci->child;
		/* Generate the list of pci cards on pci instance: pci */
		fill_pci_card_list(pci, card_node, &card, &card_list,
		    slot_name_arr);
	} /* end-for */

	if (!banner && card_list != NULL) {
		log_printf(dgettext(TEXT_DOMAIN,
		    "                    Bus  Max\n"
		    " IO  Port Bus       Freq Bus  Dev,\n"
		    "Type  ID  Side Slot MHz  Freq Func State "
		    "Name                              Model"
#ifdef DEBUG
		    "                   Notes"
#endif
		    "\n"
		    "---- ---- ---- ---- ---- ---- ---- ----- "
		    "--------------------------------  "
#ifdef DEBUG
		    "----------------------  "
#endif
		    "----------------------\n"));
		banner = TRUE;
	}

	display_io_cards(card_list);
	free_io_cards(card_list);
}
Esempio n. 13
0
void
display_cpus(Board_node *board)
{
	Prom_node 	*cpu;
	uint_t freq;
	int ecache_size;
	int *l3_shares;
	int *mid;
	int *impl;
	int *mask;
	int *coreid;
	char fru_prev = 'X'; /* Valid frus are 'A','B' */
	int mid_prev;
	int ecache_size_prev = 0;
	char fru_name;

	/*
	 * display the CPUs' operating frequency, cache size, impl. field
	 * and mask revision.
	 */

	for (cpu = dev_find_type(board->nodes, "cpu"); cpu != NULL;
	    cpu = dev_next_type(cpu, "cpu")) {

		mid = (int *)get_prop_val(find_prop(cpu, "portid"));
		if (mid == NULL)
			mid = (int *)get_prop_val(find_prop(cpu, "cpuid"));
		freq = HZ_TO_MHZ(get_cpu_freq(cpu));
		ecache_size = get_ecache_size(cpu);
		impl = (int *)get_prop_val(find_prop(cpu, "implementation#"));
		mask = (int *)get_prop_val(find_prop(cpu, "mask#"));
		l3_shares =
		    (int *)get_prop_val(find_prop(cpu, "l3-cache-sharing"));

		/* Do not display a failed CPU node */
		if ((impl == NULL) || (freq == 0) || (node_failed(cpu)))
			continue;

		fru_name = CHERRYSTONE_GETSLOT_LABEL(*mid);
		if (CPU_IMPL_IS_CMP(*impl)) {
			coreid = (int *)get_prop_val(find_prop(cpu, "reg"));
			if (coreid == NULL) {
				continue;
			}
			if ((fru_prev == 'X') ||
			    ((fru_prev != 'X') &&
			    (fru_name != fru_prev))) {
				fru_prev = fru_name;
				mid_prev = *mid;
				ecache_size_prev = ecache_size;
				continue;
			} else {
				/*
				 * Some CMP chips have a split E$,
				 * so the size for both cores is added
				 * together to get the total size for
				 * the chip.
				 *
				 * Still, other CMP chips have E$ (L3)
				 * which is logically shared, so the
				 * total size is equal to the core size.
				 */
				if ((l3_shares == NULL) ||
				    ((l3_shares != NULL) &&
				    MULTIPLE_BITS_SET(*l3_shares))) {
					ecache_size += ecache_size_prev;
				}
				ecache_size_prev = 0;
				fru_prev = 'X';
			}
		}

		log_printf(" %c", fru_name);

		/* CPU Module ID */
		if (CPU_IMPL_IS_CMP(*impl)) {
			log_printf("%3d,%3d ", mid_prev, *mid, 0);
		} else
			log_printf("   %2d   ", *mid);

		/* Running frequency */
		log_printf("%4u", freq);

		if (ecache_size == 0)
			log_printf(" N/A  ");
		else
			log_printf(" %4.1f ",
			    (float)ecache_size / (float)(1<<20));
			/* Implementation */
		if (impl == NULL) {
			log_printf(dgettext(TEXT_DOMAIN, "  N/A   "));
		} else {
			if (IS_CHEETAH(*impl))
				log_printf(dgettext(TEXT_DOMAIN,
				    "US-III  "));
			else if (IS_CHEETAH_PLUS(*impl))
				log_printf(dgettext(TEXT_DOMAIN,
				    "US-III+ "));
			else if (IS_JAGUAR(*impl))
				log_printf(dgettext(TEXT_DOMAIN,
				    "US-IV   "));
			else if (IS_PANTHER(*impl))
				log_printf(dgettext(TEXT_DOMAIN,
				    "US-IV+  "));
			else
				log_printf("%-6x  ", *impl);
		}

		/* CPU Mask */
		if (mask == NULL) {
			log_printf(dgettext(TEXT_DOMAIN, " N/A\n"));
		} else {
			log_printf(dgettext(TEXT_DOMAIN, " %d.%d\n"),
			    (*mask >> 4) & 0xf, *mask & 0xf);
		}
	}
}
Esempio n. 14
0
/*
 * display_pci
 * Display all the PCI IO cards on this board.
 */
void
display_pci(Board_node *board)
{
	struct io_card *card_list = NULL;
	struct io_card card;
	void *value;
	Prom_node *pci;
	Prom_node *card_node;
	Prom_node *pci_bridge_node = NULL;
	char	*slot_name_arr[MAX_SLOTS_PER_IO_BD] = {NULL};
	char	*slot_name = NULL;
	int	slot_name_bits;
	int	slot_name_offset = 0;
	char	*child_name;
	char	*name, *type;
	char	buf[MAXSTRLEN];
	int	*int_val;
	int	pci_bus;
	int	pci_bridge = 0;
	int	pci_bridge_dev_no;
	int	child_dev_no;
	int	i;
	int	portid;
	int	version, *pversion;

	if (board == NULL)
		return;

	/* Initialize all the common information */
	card.display = TRUE;
	card.board = board->board_num;
	card.node_id = board->node_id;

	/*
	 * Search for each schizo, then find/display all nodes under
	 * each schizo node found.  Since the model property "SUNW,schizo"
	 * is not supported on Starcat, we must match on the compatible
	 * property "pci108e,8001".
	 */
	for (pci = dev_find_node_by_compatible(board->nodes, SCHIZO_COMPATIBLE);
	    pci != NULL;
	    pci = dev_next_node_by_compatible(pci, SCHIZO_COMPATIBLE)) {

		/* set max freq for this board */
		board_bus_max_freq = DEFAULT_MAX_FREQ;
		/*
		 * Find out if this is a PCI or cPCI IO Board.
		 * If "enum-impl" property exists in pci node => cPCI.
		 */
		value = get_prop_val(find_prop(pci, "enum-impl"));
		if (value == NULL) {
			(void) sprintf(card.bus_type, "PCI");
		} else {
			(void) sprintf(card.bus_type, "cPCI");
		}

		if (strstr((char *)get_prop_val(
		    find_prop(pci, "compatible")), XMITS_COMPATIBLE)) {
			sprintf(card.notes, "%s", XMITS_COMPATIBLE);
			/*
			 * With XMITS 3.X and PCI-X mode, the bus speed
			 * can be higher than 66MHZ.
			 */
			value = (int *)get_prop_val
			    (find_prop(pci, "module-revision#"));
			if (value) {
				pversion = (int *)value;
				version = *pversion;
				if (version >= 4)
					board_bus_max_freq = PCIX_MAX_FREQ;
			}
		} else if (strstr((char *)get_prop_val(
		    find_prop(pci, "compatible")), SCHIZO_COMPATIBLE))
			sprintf(card.notes, "%s", SCHIZO_COMPATIBLE);
		else
			sprintf(card.notes, " ");

		/*
		 * Get slot-names property from parent node and
		 * store the individual slot names in an array.
		 * This is more general than Starcat requires, but
		 * it is correct, according to the slot-names property.
		 */
		value = (char *)get_prop_val(find_prop(pci, "slot-names"));
		if (value == NULL) {
			/*
			 * No slot_names property.  This could be an Xmits
			 * card, so check the child node for slot-names property
			 */
			value = (char *)get_prop_val(
			    find_prop(pci->child, "slot-names"));
		}

		if (value != NULL) {
			/* Get the 4 byte bitmask and pointer to first name */
			slot_name_bits = *(int *)value;
			if (slot_name_bits > 0)
				slot_name_offset = slot_name_bits - 1;
			slot_name = (char *)value + sizeof (int);

			for (i = 0; i < MAX_SLOTS_PER_IO_BD; i++) {
				if (! (slot_name_bits & (1 << i))) {
					slot_name_arr[i] = (char *)NULL;
					continue;
				}

				/*
				 * Save the name pointer into the array
				 * and advance it past the end of this
				 * slot name
				 */
				slot_name_arr[i] = slot_name;
				slot_name += strlen(slot_name) + 1;
			}
			slot_name = (char *)NULL;
		}

		/*
		 * Search for Children of this node ie. Cards.
		 * Note: any of these cards can be a pci-bridge
		 *	that itself has children. If we find a
		 *	pci-bridge we need to handle it specially.
		 */
		card_node = pci->child;
		while (card_node != NULL) {
			pci_bridge = 0;

			/* If it doesn't have a name, skip it */
			name = (char *)get_prop_val(
			    find_prop(card_node, "name"));
			if (name == NULL) {
				card_node = card_node->sibling;
				continue;
			}

			/*
			 * get dev# and func# for this card from the
			 * 'reg' property.
			 */
			int_val = (int *)get_prop_val(
			    find_prop(card_node, "reg"));
			if (int_val != NULL) {
				card.dev_no = (((*int_val) & 0xF800) >> 11);
				card.func_no = (((*int_val) & 0x700) >> 8);
			} else {
				card.dev_no = -1;
				card.func_no = -1;
			}

			/*
			 * If this is a pci-bridge, then store it's dev#
			 * as its children nodes need this to get their slot#.
			 * We set the pci_bridge flag so that we know we are
			 * looking at a pci-bridge node. This flag gets reset
			 * every time we enter this while loop.
			 */

			/*
			 * Check for a PCI-PCI Bridge for PCI and cPCI
			 * IO Boards using the name and type properties.
			 */
			type = (char *)get_prop_val(
			    find_prop(card_node, "device_type"));
			if ((type != NULL) &&
			    (strncmp(name, "pci", 3) == 0) &&
			    (strcmp(type, "pci") == 0)) {
				pci_bridge_dev_no = card.dev_no;
				pci_bridge_node = card_node;
				pci_bridge = TRUE;
			}

			/*
			 * Get slot-names property from slot_names_arr.
			 * If we are the child of a pci_bridge we use the
			 * dev# of the pci_bridge as an index to get
			 * the slot number. We know that we are a child of
			 * a pci-bridge if our parent is the same as the last
			 * pci_bridge node found above.
			 */
			if (card.dev_no != -1) {
				/*
				 * We compare this card's parent node with the
				 * pci_bridge_node to see if it's a child.
				 */
				if (card_node->parent == pci_bridge_node) {
					/* use dev_no of pci_bridge */
					child_dev_no = pci_bridge_dev_no - 1;
				} else {
					/* use card's own dev_no */
					child_dev_no = card.dev_no - 1;
				}

				if (child_dev_no < MAX_SLOTS_PER_IO_BD &&
				    child_dev_no >= 0 &&
				    slot_name_arr
				    [child_dev_no + slot_name_offset] != NULL) {

					slot_name = slot_name_arr[
					    child_dev_no + slot_name_offset];
				} else
					slot_name = (char *)NULL;

				if (slot_name != NULL && slot_name[0] != '\0') {
					(void) sprintf(card.slot_str, "%s",
					    slot_name);
				} else {
					(void) sprintf(card.slot_str, "-");
				}
			} else {
				(void) sprintf(card.slot_str, "%c", '-');
			}

			/*
			 * Get the portid of the schizo that this card
			 * lives under.
			 */
			portid = -1;
			value = get_prop_val(find_prop(pci, "portid"));
			if (value != NULL) {
				portid = *(int *)value;
			}
			card.schizo_portid = portid;

#ifdef	DEBUG
			(void) sprintf(card.notes, "%s portid [%d]"
			    " dev_no [%d] slot_name[%s] name_bits[%#x]",
			    card.notes, portid, card.dev_no,
			    ((slot_name != NULL) ? slot_name : "NULL"),
			    slot_name_bits);
#endif	/* DEBUG */

			/*
			 * Find out whether this is PCI bus A or B
			 * using the 'reg' property.
			 */
			int_val = (int *)get_prop_val
			    (find_prop(pci, "reg"));

			if (int_val != NULL) {
				int_val ++; /* skip over first integer */
				pci_bus = ((*int_val) & 0x7f0000);
				if (pci_bus == 0x600000)
					card.pci_bus = 'A';
				else if (pci_bus == 0x700000)
					card.pci_bus = 'B';
				else
					card.pci_bus = '-';
			} else {
				card.pci_bus = '-';
			}


			/*
			 * Check for failed status.
			 */
			if (node_failed(card_node))
				strcpy(card.status, "fail");
			else
				strcpy(card.status, "ok");

			/* Get the model of this card */
			value = get_prop_val(find_prop(card_node, "model"));
			if (value == NULL)
				card.model[0] = '\0';
			else {
				(void) sprintf(card.model, "%s", (char *)value);
				/*
				 * If we wish to exclude onboard devices
				 * (such as SBBC) then this is the place
				 * and here is how to do it:
				 *
				 * if (strcmp(card.model, "SUNW,sbbc") == 0) {
				 *	card_node = card_node->sibling;
				 *	continue;
				 * }
				 */
			}

			/*
			 * The card may have a "clock-frequency" but we
			 * are not interested in that. Instead we get the
			 * "clock-frequency" of the PCI Bus that the card
			 * resides on. PCI-A can operate at 33Mhz or 66Mhz
			 * depending on what card is plugged into the Bus.
			 * PCI-B always operates at 33Mhz.
			 *
			 */
			int_val = get_prop_val(find_prop(pci,
			    "clock-frequency"));
			if (int_val != NULL) {
				card.freq = HZ_TO_MHZ(*int_val);
			} else {
				card.freq = -1;
			}

			/*
			 * Figure out how we want to display the name
			 */
			value = get_prop_val(find_prop(card_node,
			    "compatible"));
			if (value != NULL) {
				/* use 'name'-'compatible' */
				(void) sprintf(buf, "%s-%s", name,
				    (char *)value);
			} else {
				/* just use 'name' */
				(void) sprintf(buf, "%s", name);
			}
			name = buf;

			/*
			 * If this node has children, add the device_type
			 * of the child to the name value of this card.
			 */
			child_name = (char *)get_node_name(card_node->child);
			if ((card_node->child != NULL) &&
			    (child_name != NULL)) {
				value = get_prop_val(find_prop(card_node->child,
				    "device_type"));
				if (value != NULL) {
					/* add device_type of child to name */
					(void) sprintf(card.name, "%s/%s (%s)",
					    name, child_name,
					    (char *)value);
				} else {
					/* just add child's name */
					(void) sprintf(card.name, "%s/%s",
					    name, child_name);
				}
			} else {
				/* childless, just the card's name */
				(void) sprintf(card.name, "%s", (char *)name);
			}

			/*
			 * If this is a pci-bridge, then add the word
			 * 'pci-bridge' to its model.
			 */
			if (pci_bridge) {
				if (card.model[0] == '\0')
					(void) sprintf(card.model,
					    "%s", "pci-bridge");
				else
					(void) strcat(card.model,
					    "/pci-bridge");
			}

			/* insert this card in the list to be displayed later */
			card_list = insert_io_card(card_list, &card);

			/*
			 * If we are dealing with a pci-bridge, we need to move
			 * down to the children of this bridge, if there are
			 * any, otherwise its siblings.
			 *
			 * If not a bridge, we are either dealing with a regular
			 * card (in which case we move onto the sibling of this
			 * card) or we are dealing with a child of a pci-bridge
			 * (in which case we move onto the child's siblings or
			 * if there are no more siblings for this child, we
			 * move onto the parent's siblings).  I hope you're
			 * getting all this, there will be an exam later.
			 */
			if (pci_bridge) {
				if (card_node->child != NULL)
					card_node = card_node->child;
				else
					card_node = card_node->sibling;
			} else {
				/*
				 * If our parent is a pci-bridge but there
				 * are no more of its children to process we
				 * move back up to our parent's sibling,
				 * otherwise we move onto our own sibling.
				 */
				if ((card_node->parent == pci_bridge_node) &&
				    (card_node->sibling == NULL))
					card_node =
					    pci_bridge_node->sibling;
				else
					card_node = card_node->sibling;
			}

		} /* end while (card_node ...) loop */
Esempio n. 15
0
/*
 * Fills in the i/o card list to be displayed later in display_pci();
 */
void
fill_pci_card_list(Prom_node * pci_instance, Prom_node * pci_card_node,
			struct io_card *pci_card,
			struct io_card **pci_card_list, char **slot_name_arr)
{
	Prom_node	*pci_bridge_node;
	Prom_node	*pci_parent_bridge;
	int		*int_val;
	int		pci_bridge = FALSE;
	int		pci_bridge_dev_no = -1;
	int		portid;
	int		pci_bus;
	char		buf[MAXSTRLEN];
	char		*slot_name = NULL;	/* info in "slot-names" prop */
	char		*child_name;
	char		*name;
	char		*type;
	void		*value;

	while (pci_card_node != NULL) {
		int is_pci = FALSE;
		type = NULL;
		name = NULL;
		/* If it doesn't have a name, skip it */
		name = (char *)get_prop_val(
				find_prop(pci_card_node, "name"));
		if (name == NULL) {
			pci_card_node = pci_card_node->sibling;
			continue;
		}
		/*
		 * Get the portid of the schizo that this card
		 * lives under.
		 */
		portid = -1;
		value = get_prop_val(find_prop(pci_instance, "portid"));
		if (value != NULL) {
			portid = *(int *)value;
		}
		pci_card->schizo_portid = portid;
		/*
		 * Find out whether this is PCI bus A or B
		 * using the 'reg' property.
		 */
		int_val = (int *)get_prop_val(find_prop(pci_instance, "reg"));

		if (int_val != NULL) {
			int_val++; /* skip over first integer */
			pci_bus = ((*int_val) & 0x7f0000);
			if (pci_bus == 0x600000)
				pci_card->pci_bus = 'A';
			else if (pci_bus == 0x700000)
				pci_card->pci_bus = 'B';
			else
				pci_card->pci_bus = '-';
		} else {
			pci_card->pci_bus = '-';
		}
		/*
		 * get dev# and func# for this card from the
		 * 'reg' property.
		 */
		int_val = (int *)get_prop_val(
			find_prop(pci_card_node, "reg"));
		if (int_val != NULL) {
			pci_card->dev_no = (((*int_val) & 0xF800) >> 11);
			pci_card->func_no = (((*int_val) & 0x700) >> 8);
		} else {