diff options
author | Alan Cox <alan@redhat.com> | 2008-10-15 06:50:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-10-16 05:11:00 -0400 |
commit | 8ab7b66796920e785d27c88fcde1539fa661ae14 (patch) | |
tree | f9e04fd5a13c7e065c71b5f66696b93343a25f0e | |
parent | 5dd2d3322836036da169904afcb7d0f6dff5363f (diff) |
lmc: copy_*_user under spinlock
Not sure anyone uses this driver any more, maybe we should just drop it ?
Code is still foul but at least a fraction less broken.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r-- | drivers/net/wan/lmc/lmc_main.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index f80640f5a744..d7bb63e616b5 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c | |||
@@ -122,7 +122,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
122 | * Most functions mess with the structure | 122 | * Most functions mess with the structure |
123 | * Disable interrupts while we do the polling | 123 | * Disable interrupts while we do the polling |
124 | */ | 124 | */ |
125 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
126 | 125 | ||
127 | switch (cmd) { | 126 | switch (cmd) { |
128 | /* | 127 | /* |
@@ -152,6 +151,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
152 | break; | 151 | break; |
153 | } | 152 | } |
154 | 153 | ||
154 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
155 | sc->lmc_media->set_status (sc, &ctl); | 155 | sc->lmc_media->set_status (sc, &ctl); |
156 | 156 | ||
157 | if(ctl.crc_length != sc->ictl.crc_length) { | 157 | if(ctl.crc_length != sc->ictl.crc_length) { |
@@ -161,6 +161,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
161 | else | 161 | else |
162 | sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE; | 162 | sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE; |
163 | } | 163 | } |
164 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
164 | 165 | ||
165 | ret = 0; | 166 | ret = 0; |
166 | break; | 167 | break; |
@@ -187,15 +188,18 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
187 | break; /* no change */ | 188 | break; /* no change */ |
188 | } | 189 | } |
189 | 190 | ||
191 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
190 | lmc_proto_close(sc); | 192 | lmc_proto_close(sc); |
191 | 193 | ||
192 | sc->if_type = new_type; | 194 | sc->if_type = new_type; |
193 | lmc_proto_attach(sc); | 195 | lmc_proto_attach(sc); |
194 | ret = lmc_proto_open(sc); | 196 | ret = lmc_proto_open(sc); |
197 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
195 | break; | 198 | break; |
196 | } | 199 | } |
197 | 200 | ||
198 | case LMCIOCGETXINFO: /*fold01*/ | 201 | case LMCIOCGETXINFO: /*fold01*/ |
202 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
199 | sc->lmc_xinfo.Magic0 = 0xBEEFCAFE; | 203 | sc->lmc_xinfo.Magic0 = 0xBEEFCAFE; |
200 | 204 | ||
201 | sc->lmc_xinfo.PciCardType = sc->lmc_cardtype; | 205 | sc->lmc_xinfo.PciCardType = sc->lmc_cardtype; |
@@ -208,6 +212,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
208 | sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ; | 212 | sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ; |
209 | sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc); | 213 | sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc); |
210 | sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16); | 214 | sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16); |
215 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
211 | 216 | ||
212 | sc->lmc_xinfo.Magic1 = 0xDEADBEEF; | 217 | sc->lmc_xinfo.Magic1 = 0xDEADBEEF; |
213 | 218 | ||
@@ -220,6 +225,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
220 | break; | 225 | break; |
221 | 226 | ||
222 | case LMCIOCGETLMCSTATS: | 227 | case LMCIOCGETLMCSTATS: |
228 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
223 | if (sc->lmc_cardtype == LMC_CARDTYPE_T1) { | 229 | if (sc->lmc_cardtype == LMC_CARDTYPE_T1) { |
224 | lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB); | 230 | lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB); |
225 | sc->extra_stats.framingBitErrorCount += | 231 | sc->extra_stats.framingBitErrorCount += |
@@ -243,6 +249,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
243 | sc->extra_stats.severelyErroredFrameCount += | 249 | sc->extra_stats.severelyErroredFrameCount += |
244 | regVal & T1FRAMER_SEF_MASK; | 250 | regVal & T1FRAMER_SEF_MASK; |
245 | } | 251 | } |
252 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
246 | if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats, | 253 | if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats, |
247 | sizeof(sc->lmc_device->stats)) || | 254 | sizeof(sc->lmc_device->stats)) || |
248 | copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats), | 255 | copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats), |
@@ -258,12 +265,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
258 | break; | 265 | break; |
259 | } | 266 | } |
260 | 267 | ||
268 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
261 | memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats)); | 269 | memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats)); |
262 | memset(&sc->extra_stats, 0, sizeof(sc->extra_stats)); | 270 | memset(&sc->extra_stats, 0, sizeof(sc->extra_stats)); |
263 | sc->extra_stats.check = STATCHECK; | 271 | sc->extra_stats.check = STATCHECK; |
264 | sc->extra_stats.version_size = (DRIVER_VERSION << 16) + | 272 | sc->extra_stats.version_size = (DRIVER_VERSION << 16) + |
265 | sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats); | 273 | sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats); |
266 | sc->extra_stats.lmc_cardtype = sc->lmc_cardtype; | 274 | sc->extra_stats.lmc_cardtype = sc->lmc_cardtype; |
275 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
267 | ret = 0; | 276 | ret = 0; |
268 | break; | 277 | break; |
269 | 278 | ||
@@ -282,8 +291,10 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
282 | ret = -EFAULT; | 291 | ret = -EFAULT; |
283 | break; | 292 | break; |
284 | } | 293 | } |
294 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
285 | sc->lmc_media->set_circuit_type(sc, ctl.circuit_type); | 295 | sc->lmc_media->set_circuit_type(sc, ctl.circuit_type); |
286 | sc->ictl.circuit_type = ctl.circuit_type; | 296 | sc->ictl.circuit_type = ctl.circuit_type; |
297 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
287 | ret = 0; | 298 | ret = 0; |
288 | 299 | ||
289 | break; | 300 | break; |
@@ -294,12 +305,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
294 | break; | 305 | break; |
295 | } | 306 | } |
296 | 307 | ||
308 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
297 | /* Reset driver and bring back to current state */ | 309 | /* Reset driver and bring back to current state */ |
298 | printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); | 310 | printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); |
299 | lmc_running_reset (dev); | 311 | lmc_running_reset (dev); |
300 | printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); | 312 | printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16)); |
301 | 313 | ||
302 | LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16)); | 314 | LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16)); |
315 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
303 | 316 | ||
304 | ret = 0; | 317 | ret = 0; |
305 | break; | 318 | break; |
@@ -338,14 +351,15 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
338 | */ | 351 | */ |
339 | netif_stop_queue(dev); | 352 | netif_stop_queue(dev); |
340 | 353 | ||
341 | if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) { | 354 | if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) { |
342 | ret = -EFAULT; | 355 | ret = -EFAULT; |
343 | break; | 356 | break; |
344 | } | 357 | } |
345 | switch(xc.command){ | 358 | switch(xc.command){ |
346 | case lmc_xilinx_reset: /*fold02*/ | 359 | case lmc_xilinx_reset: /*fold02*/ |
347 | { | 360 | { |
348 | u16 mii; | 361 | u16 mii; |
362 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
349 | mii = lmc_mii_readreg (sc, 0, 16); | 363 | mii = lmc_mii_readreg (sc, 0, 16); |
350 | 364 | ||
351 | /* | 365 | /* |
@@ -404,6 +418,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
404 | lmc_led_off(sc, LMC_DS3_LED2); | 418 | lmc_led_off(sc, LMC_DS3_LED2); |
405 | } | 419 | } |
406 | } | 420 | } |
421 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
407 | 422 | ||
408 | 423 | ||
409 | 424 | ||
@@ -416,6 +431,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
416 | { | 431 | { |
417 | u16 mii; | 432 | u16 mii; |
418 | int timeout = 500000; | 433 | int timeout = 500000; |
434 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
419 | mii = lmc_mii_readreg (sc, 0, 16); | 435 | mii = lmc_mii_readreg (sc, 0, 16); |
420 | 436 | ||
421 | /* | 437 | /* |
@@ -451,13 +467,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
451 | */ | 467 | */ |
452 | while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && | 468 | while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && |
453 | (timeout-- > 0)) | 469 | (timeout-- > 0)) |
454 | ; | 470 | cpu_relax(); |
455 | 471 | ||
456 | 472 | ||
457 | /* | 473 | /* |
458 | * stop driving Xilinx-related signals | 474 | * stop driving Xilinx-related signals |
459 | */ | 475 | */ |
460 | lmc_gpio_mkinput(sc, 0xff); | 476 | lmc_gpio_mkinput(sc, 0xff); |
477 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
461 | 478 | ||
462 | ret = 0x0; | 479 | ret = 0x0; |
463 | 480 | ||
@@ -493,6 +510,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
493 | 510 | ||
494 | printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data); | 511 | printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data); |
495 | 512 | ||
513 | spin_lock_irqsave(&sc->lmc_lock, flags); | ||
496 | lmc_gpio_mkinput(sc, 0xff); | 514 | lmc_gpio_mkinput(sc, 0xff); |
497 | 515 | ||
498 | /* | 516 | /* |
@@ -545,7 +563,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
545 | */ | 563 | */ |
546 | while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && | 564 | while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 && |
547 | (timeout-- > 0)) | 565 | (timeout-- > 0)) |
548 | ; | 566 | cpu_relax(); |
549 | 567 | ||
550 | printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout); | 568 | printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout); |
551 | 569 | ||
@@ -588,6 +606,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
588 | 606 | ||
589 | sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET; | 607 | sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET; |
590 | lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); | 608 | lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16); |
609 | spin_unlock_irqrestore(&sc->lmc_lock, flags); | ||
591 | 610 | ||
592 | kfree(data); | 611 | kfree(data); |
593 | 612 | ||
@@ -611,8 +630,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ | |||
611 | break; | 630 | break; |
612 | } | 631 | } |
613 | 632 | ||
614 | spin_unlock_irqrestore(&sc->lmc_lock, flags); /*fold01*/ | ||
615 | |||
616 | lmc_trace(dev, "lmc_ioctl out"); | 633 | lmc_trace(dev, "lmc_ioctl out"); |
617 | 634 | ||
618 | return ret; | 635 | return ret; |