~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/staging/rt2860/usb_main_dev.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *************************************************************************
 
3
 * Ralink Tech Inc.
 
4
 * 5F., No.36, Taiyuan St., Jhubei City,
 
5
 * Hsinchu County 302,
 
6
 * Taiwan, R.O.C.
 
7
 *
 
8
 * (c) Copyright 2002-2007, Ralink Technology, Inc.
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify  *
 
11
 * it under the terms of the GNU General Public License as published by  *
 
12
 * the Free Software Foundation; either version 2 of the License, or     *
 
13
 * (at your option) any later version.                                   *
 
14
 *                                                                       *
 
15
 * This program is distributed in the hope that it will be useful,       *
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
18
 * GNU General Public License for more details.                          *
 
19
 *                                                                       *
 
20
 * You should have received a copy of the GNU General Public License     *
 
21
 * along with this program; if not, write to the                         *
 
22
 * Free Software Foundation, Inc.,                                       *
 
23
 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
24
 *                                                                       *
 
25
 *************************************************************************/
 
26
 
 
27
#include "rt_config.h"
 
28
 
 
29
/* Following information will be show when you run 'modinfo' */
 
30
/* If you have a solution for the bug in current version of driver, please e-mail me. */
 
31
/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */
 
32
MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
 
33
MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
 
34
MODULE_LICENSE("GPL");
 
35
#ifdef MODULE_VERSION
 
36
MODULE_VERSION(STA_DRIVER_VERSION);
 
37
#endif
 
38
 
 
39
/* module table */
 
40
struct usb_device_id rtusb_usb_id[] = {
 
41
#ifdef RT2870
 
42
        {USB_DEVICE(0x148F, 0x2770)},   /* Ralink */
 
43
        {USB_DEVICE(0x148F, 0x2870)},   /* Ralink */
 
44
        {USB_DEVICE(0x07B8, 0x2870)},   /* AboCom */
 
45
        {USB_DEVICE(0x07B8, 0x2770)},   /* AboCom */
 
46
        {USB_DEVICE(0x0DF6, 0x0039)},   /* Sitecom 2770 */
 
47
        {USB_DEVICE(0x0DF6, 0x003F)},   /* Sitecom 2770 */
 
48
        {USB_DEVICE(0x083A, 0x7512)},   /* Arcadyan 2770 */
 
49
        {USB_DEVICE(0x0789, 0x0162)},   /* Logitec 2870 */
 
50
        {USB_DEVICE(0x0789, 0x0163)},   /* Logitec 2870 */
 
51
        {USB_DEVICE(0x0789, 0x0164)},   /* Logitec 2870 */
 
52
        {USB_DEVICE(0x177f, 0x0302)},   /* lsusb */
 
53
        {USB_DEVICE(0x0B05, 0x1731)},   /* Asus */
 
54
        {USB_DEVICE(0x0B05, 0x1732)},   /* Asus */
 
55
        {USB_DEVICE(0x0B05, 0x1742)},   /* Asus */
 
56
        {USB_DEVICE(0x0DF6, 0x0017)},   /* Sitecom */
 
57
        {USB_DEVICE(0x0DF6, 0x002B)},   /* Sitecom */
 
58
        {USB_DEVICE(0x0DF6, 0x002C)},   /* Sitecom */
 
59
        {USB_DEVICE(0x0DF6, 0x002D)},   /* Sitecom */
 
60
        {USB_DEVICE(0x14B2, 0x3C06)},   /* Conceptronic */
 
61
        {USB_DEVICE(0x14B2, 0x3C28)},   /* Conceptronic */
 
62
        {USB_DEVICE(0x2019, 0xED06)},   /* Planex Communications, Inc. */
 
63
        {USB_DEVICE(0x07D1, 0x3C09)},   /* D-Link */
 
64
        {USB_DEVICE(0x07D1, 0x3C11)},   /* D-Link */
 
65
        {USB_DEVICE(0x14B2, 0x3C07)},   /* AL */
 
66
        {USB_DEVICE(0x050D, 0x8053)},   /* Belkin */
 
67
        {USB_DEVICE(0x050D, 0x825B)},   /* Belkin */
 
68
        {USB_DEVICE(0x050D, 0x935A)},   /* Belkin F6D4050 v1 */
 
69
        {USB_DEVICE(0x050D, 0x935B)},   /* Belkin F6D4050 v2 */
 
70
        {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
 
71
        {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
 
72
        {USB_DEVICE(0x07AA, 0x002F)},   /* Corega */
 
73
        {USB_DEVICE(0x07AA, 0x003C)},   /* Corega */
 
74
        {USB_DEVICE(0x07AA, 0x003F)},   /* Corega */
 
75
        {USB_DEVICE(0x1044, 0x800B)},   /* Gigabyte */
 
76
        {USB_DEVICE(0x15A9, 0x0006)},   /* Sparklan */
 
77
        {USB_DEVICE(0x083A, 0xB522)},   /* SMC */
 
78
        {USB_DEVICE(0x083A, 0xA618)},   /* SMC */
 
79
        {USB_DEVICE(0x083A, 0x8522)},   /* Arcadyan */
 
80
        {USB_DEVICE(0x083A, 0x7522)},   /* Arcadyan */
 
81
        {USB_DEVICE(0x0CDE, 0x0022)},   /* ZCOM */
 
82
        {USB_DEVICE(0x0586, 0x3416)},   /* Zyxel */
 
83
        {USB_DEVICE(0x0586, 0x341a)},   /* Zyxel NWD-270N */
 
84
        {USB_DEVICE(0x0CDE, 0x0025)},   /* Zyxel */
 
85
        {USB_DEVICE(0x1740, 0x9701)},   /* EnGenius */
 
86
        {USB_DEVICE(0x1740, 0x9702)},   /* EnGenius */
 
87
        {USB_DEVICE(0x0471, 0x200f)},   /* Philips */
 
88
        {USB_DEVICE(0x14B2, 0x3C25)},   /* Draytek */
 
89
        {USB_DEVICE(0x13D3, 0x3247)},   /* AzureWave */
 
90
        {USB_DEVICE(0x083A, 0x6618)},   /* Accton */
 
91
        {USB_DEVICE(0x15c5, 0x0008)},   /* Amit */
 
92
        {USB_DEVICE(0x0E66, 0x0001)},   /* Hawking */
 
93
        {USB_DEVICE(0x0E66, 0x0003)},   /* Hawking */
 
94
        {USB_DEVICE(0x129B, 0x1828)},   /* Siemens */
 
95
        {USB_DEVICE(0x157E, 0x300E)},   /* U-Media */
 
96
        {USB_DEVICE(0x050d, 0x805c)},
 
97
        {USB_DEVICE(0x050d, 0x815c)},
 
98
        {USB_DEVICE(0x1482, 0x3C09)},   /* Abocom */
 
99
        {USB_DEVICE(0x14B2, 0x3C09)},   /* Alpha */
 
100
        {USB_DEVICE(0x04E8, 0x2018)},   /* samsung linkstick2 */
 
101
        {USB_DEVICE(0x1690, 0x0740)},   /* Askey */
 
102
        {USB_DEVICE(0x5A57, 0x0280)},   /* Zinwell */
 
103
        {USB_DEVICE(0x5A57, 0x0282)},   /* Zinwell */
 
104
        {USB_DEVICE(0x7392, 0x7718)},
 
105
        {USB_DEVICE(0x7392, 0x7717)},
 
106
        {USB_DEVICE(0x0411, 0x016f)},   /* MelCo.,Inc. WLI-UC-G301N */
 
107
        {USB_DEVICE(0x1737, 0x0070)},   /* Linksys WUSB100 */
 
108
        {USB_DEVICE(0x1737, 0x0071)},   /* Linksys WUSB600N */
 
109
        {USB_DEVICE(0x1737, 0x0078)},   /* Linksys WUSB100v2 */
 
110
        {USB_DEVICE(0x0411, 0x00e8)},   /* Buffalo WLI-UC-G300N */
 
111
        {USB_DEVICE(0x050d, 0x815c)},   /* Belkin F5D8053 */
 
112
        {USB_DEVICE(0x100D, 0x9031)},   /* Motorola 2770 */
 
113
#endif /* RT2870 // */
 
114
#ifdef RT3070
 
115
        {USB_DEVICE(0x148F, 0x3070)},   /* Ralink 3070 */
 
116
        {USB_DEVICE(0x148F, 0x3071)},   /* Ralink 3071 */
 
117
        {USB_DEVICE(0x148F, 0x3072)},   /* Ralink 3072 */
 
118
        {USB_DEVICE(0x0DB0, 0x3820)},   /* Ralink 3070 */
 
119
        {USB_DEVICE(0x0DB0, 0x871C)},   /* Ralink 3070 */
 
120
        {USB_DEVICE(0x0DB0, 0x822C)},   /* Ralink 3070 */
 
121
        {USB_DEVICE(0x0DB0, 0x871B)},   /* Ralink 3070 */
 
122
        {USB_DEVICE(0x0DB0, 0x822B)},   /* Ralink 3070 */
 
123
        {USB_DEVICE(0x0DF6, 0x003E)},   /* Sitecom 3070 */
 
124
        {USB_DEVICE(0x0DF6, 0x0042)},   /* Sitecom 3072 */
 
125
        {USB_DEVICE(0x0DF6, 0x0048)},   /* Sitecom 3070 */
 
126
        {USB_DEVICE(0x0DF6, 0x0047)},   /* Sitecom 3071 */
 
127
        {USB_DEVICE(0x14B2, 0x3C12)},   /* AL 3070 */
 
128
        {USB_DEVICE(0x18C5, 0x0012)},   /* Corega 3070 */
 
129
        {USB_DEVICE(0x083A, 0x7511)},   /* Arcadyan 3070 */
 
130
        {USB_DEVICE(0x083A, 0xA701)},   /* SMC 3070 */
 
131
        {USB_DEVICE(0x083A, 0xA702)},   /* SMC 3072 */
 
132
        {USB_DEVICE(0x1740, 0x9703)},   /* EnGenius 3070 */
 
133
        {USB_DEVICE(0x1740, 0x9705)},   /* EnGenius 3071 */
 
134
        {USB_DEVICE(0x1740, 0x9706)},   /* EnGenius 3072 */
 
135
        {USB_DEVICE(0x1740, 0x9707)},   /* EnGenius 3070 */
 
136
        {USB_DEVICE(0x1740, 0x9708)},   /* EnGenius 3071 */
 
137
        {USB_DEVICE(0x1740, 0x9709)},   /* EnGenius 3072 */
 
138
        {USB_DEVICE(0x13D3, 0x3273)},   /* AzureWave 3070 */
 
139
        {USB_DEVICE(0x13D3, 0x3305)},   /* AzureWave 3070*/
 
140
        {USB_DEVICE(0x1044, 0x800D)},   /* Gigabyte GN-WB32L 3070 */
 
141
        {USB_DEVICE(0x2019, 0xAB25)},   /* Planex Communications, Inc. RT3070 */
 
142
        {USB_DEVICE(0x07B8, 0x3070)},   /* AboCom 3070 */
 
143
        {USB_DEVICE(0x07B8, 0x3071)},   /* AboCom 3071 */
 
144
        {USB_DEVICE(0x07B8, 0x3072)},   /* Abocom 3072 */
 
145
        {USB_DEVICE(0x7392, 0x7711)},   /* Edimax 3070 */
 
146
        {USB_DEVICE(0x1A32, 0x0304)},   /* Quanta 3070 */
 
147
        {USB_DEVICE(0x1EDA, 0x2310)},   /* AirTies 3070 */
 
148
        {USB_DEVICE(0x07D1, 0x3C0A)},   /* D-Link 3072 */
 
149
        {USB_DEVICE(0x07D1, 0x3C0D)},   /* D-Link 3070 */
 
150
        {USB_DEVICE(0x07D1, 0x3C0E)},   /* D-Link 3070 */
 
151
        {USB_DEVICE(0x07D1, 0x3C0F)},   /* D-Link 3070 */
 
152
        {USB_DEVICE(0x07D1, 0x3C16)},   /* D-Link 3070 */
 
153
        {USB_DEVICE(0x07D1, 0x3C17)},   /* D-Link 8070 */
 
154
        {USB_DEVICE(0x1D4D, 0x000C)},   /* Pegatron Corporation 3070 */
 
155
        {USB_DEVICE(0x1D4D, 0x000E)},   /* Pegatron Corporation 3070 */
 
156
        {USB_DEVICE(0x5A57, 0x5257)},   /* Zinwell 3070 */
 
157
        {USB_DEVICE(0x5A57, 0x0283)},   /* Zinwell 3072 */
 
158
        {USB_DEVICE(0x04BB, 0x0945)},   /* I-O DATA 3072 */
 
159
        {USB_DEVICE(0x04BB, 0x0947)},   /* I-O DATA 3070 */
 
160
        {USB_DEVICE(0x04BB, 0x0948)},   /* I-O DATA 3072 */
 
161
        {USB_DEVICE(0x203D, 0x1480)},   /* Encore 3070 */
 
162
        {USB_DEVICE(0x20B8, 0x8888)},   /* PARA INDUSTRIAL 3070 */
 
163
        {USB_DEVICE(0x0B05, 0x1784)},   /* Asus 3072 */
 
164
        {USB_DEVICE(0x203D, 0x14A9)},   /* Encore 3070*/
 
165
        {USB_DEVICE(0x0DB0, 0x899A)},   /* MSI 3070*/
 
166
        {USB_DEVICE(0x0DB0, 0x3870)},   /* MSI 3070*/
 
167
        {USB_DEVICE(0x0DB0, 0x870A)},   /* MSI 3070*/
 
168
        {USB_DEVICE(0x0DB0, 0x6899)},   /* MSI 3070 */
 
169
        {USB_DEVICE(0x0DB0, 0x3822)},   /* MSI 3070 */
 
170
        {USB_DEVICE(0x0DB0, 0x3871)},   /* MSI 3070 */
 
171
        {USB_DEVICE(0x0DB0, 0x871A)},   /* MSI 3070 */
 
172
        {USB_DEVICE(0x0DB0, 0x822A)},   /* MSI 3070 */
 
173
        {USB_DEVICE(0x0DB0, 0x3821)},   /* Ralink 3070 */
 
174
        {USB_DEVICE(0x0DB0, 0x821A)},   /* Ralink 3070 */
 
175
        {USB_DEVICE(0x083A, 0xA703)},   /* IO-MAGIC */
 
176
        {USB_DEVICE(0x13D3, 0x3307)},   /* Azurewave */
 
177
        {USB_DEVICE(0x13D3, 0x3321)},   /* Azurewave */
 
178
        {USB_DEVICE(0x07FA, 0x7712)},   /* Edimax */
 
179
        {USB_DEVICE(0x0789, 0x0166)},   /* Edimax */
 
180
        {USB_DEVICE(0x148F, 0x2070)},   /* Edimax */
 
181
#endif /* RT3070 // */
 
182
        {USB_DEVICE(0x1737, 0x0077)},   /* Linksys WUSB54GC-EU v3 */
 
183
        {USB_DEVICE(0x2001, 0x3C09)},   /* D-Link */
 
184
        {USB_DEVICE(0x2001, 0x3C0A)},   /* D-Link 3072 */
 
185
        {USB_DEVICE(0x2019, 0xED14)},   /* Planex Communications, Inc. */
 
186
        {USB_DEVICE(0x0411, 0x015D)},   /* Buffalo Airstation WLI-UC-GN */
 
187
        {}                      /* Terminating entry */
 
188
};
 
189
 
 
190
int const rtusb_usb_id_len =
 
191
    sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
 
192
 
 
193
MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
 
194
 
 
195
static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd);
 
196
 
 
197
static int __devinit rt2870_probe(IN struct usb_interface *intf,
 
198
                                  IN struct usb_device *usb_dev,
 
199
                                  IN const struct usb_device_id *dev_id,
 
200
                                  struct rt_rtmp_adapter **ppAd);
 
201
 
 
202
#ifndef PF_NOFREEZE
 
203
#define PF_NOFREEZE  0
 
204
#endif
 
205
 
 
206
extern int rt28xx_close(IN struct net_device *net_dev);
 
207
extern int rt28xx_open(struct net_device *net_dev);
 
208
 
 
209
static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
 
210
                                IN struct usb_interface *intf,
 
211
                                struct rt_rtmp_adapter *pAd);
 
212
 
 
213
/*
 
214
========================================================================
 
215
Routine Description:
 
216
    Check the chipset vendor/product ID.
 
217
 
 
218
Arguments:
 
219
    _dev_p                              Point to the PCI or USB device
 
220
 
 
221
Return Value:
 
222
    TRUE                                Check ok
 
223
        FALSE                           Check fail
 
224
 
 
225
Note:
 
226
========================================================================
 
227
*/
 
228
BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
 
229
{
 
230
        struct usb_interface *intf = (struct usb_interface *)_dev_p;
 
231
        struct usb_device *dev_p = interface_to_usbdev(intf);
 
232
        u32 i;
 
233
 
 
234
        for (i = 0; i < rtusb_usb_id_len; i++) {
 
235
                if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
 
236
                    dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) {
 
237
                        printk(KERN_INFO "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
 
238
                               dev_p->descriptor.idVendor,
 
239
                               dev_p->descriptor.idProduct);
 
240
                        break;
 
241
                }
 
242
        }
 
243
 
 
244
        if (i == rtusb_usb_id_len) {
 
245
                printk(KERN_ERR "rt2870: Error! Device Descriptor not matching!\n");
 
246
                return FALSE;
 
247
        }
 
248
 
 
249
        return TRUE;
 
250
}
 
251
 
 
252
/**************************************************************************/
 
253
/**************************************************************************/
 
254
/*tested for kernel 2.6series */
 
255
/**************************************************************************/
 
256
/**************************************************************************/
 
257
 
 
258
#ifdef CONFIG_PM
 
259
static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
 
260
static int rt2870_resume(struct usb_interface *intf);
 
261
#endif /* CONFIG_PM // */
 
262
 
 
263
static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
 
264
                                IN struct usb_interface *intf,
 
265
                                struct rt_rtmp_adapter *pAd)
 
266
{
 
267
        struct usb_host_interface *iface_desc;
 
268
        unsigned long BulkOutIdx;
 
269
        u32 i;
 
270
 
 
271
        /* get the active interface descriptor */
 
272
        iface_desc = intf->cur_altsetting;
 
273
 
 
274
        /* get # of enpoints  */
 
275
        pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
 
276
        DBGPRINT(RT_DEBUG_TRACE,
 
277
                 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
 
278
 
 
279
        /* Configure Pipes */
 
280
        BulkOutIdx = 0;
 
281
 
 
282
        for (i = 0; i < pAd->NumberOfPipes; i++) {
 
283
                if ((iface_desc->endpoint[i].desc.bmAttributes ==
 
284
                     USB_ENDPOINT_XFER_BULK) &&
 
285
                    ((iface_desc->endpoint[i].desc.bEndpointAddress &
 
286
                      USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) {
 
287
                        pAd->BulkInEpAddr =
 
288
                            iface_desc->endpoint[i].desc.bEndpointAddress;
 
289
                        pAd->BulkInMaxPacketSize =
 
290
                            le2cpu16(iface_desc->endpoint[i].desc.
 
291
                                     wMaxPacketSize);
 
292
 
 
293
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
 
294
                                     ("BULK IN MaxPacketSize = %d\n",
 
295
                                      pAd->BulkInMaxPacketSize));
 
296
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
 
297
                                     ("EP address = 0x%2x\n",
 
298
                                      iface_desc->endpoint[i].desc.
 
299
                                      bEndpointAddress));
 
300
                } else
 
301
                    if ((iface_desc->endpoint[i].desc.bmAttributes ==
 
302
                         USB_ENDPOINT_XFER_BULK)
 
303
                        &&
 
304
                        ((iface_desc->endpoint[i].desc.
 
305
                          bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
 
306
                         USB_DIR_OUT)) {
 
307
                        /* there are 6 bulk out EP. EP6 highest priority. */
 
308
                        /* EP1-4 is EDCA.  EP5 is HCCA. */
 
309
                        pAd->BulkOutEpAddr[BulkOutIdx++] =
 
310
                            iface_desc->endpoint[i].desc.bEndpointAddress;
 
311
                        pAd->BulkOutMaxPacketSize =
 
312
                            le2cpu16(iface_desc->endpoint[i].desc.
 
313
                                     wMaxPacketSize);
 
314
 
 
315
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
 
316
                                     ("BULK OUT MaxPacketSize = %d\n",
 
317
                                      pAd->BulkOutMaxPacketSize));
 
318
                        DBGPRINT_RAW(RT_DEBUG_TRACE,
 
319
                                     ("EP address = 0x%2x  \n",
 
320
                                      iface_desc->endpoint[i].desc.
 
321
                                      bEndpointAddress));
 
322
                }
 
323
        }
 
324
 
 
325
        if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) {
 
326
                printk
 
327
                    (KERN_ERR "%s: Could not find both bulk-in and bulk-out endpoints\n",
 
328
                     __FUNCTION__);
 
329
                return FALSE;
 
330
        }
 
331
 
 
332
        pAd->config = &dev->config->desc;
 
333
        usb_set_intfdata(intf, pAd);
 
334
 
 
335
        return TRUE;
 
336
 
 
337
}
 
338
 
 
339
static int __devinit rtusb_probe(struct usb_interface *intf,
 
340
                       const struct usb_device_id *id)
 
341
{
 
342
        struct rt_rtmp_adapter *pAd;
 
343
        struct usb_device *dev;
 
344
        int rv;
 
345
 
 
346
        dev = interface_to_usbdev(intf);
 
347
        dev = usb_get_dev(dev);
 
348
 
 
349
        rv = rt2870_probe(intf, dev, id, &pAd);
 
350
        if (rv != 0)
 
351
                usb_put_dev(dev);
 
352
 
 
353
        return rv;
 
354
}
 
355
 
 
356
static void rtusb_disconnect(struct usb_interface *intf)
 
