Staging: w35und: remove true/false boolean macros
[linux-2.6] / drivers / staging / winbond / linux / wb35tx.c
1 //============================================================================
2 //  Copyright (c) 1996-2002 Winbond Electronic Corporation
3 //
4 //  Module Name:
5 //    Wb35Tx.c
6 //
7 //  Abstract:
8 //    Processing the Tx message and put into down layer
9 //
10 //============================================================================
11 #include "sysdef.h"
12
13
14 unsigned char
15 Wb35Tx_get_tx_buffer(phw_data_t pHwData, u8 **pBuffer)
16 {
17         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
18
19         *pBuffer = pWb35Tx->TxBuffer[0];
20         return true;
21 }
22
23 void Wb35Tx_start(phw_data_t pHwData)
24 {
25         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
26
27         // Allow only one thread to run into function
28         if (OS_ATOMIC_INC(pHwData->adapter, &pWb35Tx->TxFireCounter) == 1) {
29                 pWb35Tx->EP4vm_state = VM_RUNNING;
30                 Wb35Tx(pHwData);
31         } else
32                 OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxFireCounter );
33 }
34
35
36 void Wb35Tx(phw_data_t pHwData)
37 {
38         PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
39         struct wb35_adapter *adapter = pHwData->adapter;
40         u8              *pTxBufferAddress;
41         PMDS            pMds = &adapter->Mds;
42         struct urb *    pUrb = (struct urb *)pWb35Tx->Tx4Urb;
43         int             retv;
44         u32             SendIndex;
45
46
47         if (pHwData->SurpriseRemove || pHwData->HwStop)
48                 goto cleanup;
49
50         if (pWb35Tx->tx_halt)
51                 goto cleanup;
52
53         // Ownership checking
54         SendIndex = pWb35Tx->TxSendIndex;
55         if (!pMds->TxOwner[SendIndex]) //No more data need to be sent, return immediately
56                 goto cleanup;
57
58         pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex];
59         //
60         // Issuing URB
61         //
62         usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
63                           usb_sndbulkpipe(pHwData->WbUsb.udev, 4),
64                           pTxBufferAddress, pMds->TxBufferSize[ SendIndex ],
65                           Wb35Tx_complete, pHwData);
66
67         pWb35Tx->EP4vm_state = VM_RUNNING;
68         retv = usb_submit_urb(pUrb, GFP_ATOMIC);
69         if (retv<0) {
70                 printk("EP4 Tx Irp sending error\n");
71                 goto cleanup;
72         }
73
74         // Check if driver needs issue Irp for EP2
75         pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex];
76         if (pWb35Tx->TxFillCount > 12)
77                 Wb35Tx_EP2VM_start( pHwData );
78
79         pWb35Tx->ByteTransfer += pMds->TxBufferSize[SendIndex];
80         return;
81
82  cleanup:
83         pWb35Tx->EP4vm_state = VM_STOP;
84         OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxFireCounter );
85 }
86
87
88 void Wb35Tx_complete(struct urb * pUrb)
89 {
90         phw_data_t      pHwData = pUrb->context;
91         struct wb35_adapter *adapter = pHwData->adapter;
92         PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
93         PMDS            pMds = &adapter->Mds;
94
95         printk("wb35: tx complete\n");
96         // Variable setting
97         pWb35Tx->EP4vm_state = VM_COMPLETED;
98         pWb35Tx->EP4VM_status = pUrb->status; //Store the last result of Irp
99         pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0;// Set the owner. Free the owner bit always.
100         pWb35Tx->TxSendIndex++;
101         pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;
102
103         if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
104                 goto error;
105
106         if (pWb35Tx->tx_halt)
107                 goto error;
108
109         // The URB is completed, check the result
110         if (pWb35Tx->EP4VM_status != 0) {
111                 printk("URB submission failed\n");
112                 pWb35Tx->EP4vm_state = VM_STOP;
113                 goto error;
114         }
115
116         Mds_Tx(adapter);
117         Wb35Tx(pHwData);
118         return;
119
120 error:
121         OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxFireCounter );
122         pWb35Tx->EP4vm_state = VM_STOP;
123 }
124
125 void Wb35Tx_reset_descriptor(  phw_data_t pHwData )
126 {
127         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
128
129         pWb35Tx->TxSendIndex = 0;
130         pWb35Tx->tx_halt = 0;
131 }
132
133 unsigned char Wb35Tx_initial(phw_data_t pHwData)
134 {
135         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
136
137         pWb35Tx->Tx4Urb = usb_alloc_urb(0, GFP_ATOMIC);
138         if (!pWb35Tx->Tx4Urb)
139                 return false;
140
141         pWb35Tx->Tx2Urb = usb_alloc_urb(0, GFP_ATOMIC);
142         if (!pWb35Tx->Tx2Urb)
143         {
144                 usb_free_urb( pWb35Tx->Tx4Urb );
145                 return false;
146         }
147
148         return true;
149 }
150
151 //======================================================
152 void Wb35Tx_stop(phw_data_t pHwData)
153 {
154         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
155
156         // Trying to canceling the Trp of EP2
157         if (pWb35Tx->EP2vm_state == VM_RUNNING)
158                 usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them
159         #ifdef _PE_TX_DUMP_
160         WBDEBUG(("EP2 Tx stop\n"));
161         #endif
162
163         // Trying to canceling the Irp of EP4
164         if (pWb35Tx->EP4vm_state == VM_RUNNING)
165                 usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them
166         #ifdef _PE_TX_DUMP_
167         WBDEBUG(("EP4 Tx stop\n"));
168         #endif
169 }
170
171 //======================================================
172 void Wb35Tx_destroy(phw_data_t pHwData)
173 {
174         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
175
176         // Wait for VM stop
177         do {
178                 msleep(10);  // Delay for waiting function enter 940623.1.a
179         } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) );
180         msleep(10);  // Delay for waiting function enter 940623.1.b
181
182         if (pWb35Tx->Tx4Urb)
183                 usb_free_urb( pWb35Tx->Tx4Urb );
184
185         if (pWb35Tx->Tx2Urb)
186                 usb_free_urb( pWb35Tx->Tx2Urb );
187
188         #ifdef _PE_TX_DUMP_
189         WBDEBUG(("Wb35Tx_destroy OK\n"));
190         #endif
191 }
192
193 void Wb35Tx_CurrentTime(phw_data_t pHwData, u32 TimeCount)
194 {
195         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
196         unsigned char Trigger = false;
197
198         if (pWb35Tx->TxTimer > TimeCount)
199                 Trigger = true;
200         else if (TimeCount > (pWb35Tx->TxTimer+500))
201                 Trigger = true;
202
203         if (Trigger) {
204                 pWb35Tx->TxTimer = TimeCount;
205                 Wb35Tx_EP2VM_start( pHwData );
206         }
207 }
208
209 void Wb35Tx_EP2VM_start(phw_data_t pHwData)
210 {
211         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
212
213         // Allow only one thread to run into function
214         if (OS_ATOMIC_INC( pHwData->adapter, &pWb35Tx->TxResultCount ) == 1) {
215                 pWb35Tx->EP2vm_state = VM_RUNNING;
216                 Wb35Tx_EP2VM( pHwData );
217         }
218         else
219                 OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxResultCount );
220 }
221
222
223 void Wb35Tx_EP2VM(phw_data_t pHwData)
224 {
225         PWB35TX pWb35Tx = &pHwData->Wb35Tx;
226         struct urb *    pUrb = (struct urb *)pWb35Tx->Tx2Urb;
227         u32 *   pltmp = (u32 *)pWb35Tx->EP2_buf;
228         int             retv;
229
230         if (pHwData->SurpriseRemove || pHwData->HwStop)
231                 goto error;
232
233         if (pWb35Tx->tx_halt)
234                 goto error;
235
236         //
237         // Issuing URB
238         //
239         usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
240                           pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32);
241
242         pWb35Tx->EP2vm_state = VM_RUNNING;
243         retv = usb_submit_urb(pUrb, GFP_ATOMIC);
244
245         if (retv < 0) {
246                 #ifdef _PE_TX_DUMP_
247                 WBDEBUG(("EP2 Tx Irp sending error\n"));
248                 #endif
249                 goto error;
250         }
251
252         return;
253 error:
254         pWb35Tx->EP2vm_state = VM_STOP;
255         OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxResultCount );
256 }
257
258
259 void Wb35Tx_EP2VM_complete(struct urb * pUrb)
260 {
261         phw_data_t      pHwData = pUrb->context;
262         T02_DESCRIPTOR  T02, TSTATUS;
263         struct wb35_adapter *adapter = pHwData->adapter;
264         PWB35TX         pWb35Tx = &pHwData->Wb35Tx;
265         u32 *           pltmp = (u32 *)pWb35Tx->EP2_buf;
266         u32             i;
267         u16             InterruptInLength;
268
269
270         // Variable setting
271         pWb35Tx->EP2vm_state = VM_COMPLETED;
272         pWb35Tx->EP2VM_status = pUrb->status;
273
274         // For Linux 2.4. Interrupt will always trigger
275         if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
276                 goto error;
277
278         if (pWb35Tx->tx_halt)
279                 goto error;
280
281         //The Urb is completed, check the result
282         if (pWb35Tx->EP2VM_status != 0) {
283                 WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
284                 pWb35Tx->EP2vm_state= VM_STOP;
285                 goto error;
286         }
287
288         // Update the Tx result
289         InterruptInLength = pUrb->actual_length;
290         // Modify for minimum memory access and DWORD alignment.
291         T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0]
292         InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable
293         InterruptInLength >>= 2; // InterruptInLength/4
294         for (i = 1; i <= InterruptInLength; i++) {
295                 T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);
296
297                 TSTATUS.value = T02.value;  //20061009 anson's endian
298                 Mds_SendComplete( adapter, &TSTATUS );
299                 T02.value = cpu_to_le32(pltmp[i]) >> 8;
300         }
301
302         return;
303 error:
304         OS_ATOMIC_DEC( pHwData->adapter, &pWb35Tx->TxResultCount );
305         pWb35Tx->EP2vm_state = VM_STOP;
306 }
307