refresh all package patches in the buildroot using quilt
[openwrt.git] / package / nozomi / patches / 002-nozomi_vf_01.patch
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
5 @@ -7,6 +7,9 @@
6   *
7   * Maintained by: Paul Hardwick, p.hardwick@option.com
8   *
9 + * Patches:
10 + *          Locking code changes for Vodafone, Andrew Bird & Phil Sanderson
11 + *
12   * Source has been ported from an implementation made by Filip Aben, f.aben@option.com
13   *
14   * --------------------------------------------------------------------------
15 @@ -61,6 +64,7 @@
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>
21  
22  
23 @@ -133,23 +137,23 @@
24  /* TODO: rewrite to optimize macros... */
25  #define SET_FCR(value__) \
26    do {  \
27 -       writew((value__), (void*) (dc->REG_FCR )); \
28 +       writew((value__), (dc->REG_FCR )); \
29  } while(0)
30  
31  #define SET_IER(value__, mask__) \
32    do {  \
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));\
36  } while(0)
37  
38  #define GET_IER(read_val__) \
39    do {  \
40 -       (read_val__) = readw((void*) (dc->REG_IER));\
41 +       (read_val__) = readw((dc->REG_IER));\
42  } while(0)
43  
44  #define GET_IIR(read_val__) \
45    do {  \
46 -       (read_val__) = readw((void*) (dc->REG_IIR));\
47 +       (read_val__) = readw( (dc->REG_IIR));\
48  } while(0)
49  
50  #define GET_MEM(value__, addr__, length__) \
51 @@ -265,7 +269,7 @@
52  /* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */
53  typedef enum {
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 */
57  } card_type_t;
58  
59  /* Two different toggle channels exist */
60 @@ -438,12 +442,12 @@
61         u32                                  base_addr;
62         u8                                   closing;
63  
64 -       /* Register addresses */
65 -       u32                                  REG_IIR;
66 -       u32                                  REG_FCR;
67 -       u32                                  REG_IER;
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;
72  
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 */
77         struct pci_dev      *pdev;
78 @@ -490,7 +494,7 @@
79  
80  /* Used to store interrupt variables */
81  typedef struct {
82 -       volatile u16 read_iir; /* Holds current interrupt tokens */
83 +       u16 read_iir; /* Holds current interrupt tokens */
84  } irq_t;
85  
86  MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
87 @@ -1345,9 +1349,9 @@
88         u32 offset = dc->base_addr + dc->card_type/2;
89         int i;
90  
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;
98         dc->closing = 0;
99  
100 @@ -1366,13 +1370,16 @@
101  static void tty_flip_queue_function(void *tmp_dc) {
102         dc_t *dc = (dc_t*) tmp_dc;
103         int i;
104 +   u32 flags;
105  
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);
114                 }
115         }
116  }
117 @@ -1555,7 +1562,11 @@
118  
119  static void tty_do_close(dc_t *dc, port_t *port) {
120  
121 -       down(&port->tty_sem);
122 +       u32      flags;
123 +
124 +       if(down_interruptible(&port->tty_sem)){
125 +      return;
126 +   }
127  
128         if ( !port->tty_open_count ) {
129                 goto exit;
130 @@ -1569,7 +1580,9 @@
131  
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);
137         }
138  
139  exit:
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);
144 +       u32      flags;
145  
146 -       down(&port->tty_sem);
147 +   if(down_interruptible(&port->tty_sem)){
148 +      return -ERESTARTSYS;
149 +   }
150  
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);
160         }
161  
162         up(&port->tty_sem);
163 @@ -1722,6 +1740,7 @@
164         int                  rval = -EINVAL;
165         dc_t                *dc = get_dc_by_tty(tty);
166         port_t              *port = (port_t *) tty->driver_data;
167 +       u32      flags;
168  
169         /* D1( "WRITEx: %d, index = %d", count, index); */
170  
171 @@ -1729,7 +1748,10 @@
172                 return -ENODEV;
173         }
174  
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;
179 +   }
180  
181         if (! port->tty_open_count) {
182          D1( " ");
183 @@ -1752,6 +1774,7 @@
184                 goto exit;
185         }
186  
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 @@
192         } else {
193                 enable_transmit_ul(port->tty_index, dc );
194         }
195 +   spin_unlock_irqrestore(&dc->spin_mutex, flags);
196  
197  exit:
198         up(&port->tty_sem);
199 @@ -1782,7 +1806,9 @@
200          return 0;
201         }
202  
203 -       down(&port->tty_sem);
204 +   if(down_interruptible(&port->tty_sem)){
205 +      return 0;
206 +   }
207  
208         if (! port->tty_open_count) {
209                 goto exit;
210 @@ -1969,6 +1995,8 @@
211  
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);
215 +       u32      flags;
216         int mask;
217         int rval = -ENOIOCTLCMD;
218  
219 @@ -1991,7 +2019,9 @@
220                 rval =  ntty_ioctl_tiocgicount(tty, file, cmd, arg);
221                 break;
222         case TIOCMGET:
223 +      spin_lock_irqsave(&dc->spin_mutex, flags);
224                 rval = ntty_tiocmget(tty, file);
225 +      spin_unlock_irqrestore(&dc->spin_mutex, flags);
226                 break;
227         case TIOCMSET:
228                 rval = ntty_tiocmset(tty, file, arg);
229 @@ -2000,20 +2030,24 @@
230                 if (get_user(mask, (unsigned long *) arg))
231                         return -EFAULT;
232  
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);
239                 rval = 0;
240                 break;
241         case TIOCMBIS:
242                 if (get_user(mask, (unsigned long *) arg))
243                         return -EFAULT;
244  
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);
251                 rval = 0;
252                 break;
253         case TCFLSH: