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