if ( ( rc = arbel_create_eq ( arbel ) ) != 0 )
goto err_create_eq;
+ /* Update MAD parameters */
+ for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ )
+ ib_smc_update ( arbel->ibdev[i], arbel_mad );
+
/* Register Infiniband devices */
for ( i = 0 ; i < ARBEL_NUM_PORTS ; i++ ) {
if ( ( rc = register_ibdev ( arbel->ibdev[i] ) ) != 0 ) {
if ( ( rc = hermon_create_eq ( hermon ) ) != 0 )
goto err_create_eq;
+ /* Update MAD parameters */
+ for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ )
+ ib_smc_update ( hermon->ibdev[i], hermon_mad );
+
/* Register Infiniband devices */
for ( i = 0 ; i < HERMON_NUM_PORTS ; i++ ) {
if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) {
struct ipoib_mac *mac = ( ( struct ipoib_mac * ) netdev->ll_addr );
int rc;
+ /* Open IB device */
+ if ( ( rc = ib_open ( ipoib->ibdev ) ) != 0 ) {
+ DBGC ( ipoib, "IPoIB %p could not open device: %s\n",
+ ipoib, strerror ( rc ) );
+ goto err_ib_open;
+ }
+
/* Allocate metadata queue set */
if ( ( rc = ipoib_create_qset ( ipoib, &ipoib->meta,
IPOIB_META_NUM_CQES,
err_create_data_qset:
ipoib_destroy_qset ( ipoib, &ipoib->meta );
err_create_meta_qset:
+ ib_close ( ipoib->ibdev );
+ err_ib_open:
return rc;
}
/* Tear down the queues */
ipoib_destroy_qset ( ipoib, &ipoib->data );
ipoib_destroy_qset ( ipoib, &ipoib->meta );
+
+ /* Close IB device */
+ ib_close ( ipoib->ibdev );
}
/** IPoIB network device operations */
struct ib_device_operations *op;
/** Port number */
unsigned int port;
+ /** Port open request counter */
+ unsigned int open_count;
/** Port state */
uint8_t port_state;
struct ib_queue_pair *qp,
struct ib_address_vector *av,
struct io_buffer *iobuf, int rc );
+extern int ib_open ( struct ib_device *ibdev );
+extern void ib_close ( struct ib_device *ibdev );
extern int ib_mcast_attach ( struct ib_device *ibdev, struct ib_queue_pair *qp,
struct ib_gid *gid );
extern void ib_mcast_detach ( struct ib_device *ibdev,
ibdev->op->poll_cq ( ibdev, cq );
}
-/**
- * Open port
- *
- * @v ibdev Infiniband device
- * @ret rc Return status code
- */
-static inline __always_inline int
-ib_open ( struct ib_device *ibdev ) {
- return ibdev->op->open ( ibdev );
-}
-
-/**
- * Close port
- *
- * @v ibdev Infiniband device
- */
-static inline __always_inline void
-ib_close ( struct ib_device *ibdev ) {
- ibdev->op->close ( ibdev );
-}
-
/**
* Check link state
*
qp->recv.fill--;
}
+/**
+ * Open port
+ *
+ * @v ibdev Infiniband device
+ * @ret rc Return status code
+ */
+int ib_open ( struct ib_device *ibdev ) {
+ int rc;
+
+ /* Open device if this is the first requested opening */
+ if ( ibdev->open_count == 0 ) {
+ if ( ( rc = ibdev->op->open ( ibdev ) ) != 0 )
+ return rc;
+ }
+
+ /* Increment device open request counter */
+ ibdev->open_count++;
+
+ return 0;
+}
+
+/**
+ * Close port
+ *
+ * @v ibdev Infiniband device
+ */
+void ib_close ( struct ib_device *ibdev ) {
+
+ /* Decrement device open request counter */
+ ibdev->open_count--;
+
+ /* Close device if this was the last remaining requested opening */
+ if ( ibdev->open_count == 0 )
+ ibdev->op->close ( ibdev );
+}
+
/**
* Attach to multicast group
*
ibdev_get ( ibdev );
list_add_tail ( &ibdev->list, &ib_devices );
- /* Open link */
- if ( ( rc = ib_open ( ibdev ) ) != 0 )
- goto err_open;
-
/* Add IPoIB device */
if ( ( rc = ipoib_probe ( ibdev ) ) != 0 ) {
DBGC ( ibdev, "IBDEV %p could not add IPoIB device: %s\n",
return 0;
err_ipoib_probe:
- ib_close ( ibdev );
- err_open:
list_del ( &ibdev->list );
ibdev_put ( ibdev );
return rc;
/* Close device */
ipoib_remove ( ibdev );
- ib_close ( ibdev );
/* Remove from device list */
list_del ( &ibdev->list );