]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/staging/bcm/InterfaceMisc.c
b7d6e7a414a98d5ff7cc514e5753a11ac5bce632
[mv-sheeva.git] / drivers / staging / bcm / InterfaceMisc.c
1 #include "headers.h"
2
3 INT
4 InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter,
5             UINT addr,
6             PVOID buff,
7             INT len)
8 {
9         int retval = 0;
10         USHORT usRetries = 0 ;
11         if(psIntfAdapter == NULL )
12         {
13                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Interface Adapter is NULL");
14                 return -EINVAL ;
15         }
16
17         if(psIntfAdapter->psAdapter->device_removed == TRUE)
18         {
19                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
20                 return -ENODEV;
21         }
22
23         if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
24         {
25                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus");
26                 return -EACCES;
27         }
28
29         if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
30         {
31                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
32                 return -EACCES;
33         }
34         psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
35         do {
36                 retval = usb_control_msg(psIntfAdapter->udev,
37                                 usb_rcvctrlpipe(psIntfAdapter->udev,0),
38                     0x02,
39                     0xC2,
40                     (addr & 0xFFFF),
41                     ((addr >> 16) & 0xFFFF),
42                                 buff,
43                     len,
44                     5000);
45
46                 usRetries++ ;
47                 if(-ENODEV == retval)
48                 {
49                         psIntfAdapter->psAdapter->device_removed =TRUE;
50                         break;
51                 }
52
53         }while((retval < 0) && (usRetries < MAX_RDM_WRM_RETIRES ) );
54
55         if(retval < 0)
56         {
57                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM failed status :%d, retires :%d", retval,usRetries);
58                         psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
59                         return retval;
60         }
61         else
62         {
63                         BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, RDM, DBG_LVL_ALL, "RDM sent %d", retval);
64                         psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
65                         return STATUS_SUCCESS;
66         }
67 }
68
69 INT
70 InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter,
71             UINT addr,
72             PVOID buff,
73             INT len)
74 {
75         int retval = 0;
76         USHORT usRetries = 0 ;
77
78         if(psIntfAdapter == NULL )
79         {
80                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Interface Adapter  is NULL");
81                 return -EINVAL;
82         }
83         if(psIntfAdapter->psAdapter->device_removed == TRUE)
84         {
85
86                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0,"Device got removed");
87                 return -ENODEV;
88         }
89
90         if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB))
91         {
92                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus...");
93                 return EACCES;
94         }
95
96         if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE)
97         {
98                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Bus is in suspended states hence RDM not allowed..");
99                 return -EACCES;
100         }
101         psIntfAdapter->psAdapter->DeviceAccess = TRUE ;
102         do{
103                 retval = usb_control_msg(psIntfAdapter->udev,
104                                 usb_sndctrlpipe(psIntfAdapter->udev,0),
105                     0x01,
106                     0x42,
107                     (addr & 0xFFFF),
108                     ((addr >> 16) & 0xFFFF),
109                                 buff,
110                     len,
111                     5000);
112
113                 usRetries++ ;
114                 if(-ENODEV == retval)
115                 {
116                         psIntfAdapter->psAdapter->device_removed = TRUE ;
117                         break;
118                 }
119
120         }while((retval < 0) && ( usRetries < MAX_RDM_WRM_RETIRES));
121
122         if(retval < 0)
123         {
124                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM failed status :%d, retires :%d", retval, usRetries);
125                 psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
126                 return retval;
127         }
128         else
129         {
130                 psIntfAdapter->psAdapter->DeviceAccess = FALSE ;
131                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL, "WRM sent %d", retval);
132                 return STATUS_SUCCESS;
133
134         }
135
136 }
137
138 INT
139 BcmRDM(PVOID arg,
140                         UINT addr,
141                         PVOID buff,
142                         INT len)
143 {
144         return InterfaceRDM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
145 }
146
147 INT
148 BcmWRM(PVOID arg,
149                         UINT addr,
150                         PVOID buff,
151                         INT len)
152 {
153         return InterfaceWRM((PS_INTERFACE_ADAPTER)arg, addr, buff, len);
154 }
155
156
157
158 INT Bcm_clear_halt_of_endpoints(PMINI_ADAPTER Adapter)
159 {
160         PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter);
161         INT status = STATUS_SUCCESS ;
162
163         /*
164                  usb_clear_halt - tells device to clear endpoint halt/stall condition
165                  @dev: device whose endpoint is halted
166                  @pipe: endpoint "pipe" being cleared
167                  @ Context: !in_interrupt ()
168
169                 usb_clear_halt is the synchrnous call and returns 0 on success else returns with error code.
170                 This is used to clear halt conditions for bulk and interrupt endpoints only.
171                  Control and isochronous endpoints never halts.
172
173                 Any URBs  queued for such an endpoint should normally be unlinked by the driver
174                 before clearing the halt condition.
175
176         */
177
178         //Killing all the submitted urbs to different end points.
179         Bcm_kill_all_URBs(psIntfAdapter);
180
181
182         //clear the halted/stalled state for every end point
183         status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sIntrIn.int_in_pipe);
184         if(status != STATUS_SUCCESS)
185                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Interrupt IN end point. :%d ", status);
186
187         status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkIn.bulk_in_pipe);
188         if(status != STATUS_SUCCESS)
189                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk IN end point. :%d ", status);
190
191         status = usb_clear_halt(psIntfAdapter->udev,psIntfAdapter->sBulkOut.bulk_out_pipe);
192         if(status != STATUS_SUCCESS)
193                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL, "Unable to Clear Halt of Bulk OUT end point. :%d ", status);
194
195         return status ;
196 }
197
198
199 VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter)
200 {
201         struct urb *tempUrb = NULL;
202         UINT i;
203
204         /**
205           *     usb_kill_urb - cancel a transfer request and wait for it to finish
206           *     @urb: pointer to URB describing a previously submitted request,
207           *       returns nothing as it is void returned API.
208           *
209           *      This routine cancels an in-progress request. It is guaranteed that
210           *     upon return all completion handlers will have finished and the URB
211           *     will be totally idle and available for reuse
212
213           *     This routine may not be used in an interrupt context (such as a bottom
214           *      half or a completion handler), or when holding a spinlock, or in other
215           *      situations where the caller can't schedule().
216           *
217         **/
218
219         /* Cancel submitted Interrupt-URB's */
220         if(psIntfAdapter->psInterruptUrb != NULL)
221         {
222                 if(psIntfAdapter->psInterruptUrb->status == -EINPROGRESS)
223                                  usb_kill_urb(psIntfAdapter->psInterruptUrb);
224         }
225
226         /* Cancel All submitted TX URB's */
227         for(i = 0; i < MAXIMUM_USB_TCB; i++)
228         {
229                 tempUrb = psIntfAdapter->asUsbTcb[i].urb;
230                 if(tempUrb)
231                 {
232                         if(tempUrb->status == -EINPROGRESS)
233                                 usb_kill_urb(tempUrb);
234                 }
235         }
236
237         for(i = 0; i < MAXIMUM_USB_RCB; i++)
238         {
239                 tempUrb = psIntfAdapter->asUsbRcb[i].urb;
240                 if(tempUrb)
241                 {
242                         if(tempUrb->status == -EINPROGRESS)
243                                         usb_kill_urb(tempUrb);
244                 }
245         }
246
247         atomic_set(&psIntfAdapter->uNumTcbUsed, 0);
248         atomic_set(&psIntfAdapter->uCurrTcb, 0);
249
250         atomic_set(&psIntfAdapter->uNumRcbUsed, 0);
251         atomic_set(&psIntfAdapter->uCurrRcb, 0);
252 }
253
254 VOID putUsbSuspend(struct work_struct *work)
255 {
256         PS_INTERFACE_ADAPTER psIntfAdapter = NULL ;
257         struct usb_interface *intf = NULL ;
258         psIntfAdapter = container_of(work, S_INTERFACE_ADAPTER,usbSuspendWork);
259         intf=psIntfAdapter->interface ;
260
261         if(psIntfAdapter->bSuspended == FALSE)
262                 usb_autopm_put_interface(intf);
263
264 }
265