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; |
