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

📄 pic.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    pcibr_soft->bs_moduleid = iomoduleid_get(pcibr_soft->bs_nasid);    if (pcibr_soft->bs_bricktype > 0) {        switch (pcibr_soft->bs_bricktype) {	case MODULE_PXBRICK:	case MODULE_IXBRICK:	case MODULE_OPUSBRICK:            pcibr_soft->bs_first_slot = 0;            pcibr_soft->bs_last_slot = 1;            pcibr_soft->bs_last_reset = 1;            /* Bus 1 of IXBrick has a IO9, so there are 4 devices, not 2 */	    if ((pcibr_widget_to_bus(pcibr_vhdl) == 1) 		    && isIO9(pcibr_soft->bs_nasid)) {                pcibr_soft->bs_last_slot = 3;                pcibr_soft->bs_last_reset = 3;            }            break;        case MODULE_CGBRICK:            pcibr_soft->bs_first_slot = 0;            pcibr_soft->bs_last_slot = 0;            pcibr_soft->bs_last_reset = 0;            break;        default:	    printk(KERN_WARNING "%s: Unknown bricktype: 0x%x\n",                    pcibr_soft->bs_name, pcibr_soft->bs_bricktype);            break;        }        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,                    "pic_attach2: bricktype=%d, brickbus=%d, "		    "slots %d-%d\n", pcibr_soft->bs_bricktype,		    pcibr_widget_to_bus(pcibr_vhdl),                    pcibr_soft->bs_first_slot, pcibr_soft->bs_last_slot));    }    /*     * Initialize bridge and bus locks     */    spin_lock_init(&pcibr_soft->bs_lock);    /*     * If we have one, process the hints structure.     */    if (pcibr_hints) {        unsigned	rrb_fixed;        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_HINTS, pcibr_vhdl,                    "pic_attach2: pcibr_hints=0x%lx\n", pcibr_hints));        rrb_fixed = pcibr_hints->ph_rrb_fixed;        pcibr_soft->bs_rrb_fixed = rrb_fixed;        if (pcibr_hints->ph_intr_bits)            pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;        for (slot = pcibr_soft->bs_min_slot;                                slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {            int hslot = pcibr_hints->ph_host_slot[slot] - 1;            if (hslot < 0) {                pcibr_soft->bs_slot[slot].host_slot = slot;            } else {                pcibr_soft->bs_slot[slot].has_host = 1;                pcibr_soft->bs_slot[slot].host_slot = hslot;            }        }    }    /*     * Set-up initial values for state fields     */    for (slot = pcibr_soft->bs_min_slot;                                slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {        pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;        pcibr_soft->bs_slot[slot].bss_devio.bssd_ref_cnt = 0;        pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;        pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;        pcibr_soft->bs_rrb_valid_dflt[slot][VCHAN0] = -1;    }    for (ibit = 0; ibit < 8; ++ibit) {        pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_ibit = ibit;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;        pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;    }    /*     * connect up our error handler.  PIC has 2 busses (thus resulting in 2     * pcibr_soft structs under 1 widget), so only register a xwidget error     * handler for PIC's bus0.  NOTE: for PIC pcibr_error_handler_wrapper()     * is a wrapper routine we register that will call the real error handler     * pcibr_error_handler() with the correct pcibr_soft struct.     */    if (busnum == 0) {        xwidget_error_register(xconn_vhdl,                                pcibr_error_handler_wrapper, pcibr_soft);    }    /*     * Clear all pending interrupts.  Assume all interrupts are from slot 3     * until otherise setup.     */    pcireg_intr_reset_set(pcibr_soft, PIC_IRR_ALL_CLR);    pcireg_intr_device_set(pcibr_soft, 0x006db6db);    /* Setup the mapping register used for direct mapping */    pcibr_directmap_init(pcibr_soft);    /*     * Initialize the PICs control register.     */    pic_ctrl_reg = pcireg_control_get(pcibr_soft);    /* Bridges Requester ID: bus = busnum, dev = 0, func = 0 */    pic_ctrl_reg &= ~PIC_CTRL_BUS_NUM_MASK;    pic_ctrl_reg |= PIC_CTRL_BUS_NUM(busnum);    pic_ctrl_reg &= ~PIC_CTRL_DEV_NUM_MASK;    pic_ctrl_reg &= ~PIC_CTRL_FUN_NUM_MASK;    pic_ctrl_reg &= ~PIC_CTRL_NO_SNOOP;    pic_ctrl_reg &= ~PIC_CTRL_RELAX_ORDER;    /* enable parity checking on PICs internal RAM */    pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP;    pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE;    /* PIC BRINGUP WAR (PV# 862253): dont enable write request parity */    if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) {        pic_ctrl_reg |= PIC_CTRL_PAR_EN_REQ;    }    pic_ctrl_reg |= PIC_CTRL_PAGE_SIZE;    pcireg_control_set(pcibr_soft, pic_ctrl_reg);    /* Initialize internal mapping entries (ie. the ATEs) */    for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)	pcireg_int_ate_set(pcibr_soft, entry, 0);    pcibr_soft->bs_int_ate_resource.start = 0;    pcibr_soft->bs_int_ate_resource.end = pcibr_soft->bs_int_ate_size - 1;    /* Setup the PICs error interrupt handler. */    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl);    ASSERT(xtalk_intr != NULL);    irq = ((hub_intr_t)xtalk_intr)->i_bit;    cpu = ((hub_intr_t)xtalk_intr)->i_cpuid;    intr_unreserve_level(cpu, irq);    ((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR;    xtalk_intr->xi_vector = SGI_PCIBR_ERROR;    pcibr_soft->bsi_err_intr = xtalk_intr;    /*     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint     * in order to work around some addressing limitations.  In order     * for that fire wall to work properly, we need to make sure we     * start from a known clean state.     */    pcibr_clearwidint(pcibr_soft);    xtalk_intr_connect(xtalk_intr,		       (intr_func_t) pcibr_error_intr_handler,		       (intr_arg_t) pcibr_soft,		       (xtalk_intr_setfunc_t) pcibr_setwidint,		       (void *) pcibr_soft);    request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, 			"PCIBR error", (intr_arg_t) pcibr_soft);    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl,		"pcibr_setwidint: target_id=0x%lx, int_addr=0x%lx\n",		pcireg_intr_dst_target_id_get(pcibr_soft),		pcireg_intr_dst_addr_get(pcibr_soft)));    /* now we can start handling error interrupts */    int_enable = pcireg_intr_enable_get(pcibr_soft);    int_enable |= PIC_ISR_ERRORS;    /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are     * locked out to be freed up sooner (by timing out) so that the     * read tnums are never completely used up.     */    if (PCIBR_WAR_ENABLED(PV856864, pcibr_soft)) {	int_enable &= ~PIC_ISR_PCIX_REQ_TOUT;	int_enable &= ~PIC_ISR_XREAD_REQ_TIMEOUT;	pcireg_req_timeout_set(pcibr_soft, 0x750);    }    pcireg_intr_enable_set(pcibr_soft, int_enable);    pcireg_intr_mode_set(pcibr_soft, 0); /* dont send 'clear interrupt' pkts */    pcireg_tflush_get(pcibr_soft);       /* wait until Bridge PIO complete */    /*     * PIC BRINGUP WAR (PV# 856866, 859504, 861476, 861478): Don't use     * RRB0, RRB8, RRB1, and RRB9.  Assign them to DEVICE[2|3]--VCHAN3     * so they are not used.  This works since there is currently no     * API to penable VCHAN3.     */    if (PCIBR_WAR_ENABLED(PV856866, pcibr_soft)) {	pcireg_rrb_bit_set(pcibr_soft, 0, 0x000f000f);	/* even rrb reg */	pcireg_rrb_bit_set(pcibr_soft, 1, 0x000f000f);	/* odd rrb reg */    }    /* PIC only supports 64-bit direct mapping in PCI-X mode.  Since     * all PCI-X devices that initiate memory transactions must be     * capable of generating 64-bit addressed, we force 64-bit DMAs.     */    pcibr_soft->bs_dma_flags = 0;    if (IS_PCIX(pcibr_soft)) {	pcibr_soft->bs_dma_flags |= PCIIO_DMA_A64;    }    {    iopaddr_t		    prom_base_addr = pcibr_soft->bs_xid << 24;    int			    prom_base_size = 0x1000000;    int			    status;    struct resource	    *res;    /* Allocate resource maps based on bus page size; for I/O and memory     * space, free all pages except those in the base area and in the     * range set by the PROM.     *     * PROM creates BAR addresses in this format: 0x0ws00000 where w is     * the widget number and s is the device register offset for the slot.     */    /* Setup the Bus's PCI IO Root Resource. */    pcibr_soft->bs_io_win_root_resource.start = PCIBR_BUS_IO_BASE;    pcibr_soft->bs_io_win_root_resource.end = 0xffffffff;    res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);    if (!res)	panic("PCIBR:Unable to allocate resource structure\n");    /* Block off the range used by PROM. */    res->start = prom_base_addr;    res->end = prom_base_addr + (prom_base_size - 1);    status = request_resource(&pcibr_soft->bs_io_win_root_resource, res);    if (status)	panic("PCIBR:Unable to request_resource()\n");    /* Setup the Small Window Root Resource */    pcibr_soft->bs_swin_root_resource.start = PAGE_SIZE;    pcibr_soft->bs_swin_root_resource.end = 0x000FFFFF;    /* Setup the Bus's PCI Memory Root Resource */    pcibr_soft->bs_mem_win_root_resource.start = 0x200000;    pcibr_soft->bs_mem_win_root_resource.end = 0xffffffff;    res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);    if (!res)	panic("PCIBR:Unable to allocate resource structure\n");    /* Block off the range used by PROM. */    res->start = prom_base_addr;    res->end = prom_base_addr + (prom_base_size - 1);    status = request_resource(&pcibr_soft->bs_mem_win_root_resource, res);    if (status)	panic("PCIBR:Unable to request_resource()\n");    }    /* build "no-slot" connection point */    pcibr_info = pcibr_device_info_new(pcibr_soft, PCIIO_SLOT_NONE,		 PCIIO_FUNC_NONE, PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);    noslot_conn = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);    /* Store no slot connection point info for tearing it down during detach. */    pcibr_soft->bs_noslot_conn = noslot_conn;    pcibr_soft->bs_noslot_info = pcibr_info;    for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	/* Find out what is out there */	(void)pcibr_slot_info_init(pcibr_vhdl, slot);    }    for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	/* Set up the address space for this slot in the PCI land */	(void)pcibr_slot_addr_space_init(pcibr_vhdl, slot);    }    for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	/* Setup the device register */	(void)pcibr_slot_device_init(pcibr_vhdl, slot);    }    if (IS_PCIX(pcibr_soft)) {	pcibr_soft->bs_pcix_rbar_inuse = 0;	pcibr_soft->bs_pcix_rbar_avail = NUM_RBAR;	pcibr_soft->bs_pcix_rbar_percent_allowed =					pcibr_pcix_rbars_calc(pcibr_soft);	for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	    /* Setup the PCI-X Read Buffer Attribute Registers (RBARs) */	    (void)pcibr_slot_pcix_rbar_init(pcibr_soft, slot);	}    }    for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	/* Setup host/guest relations */	(void)pcibr_slot_guest_info_init(pcibr_vhdl, slot);    }    /* Handle initial RRB management */    pcibr_initial_rrb(pcibr_vhdl,		      pcibr_soft->bs_first_slot, pcibr_soft->bs_last_slot);   /* Before any drivers get called that may want to re-allocate RRB's,    * let's get some special cases pre-allocated. Drivers may override    * these pre-allocations, but by doing pre-allocations now we're    * assured not to step all over what the driver intended.    */    if (pcibr_soft->bs_bricktype > 0) {	switch (pcibr_soft->bs_bricktype) {	case MODULE_PXBRICK:	case MODULE_IXBRICK:	case MODULE_OPUSBRICK:		/*		 * If IO9 in bus 1, allocate RRBs to all the IO9 devices		 */		if ((pcibr_widget_to_bus(pcibr_vhdl) == 1) &&		    (pcibr_soft->bs_slot[0].bss_vendor_id == 0x10A9) &&		    (pcibr_soft->bs_slot[0].bss_device_id == 0x100A)) {			pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 4);			pcibr_rrb_alloc_init(pcibr_soft, 1, VCHAN0, 4);			pcibr_rrb_alloc_init(pcibr_soft, 2, VCHAN0, 4);			pcibr_rrb_alloc_init(pcibr_soft, 3, VCHAN0, 4);		} else {			pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 4);			pcibr_rrb_alloc_init(pcibr_soft, 1, VCHAN0, 4);		}		break;	case MODULE_CGBRICK:		pcibr_rrb_alloc_init(pcibr_soft, 0, VCHAN0, 8);		break;	} /* switch */    }    for (slot = pcibr_soft->bs_min_slot;				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {	/* Call the device attach */	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);    }    pciio_device_attach(noslot_conn, 0);    return 0;}/* * pci provider functions * * mostly in pcibr.c but if any are needed here then * this might be a way to get them here. */pciio_provider_t        pci_pic_provider ={    PCIIO_ASIC_TYPE_PIC,    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,    (pciio_piomap_free_f *) pcibr_piomap_free,    (pciio_piomap_addr_f *) pcibr_piomap_addr,    (pciio_piomap_done_f *) pcibr_piomap_done,    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,    (pciio_piospace_free_f *) pcibr_piospace_free,    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,    (pciio_dmamap_free_f *) pcibr_dmamap_free,    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,    (pciio_dmamap_done_f *) pcibr_dmamap_done,    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,    (pciio_intr_alloc_f *) pcibr_intr_alloc,    (pciio_intr_free_f *) pcibr_intr_free,    (pciio_intr_connect_f *) pcibr_intr_connect,    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,    (pciio_provider_startup_f *) pcibr_provider_startup,    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,    (pciio_reset_f *) pcibr_reset,    (pciio_endian_set_f *) pcibr_endian_set,    (pciio_config_get_f *) pcibr_config_get,    (pciio_config_set_f *) pcibr_config_set,    (pciio_error_extract_f *) pcibr_error_extract,    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,    (pciio_device_unregister_f 	*) pcibr_device_unregister,};

⌨️ 快捷键说明

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