diff options
| -rw-r--r-- | drivers/char/stallion.c | 208 |
1 files changed, 86 insertions, 122 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index a9c5a7230f89..bf361a5ba70d 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c | |||
| @@ -141,15 +141,6 @@ static char *stl_drvversion = "5.6.0"; | |||
| 141 | static struct tty_driver *stl_serial; | 141 | static struct tty_driver *stl_serial; |
| 142 | 142 | ||
| 143 | /* | 143 | /* |
| 144 | * We will need to allocate a temporary write buffer for chars that | ||
| 145 | * come direct from user space. The problem is that a copy from user | ||
| 146 | * space might cause a page fault (typically on a system that is | ||
| 147 | * swapping!). All ports will share one buffer - since if the system | ||
| 148 | * is already swapping a shared buffer won't make things any worse. | ||
| 149 | */ | ||
| 150 | static char *stl_tmpwritebuf; | ||
| 151 | |||
| 152 | /* | ||
| 153 | * Define a local default termios struct. All ports will be created | 144 | * Define a local default termios struct. All ports will be created |
| 154 | * with this termios initially. Basically all it defines is a raw port | 145 | * with this termios initially. Basically all it defines is a raw port |
| 155 | * at 9600, 8 data bits, 1 stop bit. | 146 | * at 9600, 8 data bits, 1 stop bit. |
| @@ -363,6 +354,14 @@ static unsigned char stl_vecmap[] = { | |||
| 363 | }; | 354 | }; |
| 364 | 355 | ||
| 365 | /* | 356 | /* |
| 357 | * Lock ordering is that you may not take stallion_lock holding | ||
| 358 | * brd_lock. | ||
| 359 | */ | ||
| 360 | |||
| 361 | static spinlock_t brd_lock; /* Guard the board mapping */ | ||
| 362 | static spinlock_t stallion_lock; /* Guard the tty driver */ | ||
| 363 | |||
| 364 | /* | ||
| 366 | * Set up enable and disable macros for the ECH boards. They require | 365 | * Set up enable and disable macros for the ECH boards. They require |
| 367 | * the secondary io address space to be activated and deactivated. | 366 | * the secondary io address space to be activated and deactivated. |
| 368 | * This way all ECH boards can share their secondary io region. | 367 | * This way all ECH boards can share their secondary io region. |
| @@ -725,17 +724,7 @@ static struct class *stallion_class; | |||
| 725 | 724 | ||
| 726 | static int __init stallion_module_init(void) | 725 | static int __init stallion_module_init(void) |
| 727 | { | 726 | { |
| 728 | unsigned long flags; | ||
| 729 | |||
| 730 | #ifdef DEBUG | ||
| 731 | printk("init_module()\n"); | ||
| 732 | #endif | ||
| 733 | |||
| 734 | save_flags(flags); | ||
| 735 | cli(); | ||
| 736 | stl_init(); | 727 | stl_init(); |
| 737 | restore_flags(flags); | ||
| 738 | |||
| 739 | return 0; | 728 | return 0; |
| 740 | } | 729 | } |
| 741 | 730 | ||
| @@ -746,7 +735,6 @@ static void __exit stallion_module_exit(void) | |||
| 746 | stlbrd_t *brdp; | 735 | stlbrd_t *brdp; |
| 747 | stlpanel_t *panelp; | 736 | stlpanel_t *panelp; |
| 748 | stlport_t *portp; | 737 | stlport_t *portp; |
| 749 | unsigned long flags; | ||
| 750 | int i, j, k; | 738 | int i, j, k; |
| 751 | 739 | ||
| 752 | #ifdef DEBUG | 740 | #ifdef DEBUG |
| @@ -756,9 +744,6 @@ static void __exit stallion_module_exit(void) | |||
| 756 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | 744 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, |
| 757 | stl_drvversion); | 745 | stl_drvversion); |
| 758 | 746 | ||
| 759 | save_flags(flags); | ||
| 760 | cli(); | ||
| 761 | |||
| 762 | /* | 747 | /* |
| 763 | * Free up all allocated resources used by the ports. This includes | 748 | * Free up all allocated resources used by the ports. This includes |
| 764 | * memory and interrupts. As part of this process we will also do | 749 | * memory and interrupts. As part of this process we will also do |
| @@ -770,7 +755,6 @@ static void __exit stallion_module_exit(void) | |||
| 770 | if (i) { | 755 | if (i) { |
| 771 | printk("STALLION: failed to un-register tty driver, " | 756 | printk("STALLION: failed to un-register tty driver, " |
| 772 | "errno=%d\n", -i); | 757 | "errno=%d\n", -i); |
| 773 | restore_flags(flags); | ||
| 774 | return; | 758 | return; |
| 775 | } | 759 | } |
| 776 | for (i = 0; i < 4; i++) { | 760 | for (i = 0; i < 4; i++) { |
| @@ -783,8 +767,6 @@ static void __exit stallion_module_exit(void) | |||
| 783 | "errno=%d\n", -i); | 767 | "errno=%d\n", -i); |
| 784 | class_destroy(stallion_class); | 768 | class_destroy(stallion_class); |
| 785 | 769 | ||
| 786 | kfree(stl_tmpwritebuf); | ||
| 787 | |||
| 788 | for (i = 0; (i < stl_nrbrds); i++) { | 770 | for (i = 0; (i < stl_nrbrds); i++) { |
| 789 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | 771 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) |
| 790 | continue; | 772 | continue; |
| @@ -814,8 +796,6 @@ static void __exit stallion_module_exit(void) | |||
| 814 | kfree(brdp); | 796 | kfree(brdp); |
| 815 | stl_brds[i] = (stlbrd_t *) NULL; | 797 | stl_brds[i] = (stlbrd_t *) NULL; |
| 816 | } | 798 | } |
| 817 | |||
| 818 | restore_flags(flags); | ||
| 819 | } | 799 | } |
| 820 | 800 | ||
| 821 | module_init(stallion_module_init); | 801 | module_init(stallion_module_init); |
| @@ -948,7 +928,7 @@ static stlbrd_t *stl_allocbrd(void) | |||
| 948 | 928 | ||
| 949 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 929 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); |
| 950 | if (!brdp) { | 930 | if (!brdp) { |
| 951 | printk("STALLION: failed to allocate memory (size=%d)\n", | 931 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
| 952 | sizeof(stlbrd_t)); | 932 | sizeof(stlbrd_t)); |
| 953 | return NULL; | 933 | return NULL; |
| 954 | } | 934 | } |
| @@ -1066,16 +1046,17 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
| 1066 | rc = 0; | 1046 | rc = 0; |
| 1067 | doclocal = 0; | 1047 | doclocal = 0; |
| 1068 | 1048 | ||
| 1049 | spin_lock_irqsave(&stallion_lock, flags); | ||
| 1050 | |||
| 1069 | if (portp->tty->termios->c_cflag & CLOCAL) | 1051 | if (portp->tty->termios->c_cflag & CLOCAL) |
| 1070 | doclocal++; | 1052 | doclocal++; |
| 1071 | 1053 | ||
| 1072 | save_flags(flags); | ||
| 1073 | cli(); | ||
| 1074 | portp->openwaitcnt++; | 1054 | portp->openwaitcnt++; |
| 1075 | if (! tty_hung_up_p(filp)) | 1055 | if (! tty_hung_up_p(filp)) |
| 1076 | portp->refcount--; | 1056 | portp->refcount--; |
| 1077 | 1057 | ||
| 1078 | for (;;) { | 1058 | for (;;) { |
| 1059 | /* Takes brd_lock internally */ | ||
| 1079 | stl_setsignals(portp, 1, 1); | 1060 | stl_setsignals(portp, 1, 1); |
| 1080 | if (tty_hung_up_p(filp) || | 1061 | if (tty_hung_up_p(filp) || |
| 1081 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { | 1062 | ((portp->flags & ASYNC_INITIALIZED) == 0)) { |
| @@ -1093,13 +1074,14 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
| 1093 | rc = -ERESTARTSYS; | 1074 | rc = -ERESTARTSYS; |
| 1094 | break; | 1075 | break; |
| 1095 | } | 1076 | } |
| 1077 | /* FIXME */ | ||
| 1096 | interruptible_sleep_on(&portp->open_wait); | 1078 | interruptible_sleep_on(&portp->open_wait); |
| 1097 | } | 1079 | } |
| 1098 | 1080 | ||
| 1099 | if (! tty_hung_up_p(filp)) | 1081 | if (! tty_hung_up_p(filp)) |
| 1100 | portp->refcount++; | 1082 | portp->refcount++; |
| 1101 | portp->openwaitcnt--; | 1083 | portp->openwaitcnt--; |
| 1102 | restore_flags(flags); | 1084 | spin_unlock_irqrestore(&stallion_lock, flags); |
| 1103 | 1085 | ||
| 1104 | return rc; | 1086 | return rc; |
| 1105 | } | 1087 | } |
| @@ -1119,16 +1101,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
| 1119 | if (portp == (stlport_t *) NULL) | 1101 | if (portp == (stlport_t *) NULL) |
| 1120 | return; | 1102 | return; |
| 1121 | 1103 | ||
| 1122 | save_flags(flags); | 1104 | spin_lock_irqsave(&stallion_lock, flags); |
| 1123 | cli(); | ||
| 1124 | if (tty_hung_up_p(filp)) { | 1105 | if (tty_hung_up_p(filp)) { |
| 1125 | restore_flags(flags); | 1106 | spin_unlock_irqrestore(&stallion_lock, flags); |
| 1126 | return; | 1107 | return; |
| 1127 | } | 1108 | } |
| 1128 | if ((tty->count == 1) && (portp->refcount != 1)) | 1109 | if ((tty->count == 1) && (portp->refcount != 1)) |
| 1129 | portp->refcount = 1; | 1110 | portp->refcount = 1; |
| 1130 | if (portp->refcount-- > 1) { | 1111 | if (portp->refcount-- > 1) { |
| 1131 | restore_flags(flags); | 1112 | spin_unlock_irqrestore(&stallion_lock, flags); |
| 1132 | return; | 1113 | return; |
| 1133 | } | 1114 | } |
| 1134 | 1115 | ||
| @@ -1142,11 +1123,18 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
| 1142 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) | 1123 | * (The sc26198 has no "end-of-data" interrupt only empty FIFO) |
| 1143 | */ | 1124 | */ |
| 1144 | tty->closing = 1; | 1125 | tty->closing = 1; |
| 1126 | |||
| 1127 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
| 1128 | |||
| 1145 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) | 1129 | if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) |
| 1146 | tty_wait_until_sent(tty, portp->closing_wait); | 1130 | tty_wait_until_sent(tty, portp->closing_wait); |
| 1147 | stl_waituntilsent(tty, (HZ / 2)); | 1131 | stl_waituntilsent(tty, (HZ / 2)); |
| 1148 | 1132 | ||
| 1133 | |||
| 1134 | spin_lock_irqsave(&stallion_lock, flags); | ||
| 1149 | portp->flags &= ~ASYNC_INITIALIZED; | 1135 | portp->flags &= ~ASYNC_INITIALIZED; |
| 1136 | spin_unlock_irqrestore(&stallion_lock, flags); | ||
| 1137 | |||
| 1150 | stl_disableintrs(portp); | 1138 | stl_disableintrs(portp); |
| 1151 | if (tty->termios->c_cflag & HUPCL) | 1139 | if (tty->termios->c_cflag & HUPCL) |
| 1152 | stl_setsignals(portp, 0, 0); | 1140 | stl_setsignals(portp, 0, 0); |
| @@ -1173,7 +1161,6 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
| 1173 | 1161 | ||
| 1174 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1162 | portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
| 1175 | wake_up_interruptible(&portp->close_wait); | 1163 | wake_up_interruptible(&portp->close_wait); |
| 1176 | restore_flags(flags); | ||
| 1177 | } | 1164 | } |
| 1178 | 1165 | ||
| 1179 | /*****************************************************************************/ | 1166 | /*****************************************************************************/ |
| @@ -1195,9 +1182,6 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
| 1195 | (int) tty, (int) buf, count); | 1182 | (int) tty, (int) buf, count); |
| 1196 | #endif | 1183 | #endif |
| 1197 | 1184 | ||
| 1198 | if ((tty == (struct tty_struct *) NULL) || | ||
| 1199 | (stl_tmpwritebuf == (char *) NULL)) | ||
| 1200 | return 0; | ||
| 1201 | portp = tty->driver_data; | 1185 | portp = tty->driver_data; |
| 1202 | if (portp == (stlport_t *) NULL) | 1186 | if (portp == (stlport_t *) NULL) |
| 1203 | return 0; | 1187 | return 0; |
| @@ -1302,11 +1286,6 @@ static void stl_flushchars(struct tty_struct *tty) | |||
| 1302 | if (portp->tx.buf == (char *) NULL) | 1286 | if (portp->tx.buf == (char *) NULL) |
| 1303 | return; | 1287 | return; |
| 1304 | 1288 | ||
| 1305 | #if 0 | ||
| 1306 | if (tty->stopped || tty->hw_stopped || | ||
| 1307 | (portp->tx.head == portp->tx.tail)) | ||
| 1308 | return; | ||
| 1309 | #endif | ||
| 1310 | stl_startrxtx(portp, -1, 1); | 1289 | stl_startrxtx(portp, -1, 1); |
| 1311 | } | 1290 | } |
| 1312 | 1291 | ||
| @@ -1977,12 +1956,14 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
| 1977 | unsigned int iobase; | 1956 | unsigned int iobase; |
| 1978 | int handled = 0; | 1957 | int handled = 0; |
| 1979 | 1958 | ||
| 1959 | spin_lock(&brd_lock); | ||
| 1980 | panelp = brdp->panels[0]; | 1960 | panelp = brdp->panels[0]; |
| 1981 | iobase = panelp->iobase; | 1961 | iobase = panelp->iobase; |
| 1982 | while (inb(brdp->iostatus) & EIO_INTRPEND) { | 1962 | while (inb(brdp->iostatus) & EIO_INTRPEND) { |
| 1983 | handled = 1; | 1963 | handled = 1; |
| 1984 | (* panelp->isr)(panelp, iobase); | 1964 | (* panelp->isr)(panelp, iobase); |
| 1985 | } | 1965 | } |
| 1966 | spin_unlock(&brd_lock); | ||
| 1986 | return handled; | 1967 | return handled; |
| 1987 | } | 1968 | } |
| 1988 | 1969 | ||
| @@ -2168,7 +2149,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
| 2168 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 2149 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); |
| 2169 | if (!portp) { | 2150 | if (!portp) { |
| 2170 | printk("STALLION: failed to allocate memory " | 2151 | printk("STALLION: failed to allocate memory " |
| 2171 | "(size=%d)\n", sizeof(stlport_t)); | 2152 | "(size=%Zd)\n", sizeof(stlport_t)); |
| 2172 | break; | 2153 | break; |
| 2173 | } | 2154 | } |
| 2174 | 2155 | ||
| @@ -2304,7 +2285,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
| 2304 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2285 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
| 2305 | if (!panelp) { | 2286 | if (!panelp) { |
| 2306 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 2287 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
| 2307 | "(size=%d)\n", sizeof(stlpanel_t)); | 2288 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
| 2308 | return -ENOMEM; | 2289 | return -ENOMEM; |
| 2309 | } | 2290 | } |
| 2310 | 2291 | ||
| @@ -2478,7 +2459,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
| 2478 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2459 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); |
| 2479 | if (!panelp) { | 2460 | if (!panelp) { |
| 2480 | printk("STALLION: failed to allocate memory " | 2461 | printk("STALLION: failed to allocate memory " |
| 2481 | "(size=%d)\n", sizeof(stlpanel_t)); | 2462 | "(size=%Zd)\n", sizeof(stlpanel_t)); |
| 2482 | break; | 2463 | break; |
| 2483 | } | 2464 | } |
| 2484 | panelp->magic = STL_PANELMAGIC; | 2465 | panelp->magic = STL_PANELMAGIC; |
| @@ -2879,8 +2860,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
| 2879 | portp->stats.lflags = 0; | 2860 | portp->stats.lflags = 0; |
| 2880 | portp->stats.rxbuffered = 0; | 2861 | portp->stats.rxbuffered = 0; |
| 2881 | 2862 | ||
| 2882 | save_flags(flags); | 2863 | spin_lock_irqsave(&stallion_lock, flags); |
| 2883 | cli(); | ||
| 2884 | if (portp->tty != (struct tty_struct *) NULL) { | 2864 | if (portp->tty != (struct tty_struct *) NULL) { |
| 2885 | if (portp->tty->driver_data == portp) { | 2865 | if (portp->tty->driver_data == portp) { |
| 2886 | portp->stats.ttystate = portp->tty->flags; | 2866 | portp->stats.ttystate = portp->tty->flags; |
| @@ -2894,7 +2874,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
| 2894 | } | 2874 | } |
| 2895 | } | 2875 | } |
| 2896 | } | 2876 | } |
| 2897 | restore_flags(flags); | 2877 | spin_unlock_irqrestore(&stallion_lock, flags); |
| 2898 | 2878 | ||
| 2899 | head = portp->tx.head; | 2879 | head = portp->tx.head; |
| 2900 | tail = portp->tx.tail; | 2880 | tail = portp->tx.tail; |
| @@ -3056,14 +3036,6 @@ static int __init stl_init(void) | |||
| 3056 | return -1; | 3036 | return -1; |
| 3057 | 3037 | ||
| 3058 | /* | 3038 | /* |
| 3059 | * Allocate a temporary write buffer. | ||
| 3060 | */ | ||
| 3061 | stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); | ||
| 3062 | if (!stl_tmpwritebuf) | ||
| 3063 | printk("STALLION: failed to allocate memory (size=%d)\n", | ||
| 3064 | STL_TXBUFSIZE); | ||
| 3065 | |||
| 3066 | /* | ||
| 3067 | * Set up a character driver for per board stuff. This is mainly used | 3039 | * Set up a character driver for per board stuff. This is mainly used |
| 3068 | * to do stats ioctls on the ports. | 3040 | * to do stats ioctls on the ports. |
| 3069 | */ | 3041 | */ |
| @@ -3147,11 +3119,13 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
| 3147 | unsigned int gfrcr; | 3119 | unsigned int gfrcr; |
| 3148 | int chipmask, i, j; | 3120 | int chipmask, i, j; |
| 3149 | int nrchips, uartaddr, ioaddr; | 3121 | int nrchips, uartaddr, ioaddr; |
| 3122 | unsigned long flags; | ||
| 3150 | 3123 | ||
| 3151 | #ifdef DEBUG | 3124 | #ifdef DEBUG |
| 3152 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | 3125 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); |
| 3153 | #endif | 3126 | #endif |
| 3154 | 3127 | ||
| 3128 | spin_lock_irqsave(&brd_lock, flags); | ||
| 3155 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3129 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
| 3156 | 3130 | ||
| 3157 | /* | 3131 | /* |
| @@ -3189,6 +3163,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
| 3189 | } | 3163 | } |
| 3190 | 3164 | ||
| 3191 | BRDDISABLE(panelp->brdnr); | 3165 | BRDDISABLE(panelp->brdnr); |
| 3166 | spin_unlock_irqrestore(&brd_lock, flags); | ||
| 3192 | return chipmask; | 3167 | return chipmask; |
| 3193 | } | 3168 | } |
| 3194 | 3169 | ||
| @@ -3200,6 +3175,7 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
| 3200 | 3175 | ||
| 3201 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 3176 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) |
| 3202 | { | 3177 | { |
| 3178 | unsigned long flags; | ||
| 3203 | #ifdef DEBUG | 3179 | #ifdef DEBUG |
| 3204 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3180 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", |
| 3205 | (int) brdp, (int) panelp, (int) portp); | 3181 | (int) brdp, (int) panelp, (int) portp); |
| @@ -3209,6 +3185,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
| 3209 | (portp == (stlport_t *) NULL)) | 3185 | (portp == (stlport_t *) NULL)) |
| 3210 | return; | 3186 | return; |
| 3211 | 3187 | ||
| 3188 | spin_lock_irqsave(&brd_lock, flags); | ||
| 3212 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || | 3189 | portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || |
| 3213 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); | 3190 | (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); |
| 3214 | portp->uartaddr = (portp->portnr & 0x04) << 5; | 3191 | portp->uartaddr = (portp->portnr & 0x04) << 5; |
| @@ -3219,6 +3196,7 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
| 3219 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); | 3196 | stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); |
| 3220 | portp->hwid = stl_cd1400getreg(portp, GFRCR); | 3197 | portp->hwid = stl_cd1400getreg(portp, GFRCR); |
| 3221 | BRDDISABLE(portp->brdnr); | 3198 | BRDDISABLE(portp->brdnr); |
| 3199 | spin_unlock_irqrestore(&brd_lock, flags); | ||
| 3222 | } | 3200 | } |
| 3223 | 3201 | ||
| 3224 | /*****************************************************************************/ | 3202 | /*****************************************************************************/ |
| @@ -3428,8 +3406,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
| 3428 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3406 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
| 3429 | #endif | 3407 | #endif |
| 3430 | 3408 | ||
| 3431 | save_flags(flags); | 3409 | spin_lock_irqsave(&brd_lock, flags); |
| 3432 | cli(); | ||
| 3433 | BRDENABLE(portp->brdnr, portp->pagenr); | 3410 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3434 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); | 3411 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); |
| 3435 | srer = stl_cd1400getreg(portp, SRER); | 3412 | srer = stl_cd1400getreg(portp, SRER); |
| @@ -3466,7 +3443,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
| 3466 | portp->sigs &= ~TIOCM_CD; | 3443 | portp->sigs &= ~TIOCM_CD; |
| 3467 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); | 3444 | stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); |
| 3468 | BRDDISABLE(portp->brdnr); | 3445 | BRDDISABLE(portp->brdnr); |
| 3469 | restore_flags(flags); | 3446 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3470 | } | 3447 | } |
| 3471 | 3448 | ||
| 3472 | /*****************************************************************************/ | 3449 | /*****************************************************************************/ |
| @@ -3492,8 +3469,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
| 3492 | if (rts > 0) | 3469 | if (rts > 0) |
| 3493 | msvr2 = MSVR2_RTS; | 3470 | msvr2 = MSVR2_RTS; |
| 3494 | 3471 | ||
| 3495 | save_flags(flags); | 3472 | spin_lock_irqsave(&brd_lock, flags); |
| 3496 | cli(); | ||
| 3497 | BRDENABLE(portp->brdnr, portp->pagenr); | 3473 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3498 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3474 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3499 | if (rts >= 0) | 3475 | if (rts >= 0) |
| @@ -3501,7 +3477,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
| 3501 | if (dtr >= 0) | 3477 | if (dtr >= 0) |
| 3502 | stl_cd1400setreg(portp, MSVR1, msvr1); | 3478 | stl_cd1400setreg(portp, MSVR1, msvr1); |
| 3503 | BRDDISABLE(portp->brdnr); | 3479 | BRDDISABLE(portp->brdnr); |
| 3504 | restore_flags(flags); | 3480 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3505 | } | 3481 | } |
| 3506 | 3482 | ||
| 3507 | /*****************************************************************************/ | 3483 | /*****************************************************************************/ |
| @@ -3520,14 +3496,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
| 3520 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | 3496 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); |
| 3521 | #endif | 3497 | #endif |
| 3522 | 3498 | ||
| 3523 | save_flags(flags); | 3499 | spin_lock_irqsave(&brd_lock, flags); |
| 3524 | cli(); | ||
| 3525 | BRDENABLE(portp->brdnr, portp->pagenr); | 3500 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3526 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3501 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3527 | msvr1 = stl_cd1400getreg(portp, MSVR1); | 3502 | msvr1 = stl_cd1400getreg(portp, MSVR1); |
| 3528 | msvr2 = stl_cd1400getreg(portp, MSVR2); | 3503 | msvr2 = stl_cd1400getreg(portp, MSVR2); |
| 3529 | BRDDISABLE(portp->brdnr); | 3504 | BRDDISABLE(portp->brdnr); |
| 3530 | restore_flags(flags); | 3505 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3531 | 3506 | ||
| 3532 | sigs = 0; | 3507 | sigs = 0; |
| 3533 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; | 3508 | sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; |
| @@ -3569,15 +3544,14 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
| 3569 | else if (rx > 0) | 3544 | else if (rx > 0) |
| 3570 | ccr |= CCR_RXENABLE; | 3545 | ccr |= CCR_RXENABLE; |
| 3571 | 3546 | ||
| 3572 | save_flags(flags); | 3547 | spin_lock_irqsave(&brd_lock, flags); |
| 3573 | cli(); | ||
| 3574 | BRDENABLE(portp->brdnr, portp->pagenr); | 3548 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3575 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3549 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3576 | stl_cd1400ccrwait(portp); | 3550 | stl_cd1400ccrwait(portp); |
| 3577 | stl_cd1400setreg(portp, CCR, ccr); | 3551 | stl_cd1400setreg(portp, CCR, ccr); |
| 3578 | stl_cd1400ccrwait(portp); | 3552 | stl_cd1400ccrwait(portp); |
| 3579 | BRDDISABLE(portp->brdnr); | 3553 | BRDDISABLE(portp->brdnr); |
| 3580 | restore_flags(flags); | 3554 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3581 | } | 3555 | } |
| 3582 | 3556 | ||
| 3583 | /*****************************************************************************/ | 3557 | /*****************************************************************************/ |
| @@ -3609,8 +3583,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
| 3609 | else if (rx > 0) | 3583 | else if (rx > 0) |
| 3610 | sreron |= SRER_RXDATA; | 3584 | sreron |= SRER_RXDATA; |
| 3611 | 3585 | ||
| 3612 | save_flags(flags); | 3586 | spin_lock_irqsave(&brd_lock, flags); |
| 3613 | cli(); | ||
| 3614 | BRDENABLE(portp->brdnr, portp->pagenr); | 3587 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3615 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3588 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3616 | stl_cd1400setreg(portp, SRER, | 3589 | stl_cd1400setreg(portp, SRER, |
| @@ -3618,7 +3591,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
| 3618 | BRDDISABLE(portp->brdnr); | 3591 | BRDDISABLE(portp->brdnr); |
| 3619 | if (tx > 0) | 3592 | if (tx > 0) |
| 3620 | set_bit(ASYI_TXBUSY, &portp->istate); | 3593 | set_bit(ASYI_TXBUSY, &portp->istate); |
| 3621 | restore_flags(flags); | 3594 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3622 | } | 3595 | } |
| 3623 | 3596 | ||
| 3624 | /*****************************************************************************/ | 3597 | /*****************************************************************************/ |
| @@ -3634,13 +3607,12 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
| 3634 | #ifdef DEBUG | 3607 | #ifdef DEBUG |
| 3635 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3608 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); |
| 3636 | #endif | 3609 | #endif |
| 3637 | save_flags(flags); | 3610 | spin_lock_irqsave(&brd_lock, flags); |
| 3638 | cli(); | ||
| 3639 | BRDENABLE(portp->brdnr, portp->pagenr); | 3611 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3640 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3612 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3641 | stl_cd1400setreg(portp, SRER, 0); | 3613 | stl_cd1400setreg(portp, SRER, 0); |
| 3642 | BRDDISABLE(portp->brdnr); | 3614 | BRDDISABLE(portp->brdnr); |
| 3643 | restore_flags(flags); | 3615 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3644 | } | 3616 | } |
| 3645 | 3617 | ||
| 3646 | /*****************************************************************************/ | 3618 | /*****************************************************************************/ |
| @@ -3653,8 +3625,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
| 3653 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 3625 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
| 3654 | #endif | 3626 | #endif |
| 3655 | 3627 | ||
| 3656 | save_flags(flags); | 3628 | spin_lock_irqsave(&brd_lock, flags); |
| 3657 | cli(); | ||
| 3658 | BRDENABLE(portp->brdnr, portp->pagenr); | 3629 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3659 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3630 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3660 | stl_cd1400setreg(portp, SRER, | 3631 | stl_cd1400setreg(portp, SRER, |
| @@ -3664,7 +3635,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
| 3664 | portp->brklen = len; | 3635 | portp->brklen = len; |
| 3665 | if (len == 1) | 3636 | if (len == 1) |
| 3666 | portp->stats.txbreaks++; | 3637 | portp->stats.txbreaks++; |
| 3667 | restore_flags(flags); | 3638 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3668 | } | 3639 | } |
| 3669 | 3640 | ||
| 3670 | /*****************************************************************************/ | 3641 | /*****************************************************************************/ |
| @@ -3688,8 +3659,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
| 3688 | if (tty == (struct tty_struct *) NULL) | 3659 | if (tty == (struct tty_struct *) NULL) |
| 3689 | return; | 3660 | return; |
| 3690 | 3661 | ||
| 3691 | save_flags(flags); | 3662 | spin_lock_irqsave(&brd_lock, flags); |
| 3692 | cli(); | ||
| 3693 | BRDENABLE(portp->brdnr, portp->pagenr); | 3663 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3694 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3664 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3695 | 3665 | ||
| @@ -3729,7 +3699,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
| 3729 | } | 3699 | } |
| 3730 | 3700 | ||
| 3731 | BRDDISABLE(portp->brdnr); | 3701 | BRDDISABLE(portp->brdnr); |
| 3732 | restore_flags(flags); | 3702 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3733 | } | 3703 | } |
| 3734 | 3704 | ||
| 3735 | /*****************************************************************************/ | 3705 | /*****************************************************************************/ |
| @@ -3753,8 +3723,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
| 3753 | if (tty == (struct tty_struct *) NULL) | 3723 | if (tty == (struct tty_struct *) NULL) |
| 3754 | return; | 3724 | return; |
| 3755 | 3725 | ||
| 3756 | save_flags(flags); | 3726 | spin_lock_irqsave(&brd_lock, flags); |
| 3757 | cli(); | ||
| 3758 | BRDENABLE(portp->brdnr, portp->pagenr); | 3727 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3728 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3760 | if (state) { | 3729 | if (state) { |
| @@ -3769,7 +3738,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
| 3769 | stl_cd1400ccrwait(portp); | 3738 | stl_cd1400ccrwait(portp); |
| 3770 | } | 3739 | } |
| 3771 | BRDDISABLE(portp->brdnr); | 3740 | BRDDISABLE(portp->brdnr); |
| 3772 | restore_flags(flags); | 3741 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3773 | } | 3742 | } |
| 3774 | 3743 | ||
| 3775 | /*****************************************************************************/ | 3744 | /*****************************************************************************/ |
| @@ -3785,8 +3754,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
| 3785 | if (portp == (stlport_t *) NULL) | 3754 | if (portp == (stlport_t *) NULL) |
| 3786 | return; | 3755 | return; |
| 3787 | 3756 | ||
| 3788 | save_flags(flags); | 3757 | spin_lock_irqsave(&brd_lock, flags); |
| 3789 | cli(); | ||
| 3790 | BRDENABLE(portp->brdnr, portp->pagenr); | 3758 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 3791 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3759 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
| 3792 | stl_cd1400ccrwait(portp); | 3760 | stl_cd1400ccrwait(portp); |
| @@ -3794,7 +3762,7 @@ static void stl_cd1400flush(stlport_t *portp) | |||
| 3794 | stl_cd1400ccrwait(portp); | 3762 | stl_cd1400ccrwait(portp); |
| 3795 | portp->tx.tail = portp->tx.head; | 3763 | portp->tx.tail = portp->tx.head; |
| 3796 | BRDDISABLE(portp->brdnr); | 3764 | BRDDISABLE(portp->brdnr); |
| 3797 | restore_flags(flags); | 3765 | spin_unlock_irqrestore(&brd_lock, flags); |
| 3798 | } | 3766 | } |
| 3799 | 3767 | ||
| 3800 | /*****************************************************************************/ | 3768 | /*****************************************************************************/ |
| @@ -3833,6 +3801,7 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
| 3833 | (int) panelp, iobase); | 3801 | (int) panelp, iobase); |
| 3834 | #endif | 3802 | #endif |
| 3835 | 3803 | ||
| 3804 | spin_lock(&brd_lock); | ||
| 3836 | outb(SVRR, iobase); | 3805 | outb(SVRR, iobase); |
| 3837 | svrtype = inb(iobase + EREG_DATA); | 3806 | svrtype = inb(iobase + EREG_DATA); |
| 3838 | if (panelp->nrports > 4) { | 3807 | if (panelp->nrports > 4) { |
| @@ -3846,6 +3815,8 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
| 3846 | stl_cd1400txisr(panelp, iobase); | 3815 | stl_cd1400txisr(panelp, iobase); |
| 3847 | else if (svrtype & SVRR_MDM) | 3816 | else if (svrtype & SVRR_MDM) |
| 3848 | stl_cd1400mdmisr(panelp, iobase); | 3817 | stl_cd1400mdmisr(panelp, iobase); |
| 3818 | |||
| 3819 | spin_unlock(&brd_lock); | ||
| 3849 | } | 3820 | } |
| 3850 | 3821 | ||
| 3851 | /*****************************************************************************/ | 3822 | /*****************************************************************************/ |
| @@ -4433,8 +4404,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
| 4433 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 4404 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
| 4434 | #endif | 4405 | #endif |
| 4435 | 4406 | ||
| 4436 | save_flags(flags); | 4407 | spin_lock_irqsave(&brd_lock, flags); |
| 4437 | cli(); | ||
| 4438 | BRDENABLE(portp->brdnr, portp->pagenr); | 4408 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4439 | stl_sc26198setreg(portp, IMR, 0); | 4409 | stl_sc26198setreg(portp, IMR, 0); |
| 4440 | stl_sc26198updatereg(portp, MR0, mr0); | 4410 | stl_sc26198updatereg(portp, MR0, mr0); |
| @@ -4461,7 +4431,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
| 4461 | portp->imr = (portp->imr & ~imroff) | imron; | 4431 | portp->imr = (portp->imr & ~imroff) | imron; |
| 4462 | stl_sc26198setreg(portp, IMR, portp->imr); | 4432 | stl_sc26198setreg(portp, IMR, portp->imr); |
| 4463 | BRDDISABLE(portp->brdnr); | 4433 | BRDDISABLE(portp->brdnr); |
| 4464 | restore_flags(flags); | 4434 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4465 | } | 4435 | } |
| 4466 | 4436 | ||
| 4467 | /*****************************************************************************/ | 4437 | /*****************************************************************************/ |
| @@ -4491,13 +4461,12 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
| 4491 | else if (rts > 0) | 4461 | else if (rts > 0) |
| 4492 | iopioron |= IPR_RTS; | 4462 | iopioron |= IPR_RTS; |
| 4493 | 4463 | ||
| 4494 | save_flags(flags); | 4464 | spin_lock_irqsave(&brd_lock, flags); |
| 4495 | cli(); | ||
| 4496 | BRDENABLE(portp->brdnr, portp->pagenr); | 4465 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4497 | stl_sc26198setreg(portp, IOPIOR, | 4466 | stl_sc26198setreg(portp, IOPIOR, |
| 4498 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); | 4467 | ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); |
| 4499 | BRDDISABLE(portp->brdnr); | 4468 | BRDDISABLE(portp->brdnr); |
| 4500 | restore_flags(flags); | 4469 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4501 | } | 4470 | } |
| 4502 | 4471 | ||
| 4503 | /*****************************************************************************/ | 4472 | /*****************************************************************************/ |
| @@ -4516,12 +4485,11 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
| 4516 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | 4485 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); |
| 4517 | #endif | 4486 | #endif |
| 4518 | 4487 | ||
| 4519 | save_flags(flags); | 4488 | spin_lock_irqsave(&brd_lock, flags); |
| 4520 | cli(); | ||
| 4521 | BRDENABLE(portp->brdnr, portp->pagenr); | 4489 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4522 | ipr = stl_sc26198getreg(portp, IPR); | 4490 | ipr = stl_sc26198getreg(portp, IPR); |
| 4523 | BRDDISABLE(portp->brdnr); | 4491 | BRDDISABLE(portp->brdnr); |
| 4524 | restore_flags(flags); | 4492 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4525 | 4493 | ||
| 4526 | sigs = 0; | 4494 | sigs = 0; |
| 4527 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; | 4495 | sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; |
| @@ -4558,13 +4526,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
| 4558 | else if (rx > 0) | 4526 | else if (rx > 0) |
| 4559 | ccr |= CR_RXENABLE; | 4527 | ccr |= CR_RXENABLE; |
| 4560 | 4528 | ||
| 4561 | save_flags(flags); | 4529 | spin_lock_irqsave(&brd_lock, flags); |
| 4562 | cli(); | ||
| 4563 | BRDENABLE(portp->brdnr, portp->pagenr); | 4530 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4564 | stl_sc26198setreg(portp, SCCR, ccr); | 4531 | stl_sc26198setreg(portp, SCCR, ccr); |
| 4565 | BRDDISABLE(portp->brdnr); | 4532 | BRDDISABLE(portp->brdnr); |
| 4566 | portp->crenable = ccr; | 4533 | portp->crenable = ccr; |
| 4567 | restore_flags(flags); | 4534 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4568 | } | 4535 | } |
| 4569 | 4536 | ||
| 4570 | /*****************************************************************************/ | 4537 | /*****************************************************************************/ |
| @@ -4593,15 +4560,14 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
| 4593 | else if (rx > 0) | 4560 | else if (rx > 0) |
| 4594 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; | 4561 | imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; |
| 4595 | 4562 | ||
| 4596 | save_flags(flags); | 4563 | spin_lock_irqsave(&brd_lock, flags); |
| 4597 | cli(); | ||
| 4598 | BRDENABLE(portp->brdnr, portp->pagenr); | 4564 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4599 | stl_sc26198setreg(portp, IMR, imr); | 4565 | stl_sc26198setreg(portp, IMR, imr); |
| 4600 | BRDDISABLE(portp->brdnr); | 4566 | BRDDISABLE(portp->brdnr); |
| 4601 | portp->imr = imr; | 4567 | portp->imr = imr; |
| 4602 | if (tx > 0) | 4568 | if (tx > 0) |
| 4603 | set_bit(ASYI_TXBUSY, &portp->istate); | 4569 | set_bit(ASYI_TXBUSY, &portp->istate); |
| 4604 | restore_flags(flags); | 4570 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4605 | } | 4571 | } |
| 4606 | 4572 | ||
| 4607 | /*****************************************************************************/ | 4573 | /*****************************************************************************/ |
| @@ -4618,13 +4584,12 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
| 4618 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | 4584 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); |
| 4619 | #endif | 4585 | #endif |
| 4620 | 4586 | ||
| 4621 | save_flags(flags); | 4587 | spin_lock_irqsave(&brd_lock, flags); |
| 4622 | cli(); | ||
| 4623 | BRDENABLE(portp->brdnr, portp->pagenr); | 4588 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4624 | portp->imr = 0; | 4589 | portp->imr = 0; |
| 4625 | stl_sc26198setreg(portp, IMR, 0); | 4590 | stl_sc26198setreg(portp, IMR, 0); |
| 4626 | BRDDISABLE(portp->brdnr); | 4591 | BRDDISABLE(portp->brdnr); |
| 4627 | restore_flags(flags); | 4592 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4628 | } | 4593 | } |
| 4629 | 4594 | ||
| 4630 | /*****************************************************************************/ | 4595 | /*****************************************************************************/ |
| @@ -4637,8 +4602,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
| 4637 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | 4602 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); |
| 4638 | #endif | 4603 | #endif |
| 4639 | 4604 | ||
| 4640 | save_flags(flags); | 4605 | spin_lock_irqsave(&brd_lock, flags); |
| 4641 | cli(); | ||
| 4642 | BRDENABLE(portp->brdnr, portp->pagenr); | 4606 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4643 | if (len == 1) { | 4607 | if (len == 1) { |
| 4644 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4608 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
| @@ -4647,7 +4611,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
| 4647 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4611 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
| 4648 | } | 4612 | } |
| 4649 | BRDDISABLE(portp->brdnr); | 4613 | BRDDISABLE(portp->brdnr); |
| 4650 | restore_flags(flags); | 4614 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4651 | } | 4615 | } |
| 4652 | 4616 | ||
| 4653 | /*****************************************************************************/ | 4617 | /*****************************************************************************/ |
| @@ -4672,8 +4636,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
| 4672 | if (tty == (struct tty_struct *) NULL) | 4636 | if (tty == (struct tty_struct *) NULL) |
| 4673 | return; | 4637 | return; |
| 4674 | 4638 | ||
| 4675 | save_flags(flags); | 4639 | spin_lock_irqsave(&brd_lock, flags); |
| 4676 | cli(); | ||
| 4677 | BRDENABLE(portp->brdnr, portp->pagenr); | 4640 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4678 | 4641 | ||
| 4679 | if (state) { | 4642 | if (state) { |
| @@ -4719,7 +4682,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
| 4719 | } | 4682 | } |
| 4720 | 4683 | ||
| 4721 | BRDDISABLE(portp->brdnr); | 4684 | BRDDISABLE(portp->brdnr); |
| 4722 | restore_flags(flags); | 4685 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4723 | } | 4686 | } |
| 4724 | 4687 | ||
| 4725 | /*****************************************************************************/ | 4688 | /*****************************************************************************/ |
| @@ -4744,8 +4707,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
| 4744 | if (tty == (struct tty_struct *) NULL) | 4707 | if (tty == (struct tty_struct *) NULL) |
| 4745 | return; | 4708 | return; |
| 4746 | 4709 | ||
| 4747 | save_flags(flags); | 4710 | spin_lock_irqsave(&brd_lock, flags); |
| 4748 | cli(); | ||
| 4749 | BRDENABLE(portp->brdnr, portp->pagenr); | 4711 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4750 | if (state) { | 4712 | if (state) { |
| 4751 | mr0 = stl_sc26198getreg(portp, MR0); | 4713 | mr0 = stl_sc26198getreg(portp, MR0); |
| @@ -4765,7 +4727,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
| 4765 | stl_sc26198setreg(portp, MR0, mr0); | 4727 | stl_sc26198setreg(portp, MR0, mr0); |
| 4766 | } | 4728 | } |
| 4767 | BRDDISABLE(portp->brdnr); | 4729 | BRDDISABLE(portp->brdnr); |
| 4768 | restore_flags(flags); | 4730 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4769 | } | 4731 | } |
| 4770 | 4732 | ||
| 4771 | /*****************************************************************************/ | 4733 | /*****************************************************************************/ |
| @@ -4781,14 +4743,13 @@ static void stl_sc26198flush(stlport_t *portp) | |||
| 4781 | if (portp == (stlport_t *) NULL) | 4743 | if (portp == (stlport_t *) NULL) |
| 4782 | return; | 4744 | return; |
| 4783 | 4745 | ||
| 4784 | save_flags(flags); | 4746 | spin_lock_irqsave(&brd_lock, flags); |
| 4785 | cli(); | ||
| 4786 | BRDENABLE(portp->brdnr, portp->pagenr); | 4747 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4787 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); | 4748 | stl_sc26198setreg(portp, SCCR, CR_TXRESET); |
| 4788 | stl_sc26198setreg(portp, SCCR, portp->crenable); | 4749 | stl_sc26198setreg(portp, SCCR, portp->crenable); |
| 4789 | BRDDISABLE(portp->brdnr); | 4750 | BRDDISABLE(portp->brdnr); |
| 4790 | portp->tx.tail = portp->tx.head; | 4751 | portp->tx.tail = portp->tx.head; |
| 4791 | restore_flags(flags); | 4752 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4792 | } | 4753 | } |
| 4793 | 4754 | ||
| 4794 | /*****************************************************************************/ | 4755 | /*****************************************************************************/ |
| @@ -4815,12 +4776,11 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
| 4815 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4776 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
| 4816 | return 1; | 4777 | return 1; |
| 4817 | 4778 | ||
| 4818 | save_flags(flags); | 4779 | spin_lock_irqsave(&brd_lock, flags); |
| 4819 | cli(); | ||
| 4820 | BRDENABLE(portp->brdnr, portp->pagenr); | 4780 | BRDENABLE(portp->brdnr, portp->pagenr); |
| 4821 | sr = stl_sc26198getreg(portp, SR); | 4781 | sr = stl_sc26198getreg(portp, SR); |
| 4822 | BRDDISABLE(portp->brdnr); | 4782 | BRDDISABLE(portp->brdnr); |
| 4823 | restore_flags(flags); | 4783 | spin_unlock_irqrestore(&brd_lock, flags); |
| 4824 | 4784 | ||
| 4825 | return (sr & SR_TXEMPTY) ? 0 : 1; | 4785 | return (sr & SR_TXEMPTY) ? 0 : 1; |
| 4826 | } | 4786 | } |
| @@ -4878,6 +4838,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
| 4878 | stlport_t *portp; | 4838 | stlport_t *portp; |
| 4879 | unsigned int iack; | 4839 | unsigned int iack; |
| 4880 | 4840 | ||
| 4841 | spin_lock(&brd_lock); | ||
| 4842 | |||
| 4881 | /* | 4843 | /* |
| 4882 | * Work around bug in sc26198 chip... Cannot have A6 address | 4844 | * Work around bug in sc26198 chip... Cannot have A6 address |
| 4883 | * line of UART high, else iack will be returned as 0. | 4845 | * line of UART high, else iack will be returned as 0. |
| @@ -4893,6 +4855,8 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
| 4893 | stl_sc26198txisr(portp); | 4855 | stl_sc26198txisr(portp); |
| 4894 | else | 4856 | else |
| 4895 | stl_sc26198otherisr(portp, iack); | 4857 | stl_sc26198otherisr(portp, iack); |
| 4858 | |||
| 4859 | spin_unlock(&brd_lock); | ||
| 4896 | } | 4860 | } |
| 4897 | 4861 | ||
| 4898 | /*****************************************************************************/ | 4862 | /*****************************************************************************/ |
