Merge remote-tracking branch 'usb-chipidea-next/ci-for-usb-next'
[deliverable/linux.git] / drivers / staging / rtl8723au / os_dep / usb_ops_linux.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 ******************************************************************************/
15 #define _USB_OPS_LINUX_C_
16
17 #include <drv_types.h>
18 #include <usb_ops_linux.h>
19 #include <rtw_sreset.h>
20
21 void rtl8723au_read_port_cancel(struct rtw_adapter *padapter)
22 {
23 struct recv_buf *precvbuf;
24 int i;
25
26 precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
27
28 DBG_8723A("%s\n", __func__);
29
30 padapter->bReadPortCancel = true;
31
32 for (i = 0; i < NR_RECVBUFF ; i++) {
33 if (precvbuf->purb)
34 usb_kill_urb(precvbuf->purb);
35 precvbuf++;
36 }
37 usb_kill_urb(padapter->recvpriv.int_in_urb);
38 }
39
40 static void usb_write_port23a_complete(struct urb *purb)
41 {
42 struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
43 struct rtw_adapter *padapter = pxmitbuf->padapter;
44 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
45 struct hal_data_8723a *phaldata;
46 unsigned long irqL;
47
48 switch (pxmitbuf->flags) {
49 case HIGH_QUEUE_INX:
50 #ifdef CONFIG_8723AU_AP_MODE
51 rtw_chk_hi_queue_cmd23a(padapter);
52 #endif
53 break;
54 default:
55 break;
56 }
57
58 if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
59 padapter->bWritePortCancel) {
60 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
61 "usb_write_port23a_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
62 padapter->bDriverStopped, padapter->bSurpriseRemoved);
63 DBG_8723A("%s(): TX Warning! bDriverStopped(%d) OR "
64 "bSurpriseRemoved(%d) bWritePortCancel(%d) "
65 "pxmitbuf->ext_tag(%x)\n", __func__,
66 padapter->bDriverStopped, padapter->bSurpriseRemoved,
67 padapter->bReadPortCancel, pxmitbuf->ext_tag);
68
69 goto check_completion;
70 }
71
72 if (purb->status) {
73 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
74 "usb_write_port23a_complete : purb->status(%d) != 0\n",
75 purb->status);
76 DBG_8723A("###=> urb_write_port_complete status(%d)\n",
77 purb->status);
78 if (purb->status == -EPIPE || purb->status == -EPROTO) {
79 } else if (purb->status == -EINPROGRESS) {
80 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
81 "usb_write_port23a_complete: EINPROGESS\n");
82 goto check_completion;
83 } else if (purb->status == -ENOENT) {
84 DBG_8723A("%s: -ENOENT\n", __func__);
85 goto check_completion;
86 } else if (purb->status == -ECONNRESET) {
87 DBG_8723A("%s: -ECONNRESET\n", __func__);
88 goto check_completion;
89 } else if (purb->status == -ESHUTDOWN) {
90 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
91 "usb_write_port23a_complete: ESHUTDOWN\n");
92 padapter->bDriverStopped = true;
93 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
94 "usb_write_port23a_complete:bDriverStopped = true\n");
95 goto check_completion;
96 } else {
97 padapter->bSurpriseRemoved = true;
98 DBG_8723A("bSurpriseRemoved = true\n");
99 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
100 "usb_write_port23a_complete:bSurpriseRemoved = true\n");
101 goto check_completion;
102 }
103 }
104 phaldata = GET_HAL_DATA(padapter);
105 phaldata->srestpriv.last_tx_complete_time = jiffies;
106
107 check_completion:
108 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
109 rtw23a_sctx_done_err(&pxmitbuf->sctx,
110 purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR :
111 RTW_SCTX_DONE_SUCCESS);
112 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
113
114 rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
115
116 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
117 }
118
119 int rtl8723au_write_port(struct rtw_adapter *padapter, u32 addr, u32 cnt,
120 struct xmit_buf *pxmitbuf)
121 {
122 struct urb *purb = NULL;
123 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
124 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
125 struct xmit_frame *pxmitframe;
126 struct usb_device *pusbd = pdvobj->pusbdev;
127 unsigned long irqL;
128 unsigned int pipe, ep_num;
129 int status;
130 int ret = _FAIL;
131
132 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "+usb_write_port23a\n");
133
134 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
135 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
136 "%s:(padapter->bDriverStopped || padapter->bSurpriseRemoved)!!!\n",
137 __func__);
138 rtw23a_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
139 goto exit;
140 }
141
142 pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
143 spin_lock_irqsave(&pxmitpriv->lock, irqL);
144
145 switch (addr) {
146 case VO_QUEUE_INX:
147 pxmitbuf->flags = VO_QUEUE_INX;
148 break;
149 case VI_QUEUE_INX:
150 pxmitbuf->flags = VI_QUEUE_INX;
151 break;
152 case BE_QUEUE_INX:
153 pxmitbuf->flags = BE_QUEUE_INX;
154 break;
155 case BK_QUEUE_INX:
156 pxmitbuf->flags = BK_QUEUE_INX;
157 break;
158 case HIGH_QUEUE_INX:
159 pxmitbuf->flags = HIGH_QUEUE_INX;
160 break;
161 default:
162 pxmitbuf->flags = MGT_QUEUE_INX;
163 break;
164 }
165
166 spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
167
168 purb = pxmitbuf->pxmit_urb[0];
169
170 /* translate DMA FIFO addr to pipehandle */
171 ep_num = pdvobj->Queue2Pipe[addr];
172 pipe = usb_sndbulkpipe(pusbd, ep_num);
173
174 usb_fill_bulk_urb(purb, pusbd, pipe,
175 pxmitframe->buf_addr, /* pxmitbuf->pbuf */
176 cnt, usb_write_port23a_complete,
177 pxmitbuf);/* context is pxmitbuf */
178
179 status = usb_submit_urb(purb, GFP_ATOMIC);
180 if (!status) {
181 struct hal_data_8723a *phaldata = GET_HAL_DATA(padapter);
182 phaldata->srestpriv.last_tx_time = jiffies;
183 } else {
184 rtw23a_sctx_done_err(&pxmitbuf->sctx,
185 RTW_SCTX_DONE_WRITE_PORT_ERR);
186 DBG_8723A("usb_write_port23a, status =%d\n", status);
187 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
188 "usb_write_port23a(): usb_submit_urb, status =%x\n",
189 status);
190
191 switch (status) {
192 case -ENODEV:
193 padapter->bDriverStopped = true;
194 break;
195 default:
196 break;
197 }
198 goto exit;
199 }
200 ret = _SUCCESS;
201 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, "-usb_write_port23a\n");
202
203 exit:
204 if (ret != _SUCCESS)
205 rtw_free_xmitbuf23a(pxmitpriv, pxmitbuf);
206
207 return ret;
208 }
209
210 void rtl8723au_write_port_cancel(struct rtw_adapter *padapter)
211 {
212 struct xmit_buf *pxmitbuf;
213 int j;
214
215 DBG_8723A("%s\n", __func__);
216
217 padapter->bWritePortCancel = true;
218
219 list_for_each_entry(pxmitbuf, &padapter->xmitpriv.xmitbuf_list,
220 list2) {
221 for (j = 0; j < 8; j++) {
222 if (pxmitbuf->pxmit_urb[j])
223 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
224 }
225 }
226 list_for_each_entry(pxmitbuf, &padapter->xmitpriv.xmitextbuf_list,
227 list2) {
228 for (j = 0; j < 8; j++) {
229 if (pxmitbuf->pxmit_urb[j])
230 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
231 }
232 }
233 }
This page took 0.035596 seconds and 5 git commands to generate.