diff options
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 35 | ||||
-rw-r--r-- | drivers/infiniband/core/sysfs.c | 122 | ||||
-rw-r--r-- | drivers/infiniband/core/user_mad.c | 4 | ||||
-rw-r--r-- | drivers/infiniband/include/ib_sa.h | 4 |
4 files changed, 74 insertions, 91 deletions
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index d4233ee61c3..276e1a53010 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -587,7 +587,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, init_mad(query->sa_query.mad, agent); - query->sa_query.callback = ib_sa_path_rec_callback; + query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; query->sa_query.release = ib_sa_path_rec_release; query->sa_query.port = port; query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET; @@ -663,7 +663,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, init_mad(query->sa_query.mad, agent); - query->sa_query.callback = ib_sa_mcmember_rec_callback; + query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; query->sa_query.release = ib_sa_mcmember_rec_release; query->sa_query.port = port; query->sa_query.mad->mad_hdr.method = method; @@ -698,20 +698,21 @@ static void send_handler(struct ib_mad_agent *agent, if (!query) return; - switch (mad_send_wc->status) { - case IB_WC_SUCCESS: - /* No callback -- already got recv */ - break; - case IB_WC_RESP_TIMEOUT_ERR: - query->callback(query, -ETIMEDOUT, NULL); - break; - case IB_WC_WR_FLUSH_ERR: - query->callback(query, -EINTR, NULL); - break; - default: - query->callback(query, -EIO, NULL); - break; - } + if (query->callback) + switch (mad_send_wc->status) { + case IB_WC_SUCCESS: + /* No callback -- already got recv */ + break; + case IB_WC_RESP_TIMEOUT_ERR: + query->callback(query, -ETIMEDOUT, NULL); + break; + case IB_WC_WR_FLUSH_ERR: + query->callback(query, -EINTR, NULL); + break; + default: + query->callback(query, -EIO, NULL); + break; + } dma_unmap_single(agent->device->dma_device, pci_unmap_addr(query, mapping), @@ -736,7 +737,7 @@ static void recv_handler(struct ib_mad_agent *mad_agent, query = idr_find(&query_idr, mad_recv_wc->wc->wr_id); spin_unlock_irqrestore(&idr_lock, flags); - if (query) { + if (query && query->callback) { if (mad_recv_wc->wc->status == IB_WC_SUCCESS) query->callback(query, mad_recv_wc->recv_buf.mad->mad_hdr.status ? diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index 3a413f72ff6..90d51b179ab 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -40,9 +40,7 @@ struct ib_port { struct kobject kobj; struct ib_device *ibdev; struct attribute_group gid_group; - struct attribute **gid_attr; struct attribute_group pkey_group; - struct attribute **pkey_attr; u8 port_num; }; @@ -60,8 +58,9 @@ struct port_attribute port_attr_##_name = __ATTR(_name, _mode, _show, _store) struct port_attribute port_attr_##_name = __ATTR_RO(_name) struct port_table_attribute { - struct port_attribute attr; - int index; + struct port_attribute attr; + char name[8]; + int index; }; static ssize_t port_attr_show(struct kobject *kobj, @@ -72,7 +71,7 @@ static ssize_t port_attr_show(struct kobject *kobj, struct ib_port *p = container_of(kobj, struct ib_port, kobj); if (!port_attr->show) - return 0; + return -EIO; return port_attr->show(p, port_attr, buf); } @@ -398,17 +397,16 @@ static void ib_port_release(struct kobject *kobj) struct attribute *a; int i; - for (i = 0; (a = p->gid_attr[i]); ++i) { - kfree(a->name); + for (i = 0; (a = p->gid_group.attrs[i]); ++i) kfree(a); - } - for (i = 0; (a = p->pkey_attr[i]); ++i) { - kfree(a->name); + kfree(p->gid_group.attrs); + + for (i = 0; (a = p->pkey_group.attrs[i]); ++i) kfree(a); - } - kfree(p->gid_attr); + kfree(p->pkey_group.attrs); + kfree(p); } @@ -449,58 +447,45 @@ static int ib_device_hotplug(struct class_device *cdev, char **envp, return 0; } -static int alloc_group(struct attribute ***attr, - ssize_t (*show)(struct ib_port *, - struct port_attribute *, char *buf), - int len) +static struct attribute ** +alloc_group_attrs(ssize_t (*show)(struct ib_port *, + struct port_attribute *, char *buf), + int len) { - struct port_table_attribute ***tab_attr = - (struct port_table_attribute ***) attr; + struct attribute **tab_attr; + struct port_table_attribute *element; int i; - int ret; - - *tab_attr = kmalloc((1 + len) * sizeof *tab_attr, GFP_KERNEL); - if (!*tab_attr) - return -ENOMEM; - memset(*tab_attr, 0, (1 + len) * sizeof *tab_attr); + tab_attr = kcalloc(1 + len, sizeof(struct attribute *), GFP_KERNEL); + if (!tab_attr) + return NULL; - for (i = 0; i < len; ++i) { - (*tab_attr)[i] = kmalloc(sizeof *(*tab_attr)[i], GFP_KERNEL); - if (!(*tab_attr)[i]) { - ret = -ENOMEM; + for (i = 0; i < len; i++) { + element = kcalloc(1, sizeof(struct port_table_attribute), + GFP_KERNEL); + if (!element) goto err; - } - memset((*tab_attr)[i], 0, sizeof *(*tab_attr)[i]); - (*tab_attr)[i]->attr.attr.name = kmalloc(8, GFP_KERNEL); - if (!(*tab_attr)[i]->attr.attr.name) { - ret = -ENOMEM; - goto err; - } - if (snprintf((*tab_attr)[i]->attr.attr.name, 8, "%d", i) >= 8) { - ret = -ENOMEM; + if (snprintf(element->name, sizeof(element->name), + "%d", i) >= sizeof(element->name)) goto err; - } - (*tab_attr)[i]->attr.attr.mode = S_IRUGO; - (*tab_attr)[i]->attr.attr.owner = THIS_MODULE; - (*tab_attr)[i]->attr.show = show; - (*tab_attr)[i]->index = i; - } - - return 0; + element->attr.attr.name = element->name; + element->attr.attr.mode = S_IRUGO; + element->attr.attr.owner = THIS_MODULE; + element->attr.show = show; + element->index = i; -err: - for (i = 0; i < len; ++i) { - if ((*tab_attr)[i]) - kfree((*tab_attr)[i]->attr.attr.name); - kfree((*tab_attr)[i]); + tab_attr[i] = &element->attr.attr; } - kfree(*tab_attr); + return tab_attr; - return ret; +err: + while (--i >= 0) + kfree(tab_attr[i]); + kfree(tab_attr); + return NULL; } static int add_port(struct ib_device *device, int port_num) @@ -541,23 +526,20 @@ static int add_port(struct ib_device *device, int port_num) if (ret) goto err_put; - ret = alloc_group(&p->gid_attr, show_port_gid, attr.gid_tbl_len); - if (ret) - goto err_remove_pma; - p->gid_group.name = "gids"; - p->gid_group.attrs = p->gid_attr; + p->gid_group.attrs = alloc_group_attrs(show_port_gid, attr.gid_tbl_len); + if (!p->gid_group.attrs) + goto err_remove_pma; ret = sysfs_create_group(&p->kobj, &p->gid_group); if (ret) goto err_free_gid; - ret = alloc_group(&p->pkey_attr, show_port_pkey, attr.pkey_tbl_len); - if (ret) - goto err_remove_gid; - p->pkey_group.name = "pkeys"; - p->pkey_group.attrs = p->pkey_attr; + p->pkey_group.attrs = alloc_group_attrs(show_port_pkey, + attr.pkey_tbl_len); + if (!p->pkey_group.attrs) + goto err_remove_gid; ret = sysfs_create_group(&p->kobj, &p->pkey_group); if (ret) @@ -568,23 +550,19 @@ static int add_port(struct ib_device *device, int port_num) return 0; err_free_pkey: - for (i = 0; i < attr.pkey_tbl_len; ++i) { - kfree(p->pkey_attr[i]->name); - kfree(p->pkey_attr[i]); - } + for (i = 0; i < attr.pkey_tbl_len; ++i) + kfree(p->pkey_group.attrs[i]); - kfree(p->pkey_attr); + kfree(p->pkey_group.attrs); err_remove_gid: sysfs_remove_group(&p->kobj, &p->gid_group); err_free_gid: - for (i = 0; i < attr.gid_tbl_len; ++i) { - kfree(p->gid_attr[i]->name); - kfree(p->gid_attr[i]); - } + for (i = 0; i < attr.gid_tbl_len; ++i) + kfree(p->gid_group.attrs[i]); - kfree(p->gid_attr); + kfree(p->gid_group.attrs); err_remove_pma: sysfs_remove_group(&p->kobj, &pma_group); diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 56b9c2fa2ec..9d912d6877f 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -499,6 +499,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) static int ib_umad_close(struct inode *inode, struct file *filp) { struct ib_umad_file *file = filp->private_data; + struct ib_umad_packet *packet, *tmp; int i; for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) @@ -507,6 +508,9 @@ static int ib_umad_close(struct inode *inode, struct file *filp) ib_unregister_mad_agent(file->agent[i]); } + list_for_each_entry_safe(packet, tmp, &file->recv_list, list) + kfree(packet); + kfree(file); return 0; diff --git a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h index f4f747707b3..00222285eb9 100644 --- a/drivers/infiniband/include/ib_sa.h +++ b/drivers/infiniband/include/ib_sa.h @@ -147,7 +147,7 @@ struct ib_sa_path_rec { /* reserved */ u8 sl; u8 mtu_selector; - enum ib_mtu mtu; + u8 mtu; u8 rate_selector; u8 rate; u8 packet_life_time_selector; @@ -180,7 +180,7 @@ struct ib_sa_mcmember_rec { u32 qkey; u16 mlid; u8 mtu_selector; - enum ib_mtu mtu; + u8 mtu; u8 traffic_class; u16 pkey; u8 rate_selector; |