/* ARGSUSED */
int
hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
{

	char *path;
	char *s1;
	char *index;
	int name_start;
	vertex_hdl_t handle = NULL;
	int rv;
	int i, count;

	path = kmalloc(1024, GFP_KERNEL);
	memset(path, 0x0, 1024);
	name_start = devfs_generate_path (from, path, 1024);
	s1 = &path[name_start];
	count = 0;
	while (1) {
		index = strstr (s1, "/");
		if (index) {
			count++;
			s1 = ++index;
		} else {
			count++;
			break;
		}
	}

	memset(path, 0x0, 1024);
	name_start = devfs_generate_path (to, path, 1024);

	for (i = 0; i < count; i++) {
		strcat(path,"../");
	}

	strcat(path, &path[name_start]);

	/*
	 * Otherwise, just create a symlink to the vertex.
	 * In this case the vertex was previous created with a REAL pathname.
	 */
	rv = devfs_mk_symlink (from, (const char *)name, 
			       DEVFS_FL_DEFAULT, path,
			       &handle, NULL);

	name_start = devfs_generate_path (handle, path, 1024);
	return(rv);

	
}
Beispiel #2
0
pciio_info_t
pciio_info_get(vertex_hdl_t pciio)
{
    pciio_info_t            pciio_info;

    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);

#ifdef DEBUG_PCIIO
    {
	int pos;
	char dname[256];
	pos = devfs_generate_path(pciio, dname, 256);
	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
    }
#endif /* DEBUG_PCIIO */

    if ((pciio_info != NULL) &&
        (pciio_info->c_fingerprint != pciio_info_fingerprint)
        && (pciio_info->c_fingerprint != NULL)) {

        return((pciio_info_t)-1); /* Should panic .. */
    }

    return pciio_info;
}
Beispiel #3
0
vertex_hdl_t
pciio_device_info_register(
		vertex_hdl_t connectpt,		/* vertex at center of bus */
		pciio_info_t pciio_info)	/* details about the connectpt */
{
    char		name[32];
    vertex_hdl_t	pconn;
    int device_master_set(vertex_hdl_t, vertex_hdl_t);

    pciio_slot_func_to_name(name,
			    pciio_info->c_slot,
			    pciio_info->c_func);

    if (GRAPH_SUCCESS !=
	hwgraph_path_add(connectpt, name, &pconn))
	return pconn;

    pciio_info->c_vertex = pconn;
    pciio_info_set(pconn, pciio_info);
#ifdef DEBUG_PCIIO
    {
	int pos;
	char dname[256];
	pos = devfs_generate_path(pconn, dname, 256);
	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
    }
#endif /* DEBUG_PCIIO */

    /*
     * create link to our pci provider
     */

    device_master_set(pconn, pciio_info->c_master);
    return pconn;
}
int
hwgraph_generate_path(
        vertex_hdl_t		de,
        char                    *path,
        int                     buflen)
{
	return (devfs_generate_path(de, path, buflen));
}
Beispiel #5
0
devfs_handle_t
pciio_device_info_register(
    devfs_handle_t connectpt,		/* vertex at center of bus */
    pciio_info_t pciio_info)	/* details about the connectpt */
{
    char		name[32];
    devfs_handle_t	pconn;

    pciio_slot_func_to_name(name,
                            pciio_info->c_slot,
                            pciio_info->c_func);

    if (GRAPH_SUCCESS !=
            hwgraph_path_add(connectpt, name, &pconn))
        return pconn;

    pciio_info->c_vertex = pconn;
    pciio_info_set(pconn, pciio_info);
#ifdef BRINGUP
    {
        int pos;
        char dname[256];
        pos = devfs_generate_path(pconn, dname, 256);
#ifdef DEBUG_PCIIO
        printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
#endif
    }
#endif /* BRINGUP */

    /*
     * create link to our pci provider
     */

    device_master_set(pconn, pciio_info->c_master);

#if USRPCI
    /*
     * Call into usrpci provider to let it initialize for
     * the given slot.
     */
    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
        usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
#endif

    return pconn;
}
static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
{
	void *handle;
	char path[64];
	int n;

	sys_unlink(name);
	if (!do_devfs)
		return sys_mknod(name, S_IFBLK|0600, kdev_t_to_nr(dev));

	handle = devfs_find_handle(NULL, dev ? NULL : devfs_name,
				MAJOR(dev), MINOR(dev), DEVFS_SPECIAL_BLK, 1);
	if (!handle)
		return -1;
	n = devfs_generate_path(handle, path + 5, sizeof (path) - 5);
	if (n < 0)
		return -1;
	return sys_symlink(path + n + 5, name);
}
Beispiel #7
0
pciio_info_t
pciio_info_get(devfs_handle_t pciio)
{
    pciio_info_t            pciio_info;

    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);