357
{
 
358
        struct usb_device *dev = interface_to_usbdev(intf);
 
359
        struct rt_rtmp_adapter *pAd;
 
360
 
 
361
        pAd = usb_get_intfdata(intf);
 
362
        usb_set_intfdata(intf, NULL);
 
363
 
 
364
        rt2870_disconnect(dev, pAd);
 
365
}
 
366
 
 
367
struct usb_driver rtusb_driver = {
 
368
        .name = "rt2870",
 
369
        .probe = rtusb_probe,
 
370
        .disconnect = rtusb_disconnect,
 
371
        .id_table = rtusb_usb_id,
 
372
 
 
373
#ifdef CONFIG_PM
 
374
suspend:rt2870_suspend,
 
375
resume:rt2870_resume,
 
376
#endif
 
377
};
 
378
 
 
379
#ifdef CONFIG_PM
 
380
 
 
381
void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd)
 
382
{
 
383
        /* clear PS packets */
 
384
        /* clear TxSw packets */
 
385
}
 
386
 
 
387
static int rt2870_suspend(struct usb_interface *intf, pm_message_t state)
 
388
{
 
389
        struct net_device *net_dev;
 
390
        struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
 
391
 
 
392
        DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
 
393
        net_dev = pAd->net_dev;
 
394
        netif_device_detach(net_dev);
 
395
 
 
396
        pAd->PM_FlgSuspend = 1;
 
397
        if (netif_running(net_dev)) {
 
398
                RTUSBCancelPendingBulkInIRP(pAd);
 
399
                RTUSBCancelPendingBulkOutIRP(pAd);
 
400
        }
 
401
        DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
 
402
        return 0;
 
403
}
 
404
 
 
405
static int rt2870_resume(struct usb_interface *intf)
 
406
{
 
407
        struct net_device *net_dev;
 
408
        struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
 
409
 
 
410
        DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
 
411
 
 
412
        pAd->PM_FlgSuspend = 0;
 
413
        net_dev = pAd->net_dev;
 
414
        netif_device_attach(net_dev);
 
415
        netif_start_queue(net_dev);
 
416
        netif_carrier_on(net_dev);
 
417
        netif_wake_queue(net_dev);
 
418
 
 
419
        DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
 
420
        return 0;
 
421
}
 
422
#endif /* CONFIG_PM // */
 
423
 
 
424
/* Init driver module */
 
425
int __init rtusb_init(void)
 
426
{
 
427
        printk(KERN_DEBUG "rtusb init --->\n");
 
428
        return usb_register(&rtusb_driver);
 
429
}
 
430
 
 
431
/* Deinit driver module */
 
432
void __exit rtusb_exit(void)
 
433
{
 
434
        usb_deregister(&rtusb_driver);
 
435
        printk(KERN_DEBUG "<--- rtusb exit\n");
 
436
}
 
437
 
 
438
module_init(rtusb_init);
 
439
module_exit(rtusb_exit);
 
440
 
 
441
/*--------------------------------------------------------------------- */
 
442
/* function declarations                                                                                                */
 
443
/*--------------------------------------------------------------------- */
 
444
 
 
445
/*
 
446
========================================================================
 
447
Routine Description:
 
448
    MLME kernel thread.
 
449
 
 
450
Arguments:
 
451
        *Context                        the pAd, driver control block pointer
 
452
 
 
453
Return Value:
 
454
    0                                   close the thread
 
455
 
 
456
Note:
 
457
========================================================================
 
458
*/
 
459
int MlmeThread(IN void *Context)
 
460
{
 
461
        struct rt_rtmp_adapter *pAd;
 
462
        struct rt_rtmp_os_task *pTask;
 
463
        int status;
 
464
        status = 0;
 
465
 
 
466
        pTask = Context;
 
467
        pAd = pTask->priv;
 
468
 
 
469
        RtmpOSTaskCustomize(pTask);
 
470
 
 
471
        while (!pTask->task_killed) {
 
472
#ifdef KTHREAD_SUPPORT
 
473
                RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
 
474
#else
 
475
                RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
 
476
 
 
477
                /* unlock the device pointers */
 
478
                if (status != 0) {
 
479
                        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 
480
                        break;
 
481
                }
 
482
#endif
 
483
 
 
484
                /* lock the device pointers , need to check if required */
 
485
                /*down(&(pAd->usbdev_semaphore)); */
 
486
 
 
487
                if (!pAd->PM_FlgSuspend)
 
488
                        MlmeHandler(pAd);
 
489
        }
 
490
 
 
491
        /* notify the exit routine that we're actually exiting now
 
492
         *
 
493
         * complete()/wait_for_completion() is similar to up()/down(),
 
494
         * except that complete() is safe in the case where the structure
 
495
         * is getting deleted in a parallel mode of execution (i.e. just
 
496
         * after the down() -- that's necessary for the thread-shutdown
 
497
         * case.
 
498
         *
 
499
         * complete_and_exit() goes even further than this -- it is safe in
 
500
         * the case that the thread of the caller is going away (not just
 
501
         * the structure) -- this is necessary for the module-remove case.
 
502
         * This is important in preemption kernels, which transfer the flow
 
503
         * of execution immediately upon a complete().
 
504
         */
 
505
        DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__));
 
506
#ifndef KTHREAD_SUPPORT
 
507
        pTask->taskPID = THREAD_PID_INIT_VALUE;
 
508
        complete_and_exit(&pTask->taskComplete, 0);
 
509
#endif
 
510
        return 0;
 
511
 
 
512
}
 
