📄 sysel3c90xend.c
字号:
/*
* get memory base address and IO base address
* Note: we read it in again, even if we just wrote it out because the
* device can change what we wrote
*/
pciConfigInLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_0, &iobaseCsr);
pciConfigInLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_1, &membaseCsr);
pciConfigInByte (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_DEV_INT_LINE, &irq);
/*
* we want to make sure the device implements memory BARs
* first, we disable PCI memory decode by the device
*/
pciConfigInWord (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_COMMAND, &tmpWord);
pciConfigOutWord (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_COMMAND, (tmpWord & (~PCI_CMD_MEM_ENABLE)));
/* Read and save the BAR */
pciConfigInLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_1, &tmpLong);
/* find out the memory space requirements of this BAR */
pciConfigOutLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_1, 0xffffffff);
pciConfigInLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_1, &tmpLong2);
if (tmpLong2 != 0)
{
/* this is a legitimate memory BAR */
pciConfigOutLong (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_BASE_ADDRESS_1, tmpLong);
}
else
{
/* the driver will use IO-mapped BAR */
membaseCsr = NONE;
}
/* re-enable PCI memory decode by the device */
pciConfigOutWord (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_COMMAND, (tmpWord));
/*
* mask off registers. IO base needs to be masked off because bit0
* will always be set to 1
*/
iobaseCsr &= PCI_IOBASE_MASK;
if (membaseCsr != NONE)
{
membaseCsr &= PCI_MEMBASE_MASK;
}
/* over write the resource table with values read */
pEl3c90xActualRsrc [unit]->membaseCsr = membaseCsr;
pEl3c90xActualRsrc [unit]->iobaseCsr = iobaseCsr;
pEl3c90xActualRsrc [unit]->irq = irq;
pEl3c90xActualRsrc [unit]->irqvec = IVEC_TO_INUM(irq);
/* enable mapped memory and IO addresses */
pciConfigOutWord (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_COMMAND, PCI_CMD_IO_ENABLE |
PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE);
/* disable sleep mode */
pciConfigOutWord (pEl3c90xActualRsrc [unit]->pciBus,
pEl3c90xActualRsrc [unit]->pciDevice,
pEl3c90xActualRsrc [unit]->pciFunc,
PCI_CFG_MODE,
SLEEP_MODE_DIS);
}
return (OK);
}
/*******************************************************************************
*
* sysEl3c90xIntEnable - enable 3c90x interrupts
*
* This routine enables 3c90x interrupts. This may involve operations on
* interrupt control hardware.
*
* RETURNS: OK or ERROR for invalid arguments.
*/
STATUS sysEl3c90xIntEnable
(
int level /* level number */
)
{
return (intEnable (level));
}
/*******************************************************************************
*
* sysEl3c90xIntDisable - disable 3c90x interrupts
*
* This routine disables 3c90x interrupts. This may involve operations on
* interrupt control hardware.
*
* RETURNS: OK or ERROR for invalid arguments.
*/
STATUS sysEl3c90xIntDisable
(
int level /* level number */
)
{
return (intDisable (level));
}
/******************************************************************************
*
* sysEl3c90xEndLoad - load an istance of the el3c90xEnd driver
*
* This routine loads the el3c90xEnd driver with the parameters specified by
* the resource table for the device, and some default values.
*
* The END device load string formed by this routine is in the following
* following format.
* <devMemAddr>:<devIoAddr>:<pciMemBase>:<vecnum>:<intLvl>:<memAdrs>
* :<memSize>:<memWidth>:<flags>:<buffMultiplier>
*
* .IP <devMemAddr>
* Device register base memory address
* .IP <devIoAddr>
* Device register base IO address
* .IP <pciMemBase>
* Base address of PCI memory space
* .IP <vecNum>
* Interrupt vector number.
* .IP <intLvl>
* Interrupt level.
* .IP <memAdrs>
* Memory pool address or NONE.
* .IP <memSize>
* Memory pool size or zero.
* .IP <memWidth>
* Memory system size, 1, 2, or 4 bytes (optional).
* .IP <flags>
* Device specific flags.
* .IP <buffMultiplier>
* Buffer Multiplier or NONE. If NONE is specified, it defaults to 2
*
* This routine only loads and initializes instance zero of the device.
* If the user wishes to use more than one el3c90x devices, this routine
* should be changed.
*
* RETURNS: pointer to END object or NULL.
*
* SEE ALSO: el3c90xEndLoad()
*/
END_OBJ * sysEl3c90xEndLoad
(
char * pParamStr, /* ptr to initialization parameter string */
void * unused /* unused optional argument */
)
{
/*
* The el3c90xEnd driver END_LOAD_STRING should be:
* <devMemAddr>:<devIoAddr>:<pciMemBase>:<vecnum>:<intLvl>:<memAdrs>
* :<memSize>:<memWidth>:<flags>:<buffMultiplier>
* Note that unit string is prepended by the mux, so we
* don't put it here.
*/
char * pStr = NULL;
char paramStr [200];
static char el3c90xParamTemplate [] =
"0x%x:0x%x:0x%x:%d:%d:-1:-1:-1:0x%x:0x%x";
END_OBJ * pEnd;
if (strlen (pParamStr) == 0)
{
/*
* muxDevLoad() calls us twice. If the string is
* zero length, then this is the first time through
* this routine.
*/
pEnd = (END_OBJ *) el3c90xEndLoad (pParamStr);
}
else
{
/*
* On the second pass through here, we actually create
* the initialization parameter string on the fly.
* Note that we will be handed our unit number on the
* second pass and we need to preserve that information.
* So we use the unit number handed from the input string.
*/
pStr = strcpy (paramStr, pParamStr);
/* Now, we get to the end of the string */
pStr += strlen (paramStr);
/* finish off the initialization parameter string */
sprintf (pStr, el3c90xParamTemplate,
(UINT) PCI_MEMIO2LOCAL
((UINT) pEl3c90xActualRsrc [0]->membaseCsr),
/* device Io base */
(UINT) PCI_IO2LOCAL
((UINT) pEl3c90xActualRsrc [0]->iobaseCsr),
(UINT) PCI_SLV_MEM_LOCAL, /* pciMemBase */
pEl3c90xActualRsrc [0]->irqvec,
pEl3c90xActualRsrc [0]->irq,
EL_3C90X_END_FLAGS,
EL_3C90X_BUFF_MTPLR
);
if ((pEnd = (END_OBJ *) el3c90xEndLoad (paramStr)) == (END_OBJ *)NULL)
{
logMsg ("Error: el3c90xEndLoad failed to load driver\n",
0, 0, 0, 0, 0, 0);
}
}
return (pEnd);
}
#endif /* INCLUDE_EL_3C90X_END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -