diff options
| author | Steve Wise <swise@opengridcomputing.com> | 2010-05-20 17:57:32 -0400 |
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2010-05-25 00:07:59 -0400 |
| commit | 1c01c5388306a4c2245b71da0cba22d521e897ae (patch) | |
| tree | 7e4fd41d4517df5d9fc6ae4075cbdb0df6ba0a0a | |
| parent | fd388ce677e7de9180a7d46d12c5162f76af64ac (diff) | |
RDMA/cxgb4: Register RDMA provider based on LLD state_change events
The LLD now supports proper UP state change events, so move the RDMA
provider registration to UP path.
This fixes a crash when loading iw_cxgb4 _after_ the NFS/RDMA
transport is up and running.
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/device.c | 46 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 | ||||
| -rw-r--r-- | drivers/infiniband/hw/cxgb4/provider.c | 2 |
3 files changed, 39 insertions, 10 deletions
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index c7e2484e7219..d870f9c17c1e 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c | |||
| @@ -306,7 +306,8 @@ static void c4iw_remove(struct c4iw_dev *dev) | |||
| 306 | PDBG("%s c4iw_dev %p\n", __func__, dev); | 306 | PDBG("%s c4iw_dev %p\n", __func__, dev); |
| 307 | cancel_delayed_work_sync(&dev->db_drop_task); | 307 | cancel_delayed_work_sync(&dev->db_drop_task); |
| 308 | list_del(&dev->entry); | 308 | list_del(&dev->entry); |
| 309 | c4iw_unregister_device(dev); | 309 | if (dev->registered) |
| 310 | c4iw_unregister_device(dev); | ||
| 310 | c4iw_rdev_close(&dev->rdev); | 311 | c4iw_rdev_close(&dev->rdev); |
| 311 | idr_destroy(&dev->cqidr); | 312 | idr_destroy(&dev->cqidr); |
| 312 | idr_destroy(&dev->qpidr); | 313 | idr_destroy(&dev->qpidr); |
| @@ -343,12 +344,6 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) | |||
| 343 | list_add_tail(&devp->entry, &dev_list); | 344 | list_add_tail(&devp->entry, &dev_list); |
| 344 | mutex_unlock(&dev_mutex); | 345 | mutex_unlock(&dev_mutex); |
| 345 | 346 | ||
| 346 | if (c4iw_register_device(devp)) { | ||
| 347 | printk(KERN_ERR MOD "Unable to register device\n"); | ||
| 348 | mutex_lock(&dev_mutex); | ||
| 349 | c4iw_remove(devp); | ||
| 350 | mutex_unlock(&dev_mutex); | ||
| 351 | } | ||
| 352 | if (c4iw_debugfs_root) { | 347 | if (c4iw_debugfs_root) { |
| 353 | devp->debugfs_root = debugfs_create_dir( | 348 | devp->debugfs_root = debugfs_create_dir( |
| 354 | pci_name(devp->rdev.lldi.pdev), | 349 | pci_name(devp->rdev.lldi.pdev), |
| @@ -379,9 +374,6 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) | |||
| 379 | 374 | ||
| 380 | for (i = 0; i < dev->rdev.lldi.nrxq; i++) | 375 | for (i = 0; i < dev->rdev.lldi.nrxq; i++) |
| 381 | PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]); | 376 | PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]); |
| 382 | |||
| 383 | printk(KERN_INFO MOD "Initialized device %s\n", | ||
| 384 | pci_name(dev->rdev.lldi.pdev)); | ||
| 385 | out: | 377 | out: |
| 386 | return dev; | 378 | return dev; |
| 387 | } | 379 | } |
| @@ -471,7 +463,41 @@ nomem: | |||
| 471 | 463 | ||
| 472 | static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) | 464 | static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state) |
| 473 | { | 465 | { |
| 466 | struct c4iw_dev *dev = handle; | ||
| 467 | |||
| 474 | PDBG("%s new_state %u\n", __func__, new_state); | 468 | PDBG("%s new_state %u\n", __func__, new_state); |
| 469 | switch (new_state) { | ||
| 470 | case CXGB4_STATE_UP: | ||
| 471 | printk(KERN_INFO MOD "%s: Up\n", pci_name(dev->rdev.lldi.pdev)); | ||
| 472 | if (!dev->registered) { | ||
| 473 | int ret; | ||
| 474 | ret = c4iw_register_device(dev); | ||
| 475 | if (ret) | ||
| 476 | printk(KERN_ERR MOD | ||
| 477 | "%s: RDMA registration failed: %d\n", | ||
| 478 | pci_name(dev->rdev.lldi.pdev), ret); | ||
| 479 | } | ||
| 480 | break; | ||
| 481 | case CXGB4_STATE_DOWN: | ||
| 482 | printk(KERN_INFO MOD "%s: Down\n", | ||
| 483 | pci_name(dev->rdev.lldi.pdev)); | ||
| 484 | if (dev->registered) | ||
| 485 | c4iw_unregister_device(dev); | ||
| 486 | break; | ||
| 487 | case CXGB4_STATE_START_RECOVERY: | ||
| 488 | printk(KERN_INFO MOD "%s: Fatal Error\n", | ||
| 489 | pci_name(dev->rdev.lldi.pdev)); | ||
| 490 | if (dev->registered) | ||
| 491 | c4iw_unregister_device(dev); | ||
| 492 | break; | ||
| 493 | case CXGB4_STATE_DETACH: | ||
| 494 | printk(KERN_INFO MOD "%s: Detach\n", | ||
| 495 | pci_name(dev->rdev.lldi.pdev)); | ||
| 496 | mutex_lock(&dev_mutex); | ||
| 497 | c4iw_remove(dev); | ||
| 498 | mutex_unlock(&dev_mutex); | ||
| 499 | break; | ||
| 500 | } | ||
| 475 | return 0; | 501 | return 0; |
| 476 | } | 502 | } |
| 477 | 503 | ||
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index a6269981e815..277ab589b44d 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h | |||
| @@ -152,6 +152,7 @@ struct c4iw_dev { | |||
| 152 | struct list_head entry; | 152 | struct list_head entry; |
| 153 | struct delayed_work db_drop_task; | 153 | struct delayed_work db_drop_task; |
| 154 | struct dentry *debugfs_root; | 154 | struct dentry *debugfs_root; |
| 155 | u8 registered; | ||
| 155 | }; | 156 | }; |
| 156 | 157 | ||
| 157 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) | 158 | static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev) |
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index dfc49020bb9c..322134bb8b73 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c | |||
| @@ -496,6 +496,7 @@ int c4iw_register_device(struct c4iw_dev *dev) | |||
| 496 | if (ret) | 496 | if (ret) |
| 497 | goto bail2; | 497 | goto bail2; |
| 498 | } | 498 | } |
| 499 | dev->registered = 1; | ||
| 499 | return 0; | 500 | return 0; |
| 500 | bail2: | 501 | bail2: |
| 501 | ib_unregister_device(&dev->ibdev); | 502 | ib_unregister_device(&dev->ibdev); |
| @@ -514,5 +515,6 @@ void c4iw_unregister_device(struct c4iw_dev *dev) | |||
| 514 | c4iw_class_attributes[i]); | 515 | c4iw_class_attributes[i]); |
| 515 | ib_unregister_device(&dev->ibdev); | 516 | ib_unregister_device(&dev->ibdev); |
| 516 | kfree(dev->ibdev.iwcm); | 517 | kfree(dev->ibdev.iwcm); |
| 518 | dev->registered = 0; | ||
| 517 | return; | 519 | return; |
| 518 | } | 520 | } |
