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

📄 pci.c

📁 此為philip 1362 USB DOS下的驅動程式包, 已經共測試並內含有說明文件
💻 C
字号:
#include <dos.h>
#include "pci.h"

static PCI_CFG_INFO pci_cfg_info[MAX_PCI_DEVICES];

USHORT pci_cfg_rd_w(ULONG addr, ULONG offset);
UCHAR  pci_cfg_rd_b(ULONG addr, ULONG offset);
ULONG  pci_cfg_rd_l(ULONG addr, ULONG offset);

/*void outl(ULONG uReg, ULONG uValue)
{
	outport(uReg, uValue & 0x0000FFFF);
	outport(uReg+2, (uValue & 0xFFFF0000) >> 16);
}

ULONG inl(ULONG uReg)
{
	ULONG wTmp;
	wTmp = inport(uReg);
	wTmp |= (inport(uReg+2) << 16);	//jason change to <<
	return wTmp;
}*/

static ULONG inpd(int portnum)
{
   static ULONG value ;
   asm mov dx,portnum ;
   asm lea bx,value ;
__emit__(0x66,0x50,			// push EAX
		0x66,0xED,			// in EAX,DX
		0x66,0x89,0x07,		// mov [BX],EAX
		0x66,0x58) ;		// pop EAX
		return value ;
}

static void outpd(int portnum, ULONG val)
{
   static ULONG value = 0 ;

   value = val ;
   asm mov dx,portnum ;
   asm lea bx,value ;
   __emit__(0x66,0x50,			// push EAX
	    0x66,0x8B,0x07,		// mov EAX,[BX]
	    0x66,0xEF,			// out DX,EAX
	    0x66,0x58) ;		// pop EAX
   return ;
}

PCI_CFG_INFO * get_pci_cfg_info_tbl()
{
    PCI_CFG_INFO  *pinfo;
    ULONG dnum, fnum, bus_num;
	ULONG addr, addr_f;
    ULONG tmpl;
    ULONG tmps;
    ULONG pci_found;


    pinfo = &pci_cfg_info[0];
    pci_found = 0;

    for(bus_num=0; bus_num < MAX_BUS_NUM; bus_num++)
        {
        for(dnum=0; dnum < MAX_DEV_NUM; dnum++)
            {
            addr = (bus_num << 16) | (dnum << 11);
	    for(fnum=0; fnum < MAX_FUNC_NUM; fnum++)
                {
				/*---------------------------------------------------------*/
                /* read vendor and device IDs and check them               */
                /*---------------------------------------------------------*/
				addr_f = addr | (fnum << 8);
                tmpl = pci_cfg_rd_l(addr_f, 0);
                if(tmpl == PCI_NO_DEVICE_ID)
                     break;

                pinfo->vendor_id = tmpl & 0xFFFF;
                pinfo->dev_id = (tmpl >> 16) & 0xFFFF;
                pinfo->pci_bus_num = bus_num;
                pinfo->pci_dev_num = dnum;
                pinfo->pci_func_num = fnum;

                pinfo->subsys_id = pci_cfg_rd_w(addr_f,
                                                  PCI_SUB_VENDOR_ID);

                pinfo->subsys_vendor_id = pci_cfg_rd_w(addr_f,
                                                  PCI_SUB_SYSTEM_ID);

                tmpl = pci_cfg_rd_l(addr_f, PCI_REV_ID);
                pinfo->rev_id = tmpl & 0xf;
				pinfo->class_code  = (tmpl >> 8) & 0xffffff;
                pinfo->base_class  = (tmpl >> 24) & 0xff;
                pinfo->sub_class  = (tmpl >> 16) & 0xff;

                pinfo->cfg_addr = addr_f;

                pci_found++;

                if(pci_found >= MAX_PCI_DEVICES)
                     break;

		pinfo->next = &pci_cfg_info[pci_found];
                pinfo = pinfo->next;

                tmpl = pci_cfg_rd_b(addr| (fnum  << 8), PCI_HEAD_TYPE);
                if(!(tmpl & MULTI_FUNC_BIT))
					break;
				}
			}
		}
	pinfo->next = 0;
	return &pci_cfg_info[0];
} /* get_pci_cfg_info_tbl() */


ULONG pci_cfg_read(ULONG dev_idx, ULONG offset, ULONG bytes)
{
	ULONG addr;

	addr = pci_cfg_info[dev_idx].cfg_addr;

    if(bytes == 1)
	return pci_cfg_rd_b(addr, offset);
    else if(bytes == 2)
	return pci_cfg_rd_w(addr, offset);
    else
	return pci_cfg_rd_l(addr, offset);

}


USHORT pci_cfg_rd_w(ULONG addr, ULONG offset)
{
	USHORT wtmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	wtmp = inport(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset));
	outpd(CFG_ADDR_REG, 0);

    return wtmp;
} /* pci_cfg_rd_w() */

UCHAR  pci_cfg_rd_b(ULONG addr, ULONG offset)
{
	UCHAR btmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	btmp = inportb(CFG_DATA_REG | OFFSET_TO_BYTE_INDEX(offset));
	outpd(CFG_ADDR_REG, 0);

	return btmp;

} /* pci_cfg_rd_b() */


ULONG  pci_cfg_rd_l(ULONG addr, ULONG offset)
{
	ULONG ltmp;

	addr |= CFG_SPACE_ENA;
	outpd(CFG_ADDR_REG, addr | OFFSET_TO_DW_INDEX(offset));
	ltmp =  inpd(CFG_DATA_REG);
	outpd(CFG_ADDR_REG, 0);

	return ltmp;

} /* pci_cfg_rd_l() */



BOOLEAN findPCIdev(ULONG classcode, ULONG *puBaseAddress, ULONG *puIntLevel)
{
	ULONG						uHostTotal;			/* Number of host found */
	PCI_CFG_INFO 			   *pci_tblp;
	ULONG 						dev_idx;
	ULONG						uRetVal;
	ULONG						uData;

	dev_idx = 0;
	pci_tblp = get_pci_cfg_info_tbl();

	/*************************************/
	/* No PCI device found in the system */
	/*************************************/
	if(pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff) {
		return 0;
	}

	/*************************************/
	/* Search for USB host controllers   */
	/*************************************/
	while (pci_tblp) {
		/* Is it the end of pSOS PCI device table? */
		if (pci_tblp->vendor_id == 0xffff && pci_tblp->dev_id == 0xffff)
			break;

		/* Is it a USB host controller? */
		if (pci_tblp->class_code == classcode) {
			*puBaseAddress = pci_cfg_read(dev_idx, PCI_BASE_ADDR_2, 4UL) & 0xFFFFFFF0;
			*puIntLevel = pci_cfg_read(dev_idx, PCI_INTR_LINE, 1UL);

			//config PLX PCI bridge local interrupt pin as input (added by wzw)
			outpd( (pci_cfg_read(dev_idx, PCI_BASE_ADDR_1, 4UL) & 0xFFFFFFF0) + 0x68, 0x00000900 );
			return 1;
		} /* if */

		dev_idx++;
		pci_tblp = pci_tblp->next;

	} /* while */

	return 0;

} /* findPCIdev() */

⌨️ 快捷键说明

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