513
 
 
514
/*
 
515
========================================================================
 
516
Routine Description:
 
517
    USB command kernel thread.
 
518
 
 
519
Arguments:
 
520
        *Context                        the pAd, driver control block pointer
 
521
 
 
522
Return Value:
 
523
    0                                   close the thread
 
524
 
 
525
Note:
 
526
========================================================================
 
527
*/
 
528
int RTUSBCmdThread(IN void *Context)
 
529
{
 
530
        struct rt_rtmp_adapter *pAd;
 
531
        struct rt_rtmp_os_task *pTask;
 
532
        int status;
 
533
        status = 0;
 
534
 
 
535
        pTask = Context;
 
536
        pAd = pTask->priv;
 
537
 
 
538
        RtmpOSTaskCustomize(pTask);
 
539
 
 
540
        NdisAcquireSpinLock(&pAd->CmdQLock);
 
541
        pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
 
542
        NdisReleaseSpinLock(&pAd->CmdQLock);
 
543
 
 
544
        while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) {
 
545
#ifdef KTHREAD_SUPPORT
 
546
                RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
 
547
#else
 
548
                /* lock the device pointers */
 
549
                RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
 
550
 
 
551
                if (status != 0) {
 
552
                        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
 
553
                        break;
 
554
                }
 
555
#endif
 
556
 
 
557
                if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
 
558
                        break;
 
559
 
 
560
                if (!pAd->PM_FlgSuspend)
 
561
                        CMDHandler(pAd);
 
562
        }
 
563
 
 
564
        if (pAd && !pAd->PM_FlgSuspend) {       /* Clear the CmdQElements. */
 
565
                struct rt_cmdqelmt *pCmdQElmt = NULL;
 
566
 
 
567
                NdisAcquireSpinLock(&pAd->CmdQLock);
 
568
                pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
 
569
                while (pAd->CmdQ.size) {
 
570
                        RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
 
571
                        if (pCmdQElmt) {
 
572
                                if (pCmdQElmt->CmdFromNdis == TRUE) {
 
573
                                        if (pCmdQElmt->buffer != NULL)
 
574
                                                os_free_mem(pAd,
 
575
                                                            pCmdQElmt->buffer);
 
576
                                        os_free_mem(pAd, (u8 *)pCmdQElmt);
 
577
                                } else {
 
578
                                        if ((pCmdQElmt->buffer != NULL)
 
579
                                            && (pCmdQElmt->bufferlength != 0))
 
580
                                                os_free_mem(pAd,
 
581
                                                            pCmdQElmt->buffer);
 
582
                                        os_free_mem(pAd, (u8 *)pCmdQElmt);
 
583
                                }
 
584
                        }
 
585
                }
 
586
 
 
587
                NdisReleaseSpinLock(&pAd->CmdQLock);
 
588
        }
 
589
        /* notify the exit routine that we're actually exiting now
 
590
         *
 
591
         * complete()/wait_for_completion() is similar to up()/down(),
 
592
         * except that complete() is safe in the case where the structure
 
593
         * is getting deleted in a parallel mode of execution (i.e. just
 
594
         * after the down() -- that's necessary for the thread-shutdown
 
595
         * case.
 
596
         *
 
597
         * complete_and_exit() goes even further than this -- it is safe in
 
598
         * the case that the thread of the caller is going away (not just
 
599
         * the structure) -- this is necessary for the module-remove case.
 
600
         * This is important in preemption kernels, which transfer the flow
 
601
         * of execution immediately upon a complete().
 
602
         */
 
603
        DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n"));
 
604
 
 
605
#ifndef KTHREAD_SUPPORT
 
606
        pTask->taskPID = THREAD_PID_INIT_VALUE;
 
607
        complete_and_exit(&pTask->taskComplete, 0);
 
608
#endif
 
609
        return 0;
 
610
 
 
611
}
 
612
 
 
613
void RTUSBWatchDog(struct rt_rtmp_adapter *pAd)
 
614
{
 
615
        struct rt_ht_tx_context *pHTTXContext;
 
616
        int idx;
 
617
        unsigned long irqFlags;
 
618
        PURB pUrb;
 
619
        BOOLEAN needDumpSeq = FALSE;
 
620
        u32 MACValue;
 
621
        u32 TxRxQ_Pcnt;
 
622
 
 
623
        idx = 0;
 
624
        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
 
625
        if ((MACValue & 0xff) != 0) {
 
626
                DBGPRINT(RT_DEBUG_TRACE,
 
627
                         ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n",
 
628
                          MACValue));
 
629
                RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
 
630
                while ((MACValue & 0xff) != 0 && (idx++ < 10)) {
 
631
                        RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
 
632
                        RTMPusecDelay(1);
 
633
                }
 
634
                RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
 
635
        }
 
636
 
 
637
        if (pAd->watchDogRxOverFlowCnt >= 2) {
 
638
                DBGPRINT(RT_DEBUG_TRACE,
 
639
                         ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
 
640
                if ((!RTMP_TEST_FLAG
 
641
                     (pAd,
 
642
                      (fRTMP_ADAPTER_RESET_IN_PROGRESS |
 
643
                       fRTMP_ADAPTER_BULKIN_RESET |
 
644
                       fRTMP_ADAPTER_HALT_IN_PROGRESS |
 
645
                       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
 
646
                        DBGPRINT(RT_DEBUG_TRACE,
 
647
                                 ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
 
648
                        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
 
649
                        RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
 
650
                                                NULL, 0);
 
651
                        needDumpSeq = TRUE;
 
652
                }
 
653
                pAd->watchDogRxOverFlowCnt = 0;
 
654
        }
 
655
 
 
656
        RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
 
657
 
 
658
        for (idx = 0; idx < NUM_OF_TX_RING; idx++) {
 
659
                pUrb = NULL;
 
660
 
 
661
                RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
 
662
                if ((pAd->BulkOutPending[idx] == TRUE)
 
663
                    && pAd->watchDogTxPendingCnt) {
 
664
                        int actual_length = 0, transfer_buffer_length = 0;
 
665
                        BOOLEAN isDataPacket = FALSE;
 
666
                        pAd->watchDogTxPendingCnt[idx]++;
 
667
 
 
668
                        if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
 
669
                            (!RTMP_TEST_FLAG
 
670
                             (pAd,
 
671
                              (fRTMP_ADAPTER_RESET_IN_PROGRESS |
 
672
                               fRTMP_ADAPTER_HALT_IN_PROGRESS |
 
673
                               fRTMP_ADAPTER_NIC_NOT_EXIST |
 
674
                               fRTMP_ADAPTER_BULKOUT_RESET)))
 
675
                            ) {
 
676
                                /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */
 
677
                                pHTTXContext =
 
678
                                    (struct rt_ht_tx_context *)(&pAd->TxContext[idx]);
 
679
                                if (pHTTXContext->IRPPending) { /* Check TxContext. */
 
680
                                        pUrb = pHTTXContext->pUrb;
 
681
 
 
682
                                        actual_length = pUrb->actual_length;
 
683
                                        transfer_buffer_length =
 
684
                                            pUrb->transfer_buffer_length;
 
685
                                        isDataPacket = TRUE;
 
686
                                } else if (idx == MGMTPIPEIDX) {
 
687
                                        struct rt_tx_context *pMLMEContext, *pNULLContext,
 
688
                                            *pPsPollContext;
 
689
 
 
690
                                        /*Check MgmtContext. */
 
691
                                        pMLMEContext =
 
692
                                            (struct rt_tx_context *)(pAd->MgmtRing.
 
693
                                                           Cell[pAd->MgmtRing.
 
694
                                                                TxDmaIdx].
 
695
                                                           AllocVa);
 
696
                                        pPsPollContext =
 
697
                                            (struct rt_tx_context *)(&pAd->PsPollContext);
 
698
                                        pNULLContext =
 
699
                                            (struct rt_tx_context *)(&pAd->NullContext);
 
700
 
 
701
                                        if (pMLMEContext->IRPPending) {
 
702
                                                ASSERT(pMLMEContext->
 
703
                                                       IRPPending);
 
704
                                                pUrb = pMLMEContext->pUrb;
 
705
                                        } else if (pNULLContext->IRPPending) {
 
706
                                                ASSERT(pNULLContext->
 
707
                                                       IRPPending);
 
708
                                                pUrb = pNULLContext->pUrb;
 
709
                                        } else if (pPsPollContext->IRPPending) {
 
710
                                                ASSERT(pPsPollContext->
 
711
                                                       IRPPending);
 
712
                                                pUrb = pPsPollContext->pUrb;
 
713
                                        }
 
714
                                }
 
715
 
 
716
                                RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
 
717
                                                irqFlags);
 
718
 
 
719
                                printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n",
 
720
                                       idx, pAd->watchDogTxPendingCnt[idx],
 
721
                                       pAd->TransferedLength[idx],
 
722
                                       actual_length, transfer_buffer_length);
 
723
 
 
724
                                if (pUrb) {
 
725
                                        if ((isDataPacket
 
726
                                             && pAd->TransferedLength[idx] ==
 
727
                                             actual_length
 
728
                                             && pAd->TransferedLength[idx] <
 
729
                                             transfer_buffer_length
 
730
                                             && actual_length != 0
 
731
/*                                      && TxRxQ_Pcnt==0 */
 
732
                                             && pAd->watchDogTxPendingCnt[idx] >
 
733
                                             3)
 
734
                                            || isDataPacket == FALSE
 
735
                                            || pAd->watchDogTxPendingCnt[idx] >
 
736
                                            6) {
 
737
                                                DBGPRINT(RT_DEBUG_TRACE,
 
738
                                                         ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n",
 
739
                                                          idx));
 
740
                                                DBGPRINT(RT_DEBUG_TRACE,
 
741
                                                         ("Unlink the pending URB!\n"));
 
742
                                                /* unlink it now */
 
743
                                                RTUSB_UNLINK_URB(pUrb);
 
744
                                                /* Sleep 200 microseconds to give cancellation time to work */
 
745
                                                /*RTMPusecDelay(200); */
 
746
                                                needDumpSeq = TRUE;
 
747
                                        }
 
748
                                } else {
 
749
                                        DBGPRINT(RT_DEBUG_ERROR,
 
750
                                                 ("Unknown bulkOut URB maybe hanged!\n"));
 
751
                                }
 
752
                        } else {
 
753
                                RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
 
754
                                                irqFlags);
 
755
                        }
 
756
 
 
757
                        if (isDataPacket == TRUE)
 
758
                                pAd->TransferedLength[idx] = actual_length;
 
759
                } else {
 
760
                        RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
 
761
                }
 
762
        }
 
763
 
 
764
        /* For Sigma debug, dump the ba_reordering sequence. */
 
