ath6kl: remove-typedef AR_SOFTC_T
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / staging / ath6kl / os / linux / ar6000_raw_if.c
blobae7c1dd96d833fecb89b59a5a3088ef6f7697cec
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Communications Inc.
3 // All rights reserved.
4 //
5 //
6 //
7 // Permission to use, copy, modify, and/or distribute this software for any
8 // purpose with or without fee is hereby granted, provided that the above
9 // copyright notice and this permission notice appear in all copies.
11 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 // Author(s): ="Atheros"
22 //------------------------------------------------------------------------------
24 #include "ar6000_drv.h"
26 #ifdef HTC_RAW_INTERFACE
28 static void
29 ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket)
31 struct ar6_softc *ar = (struct ar6_softc *)Context;
32 raw_htc_buffer *busy;
33 HTC_RAW_STREAM_ID streamID;
34 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
36 busy = (raw_htc_buffer *)pPacket->pPktContext;
37 A_ASSERT(busy != NULL);
39 if (pPacket->Status == A_ECANCELED) {
41 * HTC provides A_ECANCELED status when it doesn't want to be refilled
42 * (probably due to a shutdown)
44 return;
47 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
48 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
50 #ifdef CF
51 if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) {
52 #else
53 if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) {
54 #endif /* CF */
55 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
58 A_ASSERT((pPacket->Status != 0) ||
59 (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
61 busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
62 busy->currPtr = HTC_HEADER_LEN;
63 arRaw->read_buffer_available[streamID] = true;
64 //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
65 up(&arRaw->raw_htc_read_sem[streamID]);
67 /* Signal the waiting process */
68 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID));
69 wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]);
72 static void
73 ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket)
75 struct ar6_softc *ar = (struct ar6_softc *)Context;
76 raw_htc_buffer *free;
77 HTC_RAW_STREAM_ID streamID;
78 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
80 free = (raw_htc_buffer *)pPacket->pPktContext;
81 A_ASSERT(free != NULL);
83 if (pPacket->Status == A_ECANCELED) {
85 * HTC provides A_ECANCELED status when it doesn't want to be refilled
86 * (probably due to a shutdown)
88 return;
91 streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
92 A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
94 #ifdef CF
95 if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) {
96 #else
97 if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) {
98 #endif
99 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n"));
102 A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
104 free->length = 0;
105 arRaw->write_buffer_available[streamID] = true;
106 up(&arRaw->raw_htc_write_sem[streamID]);
108 /* Signal the waiting process */
109 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID));
110 wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]);
113 /* connect to a service */
114 static int ar6000_connect_raw_service(struct ar6_softc *ar,
115 HTC_RAW_STREAM_ID StreamID)
117 int status;
118 struct htc_service_connect_resp response;
119 u8 streamNo;
120 struct htc_service_connect_req connect;
122 do {
124 A_MEMZERO(&connect,sizeof(connect));
125 /* pass the stream ID as meta data to the RAW streams service */
126 streamNo = (u8)StreamID;
127 connect.pMetaData = &streamNo;
128 connect.MetaDataLength = sizeof(u8);
129 /* these fields are the same for all endpoints */
130 connect.EpCallbacks.pContext = ar;
131 connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
132 connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
133 /* simple interface, we don't need these optional callbacks */
134 connect.EpCallbacks.EpRecvRefill = NULL;
135 connect.EpCallbacks.EpSendFull = NULL;
136 connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
138 /* connect to the raw streams service, we may be able to get 1 or more
139 * connections, depending on WHAT is running on the target */
140 connect.ServiceID = HTC_RAW_STREAMS_SVC;
142 A_MEMZERO(&response,sizeof(response));
144 /* try to connect to the raw stream, it is okay if this fails with
145 * status HTC_SERVICE_NO_MORE_EP */
146 status = HTCConnectService(ar->arHtcTarget,
147 &connect,
148 &response);
150 if (status) {
151 if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n"));
153 status = 0;
155 break;
158 /* set endpoint mapping for the RAW HTC streams */
159 arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
161 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n",
162 StreamID, arRawStream2EndpointID(ar,StreamID)));
164 } while (false);
166 return status;
169 int ar6000_htc_raw_open(struct ar6_softc *ar)
171 int status;
172 int streamID, endPt, count2;
173 raw_htc_buffer *buffer;
174 HTC_SERVICE_ID servicepriority;
175 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
176 if (!arRaw) {
177 arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T));
178 if (arRaw) {
179 A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T));
182 A_ASSERT(ar->arHtcTarget != NULL);
183 if (!arRaw) {
184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n"));
185 return -ENOMEM;
187 /* wait for target */
188 status = HTCWaitTarget(ar->arHtcTarget);
190 if (status) {
191 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status));
192 return -ENODEV;
195 for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
196 arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
199 for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
200 /* Initialize the data structures */
201 sema_init(&arRaw->raw_htc_read_sem[streamID], 1);
202 sema_init(&arRaw->raw_htc_write_sem[streamID], 1);
203 init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]);
204 init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]);
206 /* try to connect to the raw service */
207 status = ar6000_connect_raw_service(ar,streamID);
209 if (status) {
210 break;
213 if (arRawStream2EndpointID(ar,streamID) == 0) {
214 break;
217 for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
218 /* Initialize the receive buffers */
219 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
220 memset(buffer, 0, sizeof(raw_htc_buffer));
221 buffer = &arRaw->raw_htc_read_buffer[streamID][count2];
222 memset(buffer, 0, sizeof(raw_htc_buffer));
224 SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
225 buffer,
226 buffer->data,
227 HTC_RAW_BUFFER_SIZE,
228 arRawStream2EndpointID(ar,streamID));
230 /* Queue buffers to HTC for receive */
231 if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0)
233 BMIInit();
234 return -EIO;
238 for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
239 /* Initialize the receive buffers */
240 buffer = &arRaw->raw_htc_write_buffer[streamID][count2];
241 memset(buffer, 0, sizeof(raw_htc_buffer));
244 arRaw->read_buffer_available[streamID] = false;
245 arRaw->write_buffer_available[streamID] = true;
248 if (status) {
249 return -EIO;
252 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID));
254 servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
256 /* set callbacks and priority list */
257 HTCSetCreditDistribution(ar->arHtcTarget,
259 NULL, /* use default */
260 NULL, /* use default */
261 &servicepriority,
264 /* Start the HTC component */
265 if ((status = HTCStart(ar->arHtcTarget)) != 0) {
266 BMIInit();
267 return -EIO;
270 (ar)->arRawIfInit = true;
272 return 0;
275 int ar6000_htc_raw_close(struct ar6_softc *ar)
277 A_PRINTF("ar6000_htc_raw_close called \n");
278 HTCStop(ar->arHtcTarget);
280 /* reset the device */
281 ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false);
282 /* Initialize the BMI component */
283 BMIInit();
285 return 0;
288 raw_htc_buffer *
289 get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID)
291 int count;
292 raw_htc_buffer *busy;
293 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
295 /* Check for data */
296 for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
297 busy = &arRaw->raw_htc_read_buffer[StreamID][count];
298 if (busy->length) {
299 break;
302 if (busy->length) {
303 arRaw->read_buffer_available[StreamID] = true;
304 } else {
305 arRaw->read_buffer_available[StreamID] = false;
308 return busy;
311 ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
312 char __user *buffer, size_t length)
314 int readPtr;
315 raw_htc_buffer *busy;
316 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
318 if (arRawStream2EndpointID(ar,StreamID) == 0) {
319 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
320 return -EFAULT;
323 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
324 return -ERESTARTSYS;
327 busy = get_filled_buffer(ar,StreamID);
328 while (!arRaw->read_buffer_available[StreamID]) {
329 up(&arRaw->raw_htc_read_sem[StreamID]);
331 /* Wait for the data */
332 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID));
333 if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID],
334 arRaw->read_buffer_available[StreamID]))
336 return -EINTR;
338 if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) {
339 return -ERESTARTSYS;
341 busy = get_filled_buffer(ar,StreamID);
344 /* Read the data */
345 readPtr = busy->currPtr;
346 if (length > busy->length - HTC_HEADER_LEN) {
347 length = busy->length - HTC_HEADER_LEN;
349 if (copy_to_user(buffer, &busy->data[readPtr], length)) {
350 up(&arRaw->raw_htc_read_sem[StreamID]);
351 return -EFAULT;
354 busy->currPtr += length;
356 if (busy->currPtr == busy->length)
358 busy->currPtr = 0;
359 busy->length = 0;
360 HTC_PACKET_RESET_RX(&busy->HTCPacket);
361 //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint));
362 HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
364 arRaw->read_buffer_available[StreamID] = false;
365 up(&arRaw->raw_htc_read_sem[StreamID]);
367 return length;
370 static raw_htc_buffer *
371 get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID)
373 int count;
374 raw_htc_buffer *free;
375 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
377 free = NULL;
378 for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
379 free = &arRaw->raw_htc_write_buffer[StreamID][count];
380 if (free->length == 0) {
381 break;
384 if (!free->length) {
385 arRaw->write_buffer_available[StreamID] = true;
386 } else {
387 arRaw->write_buffer_available[StreamID] = false;
390 return free;
393 ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID,
394 char __user *buffer, size_t length)
396 int writePtr;
397 raw_htc_buffer *free;
398 AR_RAW_HTC_T *arRaw = ar->arRawHtc;
399 if (arRawStream2EndpointID(ar,StreamID) == 0) {
400 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID));
401 return -EFAULT;
404 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
405 return -ERESTARTSYS;
408 /* Search for a free buffer */
409 free = get_free_buffer(ar,StreamID);
411 /* Check if there is space to write else wait */
412 while (!arRaw->write_buffer_available[StreamID]) {
413 up(&arRaw->raw_htc_write_sem[StreamID]);
415 /* Wait for buffer to become free */
416 AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID));
417 if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID],
418 arRaw->write_buffer_available[StreamID]))
420 return -EINTR;
422 if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) {
423 return -ERESTARTSYS;
425 free = get_free_buffer(ar,StreamID);
428 /* Send the data */
429 writePtr = HTC_HEADER_LEN;
430 if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) {
431 length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN;
434 if (copy_from_user(&free->data[writePtr], buffer, length)) {
435 up(&arRaw->raw_htc_read_sem[StreamID]);
436 return -EFAULT;
439 free->length = length;
441 SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
442 free,
443 &free->data[writePtr],
444 length,
445 arRawStream2EndpointID(ar,StreamID),
446 AR6K_DATA_PKT_TAG);
448 HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
450 arRaw->write_buffer_available[StreamID] = false;
451 up(&arRaw->raw_htc_write_sem[StreamID]);
453 return length;
455 #endif /* HTC_RAW_INTERFACE */