diff options
author | Bart Van Assche <bvanassche@acm.org> | 2014-05-20 09:05:21 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-05-20 12:20:51 -0400 |
commit | 76bc1e1ddd1ea8d4bc230fc0aa45c1d14c232531 (patch) | |
tree | 24fda49048ecdb2d43d6f1be704e1e63e54199e3 /drivers/infiniband/ulp/srp | |
parent | 62154b2e892807b8373a107c277f1fa8338f4333 (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.c | 77 |
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 | ||
1050 | static 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 | |||
1073 | backtrack: | ||
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 | |||
1050 | static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port *target, | 1092 | static 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 | |||
1128 | backtrack: | ||
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. |