|
@@ -150,12 +150,14 @@ static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
|
|
|
AIOP_INTR_BIT_3
|
|
|
};
|
|
|
|
|
|
+#ifdef CONFIG_PCI
|
|
|
static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
|
|
|
UPCI_AIOP_INTR_BIT_0,
|
|
|
UPCI_AIOP_INTR_BIT_1,
|
|
|
UPCI_AIOP_INTR_BIT_2,
|
|
|
UPCI_AIOP_INTR_BIT_3
|
|
|
};
|
|
|
+#endif
|
|
|
|
|
|
static Byte_t RData[RDATASIZE] = {
|
|
|
0x00, 0x09, 0xf6, 0x82,
|
|
@@ -227,7 +229,6 @@ static unsigned long nextLineNumber;
|
|
|
static int __init init_ISA(int i);
|
|
|
static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
|
|
|
static void rp_flush_buffer(struct tty_struct *tty);
|
|
|
-static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
|
|
|
static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
|
|
|
static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
|
|
|
static void rp_start(struct tty_struct *tty);
|
|
@@ -241,11 +242,6 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
|
|
|
static void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
|
|
|
static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
|
|
|
static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
|
|
|
-static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
|
|
|
- ByteIO_t * AiopIOList, int AiopIOListSize,
|
|
|
- WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
|
|
|
- int PeriodicOnly, int altChanRingIndicator,
|
|
|
- int UPCIRingInd);
|
|
|
static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
|
|
|
ByteIO_t * AiopIOList, int AiopIOListSize,
|
|
|
int IRQNum, Byte_t Frequency, int PeriodicOnly);
|
|
@@ -1775,6 +1771,145 @@ static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = {
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
|
|
|
|
|
|
+/* Resets the speaker controller on RocketModem II and III devices */
|
|
|
+static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
|
|
|
+{
|
|
|
+ ByteIO_t addr;
|
|
|
+
|
|
|
+ /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
|
|
|
+ if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
|
|
|
+ addr = CtlP->AiopIO[0] + 0x4F;
|
|
|
+ sOutB(addr, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
|
|
|
+ if ((model == MODEL_UPCI_RM3_8PORT)
|
|
|
+ || (model == MODEL_UPCI_RM3_4PORT)) {
|
|
|
+ addr = CtlP->AiopIO[0] + 0x88;
|
|
|
+ sOutB(addr, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/***************************************************************************
|
|
|
+Function: sPCIInitController
|
|
|
+Purpose: Initialization of controller global registers and controller
|
|
|
+ structure.
|
|
|
+Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
|
|
|
+ IRQNum,Frequency,PeriodicOnly)
|
|
|
+ CONTROLLER_T *CtlP; Ptr to controller structure
|
|
|
+ int CtlNum; Controller number
|
|
|
+ ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
|
|
|
+ This list must be in the order the AIOPs will be found on the
|
|
|
+ controller. Once an AIOP in the list is not found, it is
|
|
|
+ assumed that there are no more AIOPs on the controller.
|
|
|
+ int AiopIOListSize; Number of addresses in AiopIOList
|
|
|
+ int IRQNum; Interrupt Request number. Can be any of the following:
|
|
|
+ 0: Disable global interrupts
|
|
|
+ 3: IRQ 3
|
|
|
+ 4: IRQ 4
|
|
|
+ 5: IRQ 5
|
|
|
+ 9: IRQ 9
|
|
|
+ 10: IRQ 10
|
|
|
+ 11: IRQ 11
|
|
|
+ 12: IRQ 12
|
|
|
+ 15: IRQ 15
|
|
|
+ Byte_t Frequency: A flag identifying the frequency
|
|
|
+ of the periodic interrupt, can be any one of the following:
|
|
|
+ FREQ_DIS - periodic interrupt disabled
|
|
|
+ FREQ_137HZ - 137 Hertz
|
|
|
+ FREQ_69HZ - 69 Hertz
|
|
|
+ FREQ_34HZ - 34 Hertz
|
|
|
+ FREQ_17HZ - 17 Hertz
|
|
|
+ FREQ_9HZ - 9 Hertz
|
|
|
+ FREQ_4HZ - 4 Hertz
|
|
|
+ If IRQNum is set to 0 the Frequency parameter is
|
|
|
+ overidden, it is forced to a value of FREQ_DIS.
|
|
|
+ int PeriodicOnly: 1 if all interrupts except the periodic
|
|
|
+ interrupt are to be blocked.
|
|
|
+ 0 is both the periodic interrupt and
|
|
|
+ other channel interrupts are allowed.
|
|
|
+ If IRQNum is set to 0 the PeriodicOnly parameter is
|
|
|
+ overidden, it is forced to a value of 0.
|
|
|
+Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
|
|
|
+ initialization failed.
|
|
|
+
|
|
|
+Comments:
|
|
|
+ If periodic interrupts are to be disabled but AIOP interrupts
|
|
|
+ are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
|
|
|
+
|
|
|
+ If interrupts are to be completely disabled set IRQNum to 0.
|
|
|
+
|
|
|
+ Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
|
|
|
+ invalid combination.
|
|
|
+
|
|
|
+ This function performs initialization of global interrupt modes,
|
|
|
+ but it does not actually enable global interrupts. To enable
|
|
|
+ and disable global interrupts use functions sEnGlobalInt() and
|
|
|
+ sDisGlobalInt(). Enabling of global interrupts is normally not
|
|
|
+ done until all other initializations are complete.
|
|
|
+
|
|
|
+ Even if interrupts are globally enabled, they must also be
|
|
|
+ individually enabled for each channel that is to generate
|
|
|
+ interrupts.
|
|
|
+
|
|
|
+Warnings: No range checking on any of the parameters is done.
|
|
|
+
|
|
|
+ No context switches are allowed while executing this function.
|
|
|
+
|
|
|
+ After this function all AIOPs on the controller are disabled,
|
|
|
+ they can be enabled with sEnAiop().
|
|
|
+*/
|
|
|
+static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
|
|
|
+ ByteIO_t * AiopIOList, int AiopIOListSize,
|
|
|
+ WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
|
|
|
+ int PeriodicOnly, int altChanRingIndicator,
|
|
|
+ int UPCIRingInd)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+ ByteIO_t io;
|
|
|
+
|
|
|
+ CtlP->AltChanRingIndicator = altChanRingIndicator;
|
|
|
+ CtlP->UPCIRingInd = UPCIRingInd;
|
|
|
+ CtlP->CtlNum = CtlNum;
|
|
|
+ CtlP->CtlID = CTLID_0001; /* controller release 1 */
|
|
|
+ CtlP->BusType = isPCI; /* controller release 1 */
|
|
|
+
|
|
|
+ if (ConfigIO) {
|
|
|
+ CtlP->isUPCI = 1;
|
|
|
+ CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
|
|
|
+ CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
|
|
|
+ CtlP->AiopIntrBits = upci_aiop_intr_bits;
|
|
|
+ } else {
|
|
|
+ CtlP->isUPCI = 0;
|
|
|
+ CtlP->PCIIO =
|
|
|
+ (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
|
|
|
+ CtlP->AiopIntrBits = aiop_intr_bits;
|
|
|
+ }
|
|
|
+
|
|
|
+ sPCIControllerEOI(CtlP); /* clear EOI if warm init */
|
|
|
+ /* Init AIOPs */
|
|
|
+ CtlP->NumAiop = 0;
|
|
|
+ for (i = 0; i < AiopIOListSize; i++) {
|
|
|
+ io = AiopIOList[i];
|
|
|
+ CtlP->AiopIO[i] = (WordIO_t) io;
|
|
|
+ CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
|
|
|
+
|
|
|
+ CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
|
|
|
+ if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
|
|
|
+ break; /* done looking for AIOPs */
|
|
|
+
|
|
|
+ CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
|
|
|
+ sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
|
|
|
+ sOutB(io + _INDX_DATA, sClockPrescale);
|
|
|
+ CtlP->NumAiop++; /* bump count of AIOPs */
|
|
|
+ }
|
|
|
+
|
|
|
+ if (CtlP->NumAiop == 0)
|
|
|
+ return (-1);
|
|
|
+ else
|
|
|
+ return (CtlP->NumAiop);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Called when a PCI card is found. Retrieves and stores model information,
|
|
|
* init's aiopic and serial port hardware.
|
|
@@ -2519,147 +2654,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
|
|
|
return (CtlP->NumAiop);
|
|
|
}
|
|
|
|
|
|
-#ifdef CONFIG_PCI
|
|
|
-/***************************************************************************
|
|
|
-Function: sPCIInitController
|
|
|
-Purpose: Initialization of controller global registers and controller
|
|
|
- structure.
|
|
|
-Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize,
|
|
|
- IRQNum,Frequency,PeriodicOnly)
|
|
|
- CONTROLLER_T *CtlP; Ptr to controller structure
|
|
|
- int CtlNum; Controller number
|
|
|
- ByteIO_t *AiopIOList; List of I/O addresses for each AIOP.
|
|
|
- This list must be in the order the AIOPs will be found on the
|
|
|
- controller. Once an AIOP in the list is not found, it is
|
|
|
- assumed that there are no more AIOPs on the controller.
|
|
|
- int AiopIOListSize; Number of addresses in AiopIOList
|
|
|
- int IRQNum; Interrupt Request number. Can be any of the following:
|
|
|
- 0: Disable global interrupts
|
|
|
- 3: IRQ 3
|
|
|
- 4: IRQ 4
|
|
|
- 5: IRQ 5
|
|
|
- 9: IRQ 9
|
|
|
- 10: IRQ 10
|
|
|
- 11: IRQ 11
|
|
|
- 12: IRQ 12
|
|
|
- 15: IRQ 15
|
|
|
- Byte_t Frequency: A flag identifying the frequency
|
|
|
- of the periodic interrupt, can be any one of the following:
|
|
|
- FREQ_DIS - periodic interrupt disabled
|
|
|
- FREQ_137HZ - 137 Hertz
|
|
|
- FREQ_69HZ - 69 Hertz
|
|
|
- FREQ_34HZ - 34 Hertz
|
|
|
- FREQ_17HZ - 17 Hertz
|
|
|
- FREQ_9HZ - 9 Hertz
|
|
|
- FREQ_4HZ - 4 Hertz
|
|
|
- If IRQNum is set to 0 the Frequency parameter is
|
|
|
- overidden, it is forced to a value of FREQ_DIS.
|
|
|
- int PeriodicOnly: 1 if all interrupts except the periodic
|
|
|
- interrupt are to be blocked.
|
|
|
- 0 is both the periodic interrupt and
|
|
|
- other channel interrupts are allowed.
|
|
|
- If IRQNum is set to 0 the PeriodicOnly parameter is
|
|
|
- overidden, it is forced to a value of 0.
|
|
|
-Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller
|
|
|
- initialization failed.
|
|
|
-
|
|
|
-Comments:
|
|
|
- If periodic interrupts are to be disabled but AIOP interrupts
|
|
|
- are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0.
|
|
|
-
|
|
|
- If interrupts are to be completely disabled set IRQNum to 0.
|
|
|
-
|
|
|
- Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an
|
|
|
- invalid combination.
|
|
|
-
|
|
|
- This function performs initialization of global interrupt modes,
|
|
|
- but it does not actually enable global interrupts. To enable
|
|
|
- and disable global interrupts use functions sEnGlobalInt() and
|
|
|
- sDisGlobalInt(). Enabling of global interrupts is normally not
|
|
|
- done until all other initializations are complete.
|
|
|
-
|
|
|
- Even if interrupts are globally enabled, they must also be
|
|
|
- individually enabled for each channel that is to generate
|
|
|
- interrupts.
|
|
|
-
|
|
|
-Warnings: No range checking on any of the parameters is done.
|
|
|
-
|
|
|
- No context switches are allowed while executing this function.
|
|
|
-
|
|
|
- After this function all AIOPs on the controller are disabled,
|
|
|
- they can be enabled with sEnAiop().
|
|
|
-*/
|
|
|
-static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
|
|
|
- ByteIO_t * AiopIOList, int AiopIOListSize,
|
|
|
- WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
|
|
|
- int PeriodicOnly, int altChanRingIndicator,
|
|
|
- int UPCIRingInd)
|
|
|
-{
|
|
|
- int i;
|
|
|
- ByteIO_t io;
|
|
|
-
|
|
|
- CtlP->AltChanRingIndicator = altChanRingIndicator;
|
|
|
- CtlP->UPCIRingInd = UPCIRingInd;
|
|
|
- CtlP->CtlNum = CtlNum;
|
|
|
- CtlP->CtlID = CTLID_0001; /* controller release 1 */
|
|
|
- CtlP->BusType = isPCI; /* controller release 1 */
|
|
|
-
|
|
|
- if (ConfigIO) {
|
|
|
- CtlP->isUPCI = 1;
|
|
|
- CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
|
|
|
- CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
|
|
|
- CtlP->AiopIntrBits = upci_aiop_intr_bits;
|
|
|
- } else {
|
|
|
- CtlP->isUPCI = 0;
|
|
|
- CtlP->PCIIO =
|
|
|
- (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
|
|
|
- CtlP->AiopIntrBits = aiop_intr_bits;
|
|
|
- }
|
|
|
-
|
|
|
- sPCIControllerEOI(CtlP); /* clear EOI if warm init */
|
|
|
- /* Init AIOPs */
|
|
|
- CtlP->NumAiop = 0;
|
|
|
- for (i = 0; i < AiopIOListSize; i++) {
|
|
|
- io = AiopIOList[i];
|
|
|
- CtlP->AiopIO[i] = (WordIO_t) io;
|
|
|
- CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
|
|
|
-
|
|
|
- CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */
|
|
|
- if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */
|
|
|
- break; /* done looking for AIOPs */
|
|
|
-
|
|
|
- CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */
|
|
|
- sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */
|
|
|
- sOutB(io + _INDX_DATA, sClockPrescale);
|
|
|
- CtlP->NumAiop++; /* bump count of AIOPs */
|
|
|
- }
|
|
|
-
|
|
|
- if (CtlP->NumAiop == 0)
|
|
|
- return (-1);
|
|
|
- else
|
|
|
- return (CtlP->NumAiop);
|
|
|
-}
|
|
|
-
|
|
|
-/* Resets the speaker controller on RocketModem II and III devices */
|
|
|
-static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
|
|
|
-{
|
|
|
- ByteIO_t addr;
|
|
|
-
|
|
|
- /* RocketModem II speaker control is at the 8th port location of offset 0x40 */
|
|
|
- if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
|
|
|
- addr = CtlP->AiopIO[0] + 0x4F;
|
|
|
- sOutB(addr, 0);
|
|
|
- }
|
|
|
-
|
|
|
- /* RocketModem III speaker control is at the 1st port location of offset 0x80 */
|
|
|
- if ((model == MODEL_UPCI_RM3_8PORT)
|
|
|
- || (model == MODEL_UPCI_RM3_4PORT)) {
|
|
|
- addr = CtlP->AiopIO[0] + 0x88;
|
|
|
- sOutB(addr, 0);
|
|
|
- }
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/***************************************************************************
|
|
|
Function: sReadAiopID
|
|
|
Purpose: Read the AIOP idenfication number directly from an AIOP.
|