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