#ifdef DEBUG_PCIIO
    {
        int pos;
        char dname[256];
        pos = devfs_generate_path(pciio, dname, 256);
        printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
    }
#endif /* DEBUG_PCIIO */

#ifdef BRINGUP
    if ((pciio_info != NULL) &&
            (pciio_info->c_fingerprint != pciio_info_fingerprint)
            && (pciio_info->c_fingerprint != NULL)) {
#else
    if ((pciio_info != NULL) &&
            (pciio_info->c_fingerprint != pciio_info_fingerprint)) {
#endif /* BRINGUP */

        return((pciio_info_t)-1); /* Should panic .. */
    }


    return pciio_info;
}

void
pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
{
    if (pciio_info != NULL)
        pciio_info->c_fingerprint = pciio_info_fingerprint;
    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);

    /* Also, mark this vertex as a PCI slot
     * and use the pciio_info, so pciio_info_chk
     * can work (and be fairly efficient).
     */
    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
                         (arbitrary_info_t) pciio_info);
}

devfs_handle_t
pciio_info_dev_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_vertex);
}

/*ARGSUSED*/
pciio_bus_t
pciio_info_bus_get(pciio_info_t pciio_info)
{
    /* XXX for now O2 always gets back bus 0 */
    return (pciio_bus_t)0;
}

pciio_slot_t
pciio_info_slot_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_slot);
}

pciio_function_t
pciio_info_function_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_func);
}

pciio_vendor_id_t
pciio_info_vendor_id_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_vendor);
}

pciio_device_id_t
pciio_info_device_id_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_device);
}

devfs_handle_t
pciio_info_master_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_master);
}

arbitrary_info_t
pciio_info_mfast_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_mfast);
}

pciio_provider_t       *
pciio_info_pops_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_pops);
}

error_handler_f	       *
pciio_info_efunc_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_efunc);
}

error_handler_arg_t    *
pciio_info_einfo_get(pciio_info_t pciio_info)
{
    return (pciio_info->c_einfo);
}

pciio_space_t
pciio_info_bar_space_get(pciio_info_t info, int win)
{
    return info->c_window[win].w_space;
}

iopaddr_t
pciio_info_bar_base_get(pciio_info_t info, int win)
{
    return info->c_window[win].w_base;
}

size_t
pciio_info_bar_size_get(pciio_info_t info, int win)
{
    return info->c_window[win].w_size;
}

iopaddr_t
pciio_info_rom_base_get(pciio_info_t info)
{
    return info->c_rbase;
}

size_t
pciio_info_rom_size_get(pciio_info_t info)
{
    return info->c_rsize;
}


/* =====================================================================
 *          GENERIC PCI INITIALIZATION FUNCTIONS
 */

/*
 *    pciioinit: called once during device driver
 *      initializtion if this driver is configured into
 *      the system.
 */
