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

📄 pciba.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    pciba_bus_unlock(bus);}static                  pciba_map_tpciba_map_pop_hdl(pciba_bus_t bus, __psunsigned_t handle){    pciba_map_h             hdl;    pciba_map_t             map;    pciba_bus_lock(bus);    for (hdl = &bus->maps; map = *hdl; hdl = &map->next)	if (map->handle == handle) {	    *hdl = map->next;	    break;	}    pciba_bus_unlock(bus);#if DEBUG_PCIBA    printk("pciba_map_pop_va(bus=0x%x, handle=0x%x) returns map=0x%x\n",	   bus, handle, map);#endif    return map;}/* ================================================================ *            driver teardown, unregister and unload */intpciba_unload(void){#if DEBUG_PCIBA    printk("pciba_unload()\n");#endif    if (atomic_read(&pciba_prevent_unload))	return -1;    pciio_iterate("pciba_", pciba_unload_me);    return 0;}intpciba_unreg(void){#if DEBUG_PCIBA    printf("pciba_unreg()\n");#endif    if (atomic_read(&pciba_prevent_unload))	return -1;    pciio_driver_unregister("pciba_");    return 0;}intpciba_detach(devfs_handle_t conn){    devfs_handle_t          base;    pciba_bus_t             bus;    devfs_handle_t          gconn;    devfs_handle_t          gbase;    pciio_info_t            pciio_info;    devfs_handle_t          master;    arbitrary_info_t        ainfo;    int			    ret;#if DEBUG_PCIBA    printf("pciba_detach(%v)\n", conn);#endif    if ((GRAPH_SUCCESS !=	 hwgraph_traverse(conn, ".guest", &gconn)) ||	(conn == gconn))	gconn = GRAPH_VERTEX_NONE;    if (gconn != GRAPH_VERTEX_NONE) {	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_CFG);	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_DMA);	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_ROM);#if ULI	pciba_sub_detach(gconn, PCIBA_EDGE_LBL_INTR);#endif	if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &gbase)) {	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_MEM);	    pciba_sub_detach(gconn, PCIBA_EDGE_LBL_IO);	    pciba_sub_detach(gbase, "0");	    pciba_sub_detach(gbase, "1");	    pciba_sub_detach(gbase, "2");	    pciba_sub_detach(gbase, "3");	    pciba_sub_detach(gbase, "4");	    pciba_sub_detach(gbase, "5");	    hwgraph_vertex_unref(gbase);	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(gbase))) {#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",			conn, ret);#else		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",			conn, ret);#endif#if DEBUG_REFCT		printk("\tretained refct %d\n", hwgraph_vertex_refct(gbase));#endif	    }	}    }    pciba_sub_detach(conn, PCIBA_EDGE_LBL_CFG);    pciba_sub_detach(conn, PCIBA_EDGE_LBL_DMA);    pciba_sub_detach(conn, PCIBA_EDGE_LBL_ROM);#if ULI    pciba_sub_detach(conn, PCIBA_EDGE_LBL_INTR);#endif    if (GRAPH_SUCCESS == hwgraph_edge_remove(conn, PCIBA_EDGE_LBL_BASE, &base)) {	pciba_sub_detach(conn, PCIBA_EDGE_LBL_MEM);	pciba_sub_detach(conn, PCIBA_EDGE_LBL_IO);	pciba_sub_detach(base, "0");	pciba_sub_detach(base, "1");	pciba_sub_detach(base, "2");	pciba_sub_detach(base, "3");	pciba_sub_detach(base, "4");	pciba_sub_detach(base, "5");	hwgraph_vertex_unref(base);	if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(base))) {#if defined(SUPPORT_PRINTING_V_FORMAT)	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(%v/base) failed (%d)",		    conn, ret);#else	    PRINT_WARNING(CE_WARN, "pciba: hwgraph_vertex_destroy(0x%x/base) failed (%d)",		    conn, ret);#endif#if DEBUG_REFCT	    printk("\tretained refct %d\n", hwgraph_vertex_refct(base));#endif	}    }    bus = pciba_find_bus(conn, 0);    if (bus && !--(bus->refct)) {	pciio_info = pciio_info_get(conn);	master = pciio_info_master_get(pciio_info);	pciba_sub_detach(master, PCIBA_EDGE_LBL_IO);	pciba_sub_detach(master, PCIBA_EDGE_LBL_MEM);	pciba_sub_detach(master, PCIBA_EDGE_LBL_CFG);	hwgraph_info_remove_LBL(master, PCIBA_INFO_LBL_BUS, &ainfo);#if DEBUG_PCIBA	printf("pcbia_detach: DEL(bus) at %v\n", master);#endif	DEL(bus);    }     return 0;}static voidpciba_sub_detach1(devfs_handle_t conn,		  char *name,		  char *suf){    devfs_handle_t         vhdl;    pciba_soft_t            soft;    pciba_comm_t	    comm;    int			    ret;    char		nbuf[128];    if (suf && *suf) {	strcpy(nbuf, name);	name = nbuf;	strcat(name, suf);    }    if ((GRAPH_SUCCESS == hwgraph_edge_remove(conn, name, &vhdl)) &&	((soft = pciba_soft_get(vhdl)) != NULL)) {#if DEBUG_PCIBA#if defined(SUPPORT_PRINTING_V_FORMAT)	prink("pciba_sub_detach(%v,%s)\n", conn, name);#else	prink("pciba_sub_detach(0x%x,%s)\n", conn, name);#endif#endif	hwgraph_vertex_unref(soft->vhdl);#if DEBUG_REFCT	printk("\tadjusted refct %d (soft ref: %d)\n",		hwgraph_vertex_refct(vhdl),		soft->refct);#endif	if (!--(soft->refct)) {	    comm = soft->comm;	    if (!--(comm->refct)) {		DEL(comm);	    }	    pciba_soft_set(vhdl, 0);	    DEL(soft);	    hwgraph_vertex_unref(vhdl);	    if (GRAPH_SUCCESS != (ret = hwgraph_vertex_destroy(vhdl))) {#if defined(SUPPORT_PRINTING_V_FORMAT)		PRINT_WARNING("pciba: hwgraph_vertex_destroy(0x%x/%s) failed (%d)",			conn, name, ret);#else		PRINT_WARNING("pciba: hwgraph_vertex_destroy(%v/%s) failed (%d)",			conn, name, ret);#endif#if DEBUG_REFCT		printk("\tretained refct %d\n", hwgraph_vertex_refct(vhdl));#endif	    }	}    }}static voidpciba_sub_detach(devfs_handle_t conn,		 char *name){    pciba_sub_detach1(conn, name, "");    pciba_sub_detach1(conn, name, "_le");    pciba_sub_detach1(conn, name, "_be");}static voidpciba_unload_me(devfs_handle_t pconn_vhdl){    devfs_handle_t         c_vhdl;#if DEBUG_PCIBA    printf("pciba_unload_me(%v)\n", pconn_vhdl);#endif    if (GRAPH_SUCCESS !=	hwgraph_traverse(pconn_vhdl, PCIBA_EDGE_LBL_CFG, &c_vhdl))	return;    hwgraph_vertex_unref(c_vhdl);}/* ================================================================ *            standard unix entry points *//*ARGSUSED */intpciba_open(dev_t *devp, int flag, int otyp, struct cred *crp){#if DEBUG_PCIBA    printf("pciba_open(%V)\n", *devp);#endif    return 0;}/*ARGSUSED */intpciba_close(dev_t dev){    devfs_handle_t         vhdl = dev_to_vhdl(dev);    pciba_soft_t            soft = pciba_soft_get(vhdl);#if DEBUG_PCIBA    printf("pciba_close(%V)\n", dev);#endif    /* if there is pending DMA for this device, hit the     * device over the head with a baseball bat and     * release the system memory resources.     */    if (soft && soft->comm->dmap) {	pciba_dma_t             next;	pciba_dma_t             dmap;	pciba_soft_lock(soft);	if (dmap = soft->comm->dmap) {	    soft->comm->dmap = 0;	    pciio_reset(soft->comm->conn);	    do {		if (!dmap->kaddr)		    break;		if (!dmap->paddr)		    break;		if (dmap->bytes < NBPP)		    break;		next = dmap->next;		kvpfree(dmap->kaddr, dmap->bytes / NBPP);		dmap->paddr = 0;		dmap->bytes = 0;		DEL(dmap);	    } while (dmap = next);	}	pciba_soft_unlock(soft);    }    return 0;}/* ARGSUSED */intpciba_read(dev_t dev, cred_t *crp){#if DEBUG_PCIBA    printf("pciba_read(%V)\n", dev);#endif    return EINVAL;}/* ARGSUSED */intpciba_write(dev_t dev, cred_t *crp){#if DEBUG_PCIBA    printf("pciba_write(%V)\n", dev);#endif    return EINVAL;}/*ARGSUSED */intpciba_ioctl(dev_t dev, int cmd, void *uarg, int mode, cred_t *crp, int *rvalp){    devfs_handle_t          vhdl;    pciba_soft_t            soft;    pciio_space_t           space;    ioctl_arg_buffer_t      arg;    int                     psize;    int                     err = 0;#if ULI    char		    abi = get_current_abi();    pciio_intr_t            intr=0;    device_desc_t           desc;    cpuid_t                 intrcpu;    unsigned                lines;    struct uli             *uli = 0;#endif    unsigned                flags;    void                   *kaddr = 0;    iopaddr_t               paddr;    pciba_dma_h             dmah;    pciba_dma_t             dmap = 0;    pciio_dmamap_t          dmamap = 0;    size_t                  bytes;    int                     pages;    pciaddr_t               daddr;#if DEBUG_PCIBA    printf("pciba_ioctl(%V,0x%x)\n", dev, cmd);#endif    psize = (cmd >> 16) & IOCPARM_MASK;#if ULI    ASSERT(sizeof(struct uliargs) > 8);	/* prevent CFG access conflict */    ASSERT(sizeof(struct uliargs) <= IOCPARM_MASK);#endif    arg.ca = uarg;    if ((psize > 0) && (cmd & (IOC_OUT | IOC_IN))) {	if (psize > sizeof(arg))	    err = EINVAL;		/* "bad parameter size */	else {	    if (cmd & IOC_OUT)		bzero(arg.data, psize);	    if ((cmd & IOC_IN) &&		(copyin(uarg, arg.data, psize) < 0))		err = EFAULT;		/* "parameter copyin failed" */	}    }    vhdl = dev_to_vhdl(dev);    soft = pciba_soft_get(vhdl);    space = soft->space;    if (err == 0) {	err = EINVAL;			/* "invalid ioctl for this vertex" */	switch (space) {#if ULI	case PCIIO_SPACE_NONE:		/* the "intr" vertex */	    /* PCIIOCSETULI: set up user interrupts.	     */	    lines = cmd & 15;	    if (ABI_IS_64BIT(abi)) {		if (cmd != PCIIOCSETULI(lines)) {		    err = EINVAL;		/* "invalid ioctl for this vertex" */		    break;		}	    }	    else {		struct uliargs uliargs;		if (cmd != PCIIOCSETULI32(lines)) {		    err = EINVAL;		/* "invalid ioctl for this vertex" */		    break;		}				uliargs32_to_uliargs(&arg.uli32, &uliargs);		arg.uli = uliargs;	    }	    desc = device_desc_dup(soft->comm->conn);	    device_desc_flags_set(desc, (device_desc_flags_get(desc) |					 D_INTR_NOTHREAD));	    device_desc_intr_swlevel_set(desc, INTR_SWLEVEL_NOTHREAD_DEFAULT);	    device_desc_intr_name_set(desc, "PCIBA");	    device_desc_default_set(soft->comm->conn, desc);	    /* When designating interrupts, the slot number	     * is taken from the connection point.	     * Bits 0..3 are used to select INTA..INTD; more	     * than one bit can be specified. These should	     * be constructed using PCIIO_INTR_LINE_[ABCD].	     */	    intr = pciio_intr_alloc		(soft->comm->conn, desc, lines, soft->vhdl);	    if (intr == 0) {		err = ENOMEM;		/* "insufficient resources" */		break;	    }	    intrcpu = cpuvertex_to_cpuid(pciio_intr_cpu_get(intr));	    if (err = new_uli(&arg.uli, &uli, intrcpu)) {

⌨️ 快捷键说明

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