📄 ixm1200hpc.c
字号:
/* ixm1200HPC.c * Host communications driver via PCI (implementation for ixm1200) * *--------------------------------------------------------------------------- * * I N T E L P R O P R I E T A R Y * * COPYRIGHT (c) 1999 BY INTEL CORPORATION. ALL RIGHTS * RESERVED. NO PART OF THIS PROGRAM OR PUBLICATION MAY * BE REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A * RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER * LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL, * MAGNETIC, OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT * THE PRIOR WRITTEN PERMISSION OF : * * INTEL CORPORATION * * 2200 MISSION COLLEGE BLVD * * SANTA CLARA, CALIFORNIA 95052-8119 * *--------------------------------------------------------------------------- * * * system: IXM1200 * subsystem: VxWorks * author: jdg, Mar 29, 00 Initial version * revisions: * $History: ixm1200HPC.c $ * * ***************** Version 1 ***************** * User: Jdguilfo Date: 5/23/01 Time: 1:29p * Created in $/V1.3/BoardSupport/VxWorks/ixm1200 * Specific version for Spectacle Island * * ***************** Version 13 ***************** * User: Jdguilfo Date: 4/16/01 Time: 10:05a * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Remove static variable that wasn't being used under NO_OS * * ***************** Version 12 ***************** * User: Jdguilfo Date: 4/13/01 Time: 5:25p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Change SI to IXM1200 & BV to PA1104, fix C0/Hyannis PCI CSR bug, up * clock speed for Hyannis, add ECC * * ***************** Version 11 ***************** * User: Jdguilfo Date: 2/15/01 Time: 2:38p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Change name from 82555 to 21555, and fix addres error * * ***************** Version 10 ***************** * User: Jdguilfo Date: 12/27/00 Time: 4:13p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * First draft of changes for Spectacle Island HPC / 82555 driver * * ***************** Version 8 ***************** * User: Jdguilfo Date: 10/20/00 Time: 2:43p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Merge bootmgr and flashutility into bootflash * * ***************** Version 7 ***************** * User: Jdguilfo Date: 8/31/00 Time: 7:10p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Added sysCpuIDGet, ID printout on boot, fix in HPC for PCI csr write HW * bug * * ***************** Version 6 ***************** * User: Jdguilfo Date: 8/11/00 Time: 5:02p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Fix problem with HPC SIO interface, which would hang on mulitple sends * * ***************** Version 5 ***************** * User: Jdguilfo Date: 8/04/00 Time: 11:54a * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Increase priority of HPC "DPC", I had the order of priorities backwards * before * * ***************** Version 4 ***************** * User: Jdguilfo Date: 7/07/00 Time: 9:58a * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Fix bug where two threads using common IRP could corrupt it * * ***************** Version 3 ***************** * User: Jdguilfo Date: 7/06/00 Time: 5:17p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Allow app to specify incomplete message, overlapped I/O returns pending * status * * ***************** Version 2 ***************** * User: Jdguilfo Date: 6/29/00 Time: 2:18p * Updated in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Allow users to cancel read or write transactions separately * * ***************** Version 1 ***************** * User: Jdguilfo Date: 6/29/00 Time: 11:22a * Created in $/dev_1200/BoardSupport/VxWorks/IXP1200EB * Add HPC, merge VxWorks into one makefile * * --------------------------------------------------------------------- */#include "ixm1200HPC.h"#include "config.h"#include <string.h>#include <intLib.h>#include <dllLib.h>#include <taskLib.h>#include <pciIomapLib.h>#ifdef TEST#include <stdio.h>#endifHPC_CONFIG_STATUS* const configStatus = (HPC_CONFIG_STATUS*) (SDRAM_PHYS_BASE + RESERVED_LOW_MEM - sizeof(HPC_CONFIG_STATUS));HPC_BUFFER* const dataBuffer = (HPC_BUFFER*) (SDRAM_PHYS_BASE + RESERVED_LOW_MEM - ((NUM_SHARED_DATA_BUFFERS) * sizeof(HPC_BUFFER)) - sizeof(HPC_CONFIG_STATUS));static HPC_GLOBAL_STATE hpcGlobalState;static UINT32 doorbellAddr;#define SET(var, mask) ((var) |= (mask))#define CLEAR(var, mask) ((var) &= ~(mask))/* * BEGIN QUEUE FUNCTIONS * * NOTE: These are not protected against multiple accesses. It is * assumed that a higher layer provides protection. */static voidHPC_QUEUE_INIT(HPC_QUEUE *queue){ queue->head = queue->tail = NULL;}static voidHPC_QUEUE_PUSH(HPC_QUEUE *queue, HPC_IRP *irp){ if (queue->tail != NULL) { queue->tail->next = irp; queue->tail = irp; irp->next = NULL; } else { queue->head = queue->tail = irp; irp->next = NULL; }}#define HPC_QUEUE_PEEK(queue) ((queue)->head)#define HPC_QUEUE_IS_EMPTY(queue) (HPC_QUEUE_PEEK(queue) == NULL)static HPC_IRP*HPC_QUEUE_POP(HPC_QUEUE *queue){ HPC_IRP* irp; if (queue->head) { irp = queue->head; queue->head = irp->next; if (queue->head == NULL) queue->tail = NULL; return irp; } else { return NULL; }}/* * BEGIN main functions *//* return generateInterrupt */static BOOLprocRcvBuffer(HPC_BUFFER_INFO *binfo, int index){ BOOL generateInterrupt = FALSE; HPC_IRP *irp; unsigned int size, size2; unsigned int sizeValid; unsigned int incomplete; switch (binfo->interface) { case HPC_W32: /* while buffer is available and shared buffer not empty */ while ((NULL != (irp = HPC_QUEUE_PEEK(&binfo->queue))) && (0 != (sizeValid = configStatus->sizeValid[index]))) { incomplete = sizeValid & BUFFER_INCOMPLETE_MASK; CLEAR(sizeValid, BUFFER_INCOMPLETE_MASK); size = sizeValid - binfo->bytesUsed;; size2 = irp->bSize - irp->bUsed; if (size > size2) size = size2; bcopy(binfo->buff + binfo->bytesUsed, /* src */ irp->buff + irp->bUsed, /* dst */ size); irp->bUsed += size; binfo->bytesUsed += size; /* * If message is complete or we are out of user buffer, * complete the I/O */ if ((!incomplete) || (irp->bUsed == irp->bSize)) { HPC_QUEUE_POP(&binfo->queue); irp->returnStatus = HPC_OK; if (incomplete || (binfo->bytesUsed < sizeValid)) { switch (binfo->ibMode) { case HPC_IB_RC: irp->returnStatus = HPC_INCOMPLETE; break; case HPC_IB_SIZE: irp->bUsed |= HPC_IB_BIT; break; case HPC_IB_NONE: break; } /* end switch ibMode */ } /* end if we need to flag this buffer as incomplete */ semGive(irp->done); } if (binfo->bytesUsed == sizeValid) { /* buffer is empty */ configStatus->sizeValid[index] = 0; binfo->bytesUsed = 0; if (configStatus->NTIsWaitingMask & binfo->waitingMask) generateInterrupt = TRUE; break; } } /* end while */ if (HPC_QUEUE_IS_EMPTY(&binfo->queue)) { CLEAR(configStatus->IXM1200IsWaitingMask, binfo->waitingMask); } break; case HPC_SIO: if (0 != (sizeValid = configStatus->sizeValid[index])) { if (binfo->ibMode != HPC_IB_SIZE) sizeValid &= (~BUFFER_INCOMPLETE_MASK); (*binfo->putRcvChars)(binfo->buff, sizeValid, binfo->putData); configStatus->sizeValid[index] = 0; if (configStatus->NTIsWaitingMask & binfo->waitingMask) generateInterrupt = TRUE; } break; case HPC_NONE: break; } /* end switch interface */ return generateInterrupt;}static BOOLprocTxBuffer(HPC_BUFFER_INFO *binfo, int index){ BOOL generateInterrupt = FALSE; HPC_IRP *irp; unsigned int size; unsigned char *buff; switch (binfo->interface) { case HPC_W32: if ((0 == configStatus->sizeValid[index]) && (NULL != (irp = HPC_QUEUE_PEEK(&binfo->queue)))) { if (irp->bUsed == irp->bSize) { /* buffer is empty, so return it to app */ HPC_QUEUE_POP(&binfo->queue); irp->returnStatus = HPC_OK; semGive(irp->done); irp = HPC_QUEUE_PEEK(&binfo->queue); if (irp == NULL) { /* queue is empty */ CLEAR(configStatus->IXM1200IsWaitingMask, binfo->waitingMask); break; } } /* end if irp is used up */ size = irp->bSize - irp->bUsed; if (size > SHARED_DATA_BUFFER_SIZE) size = SHARED_DATA_BUFFER_SIZE; bcopy(irp->buff + irp->bUsed, /* src */ binfo->buff, /* dst */ size); irp->bUsed += size; if (irp->incomplete || (irp->bUsed < irp->bSize)) size |= BUFFER_INCOMPLETE_MASK; configStatus->sizeValid[index] = size; if (configStatus->NTIsWaitingMask & binfo->waitingMask) generateInterrupt = TRUE; } /* end if ready and processable */ break; case HPC_SIO: if ((0 == configStatus->sizeValid[index]) && (binfo->txWaiting)) { if (binfo->irp.bSize == binfo->irp.bUsed) { /* current buffer is empty, get new buffer */ /* * We have to handle txWaiting carefully. We set it to false * before calling getTxChars, and then conditionally set it * to true afterwards. This is to handle the case where the * start routine is called between the time when getTxChars * returns 0, and we update the txWaiting flag. */ binfo->txWaiting = FALSE; size = (*binfo->getTxChars)(&buff, binfo->getData); if (size == 0) { /* no more data */ CLEAR(configStatus->IXM1200IsWaitingMask, binfo->waitingMask); break; } else { binfo->txWaiting = TRUE; SET(configStatus->IXM1200IsWaitingMask, binfo->waitingMask); } if (size & HPC_IB_BIT) { CLEAR(size, HPC_IB_BIT); binfo->irp.incomplete = 1; } else { binfo->irp.incomplete = 0; } binfo->irp.buff = buff; binfo->irp.bSize = size; binfo->irp.bUsed = 0; } size = binfo->irp.bSize - binfo->irp.bUsed; if (size > SHARED_DATA_BUFFER_SIZE) size = SHARED_DATA_BUFFER_SIZE; bcopy(binfo->irp.buff + binfo->irp.bUsed, /* src */ binfo->buff, /* dst */ size); binfo->irp.bUsed += size; if (binfo->irp.incomplete || (binfo->irp.bUsed < binfo->irp.bSize)) size |= BUFFER_INCOMPLETE_MASK; configStatus->sizeValid[index] = size; if (configStatus->NTIsWaitingMask & binfo->waitingMask) generateInterrupt = TRUE; } /* end if ready and IX1200IsWaiting */ break; case HPC_NONE: break; } /* end switch interface */ return generateInterrupt;}static voidprocBuffers(HPC_GLOBAL_STATE *state){ int i; BOOL generateInterrupt = FALSE; for (i=0; i<NUM_SHARED_DATA_BUFFERS; i+=2) { if (procRcvBuffer(&state->bufferInfo[i+HPC_RX_OFFSET], i+HPC_RX_OFFSET)) { generateInterrupt = TRUE; } if (procTxBuffer(&state->bufferInfo[i+HPC_TX_OFFSET], i+HPC_TX_OFFSET)) { generateInterrupt = TRUE; } } if (generateInterrupt) {#if defined(IXM1200) REG_WRITE16(doorbellAddr, DOORBELL_SEND_MASK);#else IXM1200_PCI_REG_WRITE(IXM1200_DOORBELL, DOORBELL_SEND_MASK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -