diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2011-01-31 13:49:14 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-04 16:29:50 -0500 |
commit | 9bca0c3b540188e2beea9c2583fa16c46d209888 (patch) | |
tree | d52f0d39dd70d65d9606edfac0d3145dca412007 /drivers/net/wireless/zd1211rw/zd_chip.c | |
parent | 51272292926bc4fff61ba812d5816922b980655b (diff) |
zd1211rw: use stack and preallocated memory for small cmd-buffers
Use stack for allocing small < 64 byte arrays in zd_chip.c and preallocated
buffer in zd_usb.c. This might lower CPU usage for beacon setup.
v2:
- Do not use stack buffers in zd_usb.c as they would be used for urb
transfer_buffer.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_chip.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 43 |
1 files changed, 13 insertions, 30 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index d8dc92711f40..907e6562cb59 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -108,25 +108,17 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr | |||
108 | { | 108 | { |
109 | int r; | 109 | int r; |
110 | int i; | 110 | int i; |
111 | zd_addr_t *a16; | 111 | zd_addr_t a16[USB_MAX_IOREAD32_COUNT * 2]; |
112 | u16 *v16; | 112 | u16 v16[USB_MAX_IOREAD32_COUNT * 2]; |
113 | unsigned int count16; | 113 | unsigned int count16; |
114 | 114 | ||
115 | if (count > USB_MAX_IOREAD32_COUNT) | 115 | if (count > USB_MAX_IOREAD32_COUNT) |
116 | return -EINVAL; | 116 | return -EINVAL; |
117 | 117 | ||
118 | /* Allocate a single memory block for values and addresses. */ | 118 | /* Use stack for values and addresses. */ |
119 | count16 = 2*count; | 119 | count16 = 2 * count; |
120 | /* zd_addr_t is __nocast, so the kmalloc needs an explicit cast */ | 120 | BUG_ON(count16 * sizeof(zd_addr_t) > sizeof(a16)); |
121 | a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), | 121 | BUG_ON(count16 * sizeof(u16) > sizeof(v16)); |
122 | GFP_KERNEL); | ||
123 | if (!a16) { | ||
124 | dev_dbg_f(zd_chip_dev(chip), | ||
125 | "error ENOMEM in allocation of a16\n"); | ||
126 | r = -ENOMEM; | ||
127 | goto out; | ||
128 | } | ||
129 | v16 = (u16 *)(a16 + count16); | ||
130 | 122 | ||
131 | for (i = 0; i < count; i++) { | 123 | for (i = 0; i < count; i++) { |
132 | int j = 2*i; | 124 | int j = 2*i; |
@@ -139,7 +131,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr | |||
139 | if (r) { | 131 | if (r) { |
140 | dev_dbg_f(zd_chip_dev(chip), | 132 | dev_dbg_f(zd_chip_dev(chip), |
141 | "error: zd_ioread16v_locked. Error number %d\n", r); | 133 | "error: zd_ioread16v_locked. Error number %d\n", r); |
142 | goto out; | 134 | return r; |
143 | } | 135 | } |
144 | 136 | ||
145 | for (i = 0; i < count; i++) { | 137 | for (i = 0; i < count; i++) { |
@@ -147,18 +139,18 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr | |||
147 | values[i] = (v16[j] << 16) | v16[j+1]; | 139 | values[i] = (v16[j] << 16) | v16[j+1]; |
148 | } | 140 | } |
149 | 141 | ||
150 | out: | 142 | return 0; |
151 | kfree((void *)a16); | ||
152 | return r; | ||
153 | } | 143 | } |
154 | 144 | ||
155 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | 145 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, |
156 | unsigned int count) | 146 | unsigned int count) |
157 | { | 147 | { |
158 | int i, j, r; | 148 | int i, j, r; |
159 | struct zd_ioreq16 *ioreqs16; | 149 | struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; |
160 | unsigned int count16; | 150 | unsigned int count16; |
161 | 151 | ||
152 | /* Use stack for values and addresses. */ | ||
153 | |||
162 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 154 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
163 | 155 | ||
164 | if (count == 0) | 156 | if (count == 0) |
@@ -166,15 +158,8 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | |||
166 | if (count > USB_MAX_IOWRITE32_COUNT) | 158 | if (count > USB_MAX_IOWRITE32_COUNT) |
167 | return -EINVAL; | 159 | return -EINVAL; |
168 | 160 | ||
169 | /* Allocate a single memory block for values and addresses. */ | 161 | count16 = 2 * count; |
170 | count16 = 2*count; | 162 | BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16)); |
171 | ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL); | ||
172 | if (!ioreqs16) { | ||
173 | r = -ENOMEM; | ||
174 | dev_dbg_f(zd_chip_dev(chip), | ||
175 | "error %d in ioreqs16 allocation\n", r); | ||
176 | goto out; | ||
177 | } | ||
178 | 163 | ||
179 | for (i = 0; i < count; i++) { | 164 | for (i = 0; i < count; i++) { |
180 | j = 2*i; | 165 | j = 2*i; |
@@ -192,8 +177,6 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | |||
192 | "error %d in zd_usb_write16v\n", r); | 177 | "error %d in zd_usb_write16v\n", r); |
193 | } | 178 | } |
194 | #endif /* DEBUG */ | 179 | #endif /* DEBUG */ |
195 | out: | ||
196 | kfree(ioreqs16); | ||
197 | return r; | 180 | return r; |
198 | } | 181 | } |
199 | 182 | ||