diff options
Diffstat (limited to 'drivers/char')
47 files changed, 2090 insertions, 2014 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index a26d91743b24..1e32fb834eb8 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -127,7 +127,7 @@ config ROCKETPORT | |||
127 | 127 | ||
128 | config CYCLADES | 128 | config CYCLADES |
129 | tristate "Cyclades async mux support" | 129 | tristate "Cyclades async mux support" |
130 | depends on SERIAL_NONSTANDARD | 130 | depends on SERIAL_NONSTANDARD && (PCI || ISA) |
131 | ---help--- | 131 | ---help--- |
132 | This driver supports Cyclades Z and Y multiserial boards. | 132 | This driver supports Cyclades Z and Y multiserial boards. |
133 | You would need something like this to connect more than two modems to | 133 | You would need something like this to connect more than two modems to |
@@ -1071,5 +1071,11 @@ config TELCLOCK | |||
1071 | /sys/devices/platform/telco_clock, with a number of files for | 1071 | /sys/devices/platform/telco_clock, with a number of files for |
1072 | controlling the behavior of this hardware. | 1072 | controlling the behavior of this hardware. |
1073 | 1073 | ||
1074 | config DEVPORT | ||
1075 | bool | ||
1076 | depends on !M68K | ||
1077 | depends on ISA || PCI | ||
1078 | default y | ||
1079 | |||
1074 | endmenu | 1080 | endmenu |
1075 | 1081 | ||
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 0e2b72f2b887..4eaceabd8cea 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -1574,7 +1574,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1574 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 1574 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) |
1575 | break; | 1575 | break; |
1576 | } | 1576 | } |
1577 | current->state = TASK_RUNNING; | 1577 | __set_current_state(TASK_RUNNING); |
1578 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | 1578 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT |
1579 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | 1579 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); |
1580 | #endif | 1580 | #endif |
@@ -1700,7 +1700,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
1700 | #endif | 1700 | #endif |
1701 | schedule(); | 1701 | schedule(); |
1702 | } | 1702 | } |
1703 | current->state = TASK_RUNNING; | 1703 | __set_current_state(TASK_RUNNING); |
1704 | remove_wait_queue(&info->open_wait, &wait); | 1704 | remove_wait_queue(&info->open_wait, &wait); |
1705 | if (extra_count) | 1705 | if (extra_count) |
1706 | state->count++; | 1706 | state->count++; |
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c index b99b7561260d..fd40b959afdd 100644 --- a/drivers/char/consolemap.c +++ b/drivers/char/consolemap.c | |||
@@ -626,10 +626,10 @@ conv_uni_to_pc(struct vc_data *conp, long ucs) | |||
626 | 626 | ||
627 | /* Only 16-bit codes supported at this time */ | 627 | /* Only 16-bit codes supported at this time */ |
628 | if (ucs > 0xffff) | 628 | if (ucs > 0xffff) |
629 | ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ | 629 | return -4; /* Not found */ |
630 | else if (ucs < 0x20 || ucs >= 0xfffe) | 630 | else if (ucs < 0x20) |
631 | return -1; /* Not a printable character */ | 631 | return -1; /* Not a printable character */ |
632 | else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) | 632 | else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f)) |
633 | return -2; /* Zero-width space */ | 633 | return -2; /* Zero-width space */ |
634 | /* | 634 | /* |
635 | * UNI_DIRECT_BASE indicates the start of the region in the User Zone | 635 | * UNI_DIRECT_BASE indicates the start of the region in the User Zone |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index c02d9e99e050..fe6d2407baed 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -44,6 +44,7 @@ static struct pci_device_id divil_pci[] = { | |||
44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 44 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, |
45 | { } /* NULL entry */ | 45 | { } /* NULL entry */ |
46 | }; | 46 | }; |
47 | MODULE_DEVICE_TABLE(pci, divil_pci); | ||
47 | 48 | ||
48 | static struct cdev cs5535_gpio_cdev; | 49 | static struct cdev cs5535_gpio_cdev; |
49 | 50 | ||
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 16dc5d1d3cb4..c72ee97d3892 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -10,15 +10,14 @@ | |||
10 | * | 10 | * |
11 | * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. | 11 | * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. |
12 | * Modified and maintained by Marcio Saito <marcio@cyclades.com>. | 12 | * Modified and maintained by Marcio Saito <marcio@cyclades.com>. |
13 | * Currently maintained by Cyclades team <async@cyclades.com>. | ||
14 | * | 13 | * |
15 | * For Technical support and installation problems, please send e-mail | 14 | * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com> |
16 | * to support@cyclades.com. | ||
17 | * | 15 | * |
18 | * Much of the design and some of the code came from serial.c | 16 | * Much of the design and some of the code came from serial.c |
19 | * which was copyright (C) 1991, 1992 Linus Torvalds. It was | 17 | * which was copyright (C) 1991, 1992 Linus Torvalds. It was |
20 | * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, | 18 | * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, |
21 | * and then fixed as suggested by Michael K. Johnson 12/12/92. | 19 | * and then fixed as suggested by Michael K. Johnson 12/12/92. |
20 | * Converted to pci probing and cleaned up by Jiri Slaby. | ||
22 | * | 21 | * |
23 | * This version supports shared IRQ's (only for PCI boards). | 22 | * This version supports shared IRQ's (only for PCI boards). |
24 | * | 23 | * |
@@ -591,7 +590,7 @@ | |||
591 | * | 590 | * |
592 | */ | 591 | */ |
593 | 592 | ||
594 | #define CY_VERSION "2.4" | 593 | #define CY_VERSION "2.5" |
595 | 594 | ||
596 | /* If you need to install more boards than NR_CARDS, change the constant | 595 | /* If you need to install more boards than NR_CARDS, change the constant |
597 | in the definition below. No other change is necessary to support up to | 596 | in the definition below. No other change is necessary to support up to |
@@ -624,12 +623,6 @@ | |||
624 | #undef CY_ENABLE_MONITORING | 623 | #undef CY_ENABLE_MONITORING |
625 | #undef CY_PCI_DEBUG | 624 | #undef CY_PCI_DEBUG |
626 | 625 | ||
627 | #if 0 | ||
628 | #define PAUSE __asm__("nop") | ||
629 | #else | ||
630 | #define PAUSE do {} while (0) | ||
631 | #endif | ||
632 | |||
633 | /* | 626 | /* |
634 | * Include section | 627 | * Include section |
635 | */ | 628 | */ |
@@ -659,17 +652,6 @@ | |||
659 | #include <asm/irq.h> | 652 | #include <asm/irq.h> |
660 | #include <asm/uaccess.h> | 653 | #include <asm/uaccess.h> |
661 | 654 | ||
662 | #define CY_LOCK(info,flags) \ | ||
663 | do { \ | ||
664 | spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \ | ||
665 | } while (0) | ||
666 | |||
667 | #define CY_UNLOCK(info,flags) \ | ||
668 | do { \ | ||
669 | spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \ | ||
670 | } while (0) | ||
671 | |||
672 | #include <linux/types.h> | ||
673 | #include <linux/kernel.h> | 655 | #include <linux/kernel.h> |
674 | #include <linux/pci.h> | 656 | #include <linux/pci.h> |
675 | 657 | ||
@@ -682,13 +664,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch); | |||
682 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 664 | #define IS_CYC_Z(card) ((card).num_chips == -1) |
683 | 665 | ||
684 | #define Z_FPGA_CHECK(card) \ | 666 | #define Z_FPGA_CHECK(card) \ |
685 | ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 667 | ((readl(&((struct RUNTIME_9060 __iomem *) \ |
686 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) | 668 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) |
687 | 669 | ||
688 | #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 670 | #define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \ |
689 | ((card).ctl_addr))->mail_box_0)) || \ | 671 | ((card).ctl_addr))->mail_box_0)) || \ |
690 | Z_FPGA_CHECK(card)) && \ | 672 | Z_FPGA_CHECK(card)) && \ |
691 | (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \ | 673 | (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \ |
692 | ((card).base_addr+ID_ADDRESS))->signature))) | 674 | ((card).base_addr+ID_ADDRESS))->signature))) |
693 | 675 | ||
694 | #ifndef SERIAL_XMIT_SIZE | 676 | #ifndef SERIAL_XMIT_SIZE |
@@ -725,8 +707,8 @@ static unsigned int cy_isa_addresses[] = { | |||
725 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) | 707 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) |
726 | 708 | ||
727 | #ifdef MODULE | 709 | #ifdef MODULE |
728 | static long maddr[NR_CARDS] = { 0, }; | 710 | static long maddr[NR_CARDS]; |
729 | static int irq[NR_CARDS] = { 0, }; | 711 | static int irq[NR_CARDS]; |
730 | 712 | ||
731 | module_param_array(maddr, long, NULL, 0); | 713 | module_param_array(maddr, long, NULL, 0); |
732 | module_param_array(irq, int, NULL, 0); | 714 | module_param_array(irq, int, NULL, 0); |
@@ -739,11 +721,6 @@ module_param_array(irq, int, NULL, 0); | |||
739 | */ | 721 | */ |
740 | static struct cyclades_card cy_card[NR_CARDS]; | 722 | static struct cyclades_card cy_card[NR_CARDS]; |
741 | 723 | ||
742 | /* This is the per-channel data structure containing pointers, flags | ||
743 | and variables for the port. This driver supports a maximum of NR_PORTS. | ||
744 | */ | ||
745 | static struct cyclades_port cy_port[NR_PORTS]; | ||
746 | |||
747 | static int cy_next_channel; /* next minor available */ | 724 | static int cy_next_channel; /* next minor available */ |
748 | 725 | ||
749 | /* | 726 | /* |
@@ -825,9 +802,6 @@ static int cy_chip_offset[] = { 0x0000, | |||
825 | 802 | ||
826 | /* PCI related definitions */ | 803 | /* PCI related definitions */ |
827 | 804 | ||
828 | static unsigned short cy_pci_nboard; | ||
829 | static unsigned short cy_isa_nboard; | ||
830 | static unsigned short cy_nboard; | ||
831 | #ifdef CONFIG_PCI | 805 | #ifdef CONFIG_PCI |
832 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { | 806 | static struct pci_device_id cy_pci_dev_id[] __devinitdata = { |
833 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ | 807 | { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ |
@@ -845,7 +819,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id); | |||
845 | 819 | ||
846 | static void cy_start(struct tty_struct *); | 820 | static void cy_start(struct tty_struct *); |
847 | static void set_line_char(struct cyclades_port *); | 821 | static void set_line_char(struct cyclades_port *); |
848 | static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); | 822 | static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32); |
849 | #ifdef CONFIG_ISA | 823 | #ifdef CONFIG_ISA |
850 | static unsigned detect_isa_irq(void __iomem *); | 824 | static unsigned detect_isa_irq(void __iomem *); |
851 | #endif /* CONFIG_ISA */ | 825 | #endif /* CONFIG_ISA */ |
@@ -858,7 +832,6 @@ static void cyz_poll(unsigned long); | |||
858 | /* The Cyclades-Z polling cycle is defined by this variable */ | 832 | /* The Cyclades-Z polling cycle is defined by this variable */ |
859 | static long cyz_polling_cycle = CZ_DEF_POLL; | 833 | static long cyz_polling_cycle = CZ_DEF_POLL; |
860 | 834 | ||
861 | static int cyz_timeron = 0; | ||
862 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); | 835 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); |
863 | 836 | ||
864 | #else /* CONFIG_CYZ_INTR */ | 837 | #else /* CONFIG_CYZ_INTR */ |
@@ -871,21 +844,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info, | |||
871 | { | 844 | { |
872 | #ifdef SERIAL_PARANOIA_CHECK | 845 | #ifdef SERIAL_PARANOIA_CHECK |
873 | if (!info) { | 846 | if (!info) { |
874 | printk("cyc Warning: null cyclades_port for (%s) in %s\n", | 847 | printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) " |
875 | name, routine); | 848 | "in %s\n", name, routine); |
876 | return 1; | ||
877 | } | ||
878 | |||
879 | if ((long)info < (long)(&cy_port[0]) || | ||
880 | (long)(&cy_port[NR_PORTS]) < (long)info) { | ||
881 | printk("cyc Warning: cyclades_port out of range for (%s) in " | ||
882 | "%s\n", name, routine); | ||
883 | return 1; | 849 | return 1; |
884 | } | 850 | } |
885 | 851 | ||
886 | if (info->magic != CYCLADES_MAGIC) { | 852 | if (info->magic != CYCLADES_MAGIC) { |
887 | printk("cyc Warning: bad magic number for serial struct (%s) " | 853 | printk(KERN_WARNING "cyc Warning: bad magic number for serial " |
888 | "in %s\n", name, routine); | 854 | "struct (%s) in %s\n", name, routine); |
889 | return 1; | 855 | return 1; |
890 | } | 856 | } |
891 | #endif | 857 | #endif |
@@ -943,22 +909,16 @@ do_softint(struct work_struct *work) | |||
943 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) | 909 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) |
944 | wake_up_interruptible(&info->open_wait); | 910 | wake_up_interruptible(&info->open_wait); |
945 | #ifdef CONFIG_CYZ_INTR | 911 | #ifdef CONFIG_CYZ_INTR |
946 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { | 912 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && |
947 | if (cyz_rx_full_timer[info->line].function == NULL) { | 913 | !timer_pending(&cyz_rx_full_timer[info->line])) |
948 | cyz_rx_full_timer[info->line].expires = jiffies + 1; | 914 | mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); |
949 | cyz_rx_full_timer[info->line].function = cyz_rx_restart; | ||
950 | cyz_rx_full_timer[info->line].data = | ||
951 | (unsigned long)info; | ||
952 | add_timer(&cyz_rx_full_timer[info->line]); | ||
953 | } | ||
954 | } | ||
955 | #endif | 915 | #endif |
956 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) | 916 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) |
957 | wake_up_interruptible(&info->delta_msr_wait); | 917 | wake_up_interruptible(&info->delta_msr_wait); |
958 | tty_wakeup(tty); | 918 | tty_wakeup(tty); |
959 | #ifdef Z_WAKE | 919 | #ifdef Z_WAKE |
960 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) | 920 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) |
961 | wake_up_interruptible(&info->shutdown_wait); | 921 | complete(&info->shutdown_wait); |
962 | #endif | 922 | #endif |
963 | } /* do_softint */ | 923 | } /* do_softint */ |
964 | 924 | ||
@@ -975,11 +935,11 @@ do_softint(struct work_struct *work) | |||
975 | */ | 935 | */ |
976 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) | 936 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) |
977 | { | 937 | { |
978 | volatile int i; | 938 | unsigned int i; |
979 | 939 | ||
980 | /* Check to see that the previous command has completed */ | 940 | /* Check to see that the previous command has completed */ |
981 | for (i = 0; i < 100; i++) { | 941 | for (i = 0; i < 100; i++) { |
982 | if (cy_readb(base_addr + (CyCCR << index)) == 0) { | 942 | if (readb(base_addr + (CyCCR << index)) == 0) { |
983 | break; | 943 | break; |
984 | } | 944 | } |
985 | udelay(10L); | 945 | udelay(10L); |
@@ -1022,7 +982,7 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1022 | 982 | ||
1023 | cy_writeb(address + (CyCAR << index), 0); | 983 | cy_writeb(address + (CyCAR << index), 0); |
1024 | cy_writeb(address + (CySRER << index), | 984 | cy_writeb(address + (CySRER << index), |
1025 | cy_readb(address + (CySRER << index)) | CyTxRdy); | 985 | readb(address + (CySRER << index)) | CyTxRdy); |
1026 | local_irq_restore(flags); | 986 | local_irq_restore(flags); |
1027 | 987 | ||
1028 | /* Wait ... */ | 988 | /* Wait ... */ |
@@ -1032,11 +992,11 @@ static unsigned detect_isa_irq(void __iomem * address) | |||
1032 | irq = probe_irq_off(irqs); | 992 | irq = probe_irq_off(irqs); |
1033 | 993 | ||
1034 | /* Clean up */ | 994 | /* Clean up */ |
1035 | save_xir = (u_char) cy_readb(address + (CyTIR << index)); | 995 | save_xir = (u_char) readb(address + (CyTIR << index)); |
1036 | save_car = cy_readb(address + (CyCAR << index)); | 996 | save_car = readb(address + (CyCAR << index)); |
1037 | cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); | 997 | cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); |
1038 | cy_writeb(address + (CySRER << index), | 998 | cy_writeb(address + (CySRER << index), |
1039 | cy_readb(address + (CySRER << index)) & ~CyTxRdy); | 999 | readb(address + (CySRER << index)) & ~CyTxRdy); |
1040 | cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); | 1000 | cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); |
1041 | cy_writeb(address + (CyCAR << index), (save_car)); | 1001 | cy_writeb(address + (CyCAR << index), (save_car)); |
1042 | cy_writeb(address + (Cy_ClrIntr << index), 0); | 1002 | cy_writeb(address + (Cy_ClrIntr << index), 0); |
@@ -1051,45 +1011,43 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1051 | { | 1011 | { |
1052 | struct cyclades_port *info; | 1012 | struct cyclades_port *info; |
1053 | struct tty_struct *tty; | 1013 | struct tty_struct *tty; |
1054 | volatile int char_count; | 1014 | int char_count; |
1055 | int i, j, len, mdm_change, mdm_status, outch; | 1015 | int j, len, mdm_change, mdm_status, outch; |
1056 | int save_xir, channel, save_car; | 1016 | int save_xir, channel, save_car; |
1057 | char data; | 1017 | char data; |
1058 | 1018 | ||
1059 | if (status & CySRReceive) { /* reception interrupt */ | 1019 | if (status & CySRReceive) { /* reception interrupt */ |
1060 | #ifdef CY_DEBUG_INTERRUPTS | 1020 | #ifdef CY_DEBUG_INTERRUPTS |
1061 | printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); | 1021 | printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); |
1062 | #endif | 1022 | #endif |
1063 | /* determine the channel & change to that context */ | 1023 | /* determine the channel & change to that context */ |
1064 | spin_lock(&cinfo->card_lock); | 1024 | spin_lock(&cinfo->card_lock); |
1065 | save_xir = (u_char) cy_readb(base_addr + (CyRIR << index)); | 1025 | save_xir = (u_char) readb(base_addr + (CyRIR << index)); |
1066 | channel = (u_short) (save_xir & CyIRChannel); | 1026 | channel = (u_short) (save_xir & CyIRChannel); |
1067 | i = channel + chip * 4 + cinfo->first_line; | 1027 | info = &cinfo->ports[channel + chip * 4]; |
1068 | info = &cy_port[i]; | 1028 | save_car = readb(base_addr + (CyCAR << index)); |
1069 | info->last_active = jiffies; | ||
1070 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1071 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1029 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1072 | 1030 | ||
1073 | /* if there is nowhere to put the data, discard it */ | 1031 | /* if there is nowhere to put the data, discard it */ |
1074 | if (info->tty == 0) { | 1032 | if (info->tty == NULL) { |
1075 | j = (cy_readb(base_addr + (CyRIVR << index)) & | 1033 | j = (readb(base_addr + (CyRIVR << index)) & |
1076 | CyIVRMask); | 1034 | CyIVRMask); |
1077 | if (j == CyIVRRxEx) { /* exception */ | 1035 | if (j == CyIVRRxEx) { /* exception */ |
1078 | data = cy_readb(base_addr + (CyRDSR << index)); | 1036 | data = readb(base_addr + (CyRDSR << index)); |
1079 | } else { /* normal character reception */ | 1037 | } else { /* normal character reception */ |
1080 | char_count = cy_readb(base_addr + | 1038 | char_count = readb(base_addr + |
1081 | (CyRDCR << index)); | 1039 | (CyRDCR << index)); |
1082 | while (char_count--) { | 1040 | while (char_count--) { |
1083 | data = cy_readb(base_addr + | 1041 | data = readb(base_addr + |
1084 | (CyRDSR << index)); | 1042 | (CyRDSR << index)); |
1085 | } | 1043 | } |
1086 | } | 1044 | } |
1087 | } else { /* there is an open port for this data */ | 1045 | } else { /* there is an open port for this data */ |
1088 | tty = info->tty; | 1046 | tty = info->tty; |
1089 | j = (cy_readb(base_addr + (CyRIVR << index)) & | 1047 | j = (readb(base_addr + (CyRIVR << index)) & |
1090 | CyIVRMask); | 1048 | CyIVRMask); |
1091 | if (j == CyIVRRxEx) { /* exception */ | 1049 | if (j == CyIVRRxEx) { /* exception */ |
1092 | data = cy_readb(base_addr + (CyRDSR << index)); | 1050 | data = readb(base_addr + (CyRDSR << index)); |
1093 | 1051 | ||
1094 | /* For statistics only */ | 1052 | /* For statistics only */ |
1095 | if (data & CyBREAK) | 1053 | if (data & CyBREAK) |
@@ -1110,7 +1068,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1110 | if (data & CyBREAK) { | 1068 | if (data & CyBREAK) { |
1111 | tty_insert_flip_char( | 1069 | tty_insert_flip_char( |
1112 | tty, | 1070 | tty, |
1113 | cy_readb( | 1071 | readb( |
1114 | base_addr + | 1072 | base_addr + |
1115 | (CyRDSR << | 1073 | (CyRDSR << |
1116 | index)), | 1074 | index)), |
@@ -1123,7 +1081,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1123 | } else if (data & CyFRAME) { | 1081 | } else if (data & CyFRAME) { |
1124 | tty_insert_flip_char( | 1082 | tty_insert_flip_char( |
1125 | tty, | 1083 | tty, |
1126 | cy_readb( | 1084 | readb( |
1127 | base_addr + | 1085 | base_addr + |
1128 | (CyRDSR << | 1086 | (CyRDSR << |
1129 | index)), | 1087 | index)), |
@@ -1135,7 +1093,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1135 | /* Pieces of seven... */ | 1093 | /* Pieces of seven... */ |
1136 | tty_insert_flip_char( | 1094 | tty_insert_flip_char( |
1137 | tty, | 1095 | tty, |
1138 | cy_readb( | 1096 | readb( |
1139 | base_addr + | 1097 | base_addr + |
1140 | (CyRDSR << | 1098 | (CyRDSR << |
1141 | index)), | 1099 | index)), |
@@ -1154,7 +1112,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1154 | */ | 1112 | */ |
1155 | tty_insert_flip_char( | 1113 | tty_insert_flip_char( |
1156 | tty, | 1114 | tty, |
1157 | cy_readb( | 1115 | readb( |
1158 | base_addr + | 1116 | base_addr + |
1159 | (CyRDSR << | 1117 | (CyRDSR << |
1160 | index)), | 1118 | index)), |
@@ -1186,7 +1144,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1186 | } | 1144 | } |
1187 | } else { /* normal character reception */ | 1145 | } else { /* normal character reception */ |
1188 | /* load # chars available from the chip */ | 1146 | /* load # chars available from the chip */ |
1189 | char_count = cy_readb(base_addr + | 1147 | char_count = readb(base_addr + |
1190 | (CyRDCR << index)); | 1148 | (CyRDCR << index)); |
1191 | 1149 | ||
1192 | #ifdef CY_ENABLE_MONITORING | 1150 | #ifdef CY_ENABLE_MONITORING |
@@ -1198,7 +1156,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1198 | #endif | 1156 | #endif |
1199 | len = tty_buffer_request_room(tty, char_count); | 1157 | len = tty_buffer_request_room(tty, char_count); |
1200 | while (len--) { | 1158 | while (len--) { |
1201 | data = cy_readb(base_addr + | 1159 | data = readb(base_addr + |
1202 | (CyRDSR << index)); | 1160 | (CyRDSR << index)); |
1203 | tty_insert_flip_char(tty, data, | 1161 | tty_insert_flip_char(tty, data, |
1204 | TTY_NORMAL); | 1162 | TTY_NORMAL); |
@@ -1223,29 +1181,27 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1223 | is empty, we know we can always stuff a dozen | 1181 | is empty, we know we can always stuff a dozen |
1224 | characters. */ | 1182 | characters. */ |
1225 | #ifdef CY_DEBUG_INTERRUPTS | 1183 | #ifdef CY_DEBUG_INTERRUPTS |
1226 | printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); | 1184 | printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); |
1227 | #endif | 1185 | #endif |
1228 | 1186 | ||
1229 | /* determine the channel & change to that context */ | 1187 | /* determine the channel & change to that context */ |
1230 | spin_lock(&cinfo->card_lock); | 1188 | spin_lock(&cinfo->card_lock); |
1231 | save_xir = (u_char) cy_readb(base_addr + (CyTIR << index)); | 1189 | save_xir = (u_char) readb(base_addr + (CyTIR << index)); |
1232 | channel = (u_short) (save_xir & CyIRChannel); | 1190 | channel = (u_short) (save_xir & CyIRChannel); |
1233 | i = channel + chip * 4 + cinfo->first_line; | 1191 | save_car = readb(base_addr + (CyCAR << index)); |
1234 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1235 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1192 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1236 | 1193 | ||
1237 | /* validate the port# (as configured and open) */ | 1194 | /* validate the port# (as configured and open) */ |
1238 | if ((i < 0) || (NR_PORTS <= i)) { | 1195 | if (channel + chip * 4 >= cinfo->nports) { |
1239 | cy_writeb(base_addr + (CySRER << index), | 1196 | cy_writeb(base_addr + (CySRER << index), |
1240 | cy_readb(base_addr + (CySRER << index)) & | 1197 | readb(base_addr + (CySRER << index)) & |
1241 | ~CyTxRdy); | 1198 | ~CyTxRdy); |
1242 | goto txend; | 1199 | goto txend; |
1243 | } | 1200 | } |
1244 | info = &cy_port[i]; | 1201 | info = &cinfo->ports[channel + chip * 4]; |
1245 | info->last_active = jiffies; | 1202 | if (info->tty == NULL) { |
1246 | if (info->tty == 0) { | ||
1247 | cy_writeb(base_addr + (CySRER << index), | 1203 | cy_writeb(base_addr + (CySRER << index), |
1248 | cy_readb(base_addr + (CySRER << index)) & | 1204 | readb(base_addr + (CySRER << index)) & |
1249 | ~CyTxRdy); | 1205 | ~CyTxRdy); |
1250 | goto txdone; | 1206 | goto txdone; |
1251 | } | 1207 | } |
@@ -1278,29 +1234,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1278 | 1234 | ||
1279 | while (char_count-- > 0) { | 1235 | while (char_count-- > 0) { |
1280 | if (!info->xmit_cnt) { | 1236 | if (!info->xmit_cnt) { |
1281 | if (cy_readb(base_addr + (CySRER << index)) & | 1237 | if (readb(base_addr + (CySRER << index)) & |
1282 | CyTxMpty) { | 1238 | CyTxMpty) { |
1283 | cy_writeb(base_addr + (CySRER << index), | 1239 | cy_writeb(base_addr + (CySRER << index), |
1284 | cy_readb(base_addr + | 1240 | readb(base_addr + |
1285 | (CySRER << index)) & | 1241 | (CySRER << index)) & |
1286 | ~CyTxMpty); | 1242 | ~CyTxMpty); |
1287 | } else { | 1243 | } else { |
1288 | cy_writeb(base_addr + (CySRER << index), | 1244 | cy_writeb(base_addr + (CySRER << index), |
1289 | (cy_readb(base_addr + | 1245 | (readb(base_addr + |
1290 | (CySRER << index)) & | 1246 | (CySRER << index)) & |
1291 | ~CyTxRdy) | CyTxMpty); | 1247 | ~CyTxRdy) | CyTxMpty); |
1292 | } | 1248 | } |
1293 | goto txdone; | 1249 | goto txdone; |
1294 | } | 1250 | } |
1295 | if (info->xmit_buf == 0) { | 1251 | if (info->xmit_buf == NULL) { |
1296 | cy_writeb(base_addr + (CySRER << index), | 1252 | cy_writeb(base_addr + (CySRER << index), |
1297 | cy_readb(base_addr + (CySRER << index))& | 1253 | readb(base_addr + (CySRER << index)) & |
1298 | ~CyTxRdy); | 1254 | ~CyTxRdy); |
1299 | goto txdone; | 1255 | goto txdone; |
1300 | } | 1256 | } |
1301 | if (info->tty->stopped || info->tty->hw_stopped) { | 1257 | if (info->tty->stopped || info->tty->hw_stopped) { |
1302 | cy_writeb(base_addr + (CySRER << index), | 1258 | cy_writeb(base_addr + (CySRER << index), |
1303 | cy_readb(base_addr + (CySRER << index))& | 1259 | readb(base_addr + (CySRER << index)) & |
1304 | ~CyTxRdy); | 1260 | ~CyTxRdy); |
1305 | goto txdone; | 1261 | goto txdone; |
1306 | } | 1262 | } |
@@ -1333,7 +1289,6 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, | |||
1333 | 0); | 1289 | 0); |
1334 | info->icount.tx++; | 1290 | info->icount.tx++; |
1335 | char_count--; | 1291 | char_count--; |
1336 | } else { | ||
1337 | } | 1292 | } |
1338 | } | 1293 | } |
1339 | } | 1294 | } |
@@ -1353,19 +1308,16 @@ txend: | |||
1353 | 1308 | ||
1354 | /* determine the channel & change to that context */ | 1309 | /* determine the channel & change to that context */ |
1355 | spin_lock(&cinfo->card_lock); | 1310 | spin_lock(&cinfo->card_lock); |
1356 | save_xir = (u_char) cy_readb(base_addr + (CyMIR << index)); | 1311 | save_xir = (u_char) readb(base_addr + (CyMIR << index)); |
1357 | channel = (u_short) (save_xir & CyIRChannel); | 1312 | channel = (u_short) (save_xir & CyIRChannel); |
1358 | info = &cy_port[channel + chip * 4 + cinfo->first_line]; | 1313 | info = &cinfo->ports[channel + chip * 4]; |
1359 | info->last_active = jiffies; | 1314 | save_car = readb(base_addr + (CyCAR << index)); |
1360 | save_car = cy_readb(base_addr + (CyCAR << index)); | ||
1361 | cy_writeb(base_addr + (CyCAR << index), save_xir); | 1315 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1362 | 1316 | ||
1363 | mdm_change = cy_readb(base_addr + (CyMISR << index)); | 1317 | mdm_change = readb(base_addr + (CyMISR << index)); |
1364 | mdm_status = cy_readb(base_addr + (CyMSVR1 << index)); | 1318 | mdm_status = readb(base_addr + (CyMSVR1 << index)); |
1365 | 1319 | ||
1366 | if (info->tty == 0) { /* no place for data, ignore it */ | 1320 | if (info->tty) { |
1367 | ; | ||
1368 | } else { | ||
1369 | if (mdm_change & CyANY_DELTA) { | 1321 | if (mdm_change & CyANY_DELTA) { |
1370 | /* For statistics only */ | 1322 | /* For statistics only */ |
1371 | if (mdm_change & CyDCD) | 1323 | if (mdm_change & CyDCD) |
@@ -1398,7 +1350,7 @@ txend: | |||
1398 | info->tty->hw_stopped = 0; | 1350 | info->tty->hw_stopped = 0; |
1399 | cy_writeb(base_addr + | 1351 | cy_writeb(base_addr + |
1400 | (CySRER << index), | 1352 | (CySRER << index), |
1401 | cy_readb(base_addr + | 1353 | readb(base_addr + |
1402 | (CySRER << | 1354 | (CySRER << |
1403 | index))| | 1355 | index))| |
1404 | CyTxRdy); | 1356 | CyTxRdy); |
@@ -1412,17 +1364,17 @@ txend: | |||
1412 | info->tty->hw_stopped = 1; | 1364 | info->tty->hw_stopped = 1; |
1413 | cy_writeb(base_addr + | 1365 | cy_writeb(base_addr + |
1414 | (CySRER << index), | 1366 | (CySRER << index), |
1415 | cy_readb(base_addr + | 1367 | readb(base_addr + |
1416 | (CySRER << | 1368 | (CySRER << |
1417 | index)) & | 1369 | index)) & |
1418 | ~CyTxRdy); | 1370 | ~CyTxRdy); |
1419 | } | 1371 | } |
1420 | } | 1372 | } |
1421 | } | 1373 | } |
1422 | if (mdm_change & CyDSR) { | 1374 | /* if (mdm_change & CyDSR) { |
1423 | } | 1375 | } |
1424 | if (mdm_change & CyRI) { | 1376 | if (mdm_change & CyRI) { |
1425 | } | 1377 | }*/ |
1426 | } | 1378 | } |
1427 | /* end of service */ | 1379 | /* end of service */ |
1428 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | 1380 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); |
@@ -1438,16 +1390,16 @@ txend: | |||
1438 | static irqreturn_t cyy_interrupt(int irq, void *dev_id) | 1390 | static irqreturn_t cyy_interrupt(int irq, void *dev_id) |
1439 | { | 1391 | { |
1440 | int status; | 1392 | int status; |
1441 | struct cyclades_card *cinfo; | 1393 | struct cyclades_card *cinfo = dev_id; |
1442 | void __iomem *base_addr, *card_base_addr; | 1394 | void __iomem *base_addr, *card_base_addr; |
1443 | int chip; | 1395 | int chip; |
1444 | int index; | 1396 | int index; |
1445 | int too_many; | 1397 | int too_many; |
1446 | int had_work; | 1398 | int had_work; |
1447 | 1399 | ||
1448 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { | 1400 | if (unlikely(cinfo == NULL)) { |
1449 | #ifdef CY_DEBUG_INTERRUPTS | 1401 | #ifdef CY_DEBUG_INTERRUPTS |
1450 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | 1402 | printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq); |
1451 | #endif | 1403 | #endif |
1452 | return IRQ_NONE; /* spurious interrupt */ | 1404 | return IRQ_NONE; /* spurious interrupt */ |
1453 | } | 1405 | } |
@@ -1455,6 +1407,10 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1455 | card_base_addr = cinfo->base_addr; | 1407 | card_base_addr = cinfo->base_addr; |
1456 | index = cinfo->bus_index; | 1408 | index = cinfo->bus_index; |
1457 | 1409 | ||
1410 | /* card was not initialized yet (e.g. DEBUG_SHIRQ) */ | ||
1411 | if (unlikely(card_base_addr == NULL)) | ||
1412 | return IRQ_HANDLED; | ||
1413 | |||
1458 | /* This loop checks all chips in the card. Make a note whenever | 1414 | /* This loop checks all chips in the card. Make a note whenever |
1459 | _any_ chip had some work to do, as this is considered an | 1415 | _any_ chip had some work to do, as this is considered an |
1460 | indication that there will be more to do. Only when no chip | 1416 | indication that there will be more to do. Only when no chip |
@@ -1466,7 +1422,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1466 | base_addr = cinfo->base_addr + | 1422 | base_addr = cinfo->base_addr + |
1467 | (cy_chip_offset[chip] << index); | 1423 | (cy_chip_offset[chip] << index); |
1468 | too_many = 0; | 1424 | too_many = 0; |
1469 | while ((status = cy_readb(base_addr + | 1425 | while ((status = readb(base_addr + |
1470 | (CySVRR << index))) != 0x00) { | 1426 | (CySVRR << index))) != 0x00) { |
1471 | had_work++; | 1427 | had_work++; |
1472 | /* The purpose of the following test is to ensure that | 1428 | /* The purpose of the following test is to ensure that |
@@ -1498,7 +1454,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) | |||
1498 | 1454 | ||
1499 | static int | 1455 | static int |
1500 | cyz_fetch_msg(struct cyclades_card *cinfo, | 1456 | cyz_fetch_msg(struct cyclades_card *cinfo, |
1501 | uclong * channel, ucchar * cmd, uclong * param) | 1457 | __u32 * channel, __u8 * cmd, __u32 * param) |
1502 | { | 1458 | { |
1503 | struct FIRM_ID __iomem *firm_id; | 1459 | struct FIRM_ID __iomem *firm_id; |
1504 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1460 | struct ZFW_CTRL __iomem *zfw_ctrl; |
@@ -1509,16 +1465,15 @@ cyz_fetch_msg(struct cyclades_card *cinfo, | |||
1509 | if (!ISZLOADED(*cinfo)) { | 1465 | if (!ISZLOADED(*cinfo)) { |
1510 | return -1; | 1466 | return -1; |
1511 | } | 1467 | } |
1512 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1468 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1513 | 0xfffff); | ||
1514 | board_ctrl = &zfw_ctrl->board_ctrl; | 1469 | board_ctrl = &zfw_ctrl->board_ctrl; |
1515 | 1470 | ||
1516 | loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) | 1471 | loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *) |
1517 | (cinfo->ctl_addr))->loc_doorbell); | 1472 | (cinfo->ctl_addr))->loc_doorbell); |
1518 | if (loc_doorbell) { | 1473 | if (loc_doorbell) { |
1519 | *cmd = (char)(0xff & loc_doorbell); | 1474 | *cmd = (char)(0xff & loc_doorbell); |
1520 | *channel = cy_readl(&board_ctrl->fwcmd_channel); | 1475 | *channel = readl(&board_ctrl->fwcmd_channel); |
1521 | *param = (uclong) cy_readl(&board_ctrl->fwcmd_param); | 1476 | *param = (__u32) readl(&board_ctrl->fwcmd_param); |
1522 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> | 1477 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> |
1523 | loc_doorbell, 0xffffffff); | 1478 | loc_doorbell, 0xffffffff); |
1524 | return 1; | 1479 | return 1; |
@@ -1528,28 +1483,27 @@ cyz_fetch_msg(struct cyclades_card *cinfo, | |||
1528 | 1483 | ||
1529 | static int | 1484 | static int |
1530 | cyz_issue_cmd(struct cyclades_card *cinfo, | 1485 | cyz_issue_cmd(struct cyclades_card *cinfo, |
1531 | uclong channel, ucchar cmd, uclong param) | 1486 | __u32 channel, __u8 cmd, __u32 param) |
1532 | { | 1487 | { |
1533 | struct FIRM_ID __iomem *firm_id; | 1488 | struct FIRM_ID __iomem *firm_id; |
1534 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1489 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1535 | struct BOARD_CTRL __iomem *board_ctrl; | 1490 | struct BOARD_CTRL __iomem *board_ctrl; |
1536 | unsigned long __iomem *pci_doorbell; | 1491 | __u32 __iomem *pci_doorbell; |
1537 | int index; | 1492 | int index; |
1538 | 1493 | ||
1539 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1494 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1540 | if (!ISZLOADED(*cinfo)) { | 1495 | if (!ISZLOADED(*cinfo)) { |
1541 | return -1; | 1496 | return -1; |
1542 | } | 1497 | } |
1543 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1498 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1544 | 0xfffff); | ||
1545 | board_ctrl = &zfw_ctrl->board_ctrl; | 1499 | board_ctrl = &zfw_ctrl->board_ctrl; |
1546 | 1500 | ||
1547 | index = 0; | 1501 | index = 0; |
1548 | pci_doorbell = | 1502 | pci_doorbell = |
1549 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; | 1503 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; |
1550 | while ((cy_readl(pci_doorbell) & 0xff) != 0) { | 1504 | while ((readl(pci_doorbell) & 0xff) != 0) { |
1551 | if (index++ == 1000) { | 1505 | if (index++ == 1000) { |
1552 | return (int)(cy_readl(pci_doorbell) & 0xff); | 1506 | return (int)(readl(pci_doorbell) & 0xff); |
1553 | } | 1507 | } |
1554 | udelay(50L); | 1508 | udelay(50L); |
1555 | } | 1509 | } |
@@ -1561,34 +1515,30 @@ cyz_issue_cmd(struct cyclades_card *cinfo, | |||
1561 | } /* cyz_issue_cmd */ | 1515 | } /* cyz_issue_cmd */ |
1562 | 1516 | ||
1563 | static void | 1517 | static void |
1564 | cyz_handle_rx(struct cyclades_port *info, | 1518 | cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, |
1565 | volatile struct CH_CTRL __iomem * ch_ctrl, | 1519 | struct BUF_CTRL __iomem *buf_ctrl) |
1566 | volatile struct BUF_CTRL __iomem * buf_ctrl) | ||
1567 | { | 1520 | { |
1568 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1521 | struct cyclades_card *cinfo = info->card; |
1569 | struct tty_struct *tty = info->tty; | 1522 | struct tty_struct *tty = info->tty; |
1570 | volatile int char_count; | 1523 | int char_count; |
1571 | int len; | 1524 | int len; |
1572 | #ifdef BLOCKMOVE | 1525 | #ifdef BLOCKMOVE |
1573 | int small_count; | 1526 | unsigned char *buf; |
1574 | #else | 1527 | #else |
1575 | char data; | 1528 | char data; |
1576 | #endif | 1529 | #endif |
1577 | volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; | 1530 | __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; |
1578 | 1531 | ||
1579 | rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); | 1532 | rx_get = new_rx_get = readl(&buf_ctrl->rx_get); |
1580 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1533 | rx_put = readl(&buf_ctrl->rx_put); |
1581 | rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); | 1534 | rx_bufsize = readl(&buf_ctrl->rx_bufsize); |
1582 | rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); | 1535 | rx_bufaddr = readl(&buf_ctrl->rx_bufaddr); |
1583 | if (rx_put >= rx_get) | 1536 | if (rx_put >= rx_get) |
1584 | char_count = rx_put - rx_get; | 1537 | char_count = rx_put - rx_get; |
1585 | else | 1538 | else |
1586 | char_count = rx_put - rx_get + rx_bufsize; | 1539 | char_count = rx_put - rx_get + rx_bufsize; |
1587 | 1540 | ||
1588 | if (char_count) { | 1541 | if (char_count) { |
1589 | info->last_active = jiffies; | ||
1590 | info->jiffies[1] = jiffies; | ||
1591 | |||
1592 | #ifdef CY_ENABLE_MONITORING | 1542 | #ifdef CY_ENABLE_MONITORING |
1593 | info->mon.int_count++; | 1543 | info->mon.int_count++; |
1594 | info->mon.char_count += char_count; | 1544 | info->mon.char_count += char_count; |
@@ -1596,7 +1546,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1596 | info->mon.char_max = char_count; | 1546 | info->mon.char_max = char_count; |
1597 | info->mon.char_last = char_count; | 1547 | info->mon.char_last = char_count; |
1598 | #endif | 1548 | #endif |
1599 | if (tty == 0) { | 1549 | if (tty == NULL) { |
1600 | /* flush received characters */ | 1550 | /* flush received characters */ |
1601 | new_rx_get = (new_rx_get + char_count) & | 1551 | new_rx_get = (new_rx_get + char_count) & |
1602 | (rx_bufsize - 1); | 1552 | (rx_bufsize - 1); |
@@ -1606,30 +1556,28 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1606 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) | 1556 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) |
1607 | for performance, but because of buffer boundaries, there | 1557 | for performance, but because of buffer boundaries, there |
1608 | may be several steps to the operation */ | 1558 | may be several steps to the operation */ |
1609 | while (0 < (small_count = min_t(unsigned int, | 1559 | while (1) { |
1610 | rx_bufsize - new_rx_get, | 1560 | len = tty_prepare_flip_string(tty, &buf, |
1611 | min_t(unsigned int, TTY_FLIPBUF_SIZE - | 1561 | char_count); |
1612 | tty->flip.count, char_count)))){ | 1562 | if (!len) |
1613 | memcpy_fromio(tty->flip.char_buf_ptr, | 1563 | break; |
1614 | (char *)(cinfo->base_addr + rx_bufaddr + | ||
1615 | new_rx_get), | ||
1616 | small_count); | ||
1617 | 1564 | ||
1618 | tty->flip.char_buf_ptr += small_count; | 1565 | len = min_t(unsigned int, min(len, char_count), |
1619 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, | 1566 | rx_bufsize - new_rx_get); |
1620 | small_count); | 1567 | |
1621 | tty->flip.flag_buf_ptr += small_count; | 1568 | memcpy_fromio(buf, cinfo->base_addr + |
1622 | new_rx_get = (new_rx_get + small_count) & | 1569 | rx_bufaddr + new_rx_get, len); |
1570 | |||
1571 | new_rx_get = (new_rx_get + len) & | ||
1623 | (rx_bufsize - 1); | 1572 | (rx_bufsize - 1); |
1624 | char_count -= small_count; | 1573 | char_count -= len; |
1625 | info->icount.rx += small_count; | 1574 | info->icount.rx += len; |
1626 | info->idle_stats.recv_bytes += small_count; | 1575 | info->idle_stats.recv_bytes += len; |
1627 | tty->flip.count += small_count; | ||
1628 | } | 1576 | } |
1629 | #else | 1577 | #else |
1630 | len = tty_buffer_request_room(tty, char_count); | 1578 | len = tty_buffer_request_room(tty, char_count); |
1631 | while (len--) { | 1579 | while (len--) { |
1632 | data = cy_readb(cinfo->base_addr + rx_bufaddr + | 1580 | data = readb(cinfo->base_addr + rx_bufaddr + |
1633 | new_rx_get); | 1581 | new_rx_get); |
1634 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); | 1582 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); |
1635 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 1583 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
@@ -1640,13 +1588,12 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1640 | #ifdef CONFIG_CYZ_INTR | 1588 | #ifdef CONFIG_CYZ_INTR |
1641 | /* Recalculate the number of chars in the RX buffer and issue | 1589 | /* Recalculate the number of chars in the RX buffer and issue |
1642 | a cmd in case it's higher than the RX high water mark */ | 1590 | a cmd in case it's higher than the RX high water mark */ |
1643 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1591 | rx_put = readl(&buf_ctrl->rx_put); |
1644 | if (rx_put >= rx_get) | 1592 | if (rx_put >= rx_get) |
1645 | char_count = rx_put - rx_get; | 1593 | char_count = rx_put - rx_get; |
1646 | else | 1594 | else |
1647 | char_count = rx_put - rx_get + rx_bufsize; | 1595 | char_count = rx_put - rx_get + rx_bufsize; |
1648 | if (char_count >= (int)cy_readl(&buf_ctrl-> | 1596 | if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { |
1649 | rx_threshold)) { | ||
1650 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1597 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); |
1651 | } | 1598 | } |
1652 | #endif | 1599 | #endif |
@@ -1659,26 +1606,25 @@ cyz_handle_rx(struct cyclades_port *info, | |||
1659 | } | 1606 | } |
1660 | 1607 | ||
1661 | static void | 1608 | static void |
1662 | cyz_handle_tx(struct cyclades_port *info, | 1609 | cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, |
1663 | volatile struct CH_CTRL __iomem * ch_ctrl, | 1610 | struct BUF_CTRL __iomem *buf_ctrl) |
1664 | volatile struct BUF_CTRL __iomem * buf_ctrl) | ||
1665 | { | 1611 | { |
1666 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1612 | struct cyclades_card *cinfo = info->card; |
1667 | struct tty_struct *tty = info->tty; | 1613 | struct tty_struct *tty = info->tty; |
1668 | char data; | 1614 | char data; |
1669 | volatile int char_count; | 1615 | int char_count; |
1670 | #ifdef BLOCKMOVE | 1616 | #ifdef BLOCKMOVE |
1671 | int small_count; | 1617 | int small_count; |
1672 | #endif | 1618 | #endif |
1673 | volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; | 1619 | __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr; |
1674 | 1620 | ||
1675 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ | 1621 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ |
1676 | return; | 1622 | return; |
1677 | 1623 | ||
1678 | tx_get = cy_readl(&buf_ctrl->tx_get); | 1624 | tx_get = readl(&buf_ctrl->tx_get); |
1679 | tx_put = cy_readl(&buf_ctrl->tx_put); | 1625 | tx_put = readl(&buf_ctrl->tx_put); |
1680 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 1626 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); |
1681 | tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); | 1627 | tx_bufaddr = readl(&buf_ctrl->tx_bufaddr); |
1682 | if (tx_put >= tx_get) | 1628 | if (tx_put >= tx_get) |
1683 | char_count = tx_get - tx_put - 1 + tx_bufsize; | 1629 | char_count = tx_get - tx_put - 1 + tx_bufsize; |
1684 | else | 1630 | else |
@@ -1686,9 +1632,8 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1686 | 1632 | ||
1687 | if (char_count) { | 1633 | if (char_count) { |
1688 | 1634 | ||
1689 | if (tty == 0) { | 1635 | if (tty == NULL) |
1690 | goto ztxdone; | 1636 | goto ztxdone; |
1691 | } | ||
1692 | 1637 | ||
1693 | if (info->x_char) { /* send special char */ | 1638 | if (info->x_char) { /* send special char */ |
1694 | data = info->x_char; | 1639 | data = info->x_char; |
@@ -1698,8 +1643,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1698 | info->x_char = 0; | 1643 | info->x_char = 0; |
1699 | char_count--; | 1644 | char_count--; |
1700 | info->icount.tx++; | 1645 | info->icount.tx++; |
1701 | info->last_active = jiffies; | ||
1702 | info->jiffies[2] = jiffies; | ||
1703 | } | 1646 | } |
1704 | #ifdef BLOCKMOVE | 1647 | #ifdef BLOCKMOVE |
1705 | while (0 < (small_count = min_t(unsigned int, | 1648 | while (0 < (small_count = min_t(unsigned int, |
@@ -1719,8 +1662,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1719 | info->xmit_cnt -= small_count; | 1662 | info->xmit_cnt -= small_count; |
1720 | info->xmit_tail = (info->xmit_tail + small_count) & | 1663 | info->xmit_tail = (info->xmit_tail + small_count) & |
1721 | (SERIAL_XMIT_SIZE - 1); | 1664 | (SERIAL_XMIT_SIZE - 1); |
1722 | info->last_active = jiffies; | ||
1723 | info->jiffies[2] = jiffies; | ||
1724 | } | 1665 | } |
1725 | #else | 1666 | #else |
1726 | while (info->xmit_cnt && char_count) { | 1667 | while (info->xmit_cnt && char_count) { |
@@ -1733,8 +1674,6 @@ cyz_handle_tx(struct cyclades_port *info, | |||
1733 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1674 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1734 | char_count--; | 1675 | char_count--; |
1735 | info->icount.tx++; | 1676 | info->icount.tx++; |
1736 | info->last_active = jiffies; | ||
1737 | info->jiffies[2] = jiffies; | ||
1738 | } | 1677 | } |
1739 | #endif | 1678 | #endif |
1740 | ztxdone: | 1679 | ztxdone: |
@@ -1750,33 +1689,32 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1750 | { | 1689 | { |
1751 | struct tty_struct *tty; | 1690 | struct tty_struct *tty; |
1752 | struct cyclades_port *info; | 1691 | struct cyclades_port *info; |
1753 | static volatile struct FIRM_ID __iomem *firm_id; | 1692 | static struct FIRM_ID __iomem *firm_id; |
1754 | static volatile struct ZFW_CTRL __iomem *zfw_ctrl; | 1693 | static struct ZFW_CTRL __iomem *zfw_ctrl; |
1755 | static volatile struct BOARD_CTRL __iomem *board_ctrl; | 1694 | static struct BOARD_CTRL __iomem *board_ctrl; |
1756 | static volatile struct CH_CTRL __iomem *ch_ctrl; | 1695 | static struct CH_CTRL __iomem *ch_ctrl; |
1757 | static volatile struct BUF_CTRL __iomem *buf_ctrl; | 1696 | static struct BUF_CTRL __iomem *buf_ctrl; |
1758 | uclong channel; | 1697 | __u32 channel; |
1759 | ucchar cmd; | 1698 | __u8 cmd; |
1760 | uclong param; | 1699 | __u32 param; |
1761 | uclong hw_ver, fw_ver; | 1700 | __u32 hw_ver, fw_ver; |
1762 | int special_count; | 1701 | int special_count; |
1763 | int delta_count; | 1702 | int delta_count; |
1764 | 1703 | ||
1765 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1704 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1766 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 1705 | zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1767 | 0xfffff); | ||
1768 | board_ctrl = &zfw_ctrl->board_ctrl; | 1706 | board_ctrl = &zfw_ctrl->board_ctrl; |
1769 | fw_ver = cy_readl(&board_ctrl->fw_version); | 1707 | fw_ver = readl(&board_ctrl->fw_version); |
1770 | hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> | 1708 | hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> |
1771 | mail_box_0); | 1709 | mail_box_0); |
1772 | 1710 | ||
1773 | while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { | 1711 | while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { |
1774 | special_count = 0; | 1712 | special_count = 0; |
1775 | delta_count = 0; | 1713 | delta_count = 0; |
1776 | info = &cy_port[channel + cinfo->first_line]; | 1714 | info = &cinfo->ports[channel]; |
1777 | if ((tty = info->tty) == 0) { | 1715 | if ((tty = info->tty) == NULL) |
1778 | continue; | 1716 | continue; |
1779 | } | 1717 | |
1780 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 1718 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
1781 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | 1719 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); |
1782 | 1720 | ||
@@ -1801,7 +1739,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1801 | delta_count++; | 1739 | delta_count++; |
1802 | if (info->flags & ASYNC_CHECK_CD) { | 1740 | if (info->flags & ASYNC_CHECK_CD) { |
1803 | if ((fw_ver > 241 ? ((u_long) param) : | 1741 | if ((fw_ver > 241 ? ((u_long) param) : |
1804 | cy_readl(&ch_ctrl->rs_status)) & | 1742 | readl(&ch_ctrl->rs_status)) & |
1805 | C_RS_DCD) { | 1743 | C_RS_DCD) { |
1806 | cy_sched_event(info, | 1744 | cy_sched_event(info, |
1807 | Cy_EVENT_OPEN_WAKEUP); | 1745 | Cy_EVENT_OPEN_WAKEUP); |
@@ -1833,8 +1771,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1833 | case C_CM_INTBACK2: | 1771 | case C_CM_INTBACK2: |
1834 | /* Reception Interrupt */ | 1772 | /* Reception Interrupt */ |
1835 | #ifdef CY_DEBUG_INTERRUPTS | 1773 | #ifdef CY_DEBUG_INTERRUPTS |
1836 | printk("cyz_interrupt: rcvd intr, card %d, " | 1774 | printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " |
1837 | "port %ld\n\r", info->card, channel); | 1775 | "port %ld\n", info->card, channel); |
1838 | #endif | 1776 | #endif |
1839 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1777 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); |
1840 | break; | 1778 | break; |
@@ -1843,8 +1781,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1843 | case C_CM_INTBACK: | 1781 | case C_CM_INTBACK: |
1844 | /* Transmission Interrupt */ | 1782 | /* Transmission Interrupt */ |
1845 | #ifdef CY_DEBUG_INTERRUPTS | 1783 | #ifdef CY_DEBUG_INTERRUPTS |
1846 | printk("cyz_interrupt: xmit intr, card %d, " | 1784 | printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " |
1847 | "port %ld\n\r", info->card, channel); | 1785 | "port %ld\n", info->card, channel); |
1848 | #endif | 1786 | #endif |
1849 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1787 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1850 | break; | 1788 | break; |
@@ -1865,18 +1803,19 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) | |||
1865 | #ifdef CONFIG_CYZ_INTR | 1803 | #ifdef CONFIG_CYZ_INTR |
1866 | static irqreturn_t cyz_interrupt(int irq, void *dev_id) | 1804 | static irqreturn_t cyz_interrupt(int irq, void *dev_id) |
1867 | { | 1805 | { |
1868 | struct cyclades_card *cinfo; | 1806 | struct cyclades_card *cinfo = dev_id; |
1869 | 1807 | ||
1870 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { | 1808 | if (unlikely(cinfo == NULL)) { |
1871 | #ifdef CY_DEBUG_INTERRUPTS | 1809 | #ifdef CY_DEBUG_INTERRUPTS |
1872 | printk("cyz_interrupt: spurious interrupt %d\n\r", irq); | 1810 | printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq); |
1873 | #endif | 1811 | #endif |
1874 | return IRQ_NONE; /* spurious interrupt */ | 1812 | return IRQ_NONE; /* spurious interrupt */ |
1875 | } | 1813 | } |
1876 | 1814 | ||
1877 | if (!ISZLOADED(*cinfo)) { | 1815 | if (unlikely(!ISZLOADED(*cinfo))) { |
1878 | #ifdef CY_DEBUG_INTERRUPTS | 1816 | #ifdef CY_DEBUG_INTERRUPTS |
1879 | printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); | 1817 | printk(KERN_DEBUG "cyz_interrupt: board not yet loaded " |
1818 | "(IRQ%d).\n", irq); | ||
1880 | #endif | 1819 | #endif |
1881 | return IRQ_NONE; | 1820 | return IRQ_NONE; |
1882 | } | 1821 | } |
@@ -1890,19 +1829,18 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id) | |||
1890 | static void cyz_rx_restart(unsigned long arg) | 1829 | static void cyz_rx_restart(unsigned long arg) |
1891 | { | 1830 | { |
1892 | struct cyclades_port *info = (struct cyclades_port *)arg; | 1831 | struct cyclades_port *info = (struct cyclades_port *)arg; |
1832 | struct cyclades_card *card = info->card; | ||
1893 | int retval; | 1833 | int retval; |
1894 | int card = info->card; | 1834 | __u32 channel = info->line - card->first_line; |
1895 | uclong channel = (info->line) - (cy_card[card].first_line); | ||
1896 | unsigned long flags; | 1835 | unsigned long flags; |
1897 | 1836 | ||
1898 | CY_LOCK(info, flags); | 1837 | spin_lock_irqsave(&card->card_lock, flags); |
1899 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); | 1838 | retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L); |
1900 | if (retval != 0) { | 1839 | if (retval != 0) { |
1901 | printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", | 1840 | printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n", |
1902 | info->line, retval); | 1841 | info->line, retval); |
1903 | } | 1842 | } |
1904 | cyz_rx_full_timer[info->line].function = NULL; | 1843 | spin_unlock_irqrestore(&card->card_lock, flags); |
1905 | CY_UNLOCK(info, flags); | ||
1906 | } | 1844 | } |
1907 | 1845 | ||
1908 | #else /* CONFIG_CYZ_INTR */ | 1846 | #else /* CONFIG_CYZ_INTR */ |
@@ -1912,14 +1850,14 @@ static void cyz_poll(unsigned long arg) | |||
1912 | struct cyclades_card *cinfo; | 1850 | struct cyclades_card *cinfo; |
1913 | struct cyclades_port *info; | 1851 | struct cyclades_port *info; |
1914 | struct tty_struct *tty; | 1852 | struct tty_struct *tty; |
1915 | static volatile struct FIRM_ID *firm_id; | 1853 | static struct FIRM_ID *firm_id; |
1916 | static volatile struct ZFW_CTRL *zfw_ctrl; | 1854 | static struct ZFW_CTRL *zfw_ctrl; |
1917 | static volatile struct BOARD_CTRL *board_ctrl; | 1855 | static struct BOARD_CTRL *board_ctrl; |
1918 | static volatile struct CH_CTRL *ch_ctrl; | 1856 | static struct CH_CTRL *ch_ctrl; |
1919 | static volatile struct BUF_CTRL *buf_ctrl; | 1857 | static struct BUF_CTRL *buf_ctrl; |
1858 | unsigned long expires = jiffies + HZ; | ||
1920 | int card, port; | 1859 | int card, port; |
1921 | 1860 | ||
1922 | cyz_timerlist.expires = jiffies + (HZ); | ||
1923 | for (card = 0; card < NR_CARDS; card++) { | 1861 | for (card = 0; card < NR_CARDS; card++) { |
1924 | cinfo = &cy_card[card]; | 1862 | cinfo = &cy_card[card]; |
1925 | 1863 | ||
@@ -1930,12 +1868,12 @@ static void cyz_poll(unsigned long arg) | |||
1930 | 1868 | ||
1931 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1869 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1932 | zfw_ctrl = cinfo->base_addr + | 1870 | zfw_ctrl = cinfo->base_addr + |
1933 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1871 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
1934 | board_ctrl = &(zfw_ctrl->board_ctrl); | 1872 | board_ctrl = &(zfw_ctrl->board_ctrl); |
1935 | 1873 | ||
1936 | /* Skip first polling cycle to avoid racing conditions with the FW */ | 1874 | /* Skip first polling cycle to avoid racing conditions with the FW */ |
1937 | if (!cinfo->intr_enabled) { | 1875 | if (!cinfo->intr_enabled) { |
1938 | cinfo->nports = (int)cy_readl(&board_ctrl->n_channel); | 1876 | cinfo->nports = (int)readl(&board_ctrl->n_channel); |
1939 | cinfo->intr_enabled = 1; | 1877 | cinfo->intr_enabled = 1; |
1940 | continue; | 1878 | continue; |
1941 | } | 1879 | } |
@@ -1943,7 +1881,7 @@ static void cyz_poll(unsigned long arg) | |||
1943 | cyz_handle_cmd(cinfo); | 1881 | cyz_handle_cmd(cinfo); |
1944 | 1882 | ||
1945 | for (port = 0; port < cinfo->nports; port++) { | 1883 | for (port = 0; port < cinfo->nports; port++) { |
1946 | info = &cy_port[port + cinfo->first_line]; | 1884 | info = &cinfo->ports[port]; |
1947 | tty = info->tty; | 1885 | tty = info->tty; |
1948 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | 1886 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); |
1949 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1887 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
@@ -1953,9 +1891,9 @@ static void cyz_poll(unsigned long arg) | |||
1953 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1891 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1954 | } | 1892 | } |
1955 | /* poll every 'cyz_polling_cycle' period */ | 1893 | /* poll every 'cyz_polling_cycle' period */ |
1956 | cyz_timerlist.expires = jiffies + cyz_polling_cycle; | 1894 | expires = jiffies + cyz_polling_cycle; |
1957 | } | 1895 | } |
1958 | add_timer(&cyz_timerlist); | 1896 | mod_timer(&cyz_timerlist, expires); |
1959 | } /* cyz_poll */ | 1897 | } /* cyz_poll */ |
1960 | 1898 | ||
1961 | #endif /* CONFIG_CYZ_INTR */ | 1899 | #endif /* CONFIG_CYZ_INTR */ |
@@ -1968,20 +1906,21 @@ static void cyz_poll(unsigned long arg) | |||
1968 | */ | 1906 | */ |
1969 | static int startup(struct cyclades_port *info) | 1907 | static int startup(struct cyclades_port *info) |
1970 | { | 1908 | { |
1909 | struct cyclades_card *card; | ||
1971 | unsigned long flags; | 1910 | unsigned long flags; |
1972 | int retval = 0; | 1911 | int retval = 0; |
1973 | void __iomem *base_addr; | 1912 | void __iomem *base_addr; |
1974 | int card, chip, channel, index; | 1913 | int chip, channel, index; |
1975 | unsigned long page; | 1914 | unsigned long page; |
1976 | 1915 | ||
1977 | card = info->card; | 1916 | card = info->card; |
1978 | channel = (info->line) - (cy_card[card].first_line); | 1917 | channel = info->line - card->first_line; |
1979 | 1918 | ||
1980 | page = get_zeroed_page(GFP_KERNEL); | 1919 | page = get_zeroed_page(GFP_KERNEL); |
1981 | if (!page) | 1920 | if (!page) |
1982 | return -ENOMEM; | 1921 | return -ENOMEM; |
1983 | 1922 | ||
1984 | CY_LOCK(info, flags); | 1923 | spin_lock_irqsave(&card->card_lock, flags); |
1985 | 1924 | ||
1986 | if (info->flags & ASYNC_INITIALIZED) { | 1925 | if (info->flags & ASYNC_INITIALIZED) { |
1987 | free_page(page); | 1926 | free_page(page); |
@@ -2001,24 +1940,22 @@ static int startup(struct cyclades_port *info) | |||
2001 | else | 1940 | else |
2002 | info->xmit_buf = (unsigned char *)page; | 1941 | info->xmit_buf = (unsigned char *)page; |
2003 | 1942 | ||
2004 | CY_UNLOCK(info, flags); | 1943 | spin_unlock_irqrestore(&card->card_lock, flags); |
2005 | 1944 | ||
2006 | set_line_char(info); | 1945 | set_line_char(info); |
2007 | 1946 | ||
2008 | if (!IS_CYC_Z(cy_card[card])) { | 1947 | if (!IS_CYC_Z(*card)) { |
2009 | chip = channel >> 2; | 1948 | chip = channel >> 2; |
2010 | channel &= 0x03; | 1949 | channel &= 0x03; |
2011 | index = cy_card[card].bus_index; | 1950 | index = card->bus_index; |
2012 | base_addr = cy_card[card].base_addr + | 1951 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2013 | (cy_chip_offset[chip] << index); | ||
2014 | 1952 | ||
2015 | #ifdef CY_DEBUG_OPEN | 1953 | #ifdef CY_DEBUG_OPEN |
2016 | printk("cyc startup card %d, chip %d, channel %d, " | 1954 | printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, " |
2017 | "base_addr %lx\n", | 1955 | "base_addr %p\n", |
2018 | card, chip, channel, (long)base_addr); | 1956 | card, chip, channel, base_addr); |
2019 | /**/ | ||
2020 | #endif | 1957 | #endif |
2021 | CY_LOCK(info, flags); | 1958 | spin_lock_irqsave(&card->card_lock, flags); |
2022 | 1959 | ||
2023 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 1960 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
2024 | 1961 | ||
@@ -2034,14 +1971,14 @@ static int startup(struct cyclades_port *info) | |||
2034 | cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); | 1971 | cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); |
2035 | 1972 | ||
2036 | #ifdef CY_DEBUG_DTR | 1973 | #ifdef CY_DEBUG_DTR |
2037 | printk("cyc:startup raising DTR\n"); | 1974 | printk(KERN_DEBUG "cyc:startup raising DTR\n"); |
2038 | printk(" status: 0x%x, 0x%x\n", | 1975 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2039 | cy_readb(base_addr + (CyMSVR1 << index)), | 1976 | readb(base_addr + (CyMSVR1 << index)), |
2040 | cy_readb(base_addr + (CyMSVR2 << index))); | 1977 | readb(base_addr + (CyMSVR2 << index))); |
2041 | #endif | 1978 | #endif |
2042 | 1979 | ||
2043 | cy_writeb(base_addr + (CySRER << index), | 1980 | cy_writeb(base_addr + (CySRER << index), |
2044 | cy_readb(base_addr + (CySRER << index)) | CyRxData); | 1981 | readb(base_addr + (CySRER << index)) | CyRxData); |
2045 | info->flags |= ASYNC_INITIALIZED; | 1982 | info->flags |= ASYNC_INITIALIZED; |
2046 | 1983 | ||
2047 | if (info->tty) { | 1984 | if (info->tty) { |
@@ -2054,7 +1991,7 @@ static int startup(struct cyclades_port *info) | |||
2054 | info->idle_stats.recv_idle = | 1991 | info->idle_stats.recv_idle = |
2055 | info->idle_stats.xmit_idle = jiffies; | 1992 | info->idle_stats.xmit_idle = jiffies; |
2056 | 1993 | ||
2057 | CY_UNLOCK(info, flags); | 1994 | spin_unlock_irqrestore(&card->card_lock, flags); |
2058 | 1995 | ||
2059 | } else { | 1996 | } else { |
2060 | struct FIRM_ID __iomem *firm_id; | 1997 | struct FIRM_ID __iomem *firm_id; |
@@ -2063,24 +2000,23 @@ static int startup(struct cyclades_port *info) | |||
2063 | struct CH_CTRL __iomem *ch_ctrl; | 2000 | struct CH_CTRL __iomem *ch_ctrl; |
2064 | int retval; | 2001 | int retval; |
2065 | 2002 | ||
2066 | base_addr = cy_card[card].base_addr; | 2003 | base_addr = card->base_addr; |
2067 | 2004 | ||
2068 | firm_id = base_addr + ID_ADDRESS; | 2005 | firm_id = base_addr + ID_ADDRESS; |
2069 | if (!ISZLOADED(cy_card[card])) { | 2006 | if (!ISZLOADED(*card)) { |
2070 | return -ENODEV; | 2007 | return -ENODEV; |
2071 | } | 2008 | } |
2072 | 2009 | ||
2073 | zfw_ctrl = cy_card[card].base_addr + | 2010 | zfw_ctrl = card->base_addr + |
2074 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2011 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2075 | board_ctrl = &zfw_ctrl->board_ctrl; | 2012 | board_ctrl = &zfw_ctrl->board_ctrl; |
2076 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2013 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2077 | 2014 | ||
2078 | #ifdef CY_DEBUG_OPEN | 2015 | #ifdef CY_DEBUG_OPEN |
2079 | printk("cyc startup Z card %d, channel %d, base_addr %lx\n", | 2016 | printk(KERN_DEBUG "cyc startup Z card %d, channel %d, " |
2080 | card, channel, (long)base_addr); | 2017 | "base_addr %p\n", card, channel, base_addr); |
2081 | /**/ | ||
2082 | #endif | 2018 | #endif |
2083 | CY_LOCK(info, flags); | 2019 | spin_lock_irqsave(&card->card_lock, flags); |
2084 | 2020 | ||
2085 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); | 2021 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); |
2086 | #ifdef Z_WAKE | 2022 | #ifdef Z_WAKE |
@@ -2102,33 +2038,31 @@ static int startup(struct cyclades_port *info) | |||
2102 | #endif /* CONFIG_CYZ_INTR */ | 2038 | #endif /* CONFIG_CYZ_INTR */ |
2103 | #endif /* Z_WAKE */ | 2039 | #endif /* Z_WAKE */ |
2104 | 2040 | ||
2105 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 2041 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); |
2106 | if (retval != 0) { | 2042 | if (retval != 0) { |
2107 | printk("cyc:startup(1) retval on ttyC%d was %x\n", | 2043 | printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was " |
2108 | info->line, retval); | 2044 | "%x\n", info->line, retval); |
2109 | } | 2045 | } |
2110 | 2046 | ||
2111 | /* Flush RX buffers before raising DTR and RTS */ | 2047 | /* Flush RX buffers before raising DTR and RTS */ |
2112 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, | 2048 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L); |
2113 | 0L); | ||
2114 | if (retval != 0) { | 2049 | if (retval != 0) { |
2115 | printk("cyc:startup(2) retval on ttyC%d was %x\n", | 2050 | printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was " |
2116 | info->line, retval); | 2051 | "%x\n", info->line, retval); |
2117 | } | 2052 | } |
2118 | 2053 | ||
2119 | /* set timeout !!! */ | 2054 | /* set timeout !!! */ |
2120 | /* set RTS and DTR !!! */ | 2055 | /* set RTS and DTR !!! */ |
2121 | cy_writel(&ch_ctrl[channel].rs_control, | 2056 | cy_writel(&ch_ctrl[channel].rs_control, |
2122 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | | 2057 | readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | |
2123 | C_RS_DTR); | 2058 | C_RS_DTR); |
2124 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2059 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); |
2125 | C_CM_IOCTLM, 0L); | ||
2126 | if (retval != 0) { | 2060 | if (retval != 0) { |
2127 | printk("cyc:startup(3) retval on ttyC%d was %x\n", | 2061 | printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was " |
2128 | info->line, retval); | 2062 | "%x\n", info->line, retval); |
2129 | } | 2063 | } |
2130 | #ifdef CY_DEBUG_DTR | 2064 | #ifdef CY_DEBUG_DTR |
2131 | printk("cyc:startup raising Z DTR\n"); | 2065 | printk(KERN_DEBUG "cyc:startup raising Z DTR\n"); |
2132 | #endif | 2066 | #endif |
2133 | 2067 | ||
2134 | /* enable send, recv, modem !!! */ | 2068 | /* enable send, recv, modem !!! */ |
@@ -2144,51 +2078,50 @@ static int startup(struct cyclades_port *info) | |||
2144 | info->idle_stats.recv_idle = | 2078 | info->idle_stats.recv_idle = |
2145 | info->idle_stats.xmit_idle = jiffies; | 2079 | info->idle_stats.xmit_idle = jiffies; |
2146 | 2080 | ||
2147 | CY_UNLOCK(info, flags); | 2081 | spin_unlock_irqrestore(&card->card_lock, flags); |
2148 | } | 2082 | } |
2149 | 2083 | ||
2150 | #ifdef CY_DEBUG_OPEN | 2084 | #ifdef CY_DEBUG_OPEN |
2151 | printk(" cyc startup done\n"); | 2085 | printk(KERN_DEBUG "cyc startup done\n"); |
2152 | #endif | 2086 | #endif |
2153 | return 0; | 2087 | return 0; |
2154 | 2088 | ||
2155 | errout: | 2089 | errout: |
2156 | CY_UNLOCK(info, flags); | 2090 | spin_unlock_irqrestore(&card->card_lock, flags); |
2157 | return retval; | 2091 | return retval; |
2158 | } /* startup */ | 2092 | } /* startup */ |
2159 | 2093 | ||
2160 | static void start_xmit(struct cyclades_port *info) | 2094 | static void start_xmit(struct cyclades_port *info) |
2161 | { | 2095 | { |
2096 | struct cyclades_card *card; | ||
2162 | unsigned long flags; | 2097 | unsigned long flags; |
2163 | void __iomem *base_addr; | 2098 | void __iomem *base_addr; |
2164 | int card, chip, channel, index; | 2099 | int chip, channel, index; |
2165 | 2100 | ||
2166 | card = info->card; | 2101 | card = info->card; |
2167 | channel = (info->line) - (cy_card[card].first_line); | 2102 | channel = info->line - card->first_line; |
2168 | if (!IS_CYC_Z(cy_card[card])) { | 2103 | if (!IS_CYC_Z(*card)) { |
2169 | chip = channel >> 2; | 2104 | chip = channel >> 2; |
2170 | channel &= 0x03; | 2105 | channel &= 0x03; |
2171 | index = cy_card[card].bus_index; | 2106 | index = card->bus_index; |
2172 | base_addr = cy_card[card].base_addr + | 2107 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2173 | (cy_chip_offset[chip] << index); | ||
2174 | 2108 | ||
2175 | CY_LOCK(info, flags); | 2109 | spin_lock_irqsave(&card->card_lock, flags); |
2176 | cy_writeb(base_addr + (CyCAR << index), channel); | 2110 | cy_writeb(base_addr + (CyCAR << index), channel); |
2177 | cy_writeb(base_addr + (CySRER << index), | 2111 | cy_writeb(base_addr + (CySRER << index), |
2178 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | 2112 | readb(base_addr + (CySRER << index)) | CyTxRdy); |
2179 | CY_UNLOCK(info, flags); | 2113 | spin_unlock_irqrestore(&card->card_lock, flags); |
2180 | } else { | 2114 | } else { |
2181 | #ifdef CONFIG_CYZ_INTR | 2115 | #ifdef CONFIG_CYZ_INTR |
2182 | int retval; | 2116 | int retval; |
2183 | 2117 | ||
2184 | CY_LOCK(info, flags); | 2118 | spin_lock_irqsave(&card->card_lock, flags); |
2185 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, | 2119 | retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L); |
2186 | 0L); | ||
2187 | if (retval != 0) { | 2120 | if (retval != 0) { |
2188 | printk("cyc:start_xmit retval on ttyC%d was %x\n", | 2121 | printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was " |
2189 | info->line, retval); | 2122 | "%x\n", info->line, retval); |
2190 | } | 2123 | } |
2191 | CY_UNLOCK(info, flags); | 2124 | spin_unlock_irqrestore(&card->card_lock, flags); |
2192 | #else /* CONFIG_CYZ_INTR */ | 2125 | #else /* CONFIG_CYZ_INTR */ |
2193 | /* Don't have to do anything at this time */ | 2126 | /* Don't have to do anything at this time */ |
2194 | #endif /* CONFIG_CYZ_INTR */ | 2127 | #endif /* CONFIG_CYZ_INTR */ |
@@ -2201,30 +2134,30 @@ static void start_xmit(struct cyclades_port *info) | |||
2201 | */ | 2134 | */ |
2202 | static void shutdown(struct cyclades_port *info) | 2135 | static void shutdown(struct cyclades_port *info) |
2203 | { | 2136 | { |
2137 | struct cyclades_card *card; | ||
2204 | unsigned long flags; | 2138 | unsigned long flags; |
2205 | void __iomem *base_addr; | 2139 | void __iomem *base_addr; |
2206 | int card, chip, channel, index; | 2140 | int chip, channel, index; |
2207 | 2141 | ||
2208 | if (!(info->flags & ASYNC_INITIALIZED)) { | 2142 | if (!(info->flags & ASYNC_INITIALIZED)) { |
2209 | return; | 2143 | return; |
2210 | } | 2144 | } |
2211 | 2145 | ||
2212 | card = info->card; | 2146 | card = info->card; |
2213 | channel = info->line - cy_card[card].first_line; | 2147 | channel = info->line - card->first_line; |
2214 | if (!IS_CYC_Z(cy_card[card])) { | 2148 | if (!IS_CYC_Z(*card)) { |
2215 | chip = channel >> 2; | 2149 | chip = channel >> 2; |
2216 | channel &= 0x03; | 2150 | channel &= 0x03; |
2217 | index = cy_card[card].bus_index; | 2151 | index = card->bus_index; |
2218 | base_addr = cy_card[card].base_addr + | 2152 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2219 | (cy_chip_offset[chip] << index); | ||
2220 | 2153 | ||
2221 | #ifdef CY_DEBUG_OPEN | 2154 | #ifdef CY_DEBUG_OPEN |
2222 | printk("cyc shutdown Y card %d, chip %d, channel %d, " | 2155 | printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, " |
2223 | "base_addr %lx\n", | 2156 | "channel %d, base_addr %p\n", |
2224 | card, chip, channel, (long)base_addr); | 2157 | card, chip, channel, base_addr); |
2225 | #endif | 2158 | #endif |
2226 | 2159 | ||
2227 | CY_LOCK(info, flags); | 2160 | spin_lock_irqsave(&card->card_lock, flags); |
2228 | 2161 | ||
2229 | /* Clear delta_msr_wait queue to avoid mem leaks. */ | 2162 | /* Clear delta_msr_wait queue to avoid mem leaks. */ |
2230 | wake_up_interruptible(&info->delta_msr_wait); | 2163 | wake_up_interruptible(&info->delta_msr_wait); |
@@ -2240,10 +2173,10 @@ static void shutdown(struct cyclades_port *info) | |||
2240 | cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); | 2173 | cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); |
2241 | cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); | 2174 | cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); |
2242 | #ifdef CY_DEBUG_DTR | 2175 | #ifdef CY_DEBUG_DTR |
2243 | printk("cyc shutdown dropping DTR\n"); | 2176 | printk(KERN_DEBUG "cyc shutdown dropping DTR\n"); |
2244 | printk(" status: 0x%x, 0x%x\n", | 2177 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2245 | cy_readb(base_addr + (CyMSVR1 << index)), | 2178 | readb(base_addr + (CyMSVR1 << index)), |
2246 | cy_readb(base_addr + (CyMSVR2 << index))); | 2179 | readb(base_addr + (CyMSVR2 << index))); |
2247 | #endif | 2180 | #endif |
2248 | } | 2181 | } |
2249 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); | 2182 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); |
@@ -2254,7 +2187,7 @@ static void shutdown(struct cyclades_port *info) | |||
2254 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 2187 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2255 | } | 2188 | } |
2256 | info->flags &= ~ASYNC_INITIALIZED; | 2189 | info->flags &= ~ASYNC_INITIALIZED; |
2257 | CY_UNLOCK(info, flags); | 2190 | spin_unlock_irqrestore(&card->card_lock, flags); |
2258 | } else { | 2191 | } else { |
2259 | struct FIRM_ID __iomem *firm_id; | 2192 | struct FIRM_ID __iomem *firm_id; |
2260 | struct ZFW_CTRL __iomem *zfw_ctrl; | 2193 | struct ZFW_CTRL __iomem *zfw_ctrl; |
@@ -2262,23 +2195,23 @@ static void shutdown(struct cyclades_port *info) | |||
2262 | struct CH_CTRL __iomem *ch_ctrl; | 2195 | struct CH_CTRL __iomem *ch_ctrl; |
2263 | int retval; | 2196 | int retval; |
2264 | 2197 | ||
2265 | base_addr = cy_card[card].base_addr; | 2198 | base_addr = card->base_addr; |
2266 | #ifdef CY_DEBUG_OPEN | 2199 | #ifdef CY_DEBUG_OPEN |
2267 | printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", | 2200 | printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, " |
2268 | card, channel, (long)base_addr); | 2201 | "base_addr %p\n", card, channel, base_addr); |
2269 | #endif | 2202 | #endif |
2270 | 2203 | ||
2271 | firm_id = base_addr + ID_ADDRESS; | 2204 | firm_id = base_addr + ID_ADDRESS; |
2272 | if (!ISZLOADED(cy_card[card])) { | 2205 | if (!ISZLOADED(*card)) { |
2273 | return; | 2206 | return; |
2274 | } | 2207 | } |
2275 | 2208 | ||
2276 | zfw_ctrl = cy_card[card].base_addr + | 2209 | zfw_ctrl = card->base_addr + |
2277 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2210 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2278 | board_ctrl = &zfw_ctrl->board_ctrl; | 2211 | board_ctrl = &zfw_ctrl->board_ctrl; |
2279 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2212 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2280 | 2213 | ||
2281 | CY_LOCK(info, flags); | 2214 | spin_lock_irqsave(&card->card_lock, flags); |
2282 | 2215 | ||
2283 | if (info->xmit_buf) { | 2216 | if (info->xmit_buf) { |
2284 | unsigned char *temp; | 2217 | unsigned char *temp; |
@@ -2289,16 +2222,16 @@ static void shutdown(struct cyclades_port *info) | |||
2289 | 2222 | ||
2290 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { | 2223 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { |
2291 | cy_writel(&ch_ctrl[channel].rs_control, | 2224 | cy_writel(&ch_ctrl[channel].rs_control, |
2292 | (uclong)(cy_readl(&ch_ctrl[channel].rs_control)& | 2225 | (__u32)(readl(&ch_ctrl[channel].rs_control) & |
2293 | ~(C_RS_RTS | C_RS_DTR))); | 2226 | ~(C_RS_RTS | C_RS_DTR))); |
2294 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2227 | retval = cyz_issue_cmd(info->card, channel, |
2295 | C_CM_IOCTLM, 0L); | 2228 | C_CM_IOCTLM, 0L); |
2296 | if (retval != 0) { | 2229 | if (retval != 0) { |
2297 | printk("cyc:shutdown retval on ttyC%d was %x\n", | 2230 | printk(KERN_ERR"cyc:shutdown retval on ttyC%d " |
2298 | info->line, retval); | 2231 | "was %x\n", info->line, retval); |
2299 | } | 2232 | } |
2300 | #ifdef CY_DEBUG_DTR | 2233 | #ifdef CY_DEBUG_DTR |
2301 | printk("cyc:shutdown dropping Z DTR\n"); | 2234 | printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n"); |
2302 | #endif | 2235 | #endif |
2303 | } | 2236 | } |
2304 | 2237 | ||
@@ -2307,11 +2240,11 @@ static void shutdown(struct cyclades_port *info) | |||
2307 | } | 2240 | } |
2308 | info->flags &= ~ASYNC_INITIALIZED; | 2241 | info->flags &= ~ASYNC_INITIALIZED; |
2309 | 2242 | ||
2310 | CY_UNLOCK(info, flags); | 2243 | spin_unlock_irqrestore(&card->card_lock, flags); |
2311 | } | 2244 | } |
2312 | 2245 | ||
2313 | #ifdef CY_DEBUG_OPEN | 2246 | #ifdef CY_DEBUG_OPEN |
2314 | printk(" cyc shutdown done\n"); | 2247 | printk(KERN_DEBUG "cyc shutdown done\n"); |
2315 | #endif | 2248 | #endif |
2316 | } /* shutdown */ | 2249 | } /* shutdown */ |
2317 | 2250 | ||
@@ -2332,7 +2265,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2332 | int retval; | 2265 | int retval; |
2333 | void __iomem *base_addr; | 2266 | void __iomem *base_addr; |
2334 | 2267 | ||
2335 | cinfo = &cy_card[info->card]; | 2268 | cinfo = info->card; |
2336 | channel = info->line - cinfo->first_line; | 2269 | channel = info->line - cinfo->first_line; |
2337 | 2270 | ||
2338 | /* | 2271 | /* |
@@ -2340,9 +2273,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2340 | * until it's done, and then try again. | 2273 | * until it's done, and then try again. |
2341 | */ | 2274 | */ |
2342 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2275 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2343 | if (info->flags & ASYNC_CLOSING) { | 2276 | wait_event_interruptible(info->close_wait, |
2344 | interruptible_sleep_on(&info->close_wait); | 2277 | !(info->flags & ASYNC_CLOSING)); |
2345 | } | ||
2346 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 2278 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
2347 | } | 2279 | } |
2348 | 2280 | ||
@@ -2365,17 +2297,16 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2365 | retval = 0; | 2297 | retval = 0; |
2366 | add_wait_queue(&info->open_wait, &wait); | 2298 | add_wait_queue(&info->open_wait, &wait); |
2367 | #ifdef CY_DEBUG_OPEN | 2299 | #ifdef CY_DEBUG_OPEN |
2368 | printk("cyc block_til_ready before block: ttyC%d, count = %d\n", | 2300 | printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, " |
2369 | info->line, info->count); | 2301 | "count = %d\n", info->line, info->count); |
2370 | /**/ | ||
2371 | #endif | 2302 | #endif |
2372 | CY_LOCK(info, flags); | 2303 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2373 | if (!tty_hung_up_p(filp)) | 2304 | if (!tty_hung_up_p(filp)) |
2374 | info->count--; | 2305 | info->count--; |
2375 | CY_UNLOCK(info, flags); | 2306 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2376 | #ifdef CY_DEBUG_COUNT | 2307 | #ifdef CY_DEBUG_COUNT |
2377 | printk("cyc block_til_ready: (%d): decrementing count to %d\n", | 2308 | printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to " |
2378 | current->pid, info->count); | 2309 | "%d\n", current->pid, info->count); |
2379 | #endif | 2310 | #endif |
2380 | info->blocked_open++; | 2311 | info->blocked_open++; |
2381 | 2312 | ||
@@ -2386,7 +2317,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2386 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); | 2317 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
2387 | 2318 | ||
2388 | while (1) { | 2319 | while (1) { |
2389 | CY_LOCK(info, flags); | 2320 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2390 | if ((tty->termios->c_cflag & CBAUD)) { | 2321 | if ((tty->termios->c_cflag & CBAUD)) { |
2391 | cy_writeb(base_addr + (CyCAR << index), | 2322 | cy_writeb(base_addr + (CyCAR << index), |
2392 | (u_char) channel); | 2323 | (u_char) channel); |
@@ -2395,15 +2326,14 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2395 | cy_writeb(base_addr + (CyMSVR2 << index), | 2326 | cy_writeb(base_addr + (CyMSVR2 << index), |
2396 | CyDTR); | 2327 | CyDTR); |
2397 | #ifdef CY_DEBUG_DTR | 2328 | #ifdef CY_DEBUG_DTR |
2398 | printk("cyc:block_til_ready raising DTR\n"); | 2329 | printk(KERN_DEBUG "cyc:block_til_ready raising " |
2399 | printk(" status: 0x%x, 0x%x\n", | 2330 | "DTR\n"); |
2400 | cy_readb(base_addr + | 2331 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
2401 | (CyMSVR1 << index)), | 2332 | readb(base_addr + (CyMSVR1 << index)), |
2402 | cy_readb(base_addr + | 2333 | readb(base_addr + (CyMSVR2 << index))); |
2403 | (CyMSVR2 << index))); | ||
2404 | #endif | 2334 | #endif |
2405 | } | 2335 | } |
2406 | CY_UNLOCK(info, flags); | 2336 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2407 | 2337 | ||
2408 | set_current_state(TASK_INTERRUPTIBLE); | 2338 | set_current_state(TASK_INTERRUPTIBLE); |
2409 | if (tty_hung_up_p(filp) || | 2339 | if (tty_hung_up_p(filp) || |
@@ -2413,26 +2343,25 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2413 | break; | 2343 | break; |
2414 | } | 2344 | } |
2415 | 2345 | ||
2416 | CY_LOCK(info, flags); | 2346 | spin_lock_irqsave(&cinfo->card_lock, flags); |
2417 | cy_writeb(base_addr + (CyCAR << index), | 2347 | cy_writeb(base_addr + (CyCAR << index), |
2418 | (u_char) channel); | 2348 | (u_char) channel); |
2419 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || | 2349 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2420 | (cy_readb(base_addr + | 2350 | (readb(base_addr + |
2421 | (CyMSVR1 << index)) & CyDCD))) { | 2351 | (CyMSVR1 << index)) & CyDCD))) { |
2422 | CY_UNLOCK(info, flags); | 2352 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2423 | break; | 2353 | break; |
2424 | } | 2354 | } |
2425 | CY_UNLOCK(info, flags); | 2355 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
2426 | 2356 | ||
2427 | if (signal_pending(current)) { | 2357 | if (signal_pending(current)) { |
2428 | retval = -ERESTARTSYS; | 2358 | retval = -ERESTARTSYS; |
2429 | break; | 2359 | break; |
2430 | } | 2360 | } |
2431 | #ifdef CY_DEBUG_OPEN | 2361 | #ifdef CY_DEBUG_OPEN |
2432 | printk("cyc block_til_ready blocking: ttyC%d, " | 2362 | printk(KERN_DEBUG "cyc block_til_ready blocking: " |
2433 | "count = %d\n", | 2363 | "ttyC%d, count = %d\n", |
2434 | info->line, info->count); | 2364 | info->line, info->count); |
2435 | /**/ | ||
2436 | #endif | 2365 | #endif |
2437 | schedule(); | 2366 | schedule(); |
2438 | } | 2367 | } |
@@ -2446,31 +2375,30 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2446 | base_addr = cinfo->base_addr; | 2375 | base_addr = cinfo->base_addr; |
2447 | firm_id = base_addr + ID_ADDRESS; | 2376 | firm_id = base_addr + ID_ADDRESS; |
2448 | if (!ISZLOADED(*cinfo)) { | 2377 | if (!ISZLOADED(*cinfo)) { |
2449 | current->state = TASK_RUNNING; | 2378 | __set_current_state(TASK_RUNNING); |
2450 | remove_wait_queue(&info->open_wait, &wait); | 2379 | remove_wait_queue(&info->open_wait, &wait); |
2451 | return -EINVAL; | 2380 | return -EINVAL; |
2452 | } | 2381 | } |
2453 | 2382 | ||
2454 | zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | 2383 | zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff); |
2455 | 0xfffff); | ||
2456 | board_ctrl = &zfw_ctrl->board_ctrl; | 2384 | board_ctrl = &zfw_ctrl->board_ctrl; |
2457 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2385 | ch_ctrl = zfw_ctrl->ch_ctrl; |
2458 | 2386 | ||
2459 | while (1) { | 2387 | while (1) { |
2460 | if ((tty->termios->c_cflag & CBAUD)) { | 2388 | if ((tty->termios->c_cflag & CBAUD)) { |
2461 | cy_writel(&ch_ctrl[channel].rs_control, | 2389 | cy_writel(&ch_ctrl[channel].rs_control, |
2462 | cy_readl(&ch_ctrl[channel]. | 2390 | readl(&ch_ctrl[channel].rs_control) | |
2463 | rs_control) | (C_RS_RTS | | 2391 | C_RS_RTS | C_RS_DTR); |
2464 | C_RS_DTR)); | 2392 | retval = cyz_issue_cmd(cinfo, |
2465 | retval = cyz_issue_cmd(&cy_card[info->card], | 2393 | channel, C_CM_IOCTLM, 0L); |
2466 | channel, C_CM_IOCTLM, 0L); | ||
2467 | if (retval != 0) { | 2394 | if (retval != 0) { |
2468 | printk("cyc:block_til_ready retval on " | 2395 | printk(KERN_ERR "cyc:block_til_ready " |
2469 | "ttyC%d was %x\n", | 2396 | "retval on ttyC%d was %x\n", |
2470 | info->line, retval); | 2397 | info->line, retval); |
2471 | } | 2398 | } |
2472 | #ifdef CY_DEBUG_DTR | 2399 | #ifdef CY_DEBUG_DTR |
2473 | printk("cyc:block_til_ready raising Z DTR\n"); | 2400 | printk(KERN_DEBUG "cyc:block_til_ready raising " |
2401 | "Z DTR\n"); | ||
2474 | #endif | 2402 | #endif |
2475 | } | 2403 | } |
2476 | 2404 | ||
@@ -2482,7 +2410,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2482 | break; | 2410 | break; |
2483 | } | 2411 | } |
2484 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || | 2412 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2485 | (cy_readl(&ch_ctrl[channel].rs_status) & | 2413 | (readl(&ch_ctrl[channel].rs_status) & |
2486 | C_RS_DCD))) { | 2414 | C_RS_DCD))) { |
2487 | break; | 2415 | break; |
2488 | } | 2416 | } |
@@ -2491,28 +2419,26 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2491 | break; | 2419 | break; |
2492 | } | 2420 | } |
2493 | #ifdef CY_DEBUG_OPEN | 2421 | #ifdef CY_DEBUG_OPEN |
2494 | printk("cyc block_til_ready blocking: ttyC%d, " | 2422 | printk(KERN_DEBUG "cyc block_til_ready blocking: " |
2495 | "count = %d\n", | 2423 | "ttyC%d, count = %d\n", |
2496 | info->line, info->count); | 2424 | info->line, info->count); |
2497 | /**/ | ||
2498 | #endif | 2425 | #endif |
2499 | schedule(); | 2426 | schedule(); |
2500 | } | 2427 | } |
2501 | } | 2428 | } |
2502 | current->state = TASK_RUNNING; | 2429 | __set_current_state(TASK_RUNNING); |
2503 | remove_wait_queue(&info->open_wait, &wait); | 2430 | remove_wait_queue(&info->open_wait, &wait); |
2504 | if (!tty_hung_up_p(filp)) { | 2431 | if (!tty_hung_up_p(filp)) { |
2505 | info->count++; | 2432 | info->count++; |
2506 | #ifdef CY_DEBUG_COUNT | 2433 | #ifdef CY_DEBUG_COUNT |
2507 | printk("cyc:block_til_ready (%d): incrementing count to %d\n", | 2434 | printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing " |
2508 | current->pid, info->count); | 2435 | "count to %d\n", current->pid, info->count); |
2509 | #endif | 2436 | #endif |
2510 | } | 2437 | } |
2511 | info->blocked_open--; | 2438 | info->blocked_open--; |
2512 | #ifdef CY_DEBUG_OPEN | 2439 | #ifdef CY_DEBUG_OPEN |
2513 | printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", | 2440 | printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, " |
2514 | info->line, info->count); | 2441 | "count = %d\n", info->line, info->count); |
2515 | /**/ | ||
2516 | #endif | 2442 | #endif |
2517 | if (retval) | 2443 | if (retval) |
2518 | return retval; | 2444 | return retval; |
@@ -2527,13 +2453,20 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
2527 | static int cy_open(struct tty_struct *tty, struct file *filp) | 2453 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2528 | { | 2454 | { |
2529 | struct cyclades_port *info; | 2455 | struct cyclades_port *info; |
2456 | unsigned int i; | ||
2530 | int retval, line; | 2457 | int retval, line; |
2531 | 2458 | ||
2532 | line = tty->index; | 2459 | line = tty->index; |
2533 | if ((line < 0) || (NR_PORTS <= line)) { | 2460 | if ((line < 0) || (NR_PORTS <= line)) { |
2534 | return -ENODEV; | 2461 | return -ENODEV; |
2535 | } | 2462 | } |
2536 | info = &cy_port[line]; | 2463 | for (i = 0; i < NR_CARDS; i++) |
2464 | if (line < cy_card[i].first_line + cy_card[i].nports && | ||
2465 | line >= cy_card[i].first_line) | ||
2466 | break; | ||
2467 | if (i >= NR_CARDS) | ||
2468 | return -ENODEV; | ||
2469 | info = &cy_card[i].ports[line - cy_card[i].first_line]; | ||
2537 | if (info->line < 0) { | 2470 | if (info->line < 0) { |
2538 | return -ENODEV; | 2471 | return -ENODEV; |
2539 | } | 2472 | } |
@@ -2542,23 +2475,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2542 | treat it as absent from the system. This | 2475 | treat it as absent from the system. This |
2543 | will make the user pay attention. | 2476 | will make the user pay attention. |
2544 | */ | 2477 | */ |
2545 | if (IS_CYC_Z(cy_card[info->card])) { | 2478 | if (IS_CYC_Z(*info->card)) { |
2546 | struct cyclades_card *cinfo = &cy_card[info->card]; | 2479 | struct cyclades_card *cinfo = info->card; |
2547 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; | 2480 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; |
2548 | 2481 | ||
2549 | if (!ISZLOADED(*cinfo)) { | 2482 | if (!ISZLOADED(*cinfo)) { |
2550 | if (((ZE_V1 == cy_readl( | 2483 | if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *) |
2551 | &((struct RUNTIME_9060 __iomem *) | ||
2552 | (cinfo->ctl_addr))->mail_box_0)) && | 2484 | (cinfo->ctl_addr))->mail_box_0)) && |
2553 | Z_FPGA_CHECK(*cinfo)) && | 2485 | Z_FPGA_CHECK(*cinfo)) && |
2554 | (ZFIRM_HLT == cy_readl( | 2486 | (ZFIRM_HLT == readl( |
2555 | &firm_id->signature))) { | 2487 | &firm_id->signature))) { |
2556 | printk("cyc:Cyclades-Z Error: you need an " | 2488 | printk(KERN_ERR "cyc:Cyclades-Z Error: you " |
2557 | "external power supply for this number " | 2489 | "need an external power supply for " |
2558 | "of ports.\n\rFirmware halted.\r\n"); | 2490 | "this number of ports.\nFirmware " |
2491 | "halted.\n"); | ||
2559 | } else { | 2492 | } else { |
2560 | printk("cyc:Cyclades-Z firmware not yet " | 2493 | printk(KERN_ERR "cyc:Cyclades-Z firmware not " |
2561 | "loaded\n"); | 2494 | "yet loaded\n"); |
2562 | } | 2495 | } |
2563 | return -ENODEV; | 2496 | return -ENODEV; |
2564 | } | 2497 | } |
@@ -2572,24 +2505,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2572 | struct BOARD_CTRL __iomem *board_ctrl; | 2505 | struct BOARD_CTRL __iomem *board_ctrl; |
2573 | 2506 | ||
2574 | zfw_ctrl = cinfo->base_addr + | 2507 | zfw_ctrl = cinfo->base_addr + |
2575 | (cy_readl(&firm_id->zfwctrl_addr) & | 2508 | (readl(&firm_id->zfwctrl_addr) & |
2576 | 0xfffff); | 2509 | 0xfffff); |
2577 | 2510 | ||
2578 | board_ctrl = &zfw_ctrl->board_ctrl; | 2511 | board_ctrl = &zfw_ctrl->board_ctrl; |
2579 | 2512 | ||
2580 | /* Enable interrupts on the PLX chip */ | 2513 | /* Enable interrupts on the PLX chip */ |
2581 | cy_writew(cinfo->ctl_addr + 0x68, | 2514 | cy_writew(cinfo->ctl_addr + 0x68, |
2582 | cy_readw(cinfo->ctl_addr + | 2515 | readw(cinfo->ctl_addr + 0x68) | 0x0900); |
2583 | 0x68) | 0x0900); | ||
2584 | /* Enable interrupts on the FW */ | 2516 | /* Enable interrupts on the FW */ |
2585 | retval = cyz_issue_cmd(cinfo, 0, | 2517 | retval = cyz_issue_cmd(cinfo, 0, |
2586 | C_CM_IRQ_ENBL, 0L); | 2518 | C_CM_IRQ_ENBL, 0L); |
2587 | if (retval != 0) { | 2519 | if (retval != 0) { |
2588 | printk("cyc:IRQ enable retval was %x\n", | 2520 | printk(KERN_ERR "cyc:IRQ enable retval " |
2589 | retval); | 2521 | "was %x\n", retval); |
2590 | } | 2522 | } |
2591 | cinfo->nports = | 2523 | cinfo->nports = |
2592 | (int)cy_readl(&board_ctrl->n_channel); | 2524 | (int)readl(&board_ctrl->n_channel); |
2593 | cinfo->intr_enabled = 1; | 2525 | cinfo->intr_enabled = 1; |
2594 | } | 2526 | } |
2595 | } | 2527 | } |
@@ -2599,7 +2531,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2599 | return -ENODEV; | 2531 | return -ENODEV; |
2600 | } | 2532 | } |
2601 | #ifdef CY_DEBUG_OTHER | 2533 | #ifdef CY_DEBUG_OTHER |
2602 | printk("cyc:cy_open ttyC%d\n", info->line); /* */ | 2534 | printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); |
2603 | #endif | 2535 | #endif |
2604 | tty->driver_data = info; | 2536 | tty->driver_data = info; |
2605 | info->tty = tty; | 2537 | info->tty = tty; |
@@ -2607,12 +2539,12 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2607 | return -ENODEV; | 2539 | return -ENODEV; |
2608 | } | 2540 | } |
2609 | #ifdef CY_DEBUG_OPEN | 2541 | #ifdef CY_DEBUG_OPEN |
2610 | printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count); | 2542 | printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, |
2611 | /**/ | 2543 | info->count); |
2612 | #endif | 2544 | #endif |
2613 | info->count++; | 2545 | info->count++; |
2614 | #ifdef CY_DEBUG_COUNT | 2546 | #ifdef CY_DEBUG_COUNT |
2615 | printk("cyc:cy_open (%d): incrementing count to %d\n", | 2547 | printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", |
2616 | current->pid, info->count); | 2548 | current->pid, info->count); |
2617 | #endif | 2549 | #endif |
2618 | 2550 | ||
@@ -2620,8 +2552,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2620 | * If the port is the middle of closing, bail out now | 2552 | * If the port is the middle of closing, bail out now |
2621 | */ | 2553 | */ |
2622 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2554 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2623 | if (info->flags & ASYNC_CLOSING) | 2555 | wait_event_interruptible(info->close_wait, |
2624 | interruptible_sleep_on(&info->close_wait); | 2556 | !(info->flags & ASYNC_CLOSING)); |
2625 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 2557 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
2626 | } | 2558 | } |
2627 | 2559 | ||
@@ -2636,8 +2568,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2636 | retval = block_til_ready(tty, filp, info); | 2568 | retval = block_til_ready(tty, filp, info); |
2637 | if (retval) { | 2569 | if (retval) { |
2638 | #ifdef CY_DEBUG_OPEN | 2570 | #ifdef CY_DEBUG_OPEN |
2639 | printk("cyc:cy_open returning after block_til_ready with %d\n", | 2571 | printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready " |
2640 | retval); | 2572 | "with %d\n", retval); |
2641 | #endif | 2573 | #endif |
2642 | return retval; | 2574 | return retval; |
2643 | } | 2575 | } |
@@ -2645,8 +2577,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2645 | info->throttle = 0; | 2577 | info->throttle = 0; |
2646 | 2578 | ||
2647 | #ifdef CY_DEBUG_OPEN | 2579 | #ifdef CY_DEBUG_OPEN |
2648 | printk(" cyc:cy_open done\n"); | 2580 | printk(KERN_DEBUG "cyc:cy_open done\n"); |
2649 | /**/ | ||
2650 | #endif | 2581 | #endif |
2651 | return 0; | 2582 | return 0; |
2652 | } /* cy_open */ | 2583 | } /* cy_open */ |
@@ -2656,9 +2587,10 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
2656 | */ | 2587 | */ |
2657 | static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | 2588 | static void cy_wait_until_sent(struct tty_struct *tty, int timeout) |
2658 | { | 2589 | { |
2659 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2590 | struct cyclades_card *card; |
2591 | struct cyclades_port *info = tty->driver_data; | ||
2660 | void __iomem *base_addr; | 2592 | void __iomem *base_addr; |
2661 | int card, chip, channel, index; | 2593 | int chip, channel, index; |
2662 | unsigned long orig_jiffies; | 2594 | unsigned long orig_jiffies; |
2663 | int char_time; | 2595 | int char_time; |
2664 | 2596 | ||
@@ -2697,20 +2629,19 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2697 | if (!timeout || timeout > 2 * info->timeout) | 2629 | if (!timeout || timeout > 2 * info->timeout) |
2698 | timeout = 2 * info->timeout; | 2630 | timeout = 2 * info->timeout; |
2699 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2631 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2700 | printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); | 2632 | printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...", |
2701 | printk("jiff=%lu...", jiffies); | 2633 | timeout, char_time, jiffies); |
2702 | #endif | 2634 | #endif |
2703 | card = info->card; | 2635 | card = info->card; |
2704 | channel = (info->line) - (cy_card[card].first_line); | 2636 | channel = (info->line) - (card->first_line); |
2705 | if (!IS_CYC_Z(cy_card[card])) { | 2637 | if (!IS_CYC_Z(*card)) { |
2706 | chip = channel >> 2; | 2638 | chip = channel >> 2; |
2707 | channel &= 0x03; | 2639 | channel &= 0x03; |
2708 | index = cy_card[card].bus_index; | 2640 | index = card->bus_index; |
2709 | base_addr = | 2641 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
2710 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | 2642 | while (readb(base_addr + (CySRER << index)) & CyTxRdy) { |
2711 | while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) { | ||
2712 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2643 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2713 | printk("Not clean (jiff=%lu)...", jiffies); | 2644 | printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies); |
2714 | #endif | 2645 | #endif |
2715 | if (msleep_interruptible(jiffies_to_msecs(char_time))) | 2646 | if (msleep_interruptible(jiffies_to_msecs(char_time))) |
2716 | break; | 2647 | break; |
@@ -2718,13 +2649,11 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2718 | timeout)) | 2649 | timeout)) |
2719 | break; | 2650 | break; |
2720 | } | 2651 | } |
2721 | } else { | ||
2722 | /* Nothing to do! */ | ||
2723 | } | 2652 | } |
2724 | /* Run one more char cycle */ | 2653 | /* Run one more char cycle */ |
2725 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | 2654 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
2726 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2655 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2727 | printk("Clean (jiff=%lu)...done\n", jiffies); | 2656 | printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies); |
2728 | #endif | 2657 | #endif |
2729 | } | 2658 | } |
2730 | 2659 | ||
@@ -2733,25 +2662,29 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout) | |||
2733 | */ | 2662 | */ |
2734 | static void cy_close(struct tty_struct *tty, struct file *filp) | 2663 | static void cy_close(struct tty_struct *tty, struct file *filp) |
2735 | { | 2664 | { |
2736 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2665 | struct cyclades_port *info = tty->driver_data; |
2666 | struct cyclades_card *card; | ||
2737 | unsigned long flags; | 2667 | unsigned long flags; |
2738 | 2668 | ||
2739 | #ifdef CY_DEBUG_OTHER | 2669 | #ifdef CY_DEBUG_OTHER |
2740 | printk("cyc:cy_close ttyC%d\n", info->line); | 2670 | printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line); |
2741 | #endif | 2671 | #endif |
2742 | 2672 | ||
2743 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { | 2673 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { |
2744 | return; | 2674 | return; |
2745 | } | 2675 | } |
2746 | 2676 | ||
2747 | CY_LOCK(info, flags); | 2677 | card = info->card; |
2678 | |||
2679 | spin_lock_irqsave(&card->card_lock, flags); | ||
2748 | /* If the TTY is being hung up, nothing to do */ | 2680 | /* If the TTY is being hung up, nothing to do */ |
2749 | if (tty_hung_up_p(filp)) { | 2681 | if (tty_hung_up_p(filp)) { |
2750 | CY_UNLOCK(info, flags); | 2682 | spin_unlock_irqrestore(&card->card_lock, flags); |
2751 | return; | 2683 | return; |
2752 | } | 2684 | } |
2753 | #ifdef CY_DEBUG_OPEN | 2685 | #ifdef CY_DEBUG_OPEN |
2754 | printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); | 2686 | printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line, |
2687 | info->count); | ||
2755 | #endif | 2688 | #endif |
2756 | if ((tty->count == 1) && (info->count != 1)) { | 2689 | if ((tty->count == 1) && (info->count != 1)) { |
2757 | /* | 2690 | /* |
@@ -2761,22 +2694,22 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2761 | * one, we've got real problems, since it means the | 2694 | * one, we've got real problems, since it means the |
2762 | * serial port won't be shutdown. | 2695 | * serial port won't be shutdown. |
2763 | */ | 2696 | */ |
2764 | printk("cyc:cy_close: bad serial port count; tty->count is 1, " | 2697 | printk(KERN_ERR "cyc:cy_close: bad serial port count; " |
2765 | "info->count is %d\n", info->count); | 2698 | "tty->count is 1, info->count is %d\n", info->count); |
2766 | info->count = 1; | 2699 | info->count = 1; |
2767 | } | 2700 | } |
2768 | #ifdef CY_DEBUG_COUNT | 2701 | #ifdef CY_DEBUG_COUNT |
2769 | printk("cyc:cy_close at (%d): decrementing count to %d\n", | 2702 | printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n", |
2770 | current->pid, info->count - 1); | 2703 | current->pid, info->count - 1); |
2771 | #endif | 2704 | #endif |
2772 | if (--info->count < 0) { | 2705 | if (--info->count < 0) { |
2773 | #ifdef CY_DEBUG_COUNT | 2706 | #ifdef CY_DEBUG_COUNT |
2774 | printk("cyc:cyc_close setting count to 0\n"); | 2707 | printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n"); |
2775 | #endif | 2708 | #endif |
2776 | info->count = 0; | 2709 | info->count = 0; |
2777 | } | 2710 | } |
2778 | if (info->count) { | 2711 | if (info->count) { |
2779 | CY_UNLOCK(info, flags); | 2712 | spin_unlock_irqrestore(&card->card_lock, flags); |
2780 | return; | 2713 | return; |
2781 | } | 2714 | } |
2782 | info->flags |= ASYNC_CLOSING; | 2715 | info->flags |= ASYNC_CLOSING; |
@@ -2786,81 +2719,80 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2786 | * the line discipline to only process XON/XOFF characters. | 2719 | * the line discipline to only process XON/XOFF characters. |
2787 | */ | 2720 | */ |
2788 | tty->closing = 1; | 2721 | tty->closing = 1; |
2789 | CY_UNLOCK(info, flags); | 2722 | spin_unlock_irqrestore(&card->card_lock, flags); |
2790 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { | 2723 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { |
2791 | tty_wait_until_sent(tty, info->closing_wait); | 2724 | tty_wait_until_sent(tty, info->closing_wait); |
2792 | } | 2725 | } |
2793 | CY_LOCK(info, flags); | 2726 | spin_lock_irqsave(&card->card_lock, flags); |
2794 | 2727 | ||
2795 | if (!IS_CYC_Z(cy_card[info->card])) { | 2728 | if (!IS_CYC_Z(*card)) { |
2796 | int channel = info->line - cy_card[info->card].first_line; | 2729 | int channel = info->line - card->first_line; |
2797 | int index = cy_card[info->card].bus_index; | 2730 | int index = card->bus_index; |
2798 | void __iomem *base_addr = cy_card[info->card].base_addr + | 2731 | void __iomem *base_addr = card->base_addr + |
2799 | (cy_chip_offset[channel >> 2] << index); | 2732 | (cy_chip_offset[channel >> 2] << index); |
2800 | /* Stop accepting input */ | 2733 | /* Stop accepting input */ |
2801 | channel &= 0x03; | 2734 | channel &= 0x03; |
2802 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 2735 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
2803 | cy_writeb(base_addr + (CySRER << index), | 2736 | cy_writeb(base_addr + (CySRER << index), |
2804 | cy_readb(base_addr + (CySRER << index)) & ~CyRxData); | 2737 | readb(base_addr + (CySRER << index)) & ~CyRxData); |
2805 | if (info->flags & ASYNC_INITIALIZED) { | 2738 | if (info->flags & ASYNC_INITIALIZED) { |
2806 | /* Waiting for on-board buffers to be empty before closing | 2739 | /* Waiting for on-board buffers to be empty before closing |
2807 | the port */ | 2740 | the port */ |
2808 | CY_UNLOCK(info, flags); | 2741 | spin_unlock_irqrestore(&card->card_lock, flags); |
2809 | cy_wait_until_sent(tty, info->timeout); | 2742 | cy_wait_until_sent(tty, info->timeout); |
2810 | CY_LOCK(info, flags); | 2743 | spin_lock_irqsave(&card->card_lock, flags); |
2811 | } | 2744 | } |
2812 | } else { | 2745 | } else { |
2813 | #ifdef Z_WAKE | 2746 | #ifdef Z_WAKE |
2814 | /* Waiting for on-board buffers to be empty before closing the port */ | 2747 | /* Waiting for on-board buffers to be empty before closing the port */ |
2815 | void __iomem *base_addr = cy_card[info->card].base_addr; | 2748 | void __iomem *base_addr = card->base_addr; |
2816 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; | 2749 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; |
2817 | struct ZFW_CTRL __iomem *zfw_ctrl = | 2750 | struct ZFW_CTRL __iomem *zfw_ctrl = |
2818 | base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2751 | base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2819 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; | 2752 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; |
2820 | int channel = info->line - cy_card[info->card].first_line; | 2753 | int channel = info->line - card->first_line; |
2821 | int retval; | 2754 | int retval; |
2822 | 2755 | ||
2823 | if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { | 2756 | if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { |
2824 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2757 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L); |
2825 | C_CM_IOCTLW, 0L); | ||
2826 | if (retval != 0) { | 2758 | if (retval != 0) { |
2827 | printk("cyc:cy_close retval on ttyC%d was %x\n", | 2759 | printk(KERN_DEBUG "cyc:cy_close retval on " |
2828 | info->line, retval); | 2760 | "ttyC%d was %x\n", info->line, retval); |
2829 | } | 2761 | } |
2830 | CY_UNLOCK(info, flags); | 2762 | spin_unlock_irqrestore(&card->card_lock, flags); |
2831 | interruptible_sleep_on(&info->shutdown_wait); | 2763 | wait_for_completion_interruptible(&info->shutdown_wait); |
2832 | CY_LOCK(info, flags); | 2764 | spin_lock_irqsave(&card->card_lock, flags); |
2833 | } | 2765 | } |
2834 | #endif | 2766 | #endif |
2835 | } | 2767 | } |
2836 | 2768 | ||
2837 | CY_UNLOCK(info, flags); | 2769 | spin_unlock_irqrestore(&card->card_lock, flags); |
2838 | shutdown(info); | 2770 | shutdown(info); |
2839 | if (tty->driver->flush_buffer) | 2771 | if (tty->driver->flush_buffer) |
2840 | tty->driver->flush_buffer(tty); | 2772 | tty->driver->flush_buffer(tty); |
2841 | tty_ldisc_flush(tty); | 2773 | tty_ldisc_flush(tty); |
2842 | CY_LOCK(info, flags); | 2774 | spin_lock_irqsave(&card->card_lock, flags); |
2843 | 2775 | ||
2844 | tty->closing = 0; | 2776 | tty->closing = 0; |
2845 | info->event = 0; | 2777 | info->event = 0; |
2846 | info->tty = NULL; | 2778 | info->tty = NULL; |
2847 | if (info->blocked_open) { | 2779 | if (info->blocked_open) { |
2848 | CY_UNLOCK(info, flags); | 2780 | spin_unlock_irqrestore(&card->card_lock, flags); |
2849 | if (info->close_delay) { | 2781 | if (info->close_delay) { |
2850 | msleep_interruptible(jiffies_to_msecs | 2782 | msleep_interruptible(jiffies_to_msecs |
2851 | (info->close_delay)); | 2783 | (info->close_delay)); |
2852 | } | 2784 | } |
2853 | wake_up_interruptible(&info->open_wait); | 2785 | wake_up_interruptible(&info->open_wait); |
2854 | CY_LOCK(info, flags); | 2786 | spin_lock_irqsave(&card->card_lock, flags); |
2855 | } | 2787 | } |
2856 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | 2788 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); |
2857 | wake_up_interruptible(&info->close_wait); | 2789 | wake_up_interruptible(&info->close_wait); |
2858 | 2790 | ||
2859 | #ifdef CY_DEBUG_OTHER | 2791 | #ifdef CY_DEBUG_OTHER |
2860 | printk(" cyc:cy_close done\n"); | 2792 | printk(KERN_DEBUG "cyc:cy_close done\n"); |
2861 | #endif | 2793 | #endif |
2862 | 2794 | ||
2863 | CY_UNLOCK(info, flags); | 2795 | spin_unlock_irqrestore(&card->card_lock, flags); |
2864 | } /* cy_close */ | 2796 | } /* cy_close */ |
2865 | 2797 | ||
2866 | /* This routine gets called when tty_write has put something into | 2798 | /* This routine gets called when tty_write has put something into |
@@ -2878,12 +2810,12 @@ static void cy_close(struct tty_struct *tty, struct file *filp) | |||
2878 | */ | 2810 | */ |
2879 | static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | 2811 | static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) |
2880 | { | 2812 | { |
2881 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2813 | struct cyclades_port *info = tty->driver_data; |
2882 | unsigned long flags; | 2814 | unsigned long flags; |
2883 | int c, ret = 0; | 2815 | int c, ret = 0; |
2884 | 2816 | ||
2885 | #ifdef CY_DEBUG_IO | 2817 | #ifdef CY_DEBUG_IO |
2886 | printk("cyc:cy_write ttyC%d\n", info->line); /* */ | 2818 | printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line); |
2887 | #endif | 2819 | #endif |
2888 | 2820 | ||
2889 | if (serial_paranoia_check(info, tty->name, "cy_write")) { | 2821 | if (serial_paranoia_check(info, tty->name, "cy_write")) { |
@@ -2893,7 +2825,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2893 | if (!info->xmit_buf) | 2825 | if (!info->xmit_buf) |
2894 | return 0; | 2826 | return 0; |
2895 | 2827 | ||
2896 | CY_LOCK(info, flags); | 2828 | spin_lock_irqsave(&info->card->card_lock, flags); |
2897 | while (1) { | 2829 | while (1) { |
2898 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), | 2830 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), |
2899 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); | 2831 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); |
@@ -2909,7 +2841,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2909 | count -= c; | 2841 | count -= c; |
2910 | ret += c; | 2842 | ret += c; |
2911 | } | 2843 | } |
2912 | CY_UNLOCK(info, flags); | 2844 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2913 | 2845 | ||
2914 | info->idle_stats.xmit_bytes += ret; | 2846 | info->idle_stats.xmit_bytes += ret; |
2915 | info->idle_stats.xmit_idle = jiffies; | 2847 | info->idle_stats.xmit_idle = jiffies; |
@@ -2929,11 +2861,11 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
2929 | */ | 2861 | */ |
2930 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) | 2862 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) |
2931 | { | 2863 | { |
2932 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2864 | struct cyclades_port *info = tty->driver_data; |
2933 | unsigned long flags; | 2865 | unsigned long flags; |
2934 | 2866 | ||
2935 | #ifdef CY_DEBUG_IO | 2867 | #ifdef CY_DEBUG_IO |
2936 | printk("cyc:cy_put_char ttyC%d\n", info->line); | 2868 | printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line); |
2937 | #endif | 2869 | #endif |
2938 | 2870 | ||
2939 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 2871 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
@@ -2942,9 +2874,9 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2942 | if (!info->xmit_buf) | 2874 | if (!info->xmit_buf) |
2943 | return; | 2875 | return; |
2944 | 2876 | ||
2945 | CY_LOCK(info, flags); | 2877 | spin_lock_irqsave(&info->card->card_lock, flags); |
2946 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { | 2878 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { |
2947 | CY_UNLOCK(info, flags); | 2879 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2948 | return; | 2880 | return; |
2949 | } | 2881 | } |
2950 | 2882 | ||
@@ -2953,7 +2885,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2953 | info->xmit_cnt++; | 2885 | info->xmit_cnt++; |
2954 | info->idle_stats.xmit_bytes++; | 2886 | info->idle_stats.xmit_bytes++; |
2955 | info->idle_stats.xmit_idle = jiffies; | 2887 | info->idle_stats.xmit_idle = jiffies; |
2956 | CY_UNLOCK(info, flags); | 2888 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
2957 | } /* cy_put_char */ | 2889 | } /* cy_put_char */ |
2958 | 2890 | ||
2959 | /* | 2891 | /* |
@@ -2962,10 +2894,10 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch) | |||
2962 | */ | 2894 | */ |
2963 | static void cy_flush_chars(struct tty_struct *tty) | 2895 | static void cy_flush_chars(struct tty_struct *tty) |
2964 | { | 2896 | { |
2965 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2897 | struct cyclades_port *info = tty->driver_data; |
2966 | 2898 | ||
2967 | #ifdef CY_DEBUG_IO | 2899 | #ifdef CY_DEBUG_IO |
2968 | printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ | 2900 | printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line); |
2969 | #endif | 2901 | #endif |
2970 | 2902 | ||
2971 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) | 2903 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) |
@@ -2986,11 +2918,11 @@ static void cy_flush_chars(struct tty_struct *tty) | |||
2986 | */ | 2918 | */ |
2987 | static int cy_write_room(struct tty_struct *tty) | 2919 | static int cy_write_room(struct tty_struct *tty) |
2988 | { | 2920 | { |
2989 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2921 | struct cyclades_port *info = tty->driver_data; |
2990 | int ret; | 2922 | int ret; |
2991 | 2923 | ||
2992 | #ifdef CY_DEBUG_IO | 2924 | #ifdef CY_DEBUG_IO |
2993 | printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ | 2925 | printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line); |
2994 | #endif | 2926 | #endif |
2995 | 2927 | ||
2996 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) | 2928 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) |
@@ -3003,46 +2935,49 @@ static int cy_write_room(struct tty_struct *tty) | |||
3003 | 2935 | ||
3004 | static int cy_chars_in_buffer(struct tty_struct *tty) | 2936 | static int cy_chars_in_buffer(struct tty_struct *tty) |
3005 | { | 2937 | { |
3006 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2938 | struct cyclades_card *card; |
3007 | int card, channel; | 2939 | struct cyclades_port *info = tty->driver_data; |
2940 | int channel; | ||
3008 | 2941 | ||
3009 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) | 2942 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) |
3010 | return 0; | 2943 | return 0; |
3011 | 2944 | ||
3012 | card = info->card; | 2945 | card = info->card; |
3013 | channel = (info->line) - (cy_card[card].first_line); | 2946 | channel = (info->line) - (card->first_line); |
3014 | 2947 | ||
3015 | #ifdef Z_EXT_CHARS_IN_BUFFER | 2948 | #ifdef Z_EXT_CHARS_IN_BUFFER |
3016 | if (!IS_CYC_Z(cy_card[card])) { | 2949 | if (!IS_CYC_Z(cy_card[card])) { |
3017 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 2950 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
3018 | #ifdef CY_DEBUG_IO | 2951 | #ifdef CY_DEBUG_IO |
3019 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ | 2952 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2953 | info->line, info->xmit_cnt); | ||
3020 | #endif | 2954 | #endif |
3021 | return info->xmit_cnt; | 2955 | return info->xmit_cnt; |
3022 | #ifdef Z_EXT_CHARS_IN_BUFFER | 2956 | #ifdef Z_EXT_CHARS_IN_BUFFER |
3023 | } else { | 2957 | } else { |
3024 | static volatile struct FIRM_ID *firm_id; | 2958 | static struct FIRM_ID *firm_id; |
3025 | static volatile struct ZFW_CTRL *zfw_ctrl; | 2959 | static struct ZFW_CTRL *zfw_ctrl; |
3026 | static volatile struct CH_CTRL *ch_ctrl; | 2960 | static struct CH_CTRL *ch_ctrl; |
3027 | static volatile struct BUF_CTRL *buf_ctrl; | 2961 | static struct BUF_CTRL *buf_ctrl; |
3028 | int char_count; | 2962 | int char_count; |
3029 | volatile uclong tx_put, tx_get, tx_bufsize; | 2963 | __u32 tx_put, tx_get, tx_bufsize; |
3030 | 2964 | ||
3031 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 2965 | firm_id = card->base_addr + ID_ADDRESS; |
3032 | zfw_ctrl = cy_card[card].base_addr + | 2966 | zfw_ctrl = card->base_addr + |
3033 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2967 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3034 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 2968 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
3035 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | 2969 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); |
3036 | 2970 | ||
3037 | tx_get = cy_readl(&buf_ctrl->tx_get); | 2971 | tx_get = readl(&buf_ctrl->tx_get); |
3038 | tx_put = cy_readl(&buf_ctrl->tx_put); | 2972 | tx_put = readl(&buf_ctrl->tx_put); |
3039 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 2973 | tx_bufsize = readl(&buf_ctrl->tx_bufsize); |
3040 | if (tx_put >= tx_get) | 2974 | if (tx_put >= tx_get) |
3041 | char_count = tx_put - tx_get; | 2975 | char_count = tx_put - tx_get; |
3042 | else | 2976 | else |
3043 | char_count = tx_put - tx_get + tx_bufsize; | 2977 | char_count = tx_put - tx_get + tx_bufsize; |
3044 | #ifdef CY_DEBUG_IO | 2978 | #ifdef CY_DEBUG_IO |
3045 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */ | 2979 | printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n", |
2980 | info->line, info->xmit_cnt + char_count); | ||
3046 | #endif | 2981 | #endif |
3047 | return info->xmit_cnt + char_count; | 2982 | return info->xmit_cnt + char_count; |
3048 | } | 2983 | } |
@@ -3055,10 +2990,10 @@ static int cy_chars_in_buffer(struct tty_struct *tty) | |||
3055 | * ------------------------------------------------------------ | 2990 | * ------------------------------------------------------------ |
3056 | */ | 2991 | */ |
3057 | 2992 | ||
3058 | static void cyy_baud_calc(struct cyclades_port *info, uclong baud) | 2993 | static void cyy_baud_calc(struct cyclades_port *info, __u32 baud) |
3059 | { | 2994 | { |
3060 | int co, co_val, bpr; | 2995 | int co, co_val, bpr; |
3061 | uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : | 2996 | __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : |
3062 | 25000000); | 2997 | 25000000); |
3063 | 2998 | ||
3064 | if (baud == 0) { | 2999 | if (baud == 0) { |
@@ -3086,9 +3021,10 @@ static void cyy_baud_calc(struct cyclades_port *info, uclong baud) | |||
3086 | */ | 3021 | */ |
3087 | static void set_line_char(struct cyclades_port *info) | 3022 | static void set_line_char(struct cyclades_port *info) |
3088 | { | 3023 | { |
3024 | struct cyclades_card *card; | ||
3089 | unsigned long flags; | 3025 | unsigned long flags; |
3090 | void __iomem *base_addr; | 3026 | void __iomem *base_addr; |
3091 | int card, chip, channel, index; | 3027 | int chip, channel, index; |
3092 | unsigned cflag, iflag; | 3028 | unsigned cflag, iflag; |
3093 | unsigned short chip_number; | 3029 | unsigned short chip_number; |
3094 | int baud, baud_rate = 0; | 3030 | int baud, baud_rate = 0; |
@@ -3118,12 +3054,12 @@ static void set_line_char(struct cyclades_port *info) | |||
3118 | } | 3054 | } |
3119 | 3055 | ||
3120 | card = info->card; | 3056 | card = info->card; |
3121 | channel = (info->line) - (cy_card[card].first_line); | 3057 | channel = info->line - card->first_line; |
3122 | chip_number = channel / 4; | 3058 | chip_number = channel / 4; |
3123 | 3059 | ||
3124 | if (!IS_CYC_Z(cy_card[card])) { | 3060 | if (!IS_CYC_Z(*card)) { |
3125 | 3061 | ||
3126 | index = cy_card[card].bus_index; | 3062 | index = card->bus_index; |
3127 | 3063 | ||
3128 | /* baud rate */ | 3064 | /* baud rate */ |
3129 | baud = tty_get_baud_rate(info->tty); | 3065 | baud = tty_get_baud_rate(info->tty); |
@@ -3241,10 +3177,9 @@ static void set_line_char(struct cyclades_port *info) | |||
3241 | 3177 | ||
3242 | chip = channel >> 2; | 3178 | chip = channel >> 2; |
3243 | channel &= 0x03; | 3179 | channel &= 0x03; |
3244 | base_addr = cy_card[card].base_addr + | 3180 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3245 | (cy_chip_offset[chip] << index); | ||
3246 | 3181 | ||
3247 | CY_LOCK(info, flags); | 3182 | spin_lock_irqsave(&card->card_lock, flags); |
3248 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 3183 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3249 | 3184 | ||
3250 | /* tx and rx baud rate */ | 3185 | /* tx and rx baud rate */ |
@@ -3276,8 +3211,7 @@ static void set_line_char(struct cyclades_port *info) | |||
3276 | if (C_CLOCAL(info->tty)) { | 3211 | if (C_CLOCAL(info->tty)) { |
3277 | /* without modem intr */ | 3212 | /* without modem intr */ |
3278 | cy_writeb(base_addr + (CySRER << index), | 3213 | cy_writeb(base_addr + (CySRER << index), |
3279 | cy_readb(base_addr + | 3214 | readb(base_addr + (CySRER << index)) | CyMdmCh); |
3280 | (CySRER << index)) | CyMdmCh); | ||
3281 | /* act on 1->0 modem transitions */ | 3215 | /* act on 1->0 modem transitions */ |
3282 | if ((cflag & CRTSCTS) && info->rflow) { | 3216 | if ((cflag & CRTSCTS) && info->rflow) { |
3283 | cy_writeb(base_addr + (CyMCOR1 << index), | 3217 | cy_writeb(base_addr + (CyMCOR1 << index), |
@@ -3291,7 +3225,7 @@ static void set_line_char(struct cyclades_port *info) | |||
3291 | } else { | 3225 | } else { |
3292 | /* without modem intr */ | 3226 | /* without modem intr */ |
3293 | cy_writeb(base_addr + (CySRER << index), | 3227 | cy_writeb(base_addr + (CySRER << index), |
3294 | cy_readb(base_addr + | 3228 | readb(base_addr + |
3295 | (CySRER << index)) | CyMdmCh); | 3229 | (CySRER << index)) | CyMdmCh); |
3296 | /* act on 1->0 modem transitions */ | 3230 | /* act on 1->0 modem transitions */ |
3297 | if ((cflag & CRTSCTS) && info->rflow) { | 3231 | if ((cflag & CRTSCTS) && info->rflow) { |
@@ -3316,10 +3250,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3316 | ~CyDTR); | 3250 | ~CyDTR); |
3317 | } | 3251 | } |
3318 | #ifdef CY_DEBUG_DTR | 3252 | #ifdef CY_DEBUG_DTR |
3319 | printk("cyc:set_line_char dropping DTR\n"); | 3253 | printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n"); |
3320 | printk(" status: 0x%x, 0x%x\n", | 3254 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3321 | cy_readb(base_addr + (CyMSVR1 << index)), | 3255 | readb(base_addr + (CyMSVR1 << index)), |
3322 | cy_readb(base_addr + (CyMSVR2 << index))); | 3256 | readb(base_addr + (CyMSVR2 << index))); |
3323 | #endif | 3257 | #endif |
3324 | } else { | 3258 | } else { |
3325 | if (info->rtsdtr_inv) { | 3259 | if (info->rtsdtr_inv) { |
@@ -3330,17 +3264,17 @@ static void set_line_char(struct cyclades_port *info) | |||
3330 | CyDTR); | 3264 | CyDTR); |
3331 | } | 3265 | } |
3332 | #ifdef CY_DEBUG_DTR | 3266 | #ifdef CY_DEBUG_DTR |
3333 | printk("cyc:set_line_char raising DTR\n"); | 3267 | printk(KERN_DEBUG "cyc:set_line_char raising DTR\n"); |
3334 | printk(" status: 0x%x, 0x%x\n", | 3268 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3335 | cy_readb(base_addr + (CyMSVR1 << index)), | 3269 | readb(base_addr + (CyMSVR1 << index)), |
3336 | cy_readb(base_addr + (CyMSVR2 << index))); | 3270 | readb(base_addr + (CyMSVR2 << index))); |
3337 | #endif | 3271 | #endif |
3338 | } | 3272 | } |
3339 | 3273 | ||
3340 | if (info->tty) { | 3274 | if (info->tty) { |
3341 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 3275 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3342 | } | 3276 | } |
3343 | CY_UNLOCK(info, flags); | 3277 | spin_unlock_irqrestore(&card->card_lock, flags); |
3344 | 3278 | ||
3345 | } else { | 3279 | } else { |
3346 | struct FIRM_ID __iomem *firm_id; | 3280 | struct FIRM_ID __iomem *firm_id; |
@@ -3348,16 +3282,16 @@ static void set_line_char(struct cyclades_port *info) | |||
3348 | struct BOARD_CTRL __iomem *board_ctrl; | 3282 | struct BOARD_CTRL __iomem *board_ctrl; |
3349 | struct CH_CTRL __iomem *ch_ctrl; | 3283 | struct CH_CTRL __iomem *ch_ctrl; |
3350 | struct BUF_CTRL __iomem *buf_ctrl; | 3284 | struct BUF_CTRL __iomem *buf_ctrl; |
3351 | uclong sw_flow; | 3285 | __u32 sw_flow; |
3352 | int retval; | 3286 | int retval; |
3353 | 3287 | ||
3354 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3288 | firm_id = card->base_addr + ID_ADDRESS; |
3355 | if (!ISZLOADED(cy_card[card])) { | 3289 | if (!ISZLOADED(*card)) { |
3356 | return; | 3290 | return; |
3357 | } | 3291 | } |
3358 | 3292 | ||
3359 | zfw_ctrl = cy_card[card].base_addr + | 3293 | zfw_ctrl = card->base_addr + |
3360 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3294 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3361 | board_ctrl = &zfw_ctrl->board_ctrl; | 3295 | board_ctrl = &zfw_ctrl->board_ctrl; |
3362 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 3296 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
3363 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; | 3297 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; |
@@ -3408,10 +3342,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3408 | } | 3342 | } |
3409 | if (cflag & CSTOPB) { | 3343 | if (cflag & CSTOPB) { |
3410 | cy_writel(&ch_ctrl->comm_data_l, | 3344 | cy_writel(&ch_ctrl->comm_data_l, |
3411 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); | 3345 | readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); |
3412 | } else { | 3346 | } else { |
3413 | cy_writel(&ch_ctrl->comm_data_l, | 3347 | cy_writel(&ch_ctrl->comm_data_l, |
3414 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); | 3348 | readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); |
3415 | } | 3349 | } |
3416 | if (cflag & PARENB) { | 3350 | if (cflag & PARENB) { |
3417 | if (cflag & PARODD) { | 3351 | if (cflag & PARODD) { |
@@ -3426,12 +3360,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3426 | /* CTS flow control flag */ | 3360 | /* CTS flow control flag */ |
3427 | if (cflag & CRTSCTS) { | 3361 | if (cflag & CRTSCTS) { |
3428 | cy_writel(&ch_ctrl->hw_flow, | 3362 | cy_writel(&ch_ctrl->hw_flow, |
3429 | cy_readl(&ch_ctrl-> | 3363 | readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); |
3430 | hw_flow) | C_RS_CTS | C_RS_RTS); | ||
3431 | } else { | 3364 | } else { |
3432 | cy_writel(&ch_ctrl->hw_flow, | 3365 | cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) & |
3433 | cy_readl(&ch_ctrl-> | 3366 | ~(C_RS_CTS | C_RS_RTS)); |
3434 | hw_flow) & ~(C_RS_CTS | C_RS_RTS)); | ||
3435 | } | 3367 | } |
3436 | /* As the HW flow control is done in firmware, the driver | 3368 | /* As the HW flow control is done in firmware, the driver |
3437 | doesn't need to care about it */ | 3369 | doesn't need to care about it */ |
@@ -3446,10 +3378,10 @@ static void set_line_char(struct cyclades_port *info) | |||
3446 | } | 3378 | } |
3447 | cy_writel(&ch_ctrl->sw_flow, sw_flow); | 3379 | cy_writel(&ch_ctrl->sw_flow, sw_flow); |
3448 | 3380 | ||
3449 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 3381 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L); |
3450 | if (retval != 0) { | 3382 | if (retval != 0) { |
3451 | printk("cyc:set_line_char retval on ttyC%d was %x\n", | 3383 | printk(KERN_ERR "cyc:set_line_char retval on ttyC%d " |
3452 | info->line, retval); | 3384 | "was %x\n", info->line, retval); |
3453 | } | 3385 | } |
3454 | 3386 | ||
3455 | /* CD sensitivity */ | 3387 | /* CD sensitivity */ |
@@ -3461,22 +3393,22 @@ static void set_line_char(struct cyclades_port *info) | |||
3461 | 3393 | ||
3462 | if (baud == 0) { /* baud rate is zero, turn off line */ | 3394 | if (baud == 0) { /* baud rate is zero, turn off line */ |
3463 | cy_writel(&ch_ctrl->rs_control, | 3395 | cy_writel(&ch_ctrl->rs_control, |
3464 | cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); | 3396 | readl(&ch_ctrl->rs_control) & ~C_RS_DTR); |
3465 | #ifdef CY_DEBUG_DTR | 3397 | #ifdef CY_DEBUG_DTR |
3466 | printk("cyc:set_line_char dropping Z DTR\n"); | 3398 | printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n"); |
3467 | #endif | 3399 | #endif |
3468 | } else { | 3400 | } else { |
3469 | cy_writel(&ch_ctrl->rs_control, | 3401 | cy_writel(&ch_ctrl->rs_control, |
3470 | cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); | 3402 | readl(&ch_ctrl->rs_control) | C_RS_DTR); |
3471 | #ifdef CY_DEBUG_DTR | 3403 | #ifdef CY_DEBUG_DTR |
3472 | printk("cyc:set_line_char raising Z DTR\n"); | 3404 | printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n"); |
3473 | #endif | 3405 | #endif |
3474 | } | 3406 | } |
3475 | 3407 | ||
3476 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L); | 3408 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L); |
3477 | if (retval != 0) { | 3409 | if (retval != 0) { |
3478 | printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", | 3410 | printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d " |
3479 | info->line, retval); | 3411 | "was %x\n", info->line, retval); |
3480 | } | 3412 | } |
3481 | 3413 | ||
3482 | if (info->tty) { | 3414 | if (info->tty) { |
@@ -3490,14 +3422,15 @@ get_serial_info(struct cyclades_port *info, | |||
3490 | struct serial_struct __user * retinfo) | 3422 | struct serial_struct __user * retinfo) |
3491 | { | 3423 | { |
3492 | struct serial_struct tmp; | 3424 | struct serial_struct tmp; |
3493 | struct cyclades_card *cinfo = &cy_card[info->card]; | 3425 | struct cyclades_card *cinfo = info->card; |
3494 | 3426 | ||
3495 | if (!retinfo) | 3427 | if (!retinfo) |
3496 | return -EFAULT; | 3428 | return -EFAULT; |
3497 | memset(&tmp, 0, sizeof(tmp)); | 3429 | memset(&tmp, 0, sizeof(tmp)); |
3498 | tmp.type = info->type; | 3430 | tmp.type = info->type; |
3499 | tmp.line = info->line; | 3431 | tmp.line = info->line; |
3500 | tmp.port = info->card * 0x100 + info->line - cinfo->first_line; | 3432 | tmp.port = (info->card - cy_card) * 0x100 + info->line - |
3433 | cinfo->first_line; | ||
3501 | tmp.irq = cinfo->irq; | 3434 | tmp.irq = cinfo->irq; |
3502 | tmp.flags = info->flags; | 3435 | tmp.flags = info->flags; |
3503 | tmp.close_delay = info->close_delay; | 3436 | tmp.close_delay = info->close_delay; |
@@ -3566,25 +3499,25 @@ check_and_exit: | |||
3566 | */ | 3499 | */ |
3567 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) | 3500 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) |
3568 | { | 3501 | { |
3569 | int card, chip, channel, index; | 3502 | struct cyclades_card *card; |
3503 | int chip, channel, index; | ||
3570 | unsigned char status; | 3504 | unsigned char status; |
3571 | unsigned int result; | 3505 | unsigned int result; |
3572 | unsigned long flags; | 3506 | unsigned long flags; |
3573 | void __iomem *base_addr; | 3507 | void __iomem *base_addr; |
3574 | 3508 | ||
3575 | card = info->card; | 3509 | card = info->card; |
3576 | channel = (info->line) - (cy_card[card].first_line); | 3510 | channel = (info->line) - (card->first_line); |
3577 | if (!IS_CYC_Z(cy_card[card])) { | 3511 | if (!IS_CYC_Z(*card)) { |
3578 | chip = channel >> 2; | 3512 | chip = channel >> 2; |
3579 | channel &= 0x03; | 3513 | channel &= 0x03; |
3580 | index = cy_card[card].bus_index; | 3514 | index = card->bus_index; |
3581 | base_addr = | 3515 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3582 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3583 | 3516 | ||
3584 | CY_LOCK(info, flags); | 3517 | spin_lock_irqsave(&card->card_lock, flags); |
3585 | status = cy_readb(base_addr + (CySRER << index)) & | 3518 | status = readb(base_addr + (CySRER << index)) & |
3586 | (CyTxRdy | CyTxMpty); | 3519 | (CyTxRdy | CyTxMpty); |
3587 | CY_UNLOCK(info, flags); | 3520 | spin_unlock_irqrestore(&card->card_lock, flags); |
3588 | result = (status ? 0 : TIOCSER_TEMT); | 3521 | result = (status ? 0 : TIOCSER_TEMT); |
3589 | } else { | 3522 | } else { |
3590 | /* Not supported yet */ | 3523 | /* Not supported yet */ |
@@ -3595,8 +3528,9 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) | |||
3595 | 3528 | ||
3596 | static int cy_tiocmget(struct tty_struct *tty, struct file *file) | 3529 | static int cy_tiocmget(struct tty_struct *tty, struct file *file) |
3597 | { | 3530 | { |
3598 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3531 | struct cyclades_port *info = tty->driver_data; |
3599 | int card, chip, channel, index; | 3532 | struct cyclades_card *card; |
3533 | int chip, channel, index; | ||
3600 | void __iomem *base_addr; | 3534 | void __iomem *base_addr; |
3601 | unsigned long flags; | 3535 | unsigned long flags; |
3602 | unsigned char status; | 3536 | unsigned char status; |
@@ -3611,19 +3545,18 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3611 | return -ENODEV; | 3545 | return -ENODEV; |
3612 | 3546 | ||
3613 | card = info->card; | 3547 | card = info->card; |
3614 | channel = (info->line) - (cy_card[card].first_line); | 3548 | channel = info->line - card->first_line; |
3615 | if (!IS_CYC_Z(cy_card[card])) { | 3549 | if (!IS_CYC_Z(*card)) { |
3616 | chip = channel >> 2; | 3550 | chip = channel >> 2; |
3617 | channel &= 0x03; | 3551 | channel &= 0x03; |
3618 | index = cy_card[card].bus_index; | 3552 | index = card->bus_index; |
3619 | base_addr = | 3553 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3620 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3621 | 3554 | ||
3622 | CY_LOCK(info, flags); | 3555 | spin_lock_irqsave(&card->card_lock, flags); |
3623 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | 3556 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3624 | status = cy_readb(base_addr + (CyMSVR1 << index)); | 3557 | status = readb(base_addr + (CyMSVR1 << index)); |
3625 | status |= cy_readb(base_addr + (CyMSVR2 << index)); | 3558 | status |= readb(base_addr + (CyMSVR2 << index)); |
3626 | CY_UNLOCK(info, flags); | 3559 | spin_unlock_irqrestore(&card->card_lock, flags); |
3627 | 3560 | ||
3628 | if (info->rtsdtr_inv) { | 3561 | if (info->rtsdtr_inv) { |
3629 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | | 3562 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | |
@@ -3637,19 +3570,14 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file) | |||
3637 | ((status & CyDSR) ? TIOCM_DSR : 0) | | 3570 | ((status & CyDSR) ? TIOCM_DSR : 0) | |
3638 | ((status & CyCTS) ? TIOCM_CTS : 0); | 3571 | ((status & CyCTS) ? TIOCM_CTS : 0); |
3639 | } else { | 3572 | } else { |
3640 | base_addr = cy_card[card].base_addr; | 3573 | base_addr = card->base_addr; |
3641 | 3574 | firm_id = card->base_addr + ID_ADDRESS; | |
3642 | if (cy_card[card].num_chips != -1) { | 3575 | if (ISZLOADED(*card)) { |
3643 | return -EINVAL; | 3576 | zfw_ctrl = card->base_addr + |
3644 | } | 3577 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3645 | |||
3646 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | ||
3647 | if (ISZLOADED(cy_card[card])) { | ||
3648 | zfw_ctrl = cy_card[card].base_addr + | ||
3649 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
3650 | board_ctrl = &zfw_ctrl->board_ctrl; | 3578 | board_ctrl = &zfw_ctrl->board_ctrl; |
3651 | ch_ctrl = zfw_ctrl->ch_ctrl; | 3579 | ch_ctrl = zfw_ctrl->ch_ctrl; |
3652 | lstatus = cy_readl(&ch_ctrl[channel].rs_status); | 3580 | lstatus = readl(&ch_ctrl[channel].rs_status); |
3653 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | | 3581 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | |
3654 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | | 3582 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | |
3655 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | | 3583 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | |
@@ -3669,8 +3597,9 @@ static int | |||
3669 | cy_tiocmset(struct tty_struct *tty, struct file *file, | 3597 | cy_tiocmset(struct tty_struct *tty, struct file *file, |
3670 | unsigned int set, unsigned int clear) | 3598 | unsigned int set, unsigned int clear) |
3671 | { | 3599 | { |
3672 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3600 | struct cyclades_port *info = tty->driver_data; |
3673 | int card, chip, channel, index; | 3601 | struct cyclades_card *card; |
3602 | int chip, channel, index; | ||
3674 | void __iomem *base_addr; | 3603 | void __iomem *base_addr; |
3675 | unsigned long flags; | 3604 | unsigned long flags; |
3676 | struct FIRM_ID __iomem *firm_id; | 3605 | struct FIRM_ID __iomem *firm_id; |
@@ -3683,16 +3612,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3683 | return -ENODEV; | 3612 | return -ENODEV; |
3684 | 3613 | ||
3685 | card = info->card; | 3614 | card = info->card; |
3686 | channel = (info->line) - (cy_card[card].first_line); | 3615 | channel = (info->line) - (card->first_line); |
3687 | if (!IS_CYC_Z(cy_card[card])) { | 3616 | if (!IS_CYC_Z(*card)) { |
3688 | chip = channel >> 2; | 3617 | chip = channel >> 2; |
3689 | channel &= 0x03; | 3618 | channel &= 0x03; |
3690 | index = cy_card[card].bus_index; | 3619 | index = card->bus_index; |
3691 | base_addr = | 3620 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3692 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3693 | 3621 | ||
3694 | if (set & TIOCM_RTS) { | 3622 | if (set & TIOCM_RTS) { |
3695 | CY_LOCK(info, flags); | 3623 | spin_lock_irqsave(&card->card_lock, flags); |
3696 | cy_writeb(base_addr + (CyCAR << index), | 3624 | cy_writeb(base_addr + (CyCAR << index), |
3697 | (u_char) channel); | 3625 | (u_char) channel); |
3698 | if (info->rtsdtr_inv) { | 3626 | if (info->rtsdtr_inv) { |
@@ -3702,10 +3630,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3702 | cy_writeb(base_addr + (CyMSVR1 << index), | 3630 | cy_writeb(base_addr + (CyMSVR1 << index), |
3703 | CyRTS); | 3631 | CyRTS); |
3704 | } | 3632 | } |
3705 | CY_UNLOCK(info, flags); | 3633 | spin_unlock_irqrestore(&card->card_lock, flags); |
3706 | } | 3634 | } |
3707 | if (clear & TIOCM_RTS) { | 3635 | if (clear & TIOCM_RTS) { |
3708 | CY_LOCK(info, flags); | 3636 | spin_lock_irqsave(&card->card_lock, flags); |
3709 | cy_writeb(base_addr + (CyCAR << index), | 3637 | cy_writeb(base_addr + (CyCAR << index), |
3710 | (u_char) channel); | 3638 | (u_char) channel); |
3711 | if (info->rtsdtr_inv) { | 3639 | if (info->rtsdtr_inv) { |
@@ -3715,10 +3643,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3715 | cy_writeb(base_addr + (CyMSVR1 << index), | 3643 | cy_writeb(base_addr + (CyMSVR1 << index), |
3716 | ~CyRTS); | 3644 | ~CyRTS); |
3717 | } | 3645 | } |
3718 | CY_UNLOCK(info, flags); | 3646 | spin_unlock_irqrestore(&card->card_lock, flags); |
3719 | } | 3647 | } |
3720 | if (set & TIOCM_DTR) { | 3648 | if (set & TIOCM_DTR) { |
3721 | CY_LOCK(info, flags); | 3649 | spin_lock_irqsave(&card->card_lock, flags); |
3722 | cy_writeb(base_addr + (CyCAR << index), | 3650 | cy_writeb(base_addr + (CyCAR << index), |
3723 | (u_char) channel); | 3651 | (u_char) channel); |
3724 | if (info->rtsdtr_inv) { | 3652 | if (info->rtsdtr_inv) { |
@@ -3729,15 +3657,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3729 | CyDTR); | 3657 | CyDTR); |
3730 | } | 3658 | } |
3731 | #ifdef CY_DEBUG_DTR | 3659 | #ifdef CY_DEBUG_DTR |
3732 | printk("cyc:set_modem_info raising DTR\n"); | 3660 | printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n"); |
3733 | printk(" status: 0x%x, 0x%x\n", | 3661 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3734 | cy_readb(base_addr + (CyMSVR1 << index)), | 3662 | readb(base_addr + (CyMSVR1 << index)), |
3735 | cy_readb(base_addr + (CyMSVR2 << index))); | 3663 | readb(base_addr + (CyMSVR2 << index))); |
3736 | #endif | 3664 | #endif |
3737 | CY_UNLOCK(info, flags); | 3665 | spin_unlock_irqrestore(&card->card_lock, flags); |
3738 | } | 3666 | } |
3739 | if (clear & TIOCM_DTR) { | 3667 | if (clear & TIOCM_DTR) { |
3740 | CY_LOCK(info, flags); | 3668 | spin_lock_irqsave(&card->card_lock, flags); |
3741 | cy_writeb(base_addr + (CyCAR << index), | 3669 | cy_writeb(base_addr + (CyCAR << index), |
3742 | (u_char) channel); | 3670 | (u_char) channel); |
3743 | if (info->rtsdtr_inv) { | 3671 | if (info->rtsdtr_inv) { |
@@ -3749,68 +3677,69 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3749 | } | 3677 | } |
3750 | 3678 | ||
3751 | #ifdef CY_DEBUG_DTR | 3679 | #ifdef CY_DEBUG_DTR |
3752 | printk("cyc:set_modem_info dropping DTR\n"); | 3680 | printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n"); |
3753 | printk(" status: 0x%x, 0x%x\n", | 3681 | printk(KERN_DEBUG " status: 0x%x, 0x%x\n", |
3754 | cy_readb(base_addr + (CyMSVR1 << index)), | 3682 | readb(base_addr + (CyMSVR1 << index)), |
3755 | cy_readb(base_addr + (CyMSVR2 << index))); | 3683 | readb(base_addr + (CyMSVR2 << index))); |
3756 | #endif | 3684 | #endif |
3757 | CY_UNLOCK(info, flags); | 3685 | spin_unlock_irqrestore(&card->card_lock, flags); |
3758 | } | 3686 | } |
3759 | } else { | 3687 | } else { |
3760 | base_addr = cy_card[card].base_addr; | 3688 | base_addr = card->base_addr; |
3761 | 3689 | ||
3762 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3690 | firm_id = card->base_addr + ID_ADDRESS; |
3763 | if (ISZLOADED(cy_card[card])) { | 3691 | if (ISZLOADED(*card)) { |
3764 | zfw_ctrl = cy_card[card].base_addr + | 3692 | zfw_ctrl = card->base_addr + |
3765 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3693 | (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3766 | board_ctrl = &zfw_ctrl->board_ctrl; | 3694 | board_ctrl = &zfw_ctrl->board_ctrl; |
3767 | ch_ctrl = zfw_ctrl->ch_ctrl; | 3695 | ch_ctrl = zfw_ctrl->ch_ctrl; |
3768 | 3696 | ||
3769 | if (set & TIOCM_RTS) { | 3697 | if (set & TIOCM_RTS) { |
3770 | CY_LOCK(info, flags); | 3698 | spin_lock_irqsave(&card->card_lock, flags); |
3771 | cy_writel(&ch_ctrl[channel].rs_control, | 3699 | cy_writel(&ch_ctrl[channel].rs_control, |
3772 | cy_readl(&ch_ctrl[channel]. | 3700 | readl(&ch_ctrl[channel].rs_control) | |
3773 | rs_control) | C_RS_RTS); | 3701 | C_RS_RTS); |
3774 | CY_UNLOCK(info, flags); | 3702 | spin_unlock_irqrestore(&card->card_lock, flags); |
3775 | } | 3703 | } |
3776 | if (clear & TIOCM_RTS) { | 3704 | if (clear & TIOCM_RTS) { |
3777 | CY_LOCK(info, flags); | 3705 | spin_lock_irqsave(&card->card_lock, flags); |
3778 | cy_writel(&ch_ctrl[channel].rs_control, | 3706 | cy_writel(&ch_ctrl[channel].rs_control, |
3779 | cy_readl(&ch_ctrl[channel]. | 3707 | readl(&ch_ctrl[channel].rs_control) & |
3780 | rs_control) & ~C_RS_RTS); | 3708 | ~C_RS_RTS); |
3781 | CY_UNLOCK(info, flags); | 3709 | spin_unlock_irqrestore(&card->card_lock, flags); |
3782 | } | 3710 | } |
3783 | if (set & TIOCM_DTR) { | 3711 | if (set & TIOCM_DTR) { |
3784 | CY_LOCK(info, flags); | 3712 | spin_lock_irqsave(&card->card_lock, flags); |
3785 | cy_writel(&ch_ctrl[channel].rs_control, | 3713 | cy_writel(&ch_ctrl[channel].rs_control, |
3786 | cy_readl(&ch_ctrl[channel]. | 3714 | readl(&ch_ctrl[channel].rs_control) | |
3787 | rs_control) | C_RS_DTR); | 3715 | C_RS_DTR); |
3788 | #ifdef CY_DEBUG_DTR | 3716 | #ifdef CY_DEBUG_DTR |
3789 | printk("cyc:set_modem_info raising Z DTR\n"); | 3717 | printk(KERN_DEBUG "cyc:set_modem_info raising " |
3718 | "Z DTR\n"); | ||
3790 | #endif | 3719 | #endif |
3791 | CY_UNLOCK(info, flags); | 3720 | spin_unlock_irqrestore(&card->card_lock, flags); |
3792 | } | 3721 | } |
3793 | if (clear & TIOCM_DTR) { | 3722 | if (clear & TIOCM_DTR) { |
3794 | CY_LOCK(info, flags); | 3723 | spin_lock_irqsave(&card->card_lock, flags); |
3795 | cy_writel(&ch_ctrl[channel].rs_control, | 3724 | cy_writel(&ch_ctrl[channel].rs_control, |
3796 | cy_readl(&ch_ctrl[channel]. | 3725 | readl(&ch_ctrl[channel].rs_control) & |
3797 | rs_control) & ~C_RS_DTR); | 3726 | ~C_RS_DTR); |
3798 | #ifdef CY_DEBUG_DTR | 3727 | #ifdef CY_DEBUG_DTR |
3799 | printk("cyc:set_modem_info clearing Z DTR\n"); | 3728 | printk(KERN_DEBUG "cyc:set_modem_info clearing " |
3729 | "Z DTR\n"); | ||
3800 | #endif | 3730 | #endif |
3801 | CY_UNLOCK(info, flags); | 3731 | spin_unlock_irqrestore(&card->card_lock, flags); |
3802 | } | 3732 | } |
3803 | } else { | 3733 | } else { |
3804 | return -ENODEV; | 3734 | return -ENODEV; |
3805 | } | 3735 | } |
3806 | CY_LOCK(info, flags); | 3736 | spin_lock_irqsave(&card->card_lock, flags); |
3807 | retval = cyz_issue_cmd(&cy_card[info->card], | 3737 | retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L); |
3808 | channel, C_CM_IOCTLM, 0L); | ||
3809 | if (retval != 0) { | 3738 | if (retval != 0) { |
3810 | printk("cyc:set_modem_info retval on ttyC%d was %x\n", | 3739 | printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d " |
3811 | info->line, retval); | 3740 | "was %x\n", info->line, retval); |
3812 | } | 3741 | } |
3813 | CY_UNLOCK(info, flags); | 3742 | spin_unlock_irqrestore(&card->card_lock, flags); |
3814 | } | 3743 | } |
3815 | return 0; | 3744 | return 0; |
3816 | } /* cy_tiocmset */ | 3745 | } /* cy_tiocmset */ |
@@ -3820,14 +3749,17 @@ cy_tiocmset(struct tty_struct *tty, struct file *file, | |||
3820 | */ | 3749 | */ |
3821 | static void cy_break(struct tty_struct *tty, int break_state) | 3750 | static void cy_break(struct tty_struct *tty, int break_state) |
3822 | { | 3751 | { |
3823 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3752 | struct cyclades_port *info = tty->driver_data; |
3753 | struct cyclades_card *card; | ||
3824 | unsigned long flags; | 3754 | unsigned long flags; |
3825 | 3755 | ||
3826 | if (serial_paranoia_check(info, tty->name, "cy_break")) | 3756 | if (serial_paranoia_check(info, tty->name, "cy_break")) |
3827 | return; | 3757 | return; |
3828 | 3758 | ||
3829 | CY_LOCK(info, flags); | 3759 | card = info->card; |
3830 | if (!IS_CYC_Z(cy_card[info->card])) { | 3760 | |
3761 | spin_lock_irqsave(&card->card_lock, flags); | ||
3762 | if (!IS_CYC_Z(*card)) { | ||
3831 | /* Let the transmit ISR take care of this (since it | 3763 | /* Let the transmit ISR take care of this (since it |
3832 | requires stuffing characters into the output stream). | 3764 | requires stuffing characters into the output stream). |
3833 | */ | 3765 | */ |
@@ -3835,18 +3767,18 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3835 | if (!info->breakon) { | 3767 | if (!info->breakon) { |
3836 | info->breakon = 1; | 3768 | info->breakon = 1; |
3837 | if (!info->xmit_cnt) { | 3769 | if (!info->xmit_cnt) { |
3838 | CY_UNLOCK(info, flags); | 3770 | spin_unlock_irqrestore(&card->card_lock, flags); |
3839 | start_xmit(info); | 3771 | start_xmit(info); |
3840 | CY_LOCK(info, flags); | 3772 | spin_lock_irqsave(&card->card_lock, flags); |
3841 | } | 3773 | } |
3842 | } | 3774 | } |
3843 | } else { | 3775 | } else { |
3844 | if (!info->breakoff) { | 3776 | if (!info->breakoff) { |
3845 | info->breakoff = 1; | 3777 | info->breakoff = 1; |
3846 | if (!info->xmit_cnt) { | 3778 | if (!info->xmit_cnt) { |
3847 | CY_UNLOCK(info, flags); | 3779 | spin_unlock_irqrestore(&card->card_lock, flags); |
3848 | start_xmit(info); | 3780 | start_xmit(info); |
3849 | CY_LOCK(info, flags); | 3781 | spin_lock_irqsave(&card->card_lock, flags); |
3850 | } | 3782 | } |
3851 | } | 3783 | } |
3852 | } | 3784 | } |
@@ -3854,24 +3786,25 @@ static void cy_break(struct tty_struct *tty, int break_state) | |||
3854 | int retval; | 3786 | int retval; |
3855 | 3787 | ||
3856 | if (break_state == -1) { | 3788 | if (break_state == -1) { |
3857 | retval = cyz_issue_cmd(&cy_card[info->card], | 3789 | retval = cyz_issue_cmd(card, |
3858 | info->line - cy_card[info->card].first_line, | 3790 | info->line - card->first_line, |
3859 | C_CM_SET_BREAK, 0L); | 3791 | C_CM_SET_BREAK, 0L); |
3860 | if (retval != 0) { | 3792 | if (retval != 0) { |
3861 | printk("cyc:cy_break (set) retval on ttyC%d " | 3793 | printk(KERN_ERR "cyc:cy_break (set) retval on " |
3862 | "was %x\n", info->line, retval); | 3794 | "ttyC%d was %x\n", info->line, retval); |
3863 | } | 3795 | } |
3864 | } else { | 3796 | } else { |
3865 | retval = cyz_issue_cmd(&cy_card[info->card], | 3797 | retval = cyz_issue_cmd(card, |
3866 | info->line - cy_card[info->card].first_line, | 3798 | info->line - card->first_line, |
3867 | C_CM_CLR_BREAK, 0L); | 3799 | C_CM_CLR_BREAK, 0L); |
3868 | if (retval != 0) { | 3800 | if (retval != 0) { |
3869 | printk("cyc:cy_break (clr) retval on ttyC%d " | 3801 | printk(KERN_DEBUG "cyc:cy_break (clr) retval " |
3870 | "was %x\n", info->line, retval); | 3802 | "on ttyC%d was %x\n", info->line, |
3803 | retval); | ||
3871 | } | 3804 | } |
3872 | } | 3805 | } |
3873 | } | 3806 | } |
3874 | CY_UNLOCK(info, flags); | 3807 | spin_unlock_irqrestore(&card->card_lock, flags); |
3875 | } /* cy_break */ | 3808 | } /* cy_break */ |
3876 | 3809 | ||
3877 | static int | 3810 | static int |
@@ -3889,28 +3822,27 @@ get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) | |||
3889 | 3822 | ||
3890 | static int set_threshold(struct cyclades_port *info, unsigned long value) | 3823 | static int set_threshold(struct cyclades_port *info, unsigned long value) |
3891 | { | 3824 | { |
3825 | struct cyclades_card *card; | ||
3892 | void __iomem *base_addr; | 3826 | void __iomem *base_addr; |
3893 | int card, channel, chip, index; | 3827 | int channel, chip, index; |
3894 | unsigned long flags; | 3828 | unsigned long flags; |
3895 | 3829 | ||
3896 | card = info->card; | 3830 | card = info->card; |
3897 | channel = info->line - cy_card[card].first_line; | 3831 | channel = info->line - card->first_line; |
3898 | if (!IS_CYC_Z(cy_card[card])) { | 3832 | if (!IS_CYC_Z(*card)) { |
3899 | chip = channel >> 2; | 3833 | chip = channel >> 2; |
3900 | channel &= 0x03; | 3834 | channel &= 0x03; |
3901 | index = cy_card[card].bus_index; | 3835 | index = card->bus_index; |
3902 | base_addr = | 3836 | base_addr = |
3903 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | 3837 | card->base_addr + (cy_chip_offset[chip] << index); |
3904 | 3838 | ||
3905 | info->cor3 &= ~CyREC_FIFO; | 3839 | info->cor3 &= ~CyREC_FIFO; |
3906 | info->cor3 |= value & CyREC_FIFO; | 3840 | info->cor3 |= value & CyREC_FIFO; |
3907 | 3841 | ||
3908 | CY_LOCK(info, flags); | 3842 | spin_lock_irqsave(&card->card_lock, flags); |
3909 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); | 3843 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); |
3910 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); | 3844 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); |
3911 | CY_UNLOCK(info, flags); | 3845 | spin_unlock_irqrestore(&card->card_lock, flags); |
3912 | } else { | ||
3913 | /* Nothing to do! */ | ||
3914 | } | 3846 | } |
3915 | return 0; | 3847 | return 0; |
3916 | } /* set_threshold */ | 3848 | } /* set_threshold */ |
@@ -3918,25 +3850,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value) | |||
3918 | static int | 3850 | static int |
3919 | get_threshold(struct cyclades_port *info, unsigned long __user * value) | 3851 | get_threshold(struct cyclades_port *info, unsigned long __user * value) |
3920 | { | 3852 | { |
3853 | struct cyclades_card *card; | ||
3921 | void __iomem *base_addr; | 3854 | void __iomem *base_addr; |
3922 | int card, channel, chip, index; | 3855 | int channel, chip, index; |
3923 | unsigned long tmp; | 3856 | unsigned long tmp; |
3924 | 3857 | ||
3925 | card = info->card; | 3858 | card = info->card; |
3926 | channel = info->line - cy_card[card].first_line; | 3859 | channel = info->line - card->first_line; |
3927 | if (!IS_CYC_Z(cy_card[card])) { | 3860 | if (!IS_CYC_Z(*card)) { |
3928 | chip = channel >> 2; | 3861 | chip = channel >> 2; |
3929 | channel &= 0x03; | 3862 | channel &= 0x03; |
3930 | index = cy_card[card].bus_index; | 3863 | index = card->bus_index; |
3931 | base_addr = | 3864 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3932 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3933 | 3865 | ||
3934 | tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; | 3866 | tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; |
3935 | return put_user(tmp, value); | 3867 | return put_user(tmp, value); |
3936 | } else { | ||
3937 | /* Nothing to do! */ | ||
3938 | return 0; | ||
3939 | } | 3868 | } |
3869 | return 0; | ||
3940 | } /* get_threshold */ | 3870 | } /* get_threshold */ |
3941 | 3871 | ||
3942 | static int | 3872 | static int |
@@ -3954,49 +3884,45 @@ get_default_threshold(struct cyclades_port *info, unsigned long __user * value) | |||
3954 | 3884 | ||
3955 | static int set_timeout(struct cyclades_port *info, unsigned long value) | 3885 | static int set_timeout(struct cyclades_port *info, unsigned long value) |
3956 | { | 3886 | { |
3887 | struct cyclades_card *card; | ||
3957 | void __iomem *base_addr; | 3888 | void __iomem *base_addr; |
3958 | int card, channel, chip, index; | 3889 | int channel, chip, index; |
3959 | unsigned long flags; | 3890 | unsigned long flags; |
3960 | 3891 | ||
3961 | card = info->card; | 3892 | card = info->card; |
3962 | channel = info->line - cy_card[card].first_line; | 3893 | channel = info->line - card->first_line; |
3963 | if (!IS_CYC_Z(cy_card[card])) { | 3894 | if (!IS_CYC_Z(*card)) { |
3964 | chip = channel >> 2; | 3895 | chip = channel >> 2; |
3965 | channel &= 0x03; | 3896 | channel &= 0x03; |
3966 | index = cy_card[card].bus_index; | 3897 | index = card->bus_index; |
3967 | base_addr = | 3898 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3968 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3969 | 3899 | ||
3970 | CY_LOCK(info, flags); | 3900 | spin_lock_irqsave(&card->card_lock, flags); |
3971 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); | 3901 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); |
3972 | CY_UNLOCK(info, flags); | 3902 | spin_unlock_irqrestore(&card->card_lock, flags); |
3973 | } else { | ||
3974 | /* Nothing to do! */ | ||
3975 | } | 3903 | } |
3976 | return 0; | 3904 | return 0; |
3977 | } /* set_timeout */ | 3905 | } /* set_timeout */ |
3978 | 3906 | ||
3979 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) | 3907 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) |
3980 | { | 3908 | { |
3909 | struct cyclades_card *card; | ||
3981 | void __iomem *base_addr; | 3910 | void __iomem *base_addr; |
3982 | int card, channel, chip, index; | 3911 | int channel, chip, index; |
3983 | unsigned long tmp; | 3912 | unsigned long tmp; |
3984 | 3913 | ||
3985 | card = info->card; | 3914 | card = info->card; |
3986 | channel = info->line - cy_card[card].first_line; | 3915 | channel = info->line - card->first_line; |
3987 | if (!IS_CYC_Z(cy_card[card])) { | 3916 | if (!IS_CYC_Z(*card)) { |
3988 | chip = channel >> 2; | 3917 | chip = channel >> 2; |
3989 | channel &= 0x03; | 3918 | channel &= 0x03; |
3990 | index = cy_card[card].bus_index; | 3919 | index = card->bus_index; |
3991 | base_addr = | 3920 | base_addr = card->base_addr + (cy_chip_offset[chip] << index); |
3992 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3993 | 3921 | ||
3994 | tmp = cy_readb(base_addr + (CyRTPR << index)); | 3922 | tmp = readb(base_addr + (CyRTPR << index)); |
3995 | return put_user(tmp, value); | 3923 | return put_user(tmp, value); |
3996 | } else { | ||
3997 | /* Nothing to do! */ | ||
3998 | return 0; | ||
3999 | } | 3924 | } |
3925 | return 0; | ||
4000 | } /* get_timeout */ | 3926 | } /* get_timeout */ |
4001 | 3927 | ||
4002 | static int set_default_timeout(struct cyclades_port *info, unsigned long value) | 3928 | static int set_default_timeout(struct cyclades_port *info, unsigned long value) |
@@ -4020,7 +3946,7 @@ static int | |||
4020 | cy_ioctl(struct tty_struct *tty, struct file *file, | 3946 | cy_ioctl(struct tty_struct *tty, struct file *file, |
4021 | unsigned int cmd, unsigned long arg) | 3947 | unsigned int cmd, unsigned long arg) |
4022 | { | 3948 | { |
4023 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3949 | struct cyclades_port *info = tty->driver_data; |
4024 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ | 3950 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ |
4025 | struct serial_icounter_struct __user *p_cuser; /* user space */ | 3951 | struct serial_icounter_struct __user *p_cuser; /* user space */ |
4026 | int ret_val = 0; | 3952 | int ret_val = 0; |
@@ -4031,7 +3957,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4031 | return -ENODEV; | 3957 | return -ENODEV; |
4032 | 3958 | ||
4033 | #ifdef CY_DEBUG_OTHER | 3959 | #ifdef CY_DEBUG_OTHER |
4034 | printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */ | 3960 | printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", |
3961 | info->line, cmd, arg); | ||
4035 | #endif | 3962 | #endif |
4036 | 3963 | ||
4037 | switch (cmd) { | 3964 | switch (cmd) { |
@@ -4076,14 +4003,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4076 | case CYGETRTSDTR_INV: | 4003 | case CYGETRTSDTR_INV: |
4077 | ret_val = info->rtsdtr_inv; | 4004 | ret_val = info->rtsdtr_inv; |
4078 | break; | 4005 | break; |
4079 | case CYGETCARDINFO: | ||
4080 | if (copy_to_user(argp, &cy_card[info->card], | ||
4081 | sizeof(struct cyclades_card))) { | ||
4082 | ret_val = -EFAULT; | ||
4083 | break; | ||
4084 | } | ||
4085 | ret_val = 0; | ||
4086 | break; | ||
4087 | case CYGETCD1400VER: | 4006 | case CYGETCD1400VER: |
4088 | ret_val = info->chip_rev; | 4007 | ret_val = info->chip_rev; |
4089 | break; | 4008 | break; |
@@ -4119,34 +4038,22 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4119 | * Caller should use TIOCGICOUNT to see which one it was | 4038 | * Caller should use TIOCGICOUNT to see which one it was |
4120 | */ | 4039 | */ |
4121 | case TIOCMIWAIT: | 4040 | case TIOCMIWAIT: |
4122 | CY_LOCK(info, flags); | 4041 | spin_lock_irqsave(&info->card->card_lock, flags); |
4123 | /* note the counters on entry */ | 4042 | /* note the counters on entry */ |
4124 | cprev = info->icount; | 4043 | cnow = info->icount; |
4125 | CY_UNLOCK(info, flags); | 4044 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4126 | while (1) { | 4045 | ret_val = wait_event_interruptible(info->delta_msr_wait, ({ |
4127 | interruptible_sleep_on(&info->delta_msr_wait); | 4046 | cprev = cnow; |
4128 | /* see if a signal did it */ | 4047 | spin_lock_irqsave(&info->card->card_lock, flags); |
4129 | if (signal_pending(current)) { | ||
4130 | return -ERESTARTSYS; | ||
4131 | } | ||
4132 | |||
4133 | CY_LOCK(info, flags); | ||
4134 | cnow = info->icount; /* atomic copy */ | 4048 | cnow = info->icount; /* atomic copy */ |
4135 | CY_UNLOCK(info, flags); | 4049 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4136 | 4050 | ||
4137 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 4051 | ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || |
4138 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { | 4052 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || |
4139 | return -EIO; /* no change => error */ | 4053 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || |
4140 | } | 4054 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)); |
4141 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | 4055 | })); |
4142 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | 4056 | break; |
4143 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
4144 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
4145 | return 0; | ||
4146 | } | ||
4147 | cprev = cnow; | ||
4148 | } | ||
4149 | /* NOTREACHED */ | ||
4150 | 4057 | ||
4151 | /* | 4058 | /* |
4152 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | 4059 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) |
@@ -4155,9 +4062,9 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4155 | * RI where only 0->1 is counted. | 4062 | * RI where only 0->1 is counted. |
4156 | */ | 4063 | */ |
4157 | case TIOCGICOUNT: | 4064 | case TIOCGICOUNT: |
4158 | CY_LOCK(info, flags); | 4065 | spin_lock_irqsave(&info->card->card_lock, flags); |
4159 | cnow = info->icount; | 4066 | cnow = info->icount; |
4160 | CY_UNLOCK(info, flags); | 4067 | spin_unlock_irqrestore(&info->card->card_lock, flags); |
4161 | p_cuser = argp; | 4068 | p_cuser = argp; |
4162 | ret_val = put_user(cnow.cts, &p_cuser->cts); | 4069 | ret_val = put_user(cnow.cts, &p_cuser->cts); |
4163 | if (ret_val) | 4070 | if (ret_val) |
@@ -4199,7 +4106,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4199 | } | 4106 | } |
4200 | 4107 | ||
4201 | #ifdef CY_DEBUG_OTHER | 4108 | #ifdef CY_DEBUG_OTHER |
4202 | printk(" cyc:cy_ioctl done\n"); | 4109 | printk(KERN_DEBUG "cyc:cy_ioctl done\n"); |
4203 | #endif | 4110 | #endif |
4204 | 4111 | ||
4205 | return ret_val; | 4112 | return ret_val; |
@@ -4213,10 +4120,10 @@ cy_ioctl(struct tty_struct *tty, struct file *file, | |||
4213 | */ | 4120 | */ |
4214 | static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | 4121 | static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
4215 | { | 4122 | { |
4216 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4123 | struct cyclades_port *info = tty->driver_data; |
4217 | 4124 | ||
4218 | #ifdef CY_DEBUG_OTHER | 4125 | #ifdef CY_DEBUG_OTHER |
4219 | printk("cyc:cy_set_termios ttyC%d\n", info->line); | 4126 | printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line); |
4220 | #endif | 4127 | #endif |
4221 | 4128 | ||
4222 | if (tty->termios->c_cflag == old_termios->c_cflag && | 4129 | if (tty->termios->c_cflag == old_termios->c_cflag && |
@@ -4248,8 +4155,9 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
4248 | */ | 4155 | */ |
4249 | static void cy_send_xchar(struct tty_struct *tty, char ch) | 4156 | static void cy_send_xchar(struct tty_struct *tty, char ch) |
4250 | { | 4157 | { |
4251 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4158 | struct cyclades_port *info = tty->driver_data; |
4252 | int card, channel; | 4159 | struct cyclades_card *card; |
4160 | int channel; | ||
4253 | 4161 | ||
4254 | if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) | 4162 | if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) |
4255 | return; | 4163 | return; |
@@ -4260,15 +4168,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) | |||
4260 | cy_start(tty); | 4168 | cy_start(tty); |
4261 | 4169 | ||
4262 | card = info->card; | 4170 | card = info->card; |
4263 | channel = info->line - cy_card[card].first_line; | 4171 | channel = info->line - card->first_line; |
4264 | 4172 | ||
4265 | if (IS_CYC_Z(cy_card[card])) { | 4173 | if (IS_CYC_Z(*card)) { |
4266 | if (ch == STOP_CHAR(tty)) | 4174 | if (ch == STOP_CHAR(tty)) |
4267 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF, | 4175 | cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L); |
4268 | 0L); | ||
4269 | else if (ch == START_CHAR(tty)) | 4176 | else if (ch == START_CHAR(tty)) |
4270 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON, | 4177 | cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L); |
4271 | 0L); | ||
4272 | } | 4178 | } |
4273 | } | 4179 | } |
4274 | 4180 | ||
@@ -4278,15 +4184,16 @@ static void cy_send_xchar(struct tty_struct *tty, char ch) | |||
4278 | */ | 4184 | */ |
4279 | static void cy_throttle(struct tty_struct *tty) | 4185 | static void cy_throttle(struct tty_struct *tty) |
4280 | { | 4186 | { |
4281 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4187 | struct cyclades_port *info = tty->driver_data; |
4188 | struct cyclades_card *card; | ||
4282 | unsigned long flags; | 4189 | unsigned long flags; |
4283 | void __iomem *base_addr; | 4190 | void __iomem *base_addr; |
4284 | int card, chip, channel, index; | 4191 | int chip, channel, index; |
4285 | 4192 | ||
4286 | #ifdef CY_DEBUG_THROTTLE | 4193 | #ifdef CY_DEBUG_THROTTLE |
4287 | char buf[64]; | 4194 | char buf[64]; |
4288 | 4195 | ||
4289 | printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf), | 4196 | printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf), |
4290 | tty->ldisc.chars_in_buffer(tty), info->line); | 4197 | tty->ldisc.chars_in_buffer(tty), info->line); |
4291 | #endif | 4198 | #endif |
4292 | 4199 | ||
@@ -4297,22 +4204,22 @@ static void cy_throttle(struct tty_struct *tty) | |||
4297 | card = info->card; | 4204 | card = info->card; |
4298 | 4205 | ||
4299 | if (I_IXOFF(tty)) { | 4206 | if (I_IXOFF(tty)) { |
4300 | if (!IS_CYC_Z(cy_card[card])) | 4207 | if (!IS_CYC_Z(*card)) |
4301 | cy_send_xchar(tty, STOP_CHAR(tty)); | 4208 | cy_send_xchar(tty, STOP_CHAR(tty)); |
4302 | else | 4209 | else |
4303 | info->throttle = 1; | 4210 | info->throttle = 1; |
4304 | } | 4211 | } |
4305 | 4212 | ||
4306 | if (tty->termios->c_cflag & CRTSCTS) { | 4213 | if (tty->termios->c_cflag & CRTSCTS) { |
4307 | channel = info->line - cy_card[card].first_line; | 4214 | channel = info->line - card->first_line; |
4308 | if (!IS_CYC_Z(cy_card[card])) { | 4215 | if (!IS_CYC_Z(*card)) { |
4309 | chip = channel >> 2; | 4216 | chip = channel >> 2; |
4310 | channel &= 0x03; | 4217 | channel &= 0x03; |
4311 | index = cy_card[card].bus_index; | 4218 | index = card->bus_index; |
4312 | base_addr = cy_card[card].base_addr + | 4219 | base_addr = card->base_addr + |
4313 | (cy_chip_offset[chip] << index); | 4220 | (cy_chip_offset[chip] << index); |
4314 | 4221 | ||
4315 | CY_LOCK(info, flags); | 4222 | spin_lock_irqsave(&card->card_lock, flags); |
4316 | cy_writeb(base_addr + (CyCAR << index), | 4223 | cy_writeb(base_addr + (CyCAR << index), |
4317 | (u_char) channel); | 4224 | (u_char) channel); |
4318 | if (info->rtsdtr_inv) { | 4225 | if (info->rtsdtr_inv) { |
@@ -4322,7 +4229,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
4322 | cy_writeb(base_addr + (CyMSVR1 << index), | 4229 | cy_writeb(base_addr + (CyMSVR1 << index), |
4323 | ~CyRTS); | 4230 | ~CyRTS); |
4324 | } | 4231 | } |
4325 | CY_UNLOCK(info, flags); | 4232 | spin_unlock_irqrestore(&card->card_lock, flags); |
4326 | } else { | 4233 | } else { |
4327 | info->throttle = 1; | 4234 | info->throttle = 1; |
4328 | } | 4235 | } |
@@ -4336,16 +4243,17 @@ static void cy_throttle(struct tty_struct *tty) | |||
4336 | */ | 4243 | */ |
4337 | static void cy_unthrottle(struct tty_struct *tty) | 4244 | static void cy_unthrottle(struct tty_struct *tty) |
4338 | { | 4245 | { |
4339 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4246 | struct cyclades_port *info = tty->driver_data; |
4247 | struct cyclades_card *card; | ||
4340 | unsigned long flags; | 4248 | unsigned long flags; |
4341 | void __iomem *base_addr; | 4249 | void __iomem *base_addr; |
4342 | int card, chip, channel, index; | 4250 | int chip, channel, index; |
4343 | 4251 | ||
4344 | #ifdef CY_DEBUG_THROTTLE | 4252 | #ifdef CY_DEBUG_THROTTLE |
4345 | char buf[64]; | 4253 | char buf[64]; |
4346 | 4254 | ||
4347 | printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf), | 4255 | printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n", |
4348 | tty->ldisc.chars_in_buffer(tty), info->line); | 4256 | tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line); |
4349 | #endif | 4257 | #endif |
4350 | 4258 | ||
4351 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { | 4259 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { |
@@ -4361,15 +4269,15 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4361 | 4269 | ||
4362 | if (tty->termios->c_cflag & CRTSCTS) { | 4270 | if (tty->termios->c_cflag & CRTSCTS) { |
4363 | card = info->card; | 4271 | card = info->card; |
4364 | channel = info->line - cy_card[card].first_line; | 4272 | channel = info->line - card->first_line; |
4365 | if (!IS_CYC_Z(cy_card[card])) { | 4273 | if (!IS_CYC_Z(*card)) { |
4366 | chip = channel >> 2; | 4274 | chip = channel >> 2; |
4367 | channel &= 0x03; | 4275 | channel &= 0x03; |
4368 | index = cy_card[card].bus_index; | 4276 | index = card->bus_index; |
4369 | base_addr = cy_card[card].base_addr + | 4277 | base_addr = card->base_addr + |
4370 | (cy_chip_offset[chip] << index); | 4278 | (cy_chip_offset[chip] << index); |
4371 | 4279 | ||
4372 | CY_LOCK(info, flags); | 4280 | spin_lock_irqsave(&card->card_lock, flags); |
4373 | cy_writeb(base_addr + (CyCAR << index), | 4281 | cy_writeb(base_addr + (CyCAR << index), |
4374 | (u_char) channel); | 4282 | (u_char) channel); |
4375 | if (info->rtsdtr_inv) { | 4283 | if (info->rtsdtr_inv) { |
@@ -4379,7 +4287,7 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4379 | cy_writeb(base_addr + (CyMSVR1 << index), | 4287 | cy_writeb(base_addr + (CyMSVR1 << index), |
4380 | CyRTS); | 4288 | CyRTS); |
4381 | } | 4289 | } |
4382 | CY_UNLOCK(info, flags); | 4290 | spin_unlock_irqrestore(&card->card_lock, flags); |
4383 | } else { | 4291 | } else { |
4384 | info->throttle = 0; | 4292 | info->throttle = 0; |
4385 | } | 4293 | } |
@@ -4392,102 +4300,96 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
4392 | static void cy_stop(struct tty_struct *tty) | 4300 | static void cy_stop(struct tty_struct *tty) |
4393 | { | 4301 | { |
4394 | struct cyclades_card *cinfo; | 4302 | struct cyclades_card *cinfo; |
4395 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4303 | struct cyclades_port *info = tty->driver_data; |
4396 | void __iomem *base_addr; | 4304 | void __iomem *base_addr; |
4397 | int chip, channel, index; | 4305 | int chip, channel, index; |
4398 | unsigned long flags; | 4306 | unsigned long flags; |
4399 | 4307 | ||
4400 | #ifdef CY_DEBUG_OTHER | 4308 | #ifdef CY_DEBUG_OTHER |
4401 | printk("cyc:cy_stop ttyC%d\n", info->line); /* */ | 4309 | printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line); |
4402 | #endif | 4310 | #endif |
4403 | 4311 | ||
4404 | if (serial_paranoia_check(info, tty->name, "cy_stop")) | 4312 | if (serial_paranoia_check(info, tty->name, "cy_stop")) |
4405 | return; | 4313 | return; |
4406 | 4314 | ||
4407 | cinfo = &cy_card[info->card]; | 4315 | cinfo = info->card; |
4408 | channel = info->line - cinfo->first_line; | 4316 | channel = info->line - cinfo->first_line; |
4409 | if (!IS_CYC_Z(*cinfo)) { | 4317 | if (!IS_CYC_Z(*cinfo)) { |
4410 | index = cinfo->bus_index; | 4318 | index = cinfo->bus_index; |
4411 | chip = channel >> 2; | 4319 | chip = channel >> 2; |
4412 | channel &= 0x03; | 4320 | channel &= 0x03; |
4413 | base_addr = cy_card[info->card].base_addr + | 4321 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
4414 | (cy_chip_offset[chip] << index); | ||
4415 | 4322 | ||
4416 | CY_LOCK(info, flags); | 4323 | spin_lock_irqsave(&cinfo->card_lock, flags); |
4417 | cy_writeb(base_addr + (CyCAR << index), | 4324 | cy_writeb(base_addr + (CyCAR << index), |
4418 | (u_char)(channel & 0x0003)); /* index channel */ | 4325 | (u_char)(channel & 0x0003)); /* index channel */ |
4419 | cy_writeb(base_addr + (CySRER << index), | 4326 | cy_writeb(base_addr + (CySRER << index), |
4420 | cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); | 4327 | readb(base_addr + (CySRER << index)) & ~CyTxRdy); |
4421 | CY_UNLOCK(info, flags); | 4328 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
4422 | } else { | ||
4423 | /* Nothing to do! */ | ||
4424 | } | 4329 | } |
4425 | } /* cy_stop */ | 4330 | } /* cy_stop */ |
4426 | 4331 | ||
4427 | static void cy_start(struct tty_struct *tty) | 4332 | static void cy_start(struct tty_struct *tty) |
4428 | { | 4333 | { |
4429 | struct cyclades_card *cinfo; | 4334 | struct cyclades_card *cinfo; |
4430 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4335 | struct cyclades_port *info = tty->driver_data; |
4431 | void __iomem *base_addr; | 4336 | void __iomem *base_addr; |
4432 | int chip, channel, index; | 4337 | int chip, channel, index; |
4433 | unsigned long flags; | 4338 | unsigned long flags; |
4434 | 4339 | ||
4435 | #ifdef CY_DEBUG_OTHER | 4340 | #ifdef CY_DEBUG_OTHER |
4436 | printk("cyc:cy_start ttyC%d\n", info->line); /* */ | 4341 | printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line); |
4437 | #endif | 4342 | #endif |
4438 | 4343 | ||
4439 | if (serial_paranoia_check(info, tty->name, "cy_start")) | 4344 | if (serial_paranoia_check(info, tty->name, "cy_start")) |
4440 | return; | 4345 | return; |
4441 | 4346 | ||
4442 | cinfo = &cy_card[info->card]; | 4347 | cinfo = info->card; |
4443 | channel = info->line - cinfo->first_line; | 4348 | channel = info->line - cinfo->first_line; |
4444 | index = cinfo->bus_index; | 4349 | index = cinfo->bus_index; |
4445 | if (!IS_CYC_Z(*cinfo)) { | 4350 | if (!IS_CYC_Z(*cinfo)) { |
4446 | chip = channel >> 2; | 4351 | chip = channel >> 2; |
4447 | channel &= 0x03; | 4352 | channel &= 0x03; |
4448 | base_addr = cy_card[info->card].base_addr + | 4353 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
4449 | (cy_chip_offset[chip] << index); | ||
4450 | 4354 | ||
4451 | CY_LOCK(info, flags); | 4355 | spin_lock_irqsave(&cinfo->card_lock, flags); |
4452 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ | 4356 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ |
4453 | cy_writeb(base_addr + (CySRER << index), | 4357 | cy_writeb(base_addr + (CySRER << index), |
4454 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | 4358 | readb(base_addr + (CySRER << index)) | CyTxRdy); |
4455 | CY_UNLOCK(info, flags); | 4359 | spin_unlock_irqrestore(&cinfo->card_lock, flags); |
4456 | } else { | ||
4457 | /* Nothing to do! */ | ||
4458 | } | 4360 | } |
4459 | } /* cy_start */ | 4361 | } /* cy_start */ |
4460 | 4362 | ||
4461 | static void cy_flush_buffer(struct tty_struct *tty) | 4363 | static void cy_flush_buffer(struct tty_struct *tty) |
4462 | { | 4364 | { |
4463 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4365 | struct cyclades_port *info = tty->driver_data; |
4464 | int card, channel, retval; | 4366 | struct cyclades_card *card; |
4367 | int channel, retval; | ||
4465 | unsigned long flags; | 4368 | unsigned long flags; |
4466 | 4369 | ||
4467 | #ifdef CY_DEBUG_IO | 4370 | #ifdef CY_DEBUG_IO |
4468 | printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ | 4371 | printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line); |
4469 | #endif | 4372 | #endif |
4470 | 4373 | ||
4471 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | 4374 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) |
4472 | return; | 4375 | return; |
4473 | 4376 | ||
4474 | card = info->card; | 4377 | card = info->card; |
4475 | channel = (info->line) - (cy_card[card].first_line); | 4378 | channel = info->line - card->first_line; |
4476 | 4379 | ||
4477 | CY_LOCK(info, flags); | 4380 | spin_lock_irqsave(&card->card_lock, flags); |
4478 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 4381 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
4479 | CY_UNLOCK(info, flags); | 4382 | spin_unlock_irqrestore(&card->card_lock, flags); |
4480 | 4383 | ||
4481 | if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board | 4384 | if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board |
4482 | buffers as well */ | 4385 | buffers as well */ |
4483 | CY_LOCK(info, flags); | 4386 | spin_lock_irqsave(&card->card_lock, flags); |
4484 | retval = | 4387 | retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L); |
4485 | cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L); | ||
4486 | if (retval != 0) { | 4388 | if (retval != 0) { |
4487 | printk("cyc: flush_buffer retval on ttyC%d was %x\n", | 4389 | printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d " |
4488 | info->line, retval); | 4390 | "was %x\n", info->line, retval); |
4489 | } | 4391 | } |
4490 | CY_UNLOCK(info, flags); | 4392 | spin_unlock_irqrestore(&card->card_lock, flags); |
4491 | } | 4393 | } |
4492 | tty_wakeup(tty); | 4394 | tty_wakeup(tty); |
4493 | } /* cy_flush_buffer */ | 4395 | } /* cy_flush_buffer */ |
@@ -4497,10 +4399,10 @@ static void cy_flush_buffer(struct tty_struct *tty) | |||
4497 | */ | 4399 | */ |
4498 | static void cy_hangup(struct tty_struct *tty) | 4400 | static void cy_hangup(struct tty_struct *tty) |
4499 | { | 4401 | { |
4500 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4402 | struct cyclades_port *info = tty->driver_data; |
4501 | 4403 | ||
4502 | #ifdef CY_DEBUG_OTHER | 4404 | #ifdef CY_DEBUG_OTHER |
4503 | printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ | 4405 | printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line); |
4504 | #endif | 4406 | #endif |
4505 | 4407 | ||
4506 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) | 4408 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) |
@@ -4511,7 +4413,8 @@ static void cy_hangup(struct tty_struct *tty) | |||
4511 | info->event = 0; | 4413 | info->event = 0; |
4512 | info->count = 0; | 4414 | info->count = 0; |
4513 | #ifdef CY_DEBUG_COUNT | 4415 | #ifdef CY_DEBUG_COUNT |
4514 | printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); | 4416 | printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", |
4417 | current->pid); | ||
4515 | #endif | 4418 | #endif |
4516 | info->tty = NULL; | 4419 | info->tty = NULL; |
4517 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 4420 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
@@ -4526,10 +4429,107 @@ static void cy_hangup(struct tty_struct *tty) | |||
4526 | * --------------------------------------------------------------------- | 4429 | * --------------------------------------------------------------------- |
4527 | */ | 4430 | */ |
4528 | 4431 | ||
4432 | static int __devinit cy_init_card(struct cyclades_card *cinfo) | ||
4433 | { | ||
4434 | struct cyclades_port *info; | ||
4435 | u32 mailbox; | ||
4436 | unsigned int nports; | ||
4437 | unsigned short chip_number; | ||
4438 | int index, port; | ||
4439 | |||
4440 | spin_lock_init(&cinfo->card_lock); | ||
4441 | |||
4442 | if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */ | ||
4443 | mailbox = readl(&((struct RUNTIME_9060 __iomem *) | ||
4444 | cinfo->ctl_addr)->mail_box_0); | ||
4445 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; | ||
4446 | cinfo->intr_enabled = 0; | ||
4447 | cinfo->nports = 0; /* Will be correctly set later, after | ||
4448 | Z FW is loaded */ | ||
4449 | } else { | ||
4450 | index = cinfo->bus_index; | ||
4451 | nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; | ||
4452 | } | ||
4453 | |||
4454 | cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL); | ||
4455 | if (cinfo->ports == NULL) { | ||
4456 | printk(KERN_ERR "Cyclades: cannot allocate ports\n"); | ||
4457 | cinfo->nports = 0; | ||
4458 | return -ENOMEM; | ||
4459 | } | ||
4460 | |||
4461 | for (port = cinfo->first_line; port < cinfo->first_line + nports; | ||
4462 | port++) { | ||
4463 | info = &cinfo->ports[port - cinfo->first_line]; | ||
4464 | info->magic = CYCLADES_MAGIC; | ||
4465 | info->card = cinfo; | ||
4466 | info->line = port; | ||
4467 | info->flags = STD_COM_FLAGS; | ||
4468 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
4469 | info->close_delay = 5 * HZ / 10; | ||
4470 | |||
4471 | INIT_WORK(&info->tqueue, do_softint); | ||
4472 | init_waitqueue_head(&info->open_wait); | ||
4473 | init_waitqueue_head(&info->close_wait); | ||
4474 | init_completion(&info->shutdown_wait); | ||
4475 | init_waitqueue_head(&info->delta_msr_wait); | ||
4476 | |||
4477 | if (IS_CYC_Z(*cinfo)) { | ||
4478 | info->type = PORT_STARTECH; | ||
4479 | if (mailbox == ZO_V1) | ||
4480 | info->xmit_fifo_size = CYZ_FIFO_SIZE; | ||
4481 | else | ||
4482 | info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; | ||
4483 | #ifdef CONFIG_CYZ_INTR | ||
4484 | setup_timer(&cyz_rx_full_timer[port], | ||
4485 | cyz_rx_restart, (unsigned long)info); | ||
4486 | #endif | ||
4487 | } else { | ||
4488 | info->type = PORT_CIRRUS; | ||
4489 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; | ||
4490 | info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; | ||
4491 | info->cor2 = CyETC; | ||
4492 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | ||
4493 | |||
4494 | chip_number = (port - cinfo->first_line) / 4; | ||
4495 | if ((info->chip_rev = readb(cinfo->base_addr + | ||
4496 | (cy_chip_offset[chip_number] << | ||
4497 | index) + (CyGFRCR << index))) >= | ||
4498 | CD1400_REV_J) { | ||
4499 | /* It is a CD1400 rev. J or later */ | ||
4500 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | ||
4501 | info->tco = baud_co_60[13]; /* Tx CO */ | ||
4502 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ | ||
4503 | info->rco = baud_co_60[13]; /* Rx CO */ | ||
4504 | info->rtsdtr_inv = 1; | ||
4505 | } else { | ||
4506 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ | ||
4507 | info->tco = baud_co_25[13]; /* Tx CO */ | ||
4508 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ | ||
4509 | info->rco = baud_co_25[13]; /* Rx CO */ | ||
4510 | info->rtsdtr_inv = 0; | ||
4511 | } | ||
4512 | info->read_status_mask = CyTIMEOUT | CySPECHAR | | ||
4513 | CyBREAK | CyPARITY | CyFRAME | CyOVERRUN; | ||
4514 | } | ||
4515 | |||
4516 | } | ||
4517 | |||
4518 | #ifndef CONFIG_CYZ_INTR | ||
4519 | if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) { | ||
4520 | mod_timer(&cyz_timerlist, jiffies + 1); | ||
4521 | #ifdef CY_PCI_DEBUG | ||
4522 | printk(KERN_DEBUG "Cyclades-Z polling initialized\n"); | ||
4523 | #endif | ||
4524 | } | ||
4525 | #endif | ||
4526 | return 0; | ||
4527 | } | ||
4528 | |||
4529 | /* initialize chips on Cyclom-Y card -- return number of valid | 4529 | /* initialize chips on Cyclom-Y card -- return number of valid |
4530 | chips (which is number of ports/4) */ | 4530 | chips (which is number of ports/4) */ |
4531 | static unsigned short __init | 4531 | static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, |
4532 | cyy_init_card(void __iomem * true_base_addr, int index) | 4532 | int index) |
4533 | { | 4533 | { |
4534 | unsigned int chip_number; | 4534 | unsigned int chip_number; |
4535 | void __iomem *base_addr; | 4535 | void __iomem *base_addr; |
@@ -4544,7 +4544,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4544 | base_addr = | 4544 | base_addr = |
4545 | true_base_addr + (cy_chip_offset[chip_number] << index); | 4545 | true_base_addr + (cy_chip_offset[chip_number] << index); |
4546 | mdelay(1); | 4546 | mdelay(1); |
4547 | if (cy_readb(base_addr + (CyCCR << index)) != 0x00) { | 4547 | if (readb(base_addr + (CyCCR << index)) != 0x00) { |
4548 | /************* | 4548 | /************* |
4549 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", | 4549 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", |
4550 | chip_number, (unsigned long)base_addr); | 4550 | chip_number, (unsigned long)base_addr); |
@@ -4561,7 +4561,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4561 | chip 4 GFRCR register appears at chip 0, there is no chip 4 | 4561 | chip 4 GFRCR register appears at chip 0, there is no chip 4 |
4562 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. | 4562 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. |
4563 | */ | 4563 | */ |
4564 | if (chip_number == 4 && cy_readb(true_base_addr + | 4564 | if (chip_number == 4 && readb(true_base_addr + |
4565 | (cy_chip_offset[0] << index) + | 4565 | (cy_chip_offset[0] << index) + |
4566 | (CyGFRCR << index)) == 0) { | 4566 | (CyGFRCR << index)) == 0) { |
4567 | return chip_number; | 4567 | return chip_number; |
@@ -4570,7 +4570,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4570 | cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); | 4570 | cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); |
4571 | mdelay(1); | 4571 | mdelay(1); |
4572 | 4572 | ||
4573 | if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) { | 4573 | if (readb(base_addr + (CyGFRCR << index)) == 0x00) { |
4574 | /* | 4574 | /* |
4575 | printk(" chip #%d at %#6lx is not responding ", | 4575 | printk(" chip #%d at %#6lx is not responding ", |
4576 | chip_number, (unsigned long)base_addr); | 4576 | chip_number, (unsigned long)base_addr); |
@@ -4578,7 +4578,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4578 | */ | 4578 | */ |
4579 | return chip_number; | 4579 | return chip_number; |
4580 | } | 4580 | } |
4581 | if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) != | 4581 | if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) != |
4582 | 0x40) { | 4582 | 0x40) { |
4583 | /* | 4583 | /* |
4584 | printk(" chip #%d at %#6lx is not valid (GFRCR == " | 4584 | printk(" chip #%d at %#6lx is not valid (GFRCR == " |
@@ -4589,7 +4589,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4589 | return chip_number; | 4589 | return chip_number; |
4590 | } | 4590 | } |
4591 | cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); | 4591 | cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); |
4592 | if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { | 4592 | if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { |
4593 | /* It is a CD1400 rev. J or later */ | 4593 | /* It is a CD1400 rev. J or later */ |
4594 | /* Impossible to reach 5ms with this chip. | 4594 | /* Impossible to reach 5ms with this chip. |
4595 | Changed to 2ms instead (f = 500 Hz). */ | 4595 | Changed to 2ms instead (f = 500 Hz). */ |
@@ -4602,7 +4602,7 @@ cyy_init_card(void __iomem * true_base_addr, int index) | |||
4602 | /* | 4602 | /* |
4603 | printk(" chip #%d at %#6lx is rev 0x%2x\n", | 4603 | printk(" chip #%d at %#6lx is rev 0x%2x\n", |
4604 | chip_number, (unsigned long)base_addr, | 4604 | chip_number, (unsigned long)base_addr, |
4605 | cy_readb(base_addr+(CyGFRCR<<index))); | 4605 | readb(base_addr+(CyGFRCR<<index))); |
4606 | */ | 4606 | */ |
4607 | } | 4607 | } |
4608 | return chip_number; | 4608 | return chip_number; |
@@ -4647,9 +4647,15 @@ static int __init cy_detect_isa(void) | |||
4647 | 4647 | ||
4648 | /* probe for CD1400... */ | 4648 | /* probe for CD1400... */ |
4649 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); | 4649 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); |
4650 | if (cy_isa_address == NULL) { | ||
4651 | printk(KERN_ERR "Cyclom-Y/ISA: can't remap base " | ||
4652 | "address\n"); | ||
4653 | continue; | ||
4654 | } | ||
4650 | cy_isa_nchan = CyPORTS_PER_CHIP * | 4655 | cy_isa_nchan = CyPORTS_PER_CHIP * |
4651 | cyy_init_card(cy_isa_address, 0); | 4656 | cyy_init_card(cy_isa_address, 0); |
4652 | if (cy_isa_nchan == 0) { | 4657 | if (cy_isa_nchan == 0) { |
4658 | iounmap(cy_isa_address); | ||
4653 | continue; | 4659 | continue; |
4654 | } | 4660 | } |
4655 | #ifdef MODULE | 4661 | #ifdef MODULE |
@@ -4660,40 +4666,42 @@ static int __init cy_detect_isa(void) | |||
4660 | /* find out the board's irq by probing */ | 4666 | /* find out the board's irq by probing */ |
4661 | cy_isa_irq = detect_isa_irq(cy_isa_address); | 4667 | cy_isa_irq = detect_isa_irq(cy_isa_address); |
4662 | if (cy_isa_irq == 0) { | 4668 | if (cy_isa_irq == 0) { |
4663 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4669 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the " |
4670 | "IRQ could not be detected.\n", | ||
4664 | (unsigned long)cy_isa_address); | 4671 | (unsigned long)cy_isa_address); |
4665 | printk("but the IRQ could not be detected.\n"); | 4672 | iounmap(cy_isa_address); |
4666 | continue; | 4673 | continue; |
4667 | } | 4674 | } |
4668 | 4675 | ||
4669 | if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { | 4676 | if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { |
4670 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4677 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " |
4678 | "more channels are available. Change NR_PORTS " | ||
4679 | "in cyclades.c and recompile kernel.\n", | ||
4671 | (unsigned long)cy_isa_address); | 4680 | (unsigned long)cy_isa_address); |
4672 | printk("but no more channels are available.\n"); | 4681 | iounmap(cy_isa_address); |
4673 | printk("Change NR_PORTS in cyclades.c and recompile " | ||
4674 | "kernel.\n"); | ||
4675 | return nboard; | 4682 | return nboard; |
4676 | } | 4683 | } |
4677 | /* fill the next cy_card structure available */ | 4684 | /* fill the next cy_card structure available */ |
4678 | for (j = 0; j < NR_CARDS; j++) { | 4685 | for (j = 0; j < NR_CARDS; j++) { |
4679 | if (cy_card[j].base_addr == 0) | 4686 | if (cy_card[j].base_addr == NULL) |
4680 | break; | 4687 | break; |
4681 | } | 4688 | } |
4682 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4689 | if (j == NR_CARDS) { /* no more cy_cards available */ |
4683 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4690 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no " |
4691 | "more cards can be used. Change NR_CARDS in " | ||
4692 | "cyclades.c and recompile kernel.\n", | ||
4684 | (unsigned long)cy_isa_address); | 4693 | (unsigned long)cy_isa_address); |
4685 | printk("but no more cards can be used .\n"); | 4694 | iounmap(cy_isa_address); |
4686 | printk("Change NR_CARDS in cyclades.c and recompile " | ||
4687 | "kernel.\n"); | ||
4688 | return nboard; | 4695 | return nboard; |
4689 | } | 4696 | } |
4690 | 4697 | ||
4691 | /* allocate IRQ */ | 4698 | /* allocate IRQ */ |
4692 | if (request_irq(cy_isa_irq, cyy_interrupt, | 4699 | if (request_irq(cy_isa_irq, cyy_interrupt, |
4693 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { | 4700 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { |
4694 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4701 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
4695 | (unsigned long)cy_isa_address); | 4702 | "could not allocate IRQ#%d.\n", |
4696 | printk("but could not allocate IRQ#%d.\n", cy_isa_irq); | 4703 | (unsigned long)cy_isa_address, cy_isa_irq); |
4704 | iounmap(cy_isa_address); | ||
4697 | return nboard; | 4705 | return nboard; |
4698 | } | 4706 | } |
4699 | 4707 | ||
@@ -4704,15 +4712,23 @@ static int __init cy_detect_isa(void) | |||
4704 | cy_card[j].bus_index = 0; | 4712 | cy_card[j].bus_index = 0; |
4705 | cy_card[j].first_line = cy_next_channel; | 4713 | cy_card[j].first_line = cy_next_channel; |
4706 | cy_card[j].num_chips = cy_isa_nchan / 4; | 4714 | cy_card[j].num_chips = cy_isa_nchan / 4; |
4715 | if (cy_init_card(&cy_card[j])) { | ||
4716 | cy_card[j].base_addr = NULL; | ||
4717 | free_irq(cy_isa_irq, &cy_card[j]); | ||
4718 | iounmap(cy_isa_address); | ||
4719 | continue; | ||
4720 | } | ||
4707 | nboard++; | 4721 | nboard++; |
4708 | 4722 | ||
4709 | /* print message */ | 4723 | printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: " |
4710 | printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", | 4724 | "%d channels starting from port %d\n", |
4711 | j + 1, (unsigned long)cy_isa_address, | 4725 | j + 1, (unsigned long)cy_isa_address, |
4712 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), | 4726 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), |
4713 | cy_isa_irq); | 4727 | cy_isa_irq, cy_isa_nchan, cy_next_channel); |
4714 | printk("%d channels starting from port %d.\n", | 4728 | |
4715 | cy_isa_nchan, cy_next_channel); | 4729 | for (j = cy_next_channel; |
4730 | j < cy_next_channel + cy_isa_nchan; j++) | ||
4731 | tty_register_device(cy_serial_driver, j, NULL); | ||
4716 | cy_next_channel += cy_isa_nchan; | 4732 | cy_next_channel += cy_isa_nchan; |
4717 | } | 4733 | } |
4718 | return nboard; | 4734 | return nboard; |
@@ -4721,510 +4737,310 @@ static int __init cy_detect_isa(void) | |||
4721 | #endif /* CONFIG_ISA */ | 4737 | #endif /* CONFIG_ISA */ |
4722 | } /* cy_detect_isa */ | 4738 | } /* cy_detect_isa */ |
4723 | 4739 | ||
4724 | static void plx_init(void __iomem * addr, uclong initctl) | 4740 | #ifdef CONFIG_PCI |
4741 | static void __devinit plx_init(void __iomem * addr, __u32 initctl) | ||
4725 | { | 4742 | { |
4726 | /* Reset PLX */ | 4743 | /* Reset PLX */ |
4727 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); | 4744 | cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000); |
4728 | udelay(100L); | 4745 | udelay(100L); |
4729 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); | 4746 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000); |
4730 | 4747 | ||
4731 | /* Reload Config. Registers from EEPROM */ | 4748 | /* Reload Config. Registers from EEPROM */ |
4732 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); | 4749 | cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000); |
4733 | udelay(100L); | 4750 | udelay(100L); |
4734 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); | 4751 | cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000); |
4735 | } | 4752 | } |
4736 | 4753 | ||
4737 | /* | 4754 | static int __devinit cy_pci_probe(struct pci_dev *pdev, |
4738 | * --------------------------------------------------------------------- | 4755 | const struct pci_device_id *ent) |
4739 | * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI. | ||
4740 | * sets global variables and return the number of PCI boards found. | ||
4741 | * --------------------------------------------------------------------- | ||
4742 | */ | ||
4743 | static int __init cy_detect_pci(void) | ||
4744 | { | 4756 | { |
4745 | #ifdef CONFIG_PCI | 4757 | void __iomem *addr0 = NULL, *addr2 = NULL; |
4746 | 4758 | char *card_name = NULL; | |
4747 | struct pci_dev *pdev = NULL; | 4759 | u32 mailbox; |
4748 | unsigned char cyy_rev_id; | 4760 | unsigned int device_id, nchan = 0, card_no, i; |
4749 | unsigned char cy_pci_irq = 0; | 4761 | unsigned char plx_ver; |
4750 | uclong cy_pci_phys0, cy_pci_phys2; | 4762 | int retval, irq; |
4751 | void __iomem *cy_pci_addr0, *cy_pci_addr2; | 4763 | |
4752 | unsigned short i, j, cy_pci_nchan, plx_ver; | 4764 | retval = pci_enable_device(pdev); |
4753 | unsigned short device_id, dev_index = 0; | 4765 | if (retval) { |
4754 | uclong mailbox; | 4766 | dev_err(&pdev->dev, "cannot enable device\n"); |
4755 | uclong ZeIndex = 0; | 4767 | goto err; |
4756 | void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; | 4768 | } |
4757 | uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS]; | ||
4758 | unsigned char Ze_irq[NR_CARDS]; | ||
4759 | struct pci_dev *Ze_pdev[NR_CARDS]; | ||
4760 | |||
4761 | for (i = 0; i < NR_CARDS; i++) { | ||
4762 | /* look for a Cyclades card by vendor and device id */ | ||
4763 | while ((device_id = cy_pci_dev_id[dev_index].device) != 0) { | ||
4764 | if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, | ||
4765 | device_id, pdev)) == NULL) { | ||
4766 | dev_index++; /* try next device id */ | ||
4767 | } else { | ||
4768 | break; /* found a board */ | ||
4769 | } | ||
4770 | } | ||
4771 | |||
4772 | if (device_id == 0) | ||
4773 | break; | ||
4774 | |||
4775 | if (pci_enable_device(pdev)) | ||
4776 | continue; | ||
4777 | |||
4778 | /* read PCI configuration area */ | ||
4779 | cy_pci_irq = pdev->irq; | ||
4780 | cy_pci_phys0 = pci_resource_start(pdev, 0); | ||
4781 | cy_pci_phys2 = pci_resource_start(pdev, 2); | ||
4782 | pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id); | ||
4783 | 4769 | ||
4784 | device_id &= ~PCI_DEVICE_ID_MASK; | 4770 | /* read PCI configuration area */ |
4771 | irq = pdev->irq; | ||
4772 | device_id = pdev->device & ~PCI_DEVICE_ID_MASK; | ||
4785 | 4773 | ||
4786 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | 4774 | #if defined(__alpha__) |
4787 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 4775 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ |
4788 | #ifdef CY_PCI_DEBUG | 4776 | dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low " |
4789 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | 4777 | "addresses on Alpha systems.\n"); |
4790 | pdev->bus->number, pdev->devfn); | 4778 | retval = -EIO; |
4791 | printk("rev_id=%d) IRQ%d\n", | 4779 | goto err_dis; |
4792 | cyy_rev_id, (int)cy_pci_irq); | 4780 | } |
4793 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " | ||
4794 | "ctladdr=0x%lx\n", | ||
4795 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | ||
4796 | #endif | 4781 | #endif |
4782 | if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | ||
4783 | dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low " | ||
4784 | "addresses\n"); | ||
4785 | retval = -EIO; | ||
4786 | goto err_dis; | ||
4787 | } | ||
4797 | 4788 | ||
4798 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | 4789 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { |
4799 | printk(" Warning: PCI I/O bit incorrectly " | 4790 | dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring " |
4800 | "set. Ignoring it...\n"); | 4791 | "it...\n"); |
4801 | pdev->resource[2].flags &= ~IORESOURCE_IO; | 4792 | pdev->resource[2].flags &= ~IORESOURCE_IO; |
4802 | } | 4793 | } |
4803 | 4794 | ||
4804 | /* Although we don't use this I/O region, we should | 4795 | retval = pci_request_regions(pdev, "cyclades"); |
4805 | request it from the kernel anyway, to avoid problems | 4796 | if (retval) { |
4806 | with other drivers accessing it. */ | 4797 | dev_err(&pdev->dev, "failed to reserve resources\n"); |
4807 | if (pci_request_regions(pdev, "Cyclom-Y") != 0) { | 4798 | goto err_dis; |
4808 | printk(KERN_ERR "cyclades: failed to reserve " | 4799 | } |
4809 | "PCI resources\n"); | ||
4810 | continue; | ||
4811 | } | ||
4812 | #if defined(__alpha__) | ||
4813 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ | ||
4814 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | ||
4815 | pdev->bus->number, pdev->devfn); | ||
4816 | printk("rev_id=%d) IRQ%d\n", | ||
4817 | cyy_rev_id, (int)cy_pci_irq); | ||
4818 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " | ||
4819 | "ctladdr=0x%lx\n", | ||
4820 | (ulong)cy_pci_phys2, | ||
4821 | (ulong)cy_pci_phys0); | ||
4822 | printk("Cyclom-Y/PCI not supported for low " | ||
4823 | "addresses in Alpha systems.\n"); | ||
4824 | i--; | ||
4825 | continue; | ||
4826 | } | ||
4827 | #endif | ||
4828 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl); | ||
4829 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin); | ||
4830 | 4800 | ||
4831 | #ifdef CY_PCI_DEBUG | 4801 | retval = -EIO; |
4832 | printk("Cyclom-Y/PCI: relocate winaddr=0x%lx " | 4802 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
4833 | "ctladdr=0x%lx\n", | 4803 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4834 | (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); | 4804 | card_name = "Cyclom-Y"; |
4835 | #endif | ||
4836 | cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * | ||
4837 | cyy_init_card(cy_pci_addr2, 1)); | ||
4838 | if (cy_pci_nchan == 0) { | ||
4839 | printk("Cyclom-Y PCI host card with "); | ||
4840 | printk("no Serial-Modules at 0x%lx.\n", | ||
4841 | (ulong) cy_pci_phys2); | ||
4842 | i--; | ||
4843 | continue; | ||
4844 | } | ||
4845 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
4846 | printk("Cyclom-Y/PCI found at 0x%lx ", | ||
4847 | (ulong) cy_pci_phys2); | ||
4848 | printk("but no channels are available.\n"); | ||
4849 | printk("Change NR_PORTS in cyclades.c and " | ||
4850 | "recompile kernel.\n"); | ||
4851 | return i; | ||
4852 | } | ||
4853 | /* fill the next cy_card structure available */ | ||
4854 | for (j = 0; j < NR_CARDS; j++) { | ||
4855 | if (cy_card[j].base_addr == 0) | ||
4856 | break; | ||
4857 | } | ||
4858 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
4859 | printk("Cyclom-Y/PCI found at 0x%lx ", | ||
4860 | (ulong) cy_pci_phys2); | ||
4861 | printk("but no more cards can be used.\n"); | ||
4862 | printk("Change NR_CARDS in cyclades.c and " | ||
4863 | "recompile kernel.\n"); | ||
4864 | return i; | ||
4865 | } | ||
4866 | 4805 | ||
4867 | /* allocate IRQ */ | 4806 | addr0 = pci_iomap(pdev, 0, CyPCI_Yctl); |
4868 | if (request_irq(cy_pci_irq, cyy_interrupt, | 4807 | if (addr0 == NULL) { |
4869 | IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { | 4808 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4870 | printk("Cyclom-Y/PCI found at 0x%lx ", | 4809 | goto err_reg; |
4871 | (ulong) cy_pci_phys2); | 4810 | } |
4872 | printk("but could not allocate IRQ%d.\n", | 4811 | addr2 = pci_iomap(pdev, 2, CyPCI_Ywin); |
4873 | cy_pci_irq); | 4812 | if (addr2 == NULL) { |
4874 | return i; | 4813 | dev_err(&pdev->dev, "can't remap base region\n"); |
4875 | } | 4814 | goto err_unmap; |
4815 | } | ||
4876 | 4816 | ||
4877 | /* set cy_card */ | 4817 | nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1); |
4878 | cy_card[j].base_phys = (ulong) cy_pci_phys2; | 4818 | if (nchan == 0) { |
4879 | cy_card[j].ctl_phys = (ulong) cy_pci_phys0; | 4819 | dev_err(&pdev->dev, "Cyclom-Y PCI host card with no " |
4880 | cy_card[j].base_addr = cy_pci_addr2; | 4820 | "Serial-Modules\n"); |
4881 | cy_card[j].ctl_addr = cy_pci_addr0; | 4821 | return -EIO; |
4882 | cy_card[j].irq = (int)cy_pci_irq; | 4822 | } |
4883 | cy_card[j].bus_index = 1; | 4823 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { |
4884 | cy_card[j].first_line = cy_next_channel; | 4824 | struct RUNTIME_9060 __iomem *ctl_addr; |
4885 | cy_card[j].num_chips = cy_pci_nchan / 4; | ||
4886 | cy_card[j].pdev = pdev; | ||
4887 | |||
4888 | /* enable interrupts in the PCI interface */ | ||
4889 | plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; | ||
4890 | switch (plx_ver) { | ||
4891 | case PLX_9050: | ||
4892 | |||
4893 | cy_writeb(cy_pci_addr0 + 0x4c, 0x43); | ||
4894 | break; | ||
4895 | 4825 | ||
4896 | case PLX_9060: | 4826 | ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl); |
4897 | case PLX_9080: | 4827 | if (addr0 == NULL) { |
4898 | default: /* Old boards, use PLX_9060 */ | 4828 | dev_err(&pdev->dev, "can't remap ctl region\n"); |
4899 | 4829 | goto err_reg; | |
4900 | plx_init(cy_pci_addr0, 0x6c); | 4830 | } |
4901 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4902 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4903 | re-write it to the PCI config. registers. | ||
4904 | This will remain here until we find a permanent | ||
4905 | fix. */ | ||
4906 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4907 | cy_pci_irq); | ||
4908 | |||
4909 | cy_writew(cy_pci_addr0 + 0x68, | ||
4910 | cy_readw(cy_pci_addr0 + | ||
4911 | 0x68) | 0x0900); | ||
4912 | break; | ||
4913 | } | ||
4914 | 4831 | ||
4915 | /* print message */ | 4832 | /* Disable interrupts on the PLX before resetting it */ |
4916 | printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | 4833 | cy_writew(addr0 + 0x68, |
4917 | j + 1, (ulong)cy_pci_phys2, | 4834 | readw(addr0 + 0x68) & ~0x0900); |
4918 | (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1), | 4835 | |
4919 | (int)cy_pci_irq); | 4836 | plx_init(addr0, 0x6c); |
4920 | printk("%d channels starting from port %d.\n", | 4837 | /* For some yet unknown reason, once the PLX9060 reloads |
4921 | cy_pci_nchan, cy_next_channel); | 4838 | the EEPROM, the IRQ is lost and, thus, we have to |
4922 | 4839 | re-write it to the PCI config. registers. | |
4923 | cy_next_channel += cy_pci_nchan; | 4840 | This will remain here until we find a permanent |
4924 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | 4841 | fix. */ |
4925 | /* print message */ | 4842 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); |
4926 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | 4843 | |
4927 | pdev->bus->number, pdev->devfn); | 4844 | mailbox = (u32)readl(&ctl_addr->mail_box_0); |
4928 | printk("rev_id=%d) IRQ%d\n", | 4845 | |
4929 | cyy_rev_id, (int)cy_pci_irq); | 4846 | addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ? |
4930 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " | 4847 | CyPCI_Ze_win : CyPCI_Zwin); |
4931 | "ctladdr=0x%lx\n", | 4848 | if (addr2 == NULL) { |
4932 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4849 | dev_err(&pdev->dev, "can't remap base region\n"); |
4933 | printk("Cyclades-Z/PCI not supported for low " | 4850 | goto err_unmap; |
4934 | "addresses\n"); | 4851 | } |
4935 | break; | ||
4936 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | ||
4937 | #ifdef CY_PCI_DEBUG | ||
4938 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | ||
4939 | pdev->bus->number, pdev->devfn); | ||
4940 | printk("rev_id=%d) IRQ%d\n", | ||
4941 | cyy_rev_id, (int)cy_pci_irq); | ||
4942 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " | ||
4943 | "ctladdr=0x%lx\n", | ||
4944 | (ulong) cy_pci_phys2, (ulong) cy_pci_phys0); | ||
4945 | #endif | ||
4946 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl); | ||
4947 | |||
4948 | /* Disable interrupts on the PLX before resetting it */ | ||
4949 | cy_writew(cy_pci_addr0 + 0x68, | ||
4950 | cy_readw(cy_pci_addr0 + 0x68) & ~0x0900); | ||
4951 | |||
4952 | plx_init(cy_pci_addr0, 0x6c); | ||
4953 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4954 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4955 | re-write it to the PCI config. registers. | ||
4956 | This will remain here until we find a permanent | ||
4957 | fix. */ | ||
4958 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4959 | cy_pci_irq); | ||
4960 | |||
4961 | mailbox = | ||
4962 | (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
4963 | cy_pci_addr0)->mail_box_0); | ||
4964 | |||
4965 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | ||
4966 | printk(" Warning: PCI I/O bit incorrectly " | ||
4967 | "set. Ignoring it...\n"); | ||
4968 | pdev->resource[2].flags &= ~IORESOURCE_IO; | ||
4969 | } | ||
4970 | 4852 | ||
4971 | /* Although we don't use this I/O region, we should | 4853 | if (mailbox == ZE_V1) { |
4972 | request it from the kernel anyway, to avoid problems | 4854 | card_name = "Cyclades-Ze"; |
4973 | with other drivers accessing it. */ | ||
4974 | if (pci_request_regions(pdev, "Cyclades-Z") != 0) { | ||
4975 | printk(KERN_ERR "cyclades: failed to reserve " | ||
4976 | "PCI resources\n"); | ||
4977 | continue; | ||
4978 | } | ||
4979 | 4855 | ||
4980 | if (mailbox == ZE_V1) { | 4856 | readl(&ctl_addr->mail_box_0); |
4981 | cy_pci_addr2 = ioremap(cy_pci_phys2, | 4857 | nchan = ZE_V1_NPORTS; |
4982 | CyPCI_Ze_win); | 4858 | } else { |
4983 | if (ZeIndex == NR_CARDS) { | 4859 | card_name = "Cyclades-8Zo"; |
4984 | printk("Cyclades-Ze/PCI found at " | ||
4985 | "0x%lx but no more cards can " | ||
4986 | "be used.\nChange NR_CARDS in " | ||
4987 | "cyclades.c and recompile " | ||
4988 | "kernel.\n", | ||
4989 | (ulong)cy_pci_phys2); | ||
4990 | } else { | ||
4991 | Ze_phys0[ZeIndex] = cy_pci_phys0; | ||
4992 | Ze_phys2[ZeIndex] = cy_pci_phys2; | ||
4993 | Ze_addr0[ZeIndex] = cy_pci_addr0; | ||
4994 | Ze_addr2[ZeIndex] = cy_pci_addr2; | ||
4995 | Ze_irq[ZeIndex] = cy_pci_irq; | ||
4996 | Ze_pdev[ZeIndex] = pdev; | ||
4997 | ZeIndex++; | ||
4998 | } | ||
4999 | i--; | ||
5000 | continue; | ||
5001 | } else { | ||
5002 | cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin); | ||
5003 | } | ||
5004 | 4860 | ||
5005 | #ifdef CY_PCI_DEBUG | 4861 | #ifdef CY_PCI_DEBUG |
5006 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx " | ||
5007 | "ctladdr=0x%lx\n", | ||
5008 | (ulong) cy_pci_addr2, (ulong) cy_pci_addr0); | ||
5009 | if (mailbox == ZO_V1) { | 4862 | if (mailbox == ZO_V1) { |
5010 | cy_writel(&((struct RUNTIME_9060 *) | 4863 | cy_writel(&ctl_addr->loc_addr_base, WIN_CREG); |
5011 | (cy_pci_addr0))->loc_addr_base, | 4864 | dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA " |
5012 | WIN_CREG); | 4865 | "id %lx, ver %lx\n", (ulong)(0xff & |
5013 | PAUSE; | 4866 | readl(&((struct CUSTOM_REG *)addr2)-> |
5014 | printk("Cyclades-8Zo/PCI: FPGA id %lx, ver " | 4867 | fpga_id)), (ulong)(0xff & |
5015 | "%lx\n", (ulong) (0xff & | 4868 | readl(&((struct CUSTOM_REG *)addr2)-> |
5016 | cy_readl(&((struct CUSTOM_REG *) | 4869 | fpga_version))); |
5017 | (cy_pci_addr2))->fpga_id)), | 4870 | cy_writel(&ctl_addr->loc_addr_base, WIN_RAM); |
5018 | (ulong)(0xff & | ||
5019 | cy_readl(&((struct CUSTOM_REG *) | ||
5020 | (cy_pci_addr2))-> | ||
5021 | fpga_version))); | ||
5022 | cy_writel(&((struct RUNTIME_9060 *) | ||
5023 | (cy_pci_addr0))->loc_addr_base, | ||
5024 | WIN_RAM); | ||
5025 | } else { | 4871 | } else { |
5026 | printk("Cyclades-Z/PCI: New Cyclades-Z board. " | 4872 | dev_info(&pdev->dev, "Cyclades-Z/PCI: New " |
5027 | "FPGA not loaded\n"); | 4873 | "Cyclades-Z board. FPGA not loaded\n"); |
5028 | } | 4874 | } |
5029 | #endif | 4875 | #endif |
5030 | /* The following clears the firmware id word. This | 4876 | /* The following clears the firmware id word. This |
5031 | ensures that the driver will not attempt to talk to | 4877 | ensures that the driver will not attempt to talk to |
5032 | the board until it has been properly initialized. | 4878 | the board until it has been properly initialized. |
5033 | */ | 4879 | */ |
5034 | PAUSE; | ||
5035 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) | 4880 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) |
5036 | cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); | 4881 | cy_writel(addr2 + ID_ADDRESS, 0L); |
5037 | 4882 | ||
5038 | /* This must be a Cyclades-8Zo/PCI. The extendable | 4883 | /* This must be a Cyclades-8Zo/PCI. The extendable |
5039 | version will have a different device_id and will | 4884 | version will have a different device_id and will |
5040 | be allocated its maximum number of ports. */ | 4885 | be allocated its maximum number of ports. */ |
5041 | cy_pci_nchan = 8; | 4886 | nchan = 8; |
5042 | |||
5043 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
5044 | printk("Cyclades-8Zo/PCI found at 0x%lx but" | ||
5045 | "no channels are available.\nChange " | ||
5046 | "NR_PORTS in cyclades.c and recompile " | ||
5047 | "kernel.\n", (ulong)cy_pci_phys2); | ||
5048 | return i; | ||
5049 | } | ||
5050 | |||
5051 | /* fill the next cy_card structure available */ | ||
5052 | for (j = 0; j < NR_CARDS; j++) { | ||
5053 | if (cy_card[j].base_addr == 0) | ||
5054 | break; | ||
5055 | } | ||
5056 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
5057 | printk("Cyclades-8Zo/PCI found at 0x%lx but" | ||
5058 | "no more cards can be used.\nChange " | ||
5059 | "NR_CARDS in cyclades.c and recompile " | ||
5060 | "kernel.\n", (ulong)cy_pci_phys2); | ||
5061 | return i; | ||
5062 | } | ||
5063 | #ifdef CONFIG_CYZ_INTR | ||
5064 | /* allocate IRQ only if board has an IRQ */ | ||
5065 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | ||
5066 | if (request_irq(cy_pci_irq, cyz_interrupt, | ||
5067 | IRQF_SHARED, "Cyclades-Z", | ||
5068 | &cy_card[j])) { | ||
5069 | printk("Cyclom-8Zo/PCI found at 0x%lx " | ||
5070 | "but could not allocate " | ||
5071 | "IRQ%d.\n", (ulong)cy_pci_phys2, | ||
5072 | cy_pci_irq); | ||
5073 | return i; | ||
5074 | } | ||
5075 | } | ||
5076 | #endif /* CONFIG_CYZ_INTR */ | ||
5077 | |||
5078 | /* set cy_card */ | ||
5079 | cy_card[j].base_phys = cy_pci_phys2; | ||
5080 | cy_card[j].ctl_phys = cy_pci_phys0; | ||
5081 | cy_card[j].base_addr = cy_pci_addr2; | ||
5082 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
5083 | cy_card[j].irq = (int)cy_pci_irq; | ||
5084 | cy_card[j].bus_index = 1; | ||
5085 | cy_card[j].first_line = cy_next_channel; | ||
5086 | cy_card[j].num_chips = -1; | ||
5087 | cy_card[j].pdev = pdev; | ||
5088 | |||
5089 | /* print message */ | ||
5090 | #ifdef CONFIG_CYZ_INTR | ||
5091 | /* don't report IRQ if board is no IRQ */ | ||
5092 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) | ||
5093 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, " | ||
5094 | "IRQ%d, ", j + 1, (ulong)cy_pci_phys2, | ||
5095 | (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1), | ||
5096 | (int)cy_pci_irq); | ||
5097 | else | ||
5098 | #endif /* CONFIG_CYZ_INTR */ | ||
5099 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ", | ||
5100 | j + 1, (ulong)cy_pci_phys2, | ||
5101 | (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1)); | ||
5102 | |||
5103 | printk("%d channels starting from port %d.\n", | ||
5104 | cy_pci_nchan, cy_next_channel); | ||
5105 | cy_next_channel += cy_pci_nchan; | ||
5106 | } | 4887 | } |
5107 | } | 4888 | } |
5108 | 4889 | ||
5109 | for (; ZeIndex != 0 && i < NR_CARDS; i++) { | 4890 | if ((cy_next_channel + nchan) > NR_PORTS) { |
5110 | cy_pci_phys0 = Ze_phys0[0]; | 4891 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " |
5111 | cy_pci_phys2 = Ze_phys2[0]; | 4892 | "channels are available. Change NR_PORTS in " |
5112 | cy_pci_addr0 = Ze_addr0[0]; | 4893 | "cyclades.c and recompile kernel.\n"); |
5113 | cy_pci_addr2 = Ze_addr2[0]; | 4894 | goto err_unmap; |
5114 | cy_pci_irq = Ze_irq[0]; | 4895 | } |
5115 | pdev = Ze_pdev[0]; | 4896 | /* fill the next cy_card structure available */ |
5116 | for (j = 0; j < ZeIndex - 1; j++) { | 4897 | for (card_no = 0; card_no < NR_CARDS; card_no++) { |
5117 | Ze_phys0[j] = Ze_phys0[j + 1]; | 4898 | if (cy_card[card_no].base_addr == NULL) |
5118 | Ze_phys2[j] = Ze_phys2[j + 1]; | 4899 | break; |
5119 | Ze_addr0[j] = Ze_addr0[j + 1]; | 4900 | } |
5120 | Ze_addr2[j] = Ze_addr2[j + 1]; | 4901 | if (card_no == NR_CARDS) { /* no more cy_cards available */ |
5121 | Ze_irq[j] = Ze_irq[j + 1]; | 4902 | dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no " |
5122 | Ze_pdev[j] = Ze_pdev[j + 1]; | 4903 | "more cards can be used. Change NR_CARDS in " |
5123 | } | 4904 | "cyclades.c and recompile kernel.\n"); |
5124 | ZeIndex--; | 4905 | goto err_unmap; |
5125 | mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | 4906 | } |
5126 | cy_pci_addr0)->mail_box_0); | ||
5127 | #ifdef CY_PCI_DEBUG | ||
5128 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", | ||
5129 | (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); | ||
5130 | printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not " | ||
5131 | "loaded\n"); | ||
5132 | #endif | ||
5133 | PAUSE; | ||
5134 | /* This must be the new Cyclades-Ze/PCI. */ | ||
5135 | cy_pci_nchan = ZE_V1_NPORTS; | ||
5136 | |||
5137 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { | ||
5138 | printk("Cyclades-Ze/PCI found at 0x%lx but no channels " | ||
5139 | "are available.\nChange NR_PORTS in cyclades.c " | ||
5140 | "and recompile kernel.\n", | ||
5141 | (ulong) cy_pci_phys2); | ||
5142 | return i; | ||
5143 | } | ||
5144 | 4907 | ||
5145 | /* fill the next cy_card structure available */ | 4908 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
5146 | for (j = 0; j < NR_CARDS; j++) { | 4909 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
5147 | if (cy_card[j].base_addr == 0) | 4910 | /* allocate IRQ */ |
5148 | break; | 4911 | retval = request_irq(irq, cyy_interrupt, |
5149 | } | 4912 | IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); |
5150 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4913 | if (retval) { |
5151 | printk("Cyclades-Ze/PCI found at 0x%lx but no more " | 4914 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
5152 | "cards can be used.\nChange NR_CARDS in " | 4915 | goto err_unmap; |
5153 | "cyclades.c and recompile kernel.\n", | ||
5154 | (ulong) cy_pci_phys2); | ||
5155 | return i; | ||
5156 | } | 4916 | } |
4917 | cy_card[card_no].num_chips = nchan / 4; | ||
4918 | } else { | ||
5157 | #ifdef CONFIG_CYZ_INTR | 4919 | #ifdef CONFIG_CYZ_INTR |
5158 | /* allocate IRQ only if board has an IRQ */ | 4920 | /* allocate IRQ only if board has an IRQ */ |
5159 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | 4921 | if (irq != 0 && irq != 255) { |
5160 | if (request_irq(cy_pci_irq, cyz_interrupt, | 4922 | retval = request_irq(irq, cyz_interrupt, |
5161 | IRQF_SHARED, "Cyclades-Z", | 4923 | IRQF_SHARED, "Cyclades-Z", |
5162 | &cy_card[j])) { | 4924 | &cy_card[card_no]); |
5163 | printk("Cyclom-Ze/PCI found at 0x%lx ", | 4925 | if (retval) { |
5164 | (ulong) cy_pci_phys2); | 4926 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
5165 | printk("but could not allocate IRQ%d.\n", | 4927 | goto err_unmap; |
5166 | cy_pci_irq); | ||
5167 | return i; | ||
5168 | } | 4928 | } |
5169 | } | 4929 | } |
5170 | #endif /* CONFIG_CYZ_INTR */ | 4930 | #endif /* CONFIG_CYZ_INTR */ |
4931 | cy_card[card_no].num_chips = -1; | ||
4932 | } | ||
5171 | 4933 | ||
5172 | /* set cy_card */ | 4934 | /* set cy_card */ |
5173 | cy_card[j].base_phys = cy_pci_phys2; | 4935 | cy_card[card_no].base_addr = addr2; |
5174 | cy_card[j].ctl_phys = cy_pci_phys0; | 4936 | cy_card[card_no].ctl_addr = addr0; |
5175 | cy_card[j].base_addr = cy_pci_addr2; | 4937 | cy_card[card_no].irq = irq; |
5176 | cy_card[j].ctl_addr = cy_pci_addr0; | 4938 | cy_card[card_no].bus_index = 1; |
5177 | cy_card[j].irq = (int)cy_pci_irq; | 4939 | cy_card[card_no].first_line = cy_next_channel; |
5178 | cy_card[j].bus_index = 1; | 4940 | retval = cy_init_card(&cy_card[card_no]); |
5179 | cy_card[j].first_line = cy_next_channel; | 4941 | if (retval) |
5180 | cy_card[j].num_chips = -1; | 4942 | goto err_null; |
5181 | cy_card[j].pdev = pdev; | ||
5182 | 4943 | ||
5183 | /* print message */ | 4944 | pci_set_drvdata(pdev, &cy_card[card_no]); |
5184 | #ifdef CONFIG_CYZ_INTR | ||
5185 | /* don't report IRQ if board is no IRQ */ | ||
5186 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) | ||
5187 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | ||
5188 | j + 1, (ulong) cy_pci_phys2, | ||
5189 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1), | ||
5190 | (int)cy_pci_irq); | ||
5191 | else | ||
5192 | #endif /* CONFIG_CYZ_INTR */ | ||
5193 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ", | ||
5194 | j + 1, (ulong) cy_pci_phys2, | ||
5195 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1)); | ||
5196 | 4945 | ||
5197 | printk("%d channels starting from port %d.\n", | 4946 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
5198 | cy_pci_nchan, cy_next_channel); | 4947 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
5199 | cy_next_channel += cy_pci_nchan; | 4948 | /* enable interrupts in the PCI interface */ |
5200 | } | 4949 | plx_ver = readb(addr2 + CyPLX_VER) & 0x0f; |
5201 | if (ZeIndex != 0) { | 4950 | switch (plx_ver) { |
5202 | printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be " | 4951 | case PLX_9050: |
5203 | "used.\nChange NR_CARDS in cyclades.c and recompile " | 4952 | |
5204 | "kernel.\n", (unsigned int)Ze_phys2[0]); | 4953 | cy_writeb(addr0 + 0x4c, 0x43); |
4954 | break; | ||
4955 | |||
4956 | case PLX_9060: | ||
4957 | case PLX_9080: | ||
4958 | default: /* Old boards, use PLX_9060 */ | ||
4959 | |||
4960 | plx_init(addr0, 0x6c); | ||
4961 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4962 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4963 | re-write it to the PCI config. registers. | ||
4964 | This will remain here until we find a permanent | ||
4965 | fix. */ | ||
4966 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq); | ||
4967 | |||
4968 | cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900); | ||
4969 | break; | ||
4970 | } | ||
5205 | } | 4971 | } |
5206 | return i; | 4972 | |
5207 | #else | 4973 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " |
4974 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); | ||
4975 | for (i = cy_next_channel; i < cy_next_channel + nchan; i++) | ||
4976 | tty_register_device(cy_serial_driver, i, &pdev->dev); | ||
4977 | cy_next_channel += nchan; | ||
4978 | |||
5208 | return 0; | 4979 | return 0; |
5209 | #endif /* ifdef CONFIG_PCI */ | 4980 | err_null: |
5210 | } /* cy_detect_pci */ | 4981 | cy_card[card_no].base_addr = NULL; |
4982 | free_irq(irq, &cy_card[card_no]); | ||
4983 | err_unmap: | ||
4984 | pci_iounmap(pdev, addr0); | ||
4985 | if (addr2) | ||
4986 | pci_iounmap(pdev, addr2); | ||
4987 | err_reg: | ||
4988 | pci_release_regions(pdev); | ||
4989 | err_dis: | ||
4990 | pci_disable_device(pdev); | ||
4991 | err: | ||
4992 | return retval; | ||
4993 | } | ||
5211 | 4994 | ||
5212 | /* | 4995 | static void __devexit cy_pci_remove(struct pci_dev *pdev) |
5213 | * This routine prints out the appropriate serial driver version number | ||
5214 | * and identifies which options were configured into this driver. | ||
5215 | */ | ||
5216 | static inline void show_version(void) | ||
5217 | { | 4996 | { |
5218 | printk("Cyclades driver " CY_VERSION "\n"); | 4997 | struct cyclades_card *cinfo = pci_get_drvdata(pdev); |
5219 | printk(" built %s %s\n", __DATE__, __TIME__); | 4998 | unsigned int i; |
5220 | } /* show_version */ | 4999 | |
5000 | /* non-Z with old PLX */ | ||
5001 | if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) == | ||
5002 | PLX_9050) | ||
5003 | cy_writeb(cinfo->ctl_addr + 0x4c, 0); | ||
5004 | else | ||
5005 | #ifndef CONFIG_CYZ_INTR | ||
5006 | if (!IS_CYC_Z(*cinfo)) | ||
5007 | #endif | ||
5008 | cy_writew(cinfo->ctl_addr + 0x68, | ||
5009 | readw(cinfo->ctl_addr + 0x68) & ~0x0900); | ||
5010 | |||
5011 | pci_iounmap(pdev, cinfo->base_addr); | ||
5012 | if (cinfo->ctl_addr) | ||
5013 | pci_iounmap(pdev, cinfo->ctl_addr); | ||
5014 | if (cinfo->irq | ||
5015 | #ifndef CONFIG_CYZ_INTR | ||
5016 | && !IS_CYC_Z(*cinfo) | ||
5017 | #endif /* CONFIG_CYZ_INTR */ | ||
5018 | ) | ||
5019 | free_irq(cinfo->irq, cinfo); | ||
5020 | pci_release_regions(pdev); | ||
5021 | |||
5022 | cinfo->base_addr = NULL; | ||
5023 | for (i = cinfo->first_line; i < cinfo->first_line + | ||
5024 | cinfo->nports; i++) | ||
5025 | tty_unregister_device(cy_serial_driver, i); | ||
5026 | cinfo->nports = 0; | ||
5027 | kfree(cinfo->ports); | ||
5028 | } | ||
5029 | |||
5030 | static struct pci_driver cy_pci_driver = { | ||
5031 | .name = "cyclades", | ||
5032 | .id_table = cy_pci_dev_id, | ||
5033 | .probe = cy_pci_probe, | ||
5034 | .remove = __devexit_p(cy_pci_remove) | ||
5035 | }; | ||
5036 | #endif | ||
5221 | 5037 | ||
5222 | static int | 5038 | static int |
5223 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, | 5039 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, |
5224 | int *eof, void *data) | 5040 | int *eof, void *data) |
5225 | { | 5041 | { |
5226 | struct cyclades_port *info; | 5042 | struct cyclades_port *info; |
5227 | int i; | 5043 | unsigned int i, j; |
5228 | int len = 0; | 5044 | int len = 0; |
5229 | off_t begin = 0; | 5045 | off_t begin = 0; |
5230 | off_t pos = 0; | 5046 | off_t pos = 0; |
@@ -5238,33 +5054,34 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, | |||
5238 | len += size; | 5054 | len += size; |
5239 | 5055 | ||
5240 | /* Output one line for each known port */ | 5056 | /* Output one line for each known port */ |
5241 | for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { | 5057 | for (i = 0; i < NR_CARDS; i++) |
5242 | info = &cy_port[i]; | 5058 | for (j = 0; j < cy_card[i].nports; j++) { |
5243 | 5059 | info = &cy_card[i].ports[j]; | |
5244 | if (info->count) | 5060 | |
5245 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | 5061 | if (info->count) |
5246 | "%8lu %9lu %6ld\n", info->line, | 5062 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu " |
5247 | (cur_jifs - info->idle_stats.in_use) / HZ, | 5063 | "%10lu %8lu %9lu %6ld\n", info->line, |
5248 | info->idle_stats.xmit_bytes, | 5064 | (cur_jifs - info->idle_stats.in_use) / |
5249 | (cur_jifs - info->idle_stats.xmit_idle) / HZ, | 5065 | HZ, info->idle_stats.xmit_bytes, |
5250 | info->idle_stats.recv_bytes, | 5066 | (cur_jifs - info->idle_stats.xmit_idle)/ |
5251 | (cur_jifs - info->idle_stats.recv_idle) / HZ, | 5067 | HZ, info->idle_stats.recv_bytes, |
5252 | info->idle_stats.overruns, | 5068 | (cur_jifs - info->idle_stats.recv_idle)/ |
5253 | (long)info->tty->ldisc.num); | 5069 | HZ, info->idle_stats.overruns, |
5254 | else | 5070 | (long)info->tty->ldisc.num); |
5255 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | 5071 | else |
5256 | "%8lu %9lu %6ld\n", | 5072 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu " |
5257 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); | 5073 | "%10lu %8lu %9lu %6ld\n", |
5258 | len += size; | 5074 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); |
5259 | pos = begin + len; | 5075 | len += size; |
5260 | 5076 | pos = begin + len; | |
5261 | if (pos < offset) { | 5077 | |
5262 | len = 0; | 5078 | if (pos < offset) { |
5263 | begin = pos; | 5079 | len = 0; |
5080 | begin = pos; | ||
5081 | } | ||
5082 | if (pos > offset + length) | ||
5083 | goto done; | ||
5264 | } | 5084 | } |
5265 | if (pos > offset + length) | ||
5266 | goto done; | ||
5267 | } | ||
5268 | *eof = 1; | 5085 | *eof = 1; |
5269 | done: | 5086 | done: |
5270 | *start = buf + (offset - begin); /* Start of wanted data */ | 5087 | *start = buf + (offset - begin); /* Start of wanted data */ |
@@ -5319,18 +5136,15 @@ static const struct tty_operations cy_ops = { | |||
5319 | 5136 | ||
5320 | static int __init cy_init(void) | 5137 | static int __init cy_init(void) |
5321 | { | 5138 | { |
5322 | struct cyclades_port *info; | 5139 | unsigned int nboards; |
5323 | struct cyclades_card *cinfo; | 5140 | int retval = -ENOMEM; |
5324 | int number_z_boards = 0; | ||
5325 | int board, port, i, index; | ||
5326 | unsigned long mailbox; | ||
5327 | unsigned short chip_number; | ||
5328 | int nports; | ||
5329 | 5141 | ||
5330 | cy_serial_driver = alloc_tty_driver(NR_PORTS); | 5142 | cy_serial_driver = alloc_tty_driver(NR_PORTS); |
5331 | if (!cy_serial_driver) | 5143 | if (!cy_serial_driver) |
5332 | return -ENOMEM; | 5144 | goto err; |
5333 | show_version(); | 5145 | |
5146 | printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n", | ||
5147 | __DATE__, __TIME__); | ||
5334 | 5148 | ||
5335 | /* Initialize the tty_driver structure */ | 5149 | /* Initialize the tty_driver structure */ |
5336 | 5150 | ||
@@ -5344,15 +5158,13 @@ static int __init cy_init(void) | |||
5344 | cy_serial_driver->init_termios = tty_std_termios; | 5158 | cy_serial_driver->init_termios = tty_std_termios; |
5345 | cy_serial_driver->init_termios.c_cflag = | 5159 | cy_serial_driver->init_termios.c_cflag = |
5346 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 5160 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
5347 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; | 5161 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
5348 | tty_set_operations(cy_serial_driver, &cy_ops); | 5162 | tty_set_operations(cy_serial_driver, &cy_ops); |
5349 | 5163 | ||
5350 | if (tty_register_driver(cy_serial_driver)) | 5164 | retval = tty_register_driver(cy_serial_driver); |
5351 | panic("Couldn't register Cyclades serial driver\n"); | 5165 | if (retval) { |
5352 | 5166 | printk(KERN_ERR "Couldn't register Cyclades serial driver\n"); | |
5353 | for (i = 0; i < NR_CARDS; i++) { | 5167 | goto err_frtty; |
5354 | /* base_addr=0 indicates board not found */ | ||
5355 | cy_card[i].base_addr = NULL; | ||
5356 | } | 5168 | } |
5357 | 5169 | ||
5358 | /* the code below is responsible to find the boards. Each different | 5170 | /* the code below is responsible to find the boards. Each different |
@@ -5363,223 +5175,68 @@ static int __init cy_init(void) | |||
5363 | the cy_next_channel. */ | 5175 | the cy_next_channel. */ |
5364 | 5176 | ||
5365 | /* look for isa boards */ | 5177 | /* look for isa boards */ |
5366 | cy_isa_nboard = cy_detect_isa(); | 5178 | nboards = cy_detect_isa(); |
5367 | 5179 | ||
5180 | #ifdef CONFIG_PCI | ||
5368 | /* look for pci boards */ | 5181 | /* look for pci boards */ |
5369 | cy_pci_nboard = cy_detect_pci(); | 5182 | retval = pci_register_driver(&cy_pci_driver); |
5370 | 5183 | if (retval && !nboards) | |
5371 | cy_nboard = cy_isa_nboard + cy_pci_nboard; | 5184 | goto err_unr; |
5372 | |||
5373 | /* invalidate remaining cy_card structures */ | ||
5374 | for (i = 0; i < NR_CARDS; i++) { | ||
5375 | if (cy_card[i].base_addr == 0) { | ||
5376 | cy_card[i].first_line = -1; | ||
5377 | cy_card[i].ctl_addr = NULL; | ||
5378 | cy_card[i].irq = 0; | ||
5379 | cy_card[i].bus_index = 0; | ||
5380 | cy_card[i].first_line = 0; | ||
5381 | cy_card[i].num_chips = 0; | ||
5382 | } | ||
5383 | } | ||
5384 | /* invalidate remaining cy_port structures */ | ||
5385 | for (i = cy_next_channel; i < NR_PORTS; i++) { | ||
5386 | cy_port[i].line = -1; | ||
5387 | cy_port[i].magic = -1; | ||
5388 | } | ||
5389 | |||
5390 | /* initialize per-port data structures for each valid board found */ | ||
5391 | for (board = 0; board < cy_nboard; board++) { | ||
5392 | cinfo = &cy_card[board]; | ||
5393 | if (cinfo->num_chips == -1) { /* Cyclades-Z */ | ||
5394 | number_z_boards++; | ||
5395 | mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
5396 | cy_card[board].ctl_addr)-> | ||
5397 | mail_box_0); | ||
5398 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; | ||
5399 | cinfo->intr_enabled = 0; | ||
5400 | cinfo->nports = 0; /* Will be correctly set later, after | ||
5401 | Z FW is loaded */ | ||
5402 | spin_lock_init(&cinfo->card_lock); | ||
5403 | for (port = cinfo->first_line; | ||
5404 | port < cinfo->first_line + nports; port++) { | ||
5405 | info = &cy_port[port]; | ||
5406 | info->magic = CYCLADES_MAGIC; | ||
5407 | info->type = PORT_STARTECH; | ||
5408 | info->card = board; | ||
5409 | info->line = port; | ||
5410 | info->chip_rev = 0; | ||
5411 | info->flags = STD_COM_FLAGS; | ||
5412 | info->tty = NULL; | ||
5413 | if (mailbox == ZO_V1) | ||
5414 | info->xmit_fifo_size = CYZ_FIFO_SIZE; | ||
5415 | else | ||
5416 | info->xmit_fifo_size = | ||
5417 | 4 * CYZ_FIFO_SIZE; | ||
5418 | info->cor1 = 0; | ||
5419 | info->cor2 = 0; | ||
5420 | info->cor3 = 0; | ||
5421 | info->cor4 = 0; | ||
5422 | info->cor5 = 0; | ||
5423 | info->tbpr = 0; | ||
5424 | info->tco = 0; | ||
5425 | info->rbpr = 0; | ||
5426 | info->rco = 0; | ||
5427 | info->custom_divisor = 0; | ||
5428 | info->close_delay = 5 * HZ / 10; | ||
5429 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
5430 | info->icount.cts = info->icount.dsr = | ||
5431 | info->icount.rng = info->icount.dcd = 0; | ||
5432 | info->icount.rx = info->icount.tx = 0; | ||
5433 | info->icount.frame = info->icount.parity = 0; | ||
5434 | info->icount.overrun = info->icount.brk = 0; | ||
5435 | info->x_char = 0; | ||
5436 | info->event = 0; | ||
5437 | info->count = 0; | ||
5438 | info->blocked_open = 0; | ||
5439 | info->default_threshold = 0; | ||
5440 | info->default_timeout = 0; | ||
5441 | INIT_WORK(&info->tqueue, do_softint); | ||
5442 | init_waitqueue_head(&info->open_wait); | ||
5443 | init_waitqueue_head(&info->close_wait); | ||
5444 | init_waitqueue_head(&info->shutdown_wait); | ||
5445 | init_waitqueue_head(&info->delta_msr_wait); | ||
5446 | /* info->session */ | ||
5447 | /* info->pgrp */ | ||
5448 | info->read_status_mask = 0; | ||
5449 | /* info->timeout */ | ||
5450 | /* Bentson's vars */ | ||
5451 | info->jiffies[0] = 0; | ||
5452 | info->jiffies[1] = 0; | ||
5453 | info->jiffies[2] = 0; | ||
5454 | info->rflush_count = 0; | ||
5455 | #ifdef CONFIG_CYZ_INTR | ||
5456 | init_timer(&cyz_rx_full_timer[port]); | ||
5457 | cyz_rx_full_timer[port].function = NULL; | ||
5458 | #endif | 5185 | #endif |
5459 | } | ||
5460 | continue; | ||
5461 | } else { /* Cyclom-Y of some kind */ | ||
5462 | index = cinfo->bus_index; | ||
5463 | spin_lock_init(&cinfo->card_lock); | ||
5464 | cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; | ||
5465 | for (port = cinfo->first_line; | ||
5466 | port < cinfo->first_line + cinfo->nports; port++) { | ||
5467 | info = &cy_port[port]; | ||
5468 | info->magic = CYCLADES_MAGIC; | ||
5469 | info->type = PORT_CIRRUS; | ||
5470 | info->card = board; | ||
5471 | info->line = port; | ||
5472 | info->flags = STD_COM_FLAGS; | ||
5473 | info->tty = NULL; | ||
5474 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; | ||
5475 | info->cor1 = | ||
5476 | CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; | ||
5477 | info->cor2 = CyETC; | ||
5478 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | ||
5479 | info->cor4 = 0; | ||
5480 | info->cor5 = 0; | ||
5481 | info->custom_divisor = 0; | ||
5482 | info->close_delay = 5 * HZ / 10; | ||
5483 | info->closing_wait = CLOSING_WAIT_DELAY; | ||
5484 | info->icount.cts = info->icount.dsr = | ||
5485 | info->icount.rng = info->icount.dcd = 0; | ||
5486 | info->icount.rx = info->icount.tx = 0; | ||
5487 | info->icount.frame = info->icount.parity = 0; | ||
5488 | info->icount.overrun = info->icount.brk = 0; | ||
5489 | chip_number = (port - cinfo->first_line) / 4; | ||
5490 | if ((info->chip_rev = | ||
5491 | cy_readb(cinfo->base_addr + | ||
5492 | (cy_chip_offset[chip_number] << | ||
5493 | index) + (CyGFRCR << index))) >= | ||
5494 | CD1400_REV_J) { | ||
5495 | /* It is a CD1400 rev. J or later */ | ||
5496 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | ||
5497 | info->tco = baud_co_60[13]; /* Tx CO */ | ||
5498 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ | ||
5499 | info->rco = baud_co_60[13]; /* Rx CO */ | ||
5500 | info->rflow = 0; | ||
5501 | info->rtsdtr_inv = 1; | ||
5502 | } else { | ||
5503 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ | ||
5504 | info->tco = baud_co_25[13]; /* Tx CO */ | ||
5505 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ | ||
5506 | info->rco = baud_co_25[13]; /* Rx CO */ | ||
5507 | info->rflow = 0; | ||
5508 | info->rtsdtr_inv = 0; | ||
5509 | } | ||
5510 | info->x_char = 0; | ||
5511 | info->event = 0; | ||
5512 | info->count = 0; | ||
5513 | info->blocked_open = 0; | ||
5514 | info->default_threshold = 0; | ||
5515 | info->default_timeout = 0; | ||
5516 | INIT_WORK(&info->tqueue, do_softint); | ||
5517 | init_waitqueue_head(&info->open_wait); | ||
5518 | init_waitqueue_head(&info->close_wait); | ||
5519 | init_waitqueue_head(&info->shutdown_wait); | ||
5520 | init_waitqueue_head(&info->delta_msr_wait); | ||
5521 | /* info->session */ | ||
5522 | /* info->pgrp */ | ||
5523 | info->read_status_mask = | ||
5524 | CyTIMEOUT | CySPECHAR | CyBREAK | ||
5525 | | CyPARITY | CyFRAME | CyOVERRUN; | ||
5526 | /* info->timeout */ | ||
5527 | } | ||
5528 | } | ||
5529 | } | ||
5530 | |||
5531 | #ifndef CONFIG_CYZ_INTR | ||
5532 | if (number_z_boards && !cyz_timeron) { | ||
5533 | cyz_timeron++; | ||
5534 | cyz_timerlist.expires = jiffies + 1; | ||
5535 | add_timer(&cyz_timerlist); | ||
5536 | #ifdef CY_PCI_DEBUG | ||
5537 | printk("Cyclades-Z polling initialized\n"); | ||
5538 | #endif | ||
5539 | } | ||
5540 | #endif /* CONFIG_CYZ_INTR */ | ||
5541 | 5186 | ||
5542 | return 0; | 5187 | return 0; |
5543 | 5188 | err_unr: | |
5189 | tty_unregister_driver(cy_serial_driver); | ||
5190 | err_frtty: | ||
5191 | put_tty_driver(cy_serial_driver); | ||
5192 | err: | ||
5193 | return retval; | ||
5544 | } /* cy_init */ | 5194 | } /* cy_init */ |
5545 | 5195 | ||
5546 | static void __exit cy_cleanup_module(void) | 5196 | static void __exit cy_cleanup_module(void) |
5547 | { | 5197 | { |
5198 | struct cyclades_card *card; | ||
5548 | int i, e1; | 5199 | int i, e1; |
5549 | 5200 | ||
5550 | #ifndef CONFIG_CYZ_INTR | 5201 | #ifndef CONFIG_CYZ_INTR |
5551 | if (cyz_timeron){ | 5202 | del_timer_sync(&cyz_timerlist); |
5552 | cyz_timeron = 0; | ||
5553 | del_timer(&cyz_timerlist); | ||
5554 | } | ||
5555 | #endif /* CONFIG_CYZ_INTR */ | 5203 | #endif /* CONFIG_CYZ_INTR */ |
5556 | 5204 | ||
5557 | if ((e1 = tty_unregister_driver(cy_serial_driver))) | 5205 | if ((e1 = tty_unregister_driver(cy_serial_driver))) |
5558 | printk("cyc: failed to unregister Cyclades serial driver(%d)\n", | 5206 | printk(KERN_ERR "failed to unregister Cyclades serial " |
5559 | e1); | 5207 | "driver(%d)\n", e1); |
5560 | 5208 | ||
5561 | put_tty_driver(cy_serial_driver); | 5209 | #ifdef CONFIG_PCI |
5210 | pci_unregister_driver(&cy_pci_driver); | ||
5211 | #endif | ||
5562 | 5212 | ||
5563 | for (i = 0; i < NR_CARDS; i++) { | 5213 | for (i = 0; i < NR_CARDS; i++) { |
5564 | if (cy_card[i].base_addr) { | 5214 | card = &cy_card[i]; |
5565 | iounmap(cy_card[i].base_addr); | 5215 | if (card->base_addr) { |
5566 | if (cy_card[i].ctl_addr) | 5216 | /* clear interrupt */ |
5567 | iounmap(cy_card[i].ctl_addr); | 5217 | cy_writeb(card->base_addr + Cy_ClrIntr, 0); |
5568 | if (cy_card[i].irq | 5218 | iounmap(card->base_addr); |
5219 | if (card->ctl_addr) | ||
5220 | iounmap(card->ctl_addr); | ||
5221 | if (card->irq | ||
5569 | #ifndef CONFIG_CYZ_INTR | 5222 | #ifndef CONFIG_CYZ_INTR |
5570 | && cy_card[i].num_chips != -1 /* not a Z card */ | 5223 | && !IS_CYC_Z(*card) |
5571 | #endif /* CONFIG_CYZ_INTR */ | 5224 | #endif /* CONFIG_CYZ_INTR */ |
5572 | ) | 5225 | ) |
5573 | free_irq(cy_card[i].irq, &cy_card[i]); | 5226 | free_irq(card->irq, card); |
5574 | #ifdef CONFIG_PCI | 5227 | for (e1 = card->first_line; |
5575 | if (cy_card[i].pdev) | 5228 | e1 < card->first_line + |
5576 | pci_release_regions(cy_card[i].pdev); | 5229 | card->nports; e1++) |
5577 | #endif | 5230 | tty_unregister_device(cy_serial_driver, e1); |
5231 | kfree(card->ports); | ||
5578 | } | 5232 | } |
5579 | } | 5233 | } |
5234 | |||
5235 | put_tty_driver(cy_serial_driver); | ||
5580 | } /* cy_cleanup_module */ | 5236 | } /* cy_cleanup_module */ |
5581 | 5237 | ||
5582 | module_init(cy_init); | 5238 | module_init(cy_init); |
5583 | module_exit(cy_cleanup_module); | 5239 | module_exit(cy_cleanup_module); |
5584 | 5240 | ||
5585 | MODULE_LICENSE("GPL"); | 5241 | MODULE_LICENSE("GPL"); |
5242 | MODULE_VERSION(CY_VERSION); | ||
diff --git a/drivers/char/digi.h b/drivers/char/digi.h deleted file mode 100644 index 19df0e879b1b..000000000000 --- a/drivers/char/digi.h +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* Definitions for DigiBoard ditty(1) command. */ | ||
2 | |||
3 | #if !defined(TIOCMODG) | ||
4 | #define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */ | ||
5 | #define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */ | ||
6 | #endif | ||
7 | |||
8 | #if !defined(TIOCMSET) | ||
9 | #define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */ | ||
10 | #define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */ | ||
11 | #endif | ||
12 | |||
13 | #if !defined(TIOCMBIC) | ||
14 | #define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */ | ||
15 | #define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */ | ||
16 | #endif | ||
17 | |||
18 | #if !defined(TIOCSDTR) | ||
19 | #define TIOCSDTR (('e'<<8) | 0) /* set DTR */ | ||
20 | #define TIOCCDTR (('e'<<8) | 1) /* clear DTR */ | ||
21 | #endif | ||
22 | |||
23 | /************************************************************************ | ||
24 | * Ioctl command arguments for DIGI parameters. | ||
25 | ************************************************************************/ | ||
26 | #define DIGI_GETA (('e'<<8) | 94) /* Read params */ | ||
27 | |||
28 | #define DIGI_SETA (('e'<<8) | 95) /* Set params */ | ||
29 | #define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */ | ||
30 | #define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */ | ||
31 | |||
32 | #define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */ | ||
33 | /* control characters */ | ||
34 | #define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */ | ||
35 | /* control characters */ | ||
36 | #define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */ | ||
37 | /* flow control chars */ | ||
38 | #define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */ | ||
39 | /* flow control chars */ | ||
40 | |||
41 | struct digiflow_struct { | ||
42 | unsigned char startc; /* flow cntl start char */ | ||
43 | unsigned char stopc; /* flow cntl stop char */ | ||
44 | }; | ||
45 | |||
46 | typedef struct digiflow_struct digiflow_t; | ||
47 | |||
48 | |||
49 | /************************************************************************ | ||
50 | * Values for digi_flags | ||
51 | ************************************************************************/ | ||
52 | #define DIGI_IXON 0x0001 /* Handle IXON in the FEP */ | ||
53 | #define DIGI_FAST 0x0002 /* Fast baud rates */ | ||
54 | #define RTSPACE 0x0004 /* RTS input flow control */ | ||
55 | #define CTSPACE 0x0008 /* CTS output flow control */ | ||
56 | #define DSRPACE 0x0010 /* DSR output flow control */ | ||
57 | #define DCDPACE 0x0020 /* DCD output flow control */ | ||
58 | #define DTRPACE 0x0040 /* DTR input flow control */ | ||
59 | #define DIGI_FORCEDCD 0x0100 /* Force carrier */ | ||
60 | #define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */ | ||
61 | #define DIGI_AIXON 0x0400 /* Aux flow control in fep */ | ||
62 | |||
63 | |||
64 | /************************************************************************ | ||
65 | * Structure used with ioctl commands for DIGI parameters. | ||
66 | ************************************************************************/ | ||
67 | struct digi_struct { | ||
68 | unsigned short digi_flags; /* Flags (see above) */ | ||
69 | }; | ||
70 | |||
71 | typedef struct digi_struct digi_t; | ||
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index 3d7efc26aad6..334ad5bbe6b6 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c | |||
@@ -4,7 +4,6 @@ | |||
4 | */ | 4 | */ |
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/miscdevice.h> | 6 | #include <linux/miscdevice.h> |
7 | #include <linux/smp_lock.h> | ||
8 | #include <linux/delay.h> | 7 | #include <linux/delay.h> |
9 | #include <linux/proc_fs.h> | 8 | #include <linux/proc_fs.h> |
10 | #include <linux/capability.h> | 9 | #include <linux/capability.h> |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index db984e481d4c..9b8278e1f4f8 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <linux/fs.h> | 32 | #include <linux/fs.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/device.h> | 35 | #include <linux/device.h> |
37 | 36 | ||
38 | #include <asm/atarihw.h> | 37 | #include <asm/atarihw.h> |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index d8dbdb916232..abde6ddefe69 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -62,7 +62,6 @@ | |||
62 | #include <linux/init.h> /* for __init, module_{init,exit} */ | 62 | #include <linux/init.h> /* for __init, module_{init,exit} */ |
63 | #include <linux/poll.h> /* for POLLIN, etc. */ | 63 | #include <linux/poll.h> /* for POLLIN, etc. */ |
64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ | 64 | #include <linux/dtlk.h> /* local header file for DoubleTalk values */ |
65 | #include <linux/smp_lock.h> | ||
66 | 65 | ||
67 | #ifdef TRACING | 66 | #ifdef TRACING |
68 | #define TRACE_TEXT(str) printk(str); | 67 | #define TRACE_TEXT(str) printk(str); |
@@ -325,16 +324,22 @@ static int dtlk_release(struct inode *inode, struct file *file) | |||
325 | 324 | ||
326 | static int __init dtlk_init(void) | 325 | static int __init dtlk_init(void) |
327 | { | 326 | { |
327 | int err; | ||
328 | |||
328 | dtlk_port_lpc = 0; | 329 | dtlk_port_lpc = 0; |
329 | dtlk_port_tts = 0; | 330 | dtlk_port_tts = 0; |
330 | dtlk_busy = 0; | 331 | dtlk_busy = 0; |
331 | dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); | 332 | dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); |
332 | if (dtlk_major == 0) { | 333 | if (dtlk_major < 0) { |
333 | printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); | 334 | printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); |
334 | return 0; | 335 | return dtlk_major; |
336 | } | ||
337 | err = dtlk_dev_probe(); | ||
338 | if (err) { | ||
339 | unregister_chrdev(dtlk_major, "dtlk"); | ||
340 | return err; | ||
335 | } | 341 | } |
336 | if (dtlk_dev_probe() == 0) | 342 | printk(", MAJOR %d\n", dtlk_major); |
337 | printk(", MAJOR %d\n", dtlk_major); | ||
338 | 343 | ||
339 | init_waitqueue_head(&dtlk_process_list); | 344 | init_waitqueue_head(&dtlk_process_list); |
340 | 345 | ||
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c index 77f58ed6d59a..020011495d91 100644 --- a/drivers/char/ec3104_keyb.c +++ b/drivers/char/ec3104_keyb.c | |||
@@ -41,7 +41,6 @@ | |||
41 | #include <linux/miscdevice.h> | 41 | #include <linux/miscdevice.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/kbd_kern.h> | 43 | #include <linux/kbd_kern.h> |
44 | #include <linux/smp_lock.h> | ||
45 | #include <linux/bitops.h> | 44 | #include <linux/bitops.h> |
46 | 45 | ||
47 | #include <asm/keyboard.h> | 46 | #include <asm/keyboard.h> |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index de5be30484ad..c6c56fb8ba50 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -949,7 +949,7 @@ static int block_til_ready(struct tty_struct *tty, | |||
949 | 949 | ||
950 | } /* End forever while */ | 950 | } /* End forever while */ |
951 | 951 | ||
952 | current->state = TASK_RUNNING; | 952 | __set_current_state(TASK_RUNNING); |
953 | remove_wait_queue(&ch->open_wait, &wait); | 953 | remove_wait_queue(&ch->open_wait, &wait); |
954 | if (!tty_hung_up_p(filp)) | 954 | if (!tty_hung_up_p(filp)) |
955 | ch->count++; | 955 | ch->count++; |
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c index 23b25ada65ea..49f914e79216 100644 --- a/drivers/char/genrtc.c +++ b/drivers/char/genrtc.c | |||
@@ -207,7 +207,7 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf, | |||
207 | sizeof(unsigned long); | 207 | sizeof(unsigned long); |
208 | } | 208 | } |
209 | out: | 209 | out: |
210 | current->state = TASK_RUNNING; | 210 | __set_current_state(TASK_RUNNING); |
211 | remove_wait_queue(&gen_rtc_wait, &wait); | 211 | remove_wait_queue(&gen_rtc_wait, &wait); |
212 | 212 | ||
213 | return retval; | 213 | return retval; |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index ae76a9ffe89f..f0e7263dfcde 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -44,7 +44,6 @@ | |||
44 | #include <linux/fs.h> | 44 | #include <linux/fs.h> |
45 | #include <linux/mm.h> | 45 | #include <linux/mm.h> |
46 | #include <linux/reboot.h> | 46 | #include <linux/reboot.h> |
47 | #include <linux/smp_lock.h> | ||
48 | #include <linux/init.h> | 47 | #include <linux/init.h> |
49 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
50 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 0f9ed7b46a6d..322bc5f7d86b 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -111,7 +111,7 @@ static int last_hvc = -1; | |||
111 | * lock held. If successful, this function increments the kobject reference | 111 | * lock held. If successful, this function increments the kobject reference |
112 | * count against the target hvc_struct so it should be released when finished. | 112 | * count against the target hvc_struct so it should be released when finished. |
113 | */ | 113 | */ |
114 | struct hvc_struct *hvc_get_by_index(int index) | 114 | static struct hvc_struct *hvc_get_by_index(int index) |
115 | { | 115 | { |
116 | struct hvc_struct *hp; | 116 | struct hvc_struct *hp; |
117 | unsigned long flags; | 117 | unsigned long flags; |
@@ -150,7 +150,8 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] = | |||
150 | * hvc_console_setup() finds adapters. | 150 | * hvc_console_setup() finds adapters. |
151 | */ | 151 | */ |
152 | 152 | ||
153 | void hvc_console_print(struct console *co, const char *b, unsigned count) | 153 | static void hvc_console_print(struct console *co, const char *b, |
154 | unsigned count) | ||
154 | { | 155 | { |
155 | char c[N_OUTBUF] __ALIGNED__; | 156 | char c[N_OUTBUF] __ALIGNED__; |
156 | unsigned i = 0, n = 0; | 157 | unsigned i = 0, n = 0; |
@@ -208,7 +209,7 @@ static int __init hvc_console_setup(struct console *co, char *options) | |||
208 | return 0; | 209 | return 0; |
209 | } | 210 | } |
210 | 211 | ||
211 | struct console hvc_con_driver = { | 212 | static struct console hvc_con_driver = { |
212 | .name = "hvc", | 213 | .name = "hvc", |
213 | .write = hvc_console_print, | 214 | .write = hvc_console_print, |
214 | .device = hvc_console_device, | 215 | .device = hvc_console_device, |
@@ -278,7 +279,6 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops) | |||
278 | 279 | ||
279 | return 0; | 280 | return 0; |
280 | } | 281 | } |
281 | EXPORT_SYMBOL(hvc_instantiate); | ||
282 | 282 | ||
283 | /* Wake the sleeping khvcd */ | 283 | /* Wake the sleeping khvcd */ |
284 | static void hvc_kick(void) | 284 | static void hvc_kick(void) |
@@ -792,7 +792,6 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq, | |||
792 | 792 | ||
793 | return hp; | 793 | return hp; |
794 | } | 794 | } |
795 | EXPORT_SYMBOL(hvc_alloc); | ||
796 | 795 | ||
797 | int __devexit hvc_remove(struct hvc_struct *hp) | 796 | int __devexit hvc_remove(struct hvc_struct *hp) |
798 | { | 797 | { |
@@ -828,11 +827,10 @@ int __devexit hvc_remove(struct hvc_struct *hp) | |||
828 | tty_hangup(tty); | 827 | tty_hangup(tty); |
829 | return 0; | 828 | return 0; |
830 | } | 829 | } |
831 | EXPORT_SYMBOL(hvc_remove); | ||
832 | 830 | ||
833 | /* Driver initialization. Follow console initialization. This is where the TTY | 831 | /* Driver initialization. Follow console initialization. This is where the TTY |
834 | * interfaces start to become available. */ | 832 | * interfaces start to become available. */ |
835 | int __init hvc_init(void) | 833 | static int __init hvc_init(void) |
836 | { | 834 | { |
837 | struct tty_driver *drv; | 835 | struct tty_driver *drv; |
838 | 836 | ||
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index cc1046e6ee02..4ae9811d1a6c 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -24,10 +24,11 @@ | |||
24 | * warranty of any kind, whether express or implied. | 24 | * warranty of any kind, whether express or implied. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | 27 | #include <linux/hw_random.h> |
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | ||
29 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
30 | #include <linux/hw_random.h> | 31 | #include <linux/stop_machine.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | 33 | ||
33 | 34 | ||
@@ -217,30 +218,117 @@ static struct hwrng intel_rng = { | |||
217 | .data_read = intel_rng_data_read, | 218 | .data_read = intel_rng_data_read, |
218 | }; | 219 | }; |
219 | 220 | ||
221 | struct intel_rng_hw { | ||
222 | struct pci_dev *dev; | ||
223 | void __iomem *mem; | ||
224 | u8 bios_cntl_off; | ||
225 | u8 bios_cntl_val; | ||
226 | u8 fwh_dec_en1_off; | ||
227 | u8 fwh_dec_en1_val; | ||
228 | }; | ||
220 | 229 | ||
221 | #ifdef CONFIG_SMP | 230 | static int __init intel_rng_hw_init(void *_intel_rng_hw) |
222 | static char __initdata waitflag; | 231 | { |
232 | struct intel_rng_hw *intel_rng_hw = _intel_rng_hw; | ||
233 | u8 mfc, dvc; | ||
234 | |||
235 | /* interrupts disabled in stop_machine_run call */ | ||
236 | |||
237 | if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
238 | pci_write_config_byte(intel_rng_hw->dev, | ||
239 | intel_rng_hw->fwh_dec_en1_off, | ||
240 | intel_rng_hw->fwh_dec_en1_val | | ||
241 | FWH_F8_EN_MASK); | ||
242 | if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
243 | pci_write_config_byte(intel_rng_hw->dev, | ||
244 | intel_rng_hw->bios_cntl_off, | ||
245 | intel_rng_hw->bios_cntl_val | | ||
246 | BIOS_CNTL_WRITE_ENABLE_MASK); | ||
247 | |||
248 | writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); | ||
249 | writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem); | ||
250 | mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); | ||
251 | dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS); | ||
252 | writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem); | ||
253 | |||
254 | if (!(intel_rng_hw->bios_cntl_val & | ||
255 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) | ||
256 | pci_write_config_byte(intel_rng_hw->dev, | ||
257 | intel_rng_hw->bios_cntl_off, | ||
258 | intel_rng_hw->bios_cntl_val); | ||
259 | if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
260 | pci_write_config_byte(intel_rng_hw->dev, | ||
261 | intel_rng_hw->fwh_dec_en1_off, | ||
262 | intel_rng_hw->fwh_dec_en1_val); | ||
223 | 263 | ||
224 | static void __init intel_init_wait(void *unused) | 264 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || |
265 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | ||
266 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | ||
267 | printk(KERN_ERR PFX "FWH not detected\n"); | ||
268 | return -ENODEV; | ||
269 | } | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, | ||
275 | struct pci_dev *dev) | ||
225 | { | 276 | { |
226 | while (waitflag) | 277 | intel_rng_hw->bios_cntl_val = 0xff; |
227 | cpu_relax(); | 278 | intel_rng_hw->fwh_dec_en1_val = 0xff; |
279 | intel_rng_hw->dev = dev; | ||
280 | |||
281 | /* Check for Intel 82802 */ | ||
282 | if (dev->device < 0x2640) { | ||
283 | intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; | ||
284 | intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD; | ||
285 | } else { | ||
286 | intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; | ||
287 | intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW; | ||
288 | } | ||
289 | |||
290 | pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off, | ||
291 | &intel_rng_hw->fwh_dec_en1_val); | ||
292 | pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off, | ||
293 | &intel_rng_hw->bios_cntl_val); | ||
294 | |||
295 | if ((intel_rng_hw->bios_cntl_val & | ||
296 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
297 | == BIOS_CNTL_LOCK_ENABLE_MASK) { | ||
298 | static __initdata /*const*/ char warning[] = | ||
299 | KERN_WARNING PFX "Firmware space is locked read-only. " | ||
300 | KERN_WARNING PFX "If you can't or\n don't want to " | ||
301 | KERN_WARNING PFX "disable this in firmware setup, and " | ||
302 | KERN_WARNING PFX "if\n you are certain that your " | ||
303 | KERN_WARNING PFX "system has a functional\n RNG, try" | ||
304 | KERN_WARNING PFX "using the 'no_fwh_detect' option.\n"; | ||
305 | |||
306 | if (no_fwh_detect) | ||
307 | return -ENODEV; | ||
308 | printk(warning); | ||
309 | return -EBUSY; | ||
310 | } | ||
311 | |||
312 | intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); | ||
313 | if (intel_rng_hw->mem == NULL) | ||
314 | return -EBUSY; | ||
315 | |||
316 | return 0; | ||
228 | } | 317 | } |
229 | #endif | 318 | |
230 | 319 | ||
231 | static int __init mod_init(void) | 320 | static int __init mod_init(void) |
232 | { | 321 | { |
233 | int err = -ENODEV; | 322 | int err = -ENODEV; |
234 | unsigned i; | 323 | int i; |
235 | struct pci_dev *dev = NULL; | 324 | struct pci_dev *dev = NULL; |
236 | void __iomem *mem; | 325 | void __iomem *mem = mem; |
237 | unsigned long flags; | 326 | u8 hw_status; |
238 | u8 bios_cntl_off, fwh_dec_en1_off; | 327 | struct intel_rng_hw *intel_rng_hw; |
239 | u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff; | ||
240 | u8 hw_status, mfc, dvc; | ||
241 | 328 | ||
242 | for (i = 0; !dev && pci_tbl[i].vendor; ++i) | 329 | for (i = 0; !dev && pci_tbl[i].vendor; ++i) |
243 | dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); | 330 | dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, |
331 | NULL); | ||
244 | 332 | ||
245 | if (!dev) | 333 | if (!dev) |
246 | goto out; /* Device not found. */ | 334 | goto out; /* Device not found. */ |
@@ -250,39 +338,18 @@ static int __init mod_init(void) | |||
250 | goto fwh_done; | 338 | goto fwh_done; |
251 | } | 339 | } |
252 | 340 | ||
253 | /* Check for Intel 82802 */ | 341 | intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); |
254 | if (dev->device < 0x2640) { | 342 | if (!intel_rng_hw) { |
255 | fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD; | ||
256 | bios_cntl_off = BIOS_CNTL_REG_OLD; | ||
257 | } else { | ||
258 | fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW; | ||
259 | bios_cntl_off = BIOS_CNTL_REG_NEW; | ||
260 | } | ||
261 | |||
262 | pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val); | ||
263 | pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val); | ||
264 | |||
265 | if ((bios_cntl_val & | ||
266 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
267 | == BIOS_CNTL_LOCK_ENABLE_MASK) { | ||
268 | static __initdata /*const*/ char warning[] = | ||
269 | KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n" | ||
270 | KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n" | ||
271 | KERN_WARNING PFX "you are certain that your system has a functional\n" | ||
272 | KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n"; | ||
273 | |||
274 | pci_dev_put(dev); | 343 | pci_dev_put(dev); |
275 | if (no_fwh_detect) | ||
276 | goto fwh_done; | ||
277 | printk(warning); | ||
278 | err = -EBUSY; | ||
279 | goto out; | 344 | goto out; |
280 | } | 345 | } |
281 | 346 | ||
282 | mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); | 347 | err = intel_init_hw_struct(intel_rng_hw, dev); |
283 | if (mem == NULL) { | 348 | if (err) { |
284 | pci_dev_put(dev); | 349 | pci_dev_put(dev); |
285 | err = -EBUSY; | 350 | kfree(intel_rng_hw); |
351 | if (err == -ENODEV) | ||
352 | goto fwh_done; | ||
286 | goto out; | 353 | goto out; |
287 | } | 354 | } |
288 | 355 | ||
@@ -290,59 +357,18 @@ static int __init mod_init(void) | |||
290 | * Since the BIOS code/data is going to disappear from its normal | 357 | * Since the BIOS code/data is going to disappear from its normal |
291 | * location with the Read ID command, all activity on the system | 358 | * location with the Read ID command, all activity on the system |
292 | * must be stopped until the state is back to normal. | 359 | * must be stopped until the state is back to normal. |
360 | * | ||
361 | * Use stop_machine_run because IPIs can be blocked by disabling | ||
362 | * interrupts. | ||
293 | */ | 363 | */ |
294 | #ifdef CONFIG_SMP | 364 | err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS); |
295 | set_mb(waitflag, 1); | ||
296 | if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) { | ||
297 | set_mb(waitflag, 0); | ||
298 | pci_dev_put(dev); | ||
299 | printk(KERN_ERR PFX "cannot run on all processors\n"); | ||
300 | err = -EAGAIN; | ||
301 | goto err_unmap; | ||
302 | } | ||
303 | #endif | ||
304 | local_irq_save(flags); | ||
305 | |||
306 | if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
307 | pci_write_config_byte(dev, | ||
308 | fwh_dec_en1_off, | ||
309 | fwh_dec_en1_val | FWH_F8_EN_MASK); | ||
310 | if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK)) | ||
311 | pci_write_config_byte(dev, | ||
312 | bios_cntl_off, | ||
313 | bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK); | ||
314 | |||
315 | writeb(INTEL_FWH_RESET_CMD, mem); | ||
316 | writeb(INTEL_FWH_READ_ID_CMD, mem); | ||
317 | mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS); | ||
318 | dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS); | ||
319 | writeb(INTEL_FWH_RESET_CMD, mem); | ||
320 | |||
321 | if (!(bios_cntl_val & | ||
322 | (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))) | ||
323 | pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val); | ||
324 | if (!(fwh_dec_en1_val & FWH_F8_EN_MASK)) | ||
325 | pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val); | ||
326 | |||
327 | local_irq_restore(flags); | ||
328 | #ifdef CONFIG_SMP | ||
329 | /* Tell other CPUs to resume. */ | ||
330 | set_mb(waitflag, 0); | ||
331 | #endif | ||
332 | |||
333 | iounmap(mem); | ||
334 | pci_dev_put(dev); | 365 | pci_dev_put(dev); |
335 | 366 | iounmap(intel_rng_hw->mem); | |
336 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || | 367 | kfree(intel_rng_hw); |
337 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | 368 | if (err) |
338 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | ||
339 | printk(KERN_ERR PFX "FWH not detected\n"); | ||
340 | err = -ENODEV; | ||
341 | goto out; | 369 | goto out; |
342 | } | ||
343 | 370 | ||
344 | fwh_done: | 371 | fwh_done: |
345 | |||
346 | err = -ENOMEM; | 372 | err = -ENOMEM; |
347 | mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); | 373 | mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); |
348 | if (!mem) | 374 | if (!mem) |
@@ -352,22 +378,21 @@ fwh_done: | |||
352 | /* Check for Random Number Generator */ | 378 | /* Check for Random Number Generator */ |
353 | err = -ENODEV; | 379 | err = -ENODEV; |
354 | hw_status = hwstatus_get(mem); | 380 | hw_status = hwstatus_get(mem); |
355 | if ((hw_status & INTEL_RNG_PRESENT) == 0) | 381 | if ((hw_status & INTEL_RNG_PRESENT) == 0) { |
356 | goto err_unmap; | 382 | iounmap(mem); |
383 | goto out; | ||
384 | } | ||
357 | 385 | ||
358 | printk(KERN_INFO "Intel 82802 RNG detected\n"); | 386 | printk(KERN_INFO "Intel 82802 RNG detected\n"); |
359 | err = hwrng_register(&intel_rng); | 387 | err = hwrng_register(&intel_rng); |
360 | if (err) { | 388 | if (err) { |
361 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", | 389 | printk(KERN_ERR PFX "RNG registering failed (%d)\n", |
362 | err); | 390 | err); |
363 | goto err_unmap; | 391 | iounmap(mem); |
364 | } | 392 | } |
365 | out: | 393 | out: |
366 | return err; | 394 | return err; |
367 | 395 | ||
368 | err_unmap: | ||
369 | iounmap(mem); | ||
370 | goto out; | ||
371 | } | 396 | } |
372 | 397 | ||
373 | static void __exit mod_exit(void) | 398 | static void __exit mod_exit(void) |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 353d9f3cf8d7..0289705967de 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/proc_fs.h> | 22 | #include <linux/proc_fs.h> |
23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
24 | #include <linux/dmi.h> | 24 | #include <linux/dmi.h> |
25 | #include <linux/capability.h> | ||
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
27 | 28 | ||
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index a48da02aad2f..932264a657d0 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/poll.h> | 36 | #include <linux/poll.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/smp_lock.h> | ||
39 | 38 | ||
40 | #include <asm/m48t35.h> | 39 | #include <asm/m48t35.h> |
41 | #include <asm/sn/ioc3.h> | 40 | #include <asm/sn/ioc3.h> |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index e22146546add..6c5d15de3317 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * source@mvista.com | 9 | * source@mvista.com |
10 | * | 10 | * |
11 | * Copyright 2002 MontaVista Software Inc. | 11 | * Copyright 2002 MontaVista Software Inc. |
12 | * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com> | ||
12 | * | 13 | * |
13 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
14 | * under the terms of the GNU General Public License as published by the | 15 | * under the terms of the GNU General Public License as published by the |
@@ -64,6 +65,11 @@ | |||
64 | #include <linux/string.h> | 65 | #include <linux/string.h> |
65 | #include <linux/ctype.h> | 66 | #include <linux/ctype.h> |
66 | 67 | ||
68 | #ifdef CONFIG_PPC_OF | ||
69 | #include <asm/of_device.h> | ||
70 | #include <asm/of_platform.h> | ||
71 | #endif | ||
72 | |||
67 | #define PFX "ipmi_si: " | 73 | #define PFX "ipmi_si: " |
68 | 74 | ||
69 | /* Measure times between events in the driver. */ | 75 | /* Measure times between events in the driver. */ |
@@ -76,6 +82,12 @@ | |||
76 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a | 82 | #define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a |
77 | short timeout */ | 83 | short timeout */ |
78 | 84 | ||
85 | /* Bit for BMC global enables. */ | ||
86 | #define IPMI_BMC_RCV_MSG_INTR 0x01 | ||
87 | #define IPMI_BMC_EVT_MSG_INTR 0x02 | ||
88 | #define IPMI_BMC_EVT_MSG_BUFF 0x04 | ||
89 | #define IPMI_BMC_SYS_LOG 0x08 | ||
90 | |||
79 | enum si_intf_state { | 91 | enum si_intf_state { |
80 | SI_NORMAL, | 92 | SI_NORMAL, |
81 | SI_GETTING_FLAGS, | 93 | SI_GETTING_FLAGS, |
@@ -84,7 +96,9 @@ enum si_intf_state { | |||
84 | SI_CLEARING_FLAGS_THEN_SET_IRQ, | 96 | SI_CLEARING_FLAGS_THEN_SET_IRQ, |
85 | SI_GETTING_MESSAGES, | 97 | SI_GETTING_MESSAGES, |
86 | SI_ENABLE_INTERRUPTS1, | 98 | SI_ENABLE_INTERRUPTS1, |
87 | SI_ENABLE_INTERRUPTS2 | 99 | SI_ENABLE_INTERRUPTS2, |
100 | SI_DISABLE_INTERRUPTS1, | ||
101 | SI_DISABLE_INTERRUPTS2 | ||
88 | /* FIXME - add watchdog stuff. */ | 102 | /* FIXME - add watchdog stuff. */ |
89 | }; | 103 | }; |
90 | 104 | ||
@@ -333,6 +347,17 @@ static void start_enable_irq(struct smi_info *smi_info) | |||
333 | smi_info->si_state = SI_ENABLE_INTERRUPTS1; | 347 | smi_info->si_state = SI_ENABLE_INTERRUPTS1; |
334 | } | 348 | } |
335 | 349 | ||
350 | static void start_disable_irq(struct smi_info *smi_info) | ||
351 | { | ||
352 | unsigned char msg[2]; | ||
353 | |||
354 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
355 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | ||
356 | |||
357 | smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2); | ||
358 | smi_info->si_state = SI_DISABLE_INTERRUPTS1; | ||
359 | } | ||
360 | |||
336 | static void start_clear_flags(struct smi_info *smi_info) | 361 | static void start_clear_flags(struct smi_info *smi_info) |
337 | { | 362 | { |
338 | unsigned char msg[3]; | 363 | unsigned char msg[3]; |
@@ -353,7 +378,7 @@ static void start_clear_flags(struct smi_info *smi_info) | |||
353 | static inline void disable_si_irq(struct smi_info *smi_info) | 378 | static inline void disable_si_irq(struct smi_info *smi_info) |
354 | { | 379 | { |
355 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { | 380 | if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { |
356 | disable_irq_nosync(smi_info->irq); | 381 | start_disable_irq(smi_info); |
357 | smi_info->interrupt_disabled = 1; | 382 | smi_info->interrupt_disabled = 1; |
358 | } | 383 | } |
359 | } | 384 | } |
@@ -361,7 +386,7 @@ static inline void disable_si_irq(struct smi_info *smi_info) | |||
361 | static inline void enable_si_irq(struct smi_info *smi_info) | 386 | static inline void enable_si_irq(struct smi_info *smi_info) |
362 | { | 387 | { |
363 | if ((smi_info->irq) && (smi_info->interrupt_disabled)) { | 388 | if ((smi_info->irq) && (smi_info->interrupt_disabled)) { |
364 | enable_irq(smi_info->irq); | 389 | start_enable_irq(smi_info); |
365 | smi_info->interrupt_disabled = 0; | 390 | smi_info->interrupt_disabled = 0; |
366 | } | 391 | } |
367 | } | 392 | } |
@@ -583,7 +608,9 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
583 | } else { | 608 | } else { |
584 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 609 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); |
585 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | 610 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; |
586 | msg[2] = msg[3] | 1; /* enable msg queue int */ | 611 | msg[2] = (msg[3] | |
612 | IPMI_BMC_RCV_MSG_INTR | | ||
613 | IPMI_BMC_EVT_MSG_INTR); | ||
587 | smi_info->handlers->start_transaction( | 614 | smi_info->handlers->start_transaction( |
588 | smi_info->si_sm, msg, 3); | 615 | smi_info->si_sm, msg, 3); |
589 | smi_info->si_state = SI_ENABLE_INTERRUPTS2; | 616 | smi_info->si_state = SI_ENABLE_INTERRUPTS2; |
@@ -605,6 +632,45 @@ static void handle_transaction_done(struct smi_info *smi_info) | |||
605 | smi_info->si_state = SI_NORMAL; | 632 | smi_info->si_state = SI_NORMAL; |
606 | break; | 633 | break; |
607 | } | 634 | } |
635 | |||
636 | case SI_DISABLE_INTERRUPTS1: | ||
637 | { | ||
638 | unsigned char msg[4]; | ||
639 | |||
640 | /* We got the flags from the SMI, now handle them. */ | ||
641 | smi_info->handlers->get_result(smi_info->si_sm, msg, 4); | ||
642 | if (msg[2] != 0) { | ||
643 | printk(KERN_WARNING | ||
644 | "ipmi_si: Could not disable interrupts" | ||
645 | ", failed get.\n"); | ||
646 | smi_info->si_state = SI_NORMAL; | ||
647 | } else { | ||
648 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
649 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | ||
650 | msg[2] = (msg[3] & | ||
651 | ~(IPMI_BMC_RCV_MSG_INTR | | ||
652 | IPMI_BMC_EVT_MSG_INTR)); | ||
653 | smi_info->handlers->start_transaction( | ||
654 | smi_info->si_sm, msg, 3); | ||
655 | smi_info->si_state = SI_DISABLE_INTERRUPTS2; | ||
656 | } | ||
657 | break; | ||
658 | } | ||
659 | |||
660 | case SI_DISABLE_INTERRUPTS2: | ||
661 | { | ||
662 | unsigned char msg[4]; | ||
663 | |||
664 | /* We got the flags from the SMI, now handle them. */ | ||
665 | smi_info->handlers->get_result(smi_info->si_sm, msg, 4); | ||
666 | if (msg[2] != 0) { | ||
667 | printk(KERN_WARNING | ||
668 | "ipmi_si: Could not disable interrupts" | ||
669 | ", failed set.\n"); | ||
670 | } | ||
671 | smi_info->si_state = SI_NORMAL; | ||
672 | break; | ||
673 | } | ||
608 | } | 674 | } |
609 | } | 675 | } |
610 | 676 | ||
@@ -858,9 +924,6 @@ static void smi_timeout(unsigned long data) | |||
858 | struct timeval t; | 924 | struct timeval t; |
859 | #endif | 925 | #endif |
860 | 926 | ||
861 | if (atomic_read(&smi_info->stop_operation)) | ||
862 | return; | ||
863 | |||
864 | spin_lock_irqsave(&(smi_info->si_lock), flags); | 927 | spin_lock_irqsave(&(smi_info->si_lock), flags); |
865 | #ifdef DEBUG_TIMING | 928 | #ifdef DEBUG_TIMING |
866 | do_gettimeofday(&t); | 929 | do_gettimeofday(&t); |
@@ -916,15 +979,11 @@ static irqreturn_t si_irq_handler(int irq, void *data) | |||
916 | smi_info->interrupts++; | 979 | smi_info->interrupts++; |
917 | spin_unlock(&smi_info->count_lock); | 980 | spin_unlock(&smi_info->count_lock); |
918 | 981 | ||
919 | if (atomic_read(&smi_info->stop_operation)) | ||
920 | goto out; | ||
921 | |||
922 | #ifdef DEBUG_TIMING | 982 | #ifdef DEBUG_TIMING |
923 | do_gettimeofday(&t); | 983 | do_gettimeofday(&t); |
924 | printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 984 | printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
925 | #endif | 985 | #endif |
926 | smi_event_handler(smi_info, 0); | 986 | smi_event_handler(smi_info, 0); |
927 | out: | ||
928 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 987 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
929 | return IRQ_HANDLED; | 988 | return IRQ_HANDLED; |
930 | } | 989 | } |
@@ -1006,6 +1065,7 @@ static DEFINE_MUTEX(smi_infos_lock); | |||
1006 | static int smi_num; /* Used to sequence the SMIs */ | 1065 | static int smi_num; /* Used to sequence the SMIs */ |
1007 | 1066 | ||
1008 | #define DEFAULT_REGSPACING 1 | 1067 | #define DEFAULT_REGSPACING 1 |
1068 | #define DEFAULT_REGSIZE 1 | ||
1009 | 1069 | ||
1010 | static int si_trydefaults = 1; | 1070 | static int si_trydefaults = 1; |
1011 | static char *si_type[SI_MAX_PARMS]; | 1071 | static char *si_type[SI_MAX_PARMS]; |
@@ -1111,7 +1171,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1111 | if (info->si_type == SI_BT) { | 1171 | if (info->si_type == SI_BT) { |
1112 | rv = request_irq(info->irq, | 1172 | rv = request_irq(info->irq, |
1113 | si_bt_irq_handler, | 1173 | si_bt_irq_handler, |
1114 | IRQF_DISABLED, | 1174 | IRQF_SHARED | IRQF_DISABLED, |
1115 | DEVICE_NAME, | 1175 | DEVICE_NAME, |
1116 | info); | 1176 | info); |
1117 | if (!rv) | 1177 | if (!rv) |
@@ -1121,7 +1181,7 @@ static int std_irq_setup(struct smi_info *info) | |||
1121 | } else | 1181 | } else |
1122 | rv = request_irq(info->irq, | 1182 | rv = request_irq(info->irq, |
1123 | si_irq_handler, | 1183 | si_irq_handler, |
1124 | IRQF_DISABLED, | 1184 | IRQF_SHARED | IRQF_DISABLED, |
1125 | DEVICE_NAME, | 1185 | DEVICE_NAME, |
1126 | info); | 1186 | info); |
1127 | if (rv) { | 1187 | if (rv) { |
@@ -1701,15 +1761,11 @@ static u32 ipmi_acpi_gpe(void *context) | |||
1701 | smi_info->interrupts++; | 1761 | smi_info->interrupts++; |
1702 | spin_unlock(&smi_info->count_lock); | 1762 | spin_unlock(&smi_info->count_lock); |
1703 | 1763 | ||
1704 | if (atomic_read(&smi_info->stop_operation)) | ||
1705 | goto out; | ||
1706 | |||
1707 | #ifdef DEBUG_TIMING | 1764 | #ifdef DEBUG_TIMING |
1708 | do_gettimeofday(&t); | 1765 | do_gettimeofday(&t); |
1709 | printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); | 1766 | printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); |
1710 | #endif | 1767 | #endif |
1711 | smi_event_handler(smi_info, 0); | 1768 | smi_event_handler(smi_info, 0); |
1712 | out: | ||
1713 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); | 1769 | spin_unlock_irqrestore(&(smi_info->si_lock), flags); |
1714 | 1770 | ||
1715 | return ACPI_INTERRUPT_HANDLED; | 1771 | return ACPI_INTERRUPT_HANDLED; |
@@ -2133,12 +2189,15 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, | |||
2133 | info->irq_setup = std_irq_setup; | 2189 | info->irq_setup = std_irq_setup; |
2134 | 2190 | ||
2135 | info->dev = &pdev->dev; | 2191 | info->dev = &pdev->dev; |
2192 | pci_set_drvdata(pdev, info); | ||
2136 | 2193 | ||
2137 | return try_smi_init(info); | 2194 | return try_smi_init(info); |
2138 | } | 2195 | } |
2139 | 2196 | ||
2140 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) | 2197 | static void __devexit ipmi_pci_remove(struct pci_dev *pdev) |
2141 | { | 2198 | { |
2199 | struct smi_info *info = pci_get_drvdata(pdev); | ||
2200 | cleanup_one_si(info); | ||
2142 | } | 2201 | } |
2143 | 2202 | ||
2144 | #ifdef CONFIG_PM | 2203 | #ifdef CONFIG_PM |
@@ -2172,6 +2231,99 @@ static struct pci_driver ipmi_pci_driver = { | |||
2172 | #endif /* CONFIG_PCI */ | 2231 | #endif /* CONFIG_PCI */ |
2173 | 2232 | ||
2174 | 2233 | ||
2234 | #ifdef CONFIG_PPC_OF | ||
2235 | static int __devinit ipmi_of_probe(struct of_device *dev, | ||
2236 | const struct of_device_id *match) | ||
2237 | { | ||
2238 | struct smi_info *info; | ||
2239 | struct resource resource; | ||
2240 | const int *regsize, *regspacing, *regshift; | ||
2241 | struct device_node *np = dev->node; | ||
2242 | int ret; | ||
2243 | int proplen; | ||
2244 | |||
2245 | dev_info(&dev->dev, PFX "probing via device tree\n"); | ||
2246 | |||
2247 | ret = of_address_to_resource(np, 0, &resource); | ||
2248 | if (ret) { | ||
2249 | dev_warn(&dev->dev, PFX "invalid address from OF\n"); | ||
2250 | return ret; | ||
2251 | } | ||
2252 | |||
2253 | regsize = get_property(np, "reg-size", &proplen); | ||
2254 | if (regsize && proplen != 4) { | ||
2255 | dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); | ||
2256 | return -EINVAL; | ||
2257 | } | ||
2258 | |||
2259 | regspacing = get_property(np, "reg-spacing", &proplen); | ||
2260 | if (regspacing && proplen != 4) { | ||
2261 | dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); | ||
2262 | return -EINVAL; | ||
2263 | } | ||
2264 | |||
2265 | regshift = get_property(np, "reg-shift", &proplen); | ||
2266 | if (regshift && proplen != 4) { | ||
2267 | dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); | ||
2268 | return -EINVAL; | ||
2269 | } | ||
2270 | |||
2271 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
2272 | |||
2273 | if (!info) { | ||
2274 | dev_err(&dev->dev, | ||
2275 | PFX "could not allocate memory for OF probe\n"); | ||
2276 | return -ENOMEM; | ||
2277 | } | ||
2278 | |||
2279 | info->si_type = (enum si_type) match->data; | ||
2280 | info->addr_source = "device-tree"; | ||
2281 | info->io_setup = mem_setup; | ||
2282 | info->irq_setup = std_irq_setup; | ||
2283 | |||
2284 | info->io.addr_type = IPMI_MEM_ADDR_SPACE; | ||
2285 | info->io.addr_data = resource.start; | ||
2286 | |||
2287 | info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE; | ||
2288 | info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING; | ||
2289 | info->io.regshift = regshift ? *regshift : 0; | ||
2290 | |||
2291 | info->irq = irq_of_parse_and_map(dev->node, 0); | ||
2292 | info->dev = &dev->dev; | ||
2293 | |||
2294 | dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", | ||
2295 | info->io.addr_data, info->io.regsize, info->io.regspacing, | ||
2296 | info->irq); | ||
2297 | |||
2298 | dev->dev.driver_data = (void*) info; | ||
2299 | |||
2300 | return try_smi_init(info); | ||
2301 | } | ||
2302 | |||
2303 | static int __devexit ipmi_of_remove(struct of_device *dev) | ||
2304 | { | ||
2305 | cleanup_one_si(dev->dev.driver_data); | ||
2306 | return 0; | ||
2307 | } | ||
2308 | |||
2309 | static struct of_device_id ipmi_match[] = | ||
2310 | { | ||
2311 | { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS }, | ||
2312 | { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC }, | ||
2313 | { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT }, | ||
2314 | {}, | ||
2315 | }; | ||
2316 | |||
2317 | static struct of_platform_driver ipmi_of_platform_driver = | ||
2318 | { | ||
2319 | .name = "ipmi", | ||
2320 | .match_table = ipmi_match, | ||
2321 | .probe = ipmi_of_probe, | ||
2322 | .remove = __devexit_p(ipmi_of_remove), | ||
2323 | }; | ||
2324 | #endif /* CONFIG_PPC_OF */ | ||
2325 | |||
2326 | |||
2175 | static int try_get_dev_id(struct smi_info *smi_info) | 2327 | static int try_get_dev_id(struct smi_info *smi_info) |
2176 | { | 2328 | { |
2177 | unsigned char msg[2]; | 2329 | unsigned char msg[2]; |
@@ -2801,6 +2953,10 @@ static __devinit int init_ipmi_si(void) | |||
2801 | } | 2953 | } |
2802 | #endif | 2954 | #endif |
2803 | 2955 | ||
2956 | #ifdef CONFIG_PPC_OF | ||
2957 | of_register_platform_driver(&ipmi_of_platform_driver); | ||
2958 | #endif | ||
2959 | |||
2804 | if (si_trydefaults) { | 2960 | if (si_trydefaults) { |
2805 | mutex_lock(&smi_infos_lock); | 2961 | mutex_lock(&smi_infos_lock); |
2806 | if (list_empty(&smi_infos)) { | 2962 | if (list_empty(&smi_infos)) { |
@@ -2838,28 +2994,33 @@ static void cleanup_one_si(struct smi_info *to_clean) | |||
2838 | 2994 | ||
2839 | list_del(&to_clean->link); | 2995 | list_del(&to_clean->link); |
2840 | 2996 | ||
2841 | /* Tell the timer and interrupt handlers that we are shutting | 2997 | /* Tell the driver that we are shutting down. */ |
2842 | down. */ | ||
2843 | spin_lock_irqsave(&(to_clean->si_lock), flags); | ||
2844 | spin_lock(&(to_clean->msg_lock)); | ||
2845 | |||
2846 | atomic_inc(&to_clean->stop_operation); | 2998 | atomic_inc(&to_clean->stop_operation); |
2847 | 2999 | ||
2848 | if (to_clean->irq_cleanup) | 3000 | /* Make sure the timer and thread are stopped and will not run |
2849 | to_clean->irq_cleanup(to_clean); | 3001 | again. */ |
2850 | |||
2851 | spin_unlock(&(to_clean->msg_lock)); | ||
2852 | spin_unlock_irqrestore(&(to_clean->si_lock), flags); | ||
2853 | |||
2854 | /* Wait until we know that we are out of any interrupt | ||
2855 | handlers might have been running before we freed the | ||
2856 | interrupt. */ | ||
2857 | synchronize_sched(); | ||
2858 | |||
2859 | wait_for_timer_and_thread(to_clean); | 3002 | wait_for_timer_and_thread(to_clean); |
2860 | 3003 | ||
2861 | /* Interrupts and timeouts are stopped, now make sure the | 3004 | /* Timeouts are stopped, now make sure the interrupts are off |
2862 | interface is in a clean state. */ | 3005 | for the device. A little tricky with locks to make sure |
3006 | there are no races. */ | ||
3007 | spin_lock_irqsave(&to_clean->si_lock, flags); | ||
3008 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | ||
3009 | spin_unlock_irqrestore(&to_clean->si_lock, flags); | ||
3010 | poll(to_clean); | ||
3011 | schedule_timeout_uninterruptible(1); | ||
3012 | spin_lock_irqsave(&to_clean->si_lock, flags); | ||
3013 | } | ||
3014 | disable_si_irq(to_clean); | ||
3015 | spin_unlock_irqrestore(&to_clean->si_lock, flags); | ||
3016 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | ||
3017 | poll(to_clean); | ||
3018 | schedule_timeout_uninterruptible(1); | ||
3019 | } | ||
3020 | |||
3021 | /* Clean up interrupts and make sure that everything is done. */ | ||
3022 | if (to_clean->irq_cleanup) | ||
3023 | to_clean->irq_cleanup(to_clean); | ||
2863 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { | 3024 | while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
2864 | poll(to_clean); | 3025 | poll(to_clean); |
2865 | schedule_timeout_uninterruptible(1); | 3026 | schedule_timeout_uninterruptible(1); |
@@ -2898,6 +3059,10 @@ static __exit void cleanup_ipmi_si(void) | |||
2898 | pci_unregister_driver(&ipmi_pci_driver); | 3059 | pci_unregister_driver(&ipmi_pci_driver); |
2899 | #endif | 3060 | #endif |
2900 | 3061 | ||
3062 | #ifdef CONFIG_PPC_OF | ||
3063 | of_unregister_platform_driver(&ipmi_of_platform_driver); | ||
3064 | #endif | ||
3065 | |||
2901 | mutex_lock(&smi_infos_lock); | 3066 | mutex_lock(&smi_infos_lock); |
2902 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) | 3067 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) |
2903 | cleanup_one_si(e); | 3068 | cleanup_one_si(e); |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 6b634e8d9519..147c12047cf3 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/completion.h> | 41 | #include <linux/completion.h> |
42 | #include <linux/kdebug.h> | ||
42 | #include <linux/rwsem.h> | 43 | #include <linux/rwsem.h> |
43 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
44 | #include <asm/uaccess.h> | 45 | #include <asm/uaccess.h> |
@@ -49,9 +50,18 @@ | |||
49 | #include <linux/poll.h> | 50 | #include <linux/poll.h> |
50 | #include <linux/string.h> | 51 | #include <linux/string.h> |
51 | #include <linux/ctype.h> | 52 | #include <linux/ctype.h> |
53 | #include <linux/delay.h> | ||
52 | #include <asm/atomic.h> | 54 | #include <asm/atomic.h> |
53 | #ifdef CONFIG_X86_LOCAL_APIC | 55 | |
54 | #include <asm/apic.h> | 56 | #ifdef CONFIG_X86 |
57 | /* This is ugly, but I've determined that x86 is the only architecture | ||
58 | that can reasonably support the IPMI NMI watchdog timeout at this | ||
59 | time. If another architecture adds this capability somehow, it | ||
60 | will have to be a somewhat different mechanism and I have no idea | ||
61 | how it will work. So in the unlikely event that another | ||
62 | architecture supports this, we can figure out a good generic | ||
63 | mechanism for it at that time. */ | ||
64 | #define HAVE_DIE_NMI_POST | ||
55 | #endif | 65 | #endif |
56 | 66 | ||
57 | #define PFX "IPMI Watchdog: " | 67 | #define PFX "IPMI Watchdog: " |
@@ -317,6 +327,11 @@ static unsigned char ipmi_version_minor; | |||
317 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ | 327 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ |
318 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); | 328 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); |
319 | 329 | ||
330 | #ifdef HAVE_DIE_NMI_POST | ||
331 | static int testing_nmi; | ||
332 | static int nmi_handler_registered; | ||
333 | #endif | ||
334 | |||
320 | static int ipmi_heartbeat(void); | 335 | static int ipmi_heartbeat(void); |
321 | static void panic_halt_ipmi_heartbeat(void); | 336 | static void panic_halt_ipmi_heartbeat(void); |
322 | 337 | ||
@@ -358,6 +373,10 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, | |||
358 | int hbnow = 0; | 373 | int hbnow = 0; |
359 | 374 | ||
360 | 375 | ||
376 | /* These can be cleared as we are setting the timeout. */ | ||
377 | ipmi_start_timer_on_heartbeat = 0; | ||
378 | pretimeout_since_last_heartbeat = 0; | ||
379 | |||
361 | data[0] = 0; | 380 | data[0] = 0; |
362 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); | 381 | WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); |
363 | 382 | ||
@@ -432,13 +451,12 @@ static int ipmi_set_timeout(int do_heartbeat) | |||
432 | 451 | ||
433 | wait_for_completion(&set_timeout_wait); | 452 | wait_for_completion(&set_timeout_wait); |
434 | 453 | ||
454 | mutex_unlock(&set_timeout_lock); | ||
455 | |||
435 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) | 456 | if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) |
436 | || ((send_heartbeat_now) | 457 | || ((send_heartbeat_now) |
437 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) | 458 | && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) |
438 | { | ||
439 | rv = ipmi_heartbeat(); | 459 | rv = ipmi_heartbeat(); |
440 | } | ||
441 | mutex_unlock(&set_timeout_lock); | ||
442 | 460 | ||
443 | out: | 461 | out: |
444 | return rv; | 462 | return rv; |
@@ -518,12 +536,10 @@ static int ipmi_heartbeat(void) | |||
518 | int rv; | 536 | int rv; |
519 | struct ipmi_system_interface_addr addr; | 537 | struct ipmi_system_interface_addr addr; |
520 | 538 | ||
521 | if (ipmi_ignore_heartbeat) { | 539 | if (ipmi_ignore_heartbeat) |
522 | return 0; | 540 | return 0; |
523 | } | ||
524 | 541 | ||
525 | if (ipmi_start_timer_on_heartbeat) { | 542 | if (ipmi_start_timer_on_heartbeat) { |
526 | ipmi_start_timer_on_heartbeat = 0; | ||
527 | ipmi_watchdog_state = action_val; | 543 | ipmi_watchdog_state = action_val; |
528 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 544 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
529 | } else if (pretimeout_since_last_heartbeat) { | 545 | } else if (pretimeout_since_last_heartbeat) { |
@@ -531,7 +547,6 @@ static int ipmi_heartbeat(void) | |||
531 | We don't want to set the action, though, we want to | 547 | We don't want to set the action, though, we want to |
532 | leave that alone (thus it can't be combined with the | 548 | leave that alone (thus it can't be combined with the |
533 | above operation. */ | 549 | above operation. */ |
534 | pretimeout_since_last_heartbeat = 0; | ||
535 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); | 550 | return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); |
536 | } | 551 | } |
537 | 552 | ||
@@ -919,6 +934,45 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
919 | printk(KERN_CRIT PFX "Unable to register misc device\n"); | 934 | printk(KERN_CRIT PFX "Unable to register misc device\n"); |
920 | } | 935 | } |
921 | 936 | ||
937 | #ifdef HAVE_DIE_NMI_POST | ||
938 | if (nmi_handler_registered) { | ||
939 | int old_pretimeout = pretimeout; | ||
940 | int old_timeout = timeout; | ||
941 | int old_preop_val = preop_val; | ||
942 | |||
943 | /* Set the pretimeout to go off in a second and give | ||
944 | ourselves plenty of time to stop the timer. */ | ||
945 | ipmi_watchdog_state = WDOG_TIMEOUT_RESET; | ||
946 | preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ | ||
947 | pretimeout = 99; | ||
948 | timeout = 100; | ||
949 | |||
950 | testing_nmi = 1; | ||
951 | |||
952 | rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | ||
953 | if (rv) { | ||
954 | printk(KERN_WARNING PFX "Error starting timer to" | ||
955 | " test NMI: 0x%x. The NMI pretimeout will" | ||
956 | " likely not work\n", rv); | ||
957 | rv = 0; | ||
958 | goto out_restore; | ||
959 | } | ||
960 | |||
961 | msleep(1500); | ||
962 | |||
963 | if (testing_nmi != 2) { | ||
964 | printk(KERN_WARNING PFX "IPMI NMI didn't seem to" | ||
965 | " occur. The NMI pretimeout will" | ||
966 | " likely not work\n"); | ||
967 | } | ||
968 | out_restore: | ||
969 | testing_nmi = 0; | ||
970 | preop_val = old_preop_val; | ||
971 | pretimeout = old_pretimeout; | ||
972 | timeout = old_timeout; | ||
973 | } | ||
974 | #endif | ||
975 | |||
922 | out: | 976 | out: |
923 | up_write(®ister_sem); | 977 | up_write(®ister_sem); |
924 | 978 | ||
@@ -928,6 +982,10 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
928 | ipmi_watchdog_state = action_val; | 982 | ipmi_watchdog_state = action_val; |
929 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); | 983 | ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); |
930 | printk(KERN_INFO PFX "Starting now!\n"); | 984 | printk(KERN_INFO PFX "Starting now!\n"); |
985 | } else { | ||
986 | /* Stop the timer now. */ | ||
987 | ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | ||
988 | ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); | ||
931 | } | 989 | } |
932 | } | 990 | } |
933 | 991 | ||
@@ -964,17 +1022,28 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
964 | up_write(®ister_sem); | 1022 | up_write(®ister_sem); |
965 | } | 1023 | } |
966 | 1024 | ||
967 | #ifdef HAVE_NMI_HANDLER | 1025 | #ifdef HAVE_DIE_NMI_POST |
968 | static int | 1026 | static int |
969 | ipmi_nmi(void *dev_id, int cpu, int handled) | 1027 | ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) |
970 | { | 1028 | { |
1029 | if (val != DIE_NMI_POST) | ||
1030 | return NOTIFY_OK; | ||
1031 | |||
1032 | if (testing_nmi) { | ||
1033 | testing_nmi = 2; | ||
1034 | return NOTIFY_STOP; | ||
1035 | } | ||
1036 | |||
971 | /* If we are not expecting a timeout, ignore it. */ | 1037 | /* If we are not expecting a timeout, ignore it. */ |
972 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1038 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
973 | return NOTIFY_DONE; | 1039 | return NOTIFY_OK; |
1040 | |||
1041 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | ||
1042 | return NOTIFY_OK; | ||
974 | 1043 | ||
975 | /* If no one else handled the NMI, we assume it was the IPMI | 1044 | /* If no one else handled the NMI, we assume it was the IPMI |
976 | watchdog. */ | 1045 | watchdog. */ |
977 | if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { | 1046 | if (preop_val == WDOG_PREOP_PANIC) { |
978 | /* On some machines, the heartbeat will give | 1047 | /* On some machines, the heartbeat will give |
979 | an error and not work unless we re-enable | 1048 | an error and not work unless we re-enable |
980 | the timer. So do so. */ | 1049 | the timer. So do so. */ |
@@ -983,18 +1052,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled) | |||
983 | panic(PFX "pre-timeout"); | 1052 | panic(PFX "pre-timeout"); |
984 | } | 1053 | } |
985 | 1054 | ||
986 | return NOTIFY_DONE; | 1055 | return NOTIFY_STOP; |
987 | } | 1056 | } |
988 | 1057 | ||
989 | static struct nmi_handler ipmi_nmi_handler = | 1058 | static struct notifier_block ipmi_nmi_handler = { |
990 | { | 1059 | .notifier_call = ipmi_nmi |
991 | .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), | ||
992 | .dev_name = "ipmi_watchdog", | ||
993 | .dev_id = NULL, | ||
994 | .handler = ipmi_nmi, | ||
995 | .priority = 0, /* Call us last. */ | ||
996 | }; | 1060 | }; |
997 | int nmi_handler_registered; | ||
998 | #endif | 1061 | #endif |
999 | 1062 | ||
1000 | static int wdog_reboot_handler(struct notifier_block *this, | 1063 | static int wdog_reboot_handler(struct notifier_block *this, |
@@ -1111,7 +1174,7 @@ static int preaction_op(const char *inval, char *outval) | |||
1111 | preaction_val = WDOG_PRETIMEOUT_NONE; | 1174 | preaction_val = WDOG_PRETIMEOUT_NONE; |
1112 | else if (strcmp(inval, "pre_smi") == 0) | 1175 | else if (strcmp(inval, "pre_smi") == 0) |
1113 | preaction_val = WDOG_PRETIMEOUT_SMI; | 1176 | preaction_val = WDOG_PRETIMEOUT_SMI; |
1114 | #ifdef HAVE_NMI_HANDLER | 1177 | #ifdef HAVE_DIE_NMI_POST |
1115 | else if (strcmp(inval, "pre_nmi") == 0) | 1178 | else if (strcmp(inval, "pre_nmi") == 0) |
1116 | preaction_val = WDOG_PRETIMEOUT_NMI; | 1179 | preaction_val = WDOG_PRETIMEOUT_NMI; |
1117 | #endif | 1180 | #endif |
@@ -1145,7 +1208,7 @@ static int preop_op(const char *inval, char *outval) | |||
1145 | 1208 | ||
1146 | static void check_parms(void) | 1209 | static void check_parms(void) |
1147 | { | 1210 | { |
1148 | #ifdef HAVE_NMI_HANDLER | 1211 | #ifdef HAVE_DIE_NMI_POST |
1149 | int do_nmi = 0; | 1212 | int do_nmi = 0; |
1150 | int rv; | 1213 | int rv; |
1151 | 1214 | ||
@@ -1158,20 +1221,9 @@ static void check_parms(void) | |||
1158 | preop_op("preop_none", NULL); | 1221 | preop_op("preop_none", NULL); |
1159 | do_nmi = 0; | 1222 | do_nmi = 0; |
1160 | } | 1223 | } |
1161 | #ifdef CONFIG_X86_LOCAL_APIC | ||
1162 | if (nmi_watchdog == NMI_IO_APIC) { | ||
1163 | printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" | ||
1164 | " mode (value is %d), that is incompatible" | ||
1165 | " with using NMI in the IPMI watchdog." | ||
1166 | " Disabling IPMI nmi pretimeout.\n", | ||
1167 | nmi_watchdog); | ||
1168 | preaction_val = WDOG_PRETIMEOUT_NONE; | ||
1169 | do_nmi = 0; | ||
1170 | } | ||
1171 | #endif | ||
1172 | } | 1224 | } |
1173 | if (do_nmi && !nmi_handler_registered) { | 1225 | if (do_nmi && !nmi_handler_registered) { |
1174 | rv = request_nmi(&ipmi_nmi_handler); | 1226 | rv = register_die_notifier(&ipmi_nmi_handler); |
1175 | if (rv) { | 1227 | if (rv) { |
1176 | printk(KERN_WARNING PFX | 1228 | printk(KERN_WARNING PFX |
1177 | "Can't register nmi handler\n"); | 1229 | "Can't register nmi handler\n"); |
@@ -1179,7 +1231,7 @@ static void check_parms(void) | |||
1179 | } else | 1231 | } else |
1180 | nmi_handler_registered = 1; | 1232 | nmi_handler_registered = 1; |
1181 | } else if (!do_nmi && nmi_handler_registered) { | 1233 | } else if (!do_nmi && nmi_handler_registered) { |
1182 | release_nmi(&ipmi_nmi_handler); | 1234 | unregister_die_notifier(&ipmi_nmi_handler); |
1183 | nmi_handler_registered = 0; | 1235 | nmi_handler_registered = 0; |
1184 | } | 1236 | } |
1185 | #endif | 1237 | #endif |
@@ -1215,9 +1267,9 @@ static int __init ipmi_wdog_init(void) | |||
1215 | 1267 | ||
1216 | rv = ipmi_smi_watcher_register(&smi_watcher); | 1268 | rv = ipmi_smi_watcher_register(&smi_watcher); |
1217 | if (rv) { | 1269 | if (rv) { |
1218 | #ifdef HAVE_NMI_HANDLER | 1270 | #ifdef HAVE_DIE_NMI_POST |
1219 | if (preaction_val == WDOG_PRETIMEOUT_NMI) | 1271 | if (nmi_handler_registered) |
1220 | release_nmi(&ipmi_nmi_handler); | 1272 | unregister_die_notifier(&ipmi_nmi_handler); |
1221 | #endif | 1273 | #endif |
1222 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1274 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1223 | &wdog_panic_notifier); | 1275 | &wdog_panic_notifier); |
@@ -1236,9 +1288,9 @@ static void __exit ipmi_wdog_exit(void) | |||
1236 | ipmi_smi_watcher_unregister(&smi_watcher); | 1288 | ipmi_smi_watcher_unregister(&smi_watcher); |
1237 | ipmi_unregister_watchdog(watchdog_ifnum); | 1289 | ipmi_unregister_watchdog(watchdog_ifnum); |
1238 | 1290 | ||
1239 | #ifdef HAVE_NMI_HANDLER | 1291 | #ifdef HAVE_DIE_NMI_POST |
1240 | if (nmi_handler_registered) | 1292 | if (nmi_handler_registered) |
1241 | release_nmi(&ipmi_nmi_handler); | 1293 | unregister_die_notifier(&ipmi_nmi_handler); |
1242 | #endif | 1294 | #endif |
1243 | 1295 | ||
1244 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1296 | atomic_notifier_chain_unregister(&panic_notifier_list, |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 43ab9edc76f5..761f77740d67 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -137,11 +137,10 @@ | |||
137 | #define InterruptTheCard(base) outw(0, (base) + 0xc) | 137 | #define InterruptTheCard(base) outw(0, (base) + 0xc) |
138 | #define ClearInterrupt(base) inw((base) + 0x0a) | 138 | #define ClearInterrupt(base) inw((base) + 0x0a) |
139 | 139 | ||
140 | #define pr_dbg(str...) pr_debug("ISICOM: " str) | ||
140 | #ifdef DEBUG | 141 | #ifdef DEBUG |
141 | #define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str) | ||
142 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) | 142 | #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) |
143 | #else | 143 | #else |
144 | #define pr_dbg(str...) do { } while (0) | ||
145 | #define isicom_paranoia_check(a, b, c) 0 | 144 | #define isicom_paranoia_check(a, b, c) 0 |
146 | #endif | 145 | #endif |
147 | 146 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index c06e86ad1dab..1b094509b1d2 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -109,7 +109,7 @@ struct kbd_struct kbd_table[MAX_NR_CONSOLES]; | |||
109 | static struct kbd_struct *kbd = kbd_table; | 109 | static struct kbd_struct *kbd = kbd_table; |
110 | 110 | ||
111 | struct vt_spawn_console vt_spawn_con = { | 111 | struct vt_spawn_console vt_spawn_con = { |
112 | .lock = SPIN_LOCK_UNLOCKED, | 112 | .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), |
113 | .pid = NULL, | 113 | .pid = NULL, |
114 | .sig = 0, | 114 | .sig = 0, |
115 | }; | 115 | }; |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index b51d08be0bcf..62051f8b0910 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -118,7 +118,6 @@ | |||
118 | #include <linux/kernel.h> | 118 | #include <linux/kernel.h> |
119 | #include <linux/major.h> | 119 | #include <linux/major.h> |
120 | #include <linux/sched.h> | 120 | #include <linux/sched.h> |
121 | #include <linux/smp_lock.h> | ||
122 | #include <linux/slab.h> | 121 | #include <linux/slab.h> |
123 | #include <linux/fcntl.h> | 122 | #include <linux/fcntl.h> |
124 | #include <linux/delay.h> | 123 | #include <linux/delay.h> |
@@ -139,9 +138,6 @@ | |||
139 | /* if you have more than 8 printers, remember to increase LP_NO */ | 138 | /* if you have more than 8 printers, remember to increase LP_NO */ |
140 | #define LP_NO 8 | 139 | #define LP_NO 8 |
141 | 140 | ||
142 | /* ROUND_UP macro from fs/select.c */ | ||
143 | #define ROUND_UP(x,y) (((x)+(y)-1)/(y)) | ||
144 | |||
145 | static struct lp_struct lp_table[LP_NO]; | 141 | static struct lp_struct lp_table[LP_NO]; |
146 | 142 | ||
147 | static unsigned int lp_count = 0; | 143 | static unsigned int lp_count = 0; |
@@ -652,7 +648,7 @@ static int lp_ioctl(struct inode *inode, struct file *file, | |||
652 | (par_timeout.tv_usec < 0)) { | 648 | (par_timeout.tv_usec < 0)) { |
653 | return -EINVAL; | 649 | return -EINVAL; |
654 | } | 650 | } |
655 | to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ); | 651 | to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ); |
656 | to_jiffies += par_timeout.tv_sec * (long) HZ; | 652 | to_jiffies += par_timeout.tv_sec * (long) HZ; |
657 | if (to_jiffies <= 0) { | 653 | if (to_jiffies <= 0) { |
658 | return -EINVAL; | 654 | return -EINVAL; |
@@ -803,7 +799,7 @@ static int lp_register(int nr, struct parport *port) | |||
803 | if (reset) | 799 | if (reset) |
804 | lp_reset(nr); | 800 | lp_reset(nr); |
805 | 801 | ||
806 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, | 802 | class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev, |
807 | "lp%d", nr); | 803 | "lp%d", nr); |
808 | 804 | ||
809 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, | 805 | printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 5f066963f171..cc9a9d0df979 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/raw.h> | 18 | #include <linux/raw.h> |
19 | #include <linux/tty.h> | 19 | #include <linux/tty.h> |
20 | #include <linux/capability.h> | 20 | #include <linux/capability.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include <linux/ptrace.h> | 21 | #include <linux/ptrace.h> |
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
24 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
@@ -552,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, | |||
552 | return virtr + wrote; | 551 | return virtr + wrote; |
553 | } | 552 | } |
554 | 553 | ||
555 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 554 | #ifdef CONFIG_DEVPORT |
556 | static ssize_t read_port(struct file * file, char __user * buf, | 555 | static ssize_t read_port(struct file * file, char __user * buf, |
557 | size_t count, loff_t *ppos) | 556 | size_t count, loff_t *ppos) |
558 | { | 557 | { |
@@ -835,7 +834,7 @@ static const struct file_operations null_fops = { | |||
835 | .splice_write = splice_write_null, | 834 | .splice_write = splice_write_null, |
836 | }; | 835 | }; |
837 | 836 | ||
838 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 837 | #ifdef CONFIG_DEVPORT |
839 | static const struct file_operations port_fops = { | 838 | static const struct file_operations port_fops = { |
840 | .llseek = memory_lseek, | 839 | .llseek = memory_lseek, |
841 | .read = read_port, | 840 | .read = read_port, |
@@ -913,7 +912,7 @@ static int memory_open(struct inode * inode, struct file * filp) | |||
913 | case 3: | 912 | case 3: |
914 | filp->f_op = &null_fops; | 913 | filp->f_op = &null_fops; |
915 | break; | 914 | break; |
916 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 915 | #ifdef CONFIG_DEVPORT |
917 | case 4: | 916 | case 4: |
918 | filp->f_op = &port_fops; | 917 | filp->f_op = &port_fops; |
919 | break; | 918 | break; |
@@ -960,7 +959,7 @@ static const struct { | |||
960 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, | 959 | {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, |
961 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, | 960 | {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, |
962 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, | 961 | {3, "null", S_IRUGO | S_IWUGO, &null_fops}, |
963 | #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) | 962 | #ifdef CONFIG_DEVPORT |
964 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, | 963 | {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, |
965 | #endif | 964 | #endif |
966 | {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, | 965 | {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, |
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 7e975f606924..4e6fb9651a16 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/kernel.h> | 41 | #include <linux/kernel.h> |
42 | #include <linux/major.h> | 42 | #include <linux/major.h> |
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <linux/mutex.h> | ||
44 | #include <linux/proc_fs.h> | 45 | #include <linux/proc_fs.h> |
45 | #include <linux/seq_file.h> | 46 | #include <linux/seq_file.h> |
46 | #include <linux/stat.h> | 47 | #include <linux/stat.h> |
@@ -53,7 +54,7 @@ | |||
53 | * Head entry for the doubly linked miscdevice list | 54 | * Head entry for the doubly linked miscdevice list |
54 | */ | 55 | */ |
55 | static LIST_HEAD(misc_list); | 56 | static LIST_HEAD(misc_list); |
56 | static DECLARE_MUTEX(misc_sem); | 57 | static DEFINE_MUTEX(misc_mtx); |
57 | 58 | ||
58 | /* | 59 | /* |
59 | * Assigned numbers, used for dynamic minors | 60 | * Assigned numbers, used for dynamic minors |
@@ -69,7 +70,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos) | |||
69 | struct miscdevice *p; | 70 | struct miscdevice *p; |
70 | loff_t off = 0; | 71 | loff_t off = 0; |
71 | 72 | ||
72 | down(&misc_sem); | 73 | mutex_lock(&misc_mtx); |
73 | list_for_each_entry(p, &misc_list, list) { | 74 | list_for_each_entry(p, &misc_list, list) { |
74 | if (*pos == off++) | 75 | if (*pos == off++) |
75 | return p; | 76 | return p; |
@@ -89,7 +90,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
89 | 90 | ||
90 | static void misc_seq_stop(struct seq_file *seq, void *v) | 91 | static void misc_seq_stop(struct seq_file *seq, void *v) |
91 | { | 92 | { |
92 | up(&misc_sem); | 93 | mutex_unlock(&misc_mtx); |
93 | } | 94 | } |
94 | 95 | ||
95 | static int misc_seq_show(struct seq_file *seq, void *v) | 96 | static int misc_seq_show(struct seq_file *seq, void *v) |
@@ -129,7 +130,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
129 | int err = -ENODEV; | 130 | int err = -ENODEV; |
130 | const struct file_operations *old_fops, *new_fops = NULL; | 131 | const struct file_operations *old_fops, *new_fops = NULL; |
131 | 132 | ||
132 | down(&misc_sem); | 133 | mutex_lock(&misc_mtx); |
133 | 134 | ||
134 | list_for_each_entry(c, &misc_list, list) { | 135 | list_for_each_entry(c, &misc_list, list) { |
135 | if (c->minor == minor) { | 136 | if (c->minor == minor) { |
@@ -139,9 +140,9 @@ static int misc_open(struct inode * inode, struct file * file) | |||
139 | } | 140 | } |
140 | 141 | ||
141 | if (!new_fops) { | 142 | if (!new_fops) { |
142 | up(&misc_sem); | 143 | mutex_unlock(&misc_mtx); |
143 | request_module("char-major-%d-%d", MISC_MAJOR, minor); | 144 | request_module("char-major-%d-%d", MISC_MAJOR, minor); |
144 | down(&misc_sem); | 145 | mutex_lock(&misc_mtx); |
145 | 146 | ||
146 | list_for_each_entry(c, &misc_list, list) { | 147 | list_for_each_entry(c, &misc_list, list) { |
147 | if (c->minor == minor) { | 148 | if (c->minor == minor) { |
@@ -165,7 +166,7 @@ static int misc_open(struct inode * inode, struct file * file) | |||
165 | } | 166 | } |
166 | fops_put(old_fops); | 167 | fops_put(old_fops); |
167 | fail: | 168 | fail: |
168 | up(&misc_sem); | 169 | mutex_unlock(&misc_mtx); |
169 | return err; | 170 | return err; |
170 | } | 171 | } |
171 | 172 | ||
@@ -201,10 +202,10 @@ int misc_register(struct miscdevice * misc) | |||
201 | 202 | ||
202 | INIT_LIST_HEAD(&misc->list); | 203 | INIT_LIST_HEAD(&misc->list); |
203 | 204 | ||
204 | down(&misc_sem); | 205 | mutex_lock(&misc_mtx); |
205 | list_for_each_entry(c, &misc_list, list) { | 206 | list_for_each_entry(c, &misc_list, list) { |
206 | if (c->minor == misc->minor) { | 207 | if (c->minor == misc->minor) { |
207 | up(&misc_sem); | 208 | mutex_unlock(&misc_mtx); |
208 | return -EBUSY; | 209 | return -EBUSY; |
209 | } | 210 | } |
210 | } | 211 | } |
@@ -215,7 +216,7 @@ int misc_register(struct miscdevice * misc) | |||
215 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) | 216 | if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) |
216 | break; | 217 | break; |
217 | if (i<0) { | 218 | if (i<0) { |
218 | up(&misc_sem); | 219 | mutex_unlock(&misc_mtx); |
219 | return -EBUSY; | 220 | return -EBUSY; |
220 | } | 221 | } |
221 | misc->minor = i; | 222 | misc->minor = i; |
@@ -238,7 +239,7 @@ int misc_register(struct miscdevice * misc) | |||
238 | */ | 239 | */ |
239 | list_add(&misc->list, &misc_list); | 240 | list_add(&misc->list, &misc_list); |
240 | out: | 241 | out: |
241 | up(&misc_sem); | 242 | mutex_unlock(&misc_mtx); |
242 | return err; | 243 | return err; |
243 | } | 244 | } |
244 | 245 | ||
@@ -259,13 +260,13 @@ int misc_deregister(struct miscdevice * misc) | |||
259 | if (list_empty(&misc->list)) | 260 | if (list_empty(&misc->list)) |
260 | return -EINVAL; | 261 | return -EINVAL; |
261 | 262 | ||
262 | down(&misc_sem); | 263 | mutex_lock(&misc_mtx); |
263 | list_del(&misc->list); | 264 | list_del(&misc->list); |
264 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); | 265 | device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); |
265 | if (i < DYNAMIC_MINORS && i>0) { | 266 | if (i < DYNAMIC_MINORS && i>0) { |
266 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); | 267 | misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); |
267 | } | 268 | } |
268 | up(&misc_sem); | 269 | mutex_unlock(&misc_mtx); |
269 | return 0; | 270 | return 0; |
270 | } | 271 | } |
271 | 272 | ||
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 7dbaee8d9402..e0d35c20c04f 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -1582,7 +1582,7 @@ copy: | |||
1582 | 1582 | ||
1583 | if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) | 1583 | if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) |
1584 | return -EFAULT; | 1584 | return -EFAULT; |
1585 | if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) | 1585 | if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0) |
1586 | return -EINVAL; | 1586 | return -EINVAL; |
1587 | 1587 | ||
1588 | switch(cmd) | 1588 | switch(cmd) |
@@ -2529,6 +2529,8 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len) | |||
2529 | void __iomem *baseAddr; | 2529 | void __iomem *baseAddr; |
2530 | int i; | 2530 | int i; |
2531 | 2531 | ||
2532 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2533 | return -EINVAL; | ||
2532 | if(copy_from_user(moxaBuff, tmp, len)) | 2534 | if(copy_from_user(moxaBuff, tmp, len)) |
2533 | return -EFAULT; | 2535 | return -EFAULT; |
2534 | baseAddr = moxa_boards[cardno].basemem; | 2536 | baseAddr = moxa_boards[cardno].basemem; |
@@ -2576,7 +2578,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len) | |||
2576 | void __iomem *baseAddr; | 2578 | void __iomem *baseAddr; |
2577 | int i; | 2579 | int i; |
2578 | 2580 | ||
2579 | if(len > sizeof(moxaBuff)) | 2581 | if(len < 0 || len > sizeof(moxaBuff)) |
2580 | return -EINVAL; | 2582 | return -EINVAL; |
2581 | if(copy_from_user(moxaBuff, tmp, len)) | 2583 | if(copy_from_user(moxaBuff, tmp, len)) |
2582 | return -EFAULT; | 2584 | return -EFAULT; |
@@ -2596,6 +2598,8 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len) | |||
2596 | void __iomem *baseAddr, *ofsAddr; | 2598 | void __iomem *baseAddr, *ofsAddr; |
2597 | int retval, port, i; | 2599 | int retval, port, i; |
2598 | 2600 | ||
2601 | if(len < 0 || len > sizeof(moxaBuff)) | ||
2602 | return -EINVAL; | ||
2599 | if(copy_from_user(moxaBuff, tmp, len)) | 2603 | if(copy_from_user(moxaBuff, tmp, len)) |
2600 | return -EFAULT; | 2604 | return -EFAULT; |
2601 | baseAddr = moxa_boards[cardno].basemem; | 2605 | baseAddr = moxa_boards[cardno].basemem; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 80a01150b86c..5953a45d7e96 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -54,7 +54,6 @@ | |||
54 | #include <linux/gfp.h> | 54 | #include <linux/gfp.h> |
55 | #include <linux/ioport.h> | 55 | #include <linux/ioport.h> |
56 | #include <linux/mm.h> | 56 | #include <linux/mm.h> |
57 | #include <linux/smp_lock.h> | ||
58 | #include <linux/delay.h> | 57 | #include <linux/delay.h> |
59 | #include <linux/pci.h> | 58 | #include <linux/pci.h> |
60 | 59 | ||
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index f7603b6aeb87..6cde448cd5b2 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/gfp.h> | 37 | #include <linux/gfp.h> |
38 | #include <linux/ioport.h> | 38 | #include <linux/ioport.h> |
39 | #include <linux/mm.h> | 39 | #include <linux/mm.h> |
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
42 | #include <linux/pci.h> | 41 | #include <linux/pci.h> |
43 | 42 | ||
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 65f2d3a96b85..14557a4822c0 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -1088,13 +1088,13 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1088 | /* block until there is a message: */ | 1088 | /* block until there is a message: */ |
1089 | add_wait_queue(&pInfo->read_wait, &wait); | 1089 | add_wait_queue(&pInfo->read_wait, &wait); |
1090 | repeat: | 1090 | repeat: |
1091 | current->state = TASK_INTERRUPTIBLE; | 1091 | __set_current_state(TASK_INTERRUPTIBLE); |
1092 | pMsg = remove_msg(pInfo, pClient); | 1092 | pMsg = remove_msg(pInfo, pClient); |
1093 | if (!pMsg && !signal_pending(current)) { | 1093 | if (!pMsg && !signal_pending(current)) { |
1094 | schedule(); | 1094 | schedule(); |
1095 | goto repeat; | 1095 | goto repeat; |
1096 | } | 1096 | } |
1097 | current->state = TASK_RUNNING; | 1097 | __set_current_state(TASK_RUNNING); |
1098 | remove_wait_queue(&pInfo->read_wait, &wait); | 1098 | remove_wait_queue(&pInfo->read_wait, &wait); |
1099 | } | 1099 | } |
1100 | 1100 | ||
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 4abd1eff61d6..84ac64fc48a1 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #include <linux/poll.h> | 66 | #include <linux/poll.h> |
67 | #include <linux/major.h> | 67 | #include <linux/major.h> |
68 | #include <linux/ppdev.h> | 68 | #include <linux/ppdev.h> |
69 | #include <linux/smp_lock.h> | ||
70 | #include <linux/device.h> | 69 | #include <linux/device.h> |
71 | #include <asm/uaccess.h> | 70 | #include <asm/uaccess.h> |
72 | 71 | ||
@@ -752,7 +751,7 @@ static const struct file_operations pp_fops = { | |||
752 | 751 | ||
753 | static void pp_attach(struct parport *port) | 752 | static void pp_attach(struct parport *port) |
754 | { | 753 | { |
755 | device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), | 754 | device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number), |
756 | "parport%d", port->number); | 755 | "parport%d", port->number); |
757 | } | 756 | } |
758 | 757 | ||
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 70145254fb9d..3494e3fc44bf 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -980,7 +980,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
980 | } | 980 | } |
981 | schedule(); | 981 | schedule(); |
982 | } | 982 | } |
983 | current->state = TASK_RUNNING; | 983 | __set_current_state(TASK_RUNNING); |
984 | remove_wait_queue(&port->open_wait, &wait); | 984 | remove_wait_queue(&port->open_wait, &wait); |
985 | if (!tty_hung_up_p(filp)) | 985 | if (!tty_hung_up_p(filp)) |
986 | port->count++; | 986 | port->count++; |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 76357c855ce3..61a63da420c2 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -65,10 +65,6 @@ | |||
65 | 65 | ||
66 | /****** Kernel includes ******/ | 66 | /****** Kernel includes ******/ |
67 | 67 | ||
68 | #ifdef MODVERSIONS | ||
69 | #include <config/modversions.h> | ||
70 | #endif | ||
71 | |||
72 | #include <linux/module.h> | 68 | #include <linux/module.h> |
73 | #include <linux/errno.h> | 69 | #include <linux/errno.h> |
74 | #include <linux/major.h> | 70 | #include <linux/major.h> |
@@ -85,6 +81,7 @@ | |||
85 | #include <linux/string.h> | 81 | #include <linux/string.h> |
86 | #include <linux/fcntl.h> | 82 | #include <linux/fcntl.h> |
87 | #include <linux/ptrace.h> | 83 | #include <linux/ptrace.h> |
84 | #include <linux/mutex.h> | ||
88 | #include <linux/ioport.h> | 85 | #include <linux/ioport.h> |
89 | #include <linux/delay.h> | 86 | #include <linux/delay.h> |
90 | #include <linux/wait.h> | 87 | #include <linux/wait.h> |
@@ -93,7 +90,6 @@ | |||
93 | #include <asm/atomic.h> | 90 | #include <asm/atomic.h> |
94 | #include <linux/bitops.h> | 91 | #include <linux/bitops.h> |
95 | #include <linux/spinlock.h> | 92 | #include <linux/spinlock.h> |
96 | #include <asm/semaphore.h> | ||
97 | #include <linux/init.h> | 93 | #include <linux/init.h> |
98 | 94 | ||
99 | /****** RocketPort includes ******/ | 95 | /****** RocketPort includes ******/ |
@@ -702,7 +698,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
702 | } | 698 | } |
703 | } | 699 | } |
704 | spin_lock_init(&info->slock); | 700 | spin_lock_init(&info->slock); |
705 | sema_init(&info->write_sem, 1); | 701 | mutex_init(&info->write_mtx); |
706 | rp_table[line] = info; | 702 | rp_table[line] = info; |
707 | if (pci_dev) | 703 | if (pci_dev) |
708 | tty_register_device(rocket_driver, line, &pci_dev->dev); | 704 | tty_register_device(rocket_driver, line, &pci_dev->dev); |
@@ -947,7 +943,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
947 | #endif | 943 | #endif |
948 | schedule(); /* Don't hold spinlock here, will hang PC */ | 944 | schedule(); /* Don't hold spinlock here, will hang PC */ |
949 | } | 945 | } |
950 | current->state = TASK_RUNNING; | 946 | __set_current_state(TASK_RUNNING); |
951 | remove_wait_queue(&info->open_wait, &wait); | 947 | remove_wait_queue(&info->open_wait, &wait); |
952 | 948 | ||
953 | spin_lock_irqsave(&info->slock, flags); | 949 | spin_lock_irqsave(&info->slock, flags); |
@@ -1602,7 +1598,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout) | |||
1602 | if (signal_pending(current)) | 1598 | if (signal_pending(current)) |
1603 | break; | 1599 | break; |
1604 | } | 1600 | } |
1605 | current->state = TASK_RUNNING; | 1601 | __set_current_state(TASK_RUNNING); |
1606 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT | 1602 | #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT |
1607 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); | 1603 | printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); |
1608 | #endif | 1604 | #endif |
@@ -1661,8 +1657,11 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1661 | if (rocket_paranoia_check(info, "rp_put_char")) | 1657 | if (rocket_paranoia_check(info, "rp_put_char")) |
1662 | return; | 1658 | return; |
1663 | 1659 | ||
1664 | /* Grab the port write semaphore, locking out other processes that try to write to this port */ | 1660 | /* |
1665 | down(&info->write_sem); | 1661 | * Grab the port write mutex, locking out other processes that try to |
1662 | * write to this port | ||
1663 | */ | ||
1664 | mutex_lock(&info->write_mtx); | ||
1666 | 1665 | ||
1667 | #ifdef ROCKET_DEBUG_WRITE | 1666 | #ifdef ROCKET_DEBUG_WRITE |
1668 | printk(KERN_INFO "rp_put_char %c...", ch); | 1667 | printk(KERN_INFO "rp_put_char %c...", ch); |
@@ -1684,12 +1683,12 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch) | |||
1684 | info->xmit_fifo_room--; | 1683 | info->xmit_fifo_room--; |
1685 | } | 1684 | } |
1686 | spin_unlock_irqrestore(&info->slock, flags); | 1685 | spin_unlock_irqrestore(&info->slock, flags); |
1687 | up(&info->write_sem); | 1686 | mutex_unlock(&info->write_mtx); |
1688 | } | 1687 | } |
1689 | 1688 | ||
1690 | /* | 1689 | /* |
1691 | * Exception handler - write routine, called when user app writes to the device. | 1690 | * Exception handler - write routine, called when user app writes to the device. |
1692 | * A per port write semaphore is used to protect from another process writing to | 1691 | * A per port write mutex is used to protect from another process writing to |
1693 | * this port at the same time. This other process could be running on the other CPU | 1692 | * this port at the same time. This other process could be running on the other CPU |
1694 | * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). | 1693 | * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). |
1695 | * Spinlocks protect the info xmit members. | 1694 | * Spinlocks protect the info xmit members. |
@@ -1706,7 +1705,7 @@ static int rp_write(struct tty_struct *tty, | |||
1706 | if (count <= 0 || rocket_paranoia_check(info, "rp_write")) | 1705 | if (count <= 0 || rocket_paranoia_check(info, "rp_write")) |
1707 | return 0; | 1706 | return 0; |
1708 | 1707 | ||
1709 | down_interruptible(&info->write_sem); | 1708 | mutex_lock_interruptible(&info->write_mtx); |
1710 | 1709 | ||
1711 | #ifdef ROCKET_DEBUG_WRITE | 1710 | #ifdef ROCKET_DEBUG_WRITE |
1712 | printk(KERN_INFO "rp_write %d chars...", count); | 1711 | printk(KERN_INFO "rp_write %d chars...", count); |
@@ -1777,7 +1776,7 @@ end: | |||
1777 | wake_up_interruptible(&tty->poll_wait); | 1776 | wake_up_interruptible(&tty->poll_wait); |
1778 | #endif | 1777 | #endif |
1779 | } | 1778 | } |
1780 | up(&info->write_sem); | 1779 | mutex_unlock(&info->write_mtx); |
1781 | return retval; | 1780 | return retval; |
1782 | } | 1781 | } |
1783 | 1782 | ||
@@ -1852,6 +1851,12 @@ static void rp_flush_buffer(struct tty_struct *tty) | |||
1852 | 1851 | ||
1853 | #ifdef CONFIG_PCI | 1852 | #ifdef CONFIG_PCI |
1854 | 1853 | ||
1854 | static struct pci_device_id __devinitdata rocket_pci_ids[] = { | ||
1855 | { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) }, | ||
1856 | { } | ||
1857 | }; | ||
1858 | MODULE_DEVICE_TABLE(pci, rocket_pci_ids); | ||
1859 | |||
1855 | /* | 1860 | /* |
1856 | * Called when a PCI card is found. Retrieves and stores model information, | 1861 | * Called when a PCI card is found. Retrieves and stores model information, |
1857 | * init's aiopic and serial port hardware. | 1862 | * init's aiopic and serial port hardware. |
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h index 3a8bcc85bc14..89b4d7b10d12 100644 --- a/drivers/char/rocket_int.h +++ b/drivers/char/rocket_int.h | |||
@@ -15,6 +15,8 @@ | |||
15 | #define ROCKET_TYPE_MODEMIII 3 | 15 | #define ROCKET_TYPE_MODEMIII 3 |
16 | #define ROCKET_TYPE_PC104 4 | 16 | #define ROCKET_TYPE_PC104 4 |
17 | 17 | ||
18 | #include <linux/mutex.h> | ||
19 | |||
18 | #include <asm/io.h> | 20 | #include <asm/io.h> |
19 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
20 | 22 | ||
@@ -1171,7 +1173,7 @@ struct r_port { | |||
1171 | struct wait_queue *close_wait; | 1173 | struct wait_queue *close_wait; |
1172 | #endif | 1174 | #endif |
1173 | spinlock_t slock; | 1175 | spinlock_t slock; |
1174 | struct semaphore write_sem; | 1176 | struct mutex write_mtx; |
1175 | }; | 1177 | }; |
1176 | 1178 | ||
1177 | #define RPORT_MAGIC 0x525001 | 1179 | #define RPORT_MAGIC 0x525001 |
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index c7dac9b13351..20380a2c4dee 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
@@ -388,7 +388,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf, | |||
388 | if (!retval) | 388 | if (!retval) |
389 | retval = count; | 389 | retval = count; |
390 | out: | 390 | out: |
391 | current->state = TASK_RUNNING; | 391 | __set_current_state(TASK_RUNNING); |
392 | remove_wait_queue(&rtc_wait, &wait); | 392 | remove_wait_queue(&rtc_wait, &wait); |
393 | 393 | ||
394 | return retval; | 394 | return retval; |
diff --git a/drivers/char/selection.c b/drivers/char/selection.c index 74cff839c857..a69f094d1ed3 100644 --- a/drivers/char/selection.c +++ b/drivers/char/selection.c | |||
@@ -299,7 +299,7 @@ int paste_selection(struct tty_struct *tty) | |||
299 | pasted += count; | 299 | pasted += count; |
300 | } | 300 | } |
301 | remove_wait_queue(&vc->paste_wait, &wait); | 301 | remove_wait_queue(&vc->paste_wait, &wait); |
302 | current->state = TASK_RUNNING; | 302 | __set_current_state(TASK_RUNNING); |
303 | 303 | ||
304 | tty_ldisc_deref(ld); | 304 | tty_ldisc_deref(ld); |
305 | return 0; | 305 | return 0; |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 5fd314adc1f2..c585b4738f86 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1892,7 +1892,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp, | |||
1892 | #endif | 1892 | #endif |
1893 | schedule(); | 1893 | schedule(); |
1894 | } | 1894 | } |
1895 | current->state = TASK_RUNNING; | 1895 | __set_current_state(TASK_RUNNING); |
1896 | remove_wait_queue(&info->open_wait, &wait); | 1896 | remove_wait_queue(&info->open_wait, &wait); |
1897 | if (!tty_hung_up_p(filp)) { | 1897 | if (!tty_hung_up_p(filp)) { |
1898 | info->count++; | 1898 | info->count++; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index ce4db6f52362..f02a0795983f 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -4010,8 +4010,13 @@ static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info) | |||
4010 | for ( i=0; i<info->num_tx_holding_buffers; ++i) { | 4010 | for ( i=0; i<info->num_tx_holding_buffers; ++i) { |
4011 | info->tx_holding_buffers[i].buffer = | 4011 | info->tx_holding_buffers[i].buffer = |
4012 | kmalloc(info->max_frame_size, GFP_KERNEL); | 4012 | kmalloc(info->max_frame_size, GFP_KERNEL); |
4013 | if ( info->tx_holding_buffers[i].buffer == NULL ) | 4013 | if (info->tx_holding_buffers[i].buffer == NULL) { |
4014 | for (--i; i >= 0; i--) { | ||
4015 | kfree(info->tx_holding_buffers[i].buffer); | ||
4016 | info->tx_holding_buffers[i].buffer = NULL; | ||
4017 | } | ||
4014 | return -ENOMEM; | 4018 | return -ENOMEM; |
4019 | } | ||
4015 | } | 4020 | } |
4016 | 4021 | ||
4017 | return 0; | 4022 | return 0; |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 0a367cd4121f..2a7736b5f2f7 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -3415,6 +3415,9 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3415 | } | 3415 | } |
3416 | } | 3416 | } |
3417 | } | 3417 | } |
3418 | |||
3419 | for (i=0; i < port_count; ++i) | ||
3420 | tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); | ||
3418 | } | 3421 | } |
3419 | 3422 | ||
3420 | static int __devinit init_one(struct pci_dev *dev, | 3423 | static int __devinit init_one(struct pci_dev *dev, |
@@ -3466,6 +3469,8 @@ static void slgt_cleanup(void) | |||
3466 | printk("unload %s %s\n", driver_name, driver_version); | 3469 | printk("unload %s %s\n", driver_name, driver_version); |
3467 | 3470 | ||
3468 | if (serial_driver) { | 3471 | if (serial_driver) { |
3472 | for (info=slgt_device_list ; info != NULL ; info=info->next_device) | ||
3473 | tty_unregister_device(serial_driver, info->line); | ||
3469 | if ((rc = tty_unregister_driver(serial_driver))) | 3474 | if ((rc = tty_unregister_driver(serial_driver))) |
3470 | DBGERR(("tty_unregister_driver error=%d\n", rc)); | 3475 | DBGERR(("tty_unregister_driver error=%d\n", rc)); |
3471 | put_tty_driver(serial_driver); | 3476 | put_tty_driver(serial_driver); |
@@ -3506,23 +3511,10 @@ static int __init slgt_init(void) | |||
3506 | 3511 | ||
3507 | printk("%s %s\n", driver_name, driver_version); | 3512 | printk("%s %s\n", driver_name, driver_version); |
3508 | 3513 | ||
3509 | slgt_device_count = 0; | ||
3510 | if ((rc = pci_register_driver(&pci_driver)) < 0) { | ||
3511 | printk("%s pci_register_driver error=%d\n", driver_name, rc); | ||
3512 | return rc; | ||
3513 | } | ||
3514 | pci_registered = 1; | ||
3515 | |||
3516 | if (!slgt_device_list) { | ||
3517 | printk("%s no devices found\n",driver_name); | ||
3518 | pci_unregister_driver(&pci_driver); | ||
3519 | return -ENODEV; | ||
3520 | } | ||
3521 | |||
3522 | serial_driver = alloc_tty_driver(MAX_DEVICES); | 3514 | serial_driver = alloc_tty_driver(MAX_DEVICES); |
3523 | if (!serial_driver) { | 3515 | if (!serial_driver) { |
3524 | rc = -ENOMEM; | 3516 | printk("%s can't allocate tty driver\n", driver_name); |
3525 | goto error; | 3517 | return -ENOMEM; |
3526 | } | 3518 | } |
3527 | 3519 | ||
3528 | /* Initialize the tty_driver structure */ | 3520 | /* Initialize the tty_driver structure */ |
@@ -3539,7 +3531,7 @@ static int __init slgt_init(void) | |||
3539 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 3531 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
3540 | serial_driver->init_termios.c_ispeed = 9600; | 3532 | serial_driver->init_termios.c_ispeed = 9600; |
3541 | serial_driver->init_termios.c_ospeed = 9600; | 3533 | serial_driver->init_termios.c_ospeed = 9600; |
3542 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 3534 | serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
3543 | tty_set_operations(serial_driver, &ops); | 3535 | tty_set_operations(serial_driver, &ops); |
3544 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 3536 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
3545 | DBGERR(("%s can't register serial driver\n", driver_name)); | 3537 | DBGERR(("%s can't register serial driver\n", driver_name)); |
@@ -3552,6 +3544,16 @@ static int __init slgt_init(void) | |||
3552 | driver_name, driver_version, | 3544 | driver_name, driver_version, |
3553 | serial_driver->major); | 3545 | serial_driver->major); |
3554 | 3546 | ||
3547 | slgt_device_count = 0; | ||
3548 | if ((rc = pci_register_driver(&pci_driver)) < 0) { | ||
3549 | printk("%s pci_register_driver error=%d\n", driver_name, rc); | ||
3550 | goto error; | ||
3551 | } | ||
3552 | pci_registered = 1; | ||
3553 | |||
3554 | if (!slgt_device_list) | ||
3555 | printk("%s no devices found\n",driver_name); | ||
3556 | |||
3555 | return 0; | 3557 | return 0; |
3556 | 3558 | ||
3557 | error: | 3559 | error: |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1d8c4ae61551..39cc318011ea 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/sysrq.h> | 24 | #include <linux/sysrq.h> |
25 | #include <linux/kbd_kern.h> | 25 | #include <linux/kbd_kern.h> |
26 | #include <linux/quotaops.h> | 26 | #include <linux/quotaops.h> |
27 | #include <linux/smp_lock.h> | ||
28 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 28 | #include <linux/module.h> |
30 | #include <linux/suspend.h> | 29 | #include <linux/suspend.h> |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 47fb20f69695..35b40b996534 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -442,7 +442,7 @@ tipar_register(int nr, struct parport *port) | |||
442 | } | 442 | } |
443 | 443 | ||
444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, | 444 | class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, |
445 | TIPAR_MINOR + nr), NULL, "par%d", nr); | 445 | TIPAR_MINOR + nr), port->dev, "par%d", nr); |
446 | 446 | ||
447 | /* Display informations */ | 447 | /* Display informations */ |
448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == | 448 | pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index e5a254a434f8..9bb542913b86 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -24,7 +24,9 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <linux/spinlock.h> | 28 | #include <linux/spinlock.h> |
29 | |||
28 | #include "tpm.h" | 30 | #include "tpm.h" |
29 | 31 | ||
30 | enum tpm_const { | 32 | enum tpm_const { |
@@ -328,10 +330,10 @@ static void timeout_work(struct work_struct *work) | |||
328 | { | 330 | { |
329 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); | 331 | struct tpm_chip *chip = container_of(work, struct tpm_chip, work); |
330 | 332 | ||
331 | down(&chip->buffer_mutex); | 333 | mutex_lock(&chip->buffer_mutex); |
332 | atomic_set(&chip->data_pending, 0); | 334 | atomic_set(&chip->data_pending, 0); |
333 | memset(chip->data_buffer, 0, TPM_BUFSIZE); | 335 | memset(chip->data_buffer, 0, TPM_BUFSIZE); |
334 | up(&chip->buffer_mutex); | 336 | mutex_unlock(&chip->buffer_mutex); |
335 | } | 337 | } |
336 | 338 | ||
337 | /* | 339 | /* |
@@ -380,7 +382,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
380 | return -E2BIG; | 382 | return -E2BIG; |
381 | } | 383 | } |
382 | 384 | ||
383 | down(&chip->tpm_mutex); | 385 | mutex_lock(&chip->tpm_mutex); |
384 | 386 | ||
385 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { | 387 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { |
386 | dev_err(chip->dev, | 388 | dev_err(chip->dev, |
@@ -419,7 +421,7 @@ out_recv: | |||
419 | dev_err(chip->dev, | 421 | dev_err(chip->dev, |
420 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 422 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
421 | out: | 423 | out: |
422 | up(&chip->tpm_mutex); | 424 | mutex_unlock(&chip->tpm_mutex); |
423 | return rc; | 425 | return rc; |
424 | } | 426 | } |
425 | 427 | ||
@@ -942,12 +944,12 @@ int tpm_release(struct inode *inode, struct file *file) | |||
942 | { | 944 | { |
943 | struct tpm_chip *chip = file->private_data; | 945 | struct tpm_chip *chip = file->private_data; |
944 | 946 | ||
947 | flush_scheduled_work(); | ||
945 | spin_lock(&driver_lock); | 948 | spin_lock(&driver_lock); |
946 | file->private_data = NULL; | 949 | file->private_data = NULL; |
947 | chip->num_opens--; | ||
948 | del_singleshot_timer_sync(&chip->user_read_timer); | 950 | del_singleshot_timer_sync(&chip->user_read_timer); |
949 | flush_scheduled_work(); | ||
950 | atomic_set(&chip->data_pending, 0); | 951 | atomic_set(&chip->data_pending, 0); |
952 | chip->num_opens--; | ||
951 | put_device(chip->dev); | 953 | put_device(chip->dev); |
952 | kfree(chip->data_buffer); | 954 | kfree(chip->data_buffer); |
953 | spin_unlock(&driver_lock); | 955 | spin_unlock(&driver_lock); |
@@ -966,14 +968,14 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
966 | while (atomic_read(&chip->data_pending) != 0) | 968 | while (atomic_read(&chip->data_pending) != 0) |
967 | msleep(TPM_TIMEOUT); | 969 | msleep(TPM_TIMEOUT); |
968 | 970 | ||
969 | down(&chip->buffer_mutex); | 971 | mutex_lock(&chip->buffer_mutex); |
970 | 972 | ||
971 | if (in_size > TPM_BUFSIZE) | 973 | if (in_size > TPM_BUFSIZE) |
972 | in_size = TPM_BUFSIZE; | 974 | in_size = TPM_BUFSIZE; |
973 | 975 | ||
974 | if (copy_from_user | 976 | if (copy_from_user |
975 | (chip->data_buffer, (void __user *) buf, in_size)) { | 977 | (chip->data_buffer, (void __user *) buf, in_size)) { |
976 | up(&chip->buffer_mutex); | 978 | mutex_unlock(&chip->buffer_mutex); |
977 | return -EFAULT; | 979 | return -EFAULT; |
978 | } | 980 | } |
979 | 981 | ||
@@ -981,7 +983,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
981 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); | 983 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); |
982 | 984 | ||
983 | atomic_set(&chip->data_pending, out_size); | 985 | atomic_set(&chip->data_pending, out_size); |
984 | up(&chip->buffer_mutex); | 986 | mutex_unlock(&chip->buffer_mutex); |
985 | 987 | ||
986 | /* Set a timeout by which the reader must come claim the result */ | 988 | /* Set a timeout by which the reader must come claim the result */ |
987 | mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); | 989 | mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); |
@@ -1004,10 +1006,10 @@ ssize_t tpm_read(struct file *file, char __user *buf, | |||
1004 | if (size < ret_size) | 1006 | if (size < ret_size) |
1005 | ret_size = size; | 1007 | ret_size = size; |
1006 | 1008 | ||
1007 | down(&chip->buffer_mutex); | 1009 | mutex_lock(&chip->buffer_mutex); |
1008 | if (copy_to_user(buf, chip->data_buffer, ret_size)) | 1010 | if (copy_to_user(buf, chip->data_buffer, ret_size)) |
1009 | ret_size = -EFAULT; | 1011 | ret_size = -EFAULT; |
1010 | up(&chip->buffer_mutex); | 1012 | mutex_unlock(&chip->buffer_mutex); |
1011 | } | 1013 | } |
1012 | 1014 | ||
1013 | return ret_size; | 1015 | return ret_size; |
@@ -1097,11 +1099,16 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1097 | 1099 | ||
1098 | /* Driver specific per-device data */ | 1100 | /* Driver specific per-device data */ |
1099 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1101 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
1100 | if (chip == NULL) | 1102 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); |
1103 | |||
1104 | if (chip == NULL || devname == NULL) { | ||
1105 | kfree(chip); | ||
1106 | kfree(devname); | ||
1101 | return NULL; | 1107 | return NULL; |
1108 | } | ||
1102 | 1109 | ||
1103 | init_MUTEX(&chip->buffer_mutex); | 1110 | mutex_init(&chip->buffer_mutex); |
1104 | init_MUTEX(&chip->tpm_mutex); | 1111 | mutex_init(&chip->tpm_mutex); |
1105 | INIT_LIST_HEAD(&chip->list); | 1112 | INIT_LIST_HEAD(&chip->list); |
1106 | 1113 | ||
1107 | INIT_WORK(&chip->work, timeout_work); | 1114 | INIT_WORK(&chip->work, timeout_work); |
@@ -1124,7 +1131,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1124 | 1131 | ||
1125 | set_bit(chip->dev_num, dev_mask); | 1132 | set_bit(chip->dev_num, dev_mask); |
1126 | 1133 | ||
1127 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); | ||
1128 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 1134 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
1129 | chip->vendor.miscdev.name = devname; | 1135 | chip->vendor.miscdev.name = devname; |
1130 | 1136 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 9f273f032b0f..b2e2b002a1bb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/mutex.h> | ||
24 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
25 | #include <linux/miscdevice.h> | 26 | #include <linux/miscdevice.h> |
26 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
@@ -94,11 +95,11 @@ struct tpm_chip { | |||
94 | /* Data passed to and from the tpm via the read/write calls */ | 95 | /* Data passed to and from the tpm via the read/write calls */ |
95 | u8 *data_buffer; | 96 | u8 *data_buffer; |
96 | atomic_t data_pending; | 97 | atomic_t data_pending; |
97 | struct semaphore buffer_mutex; | 98 | struct mutex buffer_mutex; |
98 | 99 | ||
99 | struct timer_list user_read_timer; /* user needs to claim result */ | 100 | struct timer_list user_read_timer; /* user needs to claim result */ |
100 | struct work_struct work; | 101 | struct work_struct work; |
101 | struct semaphore tpm_mutex; /* tpm is processing */ | 102 | struct mutex tpm_mutex; /* tpm is processing */ |
102 | 103 | ||
103 | struct tpm_vendor_specific vendor; | 104 | struct tpm_vendor_specific vendor; |
104 | 105 | ||
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 1353b5a6bae8..967002a5a1e5 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -30,12 +30,60 @@ | |||
30 | #define TPM_MAX_TRIES 5000 | 30 | #define TPM_MAX_TRIES 5000 |
31 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 | 31 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
32 | 32 | ||
33 | /* These values will be filled after PnP-call */ | 33 | #define TPM_INF_IO_PORT 0x0 |
34 | static int TPM_INF_DATA; | 34 | #define TPM_INF_IO_MEM 0x1 |
35 | static int TPM_INF_ADDR; | 35 | |
36 | static int TPM_INF_BASE; | 36 | #define TPM_INF_ADDR 0x0 |
37 | static int TPM_INF_ADDR_LEN; | 37 | #define TPM_INF_DATA 0x1 |
38 | static int TPM_INF_PORT_LEN; | 38 | |
39 | struct tpm_inf_dev { | ||
40 | int iotype; | ||
41 | |||
42 | void __iomem *mem_base; /* MMIO ioremap'd addr */ | ||
43 | unsigned long map_base; /* phys MMIO base */ | ||
44 | unsigned long map_size; /* MMIO region size */ | ||
45 | unsigned int index_off; /* index register offset */ | ||
46 | |||
47 | unsigned int data_regs; /* Data registers */ | ||
48 | unsigned int data_size; | ||
49 | |||
50 | unsigned int config_port; /* IO Port config index reg */ | ||
51 | unsigned int config_size; | ||
52 | }; | ||
53 | |||
54 | static struct tpm_inf_dev tpm_dev; | ||
55 | |||
56 | static inline void tpm_data_out(unsigned char data, unsigned char offset) | ||
57 | { | ||
58 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
59 | outb(data, tpm_dev.data_regs + offset); | ||
60 | else | ||
61 | writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset); | ||
62 | } | ||
63 | |||
64 | static inline unsigned char tpm_data_in(unsigned char offset) | ||
65 | { | ||
66 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
67 | return inb(tpm_dev.data_regs + offset); | ||
68 | else | ||
69 | return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset); | ||
70 | } | ||
71 | |||
72 | static inline void tpm_config_out(unsigned char data, unsigned char offset) | ||
73 | { | ||
74 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
75 | outb(data, tpm_dev.config_port + offset); | ||
76 | else | ||
77 | writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset); | ||
78 | } | ||
79 | |||
80 | static inline unsigned char tpm_config_in(unsigned char offset) | ||
81 | { | ||
82 | if (tpm_dev.iotype == TPM_INF_IO_PORT) | ||
83 | return inb(tpm_dev.config_port + offset); | ||
84 | else | ||
85 | return readb(tpm_dev.mem_base + tpm_dev.index_off + offset); | ||
86 | } | ||
39 | 87 | ||
40 | /* TPM header definitions */ | 88 | /* TPM header definitions */ |
41 | enum infineon_tpm_header { | 89 | enum infineon_tpm_header { |
@@ -105,7 +153,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
105 | 153 | ||
106 | if (clear_wrfifo) { | 154 | if (clear_wrfifo) { |
107 | for (i = 0; i < 4096; i++) { | 155 | for (i = 0; i < 4096; i++) { |
108 | status = inb(chip->vendor.base + WRFIFO); | 156 | status = tpm_data_in(WRFIFO); |
109 | if (status == 0xff) { | 157 | if (status == 0xff) { |
110 | if (check == 5) | 158 | if (check == 5) |
111 | break; | 159 | break; |
@@ -125,8 +173,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
125 | */ | 173 | */ |
126 | i = 0; | 174 | i = 0; |
127 | do { | 175 | do { |
128 | status = inb(chip->vendor.base + RDFIFO); | 176 | status = tpm_data_in(RDFIFO); |
129 | status = inb(chip->vendor.base + STAT); | 177 | status = tpm_data_in(STAT); |
130 | i++; | 178 | i++; |
131 | if (i == TPM_MAX_TRIES) | 179 | if (i == TPM_MAX_TRIES) |
132 | return -EIO; | 180 | return -EIO; |
@@ -139,7 +187,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
139 | int status; | 187 | int status; |
140 | int i; | 188 | int i; |
141 | for (i = 0; i < TPM_MAX_TRIES; i++) { | 189 | for (i = 0; i < TPM_MAX_TRIES; i++) { |
142 | status = inb(chip->vendor.base + STAT); | 190 | status = tpm_data_in(STAT); |
143 | /* check the status-register if wait_for_bit is set */ | 191 | /* check the status-register if wait_for_bit is set */ |
144 | if (status & 1 << wait_for_bit) | 192 | if (status & 1 << wait_for_bit) |
145 | break; | 193 | break; |
@@ -158,7 +206,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
158 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | 206 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) |
159 | { | 207 | { |
160 | wait(chip, STAT_XFE); | 208 | wait(chip, STAT_XFE); |
161 | outb(sendbyte, chip->vendor.base + WRFIFO); | 209 | tpm_data_out(sendbyte, WRFIFO); |
162 | } | 210 | } |
163 | 211 | ||
164 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more | 212 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more |
@@ -205,7 +253,7 @@ recv_begin: | |||
205 | ret = wait(chip, STAT_RDA); | 253 | ret = wait(chip, STAT_RDA); |
206 | if (ret) | 254 | if (ret) |
207 | return -EIO; | 255 | return -EIO; |
208 | buf[i] = inb(chip->vendor.base + RDFIFO); | 256 | buf[i] = tpm_data_in(RDFIFO); |
209 | } | 257 | } |
210 | 258 | ||
211 | if (buf[0] != TPM_VL_VER) { | 259 | if (buf[0] != TPM_VL_VER) { |
@@ -220,7 +268,7 @@ recv_begin: | |||
220 | 268 | ||
221 | for (i = 0; i < size; i++) { | 269 | for (i = 0; i < size; i++) { |
222 | wait(chip, STAT_RDA); | 270 | wait(chip, STAT_RDA); |
223 | buf[i] = inb(chip->vendor.base + RDFIFO); | 271 | buf[i] = tpm_data_in(RDFIFO); |
224 | } | 272 | } |
225 | 273 | ||
226 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 274 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
@@ -269,7 +317,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
269 | u8 count_high, count_low, count_4, count_3, count_2, count_1; | 317 | u8 count_high, count_low, count_4, count_3, count_2, count_1; |
270 | 318 | ||
271 | /* Disabling Reset, LP and IRQC */ | 319 | /* Disabling Reset, LP and IRQC */ |
272 | outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); | 320 | tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); |
273 | 321 | ||
274 | ret = empty_fifo(chip, 1); | 322 | ret = empty_fifo(chip, 1); |
275 | if (ret) { | 323 | if (ret) { |
@@ -320,7 +368,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
320 | 368 | ||
321 | static u8 tpm_inf_status(struct tpm_chip *chip) | 369 | static u8 tpm_inf_status(struct tpm_chip *chip) |
322 | { | 370 | { |
323 | return inb(chip->vendor.base + STAT); | 371 | return tpm_data_in(STAT); |
324 | } | 372 | } |
325 | 373 | ||
326 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 374 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
@@ -381,51 +429,88 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
381 | /* read IO-ports through PnP */ | 429 | /* read IO-ports through PnP */ |
382 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 430 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
383 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { | 431 | !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { |
384 | TPM_INF_ADDR = pnp_port_start(dev, 0); | 432 | |
385 | TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); | 433 | tpm_dev.iotype = TPM_INF_IO_PORT; |
386 | TPM_INF_DATA = (TPM_INF_ADDR + 1); | 434 | |
387 | TPM_INF_BASE = pnp_port_start(dev, 1); | 435 | tpm_dev.config_port = pnp_port_start(dev, 0); |
388 | TPM_INF_PORT_LEN = pnp_port_len(dev, 1); | 436 | tpm_dev.config_size = pnp_port_len(dev, 0); |
389 | if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { | 437 | tpm_dev.data_regs = pnp_port_start(dev, 1); |
438 | tpm_dev.data_size = pnp_port_len(dev, 1); | ||
439 | if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) { | ||
390 | rc = -EINVAL; | 440 | rc = -EINVAL; |
391 | goto err_last; | 441 | goto err_last; |
392 | } | 442 | } |
393 | dev_info(&dev->dev, "Found %s with ID %s\n", | 443 | dev_info(&dev->dev, "Found %s with ID %s\n", |
394 | dev->name, dev_id->id); | 444 | dev->name, dev_id->id); |
395 | if (!((TPM_INF_BASE >> 8) & 0xff)) { | 445 | if (!((tpm_dev.data_regs >> 8) & 0xff)) { |
396 | rc = -EINVAL; | 446 | rc = -EINVAL; |
397 | goto err_last; | 447 | goto err_last; |
398 | } | 448 | } |
399 | /* publish my base address and request region */ | 449 | /* publish my base address and request region */ |
400 | if (request_region | 450 | if (request_region(tpm_dev.data_regs, tpm_dev.data_size, |
401 | (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 451 | "tpm_infineon0") == NULL) { |
402 | rc = -EINVAL; | 452 | rc = -EINVAL; |
403 | goto err_last; | 453 | goto err_last; |
404 | } | 454 | } |
405 | if (request_region | 455 | if (request_region(tpm_dev.config_port, tpm_dev.config_size, |
406 | (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { | 456 | "tpm_infineon0") == NULL) { |
457 | release_region(tpm_dev.data_regs, tpm_dev.data_size); | ||
407 | rc = -EINVAL; | 458 | rc = -EINVAL; |
408 | goto err_last; | 459 | goto err_last; |
409 | } | 460 | } |
461 | } else if (pnp_mem_valid(dev, 0) && | ||
462 | !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) { | ||
463 | |||
464 | tpm_dev.iotype = TPM_INF_IO_MEM; | ||
465 | |||
466 | tpm_dev.map_base = pnp_mem_start(dev, 0); | ||
467 | tpm_dev.map_size = pnp_mem_len(dev, 0); | ||
468 | |||
469 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
470 | dev->name, dev_id->id); | ||
471 | |||
472 | /* publish my base address and request region */ | ||
473 | if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size, | ||
474 | "tpm_infineon0") == NULL) { | ||
475 | rc = -EINVAL; | ||
476 | goto err_last; | ||
477 | } | ||
478 | |||
479 | tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size); | ||
480 | if (tpm_dev.mem_base == NULL) { | ||
481 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
482 | rc = -EINVAL; | ||
483 | goto err_last; | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * The only known MMIO based Infineon TPM system provides | ||
488 | * a single large mem region with the device config | ||
489 | * registers at the default TPM_ADDR. The data registers | ||
490 | * seem like they could be placed anywhere within the MMIO | ||
491 | * region, but lets just put them at zero offset. | ||
492 | */ | ||
493 | tpm_dev.index_off = TPM_ADDR; | ||
494 | tpm_dev.data_regs = 0x0; | ||
410 | } else { | 495 | } else { |
411 | rc = -EINVAL; | 496 | rc = -EINVAL; |
412 | goto err_last; | 497 | goto err_last; |
413 | } | 498 | } |
414 | 499 | ||
415 | /* query chip for its vendor, its version number a.s.o. */ | 500 | /* query chip for its vendor, its version number a.s.o. */ |
416 | outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); | 501 | tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); |
417 | outb(IDVENL, TPM_INF_ADDR); | 502 | tpm_config_out(IDVENL, TPM_INF_ADDR); |
418 | vendorid[1] = inb(TPM_INF_DATA); | 503 | vendorid[1] = tpm_config_in(TPM_INF_DATA); |
419 | outb(IDVENH, TPM_INF_ADDR); | 504 | tpm_config_out(IDVENH, TPM_INF_ADDR); |
420 | vendorid[0] = inb(TPM_INF_DATA); | 505 | vendorid[0] = tpm_config_in(TPM_INF_DATA); |
421 | outb(IDPDL, TPM_INF_ADDR); | 506 | tpm_config_out(IDPDL, TPM_INF_ADDR); |
422 | productid[1] = inb(TPM_INF_DATA); | 507 | productid[1] = tpm_config_in(TPM_INF_DATA); |
423 | outb(IDPDH, TPM_INF_ADDR); | 508 | tpm_config_out(IDPDH, TPM_INF_ADDR); |
424 | productid[0] = inb(TPM_INF_DATA); | 509 | productid[0] = tpm_config_in(TPM_INF_DATA); |
425 | outb(CHIP_ID1, TPM_INF_ADDR); | 510 | tpm_config_out(CHIP_ID1, TPM_INF_ADDR); |
426 | version[1] = inb(TPM_INF_DATA); | 511 | version[1] = tpm_config_in(TPM_INF_DATA); |
427 | outb(CHIP_ID2, TPM_INF_ADDR); | 512 | tpm_config_out(CHIP_ID2, TPM_INF_ADDR); |
428 | version[0] = inb(TPM_INF_DATA); | 513 | version[0] = tpm_config_in(TPM_INF_DATA); |
429 | 514 | ||
430 | switch ((productid[0] << 8) | productid[1]) { | 515 | switch ((productid[0] << 8) | productid[1]) { |
431 | case 6: | 516 | case 6: |
@@ -442,51 +527,54 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
442 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | 527 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { |
443 | 528 | ||
444 | /* configure TPM with IO-ports */ | 529 | /* configure TPM with IO-ports */ |
445 | outb(IOLIMH, TPM_INF_ADDR); | 530 | tpm_config_out(IOLIMH, TPM_INF_ADDR); |
446 | outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); | 531 | tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA); |
447 | outb(IOLIML, TPM_INF_ADDR); | 532 | tpm_config_out(IOLIML, TPM_INF_ADDR); |
448 | outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); | 533 | tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA); |
449 | 534 | ||
450 | /* control if IO-ports are set correctly */ | 535 | /* control if IO-ports are set correctly */ |
451 | outb(IOLIMH, TPM_INF_ADDR); | 536 | tpm_config_out(IOLIMH, TPM_INF_ADDR); |
452 | ioh = inb(TPM_INF_DATA); | 537 | ioh = tpm_config_in(TPM_INF_DATA); |
453 | outb(IOLIML, TPM_INF_ADDR); | 538 | tpm_config_out(IOLIML, TPM_INF_ADDR); |
454 | iol = inb(TPM_INF_DATA); | 539 | iol = tpm_config_in(TPM_INF_DATA); |
455 | 540 | ||
456 | if ((ioh << 8 | iol) != TPM_INF_BASE) { | 541 | if ((ioh << 8 | iol) != tpm_dev.data_regs) { |
457 | dev_err(&dev->dev, | 542 | dev_err(&dev->dev, |
458 | "Could not set IO-ports to 0x%x\n", | 543 | "Could not set IO-data registers to 0x%x\n", |
459 | TPM_INF_BASE); | 544 | tpm_dev.data_regs); |
460 | rc = -EIO; | 545 | rc = -EIO; |
461 | goto err_release_region; | 546 | goto err_release_region; |
462 | } | 547 | } |
463 | 548 | ||
464 | /* activate register */ | 549 | /* activate register */ |
465 | outb(TPM_DAR, TPM_INF_ADDR); | 550 | tpm_config_out(TPM_DAR, TPM_INF_ADDR); |
466 | outb(0x01, TPM_INF_DATA); | 551 | tpm_config_out(0x01, TPM_INF_DATA); |
467 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); | 552 | tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
468 | 553 | ||
469 | /* disable RESET, LP and IRQC */ | 554 | /* disable RESET, LP and IRQC */ |
470 | outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); | 555 | tpm_data_out(RESET_LP_IRQC_DISABLE, CMD); |
471 | 556 | ||
472 | /* Finally, we're done, print some infos */ | 557 | /* Finally, we're done, print some infos */ |
473 | dev_info(&dev->dev, "TPM found: " | 558 | dev_info(&dev->dev, "TPM found: " |
474 | "config base 0x%x, " | 559 | "config base 0x%lx, " |
475 | "io base 0x%x, " | 560 | "data base 0x%lx, " |
476 | "chip version 0x%02x%02x, " | 561 | "chip version 0x%02x%02x, " |
477 | "vendor id 0x%x%x (Infineon), " | 562 | "vendor id 0x%x%x (Infineon), " |
478 | "product id 0x%02x%02x" | 563 | "product id 0x%02x%02x" |
479 | "%s\n", | 564 | "%s\n", |
480 | TPM_INF_ADDR, | 565 | tpm_dev.iotype == TPM_INF_IO_PORT ? |
481 | TPM_INF_BASE, | 566 | tpm_dev.config_port : |
567 | tpm_dev.map_base + tpm_dev.index_off, | ||
568 | tpm_dev.iotype == TPM_INF_IO_PORT ? | ||
569 | tpm_dev.data_regs : | ||
570 | tpm_dev.map_base + tpm_dev.data_regs, | ||
482 | version[0], version[1], | 571 | version[0], version[1], |
483 | vendorid[0], vendorid[1], | 572 | vendorid[0], vendorid[1], |
484 | productid[0], productid[1], chipname); | 573 | productid[0], productid[1], chipname); |
485 | 574 | ||
486 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { | 575 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) |
487 | goto err_release_region; | 576 | goto err_release_region; |
488 | } | 577 | |
489 | chip->vendor.base = TPM_INF_BASE; | ||
490 | return 0; | 578 | return 0; |
491 | } else { | 579 | } else { |
492 | rc = -ENODEV; | 580 | rc = -ENODEV; |
@@ -494,8 +582,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
494 | } | 582 | } |
495 | 583 | ||
496 | err_release_region: | 584 | err_release_region: |
497 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); | 585 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { |
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 586 | release_region(tpm_dev.data_regs, tpm_dev.data_size); |
587 | release_region(tpm_dev.config_port, tpm_dev.config_size); | ||
588 | } else { | ||
589 | iounmap(tpm_dev.mem_base); | ||
590 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
591 | } | ||
499 | 592 | ||
500 | err_last: | 593 | err_last: |
501 | return rc; | 594 | return rc; |
@@ -506,8 +599,14 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
506 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 599 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
507 | 600 | ||
508 | if (chip) { | 601 | if (chip) { |
509 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); | 602 | if (tpm_dev.iotype == TPM_INF_IO_PORT) { |
510 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 603 | release_region(tpm_dev.data_regs, tpm_dev.data_size); |
604 | release_region(tpm_dev.config_port, | ||
605 | tpm_dev.config_size); | ||
606 | } else { | ||
607 | iounmap(tpm_dev.mem_base); | ||
608 | release_mem_region(tpm_dev.map_base, tpm_dev.map_size); | ||
609 | } | ||
511 | tpm_remove_hardware(chip->dev); | 610 | tpm_remove_hardware(chip->dev); |
512 | } | 611 | } |
513 | } | 612 | } |
@@ -539,5 +638,5 @@ module_exit(cleanup_inf); | |||
539 | 638 | ||
540 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 639 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
541 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 640 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
542 | MODULE_VERSION("1.8"); | 641 | MODULE_VERSION("1.9"); |
543 | MODULE_LICENSE("GPL"); | 642 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 389da364e6b6..7710a6a77d97 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -141,8 +141,6 @@ static DECLARE_MUTEX(allocated_ptys_lock); | |||
141 | static int ptmx_open(struct inode *, struct file *); | 141 | static int ptmx_open(struct inode *, struct file *); |
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | extern void disable_early_printk(void); | ||
145 | |||
146 | static void initialize_tty_struct(struct tty_struct *tty); | 144 | static void initialize_tty_struct(struct tty_struct *tty); |
147 | 145 | ||
148 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 146 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
@@ -155,8 +153,8 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
155 | unsigned int cmd, unsigned long arg); | 153 | unsigned int cmd, unsigned long arg); |
156 | static int tty_fasync(int fd, struct file * filp, int on); | 154 | static int tty_fasync(int fd, struct file * filp, int on); |
157 | static void release_tty(struct tty_struct *tty, int idx); | 155 | static void release_tty(struct tty_struct *tty, int idx); |
158 | static struct pid *__proc_set_tty(struct task_struct *tsk, | 156 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
159 | struct tty_struct *tty); | 157 | static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); |
160 | 158 | ||
161 | /** | 159 | /** |
162 | * alloc_tty_struct - allocate a tty object | 160 | * alloc_tty_struct - allocate a tty object |
@@ -1534,10 +1532,9 @@ void disassociate_ctty(int on_exit) | |||
1534 | } | 1532 | } |
1535 | 1533 | ||
1536 | spin_lock_irq(¤t->sighand->siglock); | 1534 | spin_lock_irq(¤t->sighand->siglock); |
1537 | tty_pgrp = current->signal->tty_old_pgrp; | 1535 | put_pid(current->signal->tty_old_pgrp); |
1538 | current->signal->tty_old_pgrp = NULL; | 1536 | current->signal->tty_old_pgrp = NULL; |
1539 | spin_unlock_irq(¤t->sighand->siglock); | 1537 | spin_unlock_irq(¤t->sighand->siglock); |
1540 | put_pid(tty_pgrp); | ||
1541 | 1538 | ||
1542 | mutex_lock(&tty_mutex); | 1539 | mutex_lock(&tty_mutex); |
1543 | /* It is possible that do_tty_hangup has free'd this tty */ | 1540 | /* It is possible that do_tty_hangup has free'd this tty */ |
@@ -1562,6 +1559,18 @@ void disassociate_ctty(int on_exit) | |||
1562 | unlock_kernel(); | 1559 | unlock_kernel(); |
1563 | } | 1560 | } |
1564 | 1561 | ||
1562 | /** | ||
1563 | * | ||
1564 | * no_tty - Ensure the current process does not have a controlling tty | ||
1565 | */ | ||
1566 | void no_tty(void) | ||
1567 | { | ||
1568 | struct task_struct *tsk = current; | ||
1569 | if (tsk->signal->leader) | ||
1570 | disassociate_ctty(0); | ||
1571 | proc_clear_tty(tsk); | ||
1572 | } | ||
1573 | |||
1565 | 1574 | ||
1566 | /** | 1575 | /** |
1567 | * stop_tty - propogate flow control | 1576 | * stop_tty - propogate flow control |
@@ -2508,7 +2517,6 @@ static int tty_open(struct inode * inode, struct file * filp) | |||
2508 | int index; | 2517 | int index; |
2509 | dev_t device = inode->i_rdev; | 2518 | dev_t device = inode->i_rdev; |
2510 | unsigned short saved_flags = filp->f_flags; | 2519 | unsigned short saved_flags = filp->f_flags; |
2511 | struct pid *old_pgrp; | ||
2512 | 2520 | ||
2513 | nonseekable_open(inode, filp); | 2521 | nonseekable_open(inode, filp); |
2514 | 2522 | ||
@@ -2602,17 +2610,15 @@ got_driver: | |||
2602 | goto retry_open; | 2610 | goto retry_open; |
2603 | } | 2611 | } |
2604 | 2612 | ||
2605 | old_pgrp = NULL; | ||
2606 | mutex_lock(&tty_mutex); | 2613 | mutex_lock(&tty_mutex); |
2607 | spin_lock_irq(¤t->sighand->siglock); | 2614 | spin_lock_irq(¤t->sighand->siglock); |
2608 | if (!noctty && | 2615 | if (!noctty && |
2609 | current->signal->leader && | 2616 | current->signal->leader && |
2610 | !current->signal->tty && | 2617 | !current->signal->tty && |
2611 | tty->session == NULL) | 2618 | tty->session == NULL) |
2612 | old_pgrp = __proc_set_tty(current, tty); | 2619 | __proc_set_tty(current, tty); |
2613 | spin_unlock_irq(¤t->sighand->siglock); | 2620 | spin_unlock_irq(¤t->sighand->siglock); |
2614 | mutex_unlock(&tty_mutex); | 2621 | mutex_unlock(&tty_mutex); |
2615 | put_pid(old_pgrp); | ||
2616 | return 0; | 2622 | return 0; |
2617 | } | 2623 | } |
2618 | 2624 | ||
@@ -3287,9 +3293,7 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3287 | case TIOCNOTTY: | 3293 | case TIOCNOTTY: |
3288 | if (current->signal->tty != tty) | 3294 | if (current->signal->tty != tty) |
3289 | return -ENOTTY; | 3295 | return -ENOTTY; |
3290 | if (current->signal->leader) | 3296 | no_tty(); |
3291 | disassociate_ctty(0); | ||
3292 | proc_clear_tty(current); | ||
3293 | return 0; | 3297 | return 0; |
3294 | case TIOCSCTTY: | 3298 | case TIOCSCTTY: |
3295 | return tiocsctty(tty, arg); | 3299 | return tiocsctty(tty, arg); |
@@ -3766,7 +3770,9 @@ int tty_register_driver(struct tty_driver *driver) | |||
3766 | if (!driver->put_char) | 3770 | if (!driver->put_char) |
3767 | driver->put_char = tty_default_put_char; | 3771 | driver->put_char = tty_default_put_char; |
3768 | 3772 | ||
3773 | mutex_lock(&tty_mutex); | ||
3769 | list_add(&driver->tty_drivers, &tty_drivers); | 3774 | list_add(&driver->tty_drivers, &tty_drivers); |
3775 | mutex_unlock(&tty_mutex); | ||
3770 | 3776 | ||
3771 | if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { | 3777 | if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { |
3772 | for(i = 0; i < driver->num; i++) | 3778 | for(i = 0; i < driver->num; i++) |
@@ -3792,8 +3798,9 @@ int tty_unregister_driver(struct tty_driver *driver) | |||
3792 | 3798 | ||
3793 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), | 3799 | unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), |
3794 | driver->num); | 3800 | driver->num); |
3795 | 3801 | mutex_lock(&tty_mutex); | |
3796 | list_del(&driver->tty_drivers); | 3802 | list_del(&driver->tty_drivers); |
3803 | mutex_unlock(&tty_mutex); | ||
3797 | 3804 | ||
3798 | /* | 3805 | /* |
3799 | * Free the termios and termios_locked structures because | 3806 | * Free the termios and termios_locked structures because |
@@ -3836,11 +3843,9 @@ void proc_clear_tty(struct task_struct *p) | |||
3836 | p->signal->tty = NULL; | 3843 | p->signal->tty = NULL; |
3837 | spin_unlock_irq(&p->sighand->siglock); | 3844 | spin_unlock_irq(&p->sighand->siglock); |
3838 | } | 3845 | } |
3839 | EXPORT_SYMBOL(proc_clear_tty); | ||
3840 | 3846 | ||
3841 | static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3847 | static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3842 | { | 3848 | { |
3843 | struct pid *old_pgrp; | ||
3844 | if (tty) { | 3849 | if (tty) { |
3845 | /* We should not have a session or pgrp to here but.... */ | 3850 | /* We should not have a session or pgrp to here but.... */ |
3846 | put_pid(tty->session); | 3851 | put_pid(tty->session); |
@@ -3848,21 +3853,16 @@ static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tt | |||
3848 | tty->session = get_pid(task_session(tsk)); | 3853 | tty->session = get_pid(task_session(tsk)); |
3849 | tty->pgrp = get_pid(task_pgrp(tsk)); | 3854 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3850 | } | 3855 | } |
3851 | old_pgrp = tsk->signal->tty_old_pgrp; | 3856 | put_pid(tsk->signal->tty_old_pgrp); |
3852 | tsk->signal->tty = tty; | 3857 | tsk->signal->tty = tty; |
3853 | tsk->signal->tty_old_pgrp = NULL; | 3858 | tsk->signal->tty_old_pgrp = NULL; |
3854 | return old_pgrp; | ||
3855 | } | 3859 | } |
3856 | 3860 | ||
3857 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3861 | static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3858 | { | 3862 | { |
3859 | struct pid *old_pgrp; | ||
3860 | |||
3861 | spin_lock_irq(&tsk->sighand->siglock); | 3863 | spin_lock_irq(&tsk->sighand->siglock); |
3862 | old_pgrp = __proc_set_tty(tsk, tty); | 3864 | __proc_set_tty(tsk, tty); |
3863 | spin_unlock_irq(&tsk->sighand->siglock); | 3865 | spin_unlock_irq(&tsk->sighand->siglock); |
3864 | |||
3865 | put_pid(old_pgrp); | ||
3866 | } | 3866 | } |
3867 | 3867 | ||
3868 | struct tty_struct *get_current_tty(void) | 3868 | struct tty_struct *get_current_tty(void) |
@@ -3897,9 +3897,6 @@ void __init console_init(void) | |||
3897 | * set up the console device so that later boot sequences can | 3897 | * set up the console device so that later boot sequences can |
3898 | * inform about problems etc.. | 3898 | * inform about problems etc.. |
3899 | */ | 3899 | */ |
3900 | #ifdef CONFIG_EARLY_PRINTK | ||
3901 | disable_early_printk(); | ||
3902 | #endif | ||
3903 | call = __con_initcall_start; | 3900 | call = __con_initcall_start; |
3904 | while (call < __con_initcall_end) { | 3901 | while (call < __con_initcall_end) { |
3905 | (*call)(); | 3902 | (*call)(); |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 791930320a13..83aeedda200c 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -28,12 +28,13 @@ | |||
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/mutex.h> | ||
31 | #include <linux/vt_kern.h> | 32 | #include <linux/vt_kern.h> |
32 | #include <linux/selection.h> | 33 | #include <linux/selection.h> |
33 | #include <linux/kbd_kern.h> | 34 | #include <linux/kbd_kern.h> |
34 | #include <linux/console.h> | 35 | #include <linux/console.h> |
35 | #include <linux/smp_lock.h> | ||
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | |||
37 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
38 | #include <asm/byteorder.h> | 39 | #include <asm/byteorder.h> |
39 | #include <asm/unaligned.h> | 40 | #include <asm/unaligned.h> |
@@ -70,11 +71,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
70 | { | 71 | { |
71 | int size; | 72 | int size; |
72 | 73 | ||
73 | down(&con_buf_sem); | 74 | mutex_lock(&con_buf_mtx); |
74 | size = vcs_size(file->f_path.dentry->d_inode); | 75 | size = vcs_size(file->f_path.dentry->d_inode); |
75 | switch (orig) { | 76 | switch (orig) { |
76 | default: | 77 | default: |
77 | up(&con_buf_sem); | 78 | mutex_unlock(&con_buf_mtx); |
78 | return -EINVAL; | 79 | return -EINVAL; |
79 | case 2: | 80 | case 2: |
80 | offset += size; | 81 | offset += size; |
@@ -85,11 +86,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
85 | break; | 86 | break; |
86 | } | 87 | } |
87 | if (offset < 0 || offset > size) { | 88 | if (offset < 0 || offset > size) { |
88 | up(&con_buf_sem); | 89 | mutex_unlock(&con_buf_mtx); |
89 | return -EINVAL; | 90 | return -EINVAL; |
90 | } | 91 | } |
91 | file->f_pos = offset; | 92 | file->f_pos = offset; |
92 | up(&con_buf_sem); | 93 | mutex_unlock(&con_buf_mtx); |
93 | return file->f_pos; | 94 | return file->f_pos; |
94 | } | 95 | } |
95 | 96 | ||
@@ -106,7 +107,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
106 | unsigned short *org = NULL; | 107 | unsigned short *org = NULL; |
107 | ssize_t ret; | 108 | ssize_t ret; |
108 | 109 | ||
109 | down(&con_buf_sem); | 110 | mutex_lock(&con_buf_mtx); |
110 | 111 | ||
111 | pos = *ppos; | 112 | pos = *ppos; |
112 | 113 | ||
@@ -263,7 +264,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
263 | ret = read; | 264 | ret = read; |
264 | unlock_out: | 265 | unlock_out: |
265 | release_console_sem(); | 266 | release_console_sem(); |
266 | up(&con_buf_sem); | 267 | mutex_unlock(&con_buf_mtx); |
267 | return ret; | 268 | return ret; |
268 | } | 269 | } |
269 | 270 | ||
@@ -280,7 +281,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
280 | u16 *org0 = NULL, *org = NULL; | 281 | u16 *org0 = NULL, *org = NULL; |
281 | size_t ret; | 282 | size_t ret; |
282 | 283 | ||
283 | down(&con_buf_sem); | 284 | mutex_lock(&con_buf_mtx); |
284 | 285 | ||
285 | pos = *ppos; | 286 | pos = *ppos; |
286 | 287 | ||
@@ -450,7 +451,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
450 | unlock_out: | 451 | unlock_out: |
451 | release_console_sem(); | 452 | release_console_sem(); |
452 | 453 | ||
453 | up(&con_buf_sem); | 454 | mutex_unlock(&con_buf_mtx); |
454 | 455 | ||
455 | return ret; | 456 | return ret; |
456 | } | 457 | } |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1bbb45b937fd..bbd9fc412877 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #include <linux/mm.h> | 86 | #include <linux/mm.h> |
87 | #include <linux/console.h> | 87 | #include <linux/console.h> |
88 | #include <linux/init.h> | 88 | #include <linux/init.h> |
89 | #include <linux/mutex.h> | ||
89 | #include <linux/vt_kern.h> | 90 | #include <linux/vt_kern.h> |
90 | #include <linux/selection.h> | 91 | #include <linux/selection.h> |
91 | #include <linux/tiocl.h> | 92 | #include <linux/tiocl.h> |
@@ -157,6 +158,8 @@ static void blank_screen_t(unsigned long dummy); | |||
157 | static void set_palette(struct vc_data *vc); | 158 | static void set_palette(struct vc_data *vc); |
158 | 159 | ||
159 | static int printable; /* Is console ready for printing? */ | 160 | static int printable; /* Is console ready for printing? */ |
161 | static int default_utf8; | ||
162 | module_param(default_utf8, int, S_IRUGO | S_IWUSR); | ||
160 | 163 | ||
161 | /* | 164 | /* |
162 | * ignore_poke: don't unblank the screen when things are typed. This is | 165 | * ignore_poke: don't unblank the screen when things are typed. This is |
@@ -348,10 +351,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count) | |||
348 | 351 | ||
349 | /* Structure of attributes is hardware-dependent */ | 352 | /* Structure of attributes is hardware-dependent */ |
350 | 353 | ||
351 | static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) | 354 | static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, |
355 | u8 _underline, u8 _reverse, u8 _italic) | ||
352 | { | 356 | { |
353 | if (vc->vc_sw->con_build_attr) | 357 | if (vc->vc_sw->con_build_attr) |
354 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse); | 358 | return vc->vc_sw->con_build_attr(vc, _color, _intensity, |
359 | _blink, _underline, _reverse, _italic); | ||
355 | 360 | ||
356 | #ifndef VT_BUF_VRAM_ONLY | 361 | #ifndef VT_BUF_VRAM_ONLY |
357 | /* | 362 | /* |
@@ -368,10 +373,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 | |||
368 | u8 a = vc->vc_color; | 373 | u8 a = vc->vc_color; |
369 | if (!vc->vc_can_do_color) | 374 | if (!vc->vc_can_do_color) |
370 | return _intensity | | 375 | return _intensity | |
376 | (_italic ? 2 : 0) | | ||
371 | (_underline ? 4 : 0) | | 377 | (_underline ? 4 : 0) | |
372 | (_reverse ? 8 : 0) | | 378 | (_reverse ? 8 : 0) | |
373 | (_blink ? 0x80 : 0); | 379 | (_blink ? 0x80 : 0); |
374 | if (_underline) | 380 | if (_italic) |
381 | a = (a & 0xF0) | vc->vc_itcolor; | ||
382 | else if (_underline) | ||
375 | a = (a & 0xf0) | vc->vc_ulcolor; | 383 | a = (a & 0xf0) | vc->vc_ulcolor; |
376 | else if (_intensity == 0) | 384 | else if (_intensity == 0) |
377 | a = (a & 0xf0) | vc->vc_ulcolor; | 385 | a = (a & 0xf0) | vc->vc_ulcolor; |
@@ -392,8 +400,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 | |||
392 | 400 | ||
393 | static void update_attr(struct vc_data *vc) | 401 | static void update_attr(struct vc_data *vc) |
394 | { | 402 | { |
395 | vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm); | 403 | vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, |
396 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' '; | 404 | vc->vc_blink, vc->vc_underline, |
405 | vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); | ||
406 | vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; | ||
397 | } | 407 | } |
398 | 408 | ||
399 | /* Note: inverting the screen twice should revert to the original state */ | 409 | /* Note: inverting the screen twice should revert to the original state */ |
@@ -934,6 +944,10 @@ int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa, | |||
934 | int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, | 944 | int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, |
935 | 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; | 945 | 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; |
936 | 946 | ||
947 | module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR); | ||
948 | module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR); | ||
949 | module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR); | ||
950 | |||
937 | /* | 951 | /* |
938 | * gotoxy() must verify all boundaries, because the arguments | 952 | * gotoxy() must verify all boundaries, because the arguments |
939 | * might also be negative. If the given position is out of | 953 | * might also be negative. If the given position is out of |
@@ -1132,6 +1146,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi | |||
1132 | static void default_attr(struct vc_data *vc) | 1146 | static void default_attr(struct vc_data *vc) |
1133 | { | 1147 | { |
1134 | vc->vc_intensity = 1; | 1148 | vc->vc_intensity = 1; |
1149 | vc->vc_italic = 0; | ||
1135 | vc->vc_underline = 0; | 1150 | vc->vc_underline = 0; |
1136 | vc->vc_reverse = 0; | 1151 | vc->vc_reverse = 0; |
1137 | vc->vc_blink = 0; | 1152 | vc->vc_blink = 0; |
@@ -1154,6 +1169,9 @@ static void csi_m(struct vc_data *vc) | |||
1154 | case 2: | 1169 | case 2: |
1155 | vc->vc_intensity = 0; | 1170 | vc->vc_intensity = 0; |
1156 | break; | 1171 | break; |
1172 | case 3: | ||
1173 | vc->vc_italic = 1; | ||
1174 | break; | ||
1157 | case 4: | 1175 | case 4: |
1158 | vc->vc_underline = 1; | 1176 | vc->vc_underline = 1; |
1159 | break; | 1177 | break; |
@@ -1194,6 +1212,9 @@ static void csi_m(struct vc_data *vc) | |||
1194 | case 22: | 1212 | case 22: |
1195 | vc->vc_intensity = 1; | 1213 | vc->vc_intensity = 1; |
1196 | break; | 1214 | break; |
1215 | case 23: | ||
1216 | vc->vc_italic = 0; | ||
1217 | break; | ||
1197 | case 24: | 1218 | case 24: |
1198 | vc->vc_underline = 0; | 1219 | vc->vc_underline = 0; |
1199 | break; | 1220 | break; |
@@ -1454,6 +1475,7 @@ static void save_cur(struct vc_data *vc) | |||
1454 | vc->vc_saved_x = vc->vc_x; | 1475 | vc->vc_saved_x = vc->vc_x; |
1455 | vc->vc_saved_y = vc->vc_y; | 1476 | vc->vc_saved_y = vc->vc_y; |
1456 | vc->vc_s_intensity = vc->vc_intensity; | 1477 | vc->vc_s_intensity = vc->vc_intensity; |
1478 | vc->vc_s_italic = vc->vc_italic; | ||
1457 | vc->vc_s_underline = vc->vc_underline; | 1479 | vc->vc_s_underline = vc->vc_underline; |
1458 | vc->vc_s_blink = vc->vc_blink; | 1480 | vc->vc_s_blink = vc->vc_blink; |
1459 | vc->vc_s_reverse = vc->vc_reverse; | 1481 | vc->vc_s_reverse = vc->vc_reverse; |
@@ -1468,6 +1490,7 @@ static void restore_cur(struct vc_data *vc) | |||
1468 | { | 1490 | { |
1469 | gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); | 1491 | gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); |
1470 | vc->vc_intensity = vc->vc_s_intensity; | 1492 | vc->vc_intensity = vc->vc_s_intensity; |
1493 | vc->vc_italic = vc->vc_s_italic; | ||
1471 | vc->vc_underline = vc->vc_s_underline; | 1494 | vc->vc_underline = vc->vc_s_underline; |
1472 | vc->vc_blink = vc->vc_s_blink; | 1495 | vc->vc_blink = vc->vc_s_blink; |
1473 | vc->vc_reverse = vc->vc_s_reverse; | 1496 | vc->vc_reverse = vc->vc_s_reverse; |
@@ -1497,7 +1520,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) | |||
1497 | vc->vc_charset = 0; | 1520 | vc->vc_charset = 0; |
1498 | vc->vc_need_wrap = 0; | 1521 | vc->vc_need_wrap = 0; |
1499 | vc->vc_report_mouse = 0; | 1522 | vc->vc_report_mouse = 0; |
1500 | vc->vc_utf = 0; | 1523 | vc->vc_utf = default_utf8; |
1501 | vc->vc_utf_count = 0; | 1524 | vc->vc_utf_count = 0; |
1502 | 1525 | ||
1503 | vc->vc_disp_ctrl = 0; | 1526 | vc->vc_disp_ctrl = 0; |
@@ -1930,7 +1953,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1930 | * kernel memory allocation is available. | 1953 | * kernel memory allocation is available. |
1931 | */ | 1954 | */ |
1932 | char con_buf[CON_BUF_SIZE]; | 1955 | char con_buf[CON_BUF_SIZE]; |
1933 | DECLARE_MUTEX(con_buf_sem); | 1956 | DEFINE_MUTEX(con_buf_mtx); |
1957 | |||
1958 | /* is_double_width() is based on the wcwidth() implementation by | ||
1959 | * Markus Kuhn -- 2003-05-20 (Unicode 4.0) | ||
1960 | * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c | ||
1961 | */ | ||
1962 | struct interval { | ||
1963 | uint32_t first; | ||
1964 | uint32_t last; | ||
1965 | }; | ||
1966 | |||
1967 | static int bisearch(uint32_t ucs, const struct interval *table, int max) | ||
1968 | { | ||
1969 | int min = 0; | ||
1970 | int mid; | ||
1971 | |||
1972 | if (ucs < table[0].first || ucs > table[max].last) | ||
1973 | return 0; | ||
1974 | while (max >= min) { | ||
1975 | mid = (min + max) / 2; | ||
1976 | if (ucs > table[mid].last) | ||
1977 | min = mid + 1; | ||
1978 | else if (ucs < table[mid].first) | ||
1979 | max = mid - 1; | ||
1980 | else | ||
1981 | return 1; | ||
1982 | } | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | static int is_double_width(uint32_t ucs) | ||
1987 | { | ||
1988 | static const struct interval double_width[] = { | ||
1989 | { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E }, | ||
1990 | { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF }, | ||
1991 | { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 }, | ||
1992 | { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } | ||
1993 | }; | ||
1994 | return bisearch(ucs, double_width, | ||
1995 | sizeof(double_width) / sizeof(*double_width) - 1); | ||
1996 | } | ||
1934 | 1997 | ||
1935 | /* acquires console_sem */ | 1998 | /* acquires console_sem */ |
1936 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) | 1999 | static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) |
@@ -1948,6 +2011,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
1948 | unsigned int currcons; | 2011 | unsigned int currcons; |
1949 | unsigned long draw_from = 0, draw_to = 0; | 2012 | unsigned long draw_from = 0, draw_to = 0; |
1950 | struct vc_data *vc; | 2013 | struct vc_data *vc; |
2014 | unsigned char vc_attr; | ||
2015 | uint8_t rescan; | ||
2016 | uint8_t inverse; | ||
2017 | uint8_t width; | ||
1951 | u16 himask, charmask; | 2018 | u16 himask, charmask; |
1952 | const unsigned char *orig_buf = NULL; | 2019 | const unsigned char *orig_buf = NULL; |
1953 | int orig_count; | 2020 | int orig_count; |
@@ -1983,7 +2050,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
1983 | 2050 | ||
1984 | /* At this point 'buf' is guaranteed to be a kernel buffer | 2051 | /* At this point 'buf' is guaranteed to be a kernel buffer |
1985 | * and therefore no access to userspace (and therefore sleeping) | 2052 | * and therefore no access to userspace (and therefore sleeping) |
1986 | * will be needed. The con_buf_sem serializes all tty based | 2053 | * will be needed. The con_buf_mtx serializes all tty based |
1987 | * console rendering and vcs write/read operations. We hold | 2054 | * console rendering and vcs write/read operations. We hold |
1988 | * the console spinlock during the entire write. | 2055 | * the console spinlock during the entire write. |
1989 | */ | 2056 | */ |
@@ -2010,53 +2077,86 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co | |||
2010 | buf++; | 2077 | buf++; |
2011 | n++; | 2078 | n++; |
2012 | count--; | 2079 | count--; |
2080 | rescan = 0; | ||
2081 | inverse = 0; | ||
2082 | width = 1; | ||
2013 | 2083 | ||
2014 | /* Do no translation at all in control states */ | 2084 | /* Do no translation at all in control states */ |
2015 | if (vc->vc_state != ESnormal) { | 2085 | if (vc->vc_state != ESnormal) { |
2016 | tc = c; | 2086 | tc = c; |
2017 | } else if (vc->vc_utf && !vc->vc_disp_ctrl) { | 2087 | } else if (vc->vc_utf && !vc->vc_disp_ctrl) { |
2018 | /* Combine UTF-8 into Unicode */ | 2088 | /* Combine UTF-8 into Unicode in vc_utf_char. |
2019 | /* Malformed sequences as sequences of replacement glyphs */ | 2089 | * vc_utf_count is the number of continuation bytes still |
2090 | * expected to arrive. | ||
2091 | * vc_npar is the number of continuation bytes arrived so | ||
2092 | * far | ||
2093 | */ | ||
2020 | rescan_last_byte: | 2094 | rescan_last_byte: |
2021 | if(c > 0x7f) { | 2095 | if ((c & 0xc0) == 0x80) { |
2096 | /* Continuation byte received */ | ||
2097 | static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff }; | ||
2022 | if (vc->vc_utf_count) { | 2098 | if (vc->vc_utf_count) { |
2023 | if ((c & 0xc0) == 0x80) { | 2099 | vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); |
2024 | vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); | 2100 | vc->vc_npar++; |
2025 | if (--vc->vc_utf_count) { | 2101 | if (--vc->vc_utf_count) { |
2026 | vc->vc_npar++; | 2102 | /* Still need some bytes */ |
2027 | continue; | ||
2028 | } | ||
2029 | tc = c = vc->vc_utf_char; | ||
2030 | } else | ||
2031 | goto replacement_glyph; | ||
2032 | } else { | ||
2033 | vc->vc_npar = 0; | ||
2034 | if ((c & 0xe0) == 0xc0) { | ||
2035 | vc->vc_utf_count = 1; | ||
2036 | vc->vc_utf_char = (c & 0x1f); | ||
2037 | } else if ((c & 0xf0) == 0xe0) { | ||
2038 | vc->vc_utf_count = 2; | ||
2039 | vc->vc_utf_char = (c & 0x0f); | ||
2040 | } else if ((c & 0xf8) == 0xf0) { | ||
2041 | vc->vc_utf_count = 3; | ||
2042 | vc->vc_utf_char = (c & 0x07); | ||
2043 | } else if ((c & 0xfc) == 0xf8) { | ||
2044 | vc->vc_utf_count = 4; | ||
2045 | vc->vc_utf_char = (c & 0x03); | ||
2046 | } else if ((c & 0xfe) == 0xfc) { | ||
2047 | vc->vc_utf_count = 5; | ||
2048 | vc->vc_utf_char = (c & 0x01); | ||
2049 | } else | ||
2050 | goto replacement_glyph; | ||
2051 | continue; | 2103 | continue; |
2052 | } | 2104 | } |
2105 | /* Got a whole character */ | ||
2106 | c = vc->vc_utf_char; | ||
2107 | /* Reject overlong sequences */ | ||
2108 | if (c <= utf8_length_changes[vc->vc_npar - 1] || | ||
2109 | c > utf8_length_changes[vc->vc_npar]) | ||
2110 | c = 0xfffd; | ||
2111 | } else { | ||
2112 | /* Unexpected continuation byte */ | ||
2113 | vc->vc_utf_count = 0; | ||
2114 | c = 0xfffd; | ||
2115 | } | ||
2053 | } else { | 2116 | } else { |
2054 | if (vc->vc_utf_count) | 2117 | /* Single ASCII byte or first byte of a sequence received */ |
2055 | goto replacement_glyph; | 2118 | if (vc->vc_utf_count) { |
2056 | tc = c; | 2119 | /* Continuation byte expected */ |
2120 | rescan = 1; | ||
2121 | vc->vc_utf_count = 0; | ||
2122 | c = 0xfffd; | ||
2123 | } else if (c > 0x7f) { | ||
2124 | /* First byte of a multibyte sequence received */ | ||
2125 | vc->vc_npar = 0; | ||
2126 | if ((c & 0xe0) == 0xc0) { | ||
2127 | vc->vc_utf_count = 1; | ||
2128 | vc->vc_utf_char = (c & 0x1f); | ||
2129 | } else if ((c & 0xf0) == 0xe0) { | ||
2130 | vc->vc_utf_count = 2; | ||
2131 | vc->vc_utf_char = (c & 0x0f); | ||
2132 | } else if ((c & 0xf8) == 0xf0) { | ||
2133 | vc->vc_utf_count = 3; | ||
2134 | vc->vc_utf_char = (c & 0x07); | ||
2135 | } else if ((c & 0xfc) == 0xf8) { | ||
2136 | vc->vc_utf_count = 4; | ||
2137 | vc->vc_utf_char = (c & 0x03); | ||
2138 | } else if ((c & 0xfe) == 0xfc) { | ||
2139 | vc->vc_utf_count = 5; | ||
2140 | vc->vc_utf_char = (c & 0x01); | ||
2141 | } else { | ||
2142 | /* 254 and 255 are invalid */ | ||
2143 | c = 0xfffd; | ||
2144 | } | ||
2145 | if (vc->vc_utf_count) { | ||
2146 | /* Still need some bytes */ | ||
2147 | continue; | ||
2148 | } | ||
2149 | } | ||
2150 | /* Nothing to do if an ASCII byte was received */ | ||
2057 | } | 2151 | } |
2152 | /* End of UTF-8 decoding. */ | ||
2153 | /* c is the received character, or U+FFFD for invalid sequences. */ | ||
2154 | /* Replace invalid Unicode code points with U+FFFD too */ | ||
2155 | if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) | ||
2156 | c = 0xfffd; | ||
2157 | tc = c; | ||
2058 | } else { /* no utf or alternate charset mode */ | 2158 | } else { /* no utf or alternate charset mode */ |
2059 | tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; | 2159 | tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; |
2060 | } | 2160 | } |
2061 | 2161 | ||
2062 | /* If the original code was a control character we | 2162 | /* If the original code was a control character we |
@@ -2076,56 +2176,80 @@ rescan_last_byte: | |||
2076 | && (c != 128+27); | 2176 | && (c != 128+27); |
2077 | 2177 | ||
2078 | if (vc->vc_state == ESnormal && ok) { | 2178 | if (vc->vc_state == ESnormal && ok) { |
2179 | if (vc->vc_utf && !vc->vc_disp_ctrl) { | ||
2180 | if (is_double_width(c)) | ||
2181 | width = 2; | ||
2182 | } | ||
2079 | /* Now try to find out how to display it */ | 2183 | /* Now try to find out how to display it */ |
2080 | tc = conv_uni_to_pc(vc, tc); | 2184 | tc = conv_uni_to_pc(vc, tc); |
2081 | if (tc & ~charmask) { | 2185 | if (tc & ~charmask) { |
2082 | if ( tc == -4 ) { | 2186 | if (tc == -1 || tc == -2) { |
2083 | /* If we got -4 (not found) then see if we have | 2187 | continue; /* nothing to display */ |
2084 | defined a replacement character (U+FFFD) */ | 2188 | } |
2085 | replacement_glyph: | 2189 | /* Glyph not found */ |
2086 | tc = conv_uni_to_pc(vc, 0xfffd); | 2190 | if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) { |
2087 | if (!(tc & ~charmask)) | 2191 | /* In legacy mode use the glyph we get by a 1:1 mapping. |
2088 | goto display_glyph; | 2192 | This would make absolutely no sense with Unicode in mind. */ |
2089 | } else if ( tc != -3 ) | 2193 | tc = c; |
2090 | continue; /* nothing to display */ | 2194 | } else { |
2091 | /* no hash table or no replacement -- | 2195 | /* Display U+FFFD. If it's not found, display an inverse question mark. */ |
2092 | * hope for the best */ | 2196 | tc = conv_uni_to_pc(vc, 0xfffd); |
2093 | if ( c & ~charmask ) | 2197 | if (tc < 0) { |
2094 | tc = '?'; | 2198 | inverse = 1; |
2095 | else | 2199 | tc = conv_uni_to_pc(vc, '?'); |
2096 | tc = c; | 2200 | if (tc < 0) tc = '?'; |
2201 | } | ||
2202 | } | ||
2097 | } | 2203 | } |
2098 | 2204 | ||
2099 | display_glyph: | 2205 | if (!inverse) { |
2100 | if (vc->vc_need_wrap || vc->vc_decim) | 2206 | vc_attr = vc->vc_attr; |
2101 | FLUSH | ||
2102 | if (vc->vc_need_wrap) { | ||
2103 | cr(vc); | ||
2104 | lf(vc); | ||
2105 | } | ||
2106 | if (vc->vc_decim) | ||
2107 | insert_char(vc, 1); | ||
2108 | scr_writew(himask ? | ||
2109 | ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : | ||
2110 | (vc->vc_attr << 8) + tc, | ||
2111 | (u16 *) vc->vc_pos); | ||
2112 | if (DO_UPDATE(vc) && draw_x < 0) { | ||
2113 | draw_x = vc->vc_x; | ||
2114 | draw_from = vc->vc_pos; | ||
2115 | } | ||
2116 | if (vc->vc_x == vc->vc_cols - 1) { | ||
2117 | vc->vc_need_wrap = vc->vc_decawm; | ||
2118 | draw_to = vc->vc_pos + 2; | ||
2119 | } else { | 2207 | } else { |
2120 | vc->vc_x++; | 2208 | /* invert vc_attr */ |
2121 | draw_to = (vc->vc_pos += 2); | 2209 | if (!vc->vc_can_do_color) { |
2210 | vc_attr = (vc->vc_attr) ^ 0x08; | ||
2211 | } else if (vc->vc_hi_font_mask == 0x100) { | ||
2212 | vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4); | ||
2213 | } else { | ||
2214 | vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4); | ||
2215 | } | ||
2122 | } | 2216 | } |
2123 | if (vc->vc_utf_count) { | 2217 | |
2124 | if (vc->vc_npar) { | 2218 | while (1) { |
2125 | vc->vc_npar--; | 2219 | if (vc->vc_need_wrap || vc->vc_decim) |
2126 | goto display_glyph; | 2220 | FLUSH |
2221 | if (vc->vc_need_wrap) { | ||
2222 | cr(vc); | ||
2223 | lf(vc); | ||
2224 | } | ||
2225 | if (vc->vc_decim) | ||
2226 | insert_char(vc, 1); | ||
2227 | scr_writew(himask ? | ||
2228 | ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) : | ||
2229 | (vc_attr << 8) + tc, | ||
2230 | (u16 *) vc->vc_pos); | ||
2231 | if (DO_UPDATE(vc) && draw_x < 0) { | ||
2232 | draw_x = vc->vc_x; | ||
2233 | draw_from = vc->vc_pos; | ||
2234 | } | ||
2235 | if (vc->vc_x == vc->vc_cols - 1) { | ||
2236 | vc->vc_need_wrap = vc->vc_decawm; | ||
2237 | draw_to = vc->vc_pos + 2; | ||
2238 | } else { | ||
2239 | vc->vc_x++; | ||
2240 | draw_to = (vc->vc_pos += 2); | ||
2127 | } | 2241 | } |
2128 | vc->vc_utf_count = 0; | 2242 | |
2243 | if (!--width) break; | ||
2244 | |||
2245 | tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */ | ||
2246 | if (tc < 0) tc = ' '; | ||
2247 | } | ||
2248 | |||
2249 | if (rescan) { | ||
2250 | rescan = 0; | ||
2251 | inverse = 0; | ||
2252 | width = 1; | ||
2129 | c = orig; | 2253 | c = orig; |
2130 | goto rescan_last_byte; | 2254 | goto rescan_last_byte; |
2131 | } | 2255 | } |
@@ -2581,6 +2705,11 @@ static void con_close(struct tty_struct *tty, struct file *filp) | |||
2581 | mutex_unlock(&tty_mutex); | 2705 | mutex_unlock(&tty_mutex); |
2582 | } | 2706 | } |
2583 | 2707 | ||
2708 | static int default_italic_color = 2; // green (ASCII) | ||
2709 | static int default_underline_color = 3; // cyan (ASCII) | ||
2710 | module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR); | ||
2711 | module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR); | ||
2712 | |||
2584 | static void vc_init(struct vc_data *vc, unsigned int rows, | 2713 | static void vc_init(struct vc_data *vc, unsigned int rows, |
2585 | unsigned int cols, int do_clear) | 2714 | unsigned int cols, int do_clear) |
2586 | { | 2715 | { |
@@ -2600,7 +2729,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows, | |||
2600 | vc->vc_palette[k++] = default_blu[j] ; | 2729 | vc->vc_palette[k++] = default_blu[j] ; |
2601 | } | 2730 | } |
2602 | vc->vc_def_color = 0x07; /* white */ | 2731 | vc->vc_def_color = 0x07; /* white */ |
2603 | vc->vc_ulcolor = 0x0f; /* bold white */ | 2732 | vc->vc_ulcolor = default_underline_color; |
2733 | vc->vc_itcolor = default_italic_color; | ||
2604 | vc->vc_halfcolor = 0x08; /* grey */ | 2734 | vc->vc_halfcolor = 0x08; /* grey */ |
2605 | init_waitqueue_head(&vc->paste_wait); | 2735 | init_waitqueue_head(&vc->paste_wait); |
2606 | reset_terminal(vc, do_clear); | 2736 | reset_terminal(vc, do_clear); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index c9f2dd620e87..c6f6f4209739 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -1061,7 +1061,7 @@ int vt_waitactive(int vt) | |||
1061 | schedule(); | 1061 | schedule(); |
1062 | } | 1062 | } |
1063 | remove_wait_queue(&vt_activate_queue, &wait); | 1063 | remove_wait_queue(&vt_activate_queue, &wait); |
1064 | current->state = TASK_RUNNING; | 1064 | __set_current_state(TASK_RUNNING); |
1065 | return retval; | 1065 | return retval; |
1066 | } | 1066 | } |
1067 | 1067 | ||
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c index 84074a697dce..b36fa8de2131 100644 --- a/drivers/char/watchdog/omap_wdt.c +++ b/drivers/char/watchdog/omap_wdt.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/miscdevice.h> | 34 | #include <linux/miscdevice.h> |
35 | #include <linux/watchdog.h> | 35 | #include <linux/watchdog.h> |
36 | #include <linux/reboot.h> | 36 | #include <linux/reboot.h> |
37 | #include <linux/smp_lock.h> | ||
38 | #include <linux/init.h> | 37 | #include <linux/init.h> |
39 | #include <linux/err.h> | 38 | #include <linux/err.h> |
40 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |