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

📄 rclanmtl.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
** 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 + -