diff options
-rw-r--r-- | drivers/tty/rocket.c | 288 |
1 files changed, 141 insertions, 147 deletions
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 82d35c5a58fd..354564ea47c5 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -150,12 +150,14 @@ static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = { | |||
150 | AIOP_INTR_BIT_3 | 150 | AIOP_INTR_BIT_3 |
151 | }; | 151 | }; |
152 | 152 | ||
153 | #ifdef CONFIG_PCI | ||
153 | static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { | 154 | static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = { |
154 | UPCI_AIOP_INTR_BIT_0, | 155 | UPCI_AIOP_INTR_BIT_0, |
155 | UPCI_AIOP_INTR_BIT_1, | 156 | UPCI_AIOP_INTR_BIT_1, |
156 | UPCI_AIOP_INTR_BIT_2, | 157 | UPCI_AIOP_INTR_BIT_2, |
157 | UPCI_AIOP_INTR_BIT_3 | 158 | UPCI_AIOP_INTR_BIT_3 |
158 | }; | 159 | }; |
160 | #endif | ||
159 | 161 | ||
160 | static Byte_t RData[RDATASIZE] = { | 162 | static Byte_t RData[RDATASIZE] = { |
161 | 0x00, 0x09, 0xf6, 0x82, | 163 | 0x00, 0x09, 0xf6, 0x82, |
@@ -227,7 +229,6 @@ static unsigned long nextLineNumber; | |||
227 | static int __init init_ISA(int i); | 229 | static int __init init_ISA(int i); |
228 | static void rp_wait_until_sent(struct tty_struct *tty, int timeout); | 230 | static void rp_wait_until_sent(struct tty_struct *tty, int timeout); |
229 | static void rp_flush_buffer(struct tty_struct *tty); | 231 | static void rp_flush_buffer(struct tty_struct *tty); |
230 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model); | ||
231 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); | 232 | static unsigned char GetLineNumber(int ctrl, int aiop, int ch); |
232 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); | 233 | static unsigned char SetLineNumber(int ctrl, int aiop, int ch); |
233 | static void rp_start(struct tty_struct *tty); | 234 | static void rp_start(struct tty_struct *tty); |
@@ -241,11 +242,6 @@ static void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags); | |||
241 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); | 242 | static void sModemReset(CONTROLLER_T * CtlP, int chan, int on); |
242 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); | 243 | static void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on); |
243 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); | 244 | static int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data); |
244 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
245 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
246 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
247 | int PeriodicOnly, int altChanRingIndicator, | ||
248 | int UPCIRingInd); | ||
249 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | 245 | static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, |
250 | ByteIO_t * AiopIOList, int AiopIOListSize, | 246 | ByteIO_t * AiopIOList, int AiopIOListSize, |
251 | int IRQNum, Byte_t Frequency, int PeriodicOnly); | 247 | int IRQNum, Byte_t Frequency, int PeriodicOnly); |
@@ -1775,6 +1771,145 @@ static DEFINE_PCI_DEVICE_TABLE(rocket_pci_ids) = { | |||
1775 | }; | 1771 | }; |
1776 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | 1772 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); |
1777 | 1773 | ||
1774 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
1775 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
1776 | { | ||
1777 | ByteIO_t addr; | ||
1778 | |||
1779 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
1780 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
1781 | addr = CtlP->AiopIO[0] + 0x4F; | ||
1782 | sOutB(addr, 0); | ||
1783 | } | ||
1784 | |||
1785 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
1786 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
1787 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
1788 | addr = CtlP->AiopIO[0] + 0x88; | ||
1789 | sOutB(addr, 0); | ||
1790 | } | ||
1791 | } | ||
1792 | |||
1793 | /*************************************************************************** | ||
1794 | Function: sPCIInitController | ||
1795 | Purpose: Initialization of controller global registers and controller | ||
1796 | structure. | ||
1797 | Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, | ||
1798 | IRQNum,Frequency,PeriodicOnly) | ||
1799 | CONTROLLER_T *CtlP; Ptr to controller structure | ||
1800 | int CtlNum; Controller number | ||
1801 | ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. | ||
1802 | This list must be in the order the AIOPs will be found on the | ||
1803 | controller. Once an AIOP in the list is not found, it is | ||
1804 | assumed that there are no more AIOPs on the controller. | ||
1805 | int AiopIOListSize; Number of addresses in AiopIOList | ||
1806 | int IRQNum; Interrupt Request number. Can be any of the following: | ||
1807 | 0: Disable global interrupts | ||
1808 | 3: IRQ 3 | ||
1809 | 4: IRQ 4 | ||
1810 | 5: IRQ 5 | ||
1811 | 9: IRQ 9 | ||
1812 | 10: IRQ 10 | ||
1813 | 11: IRQ 11 | ||
1814 | 12: IRQ 12 | ||
1815 | 15: IRQ 15 | ||
1816 | Byte_t Frequency: A flag identifying the frequency | ||
1817 | of the periodic interrupt, can be any one of the following: | ||
1818 | FREQ_DIS - periodic interrupt disabled | ||
1819 | FREQ_137HZ - 137 Hertz | ||
1820 | FREQ_69HZ - 69 Hertz | ||
1821 | FREQ_34HZ - 34 Hertz | ||
1822 | FREQ_17HZ - 17 Hertz | ||
1823 | FREQ_9HZ - 9 Hertz | ||
1824 | FREQ_4HZ - 4 Hertz | ||
1825 | If IRQNum is set to 0 the Frequency parameter is | ||
1826 | overidden, it is forced to a value of FREQ_DIS. | ||
1827 | int PeriodicOnly: 1 if all interrupts except the periodic | ||
1828 | interrupt are to be blocked. | ||
1829 | 0 is both the periodic interrupt and | ||
1830 | other channel interrupts are allowed. | ||
1831 | If IRQNum is set to 0 the PeriodicOnly parameter is | ||
1832 | overidden, it is forced to a value of 0. | ||
1833 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | ||
1834 | initialization failed. | ||
1835 | |||
1836 | Comments: | ||
1837 | If periodic interrupts are to be disabled but AIOP interrupts | ||
1838 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. | ||
1839 | |||
1840 | If interrupts are to be completely disabled set IRQNum to 0. | ||
1841 | |||
1842 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an | ||
1843 | invalid combination. | ||
1844 | |||
1845 | This function performs initialization of global interrupt modes, | ||
1846 | but it does not actually enable global interrupts. To enable | ||
1847 | and disable global interrupts use functions sEnGlobalInt() and | ||
1848 | sDisGlobalInt(). Enabling of global interrupts is normally not | ||
1849 | done until all other initializations are complete. | ||
1850 | |||
1851 | Even if interrupts are globally enabled, they must also be | ||
1852 | individually enabled for each channel that is to generate | ||
1853 | interrupts. | ||
1854 | |||
1855 | Warnings: No range checking on any of the parameters is done. | ||
1856 | |||
1857 | No context switches are allowed while executing this function. | ||
1858 | |||
1859 | After this function all AIOPs on the controller are disabled, | ||
1860 | they can be enabled with sEnAiop(). | ||
1861 | */ | ||
1862 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
1863 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
1864 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
1865 | int PeriodicOnly, int altChanRingIndicator, | ||
1866 | int UPCIRingInd) | ||
1867 | { | ||
1868 | int i; | ||
1869 | ByteIO_t io; | ||
1870 | |||
1871 | CtlP->AltChanRingIndicator = altChanRingIndicator; | ||
1872 | CtlP->UPCIRingInd = UPCIRingInd; | ||
1873 | CtlP->CtlNum = CtlNum; | ||
1874 | CtlP->CtlID = CTLID_0001; /* controller release 1 */ | ||
1875 | CtlP->BusType = isPCI; /* controller release 1 */ | ||
1876 | |||
1877 | if (ConfigIO) { | ||
1878 | CtlP->isUPCI = 1; | ||
1879 | CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; | ||
1880 | CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; | ||
1881 | CtlP->AiopIntrBits = upci_aiop_intr_bits; | ||
1882 | } else { | ||
1883 | CtlP->isUPCI = 0; | ||
1884 | CtlP->PCIIO = | ||
1885 | (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); | ||
1886 | CtlP->AiopIntrBits = aiop_intr_bits; | ||
1887 | } | ||
1888 | |||
1889 | sPCIControllerEOI(CtlP); /* clear EOI if warm init */ | ||
1890 | /* Init AIOPs */ | ||
1891 | CtlP->NumAiop = 0; | ||
1892 | for (i = 0; i < AiopIOListSize; i++) { | ||
1893 | io = AiopIOList[i]; | ||
1894 | CtlP->AiopIO[i] = (WordIO_t) io; | ||
1895 | CtlP->AiopIntChanIO[i] = io + _INT_CHAN; | ||
1896 | |||
1897 | CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ | ||
1898 | if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ | ||
1899 | break; /* done looking for AIOPs */ | ||
1900 | |||
1901 | CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ | ||
1902 | sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ | ||
1903 | sOutB(io + _INDX_DATA, sClockPrescale); | ||
1904 | CtlP->NumAiop++; /* bump count of AIOPs */ | ||
1905 | } | ||
1906 | |||
1907 | if (CtlP->NumAiop == 0) | ||
1908 | return (-1); | ||
1909 | else | ||
1910 | return (CtlP->NumAiop); | ||
1911 | } | ||
1912 | |||
1778 | /* | 1913 | /* |
1779 | * Called when a PCI card is found. Retrieves and stores model information, | 1914 | * Called when a PCI card is found. Retrieves and stores model information, |
1780 | * init's aiopic and serial port hardware. | 1915 | * init's aiopic and serial port hardware. |
@@ -2519,147 +2654,6 @@ static int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO, | |||
2519 | return (CtlP->NumAiop); | 2654 | return (CtlP->NumAiop); |
2520 | } | 2655 | } |
2521 | 2656 | ||
2522 | #ifdef CONFIG_PCI | ||
2523 | /*************************************************************************** | ||
2524 | Function: sPCIInitController | ||
2525 | Purpose: Initialization of controller global registers and controller | ||
2526 | structure. | ||
2527 | Call: sPCIInitController(CtlP,CtlNum,AiopIOList,AiopIOListSize, | ||
2528 | IRQNum,Frequency,PeriodicOnly) | ||
2529 | CONTROLLER_T *CtlP; Ptr to controller structure | ||
2530 | int CtlNum; Controller number | ||
2531 | ByteIO_t *AiopIOList; List of I/O addresses for each AIOP. | ||
2532 | This list must be in the order the AIOPs will be found on the | ||
2533 | controller. Once an AIOP in the list is not found, it is | ||
2534 | assumed that there are no more AIOPs on the controller. | ||
2535 | int AiopIOListSize; Number of addresses in AiopIOList | ||
2536 | int IRQNum; Interrupt Request number. Can be any of the following: | ||
2537 | 0: Disable global interrupts | ||
2538 | 3: IRQ 3 | ||
2539 | 4: IRQ 4 | ||
2540 | 5: IRQ 5 | ||
2541 | 9: IRQ 9 | ||
2542 | 10: IRQ 10 | ||
2543 | 11: IRQ 11 | ||
2544 | 12: IRQ 12 | ||
2545 | 15: IRQ 15 | ||
2546 | Byte_t Frequency: A flag identifying the frequency | ||
2547 | of the periodic interrupt, can be any one of the following: | ||
2548 | FREQ_DIS - periodic interrupt disabled | ||
2549 | FREQ_137HZ - 137 Hertz | ||
2550 | FREQ_69HZ - 69 Hertz | ||
2551 | FREQ_34HZ - 34 Hertz | ||
2552 | FREQ_17HZ - 17 Hertz | ||
2553 | FREQ_9HZ - 9 Hertz | ||
2554 | FREQ_4HZ - 4 Hertz | ||
2555 | If IRQNum is set to 0 the Frequency parameter is | ||
2556 | overidden, it is forced to a value of FREQ_DIS. | ||
2557 | int PeriodicOnly: 1 if all interrupts except the periodic | ||
2558 | interrupt are to be blocked. | ||
2559 | 0 is both the periodic interrupt and | ||
2560 | other channel interrupts are allowed. | ||
2561 | If IRQNum is set to 0 the PeriodicOnly parameter is | ||
2562 | overidden, it is forced to a value of 0. | ||
2563 | Return: int: Number of AIOPs on the controller, or CTLID_NULL if controller | ||
2564 | initialization failed. | ||
2565 | |||
2566 | Comments: | ||
2567 | If periodic interrupts are to be disabled but AIOP interrupts | ||
2568 | are allowed, set Frequency to FREQ_DIS and PeriodicOnly to 0. | ||
2569 | |||
2570 | If interrupts are to be completely disabled set IRQNum to 0. | ||
2571 | |||
2572 | Setting Frequency to FREQ_DIS and PeriodicOnly to 1 is an | ||
2573 | invalid combination. | ||
2574 | |||
2575 | This function performs initialization of global interrupt modes, | ||
2576 | but it does not actually enable global interrupts. To enable | ||
2577 | and disable global interrupts use functions sEnGlobalInt() and | ||
2578 | sDisGlobalInt(). Enabling of global interrupts is normally not | ||
2579 | done until all other initializations are complete. | ||
2580 | |||
2581 | Even if interrupts are globally enabled, they must also be | ||
2582 | individually enabled for each channel that is to generate | ||
2583 | interrupts. | ||
2584 | |||
2585 | Warnings: No range checking on any of the parameters is done. | ||
2586 | |||
2587 | No context switches are allowed while executing this function. | ||
2588 | |||
2589 | After this function all AIOPs on the controller are disabled, | ||
2590 | they can be enabled with sEnAiop(). | ||
2591 | */ | ||
2592 | static int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum, | ||
2593 | ByteIO_t * AiopIOList, int AiopIOListSize, | ||
2594 | WordIO_t ConfigIO, int IRQNum, Byte_t Frequency, | ||
2595 | int PeriodicOnly, int altChanRingIndicator, | ||
2596 | int UPCIRingInd) | ||
2597 | { | ||
2598 | int i; | ||
2599 | ByteIO_t io; | ||
2600 | |||
2601 | CtlP->AltChanRingIndicator = altChanRingIndicator; | ||
2602 | CtlP->UPCIRingInd = UPCIRingInd; | ||
2603 | CtlP->CtlNum = CtlNum; | ||
2604 | CtlP->CtlID = CTLID_0001; /* controller release 1 */ | ||
2605 | CtlP->BusType = isPCI; /* controller release 1 */ | ||
2606 | |||
2607 | if (ConfigIO) { | ||
2608 | CtlP->isUPCI = 1; | ||
2609 | CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL; | ||
2610 | CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL; | ||
2611 | CtlP->AiopIntrBits = upci_aiop_intr_bits; | ||
2612 | } else { | ||
2613 | CtlP->isUPCI = 0; | ||
2614 | CtlP->PCIIO = | ||
2615 | (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC); | ||
2616 | CtlP->AiopIntrBits = aiop_intr_bits; | ||
2617 | } | ||
2618 | |||
2619 | sPCIControllerEOI(CtlP); /* clear EOI if warm init */ | ||
2620 | /* Init AIOPs */ | ||
2621 | CtlP->NumAiop = 0; | ||
2622 | for (i = 0; i < AiopIOListSize; i++) { | ||
2623 | io = AiopIOList[i]; | ||
2624 | CtlP->AiopIO[i] = (WordIO_t) io; | ||
2625 | CtlP->AiopIntChanIO[i] = io + _INT_CHAN; | ||
2626 | |||
2627 | CtlP->AiopID[i] = sReadAiopID(io); /* read AIOP ID */ | ||
2628 | if (CtlP->AiopID[i] == AIOPID_NULL) /* if AIOP does not exist */ | ||
2629 | break; /* done looking for AIOPs */ | ||
2630 | |||
2631 | CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io); /* num channels in AIOP */ | ||
2632 | sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE); /* clock prescaler */ | ||
2633 | sOutB(io + _INDX_DATA, sClockPrescale); | ||
2634 | CtlP->NumAiop++; /* bump count of AIOPs */ | ||
2635 | } | ||
2636 | |||
2637 | if (CtlP->NumAiop == 0) | ||
2638 | return (-1); | ||
2639 | else | ||
2640 | return (CtlP->NumAiop); | ||
2641 | } | ||
2642 | |||
2643 | /* Resets the speaker controller on RocketModem II and III devices */ | ||
2644 | static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model) | ||
2645 | { | ||
2646 | ByteIO_t addr; | ||
2647 | |||
2648 | /* RocketModem II speaker control is at the 8th port location of offset 0x40 */ | ||
2649 | if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) { | ||
2650 | addr = CtlP->AiopIO[0] + 0x4F; | ||
2651 | sOutB(addr, 0); | ||
2652 | } | ||
2653 | |||
2654 | /* RocketModem III speaker control is at the 1st port location of offset 0x80 */ | ||
2655 | if ((model == MODEL_UPCI_RM3_8PORT) | ||
2656 | || (model == MODEL_UPCI_RM3_4PORT)) { | ||
2657 | addr = CtlP->AiopIO[0] + 0x88; | ||
2658 | sOutB(addr, 0); | ||
2659 | } | ||
2660 | } | ||
2661 | #endif | ||
2662 | |||
2663 | /*************************************************************************** | 2657 | /*************************************************************************** |
2664 | Function: sReadAiopID | 2658 | Function: sReadAiopID |
2665 | Purpose: Read the AIOP idenfication number directly from an AIOP. | 2659 | Purpose: Read the AIOP idenfication number directly from an AIOP. |