return 0;
 
 err_resource:
-       mlx4_free_resource_tracker(dev);
+       mlx4_free_resource_tracker(dev, RES_TR_FREE_ALL);
 err_thread:
        flush_workqueue(priv->mfunc.master.comm_wq);
        destroy_workqueue(priv->mfunc.master.comm_wq);
 
                        mlx4_CLOSE_PORT(dev, p);
                }
 
+               if (mlx4_is_master(dev))
+                       mlx4_free_resource_tracker(dev,
+                                                  RES_TR_FREE_SLAVES_ONLY);
+
                mlx4_cleanup_counters_table(dev);
                mlx4_cleanup_mcg_table(dev);
                mlx4_cleanup_qp_table(dev);
                mlx4_cleanup_pd_table(dev);
 
                if (mlx4_is_master(dev))
-                       mlx4_free_resource_tracker(dev);
+                       mlx4_free_resource_tracker(dev,
+                                                  RES_TR_FREE_STRUCTS_ONLY);
 
                iounmap(priv->kar);
                mlx4_uar_free(dev, &priv->driver_uar);
 
        RES_OP_MAP_ICM,
 };
 
+enum mlx4_res_tracker_free_type {
+       RES_TR_FREE_ALL,
+       RES_TR_FREE_SLAVES_ONLY,
+       RES_TR_FREE_STRUCTS_ONLY,
+};
 
 /*
  *Virtual HCR structures.
 void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave_id);
 int mlx4_init_resource_tracker(struct mlx4_dev *dev);
 
-void mlx4_free_resource_tracker(struct mlx4_dev *dev);
+void mlx4_free_resource_tracker(struct mlx4_dev *dev,
+                               enum mlx4_res_tracker_free_type type);
 
 int mlx4_SET_PORT_wrapper(struct mlx4_dev *dev, int slave,
                          struct mlx4_vhcr *vhcr,
 
        return 0 ;
 }
 
-void mlx4_free_resource_tracker(struct mlx4_dev *dev)
+void mlx4_free_resource_tracker(struct mlx4_dev *dev,
+                               enum mlx4_res_tracker_free_type type)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
        int i;
 
        if (priv->mfunc.master.res_tracker.slave_list) {
-               for (i = 0 ; i < dev->num_slaves; i++)
-                       mlx4_delete_all_resources_for_slave(dev, i);
-
-               kfree(priv->mfunc.master.res_tracker.slave_list);
+               if (type != RES_TR_FREE_STRUCTS_ONLY)
+                       for (i = 0 ; i < dev->num_slaves; i++)
+                               if (type == RES_TR_FREE_ALL ||
+                                   dev->caps.function != i)
+                                       mlx4_delete_all_resources_for_slave(dev, i);
+
+               if (type != RES_TR_FREE_SLAVES_ONLY) {
+                       kfree(priv->mfunc.master.res_tracker.slave_list);
+                       priv->mfunc.master.res_tracker.slave_list = NULL;
+               }
        }
 }