Skip to content

Commit

Permalink
IB/ehca: Fix device registration
Browse files Browse the repository at this point in the history
Move the call to ib_register_device() later, since a device should not
be registered until it is completely read to be used.  This fixes
crashes that occur if an upper-layer driver such as IPoIB is loaded
before the ehca module.

Signed-off-by: Hoang-Nam Nguyen <hnguyen@de.ibm.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Hoang-Nam Nguyen authored and Roland Dreier committed Oct 2, 2006
1 parent 13b18c8 commit 0f248d9
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions drivers/infiniband/hw/ehca/ehca_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
MODULE_VERSION("SVNEHCA_0016");
MODULE_VERSION("SVNEHCA_0017");

int ehca_open_aqp1 = 0;
int ehca_debug_level = 0;
Expand Down Expand Up @@ -239,7 +239,7 @@ static int init_node_guid(struct ehca_shca *shca)
return ret;
}

int ehca_register_device(struct ehca_shca *shca)
int ehca_init_device(struct ehca_shca *shca)
{
int ret;

Expand Down Expand Up @@ -317,11 +317,6 @@ int ehca_register_device(struct ehca_shca *shca)
/* shca->ib_device.process_mad = ehca_process_mad; */
shca->ib_device.mmap = ehca_mmap;

ret = ib_register_device(&shca->ib_device);
if (ret)
ehca_err(&shca->ib_device,
"ib_register_device() failed ret=%x", ret);

return ret;
}

Expand Down Expand Up @@ -561,17 +556,17 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe1;
}

ret = ehca_register_device(shca);
ret = ehca_init_device(shca);
if (ret) {
ehca_gen_err("Cannot register Infiniband device");
ehca_gen_err("Cannot init ehca device struct");
goto probe1;
}

/* create event queues */
ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
if (ret) {
ehca_err(&shca->ib_device, "Cannot create EQ.");
goto probe2;
goto probe1;
}

ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
Expand Down Expand Up @@ -600,14 +595,21 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe5;
}

ret = ib_register_device(&shca->ib_device);
if (ret) {
ehca_err(&shca->ib_device,
"ib_register_device() failed ret=%x", ret);
goto probe6;
}

/* create AQP1 for port 1 */
if (ehca_open_aqp1 == 1) {
shca->sport[0].port_state = IB_PORT_DOWN;
ret = ehca_create_aqp1(shca, 1);
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 1.");
goto probe6;
goto probe7;
}
}

Expand All @@ -618,7 +620,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 2.");
goto probe7;
goto probe8;
}
}

Expand All @@ -630,12 +632,15 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,

return 0;

probe7:
probe8:
ret = ehca_destroy_aqp1(&shca->sport[0]);
if (ret)
ehca_err(&shca->ib_device,
"Cannot destroy AQP1 for port 1. ret=%x", ret);

probe7:
ib_unregister_device(&shca->ib_device);

probe6:
ret = ehca_dereg_internal_maxmr(shca);
if (ret)
Expand All @@ -660,9 +665,6 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
ehca_err(&shca->ib_device,
"Cannot destroy EQ. ret=%x", ret);

probe2:
ib_unregister_device(&shca->ib_device);

probe1:
ib_dealloc_device(&shca->ib_device);

Expand Down Expand Up @@ -750,7 +752,7 @@ int __init ehca_module_init(void)
int ret;

printk(KERN_INFO "eHCA Infiniband Device Driver "
"(Rel.: SVNEHCA_0016)\n");
"(Rel.: SVNEHCA_0017)\n");
idr_init(&ehca_qp_idr);
idr_init(&ehca_cq_idr);
spin_lock_init(&ehca_qp_idr_lock);
Expand Down

0 comments on commit 0f248d9

Please sign in to comment.