Root/target/linux/s3c24xx/files-2.6.30/drivers/ar6000/ar6000/ar6000_raw_if.c

1/*
2 *
3 * Copyright (c) 2004-2007 Atheros Communications Inc.
4 * All rights reserved.
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation;
10 *
11 * Software distributed under the License is distributed on an "AS
12 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 * implied. See the License for the specific language governing
14 * rights and limitations under the License.
15 *
16 *
17 *
18 */
19
20#include "ar6000_drv.h"
21
22#ifdef HTC_RAW_INTERFACE
23
24static void
25ar6000_htc_raw_read_cb(void *Context, HTC_PACKET *pPacket)
26{
27    AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
28    raw_htc_buffer *busy;
29    HTC_RAW_STREAM_ID streamID;
30
31    busy = (raw_htc_buffer *)pPacket->pPktContext;
32    A_ASSERT(busy != NULL);
33
34    if (pPacket->Status == A_ECANCELED) {
35        /*
36         * HTC provides A_ECANCELED status when it doesn't want to be refilled
37         * (probably due to a shutdown)
38         */
39        return;
40    }
41
42    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
43    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
44
45#ifdef CF
46   if (down_trylock(&ar->raw_htc_read_sem[streamID])) {
47#else
48    if (down_interruptible(&ar->raw_htc_read_sem[streamID])) {
49#endif /* CF */
50        AR_DEBUG2_PRINTF("Unable to down the semaphore\n");
51    }
52
53    A_ASSERT((pPacket->Status != A_OK) ||
54             (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN)));
55
56    busy->length = pPacket->ActualLength + HTC_HEADER_LEN;
57    busy->currPtr = HTC_HEADER_LEN;
58    ar->read_buffer_available[streamID] = TRUE;
59    //AR_DEBUG_PRINTF("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length);
60    up(&ar->raw_htc_read_sem[streamID]);
61
62    /* Signal the waiting process */
63    AR_DEBUG2_PRINTF("Waking up the StreamID(%d) read process\n", streamID);
64    wake_up_interruptible(&ar->raw_htc_read_queue[streamID]);
65}
66
67static void
68ar6000_htc_raw_write_cb(void *Context, HTC_PACKET *pPacket)
69{
70    AR_SOFTC_T *ar = (AR_SOFTC_T *)Context;
71    raw_htc_buffer *free;
72    HTC_RAW_STREAM_ID streamID;
73
74    free = (raw_htc_buffer *)pPacket->pPktContext;
75    A_ASSERT(free != NULL);
76
77    if (pPacket->Status == A_ECANCELED) {
78        /*
79         * HTC provides A_ECANCELED status when it doesn't want to be refilled
80         * (probably due to a shutdown)
81         */
82        return;
83    }
84
85    streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint);
86    A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED);
87
88#ifdef CF
89    if (down_trylock(&ar->raw_htc_write_sem[streamID])) {
90#else
91    if (down_interruptible(&ar->raw_htc_write_sem[streamID])) {
92#endif
93        AR_DEBUG2_PRINTF("Unable to down the semaphore\n");
94    }
95
96    A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN));
97
98    free->length = 0;
99    ar->write_buffer_available[streamID] = TRUE;
100    up(&ar->raw_htc_write_sem[streamID]);
101
102    /* Signal the waiting process */
103    AR_DEBUG2_PRINTF("Waking up the StreamID(%d) write process\n", streamID);
104    wake_up_interruptible(&ar->raw_htc_write_queue[streamID]);
105}
106
107/* connect to a service */
108static A_STATUS ar6000_connect_raw_service(AR_SOFTC_T *ar,
109                                           HTC_RAW_STREAM_ID StreamID)
110{
111    A_STATUS status;
112    HTC_SERVICE_CONNECT_RESP response;
113    A_UINT8 streamNo;
114    HTC_SERVICE_CONNECT_REQ connect;
115
116    do {
117
118        A_MEMZERO(&connect,sizeof(connect));
119            /* pass the stream ID as meta data to the RAW streams service */
120        streamNo = (A_UINT8)StreamID;
121        connect.pMetaData = &streamNo;
122        connect.MetaDataLength = sizeof(A_UINT8);
123            /* these fields are the same for all endpoints */
124        connect.EpCallbacks.pContext = ar;
125        connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb;
126        connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb;
127            /* simple interface, we don't need these optional callbacks */
128        connect.EpCallbacks.EpRecvRefill = NULL;
129        connect.EpCallbacks.EpSendFull = NULL;
130        connect.EpCallbacks.EpSendAvail = NULL;
131        connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM;
132
133            /* connect to the raw streams service, we may be able to get 1 or more
134             * connections, depending on WHAT is running on the target */
135        connect.ServiceID = HTC_RAW_STREAMS_SVC;
136
137        A_MEMZERO(&response,sizeof(response));
138
139            /* try to connect to the raw stream, it is okay if this fails with
140             * status HTC_SERVICE_NO_MORE_EP */
141        status = HTCConnectService(ar->arHtcTarget,
142                                   &connect,
143                                   &response);
144
145        if (A_FAILED(status)) {
146            if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) {
147                AR_DEBUG_PRINTF("HTC RAW , No more streams allowed \n");
148                status = A_OK;
149            }
150            break;
151        }
152
153            /* set endpoint mapping for the RAW HTC streams */
154        arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint);
155
156        AR_DEBUG_PRINTF("HTC RAW : stream ID: %d, endpoint: %d\n",
157                        StreamID, arRawStream2EndpointID(ar,StreamID));
158
159    } while (FALSE);
160
161    return status;
162}
163
164int ar6000_htc_raw_open(AR_SOFTC_T *ar)
165{
166    A_STATUS status;
167    int streamID, endPt, count2;
168    raw_htc_buffer *buffer;
169    HTC_SERVICE_ID servicepriority;
170
171    A_ASSERT(ar->arHtcTarget != NULL);
172
173        /* wait for target */
174    status = HTCWaitTarget(ar->arHtcTarget);
175
176    if (A_FAILED(status)) {
177        AR_DEBUG_PRINTF("HTCWaitTarget failed (%d)\n", status);
178        return -ENODEV;
179    }
180
181    for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) {
182        ar->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED;
183    }
184
185    for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) {
186        /* Initialize the data structures */
187        init_MUTEX(&ar->raw_htc_read_sem[streamID]);
188        init_MUTEX(&ar->raw_htc_write_sem[streamID]);
189        init_waitqueue_head(&ar->raw_htc_read_queue[streamID]);
190        init_waitqueue_head(&ar->raw_htc_write_queue[streamID]);
191
192            /* try to connect to the raw service */
193        status = ar6000_connect_raw_service(ar,streamID);
194
195        if (A_FAILED(status)) {
196            break;
197        }
198
199        if (arRawStream2EndpointID(ar,streamID) == 0) {
200            break;
201        }
202
203        for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) {
204            /* Initialize the receive buffers */
205            buffer = ar->raw_htc_write_buffer[streamID][count2];
206            memset(buffer, 0, sizeof(raw_htc_buffer));
207            buffer = ar->raw_htc_read_buffer[streamID][count2];
208            memset(buffer, 0, sizeof(raw_htc_buffer));
209
210            SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket,
211                                          buffer,
212                                          buffer->data,
213                                          AR6000_BUFFER_SIZE,
214                                          arRawStream2EndpointID(ar,streamID));
215
216            /* Queue buffers to HTC for receive */
217            if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != A_OK)
218            {
219                BMIInit();
220                return -EIO;
221            }
222        }
223
224        for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) {
225            /* Initialize the receive buffers */
226            buffer = ar->raw_htc_write_buffer[streamID][count2];
227            memset(buffer, 0, sizeof(raw_htc_buffer));
228        }
229
230        ar->read_buffer_available[streamID] = FALSE;
231        ar->write_buffer_available[streamID] = TRUE;
232    }
233
234    if (A_FAILED(status)) {
235        return -EIO;
236    }
237
238    AR_DEBUG_PRINTF("HTC RAW, number of streams the target supports: %d \n", streamID);
239
240    servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */
241
242        /* set callbacks and priority list */
243    HTCSetCreditDistribution(ar->arHtcTarget,
244                             ar,
245                             NULL, /* use default */
246                             NULL, /* use default */
247                             &servicepriority,
248                             1);
249
250    /* Start the HTC component */
251    if ((status = HTCStart(ar->arHtcTarget)) != A_OK) {
252        BMIInit();
253        return -EIO;
254    }
255
256    (ar)->arRawIfInit = TRUE;
257
258    return 0;
259}
260
261int ar6000_htc_raw_close(AR_SOFTC_T *ar)
262{
263    A_PRINTF("ar6000_htc_raw_close called \n");
264    HTCStop(ar->arHtcTarget);
265
266        /* reset the device */
267    ar6000_reset_device(ar->arHifDevice, ar->arTargetType);
268    /* Initialize the BMI component */
269    BMIInit();
270
271    return 0;
272}
273
274raw_htc_buffer *
275get_filled_buffer(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID)
276{
277    int count;
278    raw_htc_buffer *busy;
279
280    /* Check for data */
281    for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) {
282        busy = ar->raw_htc_read_buffer[StreamID][count];
283        if (busy->length) {
284            break;
285        }
286    }
287    if (busy->length) {
288        ar->read_buffer_available[StreamID] = TRUE;
289    } else {
290        ar->read_buffer_available[StreamID] = FALSE;
291    }
292
293    return busy;
294}
295
296ssize_t ar6000_htc_raw_read(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID,
297                            char __user *buffer, size_t length)
298{
299    int readPtr;
300    raw_htc_buffer *busy;
301
302    if (arRawStream2EndpointID(ar,StreamID) == 0) {
303        AR_DEBUG_PRINTF("StreamID(%d) not connected! \n", StreamID);
304        return -EFAULT;
305    }
306
307    if (down_interruptible(&ar->raw_htc_read_sem[StreamID])) {
308        return -ERESTARTSYS;
309    }
310
311    busy = get_filled_buffer(ar,StreamID);
312    while (!ar->read_buffer_available[StreamID]) {
313        up(&ar->raw_htc_read_sem[StreamID]);
314
315        /* Wait for the data */
316        AR_DEBUG2_PRINTF("Sleeping StreamID(%d) read process\n", StreamID);
317        if (wait_event_interruptible(ar->raw_htc_read_queue[StreamID],
318                                     ar->read_buffer_available[StreamID]))
319        {
320            return -EINTR;
321        }
322        if (down_interruptible(&ar->raw_htc_read_sem[StreamID])) {
323            return -ERESTARTSYS;
324        }
325        busy = get_filled_buffer(ar,StreamID);
326    }
327
328    /* Read the data */
329    readPtr = busy->currPtr;
330    if (length > busy->length - HTC_HEADER_LEN) {
331        length = busy->length - HTC_HEADER_LEN;
332    }
333    if (copy_to_user(buffer, &busy->data[readPtr], length)) {
334        up(&ar->raw_htc_read_sem[StreamID]);
335        return -EFAULT;
336    }
337
338    busy->currPtr += length;
339
340    //AR_DEBUG_PRINTF("raw read ioctl: currPTR : 0x%X 0x%X \n", busy->currPtr,busy->length);
341
342    if (busy->currPtr == busy->length)
343    {
344        busy->currPtr = 0;
345        busy->length = 0;
346        HTC_PACKET_RESET_RX(&busy->HTCPacket);
347        //AR_DEBUG_PRINTF("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint);
348        HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket);
349    }
350    ar->read_buffer_available[StreamID] = FALSE;
351    up(&ar->raw_htc_read_sem[StreamID]);
352
353    return length;
354}
355
356static raw_htc_buffer *
357get_free_buffer(AR_SOFTC_T *ar, HTC_ENDPOINT_ID StreamID)
358{
359    int count;
360    raw_htc_buffer *free;
361
362    free = NULL;
363    for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) {
364        free = ar->raw_htc_write_buffer[StreamID][count];
365        if (free->length == 0) {
366            break;
367        }
368    }
369    if (!free->length) {
370        ar->write_buffer_available[StreamID] = TRUE;
371    } else {
372        ar->write_buffer_available[StreamID] = FALSE;
373    }
374
375    return free;
376}
377
378ssize_t ar6000_htc_raw_write(AR_SOFTC_T *ar, HTC_RAW_STREAM_ID StreamID,
379                     char __user *buffer, size_t length)
380{
381    int writePtr;
382    raw_htc_buffer *free;
383
384    if (arRawStream2EndpointID(ar,StreamID) == 0) {
385        AR_DEBUG_PRINTF("StreamID(%d) not connected! \n", StreamID);
386        return -EFAULT;
387    }
388
389    if (down_interruptible(&ar->raw_htc_write_sem[StreamID])) {
390        return -ERESTARTSYS;
391    }
392
393    /* Search for a free buffer */
394    free = get_free_buffer(ar,StreamID);
395
396    /* Check if there is space to write else wait */
397    while (!ar->write_buffer_available[StreamID]) {
398        up(&ar->raw_htc_write_sem[StreamID]);
399
400        /* Wait for buffer to become free */
401        AR_DEBUG2_PRINTF("Sleeping StreamID(%d) write process\n", StreamID);
402        if (wait_event_interruptible(ar->raw_htc_write_queue[StreamID],
403                                     ar->write_buffer_available[StreamID]))
404        {
405            return -EINTR;
406        }
407        if (down_interruptible(&ar->raw_htc_write_sem[StreamID])) {
408            return -ERESTARTSYS;
409        }
410        free = get_free_buffer(ar,StreamID);
411    }
412
413    /* Send the data */
414    writePtr = HTC_HEADER_LEN;
415    if (length > (AR6000_BUFFER_SIZE - HTC_HEADER_LEN)) {
416        length = AR6000_BUFFER_SIZE - HTC_HEADER_LEN;
417    }
418
419    if (copy_from_user(&free->data[writePtr], buffer, length)) {
420        up(&ar->raw_htc_read_sem[StreamID]);
421        return -EFAULT;
422    }
423
424    free->length = length;
425
426    SET_HTC_PACKET_INFO_TX(&free->HTCPacket,
427                           free,
428                           &free->data[writePtr],
429                           length,
430                           arRawStream2EndpointID(ar,StreamID),
431                           AR6K_DATA_PKT_TAG);
432
433    HTCSendPkt(ar->arHtcTarget,&free->HTCPacket);
434
435    ar->write_buffer_available[StreamID] = FALSE;
436    up(&ar->raw_htc_write_sem[StreamID]);
437
438    return length;
439}
440#endif /* HTC_RAW_INTERFACE */
441

Archive Download this file



interactive