-static ssize_t copy_recv_mad(char __user *buf, struct ib_umad_packet *packet,
- size_t count)
-{
- struct ib_mad_recv_buf *recv_buf;
- int left, seg_payload, offset, max_seg_payload;
-
- /* We need enough room to copy the first (or only) MAD segment. */
- recv_buf = &packet->recv_wc->recv_buf;
- if ((packet->length <= sizeof (*recv_buf->mad) &&
- count < sizeof (packet->mad) + packet->length) ||
- (packet->length > sizeof (*recv_buf->mad) &&
- count < sizeof (packet->mad) + sizeof (*recv_buf->mad)))
- return -EINVAL;
-
- if (copy_to_user(buf, &packet->mad, sizeof (packet->mad)))
- return -EFAULT;
-
- buf += sizeof (packet->mad);
- seg_payload = min_t(int, packet->length, sizeof (*recv_buf->mad));
- if (copy_to_user(buf, recv_buf->mad, seg_payload))
- return -EFAULT;
-
- if (seg_payload < packet->length) {
- /*
- * Multipacket RMPP MAD message. Copy remainder of message.
- * Note that last segment may have a shorter payload.
- */
- if (count < sizeof (packet->mad) + packet->length) {
- /*
- * The buffer is too small, return the first RMPP segment,
- * which includes the RMPP message length.
- */
- return -ENOSPC;
- }
- offset = ib_get_mad_data_offset(recv_buf->mad->mad_hdr.mgmt_class);
- max_seg_payload = sizeof (struct ib_mad) - offset;
-
- for (left = packet->length - seg_payload, buf += seg_payload;
- left; left -= seg_payload, buf += seg_payload) {
- recv_buf = container_of(recv_buf->list.next,
- struct ib_mad_recv_buf, list);
- seg_payload = min(left, max_seg_payload);
- if (copy_to_user(buf, ((void *) recv_buf->mad) + offset,
- seg_payload))
- return -EFAULT;
- }
- }
- return sizeof (packet->mad) + packet->length;
-}
-
-static ssize_t copy_send_mad(char __user *buf, struct ib_umad_packet *packet,
- size_t count)
-{
- ssize_t size = sizeof (packet->mad) + packet->length;
-
- if (count < size)
- return -EINVAL;
-
- if (copy_to_user(buf, &packet->mad, size))
- return -EFAULT;
-
- return size;
-}
-