📄 rclanmtl.c
字号:
** ResourceFlags indicates whether to return buffer resource explicitly** to host or keep and reuse.** CallbackFunction (if not NULL) is the function to be called when ** shutdown is complete.** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when** shutdown is done (if not NULL).**** =========================================================================*/RC_RETURN RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction){ volatile PU32 pMsg; U32 off; PPAB pPab; int i; long timeout = 0; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; pPab->pCallbackFunc = CallbackFunction; pMsg = (PU32)(pPab->pPci45LinBaseAddr + off); /* setup message */ pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_LAN_SHUTDOWN << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = DEFAULT_RECV_INIT_CONTEXT; pMsg[3] = ResourceFlags << 16; /* resource flags */ pPab->p_atu->InQueue = off; /* send it to the I2O device */ if (CallbackFunction == (PFNCALLBACK)NULL) { /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc or until timer goes off */ while (pPab->pCallbackFunc == (PFNCALLBACK)NULL) { RCProcI2OMsgQ(AdapterID); for (i = 0; i < 100000; i++) /* please don't hog the bus!!! */ ; timeout++; if (timeout > 10000) { printk("RCShutdownLANCard(): timeout\n"); break; } } if (ReturnAddr != (PU32)NULL) *ReturnAddr = (U32)pPab->pCallbackFunc; } return RC_RTN_NO_ERROR ;}/*** =========================================================================** RCSetRavlinIPandMask()**** Set the Ravlin 45/PCI cards IP address and network mask.**** IP address and mask must be in network byte order.** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be** 0x04030201 and 0x00FFFFFF on a little endian machine.**** =========================================================================*/RC_RETURNRCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask){ volatile PU32 pMsg; U32 off; PPAB pPab; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; pMsg = (PU32)(pPab->pPci45LinBaseAddr + off); /* setup private message */ pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = 0; /* initiator context */ pMsg[3] = 0x219; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK; pMsg[5] = ipAddr; pMsg[6] = netMask; pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR ;}/*** =========================================================================** RCGetRavlinIPandMask()**** get the IP address and MASK from the card** ** =========================================================================*/RC_RETURNRCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, PFNWAITCALLBACK WaitCallback){ unsigned i, timeout; U32 off; PU32 pMsg, p32; PPAB pPab; PATU p_atu; #ifdef DEBUG kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);#endif /* DEBUG */ pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; p_atu = pPab->p_atu; off = p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); *p32 = 0xFFFFFFFF; pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);#ifdef DEBUG kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);#endif /* DEBUG */ /* setup private message */ pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = 0; /* initiator context */ pMsg[3] = 0x218; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK; pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); p_atu->InQueue = off; /* send it to the I2O device */#ifdef DEBUG kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);#endif /* DEBUG */ /* wait for the rcpci45 board to update the info */ timeout = 100000; while (0xffffffff == *p32) { if (WaitCallback) (*WaitCallback)(); for (i = 0; i < 1000; i++) ; if (!timeout--) {#ifdef DEBUG kprintf("RCGetRavlinIPandMask: Timeout\n");#endif /* DEBUG */ return RC_RTN_MSG_REPLY_TIMEOUT; } }#ifdef DEBUG kprintf("RCGetRavlinIPandMask: after time out\n", \ "p32[0] (IpAddr) 0x%08.8ulx, p32[1] (IPmask) 0x%08.8ulx\n", p32[0], p32[1]);#endif /* DEBUG */ /* send IP and mask to user's space */ *pIpAddr = p32[0]; *pNetMask = p32[1];#ifdef DEBUG kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);#endif /* DEBUG */ return RC_RTN_NO_ERROR;}/* ** /////////////////////////////////////////////////////////////////////////** /////////////////////////////////////////////////////////////////////////**** local functions**** /////////////////////////////////////////////////////////////////////////** /////////////////////////////////////////////////////////////////////////*//*** =========================================================================** SendI2OOutboundQInitMsg()**** =========================================================================*/static int SendI2OOutboundQInitMsg(PPAB pPab){ U32 msgOffset, timeout, phyOutQFrames, i; volatile PU32 pMsg; volatile PU32 p32; msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) {#ifdef DEBUG kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");#endif /* DEBUG */ return RC_RTN_FREE_Q_EMPTY; } /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);#ifdef DEBUG kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);#endif /* DEBUG */ pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6; pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID; pMsg[2] = DEFAULT_RECV_INIT_CONTEXT; pMsg[3] = 0x106; /* transaction context */ pMsg[4] = 4096; /* Host page frame size */ pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80; /* outbound msg frame size and Initcode */ pMsg[6] = 0xD0000004; /* simple sgl element LE, EOB */ /* phys address to return status - area right after PAB */ pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); /* virual pointer to return buffer - clear first two dwords */ p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); p32[0] = 0; /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; /* wait for response */ timeout = 100000; while(1) { for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ ; if (p32[0]) break; if (!timeout--) {#ifdef DEBUG kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");#endif /* DEBUG */ return RC_RTN_NO_I2O_STATUS; } } timeout = 100000; while(1) { for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ ; if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE) break; if (!timeout--) {#ifdef DEBUG kprintf("Timeout wait for InitOutQ Complete status from IOP\n");#endif /* DEBUG */ return RC_RTN_NO_I2O_STATUS; } } /* load PCI outbound free Q with MF physical addresses */ phyOutQFrames = pPab->outMsgBlockPhyAddr; for (i = 0; i < NMBR_MSG_FRAMES; i++) { pPab->p_atu->OutQueue = phyOutQFrames; phyOutQFrames += MSG_FRAME_SIZE; } return RC_RTN_NO_ERROR;}/*** =========================================================================** GetI2OStatus()**** Send StatusGet Msg, wait for results return directly to buffer.**** =========================================================================*/static int GetI2OStatus(PPAB pPab){ U32 msgOffset, timeout; PU32 pMsg; volatile PU32 p32; msgOffset = pPab->p_atu->InQueue; #ifdef DEBUG printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset);#endif /* DEBUG */ if (msgOffset == 0xFFFFFFFF) {#ifdef DEBUG kprintf("GetI2OStatus(): Inbound Free Q empty!\n");#endif /* DEBUG */ return RC_RTN_FREE_Q_EMPTY; } /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset); pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_EXEC_STATUS_GET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID; pMsg[2] = 0; /* universal context */ pMsg[3] = 0; /* universal context */ pMsg[4] = 0; /* universal context */ pMsg[5] = 0; /* universal context */ /* phys address to return status - area right after PAB */ pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); pMsg[7] = 0; pMsg[8] = 88; /* return 88 bytes */ /* virual pointer to return buffer - clear first two dwords */ p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); p32[0] = 0; p32[1] = 0;#ifdef DEBUG kprintf("GetI2OStatus - pMsg:0x%08.8ulx, msgOffset:0x%08.8ulx, [1]:0x%08.8ulx, [6]:0x%08.8ulx\n", pMsg, msgOffset, pMsg[1], pMsg[6]);#endif /* DEBUG */ /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; #ifdef DEBUG kprintf("Return status to p32 = 0x%08.8ulx\n", p32);#endif /* DEBUG */ /* wait for response */ timeout = 1000000; while(1) { int i; for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ ; if (p32[0] && p32[1]) break; if (!timeout--) {#ifdef DEBUG kprintf("Timeout waiting for status from IOP\n"); kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]); kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]); kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);#endif /* DEBUG */ return RC_RTN_NO_I2O_STATUS; } } #ifdef DEBUG kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]); kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]); kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);#endif /* DEBUG */ /* get IOP state */ pPab->IOPState = ((volatile PU8)p32)[10]; pPab->InboundMFrameSize = ((volatile PU16)p32)[6]; #ifdef DEBUG kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n", pPab->IOPState, pPab->InboundMFrameSize);#endif /* DEBUG */ return RC_RTN_NO_ERROR;}/*** =========================================================================** SendEnableSysMsg()****** =========================================================================*/static in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -