diff options
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 117 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 20 |
2 files changed, 48 insertions, 89 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index d5a6527b3b3d..aebcd5fcdc55 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -237,10 +237,10 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
237 | tcp_ctask->exp_datasn++; | 237 | tcp_ctask->exp_datasn++; |
238 | 238 | ||
239 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); | 239 | tcp_ctask->data_offset = be32_to_cpu(rhdr->offset); |
240 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > sc->request_bufflen) { | 240 | if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) { |
241 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", | 241 | debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n", |
242 | __FUNCTION__, tcp_ctask->data_offset, | 242 | __FUNCTION__, tcp_ctask->data_offset, |
243 | tcp_conn->in.datalen, sc->request_bufflen); | 243 | tcp_conn->in.datalen, scsi_bufflen(sc)); |
244 | return ISCSI_ERR_DATA_OFFSET; | 244 | return ISCSI_ERR_DATA_OFFSET; |
245 | } | 245 | } |
246 | 246 | ||
@@ -250,14 +250,14 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
250 | int res_count = be32_to_cpu(rhdr->residual_count); | 250 | int res_count = be32_to_cpu(rhdr->residual_count); |
251 | 251 | ||
252 | if (res_count > 0 && | 252 | if (res_count > 0 && |
253 | res_count <= sc->request_bufflen) { | 253 | res_count <= scsi_bufflen(sc)) { |
254 | sc->resid = res_count; | 254 | scsi_set_resid(sc, res_count); |
255 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | 255 | sc->result = (DID_OK << 16) | rhdr->cmd_status; |
256 | } else | 256 | } else |
257 | sc->result = (DID_BAD_TARGET << 16) | | 257 | sc->result = (DID_BAD_TARGET << 16) | |
258 | rhdr->cmd_status; | 258 | rhdr->cmd_status; |
259 | } else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) { | 259 | } else if (rhdr->flags & ISCSI_FLAG_DATA_OVERFLOW) { |
260 | sc->resid = be32_to_cpu(rhdr->residual_count); | 260 | scsi_set_resid(sc, be32_to_cpu(rhdr->residual_count)); |
261 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | 261 | sc->result = (DID_OK << 16) | rhdr->cmd_status; |
262 | } else | 262 | } else |
263 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | 263 | sc->result = (DID_OK << 16) | rhdr->cmd_status; |
@@ -285,6 +285,8 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
285 | { | 285 | { |
286 | struct iscsi_data *hdr; | 286 | struct iscsi_data *hdr; |
287 | struct scsi_cmnd *sc = ctask->sc; | 287 | struct scsi_cmnd *sc = ctask->sc; |
288 | int i, sg_count = 0; | ||
289 | struct scatterlist *sg; | ||
288 | 290 | ||
289 | hdr = &r2t->dtask.hdr; | 291 | hdr = &r2t->dtask.hdr; |
290 | memset(hdr, 0, sizeof(struct iscsi_data)); | 292 | memset(hdr, 0, sizeof(struct iscsi_data)); |
@@ -312,39 +314,30 @@ iscsi_solicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
312 | iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, | 314 | iscsi_buf_init_iov(&r2t->headbuf, (char*)hdr, |
313 | sizeof(struct iscsi_hdr)); | 315 | sizeof(struct iscsi_hdr)); |
314 | 316 | ||
315 | if (sc->use_sg) { | 317 | sg = scsi_sglist(sc); |
316 | int i, sg_count = 0; | 318 | r2t->sg = NULL; |
317 | struct scatterlist *sg = sc->request_buffer; | 319 | for (i = 0; i < scsi_sg_count(sc); i++, sg += 1) { |
318 | 320 | /* FIXME: prefetch ? */ | |
319 | r2t->sg = NULL; | 321 | if (sg_count + sg->length > r2t->data_offset) { |
320 | for (i = 0; i < sc->use_sg; i++, sg += 1) { | 322 | int page_offset; |
321 | /* FIXME: prefetch ? */ | ||
322 | if (sg_count + sg->length > r2t->data_offset) { | ||
323 | int page_offset; | ||
324 | 323 | ||
325 | /* sg page found! */ | 324 | /* sg page found! */ |
326 | 325 | ||
327 | /* offset within this page */ | 326 | /* offset within this page */ |
328 | page_offset = r2t->data_offset - sg_count; | 327 | page_offset = r2t->data_offset - sg_count; |
329 | 328 | ||
330 | /* fill in this buffer */ | 329 | /* fill in this buffer */ |
331 | iscsi_buf_init_sg(&r2t->sendbuf, sg); | 330 | iscsi_buf_init_sg(&r2t->sendbuf, sg); |
332 | r2t->sendbuf.sg.offset += page_offset; | 331 | r2t->sendbuf.sg.offset += page_offset; |
333 | r2t->sendbuf.sg.length -= page_offset; | 332 | r2t->sendbuf.sg.length -= page_offset; |
334 | 333 | ||
335 | /* xmit logic will continue with next one */ | 334 | /* xmit logic will continue with next one */ |
336 | r2t->sg = sg + 1; | 335 | r2t->sg = sg + 1; |
337 | break; | 336 | break; |
338 | } | ||
339 | sg_count += sg->length; | ||
340 | } | 337 | } |
341 | BUG_ON(r2t->sg == NULL); | 338 | sg_count += sg->length; |
342 | } else { | ||
343 | iscsi_buf_init_iov(&r2t->sendbuf, | ||
344 | (char*)sc->request_buffer + r2t->data_offset, | ||
345 | r2t->data_count); | ||
346 | r2t->sg = NULL; | ||
347 | } | 339 | } |
340 | BUG_ON(r2t->sg == NULL); | ||
348 | } | 341 | } |
349 | 342 | ||
350 | /** | 343 | /** |
@@ -404,11 +397,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
404 | r2t->data_length, session->max_burst); | 397 | r2t->data_length, session->max_burst); |
405 | 398 | ||
406 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); | 399 | r2t->data_offset = be32_to_cpu(rhdr->data_offset); |
407 | if (r2t->data_offset + r2t->data_length > ctask->sc->request_bufflen) { | 400 | if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) { |
408 | spin_unlock(&session->lock); | 401 | spin_unlock(&session->lock); |
409 | printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at " | 402 | printk(KERN_ERR "iscsi_tcp: invalid R2T with data len %u at " |
410 | "offset %u and total length %d\n", r2t->data_length, | 403 | "offset %u and total length %d\n", r2t->data_length, |
411 | r2t->data_offset, ctask->sc->request_bufflen); | 404 | r2t->data_offset, scsi_bufflen(ctask->sc)); |
412 | return ISCSI_ERR_DATALEN; | 405 | return ISCSI_ERR_DATALEN; |
413 | } | 406 | } |
414 | 407 | ||
@@ -612,7 +605,7 @@ iscsi_ctask_copy(struct iscsi_tcp_conn *tcp_conn, struct iscsi_cmd_task *ctask, | |||
612 | size, tcp_conn->in.offset, tcp_conn->in.copied); | 605 | size, tcp_conn->in.offset, tcp_conn->in.copied); |
613 | 606 | ||
614 | BUG_ON(size <= 0); | 607 | BUG_ON(size <= 0); |
615 | BUG_ON(tcp_ctask->sent + size > ctask->sc->request_bufflen); | 608 | BUG_ON(tcp_ctask->sent + size > scsi_bufflen(ctask->sc)); |
616 | 609 | ||
617 | rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, | 610 | rc = skb_copy_bits(tcp_conn->in.skb, tcp_conn->in.offset, |
618 | (char*)buf + (offset + tcp_conn->data_copied), size); | 611 | (char*)buf + (offset + tcp_conn->data_copied), size); |
@@ -710,25 +703,8 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
710 | 703 | ||
711 | BUG_ON((void*)ctask != sc->SCp.ptr); | 704 | BUG_ON((void*)ctask != sc->SCp.ptr); |
712 | 705 | ||
713 | /* | ||
714 | * copying Data-In into the Scsi_Cmnd | ||
715 | */ | ||
716 | if (!sc->use_sg) { | ||
717 | i = ctask->data_count; | ||
718 | rc = iscsi_ctask_copy(tcp_conn, ctask, sc->request_buffer, | ||
719 | sc->request_bufflen, | ||
720 | tcp_ctask->data_offset); | ||
721 | if (rc == -EAGAIN) | ||
722 | return rc; | ||
723 | if (conn->datadgst_en) | ||
724 | iscsi_recv_digest_update(tcp_conn, sc->request_buffer, | ||
725 | i); | ||
726 | rc = 0; | ||
727 | goto done; | ||
728 | } | ||
729 | |||
730 | offset = tcp_ctask->data_offset; | 706 | offset = tcp_ctask->data_offset; |
731 | sg = sc->request_buffer; | 707 | sg = scsi_sglist(sc); |
732 | 708 | ||
733 | if (tcp_ctask->data_offset) | 709 | if (tcp_ctask->data_offset) |
734 | for (i = 0; i < tcp_ctask->sg_count; i++) | 710 | for (i = 0; i < tcp_ctask->sg_count; i++) |
@@ -737,7 +713,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
737 | if (offset < 0) | 713 | if (offset < 0) |
738 | offset = 0; | 714 | offset = 0; |
739 | 715 | ||
740 | for (i = tcp_ctask->sg_count; i < sc->use_sg; i++) { | 716 | for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) { |
741 | char *dest; | 717 | char *dest; |
742 | 718 | ||
743 | dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0); | 719 | dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0); |
@@ -782,7 +758,6 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn) | |||
782 | } | 758 | } |
783 | BUG_ON(ctask->data_count); | 759 | BUG_ON(ctask->data_count); |
784 | 760 | ||
785 | done: | ||
786 | /* check for non-exceptional status */ | 761 | /* check for non-exceptional status */ |
787 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 762 | if (tcp_conn->in.hdr->flags & ISCSI_FLAG_DATA_STATUS) { |
788 | debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n", | 763 | debug_scsi("done [sc %lx res %d itt 0x%x flags 0x%x]\n", |
@@ -1241,7 +1216,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1241 | struct iscsi_r2t_info *r2t, int left) | 1216 | struct iscsi_r2t_info *r2t, int left) |
1242 | { | 1217 | { |
1243 | struct iscsi_data *hdr; | 1218 | struct iscsi_data *hdr; |
1244 | struct scsi_cmnd *sc = ctask->sc; | ||
1245 | int new_offset; | 1219 | int new_offset; |
1246 | 1220 | ||
1247 | hdr = &r2t->dtask.hdr; | 1221 | hdr = &r2t->dtask.hdr; |
@@ -1271,15 +1245,8 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1271 | if (iscsi_buf_left(&r2t->sendbuf)) | 1245 | if (iscsi_buf_left(&r2t->sendbuf)) |
1272 | return; | 1246 | return; |
1273 | 1247 | ||
1274 | if (sc->use_sg) { | 1248 | iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); |
1275 | iscsi_buf_init_sg(&r2t->sendbuf, r2t->sg); | 1249 | r2t->sg += 1; |
1276 | r2t->sg += 1; | ||
1277 | } else { | ||
1278 | iscsi_buf_init_iov(&r2t->sendbuf, | ||
1279 | (char*)sc->request_buffer + new_offset, | ||
1280 | r2t->data_count); | ||
1281 | r2t->sg = NULL; | ||
1282 | } | ||
1283 | } | 1250 | } |
1284 | 1251 | ||
1285 | static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask, | 1252 | static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask, |
@@ -1408,23 +1375,15 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1408 | tcp_ctask->exp_datasn = 0; | 1375 | tcp_ctask->exp_datasn = 0; |
1409 | 1376 | ||
1410 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 1377 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
1411 | if (sc->use_sg) { | 1378 | struct scatterlist *sg = scsi_sglist(sc); |
1412 | struct scatterlist *sg = sc->request_buffer; | 1379 | |
1413 | 1380 | iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg); | |
1414 | iscsi_buf_init_sg(&tcp_ctask->sendbuf, sg); | 1381 | tcp_ctask->sg = sg + 1; |
1415 | tcp_ctask->sg = sg + 1; | 1382 | tcp_ctask->bad_sg = sg + scsi_sg_count(sc); |
1416 | tcp_ctask->bad_sg = sg + sc->use_sg; | ||
1417 | } else { | ||
1418 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, | ||
1419 | sc->request_buffer, | ||
1420 | sc->request_bufflen); | ||
1421 | tcp_ctask->sg = NULL; | ||
1422 | tcp_ctask->bad_sg = NULL; | ||
1423 | } | ||
1424 | 1383 | ||
1425 | debug_scsi("cmd [itt 0x%x total %d imm_data %d " | 1384 | debug_scsi("cmd [itt 0x%x total %d imm_data %d " |
1426 | "unsol count %d, unsol offset %d]\n", | 1385 | "unsol count %d, unsol offset %d]\n", |
1427 | ctask->itt, sc->request_bufflen, | 1386 | ctask->itt, scsi_bufflen(sc), |
1428 | ctask->imm_count, ctask->unsol_count, | 1387 | ctask->imm_count, ctask->unsol_count, |
1429 | ctask->unsol_offset); | 1388 | ctask->unsol_offset); |
1430 | } | 1389 | } |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 865dd5739f0e..4d85ce100192 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -140,7 +140,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
140 | hdr->flags = ISCSI_ATTR_SIMPLE; | 140 | hdr->flags = ISCSI_ATTR_SIMPLE; |
141 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); | 141 | int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun); |
142 | hdr->itt = build_itt(ctask->itt, conn->id, session->age); | 142 | hdr->itt = build_itt(ctask->itt, conn->id, session->age); |
143 | hdr->data_length = cpu_to_be32(sc->request_bufflen); | 143 | hdr->data_length = cpu_to_be32(scsi_bufflen(sc)); |
144 | hdr->cmdsn = cpu_to_be32(session->cmdsn); | 144 | hdr->cmdsn = cpu_to_be32(session->cmdsn); |
145 | session->cmdsn++; | 145 | session->cmdsn++; |
146 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | 146 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); |
@@ -172,11 +172,11 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
172 | ctask->unsol_datasn = 0; | 172 | ctask->unsol_datasn = 0; |
173 | 173 | ||
174 | if (session->imm_data_en) { | 174 | if (session->imm_data_en) { |
175 | if (sc->request_bufflen >= session->first_burst) | 175 | if (scsi_bufflen(sc) >= session->first_burst) |
176 | ctask->imm_count = min(session->first_burst, | 176 | ctask->imm_count = min(session->first_burst, |
177 | conn->max_xmit_dlength); | 177 | conn->max_xmit_dlength); |
178 | else | 178 | else |
179 | ctask->imm_count = min(sc->request_bufflen, | 179 | ctask->imm_count = min(scsi_bufflen(sc), |
180 | conn->max_xmit_dlength); | 180 | conn->max_xmit_dlength); |
181 | hton24(ctask->hdr->dlength, ctask->imm_count); | 181 | hton24(ctask->hdr->dlength, ctask->imm_count); |
182 | } else | 182 | } else |
@@ -184,7 +184,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
184 | 184 | ||
185 | if (!session->initial_r2t_en) { | 185 | if (!session->initial_r2t_en) { |
186 | ctask->unsol_count = min((session->first_burst), | 186 | ctask->unsol_count = min((session->first_burst), |
187 | (sc->request_bufflen)) - ctask->imm_count; | 187 | (scsi_bufflen(sc))) - ctask->imm_count; |
188 | ctask->unsol_offset = ctask->imm_count; | 188 | ctask->unsol_offset = ctask->imm_count; |
189 | } | 189 | } |
190 | 190 | ||
@@ -204,7 +204,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
204 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " | 204 | debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d " |
205 | "cmdsn %d win %d]\n", | 205 | "cmdsn %d win %d]\n", |
206 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", | 206 | sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read", |
207 | conn->id, sc, sc->cmnd[0], ctask->itt, sc->request_bufflen, | 207 | conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc), |
208 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); | 208 | session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1); |
209 | } | 209 | } |
210 | 210 | ||
@@ -297,14 +297,14 @@ invalid_datalen: | |||
297 | if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { | 297 | if (rhdr->flags & ISCSI_FLAG_CMD_UNDERFLOW) { |
298 | int res_count = be32_to_cpu(rhdr->residual_count); | 298 | int res_count = be32_to_cpu(rhdr->residual_count); |
299 | 299 | ||
300 | if (res_count > 0 && res_count <= sc->request_bufflen) | 300 | if (res_count > 0 && res_count <= scsi_bufflen(sc)) |
301 | sc->resid = res_count; | 301 | scsi_set_resid(sc, res_count); |
302 | else | 302 | else |
303 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 303 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
304 | } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) | 304 | } else if (rhdr->flags & ISCSI_FLAG_CMD_BIDI_UNDERFLOW) |
305 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | 305 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; |
306 | else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) | 306 | else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) |
307 | sc->resid = be32_to_cpu(rhdr->residual_count); | 307 | scsi_set_resid(sc, be32_to_cpu(rhdr->residual_count)); |
308 | 308 | ||
309 | out: | 309 | out: |
310 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", | 310 | debug_scsi("done [sc %lx res %d itt 0x%x]\n", |
@@ -876,7 +876,7 @@ fault: | |||
876 | printk(KERN_ERR "iscsi: cmd 0x%x is not queued (%d)\n", | 876 | printk(KERN_ERR "iscsi: cmd 0x%x is not queued (%d)\n", |
877 | sc->cmnd[0], reason); | 877 | sc->cmnd[0], reason); |
878 | sc->result = (DID_NO_CONNECT << 16); | 878 | sc->result = (DID_NO_CONNECT << 16); |
879 | sc->resid = sc->request_bufflen; | 879 | scsi_set_resid(sc, scsi_bufflen(sc)); |
880 | sc->scsi_done(sc); | 880 | sc->scsi_done(sc); |
881 | return 0; | 881 | return 0; |
882 | } | 882 | } |
@@ -1145,7 +1145,7 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1145 | iscsi_ctask_mtask_cleanup(ctask); | 1145 | iscsi_ctask_mtask_cleanup(ctask); |
1146 | 1146 | ||
1147 | sc->result = err; | 1147 | sc->result = err; |
1148 | sc->resid = sc->request_bufflen; | 1148 | scsi_set_resid(sc, scsi_bufflen(sc)); |
1149 | if (conn->ctask == ctask) | 1149 | if (conn->ctask == ctask) |
1150 | conn->ctask = NULL; | 1150 | conn->ctask = NULL; |
1151 | /* release ref from queuecommand */ | 1151 | /* release ref from queuecommand */ |