Skip to content

Commit

Permalink
providers: Use the new match_device and allocate_device ops
Browse files Browse the repository at this point in the history
This is the first step to simplify the provider binding process.

Checking of the ABI version is hoisted into the core code, as are some
of the common error messages.

Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Acked-by: Ram Amrani <Ram.Amrani@cavium.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
  • Loading branch information
jgunthorpe authored and rleon committed Sep 28, 2017
1 parent 36c8b58 commit 516b8d4
Show file tree
Hide file tree
Showing 15 changed files with 313 additions and 337 deletions.
36 changes: 17 additions & 19 deletions providers/bnxt_re/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,43 +174,38 @@ static void bnxt_re_uninit_context(struct verbs_device *vdev,
}
}

static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,
int abi_version)
static bool bnxt_re_device_match(struct verbs_sysfs_dev *sysfs_dev)
{
const char *uverbs_sys_path = sysfs_dev->sysfs_path;
char value[10];
struct bnxt_re_dev *dev;
unsigned int vendor, device;
int i;

if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
value, sizeof(value)) < 0)
return NULL;
return false;
vendor = strtol(value, NULL, 16);

if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
value, sizeof(value)) < 0)
return NULL;
return false;
device = strtol(value, NULL, 16);

for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i)
if (vendor == cna_table[i].vendor &&
device == cna_table[i].device)
goto found;
return NULL;
found:
if (abi_version != BNXT_RE_ABI_VERSION) {
fprintf(stderr, DEV "FATAL: Max supported ABI of %s is %d "
"check for the latest version of kernel driver and"
"user library\n", uverbs_sys_path, abi_version);
return NULL;
}
return true;
return false;
}

static struct verbs_device *
bnxt_re_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
{
struct bnxt_re_dev *dev;

dev = calloc(1, sizeof(*dev));
if (!dev) {
fprintf(stderr, DEV "Failed to allocate device for %s\n",
uverbs_sys_path);
if (!dev)
return NULL;
}

dev->vdev.sz = sizeof(*dev);
dev->vdev.size_of_context =
Expand All @@ -221,7 +216,10 @@ static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path,

static const struct verbs_device_ops bnxt_re_dev_ops = {
.name = "bnxt_re",
.init_device = bnxt_re_driver_init,
.match_min_abi_version = BNXT_RE_ABI_VERSION,
.match_max_abi_version = BNXT_RE_ABI_VERSION,
.match_device = bnxt_re_device_match,
.alloc_device = bnxt_re_device_alloc,
.init_context = bnxt_re_init_context,
.uninit_context = bnxt_re_uninit_context,
};
Expand Down
60 changes: 27 additions & 33 deletions providers/cxgb3/iwch.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
.device = PCI_DEVICE_ID_CHELSIO_##d, \
.type = CHELSIO_##t }

static struct {
static struct hca_ent {
unsigned vendor;
unsigned device;
enum iwch_hca_type type;
Expand Down Expand Up @@ -173,46 +173,41 @@ static void iwch_uninit_device(struct verbs_device *verbs_device)
free(dev);
}

static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
int abi_version)
static bool iwch_device_match(struct verbs_sysfs_dev *sysfs_dev)
{
char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
struct iwch_device *dev;
const char *uverbs_sys_path = sysfs_dev->sysfs_path;
char value[32], *cp;
unsigned vendor, device, fw_maj, fw_min;
int i;

if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &vendor);

if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &device);

for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
if (vendor == hca_table[i].vendor &&
device == hca_table[i].device)
device == hca_table[i].device) {
sysfs_dev->provider_data = &hca_table[i];
goto found;
}

return NULL;
return false;

found:

/*
* Verify that the firmware major number matches. Major number
* mismatches are fatal. Minor number mismatches are tolerated.
*/
if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
ibdev, sizeof ibdev) < 0)
return NULL;

memset(devstr, 0, sizeof devstr);
snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s",
ibv_get_sysfs_path(), ibdev);
if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
return NULL;
if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
sizeof(value)) < 0)
return false;

cp = strtok(value+1, ".");
sscanf(cp, "%i", &fw_maj);
Expand All @@ -224,7 +219,7 @@ static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
"Firmware major number is %u and libcxgb3 needs %u.\n",
fw_maj, FW_MAJ);
fflush(stderr);
return NULL;
return false;
}

DBGLOG("libcxgb3");
Expand All @@ -236,25 +231,21 @@ static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,
fflush(stderr);
}

if (abi_version > ABI_VERS) {
PDBG("libcxgb3: ABI version mismatch. "
"Kernel driver ABI is %u and libcxgb3 needs <= %u.\n",
abi_version, ABI_VERS);
fflush(stderr);
return NULL;
}
return true;
}

PDBG("%s found vendor %d device %d type %d\n",
__FUNCTION__, vendor, device, hca_table[i].type);
static struct verbs_device *iwch_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
{
struct iwch_device *dev;
struct hca_ent *hca_ent = sysfs_dev->provider_data;

dev = calloc(1, sizeof(*dev));
if (!dev) {
if (!dev)
return NULL;
}

pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
dev->hca_type = hca_table[i].type;
dev->abi_version = abi_version;
dev->hca_type = hca_ent->type;
dev->abi_version = sysfs_dev->abi_ver;

iwch_page_size = sysconf(_SC_PAGESIZE);
iwch_page_shift = long_log2(iwch_page_size);
Expand Down Expand Up @@ -285,7 +276,10 @@ static struct verbs_device *cxgb3_driver_init(const char *uverbs_sys_path,

static const struct verbs_device_ops iwch_dev_ops = {
.name = "cxgb3",
.init_device = cxgb3_driver_init,
.match_min_abi_version = 0,
.match_max_abi_version = ABI_VERS,
.match_device = iwch_device_match,
.alloc_device = iwch_device_alloc,
.uninit_device = iwch_uninit_device,
.alloc_context = iwch_alloc_context,
.free_context = iwch_free_context,
Expand Down
56 changes: 28 additions & 28 deletions providers/cxgb4/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
* Macros needed to support the PCI Device ID Table ...
*/
#define CH_PCI_DEVICE_ID_TABLE_DEFINE_BEGIN \
static struct { \
static struct hca_ent { \
unsigned vendor; \
unsigned device; \
} hca_table[] = {
Expand Down Expand Up @@ -399,47 +399,40 @@ void dump_state(void)
*/
int c4iw_abi_version = 1;

static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,
int abi_version)
static bool c4iw_device_match(struct verbs_sysfs_dev *sysfs_dev)
{
char devstr[IBV_SYSFS_PATH_MAX], ibdev[16], value[32], *cp;
struct c4iw_dev *dev;
const char *uverbs_sys_path = sysfs_dev->sysfs_path;
char value[32], *cp;
unsigned vendor, device, fw_maj, fw_min;
int i;

if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &vendor);

if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &device);

for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
if (vendor == hca_table[i].vendor &&
device == hca_table[i].device)
device == hca_table[i].device) {
sysfs_dev->provider_data = &hca_table[i];
goto found;
}

return NULL;
return false;

found:
c4iw_abi_version = abi_version;

/*
* Verify that the firmware major number matches. Major number
* mismatches are fatal. Minor number mismatches are tolerated.
*/
if (ibv_read_sysfs_file(uverbs_sys_path, "ibdev",
ibdev, sizeof ibdev) < 0)
return NULL;

memset(devstr, 0, sizeof devstr);
snprintf(devstr, sizeof devstr, "%s/class/infiniband/%s",
ibv_get_sysfs_path(), ibdev);
if (ibv_read_sysfs_file(devstr, "fw_ver", value, sizeof value) < 0)
return NULL;
if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "fw_ver", value,
sizeof(value)) < 0)
return false;

cp = strtok(value+1, ".");
sscanf(cp, "%i", &fw_maj);
Expand All @@ -451,7 +444,7 @@ static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,
"Firmware major number is %u and libcxgb4 needs %u.\n",
fw_maj, FW_MAJ);
fflush(stderr);
return NULL;
return false;
}

