diff options
Diffstat (limited to 'drivers/net/wireless/orinoco_plx.c')
-rw-r--r-- | drivers/net/wireless/orinoco_plx.c | 223 |
1 files changed, 96 insertions, 127 deletions
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c index 210e73776545..84f696c77551 100644 --- a/drivers/net/wireless/orinoco_plx.c +++ b/drivers/net/wireless/orinoco_plx.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Driver for Prism II devices which would usually be driven by orinoco_cs, | 3 | * Driver for Prism II devices which would usually be driven by orinoco_cs, |
4 | * but are connected to the PCI bus by a PLX9052. | 4 | * but are connected to the PCI bus by a PLX9052. |
5 | * | 5 | * |
6 | * Current maintainers (as of 29 September 2003) are: | 6 | * Current maintainers are: |
7 | * Pavel Roskin <proski AT gnu.org> | 7 | * Pavel Roskin <proski AT gnu.org> |
8 | * and David Gibson <hermes AT gibson.dropbear.id.au> | 8 | * and David Gibson <hermes AT gibson.dropbear.id.au> |
9 | * | 9 | * |
@@ -30,38 +30,18 @@ | |||
30 | * other provisions required by the GPL. If you do not delete the | 30 | * other provisions required by the GPL. If you do not delete the |
31 | * provisions above, a recipient may use your version of this file | 31 | * provisions above, a recipient may use your version of this file |
32 | * under either the MPL or the GPL. | 32 | * under either the MPL or the GPL. |
33 | |||
34 | * Caution: this is experimental and probably buggy. For success and | ||
35 | * failure reports for different cards and adaptors, see | ||
36 | * orinoco_plx_pci_id_table near the end of the file. If you have a | ||
37 | * card we don't have the PCI id for, and looks like it should work, | ||
38 | * drop me mail with the id and "it works"/"it doesn't work". | ||
39 | * | ||
40 | * Note: if everything gets detected fine but it doesn't actually send | ||
41 | * or receive packets, your first port of call should probably be to | ||
42 | * try newer firmware in the card. Especially if you're doing Ad-Hoc | ||
43 | * modes. | ||
44 | * | ||
45 | * The actual driving is done by orinoco.c, this is just resource | ||
46 | * allocation stuff. The explanation below is courtesy of Ryan Niemi | ||
47 | * on the linux-wlan-ng list at | ||
48 | * http://archives.neohapsis.com/archives/dev/linux-wlan/2001-q1/0026.html | ||
49 | * | 33 | * |
50 | * The PLX9052-based cards (WL11000 and several others) are a | 34 | * Here's the general details on how the PLX9052 adapter works: |
51 | * different beast than the usual PCMCIA-based PRISM2 configuration | ||
52 | * expected by wlan-ng. Here's the general details on how the WL11000 | ||
53 | * PCI adapter works: | ||
54 | * | 35 | * |
55 | * - Two PCI I/O address spaces, one 0x80 long which contains the | 36 | * - Two PCI I/O address spaces, one 0x80 long which contains the |
56 | * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA | 37 | * PLX9052 registers, and one that's 0x40 long mapped to the PCMCIA |
57 | * slot I/O address space. | 38 | * slot I/O address space. |
58 | * | 39 | * |
59 | * - One PCI memory address space, mapped to the PCMCIA memory space | 40 | * - One PCI memory address space, mapped to the PCMCIA attribute space |
60 | * (containing the CIS). | 41 | * (containing the CIS). |
61 | * | 42 | * |
62 | * After identifying the I/O and memory space, you can read through | 43 | * Using the later, you can read through the CIS data to make sure the |
63 | * the memory space to confirm the CIS's device ID or manufacturer ID | 44 | * card is compatible with the driver. Keep in mind that the PCMCIA |
64 | * to make sure it's the expected card. qKeep in mind that the PCMCIA | ||
65 | * spec specifies the CIS as the lower 8 bits of each word read from | 45 | * spec specifies the CIS as the lower 8 bits of each word read from |
66 | * the CIS, so to read the bytes of the CIS, read every other byte | 46 | * the CIS, so to read the bytes of the CIS, read every other byte |
67 | * (0,2,4,...). Passing that test, you need to enable the I/O address | 47 | * (0,2,4,...). Passing that test, you need to enable the I/O address |
@@ -71,7 +51,7 @@ | |||
71 | * within the PCI memory space. Write 0x41 to the COR register to | 51 | * within the PCI memory space. Write 0x41 to the COR register to |
72 | * enable I/O mode and to select level triggered interrupts. To | 52 | * enable I/O mode and to select level triggered interrupts. To |
73 | * confirm you actually succeeded, read the COR register back and make | 53 | * confirm you actually succeeded, read the COR register back and make |
74 | * sure it actually got set to 0x41, incase you have an unexpected | 54 | * sure it actually got set to 0x41, in case you have an unexpected |
75 | * card inserted. | 55 | * card inserted. |
76 | * | 56 | * |
77 | * Following that, you can treat the second PCI I/O address space (the | 57 | * Following that, you can treat the second PCI I/O address space (the |
@@ -101,16 +81,6 @@ | |||
101 | * that, I've hot-swapped a number of times during debugging and | 81 | * that, I've hot-swapped a number of times during debugging and |
102 | * driver development for various reasons (stuck WAIT# line after the | 82 | * driver development for various reasons (stuck WAIT# line after the |
103 | * radio card's firmware locks up). | 83 | * radio card's firmware locks up). |
104 | * | ||
105 | * Hope this is enough info for someone to add PLX9052 support to the | ||
106 | * wlan-ng card. In the case of the WL11000, the PCI ID's are | ||
107 | * 0x1639/0x0200, with matching subsystem ID's. Other PLX9052-based | ||
108 | * manufacturers other than Eumitcom (or on cards other than the | ||
109 | * WL11000) may have different PCI ID's. | ||
110 | * | ||
111 | * If anyone needs any more specific info, let me know. I haven't had | ||
112 | * time to implement support myself yet, and with the way things are | ||
113 | * going, might not have time for a while.. | ||
114 | */ | 84 | */ |
115 | 85 | ||
116 | #define DRIVER_NAME "orinoco_plx" | 86 | #define DRIVER_NAME "orinoco_plx" |
@@ -125,6 +95,7 @@ | |||
125 | #include <pcmcia/cisreg.h> | 95 | #include <pcmcia/cisreg.h> |
126 | 96 | ||
127 | #include "orinoco.h" | 97 | #include "orinoco.h" |
98 | #include "orinoco_pci.h" | ||
128 | 99 | ||
129 | #define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */ | 100 | #define COR_OFFSET (0x3e0) /* COR attribute offset of Prism2 PC card */ |
130 | #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */ | 101 | #define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */ |
@@ -134,30 +105,20 @@ | |||
134 | #define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */ | 105 | #define PLX_INTCSR 0x4c /* Interrupt Control & Status Register */ |
135 | #define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */ | 106 | #define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */ |
136 | 107 | ||
137 | static const u8 cis_magic[] = { | ||
138 | 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67 | ||
139 | }; | ||
140 | |||
141 | /* Orinoco PLX specific data */ | ||
142 | struct orinoco_plx_card { | ||
143 | void __iomem *attr_mem; | ||
144 | }; | ||
145 | |||
146 | /* | 108 | /* |
147 | * Do a soft reset of the card using the Configuration Option Register | 109 | * Do a soft reset of the card using the Configuration Option Register |
148 | */ | 110 | */ |
149 | static int orinoco_plx_cor_reset(struct orinoco_private *priv) | 111 | static int orinoco_plx_cor_reset(struct orinoco_private *priv) |
150 | { | 112 | { |
151 | hermes_t *hw = &priv->hw; | 113 | hermes_t *hw = &priv->hw; |
152 | struct orinoco_plx_card *card = priv->card; | 114 | struct orinoco_pci_card *card = priv->card; |
153 | u8 __iomem *attr_mem = card->attr_mem; | ||
154 | unsigned long timeout; | 115 | unsigned long timeout; |
155 | u16 reg; | 116 | u16 reg; |
156 | 117 | ||
157 | writeb(COR_VALUE | COR_RESET, attr_mem + COR_OFFSET); | 118 | iowrite8(COR_VALUE | COR_RESET, card->attr_io + COR_OFFSET); |
158 | mdelay(1); | 119 | mdelay(1); |
159 | 120 | ||
160 | writeb(COR_VALUE, attr_mem + COR_OFFSET); | 121 | iowrite8(COR_VALUE, card->attr_io + COR_OFFSET); |
161 | mdelay(1); | 122 | mdelay(1); |
162 | 123 | ||
163 | /* Just in case, wait more until the card is no longer busy */ | 124 | /* Just in case, wait more until the card is no longer busy */ |
@@ -168,7 +129,7 @@ static int orinoco_plx_cor_reset(struct orinoco_private *priv) | |||
168 | reg = hermes_read_regn(hw, CMD); | 129 | reg = hermes_read_regn(hw, CMD); |
169 | } | 130 | } |
170 | 131 | ||
171 | /* Did we timeout ? */ | 132 | /* Still busy? */ |
172 | if (reg & HERMES_CMD_BUSY) { | 133 | if (reg & HERMES_CMD_BUSY) { |
173 | printk(KERN_ERR PFX "Busy timeout\n"); | 134 | printk(KERN_ERR PFX "Busy timeout\n"); |
174 | return -ETIMEDOUT; | 135 | return -ETIMEDOUT; |
@@ -177,20 +138,55 @@ static int orinoco_plx_cor_reset(struct orinoco_private *priv) | |||
177 | return 0; | 138 | return 0; |
178 | } | 139 | } |
179 | 140 | ||
141 | static int orinoco_plx_hw_init(struct orinoco_pci_card *card) | ||
142 | { | ||
143 | int i; | ||
144 | u32 csr_reg; | ||
145 | static const u8 cis_magic[] = { | ||
146 | 0x01, 0x03, 0x00, 0x00, 0xff, 0x17, 0x04, 0x67 | ||
147 | }; | ||
148 | |||
149 | printk(KERN_DEBUG PFX "CIS: "); | ||
150 | for (i = 0; i < 16; i++) { | ||
151 | printk("%02X:", ioread8(card->attr_io + (i << 1))); | ||
152 | } | ||
153 | printk("\n"); | ||
154 | |||
155 | /* Verify whether a supported PC card is present */ | ||
156 | /* FIXME: we probably need to be smarted about this */ | ||
157 | for (i = 0; i < sizeof(cis_magic); i++) { | ||
158 | if (cis_magic[i] != ioread8(card->attr_io + (i << 1))) { | ||
159 | printk(KERN_ERR PFX "The CIS value of Prism2 PC " | ||
160 | "card is unexpected\n"); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | } | ||
164 | |||
165 | /* bjoern: We need to tell the card to enable interrupts, in | ||
166 | case the serial eprom didn't do this already. See the | ||
167 | PLX9052 data book, p8-1 and 8-24 for reference. */ | ||
168 | csr_reg = ioread32(card->bridge_io + PLX_INTCSR); | ||
169 | if (!(csr_reg & PLX_INTCSR_INTEN)) { | ||
170 | csr_reg |= PLX_INTCSR_INTEN; | ||
171 | iowrite32(csr_reg, card->bridge_io + PLX_INTCSR); | ||
172 | csr_reg = ioread32(card->bridge_io + PLX_INTCSR); | ||
173 | if (!(csr_reg & PLX_INTCSR_INTEN)) { | ||
174 | printk(KERN_ERR PFX "Cannot enable interrupts\n"); | ||
175 | return -EIO; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
180 | 181 | ||
181 | static int orinoco_plx_init_one(struct pci_dev *pdev, | 182 | static int orinoco_plx_init_one(struct pci_dev *pdev, |
182 | const struct pci_device_id *ent) | 183 | const struct pci_device_id *ent) |
183 | { | 184 | { |
184 | int err = 0; | 185 | int err; |
185 | u8 __iomem *attr_mem = NULL; | 186 | struct orinoco_private *priv; |
186 | u32 csr_reg, plx_addr; | 187 | struct orinoco_pci_card *card; |
187 | struct orinoco_private *priv = NULL; | 188 | struct net_device *dev; |
188 | struct orinoco_plx_card *card; | 189 | void __iomem *hermes_io, *attr_io, *bridge_io; |
189 | unsigned long pccard_ioaddr = 0; | ||
190 | unsigned long pccard_iolen = 0; | ||
191 | struct net_device *dev = NULL; | ||
192 | void __iomem *mem; | ||
193 | int i; | ||
194 | 190 | ||
195 | err = pci_enable_device(pdev); | 191 | err = pci_enable_device(pdev); |
196 | if (err) { | 192 | if (err) { |
@@ -199,30 +195,30 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
199 | } | 195 | } |
200 | 196 | ||
201 | err = pci_request_regions(pdev, DRIVER_NAME); | 197 | err = pci_request_regions(pdev, DRIVER_NAME); |
202 | if (err != 0) { | 198 | if (err) { |
203 | printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); | 199 | printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); |
204 | goto fail_resources; | 200 | goto fail_resources; |
205 | } | 201 | } |
206 | 202 | ||
207 | /* Resource 1 is mapped to PLX-specific registers */ | 203 | bridge_io = pci_iomap(pdev, 1, 0); |
208 | plx_addr = pci_resource_start(pdev, 1); | 204 | if (!bridge_io) { |
205 | printk(KERN_ERR PFX "Cannot map bridge registers\n"); | ||
206 | err = -EIO; | ||
207 | goto fail_map_bridge; | ||
208 | } | ||
209 | 209 | ||
210 | /* Resource 2 is mapped to the PCMCIA attribute memory */ | 210 | attr_io = pci_iomap(pdev, 2, 0); |
211 | attr_mem = ioremap(pci_resource_start(pdev, 2), | 211 | if (!attr_io) { |
212 | pci_resource_len(pdev, 2)); | 212 | printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n"); |
213 | if (!attr_mem) { | 213 | err = -EIO; |
214 | printk(KERN_ERR PFX "Cannot remap PCMCIA space\n"); | ||
215 | goto fail_map_attr; | 214 | goto fail_map_attr; |
216 | } | 215 | } |
217 | 216 | ||
218 | /* Resource 3 is mapped to the PCMCIA I/O address space */ | 217 | hermes_io = pci_iomap(pdev, 3, 0); |
219 | pccard_ioaddr = pci_resource_start(pdev, 3); | 218 | if (!hermes_io) { |
220 | pccard_iolen = pci_resource_len(pdev, 3); | 219 | printk(KERN_ERR PFX "Cannot map chipset registers\n"); |
221 | 220 | err = -EIO; | |
222 | mem = pci_iomap(pdev, 3, 0); | 221 | goto fail_map_hermes; |
223 | if (!mem) { | ||
224 | err = -ENOMEM; | ||
225 | goto fail_map_io; | ||
226 | } | 222 | } |
227 | 223 | ||
228 | /* Allocate network device */ | 224 | /* Allocate network device */ |
@@ -235,16 +231,12 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
235 | 231 | ||
236 | priv = netdev_priv(dev); | 232 | priv = netdev_priv(dev); |
237 | card = priv->card; | 233 | card = priv->card; |
238 | card->attr_mem = attr_mem; | 234 | card->bridge_io = bridge_io; |
239 | dev->base_addr = pccard_ioaddr; | 235 | card->attr_io = attr_io; |
240 | SET_MODULE_OWNER(dev); | 236 | SET_MODULE_OWNER(dev); |
241 | SET_NETDEV_DEV(dev, &pdev->dev); | 237 | SET_NETDEV_DEV(dev, &pdev->dev); |
242 | 238 | ||
243 | hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING); | 239 | hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING); |
244 | |||
245 | printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device " | ||
246 | "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq, | ||
247 | pccard_ioaddr); | ||
248 | 240 | ||
249 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, | 241 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, |
250 | dev->name, dev); | 242 | dev->name, dev); |
@@ -253,20 +245,11 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
253 | err = -EBUSY; | 245 | err = -EBUSY; |
254 | goto fail_irq; | 246 | goto fail_irq; |
255 | } | 247 | } |
256 | dev->irq = pdev->irq; | ||
257 | 248 | ||
258 | /* bjoern: We need to tell the card to enable interrupts, in | 249 | err = orinoco_plx_hw_init(card); |
259 | case the serial eprom didn't do this already. See the | 250 | if (err) { |
260 | PLX9052 data book, p8-1 and 8-24 for reference. */ | 251 | printk(KERN_ERR PFX "Hardware initialization failed\n"); |
261 | csr_reg = inl(plx_addr + PLX_INTCSR); | 252 | goto fail; |
262 | if (!(csr_reg & PLX_INTCSR_INTEN)) { | ||
263 | csr_reg |= PLX_INTCSR_INTEN; | ||
264 | outl(csr_reg, plx_addr + PLX_INTCSR); | ||
265 | csr_reg = inl(plx_addr + PLX_INTCSR); | ||
266 | if (!(csr_reg & PLX_INTCSR_INTEN)) { | ||
267 | printk(KERN_ERR PFX "Cannot enable interrupts\n"); | ||
268 | goto fail; | ||
269 | } | ||
270 | } | 253 | } |
271 | 254 | ||
272 | err = orinoco_plx_cor_reset(priv); | 255 | err = orinoco_plx_cor_reset(priv); |
@@ -275,23 +258,6 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
275 | goto fail; | 258 | goto fail; |
276 | } | 259 | } |
277 | 260 | ||
278 | printk(KERN_DEBUG PFX "CIS: "); | ||
279 | for (i = 0; i < 16; i++) { | ||
280 | printk("%02X:", readb(attr_mem + 2*i)); | ||
281 | } | ||
282 | printk("\n"); | ||
283 | |||
284 | /* Verify whether a supported PC card is present */ | ||
285 | /* FIXME: we probably need to be smarted about this */ | ||
286 | for (i = 0; i < sizeof(cis_magic); i++) { | ||
287 | if (cis_magic[i] != readb(attr_mem +2*i)) { | ||
288 | printk(KERN_ERR PFX "The CIS value of Prism2 PC " | ||
289 | "card is unexpected\n"); | ||
290 | err = -EIO; | ||
291 | goto fail; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | err = register_netdev(dev); | 261 | err = register_netdev(dev); |
296 | if (err) { | 262 | if (err) { |
297 | printk(KERN_ERR PFX "Cannot register network device\n"); | 263 | printk(KERN_ERR PFX "Cannot register network device\n"); |
@@ -299,6 +265,8 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
299 | } | 265 | } |
300 | 266 | ||
301 | pci_set_drvdata(pdev, dev); | 267 | pci_set_drvdata(pdev, dev); |
268 | printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name, | ||
269 | pci_name(pdev)); | ||
302 | 270 | ||
303 | return 0; | 271 | return 0; |
304 | 272 | ||
@@ -310,12 +278,15 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, | |||
310 | free_orinocodev(dev); | 278 | free_orinocodev(dev); |
311 | 279 | ||
312 | fail_alloc: | 280 | fail_alloc: |
313 | pci_iounmap(pdev, mem); | 281 | pci_iounmap(pdev, hermes_io); |
314 | 282 | ||
315 | fail_map_io: | 283 | fail_map_hermes: |
316 | iounmap(attr_mem); | 284 | pci_iounmap(pdev, attr_io); |
317 | 285 | ||
318 | fail_map_attr: | 286 | fail_map_attr: |
287 | pci_iounmap(pdev, bridge_io); | ||
288 | |||
289 | fail_map_bridge: | ||
319 | pci_release_regions(pdev); | 290 | pci_release_regions(pdev); |
320 | 291 | ||
321 | fail_resources: | 292 | fail_resources: |
@@ -328,23 +299,20 @@ static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) | |||
328 | { | 299 | { |
329 | struct net_device *dev = pci_get_drvdata(pdev); | 300 | struct net_device *dev = pci_get_drvdata(pdev); |
330 | struct orinoco_private *priv = netdev_priv(dev); | 301 | struct orinoco_private *priv = netdev_priv(dev); |
331 | struct orinoco_plx_card *card = priv->card; | 302 | struct orinoco_pci_card *card = priv->card; |
332 | u8 __iomem *attr_mem = card->attr_mem; | ||
333 | |||
334 | BUG_ON(! dev); | ||
335 | 303 | ||
336 | unregister_netdev(dev); | 304 | unregister_netdev(dev); |
337 | free_irq(dev->irq, dev); | 305 | free_irq(pdev->irq, dev); |
338 | pci_set_drvdata(pdev, NULL); | 306 | pci_set_drvdata(pdev, NULL); |
339 | free_orinocodev(dev); | 307 | free_orinocodev(dev); |
340 | pci_iounmap(pdev, priv->hw.iobase); | 308 | pci_iounmap(pdev, priv->hw.iobase); |
341 | iounmap(attr_mem); | 309 | pci_iounmap(pdev, card->attr_io); |
310 | pci_iounmap(pdev, card->bridge_io); | ||
342 | pci_release_regions(pdev); | 311 | pci_release_regions(pdev); |
343 | pci_disable_device(pdev); | 312 | pci_disable_device(pdev); |
344 | } | 313 | } |
345 | 314 | ||
346 | 315 | static struct pci_device_id orinoco_plx_id_table[] = { | |
347 | static struct pci_device_id orinoco_plx_pci_id_table[] = { | ||
348 | {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */ | 316 | {0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,}, /* Siemens SpeedStream SS1023 */ |
349 | {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */ | 317 | {0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,}, /* Netgear MA301 */ |
350 | {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */ | 318 | {0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,}, /* Correga - does this work? */ |
@@ -362,13 +330,15 @@ static struct pci_device_id orinoco_plx_pci_id_table[] = { | |||
362 | {0,}, | 330 | {0,}, |
363 | }; | 331 | }; |
364 | 332 | ||
365 | MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table); | 333 | MODULE_DEVICE_TABLE(pci, orinoco_plx_id_table); |
366 | 334 | ||
367 | static struct pci_driver orinoco_plx_driver = { | 335 | static struct pci_driver orinoco_plx_driver = { |
368 | .name = DRIVER_NAME, | 336 | .name = DRIVER_NAME, |
369 | .id_table = orinoco_plx_pci_id_table, | 337 | .id_table = orinoco_plx_id_table, |
370 | .probe = orinoco_plx_init_one, | 338 | .probe = orinoco_plx_init_one, |
371 | .remove = __devexit_p(orinoco_plx_remove_one), | 339 | .remove = __devexit_p(orinoco_plx_remove_one), |
340 | .suspend = orinoco_pci_suspend, | ||
341 | .resume = orinoco_pci_resume, | ||
372 | }; | 342 | }; |
373 | 343 | ||
374 | static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION | 344 | static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION |
@@ -388,7 +358,6 @@ static int __init orinoco_plx_init(void) | |||
388 | static void __exit orinoco_plx_exit(void) | 358 | static void __exit orinoco_plx_exit(void) |
389 | { | 359 | { |
390 | pci_unregister_driver(&orinoco_plx_driver); | 360 | pci_unregister_driver(&orinoco_plx_driver); |
391 | ssleep(1); | ||
392 | } | 361 | } |
393 | 362 | ||
394 | module_init(orinoco_plx_init); | 363 | module_init(orinoco_plx_init); |