Staging: csr: update to version 5.1.0 of the driver
[linux-2.6.git] / drivers / staging / csr / os.c
blobf5a9352ce78496b2932f6e4f266dc9d91c9dae60
1 /*
2 * ---------------------------------------------------------------------------
3 * FILE: os.c
5 * PURPOSE:
6 * Routines to fulfil the OS-abstraction for the HIP lib.
7 * It is part of the porting exercise.
9 * Copyright (C) 2005-2009 by Cambridge Silicon Radio Ltd.
11 * Refer to LICENSE.txt included with this source code for details on
12 * the license terms.
14 * ---------------------------------------------------------------------------
17 /**
18 * The HIP lib OS abstraction consists of the implementation
19 * of the functions in this file. It is part of the porting exercise.
22 #include "unifi_priv.h"
26 * ---------------------------------------------------------------------------
27 * unifi_net_data_malloc
29 * Allocate an OS specific net data buffer of "size" bytes.
30 * The bulk_data_slot.os_data_ptr must be initialised to point
31 * to the buffer allocated. The bulk_data_slot.length must be
32 * initialised to the requested size, zero otherwise.
33 * The bulk_data_slot.os_net_buf_ptr can be initialised to
34 * an OS specific pointer to be used in the unifi_net_data_free().
37 * Arguments:
38 * ospriv Pointer to device private context struct.
39 * bulk_data_slot Pointer to the bulk data structure to initialise.
40 * size Size of the buffer to be allocated.
42 * Returns:
43 * CSR_RESULT_SUCCESS on success, CSR_RESULT_FAILURE otherwise.
44 * ---------------------------------------------------------------------------
46 CsrResult
47 unifi_net_data_malloc(void *ospriv, bulk_data_desc_t *bulk_data_slot, unsigned int size)
49 struct sk_buff *skb;
50 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
51 int rounded_length;
53 if (priv->card_info.sdio_block_size == 0) {
54 unifi_error(priv, "unifi_net_data_malloc: Invalid SDIO block size\n");
55 return CSR_RESULT_FAILURE;
58 rounded_length = (size + priv->card_info.sdio_block_size - 1) & ~(priv->card_info.sdio_block_size - 1);
61 * (ETH_HLEN + 2) bytes tailroom for header manipulation
62 * CSR_WIFI_ALIGN_BYTES bytes headroom for alignment manipulation
64 skb = dev_alloc_skb(rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES);
65 if (! skb) {
66 unifi_error(ospriv, "alloc_skb failed.\n");
67 bulk_data_slot->os_net_buf_ptr = NULL;
68 bulk_data_slot->net_buf_length = 0;
69 bulk_data_slot->os_data_ptr = NULL;
70 bulk_data_slot->data_length = 0;
71 return CSR_RESULT_FAILURE;
74 bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb;
75 bulk_data_slot->net_buf_length = rounded_length + 2 + ETH_HLEN + CSR_WIFI_ALIGN_BYTES;
76 bulk_data_slot->os_data_ptr = (const void*)skb->data;
77 bulk_data_slot->data_length = size;
79 return CSR_RESULT_SUCCESS;
80 } /* unifi_net_data_malloc() */
83 * ---------------------------------------------------------------------------
84 * unifi_net_data_free
86 * Free an OS specific net data buffer.
87 * The bulk_data_slot.length must be initialised to 0.
90 * Arguments:
91 * ospriv Pointer to device private context struct.
92 * bulk_data_slot Pointer to the bulk data structure that
93 * holds the data to be freed.
95 * Returns:
96 * None.
97 * ---------------------------------------------------------------------------
99 void
100 unifi_net_data_free(void *ospriv, bulk_data_desc_t *bulk_data_slot)
102 struct sk_buff *skb;
103 CSR_UNUSED(ospriv);
105 skb = (struct sk_buff *)bulk_data_slot->os_net_buf_ptr;
106 dev_kfree_skb(skb);
108 bulk_data_slot->net_buf_length = 0;
109 bulk_data_slot->data_length = 0;
110 bulk_data_slot->os_data_ptr = bulk_data_slot->os_net_buf_ptr = NULL;
112 } /* unifi_net_data_free() */
116 * ---------------------------------------------------------------------------
117 * unifi_net_dma_align
119 * DMA align an OS specific net data buffer.
120 * The buffer must be empty.
123 * Arguments:
124 * ospriv Pointer to device private context struct.
125 * bulk_data_slot Pointer to the bulk data structure that
126 * holds the data to be aligned.
128 * Returns:
129 * None.
130 * ---------------------------------------------------------------------------
132 CsrResult
133 unifi_net_dma_align(void *ospriv, bulk_data_desc_t *bulk_data_slot)
135 struct sk_buff *skb;
136 unsigned long buf_address;
137 int offset;
138 unifi_priv_t *priv = (unifi_priv_t*)ospriv;
140 if ((bulk_data_slot == NULL) || (CSR_WIFI_ALIGN_BYTES == 0)) {
141 return CSR_RESULT_SUCCESS;
144 if ((bulk_data_slot->os_data_ptr == NULL) || (bulk_data_slot->data_length == 0)) {
145 return CSR_RESULT_SUCCESS;
148 buf_address = (unsigned long)(bulk_data_slot->os_data_ptr) & (CSR_WIFI_ALIGN_BYTES - 1);
150 unifi_trace(priv, UDBG5,
151 "unifi_net_dma_align: Allign buffer (0x%p) by %d bytes\n",
152 bulk_data_slot->os_data_ptr, buf_address);
154 offset = CSR_WIFI_ALIGN_BYTES - buf_address;
155 if (offset < 0) {
156 unifi_error(priv, "unifi_net_dma_align: Failed (offset=%d)\n", offset);
157 return CSR_RESULT_FAILURE;
160 skb = (struct sk_buff*)(bulk_data_slot->os_net_buf_ptr);
161 skb_reserve(skb, offset);
162 bulk_data_slot->os_net_buf_ptr = (const unsigned char*)skb;
163 bulk_data_slot->os_data_ptr = (const void*)(skb->data);
165 return CSR_RESULT_SUCCESS;
167 } /* unifi_net_dma_align() */
169 #ifdef ANDROID_TIMESTAMP
170 static volatile unsigned int printk_cpu = UINT_MAX;
171 char tbuf[30];
173 char* print_time(void )
175 unsigned long long t;
176 unsigned long nanosec_rem;
178 t = cpu_clock(printk_cpu);
179 nanosec_rem = do_div(t, 1000000000);
180 sprintf(tbuf, "[%5lu.%06lu] ",
181 (unsigned long) t,
182 nanosec_rem / 1000);
184 return tbuf;
186 #endif
189 /* Module parameters */
190 extern int unifi_debug;
192 #ifdef UNIFI_DEBUG
193 #define DEBUG_BUFFER_SIZE 120
195 #define FORMAT_TRACE(_s, _len, _args, _fmt) \
196 do { \
197 va_start(_args, _fmt); \
198 _len += vsnprintf(&(_s)[_len], \
199 (DEBUG_BUFFER_SIZE - _len), \
200 _fmt, _args); \
201 va_end(_args); \
202 if (_len >= DEBUG_BUFFER_SIZE) { \
203 (_s)[DEBUG_BUFFER_SIZE - 2] = '\n'; \
204 (_s)[DEBUG_BUFFER_SIZE - 1] = 0; \
206 } while (0)
208 void
209 unifi_error(void* ospriv, const char *fmt, ...)
211 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
212 char s[DEBUG_BUFFER_SIZE];
213 va_list args;
214 unsigned int len;
215 #ifdef ANDROID_TIMESTAMP
216 if (priv != NULL) {
217 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance);
218 } else {
219 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time());
221 #else
222 if (priv != NULL) {
223 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
224 } else {
225 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
227 #endif /* ANDROID_TIMESTAMP */
228 FORMAT_TRACE(s, len, args, fmt);
230 printk("%s", s);
233 void
234 unifi_warning(void* ospriv, const char *fmt, ...)
236 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
237 char s[DEBUG_BUFFER_SIZE];
238 va_list args;
239 unsigned int len;
241 #ifdef ANDROID_TIMESTAMP
242 if (priv != NULL) {
243 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi%d: ", print_time(), priv->instance);
244 } else {
245 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "%s unifi: ", print_time());
247 #else
248 if (priv != NULL) {
249 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi%d: ", priv->instance);
250 } else {
251 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_WARNING "unifi: ");
253 #endif /* ANDROID_TIMESTAMP */
255 FORMAT_TRACE(s, len, args, fmt);
257 printk("%s", s);
261 void
262 unifi_notice(void* ospriv, const char *fmt, ...)
264 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
265 char s[DEBUG_BUFFER_SIZE];
266 va_list args;
267 unsigned int len;
269 #ifdef ANDROID_TIMESTAMP
270 if (priv != NULL) {
271 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi%d: ", print_time(), priv->instance);
272 } else {
273 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "%s unifi: ", print_time());
275 #else
276 if (priv != NULL) {
277 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi%d: ", priv->instance);
278 } else {
279 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_NOTICE "unifi: ");
281 #endif /* ANDROID_TIMESTAMP */
283 FORMAT_TRACE(s, len, args, fmt);
285 printk("%s", s);
289 void
290 unifi_info(void* ospriv, const char *fmt, ...)
292 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
293 char s[DEBUG_BUFFER_SIZE];
294 va_list args;
295 unsigned int len;
297 #ifdef ANDROID_TIMESTAMP
298 if (priv != NULL) {
299 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi%d: ", print_time(), priv->instance);
300 } else {
301 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "%s unifi: ", print_time());
303 #else
304 if (priv != NULL) {
305 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi%d: ", priv->instance);
306 } else {
307 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_INFO "unifi: ");
309 #endif /* ANDROID_TIMESTAMP */
311 FORMAT_TRACE(s, len, args, fmt);
313 printk("%s", s);
316 /* debugging */
317 void
318 unifi_trace(void* ospriv, int level, const char *fmt, ...)
320 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
321 char s[DEBUG_BUFFER_SIZE];
322 va_list args;
323 unsigned int len;
325 if (unifi_debug >= level) {
326 #ifdef ANDROID_TIMESTAMP
327 if (priv != NULL) {
328 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi%d: ", print_time(), priv->instance);
329 } else {
330 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "%s unifi: ", print_time());
332 #else
333 if (priv != NULL) {
334 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi%d: ", priv->instance);
335 } else {
336 len = snprintf(s, DEBUG_BUFFER_SIZE, KERN_ERR "unifi: ");
338 #endif /* ANDROID_TIMESTAMP */
340 FORMAT_TRACE(s, len, args, fmt);
342 printk("%s", s);
346 #else
348 void
349 unifi_error_nop(void* ospriv, const char *fmt, ...)
353 void
354 unifi_trace_nop(void* ospriv, int level, const char *fmt, ...)
358 #endif /* UNIFI_DEBUG */
362 * ---------------------------------------------------------------------------
364 * Debugging support.
366 * ---------------------------------------------------------------------------
369 #ifdef UNIFI_DEBUG
371 /* Memory dump with level filter controlled by unifi_debug */
372 void
373 unifi_dump(void *ospriv, int level, const char *msg, void *mem, CsrUint16 len)
375 unifi_priv_t *priv = (unifi_priv_t*) ospriv;
377 if (unifi_debug >= level) {
378 #ifdef ANDROID_TIMESTAMP
379 if (priv != NULL) {
380 printk(KERN_ERR "%s unifi%d: --- dump: %s ---\n", print_time(), priv->instance, msg ? msg : "");
381 } else {
382 printk(KERN_ERR "%s unifi: --- dump: %s ---\n", print_time(), msg ? msg : "");
384 #else
385 if (priv != NULL) {
386 printk(KERN_ERR "unifi%d: --- dump: %s ---\n", priv->instance, msg ? msg : "");
387 } else {
388 printk(KERN_ERR "unifi: --- dump: %s ---\n", msg ? msg : "");
390 #endif /* ANDROID_TIMESTAMP */
391 dump(mem, len);
393 if (priv != NULL) {
394 printk(KERN_ERR "unifi%d: --- end of dump ---\n", priv->instance);
395 } else {
396 printk(KERN_ERR "unifi: --- end of dump ---\n");
401 /* Memory dump that appears all the time, use sparingly */
402 void
403 dump(void *mem, CsrUint16 len)
405 int i, col = 0;
406 unsigned char *pdata = (unsigned char *)mem;
407 #ifdef ANDROID_TIMESTAMP
408 printk("timestamp %s \n", print_time());
409 #endif /* ANDROID_TIMESTAMP */
410 if (mem == NULL) {
411 printk("(null dump)\n");
412 return;
414 for (i = 0; i < len; i++) {
415 if (col == 0) {
416 printk("0x%02X: ", i);
419 printk(" %02X", pdata[i]);
421 if (++col == 16) {
422 printk("\n");
423 col = 0;
426 if (col) {
427 printk("\n");
429 } /* dump() */
432 void
433 dump16(void *mem, CsrUint16 len)
435 int i, col=0;
436 unsigned short *p = (unsigned short *)mem;
437 #ifdef ANDROID_TIMESTAMP
438 printk("timestamp %s \n", print_time());
439 #endif /* ANDROID_TIMESTAMP */
440 for (i = 0; i < len; i+=2) {
441 if (col == 0) {
442 printk("0x%02X: ", i);
445 printk(" %04X", *p++);
447 if (++col == 8) {
448 printk("\n");
449 col = 0;
452 if (col) {
453 printk("\n");
458 #ifdef CSR_WIFI_HIP_DEBUG_OFFLINE
459 void
460 dump_str(void *mem, CsrUint16 len)
462 int i, col = 0;
463 unsigned char *pdata = (unsigned char *)mem;
464 #ifdef ANDROID_TIMESTAMP
465 printk("timestamp %s \n", print_time());
466 #endif /* ANDROID_TIMESTAMP */
467 for (i = 0; i < len; i++) {
468 printk("%c", pdata[i]);
470 if (col) {
471 printk("\n");
474 } /* dump_str() */
475 #endif /* CSR_ONLY_NOTES */
478 #endif /* UNIFI_DEBUG */
481 /* ---------------------------------------------------------------------------
482 * - End -
483 * ------------------------------------------------------------------------- */