aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/ulp/srp
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2014-05-20 09:05:21 -0400
committerRoland Dreier <roland@purestorage.com>2014-05-20 12:20:51 -0400
commit76bc1e1ddd1ea8d4bc230fc0aa45c1d14c232531 (patch)
tree24fda49048ecdb2d43d6f1be704e1e63e54199e3 /drivers/infiniband/ulp/srp
parent62154b2e892807b8373a107c277f1fa8338f4333 (diff)
IB/srp: Introduce srp_map_fmr()
This patch does not change any functionality. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/ulp/srp')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c77
1 files changed, 45 insertions, 32 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 281f78553061..be84c94aaeae 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1047,12 +1047,54 @@ static int srp_map_sg_entry(struct srp_map_state *state,
1047 return ret; 1047 return ret;
1048} 1048}
1049 1049
1050static void srp_map_fmr(struct srp_map_state *state,
1051 struct srp_target_port *target, struct srp_request *req,
1052 struct scatterlist *scat, int count)
1053{
1054 struct srp_device *dev = target->srp_host->srp_dev;
1055 struct ib_device *ibdev = dev->dev;
1056 struct scatterlist *sg;
1057 int i, use_fmr;
1058
1059 state->desc = req->indirect_desc;
1060 state->pages = req->map_page;
1061 state->next_fmr = req->fmr_list;
1062
1063 use_fmr = dev->fmr_pool ? SRP_MAP_ALLOW_FMR : SRP_MAP_NO_FMR;
1064
1065 for_each_sg(scat, sg, count, i) {
1066 if (srp_map_sg_entry(state, target, sg, i, use_fmr)) {
1067 /* FMR mapping failed, so backtrack to the first
1068 * unmapped entry and continue on without using FMR.
1069 */
1070 dma_addr_t dma_addr;
1071 unsigned int dma_len;
1072
1073backtrack:
1074 sg = state->unmapped_sg;
1075 i = state->unmapped_index;
1076
1077 dma_addr = ib_sg_dma_address(ibdev, sg);
1078 dma_len = ib_sg_dma_len(ibdev, sg);
1079 dma_len -= (state->unmapped_addr - dma_addr);
1080 dma_addr = state->unmapped_addr;
1081 use_fmr = SRP_MAP_NO_FMR;
1082 srp_map_desc(state, dma_addr, dma_len, target->rkey);
1083 }
1084 }
1085
1086 if (use_fmr == SRP_MAP_ALLOW_FMR && srp_map_finish_fmr(state, target))
1087 goto backtrack;
1088
1089 req->nfmr = state->nfmr;
1090}
1091
1050static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, 1092static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
1051 struct srp_request *req) 1093 struct srp_request *req)
1052{ 1094{
1053 struct scatterlist *scat, *sg; 1095 struct scatterlist *scat;
1054 struct srp_cmd *cmd = req->cmd->buf; 1096 struct srp_cmd *cmd = req->cmd->buf;
1055 int i, len, nents, count, use_fmr; 1097 int len, nents, count;
1056 struct srp_device *dev; 1098 struct srp_device *dev;
1057 struct ib_device *ibdev; 1099 struct ib_device *ibdev;
1058 struct srp_map_state state; 1100 struct srp_map_state state;
@@ -1111,35 +1153,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target,
1111 target->indirect_size, DMA_TO_DEVICE); 1153 target->indirect_size, DMA_TO_DEVICE);
1112 1154
1113 memset(&state, 0, sizeof(state)); 1155 memset(&state, 0, sizeof(state));
1114 state.desc = req->indirect_desc; 1156 srp_map_fmr(&state, target, req, scat, count);
1115 state.pages = req->map_page;
1116 state.next_fmr = req->fmr_list;
1117
1118 use_fmr = dev->fmr_pool ? SRP_MAP_ALLOW_FMR : SRP_MAP_NO_FMR;
1119
1120 for_each_sg(scat, sg, count, i) {
1121 if (srp_map_sg_entry(&state, target, sg, i, use_fmr)) {
1122 /* FMR mapping failed, so backtrack to the first
1123 * unmapped entry and continue on without using FMR.
1124 */
1125 dma_addr_t dma_addr;
1126 unsigned int dma_len;
1127
1128backtrack:
1129 sg = state.unmapped_sg;
1130 i = state.unmapped_index;
1131
1132 dma_addr = ib_sg_dma_address(ibdev, sg);
1133 dma_len = ib_sg_dma_len(ibdev, sg);
1134 dma_len -= (state.unmapped_addr - dma_addr);
1135 dma_addr = state.unmapped_addr;
1136 use_fmr = SRP_MAP_NO_FMR;
1137 srp_map_desc(&state, dma_addr, dma_len, target->rkey);
1138 }
1139 }
1140
1141 if (use_fmr == SRP_MAP_ALLOW_FMR && srp_map_finish_fmr(&state, target))
1142 goto backtrack;
1143 1157
1144 /* We've mapped the request, now pull as much of the indirect 1158 /* We've mapped the request, now pull as much of the indirect
1145 * descriptor table as we can into the command buffer. If this 1159 * descriptor table as we can into the command buffer. If this
@@ -1147,7 +1161,6 @@ backtrack:
1147 * guaranteed to fit into the command, as the SCSI layer won't 1161 * guaranteed to fit into the command, as the SCSI layer won't
1148 * give us more S/G entries than we allow. 1162 * give us more S/G entries than we allow.
1149 */ 1163 */
1150 req->nfmr = state.nfmr;
1151 if (state.ndesc == 1) { 1164 if (state.ndesc == 1) {
1152 /* FMR mapping was able to collapse this to one entry, 1165 /* FMR mapping was able to collapse this to one entry,
1153 * so use a direct descriptor. 1166 * so use a direct descriptor.