GNU Linux-libre 4.9.309-gnu1
[releases.git] / drivers / staging / rtl8188eu / os_dep / osdep_service.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
16
17 #define _OSDEP_SERVICE_C_
18
19 #include <osdep_service.h>
20 #include <osdep_intf.h>
21 #include <drv_types.h>
22 #include <recv_osdep.h>
23 #include <linux/vmalloc.h>
24 #include <rtw_ioctl_set.h>
25
26 /*
27 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
28 * @return: one of RTW_STATUS_CODE
29 */
30 inline int RTW_STATUS_CODE(int error_code)
31 {
32         if (error_code >= 0)
33                 return _SUCCESS;
34         return _FAIL;
35 }
36
37 u8 *_rtw_malloc(u32 sz)
38 {
39         return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
40 }
41
42 void *rtw_malloc2d(int h, int w, int size)
43 {
44         int j;
45
46         void **a = kzalloc(h*sizeof(void *) + h*w*size, GFP_KERNEL);
47         if (!a) {
48                 pr_info("%s: alloc memory fail!\n", __func__);
49                 return NULL;
50         }
51
52         for (j = 0; j < h; j++)
53                 a[j] = ((char *)(a+h)) + j*w*size;
54
55         return a;
56 }
57
58 void    _rtw_init_queue(struct __queue *pqueue)
59 {
60         INIT_LIST_HEAD(&(pqueue->queue));
61         spin_lock_init(&(pqueue->lock));
62 }
63
64 struct net_device *rtw_alloc_etherdev_with_old_priv(void *old_priv)
65 {
66         struct net_device *pnetdev;
67         struct rtw_netdev_priv_indicator *pnpi;
68
69         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
70         if (!pnetdev)
71                 goto RETURN;
72
73         pnpi = netdev_priv(pnetdev);
74         pnpi->priv = old_priv;
75
76 RETURN:
77         return pnetdev;
78 }
79
80 void rtw_free_netdev(struct net_device *netdev)
81 {
82         struct rtw_netdev_priv_indicator *pnpi;
83
84         if (!netdev)
85                 goto RETURN;
86
87         pnpi = netdev_priv(netdev);
88
89         if (!pnpi->priv)
90                 goto RETURN;
91
92         vfree(pnpi->priv);
93         free_netdev(netdev);
94
95 RETURN:
96         return;
97 }
98
99 u64 rtw_modular64(u64 x, u64 y)
100 {
101         return do_div(x, y);
102 }
103
104 void rtw_buf_free(u8 **buf, u32 *buf_len)
105 {
106         *buf_len = 0;
107         kfree(*buf);
108         *buf = NULL;
109 }
110
111 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
112 {
113         u32 dup_len = 0;
114         u8 *ori = NULL;
115         u8 *dup = NULL;
116
117         if (!buf || !buf_len)
118                 return;
119
120         if (!src || !src_len)
121                 goto keep_ori;
122
123         /* duplicate src */
124         dup = rtw_malloc(src_len);
125         if (dup) {
126                 dup_len = src_len;
127                 memcpy(dup, src, dup_len);
128         }
129
130 keep_ori:
131         ori = *buf;
132
133         /* replace buf with dup */
134         *buf_len = 0;
135         *buf = dup;
136         *buf_len = dup_len;
137
138         /* free ori */
139         kfree(ori);
140 }