@ -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 .