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