@@ -1449,15 +1449,29 @@
if (cmd.wqe_size < sizeof (struct ib_uverbs_send_wr))
return -EINVAL;
+ qp = idr_read_qp(cmd.qp_handle, file->ucontext);
+ if (!qp)
+ goto out_raw_qp;
+
+ if (qp->qp_type == IB_QPT_RAW_ETH) {
+ resp.bad_wr = 0;
+ ret = qp->device->post_send(qp, NULL, NULL);
+ if (ret)
+ resp.bad_wr = cmd.wr_count;
+
+ if (copy_to_user((void __user *) (unsigned long)
+ cmd.response,
+ &resp,
+ sizeof resp))
+ ret = -EFAULT;
+ put_qp_read(qp);
+ goto out_raw_qp;
+ }
user_wr = kmalloc(cmd.wqe_size, GFP_KERNEL);
if (!user_wr)
return -ENOMEM;
- qp = idr_read_qp(cmd.qp_handle, file->ucontext);
- if (!qp)
- goto out;
-
is_ud = qp->qp_type == IB_QPT_UD;
sg_ind = 0;
last = NULL;
@@ -1577,9 +1591,8 @@
wr = next;
}
-out:
kfree(user_wr);
-
+out_raw_qp:
return ret ? ret : in_len;
}
@@ -1681,16 +1694,31 @@
if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT;
+ qp = idr_read_qp(cmd.qp_handle, file->ucontext);
+ if (!qp)
+ goto out_raw_qp;
+
+ if (qp->qp_type == IB_QPT_RAW_ETH) {
+ resp.bad_wr = 0;
+ ret = qp->device->post_recv(qp, NULL, NULL);
+ if (ret)
+ resp.bad_wr = cmd.wr_count;
+
+ if (copy_to_user((void __user *) (unsigned long)
+ cmd.response,
+ &resp,
+ sizeof resp))
+ ret = -EFAULT;
+ put_qp_read(qp);
+ goto out_raw_qp;
+ }
+
wr = ib_uverbs_unmarshall_recv(buf + sizeof cmd,
in_len - sizeof cmd, cmd.wr_count,
cmd.sge_count, cmd.wqe_size);
if (IS_ERR(wr))
return PTR_ERR(wr);
- qp = idr_read_qp(cmd.qp_handle, file->ucontext);
- if (!qp)
- goto out;
-
resp.bad_wr = 0;
ret = qp->device->post_recv(qp, wr, &bad_wr);
@@ -1707,13 +1735,13 @@
&resp, sizeof resp))
ret = -EFAULT;
-out:
while (wr) {
next = wr->next;
kfree(wr);
wr = next;
}
+out_raw_qp:
return ret ? ret : in_len;
}