1 Index: nozomi-060209/nozomi.c
2 ===================================================================
3 --- nozomi-060209.orig/nozomi.c 2007-06-04 13:22:47.338658712 +0200
4 +++ nozomi-060209/nozomi.c 2007-06-04 13:22:47.527629984 +0200
7 * Maintained by: Paul Hardwick, p.hardwick@option.com
10 + * Locking code changes for Vodafone, Andrew Bird & Phil Sanderson
12 * Source has been ported from an implementation made by Filip Aben, f.aben@option.com
14 * --------------------------------------------------------------------------
16 #include <linux/interrupt.h>
17 #include <linux/kmod.h>
18 #include <linux/proc_fs.h>
19 +#include <linux/init.h>
20 #include <asm/uaccess.h>
24 /* TODO: rewrite to optimize macros... */
25 #define SET_FCR(value__) \
27 - writew((value__), (void*) (dc->REG_FCR )); \
28 + writew((value__), (dc->REG_FCR )); \
31 #define SET_IER(value__, mask__) \
33 dc->ier_last_written = (dc->ier_last_written & ~mask__) | (value__ & mask__ );\
34 - writew( dc->ier_last_written, (void*) (dc->REG_IER));\
35 + writew( dc->ier_last_written, (dc->REG_IER));\
38 #define GET_IER(read_val__) \
40 - (read_val__) = readw((void*) (dc->REG_IER));\
41 + (read_val__) = readw((dc->REG_IER));\
44 #define GET_IIR(read_val__) \
46 - (read_val__) = readw((void*) (dc->REG_IIR));\
47 + (read_val__) = readw( (dc->REG_IIR));\
50 #define GET_MEM(value__, addr__, length__) \
52 /* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */
54 F32_2 = 2048, /* Has 512 bytes downlink and uplink * 2 -> 2048 */
55 - F32_8 = 9192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
56 + F32_8 = 8192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
59 /* Two different toggle channels exist */
64 - /* Register addresses */
68 + /* Pointers to registers ( register is tagged volatile, not pointer ) */
69 + volatile u16 * REG_IIR;
70 + volatile u16 * REG_FCR;
71 + volatile u16 * REG_IER;
73 - volatile u16 ier_last_written;
74 + u16 ier_last_written;
75 card_type_t card_type;
76 config_table_t config_table; /* Configuration table */
80 /* Used to store interrupt variables */
82 - volatile u16 read_iir; /* Holds current interrupt tokens */
83 + u16 read_iir; /* Holds current interrupt tokens */
86 MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
88 u32 offset = dc->base_addr + dc->card_type/2;
91 - dc->REG_FCR = offset + R_FCR;
92 - dc->REG_IIR = offset + R_IIR;
93 - dc->REG_IER = offset + R_IER;
94 + dc->REG_FCR = (u16 *) (offset + R_FCR);
95 + dc->REG_IIR = (u16 *) (offset + R_IIR);
96 + dc->REG_IER = (u16 *) (offset + R_IER);
97 dc->ier_last_written = 0;
100 @@ -1366,13 +1370,16 @@
101 static void tty_flip_queue_function(void *tmp_dc) {
102 dc_t *dc = (dc_t*) tmp_dc;
106 /* Enable interrupt for that port */
107 for(i=0;i<MAX_PORT;i++) {
108 if (dc->port[i].tty_dont_flip) {
109 D6("Enable for port: %d", i);
110 dc->port[i].tty_dont_flip = 0;
111 + spin_lock_irqsave(&dc->spin_mutex, flags);
112 enable_transmit_dl(dc->port[i].tty_index, dc);
113 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
117 @@ -1555,7 +1562,11 @@
119 static void tty_do_close(dc_t *dc, port_t *port) {
121 - down(&port->tty_sem);
124 + if(down_interruptible(&port->tty_sem)){
128 if ( !port->tty_open_count ) {
130 @@ -1569,7 +1580,9 @@
132 if ( port->tty_open_count == 0) {
133 D1("close: %d", port->token_dl );
134 + spin_lock_irqsave(&dc->spin_mutex, flags);
135 SET_IER( 0, port->token_dl );
136 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
140 @@ -1679,8 +1692,11 @@
141 s32 index = get_index(tty);
142 port_t *port = get_port_by_tty(tty);
143 dc_t *dc = get_dc_by_tty(tty);
146 - down(&port->tty_sem);
147 + if(down_interruptible(&port->tty_sem)){
148 + return -ERESTARTSYS;
151 tty->low_latency = 1;
152 tty->driver_data = port;
153 @@ -1698,7 +1714,9 @@
154 if ( port->tty_open_count == 1) {
155 port->rx_data = port->tx_data = 0;
156 D1("open: %d", port->token_dl );
157 + spin_lock_irqsave(&dc->spin_mutex, flags);
158 SET_IER( port->token_dl, port->token_dl );
159 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
163 @@ -1722,6 +1740,7 @@
165 dc_t *dc = get_dc_by_tty(tty);
166 port_t *port = (port_t *) tty->driver_data;
169 /* D1( "WRITEx: %d, index = %d", count, index); */
171 @@ -1729,7 +1748,10 @@
175 - down(&port->tty_sem);
176 + if(down_trylock(&port->tty_sem) ) { // must test lock as tty layer wraps calls to this function with BKL
177 + ERR("Would have deadlocked - return ERESTARTSYS");
178 + return -ERESTARTSYS;
181 if (! port->tty_open_count) {
183 @@ -1752,6 +1774,7 @@
187 + spin_lock_irqsave(&dc->spin_mutex, flags);
188 // CTS is only valid on the modem channel
189 if ( port == &(dc->port[PORT_MDM]) ) {
190 if ( port->ctrl_dl.CTS ) {
191 @@ -1763,6 +1786,7 @@
193 enable_transmit_ul(port->tty_index, dc );
195 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
199 @@ -1782,7 +1806,9 @@
203 - down(&port->tty_sem);
204 + if(down_interruptible(&port->tty_sem)){
208 if (! port->tty_open_count) {
210 @@ -1969,6 +1995,8 @@
212 static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) {
213 port_t *port = (port_t *) tty->driver_data;
214 + dc_t *dc = get_dc_by_tty(tty);
217 int rval = -ENOIOCTLCMD;
219 @@ -1991,7 +2019,9 @@
220 rval = ntty_ioctl_tiocgicount(tty, file, cmd, arg);
223 + spin_lock_irqsave(&dc->spin_mutex, flags);
224 rval = ntty_tiocmget(tty, file);
225 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
228 rval = ntty_tiocmset(tty, file, arg);
229 @@ -2000,20 +2030,24 @@
230 if (get_user(mask, (unsigned long *) arg))
233 + spin_lock_irqsave(&dc->spin_mutex, flags);
234 if (mask & TIOCM_RTS)
235 set_rts(port->tty_index, 0);
236 if (mask & TIOCM_DTR)
237 set_dtr(port->tty_index, 0);
238 + spin_unlock_irqrestore(&dc->spin_mutex, flags);
242 if (get_user(mask, (unsigned long *) arg))
245 + spin_lock_irqsave(&dc->spin_mutex, flags);
246 if (mask & TIOCM_RTS)
247 set_rts(port->tty_index, 1);
248 if (mask & TIOCM_DTR)
249 set_dtr(port->tty_index, 1);
250 + spin_unlock_irqrestore(&dc->spin_mutex, flags);