aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/iscsi_tcp.c117
-rw-r--r--drivers/scsi/libiscsi.c20
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
785done:
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
1285static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask, 1252static 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
309out: 309out:
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 */