• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "headers.h"
2 
InterfaceRDM(struct bcm_interface_adapter * psIntfAdapter,unsigned int addr,void * buff,int len)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 
InterfaceWRM(struct bcm_interface_adapter * psIntfAdapter,unsigned int addr,void * buff,int len)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 
BcmRDM(void * arg,unsigned int addr,void * buff,int len)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 
BcmWRM(void * arg,unsigned int addr,void * buff,int len)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 
Bcm_clear_halt_of_endpoints(struct bcm_mini_adapter * Adapter)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 
Bcm_kill_all_URBs(struct bcm_interface_adapter * psIntfAdapter)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 
putUsbSuspend(struct work_struct * work)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 
218