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 | |
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')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 41 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 1 |
3 files changed, 41 insertions, 44 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 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 9493ab86a41e..bf1de04dc9f2 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -1361,15 +1361,20 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1361 | return -EWOULDBLOCK; | 1361 | return -EWOULDBLOCK; |
1362 | } | 1362 | } |
1363 | if (!usb_int_enabled(usb)) { | 1363 | if (!usb_int_enabled(usb)) { |
1364 | dev_dbg_f(zd_usb_dev(usb), | 1364 | dev_dbg_f(zd_usb_dev(usb), |
1365 | "error: usb interrupt not enabled\n"); | 1365 | "error: usb interrupt not enabled\n"); |
1366 | return -EWOULDBLOCK; | 1366 | return -EWOULDBLOCK; |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1370 | BUILD_BUG_ON(sizeof(struct usb_req_read_regs) + USB_MAX_IOREAD16_COUNT * | ||
1371 | sizeof(__le16) > sizeof(usb->req_buf)); | ||
1372 | BUG_ON(sizeof(struct usb_req_read_regs) + count * sizeof(__le16) > | ||
1373 | sizeof(usb->req_buf)); | ||
1374 | |||
1369 | req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16); | 1375 | req_len = sizeof(struct usb_req_read_regs) + count * sizeof(__le16); |
1370 | req = kmalloc(req_len, GFP_KERNEL); | 1376 | req = (void *)usb->req_buf; |
1371 | if (!req) | 1377 | |
1372 | return -ENOMEM; | ||
1373 | req->id = cpu_to_le16(USB_REQ_READ_REGS); | 1378 | req->id = cpu_to_le16(USB_REQ_READ_REGS); |
1374 | for (i = 0; i < count; i++) | 1379 | for (i = 0; i < count; i++) |
1375 | req->addr[i] = cpu_to_le16((u16)addresses[i]); | 1380 | req->addr[i] = cpu_to_le16((u16)addresses[i]); |
@@ -1402,7 +1407,6 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1402 | 1407 | ||
1403 | r = get_results(usb, values, req, count); | 1408 | r = get_results(usb, values, req, count); |
1404 | error: | 1409 | error: |
1405 | kfree(req); | ||
1406 | return r; | 1410 | return r; |
1407 | } | 1411 | } |
1408 | 1412 | ||
@@ -1428,11 +1432,17 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1428 | return -EWOULDBLOCK; | 1432 | return -EWOULDBLOCK; |
1429 | } | 1433 | } |
1430 | 1434 | ||
1435 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1436 | BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + | ||
1437 | USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > | ||
1438 | sizeof(usb->req_buf)); | ||
1439 | BUG_ON(sizeof(struct usb_req_write_regs) + | ||
1440 | count * sizeof(struct reg_data) > | ||
1441 | sizeof(usb->req_buf)); | ||
1442 | |||
1431 | req_len = sizeof(struct usb_req_write_regs) + | 1443 | req_len = sizeof(struct usb_req_write_regs) + |
1432 | count * sizeof(struct reg_data); | 1444 | count * sizeof(struct reg_data); |
1433 | req = kmalloc(req_len, GFP_KERNEL); | 1445 | req = (void *)usb->req_buf; |
1434 | if (!req) | ||
1435 | return -ENOMEM; | ||
1436 | 1446 | ||
1437 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); | 1447 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); |
1438 | for (i = 0; i < count; i++) { | 1448 | for (i = 0; i < count; i++) { |
@@ -1460,7 +1470,6 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1460 | 1470 | ||
1461 | /* FALL-THROUGH with r == 0 */ | 1471 | /* FALL-THROUGH with r == 0 */ |
1462 | error: | 1472 | error: |
1463 | kfree(req); | ||
1464 | return r; | 1473 | return r; |
1465 | } | 1474 | } |
1466 | 1475 | ||
@@ -1505,14 +1514,19 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) | |||
1505 | if (r) { | 1514 | if (r) { |
1506 | dev_dbg_f(zd_usb_dev(usb), | 1515 | dev_dbg_f(zd_usb_dev(usb), |
1507 | "error %d: Couldn't read CR203\n", r); | 1516 | "error %d: Couldn't read CR203\n", r); |
1508 | goto out; | 1517 | return r; |
1509 | } | 1518 | } |
1510 | bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); | 1519 | bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA); |
1511 | 1520 | ||
1521 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1522 | BUILD_BUG_ON(sizeof(struct usb_req_rfwrite) + | ||
1523 | USB_MAX_RFWRITE_BIT_COUNT * sizeof(__le16) > | ||
1524 | sizeof(usb->req_buf)); | ||
1525 | BUG_ON(sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16) > | ||
1526 | sizeof(usb->req_buf)); | ||
1527 | |||
1512 | req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16); | 1528 | req_len = sizeof(struct usb_req_rfwrite) + bits * sizeof(__le16); |
1513 | req = kmalloc(req_len, GFP_KERNEL); | 1529 | req = (void *)usb->req_buf; |
1514 | if (!req) | ||
1515 | return -ENOMEM; | ||
1516 | 1530 | ||
1517 | req->id = cpu_to_le16(USB_REQ_WRITE_RF); | 1531 | req->id = cpu_to_le16(USB_REQ_WRITE_RF); |
1518 | /* 1: 3683a, but not used in ZYDAS driver */ | 1532 | /* 1: 3683a, but not used in ZYDAS driver */ |
@@ -1544,6 +1558,5 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) | |||
1544 | 1558 | ||
1545 | /* FALL-THROUGH with r == 0 */ | 1559 | /* FALL-THROUGH with r == 0 */ |
1546 | out: | 1560 | out: |
1547 | kfree(req); | ||
1548 | return r; | 1561 | return r; |
1549 | } | 1562 | } |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 233ce825b71c..2ed48ae3e604 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -207,6 +207,7 @@ struct zd_usb { | |||
207 | struct zd_usb_rx rx; | 207 | struct zd_usb_rx rx; |
208 | struct zd_usb_tx tx; | 208 | struct zd_usb_tx tx; |
209 | struct usb_interface *intf; | 209 | struct usb_interface *intf; |
210 | u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ | ||
210 | u8 is_zd1211b:1, initialized:1; | 211 | u8 is_zd1211b:1, initialized:1; |
211 | }; | 212 | }; |
212 | 213 | ||