Root/package/nozomi/patches/002-nozomi_vf_01.patch

1--- a/nozomi.c
2+++ b/nozomi.c
3@@ -7,6 +7,9 @@
4  *
5  * Maintained by: Paul Hardwick, p.hardwick@option.com
6  *
7+ * Patches:
8+ * Locking code changes for Vodafone, Andrew Bird & Phil Sanderson
9+ *
10  * Source has been ported from an implementation made by Filip Aben, f.aben@option.com
11  *
12  * --------------------------------------------------------------------------
13@@ -61,6 +64,7 @@
14 #include <linux/interrupt.h>
15 #include <linux/kmod.h>
16 #include <linux/proc_fs.h>
17+#include <linux/init.h>
18 #include <asm/uaccess.h>
19 
20 
21@@ -133,23 +137,23 @@ static int nzdebug = NOZOMI_DEBUG_LEVEL;
22 /* TODO: rewrite to optimize macros... */
23 #define SET_FCR(value__) \
24   do { \
25- writew((value__), (void*) (dc->REG_FCR )); \
26+ writew((value__), (dc->REG_FCR )); \
27 } while(0)
28 
29 #define SET_IER(value__, mask__) \
30   do { \
31     dc->ier_last_written = (dc->ier_last_written & ~mask__) | (value__ & mask__ );\
32- writew( dc->ier_last_written, (void*) (dc->REG_IER));\
33+ writew( dc->ier_last_written, (dc->REG_IER));\
34 } while(0)
35 
36 #define GET_IER(read_val__) \
37   do { \
38- (read_val__) = readw((void*) (dc->REG_IER));\
39+ (read_val__) = readw((dc->REG_IER));\
40 } while(0)
41 
42 #define GET_IIR(read_val__) \
43   do { \
44- (read_val__) = readw((void*) (dc->REG_IIR));\
45+ (read_val__) = readw( (dc->REG_IIR));\
46 } while(0)
47 
48 #define GET_MEM(value__, addr__, length__) \
49@@ -265,7 +269,7 @@ static int nzdebug = NOZOMI_DEBUG_LEVEL;
50 /* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */
51 typedef enum {
52     F32_2 = 2048, /* Has 512 bytes downlink and uplink * 2 -> 2048 */
53- F32_8 = 9192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
54+ F32_8 = 8192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
55 } card_type_t;
56 
57 /* Two different toggle channels exist */
58@@ -438,12 +442,12 @@ typedef struct {
59     u32 base_addr;
60     u8 closing;
61 
62- /* Register addresses */
63- u32 REG_IIR;
64- u32 REG_FCR;
65- u32 REG_IER;
66+ /* Pointers to registers ( register is tagged volatile, not pointer ) */
67+ volatile u16 * REG_IIR;
68+ volatile u16 * REG_FCR;
69+ volatile u16 * REG_IER;
70 
71- volatile u16 ier_last_written;
72+ u16 ier_last_written;
73     card_type_t card_type;
74     config_table_t config_table; /* Configuration table */
75     struct pci_dev *pdev;
76@@ -490,7 +494,7 @@ static struct pci_device_id nozomi_pci_t
77 
78 /* Used to store interrupt variables */
79 typedef struct {
80- volatile u16 read_iir; /* Holds current interrupt tokens */
81+ u16 read_iir; /* Holds current interrupt tokens */
82 } irq_t;
83 
84 MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
85@@ -1345,9 +1349,9 @@ void nozomi_setup_private_data(dc_t *dc)
86     u32 offset = dc->base_addr + dc->card_type/2;
87     int i;
88 
89- dc->REG_FCR = offset + R_FCR;
90- dc->REG_IIR = offset + R_IIR;
91- dc->REG_IER = offset + R_IER;
92+ dc->REG_FCR = (u16 *) (offset + R_FCR);
93+ dc->REG_IIR = (u16 *) (offset + R_IIR);
94+ dc->REG_IER = (u16 *) (offset + R_IER);
95     dc->ier_last_written = 0;
96     dc->closing = 0;
97 
98@@ -1366,13 +1370,16 @@ void nozomi_setup_private_data(dc_t *dc)
99 static void tty_flip_queue_function(void *tmp_dc) {
100     dc_t *dc = (dc_t*) tmp_dc;
101     int i;
102+ u32 flags;
103 
104     /* Enable interrupt for that port */
105     for(i=0;i<MAX_PORT;i++) {
106         if (dc->port[i].tty_dont_flip) {
107             D6("Enable for port: %d", i);
108             dc->port[i].tty_dont_flip = 0;
109+ spin_lock_irqsave(&dc->spin_mutex, flags);
110             enable_transmit_dl(dc->port[i].tty_index, dc);
111+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
112         }
113     }
114 }
115@@ -1555,7 +1562,11 @@ err_disable_device:
116 
117 static void tty_do_close(dc_t *dc, port_t *port) {
118 
119- down(&port->tty_sem);
120+ u32 flags;
121+
122+ if(down_interruptible(&port->tty_sem)){
123+ return;
124+ }
125 
126     if ( !port->tty_open_count ) {
127         goto exit;
128@@ -1569,7 +1580,9 @@ static void tty_do_close(dc_t *dc, port_
129 
130     if ( port->tty_open_count == 0) {
131         D1("close: %d", port->token_dl );
132+ spin_lock_irqsave(&dc->spin_mutex, flags);
133         SET_IER( 0, port->token_dl );
134+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
135     }
136 
137 exit:
138@@ -1679,8 +1692,11 @@ static int ntty_open(struct tty_struct *
139     s32 index = get_index(tty);
140     port_t *port = get_port_by_tty(tty);
141     dc_t *dc = get_dc_by_tty(tty);
142+ u32 flags;
143 
144- down(&port->tty_sem);
145+ if(down_interruptible(&port->tty_sem)){
146+ return -ERESTARTSYS;
147+ }
148 
149     tty->low_latency = 1;
150     tty->driver_data = port;
151@@ -1698,7 +1714,9 @@ static int ntty_open(struct tty_struct *
152     if ( port->tty_open_count == 1) {
153         port->rx_data = port->tx_data = 0;
154         D1("open: %d", port->token_dl );
155+ spin_lock_irqsave(&dc->spin_mutex, flags);
156         SET_IER( port->token_dl, port->token_dl );
157+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
158     }
159 
160     up(&port->tty_sem);
161@@ -1722,6 +1740,7 @@ static s32 ntty_write(struct tty_struct
162     int rval = -EINVAL;
163     dc_t *dc = get_dc_by_tty(tty);
164     port_t *port = (port_t *) tty->driver_data;
165+ u32 flags;
166 
167     /* D1( "WRITEx: %d, index = %d", count, index); */
168 
169@@ -1729,7 +1748,10 @@ static s32 ntty_write(struct tty_struct
170         return -ENODEV;
171     }
172 
173- down(&port->tty_sem);
174+ if(down_trylock(&port->tty_sem) ) { // must test lock as tty layer wraps calls to this function with BKL
175+ ERR("Would have deadlocked - return ERESTARTSYS");
176+ return -ERESTARTSYS;
177+ }
178 
179     if (! port->tty_open_count) {
180         D1( " ");
181@@ -1752,6 +1774,7 @@ static s32 ntty_write(struct tty_struct
182         goto exit;
183     }
184 
185+ spin_lock_irqsave(&dc->spin_mutex, flags);
186     // CTS is only valid on the modem channel
187     if ( port == &(dc->port[PORT_MDM]) ) {
188         if ( port->ctrl_dl.CTS ) {
189@@ -1763,6 +1786,7 @@ static s32 ntty_write(struct tty_struct
190     } else {
191         enable_transmit_ul(port->tty_index, dc );
192     }
193+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
194 
195 exit:
196     up(&port->tty_sem);
197@@ -1782,7 +1806,9 @@ static int ntty_write_room(struct tty_st
198         return 0;
199     }
200 
201- down(&port->tty_sem);
202+ if(down_interruptible(&port->tty_sem)){
203+ return 0;
204+ }
205 
206     if (! port->tty_open_count) {
207         goto exit;
208@@ -1969,6 +1995,8 @@ static int ntty_ioctl_tiocgicount(struct
209 
210 static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) {
211     port_t *port = (port_t *) tty->driver_data;
212+ dc_t *dc = get_dc_by_tty(tty);
213+ u32 flags;
214     int mask;
215     int rval = -ENOIOCTLCMD;
216 
217@@ -1991,7 +2019,9 @@ static int ntty_ioctl(struct tty_struct
218         rval = ntty_ioctl_tiocgicount(tty, file, cmd, arg);
219         break;
220     case TIOCMGET:
221+ spin_lock_irqsave(&dc->spin_mutex, flags);
222         rval = ntty_tiocmget(tty, file);
223+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
224         break;
225     case TIOCMSET:
226         rval = ntty_tiocmset(tty, file, arg);
227@@ -2000,20 +2030,24 @@ static int ntty_ioctl(struct tty_struct
228         if (get_user(mask, (unsigned long *) arg))
229             return -EFAULT;
230 
231+ spin_lock_irqsave(&dc->spin_mutex, flags);
232         if (mask & TIOCM_RTS)
233             set_rts(port->tty_index, 0);
234         if (mask & TIOCM_DTR)
235             set_dtr(port->tty_index, 0);
236+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
237         rval = 0;
238         break;
239        case TIOCMBIS:
240         if (get_user(mask, (unsigned long *) arg))
241             return -EFAULT;
242 
243+ spin_lock_irqsave(&dc->spin_mutex, flags);
244         if (mask & TIOCM_RTS)
245             set_rts(port->tty_index, 1);
246         if (mask & TIOCM_DTR)
247             set_dtr(port->tty_index, 1);
248+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
249         rval = 0;
250         break;
251     case TCFLSH:
252

Archive Download this file



interactive