Commit a78b3371 authored by Linus Torvalds's avatar Linus Torvalds

Merge HEAD from master.kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git

parents 97c169a2 a4d61e84
EXTRA_CFLAGS += -Idrivers/infiniband/include
obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
ib_cm.o ib_umad.o ib_ucm.o
obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o
......
/*
* Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -40,7 +41,7 @@
#include <asm/bug.h>
#include <ib_smi.h>
#include <rdma/ib_smi.h>
#include "smi.h"
#include "agent_priv.h"
......
/*
* Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -32,12 +35,11 @@
* $Id: cache.c 1349 2004-12-16 21:09:43Z roland $
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <ib_cache.h>
#include <rdma/ib_cache.h>
#include "core_priv.h"
......
This diff is collapsed.
This diff is collapsed.
......@@ -38,7 +38,7 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <ib_verbs.h>
#include <rdma/ib_verbs.h>
int ib_device_register_sysfs(struct ib_device *device);
void ib_device_unregister_sysfs(struct ib_device *device);
......
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......
......@@ -39,7 +39,7 @@
#include <linux/jhash.h>
#include <linux/kthread.h>
#include <ib_fmr_pool.h>
#include <rdma/ib_fmr_pool.h>
#include "core_priv.h"
......@@ -334,6 +334,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
{
struct ib_pool_fmr *fmr;
struct ib_pool_fmr *tmp;
LIST_HEAD(fmr_list);
int i;
kthread_stop(pool->thread);
......@@ -341,6 +342,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
i = 0;
list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
if (fmr->remap_count) {
INIT_LIST_HEAD(&fmr_list);
list_add_tail(&fmr->fmr->list, &fmr_list);
ib_unmap_fmr(&fmr_list);
}
ib_dealloc_fmr(fmr->fmr);
list_del(&fmr->list);
kfree(fmr);
......
......@@ -693,7 +693,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
goto out;
}
build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index,
build_smp_wc(send_wr->wr_id, be16_to_cpu(smp->dr_slid),
send_wr->wr.ud.pkey_index,
send_wr->wr.ud.port_num, &mad_wc);
/* No GRH for DR SMP */
......@@ -1554,7 +1555,7 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv,
}
struct ib_mad_send_wr_private*
ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid)
ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid)
{
struct ib_mad_send_wr_private *mad_send_wr;
......@@ -1597,7 +1598,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
struct ib_mad_send_wr_private *mad_send_wr;
struct ib_mad_send_wc mad_send_wc;
unsigned long flags;
u64 tid;
__be64 tid;
INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
......@@ -2165,7 +2166,8 @@ static void local_completions(void *data)
* Defined behavior is to complete response
* before request
*/
build_smp_wc(local->wr_id, IB_LID_PERMISSIVE,
build_smp_wc(local->wr_id,
be16_to_cpu(IB_LID_PERMISSIVE),
0 /* pkey index */,
recv_mad_agent->agent.port_num, &wc);
......@@ -2294,7 +2296,7 @@ static void timeout_sends(void *data)
spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
}
static void ib_mad_thread_completion_handler(struct ib_cq *cq)
static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg)
{
struct ib_mad_port_private *port_priv = cq->cq_context;
......@@ -2574,8 +2576,7 @@ static int ib_mad_port_open(struct ib_device *device,
cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
port_priv->cq = ib_create_cq(port_priv->device,
(ib_comp_handler)
ib_mad_thread_completion_handler,
ib_mad_thread_completion_handler,
NULL, port_priv, cq_size);
if (IS_ERR(port_priv->cq)) {
printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n");
......
......@@ -40,8 +40,8 @@
#include <linux/pci.h>
#include <linux/kthread.h>
#include <linux/workqueue.h>
#include <ib_mad.h>
#include <ib_smi.h>
#include <rdma/ib_mad.h>
#include <rdma/ib_smi.h>
#define PFX "ib_mad: "
......@@ -121,7 +121,7 @@ struct ib_mad_send_wr_private {
struct ib_send_wr send_wr;
struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
u64 wr_id; /* client WR ID */
u64 tid;
__be64 tid;
unsigned long timeout;
int retries;
int retry;
......@@ -144,7 +144,7 @@ struct ib_mad_local_private {
struct ib_send_wr send_wr;
struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
u64 wr_id; /* client WR ID */
u64 tid;
__be64 tid;
};
struct ib_mad_mgmt_method_table {
......@@ -210,7 +210,7 @@ extern kmem_cache_t *ib_mad_cache;
int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr);
struct ib_mad_send_wr_private *
ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid);
ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid);
void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
struct ib_mad_send_wc *mad_send_wc);
......
This diff is collapsed.
/*
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -32,7 +33,7 @@
* $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
*/
#include <ib_pack.h>
#include <rdma/ib_pack.h>
static u64 value_read(int offset, int size, void *structure)
{
......
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -44,8 +44,8 @@
#include <linux/kref.h>
#include <linux/idr.h>
#include <ib_pack.h>
#include <ib_sa.h>
#include <rdma/ib_pack.h>
#include <rdma/ib_sa.h>
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand subnet administration query support");
......
/*
* Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004 Intel Corporation. All rights reserved.
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2004 Voltaire Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
* Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -36,7 +37,7 @@
* $Id: smi.c 1389 2004-12-27 22:56:47Z roland $
*/
#include <ib_smi.h>
#include <rdma/ib_smi.h>
#include "smi.h"
/*
......
/*
* Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -34,7 +36,7 @@
#include "core_priv.h"
#include <ib_mad.h>
#include <rdma/ib_mad.h>
struct ib_port {
struct kobject kobj;
......@@ -253,14 +255,14 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
return ret;
return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
be16_to_cpu(((u16 *) gid.raw)[0]),
be16_to_cpu(((u16 *) gid.raw)[1]),
be16_to_cpu(((u16 *) gid.raw)[2]),
be16_to_cpu(((u16 *) gid.raw)[3]),
be16_to_cpu(((u16 *) gid.raw)[4]),
be16_to_cpu(((u16 *) gid.raw)[5]),
be16_to_cpu(((u16 *) gid.raw)[6]),
be16_to_cpu(((u16 *) gid.raw)[7]));
be16_to_cpu(((__be16 *) gid.raw)[0]),
be16_to_cpu(((__be16 *) gid.raw)[1]),
be16_to_cpu(((__be16 *) gid.raw)[2]),
be16_to_cpu(((__be16 *) gid.raw)[3]),
be16_to_cpu(((__be16 *) gid.raw)[4]),
be16_to_cpu(((__be16 *) gid.raw)[5]),
be16_to_cpu(((__be16 *) gid.raw)[6]),
be16_to_cpu(((__be16 *) gid.raw)[7]));
}
static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
......@@ -332,11 +334,11 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
break;
case 16:
ret = sprintf(buf, "%u\n",
be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8)));
be16_to_cpup((__be16 *)(out_mad->data + 40 + offset / 8)));
break;
case 32:
ret = sprintf(buf, "%u\n",
be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8)));
be32_to_cpup((__be32 *)(out_mad->data + 40 + offset / 8)));
break;
default:
ret = 0;
......@@ -598,10 +600,10 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
return ret;
return sprintf(buf, "%04x:%04x:%04x:%04x\n",
be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]),
be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]),
be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]),
be16_to_cpu(((u16 *) &attr.sys_image_guid)[3]));
be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
}
static ssize_t show_node_guid(struct class_device *cdev, char *buf)
......@@ -615,10 +617,10 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf)
return ret;
return sprintf(buf, "%04x:%04x:%04x:%04x\n",
be16_to_cpu(((u16 *) &attr.node_guid)[0]),
be16_to_cpu(((u16 *) &attr.node_guid)[1]),
be16_to_cpu(((u16 *) &attr.node_guid)[2]),
be16_to_cpu(((u16 *) &attr.node_guid)[3]));
be16_to_cpu(((__be16 *) &attr.node_guid)[0]),
be16_to_cpu(((__be16 *) &attr.node_guid)[1]),
be16_to_cpu(((__be16 *) &attr.node_guid)[2]),
be16_to_cpu(((__be16 *) &attr.node_guid)[3]));
}
static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
......
This diff is collapsed.
......@@ -40,17 +40,15 @@
#include <linux/cdev.h>
#include <linux/idr.h>
#include <ib_cm.h>
#include <ib_user_cm.h>
#include <rdma/ib_cm.h>
#include <rdma/ib_user_cm.h>
#define IB_UCM_CM_ID_INVALID 0xffffffff
struct ib_ucm_file {
struct semaphore mutex;
struct file *filp;
/*
* list of pending events
*/
struct list_head ctxs; /* list of active connections */
struct list_head events; /* list of pending events */
wait_queue_head_t poll_wait;
......@@ -58,12 +56,11 @@ struct ib_ucm_file {
struct ib_ucm_context {
int id;
int ref;
int error;
wait_queue_head_t wait;
atomic_t ref;
struct ib_ucm_file *file;
struct ib_cm_id *cm_id;
struct semaphore mutex;
struct list_head events; /* list of pending events. */
struct list_head file_list; /* member in file ctx list */
......
/*
* Copyright (c) 2004 Topspin Corporation. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -34,7 +35,7 @@
#include <linux/errno.h>
#include <ib_pack.h>
#include <rdma/ib_pack.h>
#define STRUCT_FIELD(header, field) \
.struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \
......@@ -194,6 +195,7 @@ void ib_ud_header_init(int payload_bytes,
struct ib_ud_header *header)
{
int header_len;
u16 packet_length;
memset(header, 0, sizeof *header);
......@@ -208,7 +210,7 @@ void ib_ud_header_init(int payload_bytes,
header->lrh.link_version = 0;
header->lrh.link_next_header =
grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
header->lrh.packet_length = (IB_LRH_BYTES +
packet_length = (IB_LRH_BYTES +
IB_BTH_BYTES +
IB_DETH_BYTES +
payload_bytes +
......@@ -217,8 +219,7 @@ void ib_ud_header_init(int payload_bytes,
header->grh_present = grh_present;
if (grh_present) {
header->lrh.packet_length += IB_GRH_BYTES / 4;
packet_length += IB_GRH_BYTES / 4;
header->grh.ip_version = 6;
header->grh.payload_length =
cpu_to_be16((IB_BTH_BYTES +
......@@ -229,7 +230,7 @@ void ib_ud_header_init(int payload_bytes,
header->grh.next_header = 0x1b;
}
cpu_to_be16s(&header->lrh.packet_length);
header->lrh.packet_length = cpu_to_be16(packet_length);
if (header->immediate_present)
header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
......
/*
* Copyright (c) 2004 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
* Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
......@@ -49,8 +49,8 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <ib_mad.h>
#include <ib_user_mad.h>
#include <rdma/ib_mad.h>
#include <rdma/ib_user_mad.h>
MODULE_AUTHOR("Roland Dreier");
MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
......@@ -271,7 +271,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
struct ib_send_wr *bad_wr;
struct ib_rmpp_mad *rmpp_mad;
u8 method;
u64 *tid;
__be64 *tid;
int ret, length, hdr_len, data_len, rmpp_hdr_size;
int rmpp_active = 0;
......@@ -316,7 +316,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
if (packet->mad.hdr.grh_present) {
ah_attr.ah_flags = IB_AH_GRH;
memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16);
ah_attr.grh.flow_label = packet->mad.hdr.flow_label;
ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label);
ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit;
ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class;
}
......
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Cisco Systems. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies. All rights reserved.
* Copyright (c) 2005 Voltaire, Inc. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
......@@ -43,8 +45,8 @@
#include <linux/kref.h>
#include <linux/idr.h>
#include <ib_verbs.h>
#include <ib_user_verbs.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_user_verbs.h>
struct ib_uverbs_device {
int devnum;
......@@ -97,10 +99,12 @@ extern struct idr ib_uverbs_mw_idr;
extern struct idr ib_uverbs_ah_idr;
extern struct idr ib_uverbs_cq_idr;
extern struct idr ib_uverbs_qp_idr;
extern struct idr ib_uverbs_srq_idr;
void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
void *addr, size_t size, int write);
......@@ -129,5 +133,8 @@ IB_UVERBS_DECLARE_CMD(modify_qp);
IB_UVERBS_DECLARE_CMD(destroy_qp);
IB_UVERBS_DECLARE_CMD(attach_mcast);
IB_UVERBS_DECLARE_CMD(detach_mcast);
IB_UVERBS_DECLARE_CMD(create_srq);
IB_UVERBS_DECLARE_CMD(modify_srq);
IB_UVERBS_DECLARE_CMD(destroy_srq);
#endif /* UVERBS_H */
......@@ -724,6 +724,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_cq *scq, *rcq;
struct ib_srq *srq;
struct ib_qp *qp;
struct ib_qp_init_attr attr;
int ret;
......@@ -747,10 +748,12 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL;
if (!pd || pd->uobject->context != file->ucontext ||
!scq || scq->uobject->context != file->ucontext ||
!rcq || rcq->uobject->context != file->ucontext) {
!rcq || rcq->uobject->context != file->ucontext ||
(cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
ret = -EINVAL;
goto err_up;
}
......@@ -759,7 +762,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
attr.qp_context = file;
attr.send_cq = scq;
attr.recv_cq = rcq;
attr.srq = NULL;
attr.srq = srq;
attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
attr.qp_type = cmd.qp_type;
......@@ -1004,3 +1007,178 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
return ret ? ret : in_len;
}
ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_create_srq cmd;
struct ib_uverbs_create_srq_resp resp;
struct ib_udata udata;
struct ib_uobject *uobj;
struct ib_pd *pd;
struct ib_srq *srq;
struct ib_srq_init_attr attr;
int ret;
if (out_len < sizeof resp)
return -ENOSPC;
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
INIT_UDATA(&udata, buf + sizeof cmd,
(unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp);
uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
if (!uobj)
return -ENOMEM;
down(&ib_uverbs_idr_mutex);
pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
if (!pd || pd->uobject->context != file->ucontext) {
ret = -EINVAL;
goto err_up;
}
attr.event_handler = ib_uverbs_srq_event_handler;
attr.srq_context = file;
attr.attr.max_wr = cmd.max_wr;
attr.attr.max_sge = cmd.max_sge;
attr.attr.srq_limit = cmd.srq_limit;
uobj->user_handle = cmd.user_handle;
uobj->context = file->ucontext;
srq = pd->device->create_srq(pd, &attr, &udata);
if (IS_ERR(srq)) {
ret = PTR_ERR(srq);
goto err_up;
}
srq->device = pd->device;
srq->pd = pd;
srq->uobject = uobj;
srq->event_handler = attr.event_handler;
srq->srq_context = attr.srq_context;
atomic_inc(&pd->usecnt);
atomic_set(&srq->usecnt, 0);
memset(&resp, 0, sizeof resp);
retry:
if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) {
ret = -ENOMEM;
goto err_destroy;
}
ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->id);
if (ret == -EAGAIN)
goto retry;
if (ret)
goto err_destroy;
resp.srq_handle = uobj->id;
spin_lock_irq(&file->ucontext->lock);
list_add_tail(&uobj->list, &file->ucontext->srq_list);
spin_unlock_irq(&file->ucontext->lock);
if (copy_to_user((void __user *) (unsigned long) cmd.response,
&resp, sizeof resp)) {
ret = -EFAULT;
goto err_list;
}
up(&ib_uverbs_idr_mutex);
return in_len;
err_list:
spin_lock_irq(&file->ucontext->lock);
list_del(&uobj->list);
spin_unlock_irq(&file->ucontext->lock);
err_destroy:
ib_destroy_srq(srq);
err_up:
up(&ib_uverbs_idr_mutex);
kfree(uobj);
return ret;
}
ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
const char __user *buf, int in_len,
int out_len)
{
struct ib_uverbs_modify_srq cmd;
struct ib_srq *srq<