0001
0002
0003
0004
0005
0006 #ifndef SVC_RDMA_PCL_H
0007 #define SVC_RDMA_PCL_H
0008
0009 #include <linux/list.h>
0010
0011 struct svc_rdma_segment {
0012 u32 rs_handle;
0013 u32 rs_length;
0014 u64 rs_offset;
0015 };
0016
0017 struct svc_rdma_chunk {
0018 struct list_head ch_list;
0019
0020 u32 ch_position;
0021 u32 ch_length;
0022 u32 ch_payload_length;
0023
0024 u32 ch_segcount;
0025 struct svc_rdma_segment ch_segments[];
0026 };
0027
0028 struct svc_rdma_pcl {
0029 unsigned int cl_count;
0030 struct list_head cl_chunks;
0031 };
0032
0033
0034
0035
0036
0037
0038 static inline void pcl_init(struct svc_rdma_pcl *pcl)
0039 {
0040 INIT_LIST_HEAD(&pcl->cl_chunks);
0041 }
0042
0043
0044
0045
0046
0047
0048 static inline bool pcl_is_empty(const struct svc_rdma_pcl *pcl)
0049 {
0050 return list_empty(&pcl->cl_chunks);
0051 }
0052
0053
0054
0055
0056
0057
0058
0059 static inline struct svc_rdma_chunk *
0060 pcl_first_chunk(const struct svc_rdma_pcl *pcl)
0061 {
0062 if (pcl_is_empty(pcl))
0063 return NULL;
0064 return list_first_entry(&pcl->cl_chunks, struct svc_rdma_chunk,
0065 ch_list);
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075 static inline struct svc_rdma_chunk *
0076 pcl_next_chunk(const struct svc_rdma_pcl *pcl, struct svc_rdma_chunk *chunk)
0077 {
0078 if (list_is_last(&chunk->ch_list, &pcl->cl_chunks))
0079 return NULL;
0080 return list_next_entry(chunk, ch_list);
0081 }
0082
0083
0084
0085
0086
0087
0088 #define pcl_for_each_chunk(pos, pcl) \
0089 for (pos = list_first_entry(&(pcl)->cl_chunks, struct svc_rdma_chunk, ch_list); \
0090 &pos->ch_list != &(pcl)->cl_chunks; \
0091 pos = list_next_entry(pos, ch_list))
0092
0093
0094
0095
0096
0097
0098 #define pcl_for_each_segment(pos, chunk) \
0099 for (pos = &(chunk)->ch_segments[0]; \
0100 pos <= &(chunk)->ch_segments[(chunk)->ch_segcount - 1]; \
0101 pos++)
0102
0103
0104
0105
0106
0107
0108
0109 static inline unsigned int
0110 pcl_chunk_end_offset(const struct svc_rdma_chunk *chunk)
0111 {
0112 return xdr_align_size(chunk->ch_position + chunk->ch_payload_length);
0113 }
0114
0115 struct svc_rdma_recv_ctxt;
0116
0117 extern void pcl_free(struct svc_rdma_pcl *pcl);
0118 extern bool pcl_alloc_call(struct svc_rdma_recv_ctxt *rctxt, __be32 *p);
0119 extern bool pcl_alloc_read(struct svc_rdma_recv_ctxt *rctxt, __be32 *p);
0120 extern bool pcl_alloc_write(struct svc_rdma_recv_ctxt *rctxt,
0121 struct svc_rdma_pcl *pcl, __be32 *p);
0122 extern int pcl_process_nonpayloads(const struct svc_rdma_pcl *pcl,
0123 const struct xdr_buf *xdr,
0124 int (*actor)(const struct xdr_buf *,
0125 void *),
0126 void *data);
0127
0128 #endif