void
pciio_init(void)
{
    cdl_p                   cp;

#if DEBUG && ATTACH_DEBUG
    printf("pciio_init\n");
#endif
    /* Allocate the registry.
     * We might already have one.
     * If we don't, go get one.
     * MPness: someone might have
     * set one up for us while we
     * were not looking; use an atomic
     * compare-and-swap to commit to
     * using the new registry if and
     * only if nobody else did first.
     * If someone did get there first,
     * toss the one we allocated back
     * into the pool.
     */
    if (pciio_registry == NULL) {
        cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
        if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
            cdl_del(cp);
        }
    }
    ASSERT(pciio_registry != NULL);
}
Beispiel #8
0
char *disk_name (struct gendisk *hd, int minor, char *buf)
{
	const char *maj = hd->major_name;
	unsigned int unit = minor >> hd->minor_shift;
	unsigned int part = minor & (( 1 << hd->minor_shift) - 1);
	char *p;

	if (unit < hd->nr_real && hd->part[minor].de) {
		int pos;

		pos = devfs_generate_path (hd->part[minor].de, buf, 64);
		if (pos >= 0)
			return buf + pos;
	}

#ifdef CONFIG_ARCH_S390
	if (genhd_dasd_name
	    && genhd_dasd_name (buf, unit, part, hd) == 0)
		return buf;
#endif
	/*
	 * IDE devices use multiple major numbers, but the drives
	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
	 * This requires special handling here.
	 */
	switch (hd->major) {
		case IDE9_MAJOR:
			unit += 2;
		case IDE8_MAJOR:
			unit += 2;
		case IDE7_MAJOR:
			unit += 2;
		case IDE6_MAJOR:
			unit += 2;
		case IDE5_MAJOR:
			unit += 2;
		case IDE4_MAJOR:
			unit += 2;
		case IDE3_MAJOR:
			unit += 2;
		case IDE2_MAJOR:
			unit += 2;
		case IDE1_MAJOR:
			unit += 2;
		case IDE0_MAJOR:
			maj = "hd";
			break;
		case MD_MAJOR:
			sprintf(buf, "%s%d", maj, unit);
			return buf;
	}
	if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
		unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
	}
	if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) {
		return raid_name(hd, unit, part, COMPAQ_SMART2_MAJOR, buf);
	}
	if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
		return raid_name(hd, unit, part, COMPAQ_CISS_MAJOR, buf);
	}
	if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
		return raid_name(hd, unit, part, DAC960_MAJOR, buf);
	}
	if (hd->major == ATARAID_MAJOR) {
 		int disk = minor >> hd->minor_shift;
 		int part = minor & (( 1 << hd->minor_shift) - 1);
 		if (part == 0)
 			sprintf(buf, "%s/d%d", maj, disk);
 		else
 			sprintf(buf, "%s/d%dp%d", maj, disk, part);
 		return buf;
 	}
Beispiel #9
0
/*
 * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
 *
 *	Linux PCI Bus numbers are assigned from lowest module_id numbers
 *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
 *	HUB_WIDGET_ID_MIN:
 *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
 *
 *	Given 2 modules 001c01 and 001c02 we get the following mappings:
 *		001c01, widgetnum 15 = Bus number 0
 *		001c01, widgetnum 14 = Bus number 1
 *		001c02, widgetnum 15 = Bus number 3
 *		001c02, widgetnum 14 = Bus number 4
 *		etc.
 *
 * The rational for starting Bus Number 0 with Widget number 15 is because 
 * the system boot disks are always connected via Widget 15 Slot 0 of the 
 * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
 * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
 * module id(Master Cnode) of the system.
 *	
 */
static int 
pci_bus_map_create(devfs_handle_t xtalk)
{

	devfs_handle_t master_node_vertex = NULL;
	devfs_handle_t xwidget = NULL;
	devfs_handle_t pci_bus = NULL;
	hubinfo_t hubinfo = NULL;
	xwidgetnum_t widgetnum;
	char pathname[128];
	graph_error_t rv;

	/*
	 * Loop throught this vertex and get the Xwidgets ..
	 */
	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
#if 0
        {
                int pos;
                char dname[256];
                pos = devfs_generate_path(xtalk, dname, 256);
                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
        }
#endif

		sprintf(pathname, "%d", widgetnum);
		xwidget = NULL;
		
		/*
		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
		 */
		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
		if ( (rv != GRAPH_SUCCESS) ) {
			if (!xwidget)
				continue;
		}

		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
		pci_bus = NULL;
		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
			if (!pci_bus)
				continue;

		/*
		 * Assign the correct bus number and also the nasid of this 
		 * pci Xwidget.
		 * 
		 * Should not be any race here ...
		 */
		num_bridges++;
		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;

		/*
		 * Get the master node and from there get the NASID.
		 */
		master_node_vertex = device_master_get(xwidget);
		if (!master_node_vertex) {
			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
		}
	
		hubinfo_get(master_node_vertex, &hubinfo);
		if (!hubinfo) {
			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
			return(1);
		} else {
			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
		}

		/*
		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
		 */
		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
		if (!busnum_to_atedmamaps[num_bridges - 1])
			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);

		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);

	}

        return(0);
}