.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (c) 1999-2013 Petko Manolov (petkan@nucleusys.com) |
---|
3 | | - * |
---|
4 | | - * This program is free software; you can redistribute it and/or modify |
---|
5 | | - * it under the terms of the GNU General Public License version 2 as |
---|
6 | | - * published by the Free Software Foundation. |
---|
7 | 4 | * |
---|
8 | 5 | * ChangeLog: |
---|
9 | 6 | * .... Most of the time spent on reading sources & docs. |
---|
.. | .. |
---|
57 | 54 | #undef PEGASUS_WRITE_EEPROM |
---|
58 | 55 | #define BMSR_MEDIA (BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | \ |
---|
59 | 56 | BMSR_100FULL | BMSR_ANEGCAPABLE) |
---|
| 57 | +#define CARRIER_CHECK_DELAY (2 * HZ) |
---|
60 | 58 | |
---|
61 | 59 | static bool loopback; |
---|
62 | 60 | static bool mii_mode; |
---|
.. | .. |
---|
126 | 124 | |
---|
127 | 125 | static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) |
---|
128 | 126 | { |
---|
129 | | - u8 *buf; |
---|
130 | | - int ret; |
---|
131 | | - |
---|
132 | | - buf = kmalloc(size, GFP_NOIO); |
---|
133 | | - if (!buf) |
---|
134 | | - return -ENOMEM; |
---|
135 | | - |
---|
136 | | - ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), |
---|
137 | | - PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, |
---|
138 | | - indx, buf, size, 1000); |
---|
139 | | - if (ret < 0) |
---|
140 | | - netif_dbg(pegasus, drv, pegasus->net, |
---|
141 | | - "%s returned %d\n", __func__, ret); |
---|
142 | | - else if (ret <= size) |
---|
143 | | - memcpy(data, buf, ret); |
---|
144 | | - kfree(buf); |
---|
145 | | - return ret; |
---|
| 127 | + return usb_control_msg_recv(pegasus->usb, 0, PEGASUS_REQ_GET_REGS, |
---|
| 128 | + PEGASUS_REQT_READ, 0, indx, data, size, |
---|
| 129 | + 1000, GFP_NOIO); |
---|
146 | 130 | } |
---|
147 | 131 | |
---|
148 | 132 | static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, |
---|
149 | 133 | const void *data) |
---|
150 | 134 | { |
---|
151 | | - u8 *buf; |
---|
152 | 135 | int ret; |
---|
153 | 136 | |
---|
154 | | - buf = kmemdup(data, size, GFP_NOIO); |
---|
155 | | - if (!buf) |
---|
156 | | - return -ENOMEM; |
---|
157 | | - |
---|
158 | | - ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), |
---|
159 | | - PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, |
---|
160 | | - indx, buf, size, 100); |
---|
| 137 | + ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REGS, |
---|
| 138 | + PEGASUS_REQT_WRITE, 0, indx, data, size, |
---|
| 139 | + 1000, GFP_NOIO); |
---|
161 | 140 | if (ret < 0) |
---|
162 | | - netif_dbg(pegasus, drv, pegasus->net, |
---|
163 | | - "%s returned %d\n", __func__, ret); |
---|
164 | | - kfree(buf); |
---|
| 141 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret); |
---|
| 142 | + |
---|
165 | 143 | return ret; |
---|
166 | 144 | } |
---|
167 | 145 | |
---|
| 146 | +/* |
---|
| 147 | + * There is only one way to write to a single ADM8511 register and this is via |
---|
| 148 | + * specific control request. 'data' is ignored by the device, but it is here to |
---|
| 149 | + * not break the API. |
---|
| 150 | + */ |
---|
168 | 151 | static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) |
---|
169 | 152 | { |
---|
170 | | - u8 *buf; |
---|
| 153 | + void *buf = &data; |
---|
171 | 154 | int ret; |
---|
172 | 155 | |
---|
173 | | - buf = kmemdup(&data, 1, GFP_NOIO); |
---|
174 | | - if (!buf) |
---|
175 | | - return -ENOMEM; |
---|
176 | | - |
---|
177 | | - ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), |
---|
178 | | - PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, |
---|
179 | | - indx, buf, 1, 1000); |
---|
| 156 | + ret = usb_control_msg_send(pegasus->usb, 0, PEGASUS_REQ_SET_REG, |
---|
| 157 | + PEGASUS_REQT_WRITE, data, indx, buf, 1, |
---|
| 158 | + 1000, GFP_NOIO); |
---|
180 | 159 | if (ret < 0) |
---|
181 | | - netif_dbg(pegasus, drv, pegasus->net, |
---|
182 | | - "%s returned %d\n", __func__, ret); |
---|
183 | | - kfree(buf); |
---|
| 160 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed with %d\n", __func__, ret); |
---|
| 161 | + |
---|
184 | 162 | return ret; |
---|
185 | 163 | } |
---|
186 | 164 | |
---|
.. | .. |
---|
221 | 199 | |
---|
222 | 200 | static int __mii_op(pegasus_t *p, __u8 phy, __u8 indx, __u16 *regd, __u8 cmd) |
---|
223 | 201 | { |
---|
224 | | - int i; |
---|
225 | | - __u8 data[4] = { phy, 0, 0, indx }; |
---|
| 202 | + int i, ret; |
---|
226 | 203 | __le16 regdi; |
---|
227 | | - int ret = -ETIMEDOUT; |
---|
| 204 | + __u8 data[4] = { phy, 0, 0, indx }; |
---|
228 | 205 | |
---|
229 | 206 | if (cmd & PHY_WRITE) { |
---|
230 | 207 | __le16 *t = (__le16 *) & data[1]; |
---|
.. | .. |
---|
240 | 217 | if (data[0] & PHY_DONE) |
---|
241 | 218 | break; |
---|
242 | 219 | } |
---|
243 | | - if (i >= REG_TIMEOUT) |
---|
| 220 | + if (i >= REG_TIMEOUT) { |
---|
| 221 | + ret = -ETIMEDOUT; |
---|
244 | 222 | goto fail; |
---|
| 223 | + } |
---|
245 | 224 | if (cmd & PHY_READ) { |
---|
246 | 225 | ret = get_registers(p, PhyData, 2, ®di); |
---|
| 226 | + if (ret < 0) |
---|
| 227 | + goto fail; |
---|
247 | 228 | *regd = le16_to_cpu(regdi); |
---|
248 | | - return ret; |
---|
249 | 229 | } |
---|
250 | 230 | return 0; |
---|
251 | 231 | fail: |
---|
.. | .. |
---|
268 | 248 | static int mdio_read(struct net_device *dev, int phy_id, int loc) |
---|
269 | 249 | { |
---|
270 | 250 | pegasus_t *pegasus = netdev_priv(dev); |
---|
| 251 | + int ret; |
---|
271 | 252 | u16 res; |
---|
272 | 253 | |
---|
273 | | - read_mii_word(pegasus, phy_id, loc, &res); |
---|
| 254 | + ret = read_mii_word(pegasus, phy_id, loc, &res); |
---|
| 255 | + if (ret < 0) |
---|
| 256 | + return ret; |
---|
| 257 | + |
---|
274 | 258 | return (int)res; |
---|
275 | 259 | } |
---|
276 | 260 | |
---|
.. | .. |
---|
284 | 268 | |
---|
285 | 269 | static int read_eprom_word(pegasus_t *pegasus, __u8 index, __u16 *retdata) |
---|
286 | 270 | { |
---|
287 | | - int i; |
---|
288 | | - __u8 tmp = 0; |
---|
| 271 | + int ret, i; |
---|
289 | 272 | __le16 retdatai; |
---|
290 | | - int ret; |
---|
| 273 | + __u8 tmp = 0; |
---|
291 | 274 | |
---|
292 | 275 | set_register(pegasus, EpromCtrl, 0); |
---|
293 | 276 | set_register(pegasus, EpromOffset, index); |
---|
.. | .. |
---|
295 | 278 | |
---|
296 | 279 | for (i = 0; i < REG_TIMEOUT; i++) { |
---|
297 | 280 | ret = get_registers(pegasus, EpromCtrl, 1, &tmp); |
---|
| 281 | + if (ret < 0) |
---|
| 282 | + goto fail; |
---|
298 | 283 | if (tmp & EPROM_DONE) |
---|
299 | 284 | break; |
---|
300 | | - if (ret == -ESHUTDOWN) |
---|
301 | | - goto fail; |
---|
302 | 285 | } |
---|
303 | | - if (i >= REG_TIMEOUT) |
---|
| 286 | + if (i >= REG_TIMEOUT) { |
---|
| 287 | + ret = -ETIMEDOUT; |
---|
304 | 288 | goto fail; |
---|
| 289 | + } |
---|
305 | 290 | |
---|
306 | 291 | ret = get_registers(pegasus, EpromData, 2, &retdatai); |
---|
| 292 | + if (ret < 0) |
---|
| 293 | + goto fail; |
---|
307 | 294 | *retdata = le16_to_cpu(retdatai); |
---|
308 | 295 | return ret; |
---|
309 | 296 | |
---|
310 | 297 | fail: |
---|
311 | | - netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
312 | | - return -ETIMEDOUT; |
---|
| 298 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
| 299 | + return ret; |
---|
313 | 300 | } |
---|
314 | 301 | |
---|
315 | 302 | #ifdef PEGASUS_WRITE_EEPROM |
---|
.. | .. |
---|
357 | 344 | return ret; |
---|
358 | 345 | |
---|
359 | 346 | fail: |
---|
360 | | - netif_warn(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
| 347 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
361 | 348 | return -ETIMEDOUT; |
---|
362 | 349 | } |
---|
363 | | -#endif /* PEGASUS_WRITE_EEPROM */ |
---|
| 350 | +#endif /* PEGASUS_WRITE_EEPROM */ |
---|
364 | 351 | |
---|
365 | | -static inline void get_node_id(pegasus_t *pegasus, __u8 *id) |
---|
| 352 | +static inline int get_node_id(pegasus_t *pegasus, u8 *id) |
---|
366 | 353 | { |
---|
367 | | - int i; |
---|
368 | | - __u16 w16; |
---|
| 354 | + int i, ret; |
---|
| 355 | + u16 w16; |
---|
369 | 356 | |
---|
370 | 357 | for (i = 0; i < 3; i++) { |
---|
371 | | - read_eprom_word(pegasus, i, &w16); |
---|
| 358 | + ret = read_eprom_word(pegasus, i, &w16); |
---|
| 359 | + if (ret < 0) |
---|
| 360 | + return ret; |
---|
372 | 361 | ((__le16 *) id)[i] = cpu_to_le16(w16); |
---|
373 | 362 | } |
---|
| 363 | + |
---|
| 364 | + return 0; |
---|
374 | 365 | } |
---|
375 | 366 | |
---|
376 | 367 | static void set_ethernet_addr(pegasus_t *pegasus) |
---|
377 | 368 | { |
---|
378 | | - __u8 node_id[6]; |
---|
| 369 | + int ret; |
---|
| 370 | + u8 node_id[6]; |
---|
379 | 371 | |
---|
380 | 372 | if (pegasus->features & PEGASUS_II) { |
---|
381 | | - get_registers(pegasus, 0x10, sizeof(node_id), node_id); |
---|
| 373 | + ret = get_registers(pegasus, 0x10, sizeof(node_id), node_id); |
---|
| 374 | + if (ret < 0) |
---|
| 375 | + goto err; |
---|
382 | 376 | } else { |
---|
383 | | - get_node_id(pegasus, node_id); |
---|
384 | | - set_registers(pegasus, EthID, sizeof(node_id), node_id); |
---|
| 377 | + ret = get_node_id(pegasus, node_id); |
---|
| 378 | + if (ret < 0) |
---|
| 379 | + goto err; |
---|
| 380 | + ret = set_registers(pegasus, EthID, sizeof(node_id), node_id); |
---|
| 381 | + if (ret < 0) |
---|
| 382 | + goto err; |
---|
385 | 383 | } |
---|
| 384 | + |
---|
386 | 385 | memcpy(pegasus->net->dev_addr, node_id, sizeof(node_id)); |
---|
| 386 | + |
---|
| 387 | + return; |
---|
| 388 | +err: |
---|
| 389 | + eth_hw_addr_random(pegasus->net); |
---|
| 390 | + netif_dbg(pegasus, drv, pegasus->net, "software assigned MAC address.\n"); |
---|
| 391 | + |
---|
| 392 | + return; |
---|
387 | 393 | } |
---|
388 | 394 | |
---|
389 | 395 | static inline int reset_mac(pegasus_t *pegasus) |
---|
390 | 396 | { |
---|
| 397 | + int ret, i; |
---|
391 | 398 | __u8 data = 0x8; |
---|
392 | | - int i; |
---|
393 | 399 | |
---|
394 | 400 | set_register(pegasus, EthCtrl1, data); |
---|
395 | 401 | for (i = 0; i < REG_TIMEOUT; i++) { |
---|
396 | | - get_registers(pegasus, EthCtrl1, 1, &data); |
---|
| 402 | + ret = get_registers(pegasus, EthCtrl1, 1, &data); |
---|
| 403 | + if (ret < 0) |
---|
| 404 | + goto fail; |
---|
397 | 405 | if (~data & 0x08) { |
---|
398 | 406 | if (loopback) |
---|
399 | 407 | break; |
---|
.. | .. |
---|
416 | 424 | } |
---|
417 | 425 | if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) { |
---|
418 | 426 | __u16 auxmode; |
---|
419 | | - read_mii_word(pegasus, 3, 0x1b, &auxmode); |
---|
| 427 | + ret = read_mii_word(pegasus, 3, 0x1b, &auxmode); |
---|
| 428 | + if (ret < 0) |
---|
| 429 | + goto fail; |
---|
420 | 430 | auxmode |= 4; |
---|
421 | 431 | write_mii_word(pegasus, 3, 0x1b, &auxmode); |
---|
422 | 432 | } |
---|
423 | 433 | |
---|
424 | 434 | return 0; |
---|
| 435 | +fail: |
---|
| 436 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
| 437 | + return ret; |
---|
425 | 438 | } |
---|
426 | 439 | |
---|
427 | 440 | static int enable_net_traffic(struct net_device *dev, struct usb_device *usb) |
---|
428 | 441 | { |
---|
429 | | - __u16 linkpart; |
---|
430 | | - __u8 data[4]; |
---|
431 | 442 | pegasus_t *pegasus = netdev_priv(dev); |
---|
432 | 443 | int ret; |
---|
| 444 | + __u16 linkpart; |
---|
| 445 | + __u8 data[4]; |
---|
433 | 446 | |
---|
434 | | - read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); |
---|
| 447 | + ret = read_mii_word(pegasus, pegasus->phy, MII_LPA, &linkpart); |
---|
| 448 | + if (ret < 0) |
---|
| 449 | + goto fail; |
---|
435 | 450 | data[0] = 0xc8; /* TX & RX enable, append status, no CRC */ |
---|
436 | 451 | data[1] = 0; |
---|
437 | 452 | if (linkpart & (ADVERTISE_100FULL | ADVERTISE_10FULL)) |
---|
.. | .. |
---|
449 | 464 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 || |
---|
450 | 465 | usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) { |
---|
451 | 466 | u16 auxmode; |
---|
452 | | - read_mii_word(pegasus, 0, 0x1b, &auxmode); |
---|
| 467 | + ret = read_mii_word(pegasus, 0, 0x1b, &auxmode); |
---|
| 468 | + if (ret < 0) |
---|
| 469 | + goto fail; |
---|
453 | 470 | auxmode |= 4; |
---|
454 | 471 | write_mii_word(pegasus, 0, 0x1b, &auxmode); |
---|
455 | 472 | } |
---|
456 | 473 | |
---|
| 474 | + return ret; |
---|
| 475 | +fail: |
---|
| 476 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
457 | 477 | return ret; |
---|
458 | 478 | } |
---|
459 | 479 | |
---|
.. | .. |
---|
461 | 481 | { |
---|
462 | 482 | pegasus_t *pegasus = urb->context; |
---|
463 | 483 | struct net_device *net; |
---|
| 484 | + u8 *buf = urb->transfer_buffer; |
---|
464 | 485 | int rx_status, count = urb->actual_length; |
---|
465 | 486 | int status = urb->status; |
---|
466 | | - u8 *buf = urb->transfer_buffer; |
---|
467 | 487 | __u16 pkt_len; |
---|
468 | 488 | |
---|
469 | 489 | if (!pegasus) |
---|
.. | .. |
---|
631 | 651 | return; |
---|
632 | 652 | default: |
---|
633 | 653 | netif_info(pegasus, tx_err, net, "TX status %d\n", status); |
---|
634 | | - /* FALL THROUGH */ |
---|
| 654 | + fallthrough; |
---|
635 | 655 | case 0: |
---|
636 | 656 | break; |
---|
637 | 657 | } |
---|
.. | .. |
---|
696 | 716 | "can't resubmit interrupt urb, %d\n", res); |
---|
697 | 717 | } |
---|
698 | 718 | |
---|
699 | | -static void pegasus_tx_timeout(struct net_device *net) |
---|
| 719 | +static void pegasus_tx_timeout(struct net_device *net, unsigned int txqueue) |
---|
700 | 720 | { |
---|
701 | 721 | pegasus_t *pegasus = netdev_priv(net); |
---|
702 | 722 | netif_warn(pegasus, timer, net, "tx timeout\n"); |
---|
.. | .. |
---|
841 | 861 | if (!pegasus->rx_skb) |
---|
842 | 862 | goto exit; |
---|
843 | 863 | |
---|
844 | | - res = set_registers(pegasus, EthID, 6, net->dev_addr); |
---|
| 864 | + set_registers(pegasus, EthID, 6, net->dev_addr); |
---|
845 | 865 | |
---|
846 | 866 | usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, |
---|
847 | 867 | usb_rcvbulkpipe(pegasus->usb, 1), |
---|
.. | .. |
---|
1017 | 1037 | switch (cmd) { |
---|
1018 | 1038 | case SIOCDEVPRIVATE: |
---|
1019 | 1039 | data[0] = pegasus->phy; |
---|
| 1040 | + fallthrough; |
---|
1020 | 1041 | case SIOCDEVPRIVATE + 1: |
---|
1021 | | - read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]); |
---|
1022 | | - res = 0; |
---|
| 1042 | + res = read_mii_word(pegasus, data[0], data[1] & 0x1f, &data[3]); |
---|
1023 | 1043 | break; |
---|
1024 | 1044 | case SIOCDEVPRIVATE + 2: |
---|
1025 | 1045 | if (!capable(CAP_NET_ADMIN)) |
---|
.. | .. |
---|
1053 | 1073 | |
---|
1054 | 1074 | static __u8 mii_phy_probe(pegasus_t *pegasus) |
---|
1055 | 1075 | { |
---|
1056 | | - int i; |
---|
| 1076 | + int i, ret; |
---|
1057 | 1077 | __u16 tmp; |
---|
1058 | 1078 | |
---|
1059 | 1079 | for (i = 0; i < 32; i++) { |
---|
1060 | | - read_mii_word(pegasus, i, MII_BMSR, &tmp); |
---|
| 1080 | + ret = read_mii_word(pegasus, i, MII_BMSR, &tmp); |
---|
| 1081 | + if (ret < 0) |
---|
| 1082 | + goto fail; |
---|
1061 | 1083 | if (tmp == 0 || tmp == 0xffff || (tmp & BMSR_MEDIA) == 0) |
---|
1062 | 1084 | continue; |
---|
1063 | 1085 | else |
---|
1064 | 1086 | return i; |
---|
1065 | 1087 | } |
---|
1066 | | - |
---|
| 1088 | +fail: |
---|
1067 | 1089 | return 0xff; |
---|
1068 | 1090 | } |
---|
1069 | 1091 | |
---|
1070 | 1092 | static inline void setup_pegasus_II(pegasus_t *pegasus) |
---|
1071 | 1093 | { |
---|
| 1094 | + int ret; |
---|
1072 | 1095 | __u8 data = 0xa5; |
---|
1073 | 1096 | |
---|
1074 | 1097 | set_register(pegasus, Reg1d, 0); |
---|
.. | .. |
---|
1080 | 1103 | set_register(pegasus, Reg7b, 2); |
---|
1081 | 1104 | |
---|
1082 | 1105 | set_register(pegasus, 0x83, data); |
---|
1083 | | - get_registers(pegasus, 0x83, 1, &data); |
---|
| 1106 | + ret = get_registers(pegasus, 0x83, 1, &data); |
---|
| 1107 | + if (ret < 0) |
---|
| 1108 | + goto fail; |
---|
1084 | 1109 | |
---|
1085 | 1110 | if (data == 0xa5) |
---|
1086 | 1111 | pegasus->chip = 0x8513; |
---|
.. | .. |
---|
1095 | 1120 | set_register(pegasus, Reg81, 6); |
---|
1096 | 1121 | else |
---|
1097 | 1122 | set_register(pegasus, Reg81, 2); |
---|
| 1123 | + |
---|
| 1124 | + return; |
---|
| 1125 | +fail: |
---|
| 1126 | + netif_dbg(pegasus, drv, pegasus->net, "%s failed\n", __func__); |
---|
1098 | 1127 | } |
---|
1099 | | - |
---|
1100 | | - |
---|
1101 | | -static int pegasus_count; |
---|
1102 | | -static struct workqueue_struct *pegasus_workqueue; |
---|
1103 | | -#define CARRIER_CHECK_DELAY (2 * HZ) |
---|
1104 | 1128 | |
---|
1105 | 1129 | static void check_carrier(struct work_struct *work) |
---|
1106 | 1130 | { |
---|
1107 | 1131 | pegasus_t *pegasus = container_of(work, pegasus_t, carrier_check.work); |
---|
1108 | 1132 | set_carrier(pegasus->net); |
---|
1109 | 1133 | if (!(pegasus->flags & PEGASUS_UNPLUG)) { |
---|
1110 | | - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, |
---|
| 1134 | + queue_delayed_work(system_long_wq, &pegasus->carrier_check, |
---|
1111 | 1135 | CARRIER_CHECK_DELAY); |
---|
1112 | 1136 | } |
---|
1113 | 1137 | } |
---|
.. | .. |
---|
1128 | 1152 | return 0; |
---|
1129 | 1153 | } |
---|
1130 | 1154 | |
---|
1131 | | -/* we rely on probe() and remove() being serialized so we |
---|
1132 | | - * don't need extra locking on pegasus_count. |
---|
1133 | | - */ |
---|
1134 | | -static void pegasus_dec_workqueue(void) |
---|
1135 | | -{ |
---|
1136 | | - pegasus_count--; |
---|
1137 | | - if (pegasus_count == 0) { |
---|
1138 | | - destroy_workqueue(pegasus_workqueue); |
---|
1139 | | - pegasus_workqueue = NULL; |
---|
1140 | | - } |
---|
1141 | | -} |
---|
1142 | | - |
---|
1143 | 1155 | static int pegasus_probe(struct usb_interface *intf, |
---|
1144 | 1156 | const struct usb_device_id *id) |
---|
1145 | 1157 | { |
---|
.. | .. |
---|
1151 | 1163 | |
---|
1152 | 1164 | if (pegasus_blacklisted(dev)) |
---|
1153 | 1165 | return -ENODEV; |
---|
1154 | | - |
---|
1155 | | - if (pegasus_count == 0) { |
---|
1156 | | - pegasus_workqueue = alloc_workqueue("pegasus", WQ_MEM_RECLAIM, |
---|
1157 | | - 0); |
---|
1158 | | - if (!pegasus_workqueue) |
---|
1159 | | - return -ENOMEM; |
---|
1160 | | - } |
---|
1161 | | - pegasus_count++; |
---|
1162 | 1166 | |
---|
1163 | 1167 | net = alloc_etherdev(sizeof(struct pegasus)); |
---|
1164 | 1168 | if (!net) |
---|
.. | .. |
---|
1219 | 1223 | res = register_netdev(net); |
---|
1220 | 1224 | if (res) |
---|
1221 | 1225 | goto out3; |
---|
1222 | | - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, |
---|
| 1226 | + queue_delayed_work(system_long_wq, &pegasus->carrier_check, |
---|
1223 | 1227 | CARRIER_CHECK_DELAY); |
---|
1224 | 1228 | dev_info(&intf->dev, "%s, %s, %pM\n", net->name, |
---|
1225 | 1229 | usb_dev_id[dev_index].name, net->dev_addr); |
---|
.. | .. |
---|
1232 | 1236 | out1: |
---|
1233 | 1237 | free_netdev(net); |
---|
1234 | 1238 | out: |
---|
1235 | | - pegasus_dec_workqueue(); |
---|
1236 | 1239 | return res; |
---|
1237 | 1240 | } |
---|
1238 | 1241 | |
---|
.. | .. |
---|
1247 | 1250 | } |
---|
1248 | 1251 | |
---|
1249 | 1252 | pegasus->flags |= PEGASUS_UNPLUG; |
---|
1250 | | - cancel_delayed_work(&pegasus->carrier_check); |
---|
| 1253 | + cancel_delayed_work_sync(&pegasus->carrier_check); |
---|
1251 | 1254 | unregister_netdev(pegasus->net); |
---|
1252 | 1255 | unlink_all_urbs(pegasus); |
---|
1253 | 1256 | free_all_urbs(pegasus); |
---|
.. | .. |
---|
1256 | 1259 | pegasus->rx_skb = NULL; |
---|
1257 | 1260 | } |
---|
1258 | 1261 | free_netdev(pegasus->net); |
---|
1259 | | - pegasus_dec_workqueue(); |
---|
1260 | 1262 | } |
---|
1261 | 1263 | |
---|
1262 | 1264 | static int pegasus_suspend(struct usb_interface *intf, pm_message_t message) |
---|
.. | .. |
---|
1264 | 1266 | struct pegasus *pegasus = usb_get_intfdata(intf); |
---|
1265 | 1267 | |
---|
1266 | 1268 | netif_device_detach(pegasus->net); |
---|
1267 | | - cancel_delayed_work(&pegasus->carrier_check); |
---|
| 1269 | + cancel_delayed_work_sync(&pegasus->carrier_check); |
---|
1268 | 1270 | if (netif_running(pegasus->net)) { |
---|
1269 | 1271 | usb_kill_urb(pegasus->rx_urb); |
---|
1270 | 1272 | usb_kill_urb(pegasus->intr_urb); |
---|
.. | .. |
---|
1286 | 1288 | pegasus->intr_urb->actual_length = 0; |
---|
1287 | 1289 | intr_callback(pegasus->intr_urb); |
---|
1288 | 1290 | } |
---|
1289 | | - queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, |
---|
| 1291 | + queue_delayed_work(system_long_wq, &pegasus->carrier_check, |
---|
1290 | 1292 | CARRIER_CHECK_DELAY); |
---|
1291 | 1293 | return 0; |
---|
1292 | 1294 | } |
---|