⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciba.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname0)))			printk("unable to create %v/%s (ret=%d)\n", conn, uname0, vhdl, ret);		    else				SHOWREF(vhdl, hwgraph_edge_add);		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))			printk("unable to unref %v\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_unref);		}		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))		    printk("unable to unref %v\n", conn);		else					SHOWREF(conn, hwgraph_vertex_unref);	    } 	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);	    else {					SHOWREF(conn, hwgraph_traverse);		if (GRAPH_SUCCESS != (ret = hwgraph_char_device_add(conn, dname, "pciba_", &vhdl)))		    printk("unable to create %v/%s (ret=%d)\n", conn, dname, ret);		else {					SHOWREF(vhdl, hwgraph_char_device_add);		    hwgraph_chmod(vhdl, 0666);		SHOWREF(vhdl, hwgraph_chmod);		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_add(conv, vhdl, uname1)))			printk("unable to create %v/%s (ret=%d)\n", conn, uname1, vhdl, ret);		    else				SHOWREF(vhdl, hwgraph_edge_add);		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))			printk("unable to unref %v\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_unref);		}		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))		    printk("unable to unref %v\n", conn);		else					SHOWREF(conn, hwgraph_vertex_unref);	    } 	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath0, &conn)))		printk("\tunable to find %s (ret=%d)\n", cpath0, ret);	    else {					SHOWREF(conn, hwgraph_traverse);		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);		else {					SHOWREF(vhdl, hwgraph_traverse);		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname0, NULL)))			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname0, ret);		    else				SHOWREF(vhdl, hwgraph_edge_remove);		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);		    else				SHOWREF(vhdl, hwgraph_edge_remove);		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))			printk("unable to unref %v\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_unref);		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))			printk("\tvertex %d destroyed OK\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);		}		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))		    printk("unable to unref %v\n", conn);		else					SHOWREF(conn, hwgraph_vertex_unref);	    }	    if (GRAPH_SUCCESS != (ret = hwgraph_traverse(hwgraph_root, cpath1, &conn)))		printk("\tunable to find %s (ret=%d)\n", cpath1, ret);	    else {					SHOWREF(conn, hwgraph_traverse);		if (GRAPH_SUCCESS != (ret = hwgraph_traverse(conn, dname, &vhdl)))		    printk("\tunable to find %v/%s (ret=%d)\n", conn, dname, ret);		else {					SHOWREF(vhdl, hwgraph_traverse);		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conv, uname1, NULL)))			printk("\tunable to remove edge %v/%s (ret=%d)\n", conv, uname1, ret);		    else				SHOWREF(vhdl, hwgraph_edge_remove);		    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(conn, dname, NULL)))			printk("\tunable to remove edge %v/%s (ret=%d)\n", conn, dname, ret);		    else				SHOWREF(vhdl, hwgraph_edge_remove);		    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(vhdl)))			printk("unable to unref %v\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_unref);		    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(vhdl)))			printk("\tvertex %d destroyed OK\n", vhdl);		    else				SHOWREF(vhdl, hwgraph_vertex_destroy);		}		if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conn)))		    printk("unable to unref %v\n", conn);		else					SHOWREF(conn, hwgraph_vertex_unref);	    }	    if (GRAPH_SUCCESS != (ret = hwgraph_edge_remove(hwgraph_root, cname, NULL)))		printk("\tunable to remove edge %v/%s (ret=%d)\n", hwgraph_root, cname, ret);	    else				SHOWREF(conv, hwgraph_edge_remove);	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_unref(conv)))		printk("unable to unref %v\n", conv);	    else					SHOWREF(conv, hwgraph_vertex_unref);	    if (GRAPH_SUCCESS == (ret = hwgraph_vertex_destroy(conv)))		printk("\tvertex %d destroyed OK\n", conv);	    else					SHOWREF(conv, hwgraph_vertex_destroy);	}    }#endif    return 0;}#endifintpciba_attach(devfs_handle_t hconn){#if defined(PCIIO_SLOT_NONE)    pciio_info_t            info = pciio_info_get(hconn);    pciio_slot_t            slot = pciio_info_slot_get(info);#endif    pciba_comm_t	    comm;    pciba_bus_t             bus;    int                     ht;    devfs_handle_t	    hbase;    devfs_handle_t          gconn;    devfs_handle_t          gbase;    int                     win;    int                     wins;    pciio_space_t           space;    pciaddr_t               base;    int                     iwins;    int                     mwins;#if DEBUG_PCIBA    printk("pciba_attach(%p)\n", hconn);#endif    /* Pick up "dualslot guest" vertex,     * which gets all functionality except     * config space access.     */    if ((GRAPH_SUCCESS !=	 hwgraph_traverse(hconn, ".guest", &gconn)) ||	(hconn == gconn))	gconn = GRAPH_VERTEX_NONE;    bus = pciba_find_bus(hconn, 1);    bus->refct ++;    /* set up data common to all pciba openables     * on this connection point.     */    NEW(comm);    comm->conn = hconn;    comm->bus = bus;    comm->refct = 0;    sema_init(&comm->lock, 1);#if !defined(PCIIO_SLOT_NONE)    if (bus->refct == 1)#else    if (slot == PCIIO_SLOT_NONE)#endif    {	pciio_info_t            pciio_info;	devfs_handle_t          master;	pciio_info = pciio_info_get(hconn);	master = pciio_info_master_get(pciio_info);	pciba_sub_attach(comm, PCIIO_SPACE_IO, PCIIO_SPACE_IO, 0, master, master, PCIBA_EDGE_LBL_IO);	pciba_sub_attach(comm, PCIIO_SPACE_MEM, PCIIO_SPACE_MEM, 0, master, master, PCIBA_EDGE_LBL_MEM);#if defined(PCIIO_SLOT_NONE)	return 0;#endif    }    ht = 0x7F & pciio_config_get(hconn, PCI_CFG_HEADER_TYPE, 1);    wins = ((ht == 0x00) ? 6 :	    (ht == 0x01) ? 2 :	    0);    mwins = iwins = 0;    hbase = GRAPH_VERTEX_NONE;    gbase = GRAPH_VERTEX_NONE;    for (win = 0; win < wins; win++) {	base = pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win), 4);	if (base & 1) {	    space = PCIIO_SPACE_IO;	    base &= 0xFFFFFFFC;	} else if ((base & 7) == 4) {	    space = PCIIO_SPACE_MEM;	    base &= 0xFFFFFFF0;	    base |= ((pciaddr_t) pciio_config_get(hconn, PCI_CFG_BASE_ADDR(win + 1), 4)) << 32;	} else {	    space = PCIIO_SPACE_MEM;	    base &= 0xFFFFFFF0;	}	if (!base)	    break;#if PCIBA_ALIGN_CHECK	if (base & (_PAGESZ - 1)) {#if DEBUG_PCIBA	    PRINT_WARNING("%p pciba: BASE%d not page aligned!\n"		    "\tmmap this window at offset 0x%x via \".../pci/%s\"\n",		    hconn, win, base,		    (space == PCIIO_SPACE_IO) ? "io" : "mem");#endif	    continue;			/* next window */	}#endif	if ((hbase == GRAPH_VERTEX_NONE) &&	    ((GRAPH_SUCCESS !=	      hwgraph_path_add(hconn, PCIBA_EDGE_LBL_BASE, &hbase)) ||	     (hbase == GRAPH_VERTEX_NONE)))	    break;			/* no base vertex, no more windows. */	if ((gconn != GRAPH_VERTEX_NONE) &&	    (gbase == GRAPH_VERTEX_NONE) &&	    ((GRAPH_SUCCESS !=	      hwgraph_path_add(gconn, PCIBA_EDGE_LBL_BASE, &gbase)) ||	     (gbase == GRAPH_VERTEX_NONE)))	    break;			/* no base vertex, no more windows. */	pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hbase, gbase, PCIBA_EDGE_LBL_WIN(win));	if (space == PCIIO_SPACE_IO) {	    if (!iwins++) {		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_IO);	    }	} else {	    if (!mwins++) {		pciba_sub_attach(comm, PCIIO_SPACE_WIN(win), space, base, hconn, gconn, PCIBA_EDGE_LBL_MEM);	    }	}	if ((base & 7) == 4)	    win++;    }    pciba_sub_attach(comm, PCIIO_SPACE_CFG, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_CFG);    pciba_sub_attach(comm, PCIBA_SPACE_UDMA, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_DMA);#if ULI    pciba_sub_attach(comm, PCIIO_SPACE_NONE, PCIIO_SPACE_NONE, 0, hconn, gconn, PCIBA_EDGE_LBL_INTR);#endif    /* XXX should ignore if device is an IOC3 */    if (ht == 0x01)	base = pciio_config_get(hconn, PCI_EXPANSION_ROM+8, 4);    else	base = pciio_config_get(hconn, PCI_EXPANSION_ROM, 4);    base &= 0xFFFFF000;    if (base) {	if (base & (_PAGESZ - 1))#if defined(SUPPORT_PRINTING_V_FORMAT)	    PRINT_WARNING("%v pciba: ROM is 0x%x\n"		    "\tnot page aligned, mmap will be difficult\n",		    hconn, base);#else	    PRINT_WARNING("0x%x pciba: ROM is 0x%x\n"		    "\tnot page aligned, mmap will be difficult\n",		    hconn, base);#endif	pciba_sub_attach(comm, PCIIO_SPACE_ROM, PCIIO_SPACE_MEM, base, hconn, gconn, PCIBA_EDGE_LBL_ROM);    }#if !FICUS	/* FICUS shorts the refct by one on path_add */    if (hbase != GRAPH_VERTEX_NONE)	hwgraph_vertex_unref(hbase);    if (gbase != GRAPH_VERTEX_NONE)	hwgraph_vertex_unref(gbase);#endif    return 0;}static voidpciba_sub_attach2(pciba_comm_t comm,		  pciio_space_t space,		  pciio_space_t iomem,		  pciaddr_t base,		  devfs_handle_t from,		  char *name,		  char *suf,		  unsigned bigend){    char		nbuf[128];    pciba_soft_t            soft;    devfs_handle_t	handle = NULL;    if (suf && *suf) {	strcpy(nbuf, name);	name = nbuf;	strcat(name, suf);    }#if DEBUG_PCIBA    printk("pciba_sub_attach2 %p/%s %p at %p[%x]\n",	   from, name, space, space_desc, iomem, space_desc, base, from, name);#endif    if (space < TRACKED_SPACES)	if ((soft = comm->soft[space][bigend]) != NULL) {	    soft->refct ++;	    hwgraph_edge_add(from, soft->vhdl, name);	    return;	}    NEW(soft);    if (!soft)	return;    soft->comm = comm;    soft->space = space;    soft->size = 0;    soft->iomem = iomem;    soft->base = base;    soft->refct = 1;    if (space == PCIIO_SPACE_NONE)	soft->flags = 0;    else if (bigend)	soft->flags = PCIIO_BYTE_STREAM;    else	soft->flags = PCIIO_WORD_VALUES;    handle = hwgraph_register(from, name,		0, DEVFS_FL_AUTO_DEVNUM,		0, 0,		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,		&pciba_fops, NULL);    soft->vhdl = handle;    pciba_soft_set(soft->vhdl, soft);    if (space < TRACKED_SPACES)	comm->soft[space][bigend] = soft;    comm->refct ++;}static voidpciba_sub_attach1(pciba_comm_t comm,		  pciio_space_t space,		  pciio_space_t iomem,		  pciaddr_t base,		  devfs_handle_t hfrom,		  devfs_handle_t gfrom,		  char *name,		  char *suf,		  unsigned bigend){    pciba_sub_attach2(comm, space, iomem, base, hfrom, name, suf, bigend);    if ((gfrom != GRAPH_VERTEX_NONE) && (gfrom != hfrom))	pciba_sub_attach2(comm, space, iomem, base, gfrom, name, suf, bigend);}static voidpciba_sub_attach(pciba_comm_t comm,		 pciio_space_t space,		 pciio_space_t iomem,		 pciaddr_t base,		 devfs_handle_t hfrom,		 devfs_handle_t gfrom,		 char *name){    pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, NULL, 0);    if (iomem != PCIIO_SPACE_NONE) {	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_le", 0);	pciba_sub_attach1(comm, space, iomem, base, hfrom, gfrom, name, "_be", 1);    }}#ifdef LATERstatic voidpciba_reload_me(devfs_handle_t pconn_vhdl){    devfs_handle_t            vhdl;#if DEBUG_PCIBA    printf("pciba_reload_me(%v)\n", pconn_vhdl);#endif    if (GRAPH_SUCCESS !=	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &vhdl))	return;    hwgraph_vertex_unref(vhdl);}#endif	/* LATER */static                  pciba_bus_tpciba_find_bus(devfs_handle_t pconn, int cflag){    pciio_info_t            pciio_info;    devfs_handle_t          master;    arbitrary_info_t        ainfo;    pciba_bus_t             bus;    pciio_info = pciio_info_get(pconn);    master = pciio_info_master_get(pciio_info);    if (GRAPH_SUCCESS ==	hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo))	return (pciba_bus_t) ainfo;    if (!cflag)	return 0;    NEW(bus);    if (!bus)	return 0;    sema_init(&bus->lock, 1);    ainfo = (arbitrary_info_t) bus;    hwgraph_info_add_LBL(master, PCIBA_INFO_LBL_BUS, ainfo);    hwgraph_info_get_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);    if ((pciba_bus_t) ainfo != bus)	DEL(bus);#if DEBUG_PCIBA    else	printk("pcbia_find_bus: new bus at %p\n", master);#endif    return (pciba_bus_t) ainfo;}#ifdef LATERstatic voidpciba_map_push(pciba_bus_t bus, pciba_map_t map){#if DEBUG_PCIBA    printk("pciba_map_push(bus=0x%x, map=0x%x, hdl=0x%x\n",	   bus, map, map->handle);#endif    pciba_bus_lock(bus);    map->next = bus->maps;    bus->maps = map;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -