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

📄 pcibr_slot.c

📁 microwindows移植到S3C44B0的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * * This file is subject to the terms and conditions of the GNU General Public * License.  See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved. */#include <linux/types.h>#include <linux/slab.h>#include <linux/module.h>#include <asm/sn/sgi.h>#include <asm/sn/sn_cpuid.h>#include <asm/sn/addrs.h>#include <asm/sn/arch.h>#include <asm/sn/iograph.h>#include <asm/sn/invent.h>#include <asm/sn/hcl.h>#include <asm/sn/labelcl.h>#include <asm/sn/xtalk/xwidget.h>#include <asm/sn/pci/bridge.h>#include <asm/sn/pci/pciio.h>#include <asm/sn/pci/pcibr.h>#include <asm/sn/pci/pcibr_private.h>#include <asm/sn/pci/pci_defs.h>#include <asm/sn/prio.h>#include <asm/sn/xtalk/xbow.h>#include <asm/sn/ioc3.h>#include <asm/sn/eeprom.h>#include <asm/sn/io.h>#include <asm/sn/sn_private.h>extern pcibr_info_t     pcibr_info_get(devfs_handle_t);extern int              pcibr_widget_to_bus(int);extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);extern void             pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);#if 0int pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);#endifint pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,		 pciio_slot_t slot, int drv_flags);int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,		 pciio_slot_t slot, int drv_flags);int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot, int drv_flags);int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);void		 pcibr_device_info_free(devfs_handle_t, pciio_slot_t);extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);#ifdef LATERint pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,                int drv_flags, char *l1_msg, int *sub_errorp);int pcibr_slot_pwr(devfs_handle_t, pciio_slot_t, int, char *);int pcibr_slot_startup(devfs_handle_t, pcibr_slot_req_t);int pcibr_slot_shutdown(devfs_handle_t, pcibr_slot_req_t);void pcibr_slot_func_info_return(pcibr_info_h pcibr_infoh, int func,                 pcibr_slot_func_info_resp_t funcp);int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,                 pcibr_slot_info_resp_t respp);int pcibr_slot_query(devfs_handle_t, pcibr_slot_req_t);#endif	/* LATER */extern devfs_handle_t baseio_pci_vhdl;int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);/* For now .... *//* * PCI Hot-Plug Capability Flags */#define D_PCI_HOT_PLUG_ATTACH  0x200  /* Driver supports PCI hot-plug attach */#define D_PCI_HOT_PLUG_DETACH  0x400  /* Driver supports PCI hot-plug detach *//*========================================================================== *	BRIDGE PCI SLOT RELATED IOCTLs */#ifdef LATER/* * pcibr_slot_startup *	Software start-up the PCI slot. */intpcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp){    pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);    pciio_slot_t                   slot = reqp->req_slot;    int                            error = 0;    char                           l1_msg[BRL1_QSIZE+1];    struct pcibr_slot_up_resp_s    tmp_up_resp;    /* Make sure that we are dealing with a bridge device vertex */    if (!pcibr_soft) {        return(PCI_NOT_A_BRIDGE);    }    /* Do not allow start-up of a slot in a shoehorn */    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {       return(PCI_SLOT_IN_SHOEHORN);    }     /* Check for the valid slot */    if (!PCIBR_VALID_SLOT(slot))        return(PCI_NOT_A_SLOT);    /* Acquire update access to the bus */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);    if (pcibr_soft->bs_slot[slot].slot_status & SLOT_STARTUP_CMPLT) {        error = PCI_SLOT_ALREADY_UP;        goto startup_unlock;    }    error = pcibr_slot_attach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_ATTACH,                              l1_msg, &tmp_up_resp.resp_sub_errno);    strncpy(tmp_up_resp.resp_l1_msg, l1_msg, L1_QSIZE);    tmp_up_resp.resp_l1_msg[L1_QSIZE] = '\0';    if (COPYOUT(&tmp_up_resp, reqp->req_respp.up, reqp->req_size)) {        return(EFAULT);    }    startup_unlock:    /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);    return(error);}/* * pcibr_slot_shutdown *	Software shut-down the PCI slot */intpcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp){    pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);    bridge_t                      *bridge;    pciio_slot_t                   slot = reqp->req_slot;    int                            error = 0;    char                           l1_msg[BRL1_QSIZE+1];    struct pcibr_slot_down_resp_s  tmp_down_resp;    pciio_slot_t                   tmp_slot;    /* Make sure that we are dealing with a bridge device vertex */    if (!pcibr_soft) {        return(PCI_NOT_A_BRIDGE);    }    bridge = pcibr_soft->bs_base;    /* Check for valid slot */    if (!PCIBR_VALID_SLOT(slot))        return(PCI_NOT_A_SLOT);    /* Do not allow shut-down of a slot in a shoehorn */    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {       return(PCI_SLOT_IN_SHOEHORN);    }    /* Acquire update access to the bus */    mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);    if ((pcibr_soft->bs_slot[slot].slot_status & SLOT_SHUTDOWN_CMPLT) ||        ((pcibr_soft->bs_slot[slot].slot_status & SLOT_STATUS_MASK) == 0)) {        error = PCI_SLOT_ALREADY_DOWN;        /*         * RJR - Should we invoke an L1 slot power-down command just in case         *       a previous shut-down failed to power-down the slot?         */        goto shutdown_unlock;    }    /* Do not allow the last 33 MHz card to be removed */    if ((bridge->b_wid_control & BRIDGE_CTRL_BUS_SPEED_MASK) ==         BRIDGE_CTRL_BUS_SPEED_33) {        for (tmp_slot = pcibr_soft->bs_first_slot;             tmp_slot <= pcibr_soft->bs_last_slot; tmp_slot++)            if (tmp_slot != slot)                if (pcibr_soft->bs_slot[tmp_slot].slot_status & SLOT_POWER_UP) {                    error++;                    break;                }        if (!error) {            error = PCI_EMPTY_33MHZ;            goto shutdown_unlock;        }    }    error = pcibr_slot_detach(pcibr_vhdl, slot, D_PCI_HOT_PLUG_DETACH,                              l1_msg, &tmp_down_resp.resp_sub_errno);    strncpy(tmp_down_resp.resp_l1_msg, l1_msg, L1_QSIZE);    tmp_down_resp.resp_l1_msg[L1_QSIZE] = '\0';    if (COPYOUT(&tmp_down_resp, reqp->req_respp.down, reqp->req_size)) {        return(EFAULT);    }    shutdown_unlock:    /* Release the bus lock */    mrunlock(pcibr_soft->bs_bus_lock);    return(error);}char *pci_space_name[] = {"NONE", 			  "ROM",			  "IO",			  "",			  "MEM",			  "MEM32",			  "MEM64",			  "CFG",			  "WIN0",			  "WIN1",			  "WIN2",			  "WIN3",			  "WIN4",			  "WIN5",			  "",			  "BAD"};voidpcibr_slot_func_info_return(pcibr_info_h pcibr_infoh,                            int func,                            pcibr_slot_func_info_resp_t funcp){    pcibr_info_t                 pcibr_info = pcibr_infoh[func];    int                          win;    funcp->resp_f_status = 0;    if (!pcibr_info) {        return;    }    funcp->resp_f_status |= FUNC_IS_VALID;    sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;    }    funcp->resp_f_bus = pcibr_info->f_bus;    funcp->resp_f_slot = pcibr_info->f_slot;    funcp->resp_f_func = pcibr_info->f_func;    sprintf(funcp->resp_f_master_name, "%v", pcibr_info->f_master);    funcp->resp_f_pops = pcibr_info->f_pops;    funcp->resp_f_efunc = pcibr_info->f_efunc;    funcp->resp_f_einfo = pcibr_info->f_einfo;    funcp->resp_f_vendor = pcibr_info->f_vendor;    funcp->resp_f_device = pcibr_info->f_device;    for(win = 0 ; win < 6 ; win++) {        funcp->resp_f_window[win].resp_w_base =                                  pcibr_info->f_window[win].w_base;        funcp->resp_f_window[win].resp_w_size =                                  pcibr_info->f_window[win].w_size;        sprintf(funcp->resp_f_window[win].resp_w_space,                "%s",                pci_space_name[pcibr_info->f_window[win].w_space]);    }    funcp->resp_f_rbase = pcibr_info->f_rbase;    funcp->resp_f_rsize = pcibr_info->f_rsize;    for (win = 0 ; win < 4; win++) {        funcp->resp_f_ibit[win] = pcibr_info->f_ibit[win];    }    funcp->resp_f_att_det_error = pcibr_info->f_att_det_error;}intpcibr_slot_info_return(pcibr_soft_t             pcibr_soft,                       pciio_slot_t             slot,                       pcibr_slot_info_resp_t   respp){    pcibr_soft_slot_t            pss;    int                          func;    bridge_t                    *bridge = pcibr_soft->bs_base;    reg_p                        b_respp;    pcibr_slot_info_resp_t       slotp;    pcibr_slot_func_info_resp_t  funcp;    slotp = kmem_zalloc(sizeof(*slotp), KM_SLEEP);    if (slotp == NULL) {        return(ENOMEM);    }    pss = &pcibr_soft->bs_slot[slot];    slotp->resp_has_host = pss->has_host;    slotp->resp_host_slot = pss->host_slot;    sprintf(slotp->resp_slot_conn_name, "%v", pss->slot_conn);    slotp->resp_slot_status = pss->slot_status;    slotp->resp_l1_bus_num = io_path_map_widget(pcibr_soft->bs_vhdl);    if (is_sys_critical_vertex(pss->slot_conn)) {        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;    }    slotp->resp_bss_ninfo = pss->bss_ninfo;    for (func = 0; func < pss->bss_ninfo; func++) {        funcp = &(slotp->resp_func[func]);        pcibr_slot_func_info_return(pss->bss_infos, func, funcp);    }    sprintf(slotp->resp_bss_devio_bssd_space, "%s",            pci_space_name[pss->bss_devio.bssd_space]);    slotp->resp_bss_devio_bssd_base = pss->bss_devio.bssd_base;    slotp->resp_bss_device = pss->bss_device;    slotp->resp_bss_pmu_uctr = pss->bss_pmu_uctr;    slotp->resp_bss_d32_uctr = pss->bss_d32_uctr;    slotp->resp_bss_d64_uctr = pss->bss_d64_uctr;    slotp->resp_bss_d64_base = pss->bss_d64_base;    slotp->resp_bss_d64_flags = pss->bss_d64_flags;    slotp->resp_bss_d32_base = pss->bss_d32_base;    slotp->resp_bss_d32_flags = pss->bss_d32_flags;    slotp->resp_bss_ext_ates_active = pss->bss_ext_ates_active;    slotp->resp_bss_cmd_pointer = pss->bss_cmd_pointer;    slotp->resp_bss_cmd_shadow = pss->bss_cmd_shadow;    slotp->resp_bs_rrb_valid = pcibr_soft->bs_rrb_valid[slot];    slotp->resp_bs_rrb_valid_v = pcibr_soft->bs_rrb_valid[slot +                                                      PCIBR_RRB_SLOT_VIRTUAL];    slotp->resp_bs_rrb_res = pcibr_soft->bs_rrb_res[slot];    if (slot & 1) {        b_respp = &bridge->b_odd_resp;    } else {        b_respp = &bridge->b_even_resp;    }    slotp->resp_b_resp = *b_respp;    slotp->resp_b_wid_control = bridge->b_wid_control;    slotp->resp_b_int_device = bridge->b_int_device;    slotp->resp_b_int_enable = bridge->b_int_enable;    slotp->resp_b_int_host = bridge->b_int_addr[slot].addr;    if (COPYOUT(slotp, respp, sizeof(*respp))) {        return(EFAULT);    }    kmem_free(slotp, sizeof(*slotp));    return(0);}/* * pcibr_slot_query *	Return information about the PCI slot maintained by the infrastructure. *	Information is requested in the request structure. * *      Information returned in the response structure: *		Slot hwgraph name *		Vendor/Device info *		Base register info *		Interrupt mapping from device pins to the bridge pins *		Devio register *		Software RRB info *		RRB register info *		Host/Gues info *		PCI Bus #,slot #, function # *		Slot provider hwgraph name *		Provider Functions *		Error handler *		DMA mapping usage counters *		DMA direct translation info *		External SSRAM workaround info */intpcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp){    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);    pciio_slot_t            slot = reqp->req_slot;    pciio_slot_t            tmp_slot;    pcibr_slot_info_resp_t  respp = reqp->req_respp.query;    int                     size = reqp->req_size;    int                     error;    /* Make sure that we are dealing with a bridge device vertex */    if (!pcibr_soft) {        return(PCI_NOT_A_BRIDGE);    }    /* Make sure that we have a valid PCI slot number or PCIIO_SLOT_NONE */    if ((!PCIBR_VALID_SLOT(slot)) && (slot != PCIIO_SLOT_NONE)) {        return(PCI_NOT_A_SLOT);    }    /* Do not allow a query of a slot in a shoehorn */    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {       return(PCI_SLOT_IN_SHOEHORN);    }    /* Return information for the requested PCI slot */    if (slot != PCIIO_SLOT_NONE) {        if (size < sizeof(*respp)) {            return(PCI_RESP_AREA_TOO_SMALL);        }

⌨️ 快捷键说明

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