- ret = ib_post_send_mad(agent, &wr, &bad_wr);
- if (ret) {
- dma_unmap_single(agent->device->dma_device,
- pci_unmap_addr(packet, mapping),
- sizeof packet->mad.data,
- DMA_TO_DEVICE);
- goto err_up;
+ if (!rmpp_active) {
+ /* Copy message from user into send buffer */
+ if (copy_from_user(packet->msg->mad,
+ buf + sizeof(struct ib_user_mad), length)) {
+ ret = -EFAULT;
+ goto err_msg;
+ }
+ } else {
+ rmpp_hdr_size = sizeof(struct ib_mad_hdr) +
+ sizeof(struct ib_rmpp_hdr);
+
+ /* Only copy MAD headers (RMPP header in place) */
+ memcpy(packet->msg->mad, packet->mad.data,
+ sizeof(struct ib_mad_hdr));
+
+ /* Now, copy rest of message from user into send buffer */
+ if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data,
+ buf + sizeof (struct ib_user_mad) + rmpp_hdr_size,
+ length - rmpp_hdr_size)) {
+ ret = -EFAULT;
+ goto err_msg;
+ }
+ }
+
+ /*
+ * If userspace is generating a request that will generate a
+ * response, we need to make sure the high-order part of the
+ * transaction ID matches the agent being used to send the
+ * MAD.
+ */
+ method = packet->msg->mad->mad_hdr.method;
+
+ if (!(method & IB_MGMT_METHOD_RESP) &&
+ method != IB_MGMT_METHOD_TRAP_REPRESS &&
+ method != IB_MGMT_METHOD_SEND) {
+ tid = &packet->msg->mad->mad_hdr.tid;
+ *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
+ (be64_to_cpup(tid) & 0xffffffff));