DBGLOG("libcxgb4");
Expand All @@ -462,22 +455,26 @@ static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,
fw_min, FW_MIN);
fflush(stderr);
}
return true;
}

PDBG("%s found vendor %d device %d type %d\n",
__FUNCTION__, vendor, device, CHELSIO_CHIP_VERSION(hca_table[i].device >> 8));
static struct verbs_device *c4iw_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
{
struct c4iw_dev *dev;
struct hca_ent *hca_ent = sysfs_dev->provider_data;

c4iw_page_size = sysconf(_SC_PAGESIZE);
c4iw_page_shift = long_log2(c4iw_page_size);
c4iw_page_mask = ~(c4iw_page_size - 1);

dev = calloc(1, sizeof *dev);
if (!dev) {
if (!dev)
return NULL;
}

pthread_spin_init(&dev->lock, PTHREAD_PROCESS_PRIVATE);
dev->chip_version = CHELSIO_CHIP_VERSION(hca_table[i].device >> 8);
dev->abi_version = abi_version;
c4iw_abi_version = sysfs_dev->abi_ver;
dev->chip_version = CHELSIO_CHIP_VERSION(hca_ent->device >> 8);
dev->abi_version = sysfs_dev->abi_ver;
list_node_init(&dev->list);

PDBG("%s device claimed\n", __FUNCTION__);
Expand Down Expand Up @@ -514,7 +511,10 @@ static struct verbs_device *cxgb4_driver_init(const char *uverbs_sys_path,

static const struct verbs_device_ops c4iw_dev_ops = {
.name = "cxgb4",
.init_device = cxgb4_driver_init,
.match_min_abi_version = 0,
.match_max_abi_version = INT_MAX,
.match_device = c4iw_device_match,
.alloc_device = c4iw_device_alloc,
.uninit_device = c4iw_uninit_device,
.alloc_context = c4iw_alloc_context,
.free_context = c4iw_free_context,
Expand Down
31 changes: 17 additions & 14 deletions providers/hfi1verbs/hfiverbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,47 +180,50 @@ static void hf11_uninit_device(struct verbs_device *verbs_device)
free(dev);
}

static struct verbs_device *hfi1_driver_init(const char *uverbs_sys_path,
int abi_version)
static bool hfi1_device_match(struct verbs_sysfs_dev *sysfs_dev)
{
const char *uverbs_sys_path = sysfs_dev->sysfs_path;
char value[8];
struct hfi1_device *dev;
unsigned vendor, device;
int i;

if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &vendor);

if (ibv_read_sysfs_file(uverbs_sys_path, "device/device",
value, sizeof value) < 0)
return NULL;
return false;
sscanf(value, "%i", &device);

for (i = 0; i < sizeof hca_table / sizeof hca_table[0]; ++i)
if (vendor == hca_table[i].vendor &&
device == hca_table[i].device)
goto found;
return true;

return NULL;
return false;
}

static struct verbs_device *hfi1_device_alloc(struct verbs_sysfs_dev *sysfs_dev)
{
struct hfi1_device *dev;

found:
dev = calloc(1, sizeof(*dev));
if (!dev) {
fprintf(stderr, PFX "Fatal: couldn't allocate device for %s\n",
uverbs_sys_path);
if (!dev)
return NULL;
}

dev->abi_version = abi_version;
dev->abi_version = sysfs_dev->abi_ver;

return &dev->ibv_dev;
}

static const struct verbs_device_ops hfi1_dev_ops = {
.name = "hfi1verbs",
.init_device = hfi1_driver_init,
.match_min_abi_version = 0,
.match_max_abi_version = INT_MAX,
.match_device = hfi1_device_match,
.alloc_device = hfi1_device_alloc,
.uninit_device = hf11_uninit_device,
.alloc_context = hfi1_alloc_context,
.free_context = hfi1_free_context,
Expand Down

0 comments on commit 516b8d4

Please sign in to comment.