#include #include #include #include #include #include #include #include #include #include #include #include #include IMPORT SL_LIST vxbPciCtrlList; IMPORT BOOL vxbPciCtrlListInited;IMPORT SL_LIST vxbPciCtrlList; IMPORT BOOL vxbPciCtrlListInited; /******************************************************************************* * * vxbPciConfigInByte - read one byte from the PCI configuration space * * This routine reads one byte from the PCI configuration space * * RETURNS: OK, or ERROR if this library is not initialized * * ERRNO * */ LOCAL STATUS vxbPciConfigInByte ( VXB_DEV_ID busCtrlID, UINT8 busNo, /* bus number */ UINT8 deviceNo, /* device number */ UINT8 funcNo, /* function number */ int offset, /* offset into the configuration space */ UINT8 * pData /* data read from the offset */ ) { PCI_HARDWARE phard; phard.pciBus = busNo; phard.pciDev = deviceNo; phard.pciFunc = funcNo; return VXB_PCI_CFG_READ(busCtrlID, &phard, offset, 1, pData); } LOCAL STATUS vxbPciConfigInWord ( VXB_DEV_ID busCtrlID, UINT8 busNo, /* bus number */ UINT8 deviceNo, /* device number */ UINT8 funcNo, /* function number */ int offset, /* offset into the configuration space */ UINT16 * pData /* data read from the offset */ ) { PCI_HARDWARE phard; phard.pciBus = busNo; phard.pciDev = deviceNo; phard.pciFunc = funcNo; return VXB_PCI_CFG_READ(busCtrlID, &phard, offset, 2, pData); } LOCAL STATUS vxbPciConfigInLong ( VXB_DEV_ID busCtrlID, UINT8 busNo, /* bus number */ UINT8 deviceNo, /* device number */ UINT8 funcNo, /* function number */ int offset, /* offset into the configuration space */ UINT32 * pData /* data read from the offset */ ) { PCI_HARDWARE phard; phard.pciBus = busNo; phard.pciDev = deviceNo; phard.pciFunc = funcNo; return VXB_PCI_CFG_READ(busCtrlID, &phard, offset, 4, pData); } LOCAL STATUS vxbPciConfigOutLong ( VXB_DEV_ID busCtrlID, UINT8 busNo, /* bus number */ UINT8 deviceNo, /* device number */ UINT8 funcNo, /* function number */ int offset, /* offset into the configuration space */ UINT32 data /* data write at the offset */ ) { PCI_HARDWARE phard; phard.pciBus = busNo; phard.pciDev = deviceNo; phard.pciFunc = funcNo; return VXB_PCI_CFG_WRITE(busCtrlID, &phard, offset, 4, data); } typedef struct _aiopcieserialtableentry { UINT16 deviceId; UINT8 ports; UINT8 is4thPortAt0x38; } aiopcieserialtableentry; LOCAL const aiopcieserialtableentry tableOfPericomBoardsByACCES[] = { { 0x1093, 2, 0 }, /* mPCIe-COM232-2 */ { 0x109B, 4, 1 }, /* mPCIe-COM232-4 */ { 0x1053, 2, 0 }, /* mPCIe-COM-2S */ { 0x10D3, 2, 0 }, /* mPCIe-COM-2SM */ { 0x105E, 4, 1 }, /* mPCIe-COM-4S */ { 0x10DC, 4, 1 }, /* mPCIe-COM-4SM */ { 0x1191, 2, 0 }, /* mPCIe-ICM232-2 */ { 0x1199, 4, 1 }, /* mPCIe-ICM232-4 */ { 0x1110, 2, 0 }, /* mPCIe-ICM422-2 */ { 0x1118, 4, 1 }, /* mPCIe-ICM422-4 */ { 0x1111, 2, 0 }, /* mPCIe-ICM485-2 */ { 0x1119, 4, 1 }, /* mPCIe-ICM485-4 */ { 0x1109, 1, 0 }, /* mPCIe-ICM422-1 */ { 0x1108, 1, 0 }, /* mPCIe-ICM485-1 */ { 0x1091, 2, 0 }, /* PCIe-COM232-2DB, PCIe-COM232-2RJ */ { 0x1099, 4, 1 }, /* PCIe-COM232-4DB, PCIe-COM232-4RJ */ { 0x1051, 2, 0 }, /* PCIe-COM-2SDB, PCIe-COM-2SRJ */ // should be 2,0 { 0x10D1, 2, 0 }, /* PCIe-COM-2SMDB, PCIe-COM-2SMRJ */ { 0x105C, 4, 1 }, /* PCIe-COM-4SDB, PCIe-COM-4SRJ */ { 0x10DA, 4, 1 }, /* PCIe-COM-4SMDB, PCIe-COM-4SMRJ */ { 0x1098, 4, 0 }, /* PCIe-COM232-4 4-port, based on 8-port chip... */ { 0x10A9, 8, 0 }, /* PCIe-COM232-8 */ { 0x105A, 4, 0 }, /* PCIe-COM422-4 4-port, based on 8-port chip... */ { 0x106A, 8, 0 }, /* PCIe-COM422-8 */ { 0x105B, 4, 0 }, /* PCIe-COM485-4 4-port, based on 8-port chip... */ { 0x106B, 8, 0 }, /* PCIe-COM485-8 */ { 0x10D9, 4, 0 }, /* PCIe-COM-4SM 4-port, based on 8-port chip... */ { 0x10E9, 8, 0 }, /* PCIe-COM-8SM */ { 0x1190, 2, 0 }, /* PCIe-ICM232-2 */ { 0x1198, 4, 1 }, /* PCIe-ICM232-4 */ { 0x1152, 2, 0 }, /* PCIe-ICM-2S */ { 0x115A, 4, 1 }, /* PCIe-ICM-4S */ { 0x11D0, 2, 0 }, /* PCIe-ICM-2SM */ { 0x11D8, 4, 1 }, /* PCIe-ICM-4SM */ {0} /* Empty terminated list */ }; LOCAL BOOL configValid(char * config, UINT8 n) { UINT8 i=0; if (n != strlen(config)) { printf("!!wrong number of characters passed for configuration string." "\r\n!!Must match # ports.\r\n"); return FALSE; } for (i=0; ipDev; pNode = SLL_NEXT(pNode); */ busCtrlID = 0xffff8000003c16d0; { /* mark 256 buses by 8*32 = 256 bits */ bridgeFound[0] = 0x1; /* bus 0 always available */ if(busCtrlID == NULL) return; for (busNo = 0; busNo <= PCI_MAX_BUS; busNo++) { if (!(bridgeFound[busNo/PCI_MAX_DEV] & (1 << busNo%PCI_MAX_DEV))) continue; for (deviceNo=0; deviceNo < PCI_MAX_DEV; deviceNo++) { for (func = 0; func < 8; func++) { /* avoid a special bus cycle */ vendorId = 0xffff; if ((deviceNo == 0x1f) && (func == 0x07)) continue; (void) vxbPciConfigInWord (busCtrlID, (UINT8)busNo, deviceNo, func, PCI_CFG_VENDOR_ID, &vendorId); if ((vendorId == PCI_CONFIG_ABSENT_F) || (vendorId == PCI_CONFIG_ABSENT_0) ) { if (func == 0) { break; /* non-existent device, goto next device */ } else continue; /* function empty, try the next function */ } /* show data about ACCES Pericom-UART PCIe cards */ if (vendorId == 0x494F) { (void) vxbPciConfigInWord (busCtrlID, (UINT8)busNo, deviceNo, func, PCI_CFG_DEVICE_ID, &deviceId); for (itemInList = 0; 0 != tableOfPericomBoardsByACCES[itemInList].deviceId; ++itemInList) if (deviceId == tableOfPericomBoardsByACCES[itemInList].deviceId) { printf("detected card on bus# %d: 0x494F:%04x, %d port%c\r\n", busNo, deviceId, tableOfPericomBoardsByACCES[itemInList].ports, tableOfPericomBoardsByACCES[itemInList].ports==1?' ':'s'); /* if an appropriate card was specified, show configuration options */ if (busNo == busToConfigure) { // confirm config string is valid, show instructions if not if (!configValid(config, tableOfPericomBoardsByACCES[itemInList].ports)) { switch(tableOfPericomBoardsByACCES[itemInList].ports) { case 1: printf(" a single character, `0`, `1`, or `F`, to configure the only port (port A)\r\n"); break; case 2: printf(" two characters, port A config then port B; `AB`.\r\n ex:The string `01` sets port A to RS232 and B to RS422.\r\n"); break; case 4: printf(" four characters, port A config first; `ABCD`.\r\n ex:The string `01F1` sets port A to RS232, B and D to RS422, and C to RS485\r\n"); break; case 8: printf(" eight characters, port A config first; `ABCDEFGH`.\r\n ex:The string `01F1000F` sets ports A, E, F, and G to RS232,\r\n B and D to RS422, and C and H to RS485\r\n"); break; default:printf("!!!!end of the world!!!!\r\n");break; // should be impossible } continue; } for (portIndex = 0; portIndex < tableOfPericomBoardsByACCES[itemInList].ports; ++portIndex) { if ((portIndex == 3) && (tableOfPericomBoardsByACCES[itemInList].is4thPortAt0x38)) portShift = 28; else portShift = portIndex * 4 ; if (portIndex == 4) printf("\r\n"); switch(config[portIndex]) { case '0': nybbleForProtocol = 0; printf(" port %c=RS232",portIndex+'A'); break; case '1': nybbleForProtocol = 1; printf(" port %c=RS422",portIndex+'A'); break; case 'F':case 'f': nybbleForProtocol = 0xF; printf(" port %c=RS485",portIndex+'A'); break; } protocolRegisterValue |= nybbleForProtocol << portShift; } printf("\r\n"); printf("Protocol DWORD (to be written to card's register)= %08lX\r\n", protocolRegisterValue); /* write protocolRegisterValue to card at +0xB4 */ vxbPciConfigInLong(busCtrlID, (UINT8)busNo, deviceNo, func, 0xB4, &oldReg); printf("Value of protocol register before write: %08lX\r\n", oldReg); vxbPciConfigOutLong(busCtrlID, (UINT8)busNo, deviceNo, func, 0xB4, protocolRegisterValue); printf("wrote %08lX to register at +0xB4\r\n", protocolRegisterValue); vxbPciConfigInLong(busCtrlID, (UINT8)busNo, deviceNo, func, 0xB4, &oldReg); printf("Value of protocol register after write: %08lX\r\n", oldReg); if (oldReg == protocolRegisterValue) printf("SUCCESS\r\n"); else printf("FAILURE\r\n"); } } } (void) vxbPciConfigInByte (busCtrlID, (UINT8)busNo, deviceNo, func, PCI_CFG_HEADER_TYPE, &headerType); if ((headerType & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE || (headerType & PCI_HEADER_TYPE_MASK) == PCI_HEADER_PCI_CARDBUS) { (void) vxbPciConfigInByte (busCtrlID, (UINT8)busNo, deviceNo, func, PCI_CFG_SECONDARY_BUS, &secBus); if(secBus != 0) { bridgeFound[secBus/PCI_MAX_DEV] |= 1<