📄 pciio.c
字号:
if (mapp) { map = *mapp; /* possible pre-allocated map */ *mapp = 0; /* record "no map used" */ } res = pciio_dmatrans_addr (dev, dev_desc, paddr, byte_count, flags); if (res) return res; /* pciio_dmatrans worked */ if (!map) { map = pciio_dmamap_alloc (dev, dev_desc, byte_count, flags); if (!map) return res; /* pciio_dmamap_alloc failed */ errfree = 1; } res = pciio_dmamap_addr (map, paddr, byte_count); if (!res) { if (errfree) pciio_dmamap_free(map); return res; /* pciio_dmamap_addr failed */ } if (mapp) *mapp = map; /* pass back map used */ return res; /* pciio_dmamap_addr succeeded */}voidpciio_dmamap_drain(pciio_dmamap_t map){ DMAMAP_FUNC(map, dmamap_drain) (CAST_DMAMAP(map));}voidpciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size){ DEV_FUNC(dev, dmaaddr_drain) (dev, addr, size);}voidpciio_dmalist_drain(devfs_handle_t dev, alenlist_t list){ DEV_FUNC(dev, dmalist_drain) (dev, list);}/* ===================================================================== * INTERRUPT MANAGEMENT * * Allow crosstalk devices to establish interrupts *//* * Allocate resources required for an interrupt as specified in intr_desc. * Return resource handle in intr_hdl. */pciio_intr_tpciio_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */ device_desc_t dev_desc, /* device descriptor */ pciio_intr_line_t lines, /* INTR line(s) to attach */ devfs_handle_t owner_dev){ /* owner of this interrupt */ return (pciio_intr_t) DEV_FUNC(dev, intr_alloc) (dev, dev_desc, lines, owner_dev);}/* * Free resources consumed by intr_alloc. */voidpciio_intr_free(pciio_intr_t intr_hdl){ INTR_FUNC(intr_hdl, intr_free) (CAST_INTR(intr_hdl));}/* * Associate resources allocated with a previous pciio_intr_alloc call with the * described handler, arg, name, etc. * * Returns 0 on success, returns <0 on failure. */intpciio_intr_connect(pciio_intr_t intr_hdl) /* pciio intr resource handle */{ return INTR_FUNC(intr_hdl, intr_connect) (CAST_INTR(intr_hdl));}/* * Disassociate handler with the specified interrupt. */voidpciio_intr_disconnect(pciio_intr_t intr_hdl){ INTR_FUNC(intr_hdl, intr_disconnect) (CAST_INTR(intr_hdl));}/* * Return a hwgraph vertex that represents the CPU currently * targeted by an interrupt. */devfs_handle_tpciio_intr_cpu_get(pciio_intr_t intr_hdl){ return INTR_FUNC(intr_hdl, intr_cpu_get) (CAST_INTR(intr_hdl));}voidpciio_slot_func_to_name(char *name, pciio_slot_t slot, pciio_function_t func){ /* * standard connection points: * * PCIIO_SLOT_NONE: .../pci/direct * PCIIO_FUNC_NONE: .../pci/<SLOT> ie. .../pci/3 * multifunction: .../pci/<SLOT><FUNC> ie. .../pci/3c */ if (slot == PCIIO_SLOT_NONE) sprintf(name, "direct"); else if (func == PCIIO_FUNC_NONE) sprintf(name, "%d", slot); else sprintf(name, "%d%c", slot, 'a'+func);}/* ===================================================================== * CONFIGURATION MANAGEMENT *//* * Startup a crosstalk provider */voidpciio_provider_startup(devfs_handle_t pciio_provider){ DEV_FUNC(pciio_provider, provider_startup) (pciio_provider);}/* * Shutdown a crosstalk provider */voidpciio_provider_shutdown(devfs_handle_t pciio_provider){ DEV_FUNC(pciio_provider, provider_shutdown) (pciio_provider);}/* * Specify endianness constraints. The driver tells us what the device * does and how it would like to see things in memory. We reply with * how things will actually appear in memory. */pciio_endian_tpciio_endian_set(devfs_handle_t dev, pciio_endian_t device_end, pciio_endian_t desired_end){ ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE)); ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));#if DEBUG#if defined(SUPPORT_PRINTING_V_FORMAT) printk(KERN_ALERT "%v: pciio_endian_set is going away.\n" "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", dev);#else printk(KERN_ALERT "0x%x: pciio_endian_set is going away.\n" "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n" "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n", dev);#endif#endif return DEV_FUNC(dev, endian_set) (dev, device_end, desired_end);}/* * Specify PCI arbitration priority. */pciio_priority_tpciio_priority_set(devfs_handle_t dev, pciio_priority_t device_prio){ ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW)); return DEV_FUNC(dev, priority_set) (dev, device_prio);}/* * Read value of configuration register */uint64_tpciio_config_get(devfs_handle_t dev, unsigned reg, unsigned size){ uint64_t value = 0; unsigned shift = 0; /* handle accesses that cross words here, * since that's common code between all * possible providers. */ while (size > 0) { unsigned biw = 4 - (reg&3); if (biw > size) biw = size; value |= DEV_FUNC(dev, config_get) (dev, reg, biw) << shift; shift += 8*biw; reg += biw; size -= biw; } return value;}/* * Change value of configuration register */voidpciio_config_set(devfs_handle_t dev, unsigned reg, unsigned size, uint64_t value){ /* handle accesses that cross words here, * since that's common code between all * possible providers. */ while (size > 0) { unsigned biw = 4 - (reg&3); if (biw > size) biw = size; DEV_FUNC(dev, config_set) (dev, reg, biw, value); reg += biw; size -= biw; value >>= biw * 8; }}/* ===================================================================== * GENERIC PCI SUPPORT FUNCTIONS *//* * Issue a hardware reset to a card. */intpciio_reset(devfs_handle_t dev){ return DEV_FUNC(dev, reset) (dev);}/* * flush write gather buffers */intpciio_write_gather_flush(devfs_handle_t dev){ return DEV_FUNC(dev, write_gather_flush) (dev);}devfs_handle_tpciio_intr_dev_get(pciio_intr_t pciio_intr){ return (pciio_intr->pi_dev);}/****** Generic crosstalk pio interfaces ******/devfs_handle_tpciio_pio_dev_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_dev);}pciio_slot_tpciio_pio_slot_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_slot);}pciio_space_tpciio_pio_space_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_space);}iopaddr_tpciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_pciaddr);}ulongpciio_pio_mapsz_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_mapsz);}caddr_tpciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap){ return (pciio_piomap->pp_kvaddr);}/****** Generic crosstalk dma interfaces ******/devfs_handle_tpciio_dma_dev_get(pciio_dmamap_t pciio_dmamap){ return (pciio_dmamap->pd_dev);}pciio_slot_tpciio_dma_slot_get(pciio_dmamap_t pciio_dmamap){ return (pciio_dmamap->pd_slot);}/****** Generic pci slot information interfaces ******/pciio_info_tpciio_info_chk(devfs_handle_t pciio){ arbitrary_info_t ainfo = 0; hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo); return (pciio_info_t) ainfo;}pciio_info_tpciio_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 */ 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;}voidpciio_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_tpciio_info_dev_get(pciio_info_t pciio_info){ return (pciio_info->c_vertex);}/*ARGSUSED*/pciio_bus_tpciio_info_bus_get(pciio_info_t pciio_info){ /* XXX for now O2 always gets back bus 0 */ return (pciio_bus_t)0;}pciio_slot_tpciio_info_slot_get(pciio_info_t pciio_info){ return (pciio_info->c_slot);}pciio_function_tpciio_info_function_get(pciio_info_t pciio_info){ return (pciio_info->c_func);}pciio_vendor_id_tpciio_info_vendor_id_get(pciio_info_t pciio_info){ return (pciio_info->c_vendor);}pciio_device_id_tpciio_info_device_id_get(pciio_info_t pciio_info){ return (pciio_info->c_device);}devfs_handle_tpciio_info_master_get(pciio_info_t pciio_info){ return (pciio_info->c_master);}arbitrary_info_tpciio_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_tpciio_info_bar_space_get(pciio_info_t info, int win){ return info->c_window[win].w_space;}iopaddr_tpciio_info_bar_base_get(pciio_info_t info, int win){ return info->c_window[win].w_base;}size_tpciio_info_bar_size_get(pciio_info_t info, int win){ return info->c_window[win].w_size;}iopaddr_tpciio_info_rom_base_get(pciio_info_t info){ return info->c_rbase;}size_tpciio_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. */voidpciio_init(void){ cdl_p cp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -