diff options
author | David Kilroy <kilroyd@googlemail.com> | 2010-05-01 09:05:40 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-03 14:53:07 -0400 |
commit | bcad6e80f3fb0d6724c3814cf32258bbcf1d67db (patch) | |
tree | 13fc2edae79405b7ae393099486153eefa3091d1 | |
parent | 593ef09c9e70c92c0d76c67a1c03a5d44d3aec82 (diff) |
orinoco: encapsulate driver locking
Local bus and USB drivers will need to do locking differently.
The original orinoco_usb patches had a boolean variable controlling
whether spin_lock_bh was used, or irq based locking. This version
provides wrappers for the lock functions and the drivers specify the
functions pointers needed.
This will introduce a performance penalty, but I'm not expecting it to
be noticable.
Signed-off-by: David Kilroy <kilroyd@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/orinoco/airport.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/hermes.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/hermes.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/orinoco_cs.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/spectrum_cs.c | 4 |
7 files changed, 60 insertions, 20 deletions
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c index 7dac5adb6c1c..9bcee10c9308 100644 --- a/drivers/net/wireless/orinoco/airport.c +++ b/drivers/net/wireless/orinoco/airport.c | |||
@@ -77,9 +77,9 @@ airport_resume(struct macio_dev *mdev) | |||
77 | 77 | ||
78 | enable_irq(card->irq); | 78 | enable_irq(card->irq); |
79 | 79 | ||
80 | spin_lock_irqsave(&priv->lock, flags); | 80 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
81 | err = orinoco_up(priv); | 81 | err = orinoco_up(priv); |
82 | spin_unlock_irqrestore(&priv->lock, flags); | 82 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
83 | 83 | ||
84 | return err; | 84 | return err; |
85 | } | 85 | } |
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c index a7df5240779c..845693fb25f3 100644 --- a/drivers/net/wireless/orinoco/hermes.c +++ b/drivers/net/wireless/orinoco/hermes.c | |||
@@ -529,6 +529,28 @@ static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, | |||
529 | return err; | 529 | return err; |
530 | } | 530 | } |
531 | 531 | ||
532 | static void hermes_lock_irqsave(spinlock_t *lock, | ||
533 | unsigned long *flags) __acquires(lock) | ||
534 | { | ||
535 | spin_lock_irqsave(lock, *flags); | ||
536 | } | ||
537 | |||
538 | static void hermes_unlock_irqrestore(spinlock_t *lock, | ||
539 | unsigned long *flags) __releases(lock) | ||
540 | { | ||
541 | spin_unlock_irqrestore(lock, *flags); | ||
542 | } | ||
543 | |||
544 | static void hermes_lock_irq(spinlock_t *lock) __acquires(lock) | ||
545 | { | ||
546 | spin_lock_irq(lock); | ||
547 | } | ||
548 | |||
549 | static void hermes_unlock_irq(spinlock_t *lock) __releases(lock) | ||
550 | { | ||
551 | spin_unlock_irq(lock); | ||
552 | } | ||
553 | |||
532 | /* Hermes operations for local buses */ | 554 | /* Hermes operations for local buses */ |
533 | static const struct hermes_ops hermes_ops_local = { | 555 | static const struct hermes_ops hermes_ops_local = { |
534 | .init = hermes_init, | 556 | .init = hermes_init, |
@@ -538,5 +560,9 @@ static const struct hermes_ops hermes_ops_local = { | |||
538 | .read_ltv = hermes_read_ltv, | 560 | .read_ltv = hermes_read_ltv, |
539 | .write_ltv = hermes_write_ltv, | 561 | .write_ltv = hermes_write_ltv, |
540 | .bap_pread = hermes_bap_pread, | 562 | .bap_pread = hermes_bap_pread, |
541 | .bap_pwrite = hermes_bap_pwrite | 563 | .bap_pwrite = hermes_bap_pwrite, |
564 | .lock_irqsave = hermes_lock_irqsave, | ||
565 | .unlock_irqrestore = hermes_unlock_irqrestore, | ||
566 | .lock_irq = hermes_lock_irq, | ||
567 | .unlock_irq = hermes_unlock_irq, | ||
542 | }; | 568 | }; |
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h index 18b268c54dfe..9e21ecdb4e70 100644 --- a/drivers/net/wireless/orinoco/hermes.h +++ b/drivers/net/wireless/orinoco/hermes.h | |||
@@ -393,6 +393,10 @@ struct hermes_ops { | |||
393 | u16 id, u16 offset); | 393 | u16 id, u16 offset); |
394 | int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf, | 394 | int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf, |
395 | int len, u16 id, u16 offset); | 395 | int len, u16 id, u16 offset); |
396 | void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags); | ||
397 | void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags); | ||
398 | void (*lock_irq)(spinlock_t *lock); | ||
399 | void (*unlock_irq)(spinlock_t *lock); | ||
396 | }; | 400 | }; |
397 | 401 | ||
398 | /* Basic control structure */ | 402 | /* Basic control structure */ |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 7acb6bc3ebff..36c4ba865c7c 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -281,13 +281,13 @@ int orinoco_stop(struct net_device *dev) | |||
281 | /* We mustn't use orinoco_lock() here, because we need to be | 281 | /* We mustn't use orinoco_lock() here, because we need to be |
282 | able to close the interface even if hw_unavailable is set | 282 | able to close the interface even if hw_unavailable is set |
283 | (e.g. as we're released after a PC Card removal) */ | 283 | (e.g. as we're released after a PC Card removal) */ |
284 | spin_lock_irq(&priv->lock); | 284 | orinoco_lock_irq(priv); |
285 | 285 | ||
286 | priv->open = 0; | 286 | priv->open = 0; |
287 | 287 | ||
288 | err = __orinoco_down(priv); | 288 | err = __orinoco_down(priv); |
289 | 289 | ||
290 | spin_unlock_irq(&priv->lock); | 290 | orinoco_unlock_irq(priv); |
291 | 291 | ||
292 | return err; | 292 | return err; |
293 | } | 293 | } |
@@ -1741,7 +1741,7 @@ void orinoco_reset(struct work_struct *work) | |||
1741 | } | 1741 | } |
1742 | 1742 | ||
1743 | /* This has to be called from user context */ | 1743 | /* This has to be called from user context */ |
1744 | spin_lock_irq(&priv->lock); | 1744 | orinoco_lock_irq(priv); |
1745 | 1745 | ||
1746 | priv->hw_unavailable--; | 1746 | priv->hw_unavailable--; |
1747 | 1747 | ||
@@ -1756,7 +1756,7 @@ void orinoco_reset(struct work_struct *work) | |||
1756 | dev->trans_start = jiffies; | 1756 | dev->trans_start = jiffies; |
1757 | } | 1757 | } |
1758 | 1758 | ||
1759 | spin_unlock_irq(&priv->lock); | 1759 | orinoco_unlock_irq(priv); |
1760 | 1760 | ||
1761 | return; | 1761 | return; |
1762 | disable: | 1762 | disable: |
@@ -2073,9 +2073,9 @@ int orinoco_init(struct orinoco_private *priv) | |||
2073 | 2073 | ||
2074 | /* Make the hardware available, as long as it hasn't been | 2074 | /* Make the hardware available, as long as it hasn't been |
2075 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ | 2075 | * removed elsewhere (e.g. by PCMCIA hot unplug) */ |
2076 | spin_lock_irq(&priv->lock); | 2076 | orinoco_lock_irq(priv); |
2077 | priv->hw_unavailable--; | 2077 | priv->hw_unavailable--; |
2078 | spin_unlock_irq(&priv->lock); | 2078 | orinoco_unlock_irq(priv); |
2079 | 2079 | ||
2080 | dev_dbg(dev, "Ready\n"); | 2080 | dev_dbg(dev, "Ready\n"); |
2081 | 2081 | ||
@@ -2317,7 +2317,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2317 | unsigned long flags; | 2317 | unsigned long flags; |
2318 | int err; | 2318 | int err; |
2319 | 2319 | ||
2320 | spin_lock_irqsave(&priv->lock, flags); | 2320 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2321 | 2321 | ||
2322 | err = orinoco_reinit_firmware(priv); | 2322 | err = orinoco_reinit_firmware(priv); |
2323 | if (err) { | 2323 | if (err) { |
@@ -2337,7 +2337,7 @@ int orinoco_up(struct orinoco_private *priv) | |||
2337 | } | 2337 | } |
2338 | 2338 | ||
2339 | exit: | 2339 | exit: |
2340 | spin_unlock_irqrestore(&priv->lock, flags); | 2340 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2341 | 2341 | ||
2342 | return 0; | 2342 | return 0; |
2343 | } | 2343 | } |
@@ -2349,7 +2349,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2349 | unsigned long flags; | 2349 | unsigned long flags; |
2350 | int err; | 2350 | int err; |
2351 | 2351 | ||
2352 | spin_lock_irqsave(&priv->lock, flags); | 2352 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
2353 | err = __orinoco_down(priv); | 2353 | err = __orinoco_down(priv); |
2354 | if (err) | 2354 | if (err) |
2355 | printk(KERN_WARNING "%s: Error %d downing interface\n", | 2355 | printk(KERN_WARNING "%s: Error %d downing interface\n", |
@@ -2357,7 +2357,7 @@ void orinoco_down(struct orinoco_private *priv) | |||
2357 | 2357 | ||
2358 | netif_device_detach(dev); | 2358 | netif_device_detach(dev); |
2359 | priv->hw_unavailable++; | 2359 | priv->hw_unavailable++; |
2360 | spin_unlock_irqrestore(&priv->lock, flags); | 2360 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
2361 | } | 2361 | } |
2362 | EXPORT_SYMBOL(orinoco_down); | 2362 | EXPORT_SYMBOL(orinoco_down); |
2363 | 2363 | ||
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index f1901d6e6af8..80a1386ce0b4 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h | |||
@@ -212,11 +212,11 @@ void orinoco_tx_timeout(struct net_device *dev); | |||
212 | static inline int orinoco_lock(struct orinoco_private *priv, | 212 | static inline int orinoco_lock(struct orinoco_private *priv, |
213 | unsigned long *flags) | 213 | unsigned long *flags) |
214 | { | 214 | { |
215 | spin_lock_irqsave(&priv->lock, *flags); | 215 | priv->hw.ops->lock_irqsave(&priv->lock, flags); |
216 | if (priv->hw_unavailable) { | 216 | if (priv->hw_unavailable) { |
217 | DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", | 217 | DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", |
218 | priv->ndev); | 218 | priv->ndev); |
219 | spin_unlock_irqrestore(&priv->lock, *flags); | 219 | priv->hw.ops->unlock_irqrestore(&priv->lock, flags); |
220 | return -EBUSY; | 220 | return -EBUSY; |
221 | } | 221 | } |
222 | return 0; | 222 | return 0; |
@@ -225,7 +225,17 @@ static inline int orinoco_lock(struct orinoco_private *priv, | |||
225 | static inline void orinoco_unlock(struct orinoco_private *priv, | 225 | static inline void orinoco_unlock(struct orinoco_private *priv, |
226 | unsigned long *flags) | 226 | unsigned long *flags) |
227 | { | 227 | { |
228 | spin_unlock_irqrestore(&priv->lock, *flags); | 228 | priv->hw.ops->unlock_irqrestore(&priv->lock, flags); |
229 | } | ||
230 | |||
231 | static inline void orinoco_lock_irq(struct orinoco_private *priv) | ||
232 | { | ||
233 | priv->hw.ops->lock_irq(&priv->lock); | ||
234 | } | ||
235 | |||
236 | static inline void orinoco_unlock_irq(struct orinoco_private *priv) | ||
237 | { | ||
238 | priv->hw.ops->unlock_irq(&priv->lock); | ||
229 | } | 239 | } |
230 | 240 | ||
231 | /*** Navigate from net_device to orinoco_private ***/ | 241 | /*** Navigate from net_device to orinoco_private ***/ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 525f74e68294..f99b13ba92b3 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -327,9 +327,9 @@ orinoco_cs_release(struct pcmcia_device *link) | |||
327 | 327 | ||
328 | /* We're committed to taking the device away now, so mark the | 328 | /* We're committed to taking the device away now, so mark the |
329 | * hardware as unavailable */ | 329 | * hardware as unavailable */ |
330 | spin_lock_irqsave(&priv->lock, flags); | 330 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
331 | priv->hw_unavailable++; | 331 | priv->hw_unavailable++; |
332 | spin_unlock_irqrestore(&priv->lock, flags); | 332 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
333 | 333 | ||
334 | pcmcia_disable_device(link); | 334 | pcmcia_disable_device(link); |
335 | if (priv->hw.iobase) | 335 | if (priv->hw.iobase) |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index 77b58717d185..b4f68ef771e4 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -405,9 +405,9 @@ spectrum_cs_release(struct pcmcia_device *link) | |||
405 | 405 | ||
406 | /* We're committed to taking the device away now, so mark the | 406 | /* We're committed to taking the device away now, so mark the |
407 | * hardware as unavailable */ | 407 | * hardware as unavailable */ |
408 | spin_lock_irqsave(&priv->lock, flags); | 408 | priv->hw.ops->lock_irqsave(&priv->lock, &flags); |
409 | priv->hw_unavailable++; | 409 | priv->hw_unavailable++; |
410 | spin_unlock_irqrestore(&priv->lock, flags); | 410 | priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); |
411 | 411 | ||
412 | pcmcia_disable_device(link); | 412 | pcmcia_disable_device(link); |
413 | if (priv->hw.iobase) | 413 | if (priv->hw.iobase) |