765
        if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) {
 
766
                u16 Idx;
 
767
                struct rt_ba_rec_entry *pBAEntry = NULL;
 
768
                u8 count = 0;
 
769
                struct reordering_mpdu *mpdu_blk;
 
770
 
 
771
                Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
 
772
 
 
773
                pBAEntry = &pAd->BATable.BARecEntry[Idx];
 
774
                if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) {
 
775
                        DBGPRINT(RT_DEBUG_TRACE,
 
776
                                 ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
 
777
                        NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
 
778
                        mpdu_blk = pBAEntry->list.next;
 
779
                        while (mpdu_blk) {
 
780
                                DBGPRINT(RT_DEBUG_TRACE,
 
781
                                         ("\t%d:Seq-%d, bAMSDU-%d!\n", count,
 
782
                                          mpdu_blk->Sequence,
 
783
                                          mpdu_blk->bAMSDU));
 
784
                                mpdu_blk = mpdu_blk->next;
 
785
                                count++;
 
786
                        }
 
787
 
 
788
                        DBGPRINT(RT_DEBUG_TRACE,
 
789
                                 ("\npBAEntry->LastIndSeq=%d!\n",
 
790
                                  pBAEntry->LastIndSeq));
 
791
                        NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
 
792
                }
 
793
        }
 
794
}
 
795
 
 
796
/*
 
797
========================================================================
 
798
Routine Description:
 
799
    Release allocated resources.
 
800
 
 
801
Arguments:
 
802
    *dev                                Point to the PCI or USB device
 
803
        pAd                                     driver control block pointer
 
804
 
 
805
Return Value:
 
806
    None
 
807
 
 
808
Note:
 
809
========================================================================
 
810
*/
 
811
static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd)
 
812
{
 
813
        DBGPRINT(RT_DEBUG_ERROR,
 
814
                 ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
 
815
                  dev->bus->bus_name, dev->devpath));
 
816
        if (!pAd) {
 
817
                usb_put_dev(dev);
 
818
                printk(KERN_ERR "rtusb_disconnect: pAd == NULL!\n");
 
819
                return;
 
820
        }
 
821
        RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
 
822
 
 
823
        /* for debug, wait to show some messages to /proc system */
 
824
        udelay(1);
 
825
 
 
826
        RtmpPhyNetDevExit(pAd, pAd->net_dev);
 
827
 
 
828
        /* FIXME: Shall we need following delay and flush the schedule?? */
 
829
        udelay(1);
 
830
        flush_scheduled_work();
 
831
        udelay(1);
 
832
 
 
833
        /* free the root net_device */
 
834
        RtmpOSNetDevFree(pAd->net_dev);
 
835
 
 
836
        RtmpRaDevCtrlExit(pAd);
 
837
 
 
838
        /* release a use of the usb device structure */
 
839
        usb_put_dev(dev);
 
840
        udelay(1);
 
841
 
 
842
        DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
 
843
}
 
844
 
 
845
static int __devinit rt2870_probe(IN struct usb_interface *intf,
 
846
                                  IN struct usb_device *usb_dev,
 
847
                                  IN const struct usb_device_id *dev_id,
 
848
                                  struct rt_rtmp_adapter **ppAd)
 
849
{
 
850
        struct net_device *net_dev = NULL;
 
851
        struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
 
852
        int status, rv;
 
853
        void *handle;
 
854
        struct rt_rtmp_os_netdev_op_hook netDevHook;
 
855
 
 
856
        DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
 
857
 
 
858
        /* Check chipset vendor/product ID */
 
859
        /*if (RT28XXChipsetCheck(_dev_p) == FALSE) */
 
860
        /*      goto err_out; */
 
861
 
 
862
/*RtmpDevInit============================================= */
 
863
        /* Allocate struct rt_rtmp_adapter adapter structure */
 
864
        handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
 
865
        if (handle == NULL) {
 
866
                printk
 
867
                    ("rt2870_probe(): Allocate memory for os handle failed!\n");
 
868
                return -ENOMEM;
 
869
        }
 
870
        ((struct os_cookie *)handle)->pUsb_Dev = usb_dev;
 
871
 
 
872
        rv = RTMPAllocAdapterBlock(handle, &pAd);
 
873
        if (rv != NDIS_STATUS_SUCCESS) {
 
874
                kfree(handle);
 
875
                goto err_out;
 
876
        }
 
877
/*USBDevInit============================================== */
 
878
        if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
 
879
                goto err_out_free_radev;
 
880
 
 
881
        RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
 
882
 
 
883
/*NetDevInit============================================== */
 
884
        net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
 
885
        if (net_dev == NULL)
 
886
                goto err_out_free_radev;
 
887
 
 
888
        /* Here are the net_device structure with usb specific parameters. 
 
889
         * for supporting Network Manager.
 
890
         * Set the sysfs physical device reference for the network logical device if set prior to registration will
 
891
         * cause a symlink during initialization.
 
892
         */
 
893
        SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
 
894
 
 
895
        pAd->StaCfg.OriDevType = net_dev->type;
 
896
 
 
897
/*All done, it's time to register the net device to linux kernel. */
 
898
        /* Register this device */
 
899
        status = RtmpOSNetDevAttach(net_dev, &netDevHook);
 
900
        if (status != 0)
 
901
                goto err_out_free_netdev;
 
902
 
 
903
#ifdef KTHREAD_SUPPORT
 
904
        init_waitqueue_head(&pAd->mlmeTask.kthread_q);
 
905
        init_waitqueue_head(&pAd->timerTask.kthread_q);
 
906
        init_waitqueue_head(&pAd->cmdQTask.kthread_q);
 
907
#endif
 
908
 
 
909
        *ppAd = pAd;
 
910
 
 
911
        DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
 
912
 
 
913
        return 0;
 
914
 
 
915
        /* --------------------------- ERROR HANDLE --------------------------- */
 
916
err_out_free_netdev:
 
917
        RtmpOSNetDevFree(net_dev);
 
918
 
 
919
err_out_free_radev:
 
920
        RTMPFreeAdapter(pAd);
 
921
 
 
922
err_out:
 
923
        *ppAd = NULL;
 
924
 
 
925
        return -1;
 
926
 
 
927
}