aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Battersby <tonyb@cybernetics.com>2007-11-14 15:38:42 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2007-11-14 15:51:58 -0500
commit505f76b3061f6e74a50f378e45ac931abc1fe784 (patch)
tree55074ebf00aa0f7fc336d83392a01b20267978c6
parent5f78e89b5f7041895c4820be5c000792243b634f (diff)
[SCSI] iscsi_tcp: fix potential lockup with write commands
There is a race condition in iscsi_tcp.c that may cause it to forget that it received a R2T from the target. This race may cause a data-out command (such as a write) to lock up. The race occurs here: static int iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; int rc; if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { BUG_ON(!ctask->unsol_count); tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR; <---- RACE ... static int iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) { ... tcp_ctask->xmstate |= XMSTATE_SOL_HDR_INIT; <---- RACE ... While iscsi_xmitworker() (called from scsi_queue_work()) is preparing to send unsolicited data, iscsi_tcp_data_recv() (called from tcp_read_sock()) interrupts it upon receipt of a R2T from the target. Both contexts do read-modify-write of tcp_ctask->xmstate. Usually, gcc on x86 will make &= and |= atomic on UP (not guaranteed of course), but in this case iscsi_send_unsol_pdu() reads the value of xmstate before clearing the bit, which causes gcc to read xmstate into a CPU register, test it, clear the bit, and then store it back to memory. If the recv interrupt happens during this sequence, then the XMSTATE_SOL_HDR_INIT bit set by the recv interrupt will be lost, and the R2T will be forgotten. The patch below (against 2.6.24-rc1) converts accesses of xmstate to use set_bit, clear_bit, and test_bit instead of |= and &=. I have tested this patch and verified that it fixes the problem. Another possible approach would be to hold a lock during most of the rx/tx setup and post-processing, and drop the lock only for the actual rx/tx. Signed-off-by: Tony Battersby <tonyb@cybernetics.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/iscsi_tcp.c139
-rw-r--r--drivers/scsi/iscsi_tcp.h34
2 files changed, 86 insertions, 87 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 4bcf916c21a7..57ce2251abc8 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -197,7 +197,7 @@ iscsi_tcp_cleanup_ctask(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
197 if (unlikely(!sc)) 197 if (unlikely(!sc))
198 return; 198 return;
199 199
200 tcp_ctask->xmstate = XMSTATE_IDLE; 200 tcp_ctask->xmstate = XMSTATE_VALUE_IDLE;
201 tcp_ctask->r2t = NULL; 201 tcp_ctask->r2t = NULL;
202} 202}
203 203
@@ -409,7 +409,7 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
409 409
410 tcp_ctask->exp_datasn = r2tsn + 1; 410 tcp_ctask->exp_datasn = r2tsn + 1;
411 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*)); 411 __kfifo_put(tcp_ctask->r2tqueue, (void*)&r2t, sizeof(void*));
412 tcp_ctask->xmstate |= XMSTATE_SOL_HDR_INIT; 412 set_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate);
413 list_move_tail(&ctask->running, &conn->xmitqueue); 413 list_move_tail(&ctask->running, &conn->xmitqueue);
414 414
415 scsi_queue_work(session->host, &conn->xmitwork); 415 scsi_queue_work(session->host, &conn->xmitwork);
@@ -1254,7 +1254,7 @@ static void iscsi_set_padding(struct iscsi_tcp_cmd_task *tcp_ctask,
1254 1254
1255 tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count; 1255 tcp_ctask->pad_count = ISCSI_PAD_LEN - tcp_ctask->pad_count;
1256 debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count); 1256 debug_scsi("write padding %d bytes\n", tcp_ctask->pad_count);
1257 tcp_ctask->xmstate |= XMSTATE_W_PAD; 1257 set_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate);
1258} 1258}
1259 1259
1260/** 1260/**
@@ -1269,7 +1269,7 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1269 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1269 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1270 1270
1271 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue)); 1271 BUG_ON(__kfifo_len(tcp_ctask->r2tqueue));
1272 tcp_ctask->xmstate = XMSTATE_CMD_HDR_INIT; 1272 tcp_ctask->xmstate = 1 << XMSTATE_BIT_CMD_HDR_INIT;
1273} 1273}
1274 1274
1275/** 1275/**
@@ -1283,10 +1283,10 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1283 * xmit. 1283 * xmit.
1284 * 1284 *
1285 * Management xmit state machine consists of these states: 1285 * Management xmit state machine consists of these states:
1286 * XMSTATE_IMM_HDR_INIT - calculate digest of PDU Header 1286 * XMSTATE_BIT_IMM_HDR_INIT - calculate digest of PDU Header
1287 * XMSTATE_IMM_HDR - PDU Header xmit in progress 1287 * XMSTATE_BIT_IMM_HDR - PDU Header xmit in progress
1288 * XMSTATE_IMM_DATA - PDU Data xmit in progress 1288 * XMSTATE_BIT_IMM_DATA - PDU Data xmit in progress
1289 * XMSTATE_IDLE - management PDU is done 1289 * XMSTATE_VALUE_IDLE - management PDU is done
1290 **/ 1290 **/
1291static int 1291static int
1292iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) 1292iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
@@ -1297,12 +1297,12 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1297 debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", 1297 debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n",
1298 conn->id, tcp_mtask->xmstate, mtask->itt); 1298 conn->id, tcp_mtask->xmstate, mtask->itt);
1299 1299
1300 if (tcp_mtask->xmstate & XMSTATE_IMM_HDR_INIT) { 1300 if (test_bit(XMSTATE_BIT_IMM_HDR_INIT, &tcp_mtask->xmstate)) {
1301 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr, 1301 iscsi_buf_init_iov(&tcp_mtask->headbuf, (char*)mtask->hdr,
1302 sizeof(struct iscsi_hdr)); 1302 sizeof(struct iscsi_hdr));
1303 1303
1304 if (mtask->data_count) { 1304 if (mtask->data_count) {
1305 tcp_mtask->xmstate |= XMSTATE_IMM_DATA; 1305 set_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate);
1306 iscsi_buf_init_iov(&tcp_mtask->sendbuf, 1306 iscsi_buf_init_iov(&tcp_mtask->sendbuf,
1307 (char*)mtask->data, 1307 (char*)mtask->data,
1308 mtask->data_count); 1308 mtask->data_count);
@@ -1315,21 +1315,20 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1315 (u8*)tcp_mtask->hdrext); 1315 (u8*)tcp_mtask->hdrext);
1316 1316
1317 tcp_mtask->sent = 0; 1317 tcp_mtask->sent = 0;
1318 tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR_INIT; 1318 clear_bit(XMSTATE_BIT_IMM_HDR_INIT, &tcp_mtask->xmstate);
1319 tcp_mtask->xmstate |= XMSTATE_IMM_HDR; 1319 set_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate);
1320 } 1320 }
1321 1321
1322 if (tcp_mtask->xmstate & XMSTATE_IMM_HDR) { 1322 if (test_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate)) {
1323 rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf, 1323 rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf,
1324 mtask->data_count); 1324 mtask->data_count);
1325 if (rc) 1325 if (rc)
1326 return rc; 1326 return rc;
1327 tcp_mtask->xmstate &= ~XMSTATE_IMM_HDR; 1327 clear_bit(XMSTATE_BIT_IMM_HDR, &tcp_mtask->xmstate);
1328 } 1328 }
1329 1329
1330 if (tcp_mtask->xmstate & XMSTATE_IMM_DATA) { 1330 if (test_and_clear_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate)) {
1331 BUG_ON(!mtask->data_count); 1331 BUG_ON(!mtask->data_count);
1332 tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA;
1333 /* FIXME: implement. 1332 /* FIXME: implement.
1334 * Virtual buffer could be spreaded across multiple pages... 1333 * Virtual buffer could be spreaded across multiple pages...
1335 */ 1334 */
@@ -1339,13 +1338,13 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1339 rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf, 1338 rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf,
1340 &mtask->data_count, &tcp_mtask->sent); 1339 &mtask->data_count, &tcp_mtask->sent);
1341 if (rc) { 1340 if (rc) {
1342 tcp_mtask->xmstate |= XMSTATE_IMM_DATA; 1341 set_bit(XMSTATE_BIT_IMM_DATA, &tcp_mtask->xmstate);
1343 return rc; 1342 return rc;
1344 } 1343 }
1345 } while (mtask->data_count); 1344 } while (mtask->data_count);
1346 } 1345 }
1347 1346
1348 BUG_ON(tcp_mtask->xmstate != XMSTATE_IDLE); 1347 BUG_ON(tcp_mtask->xmstate != XMSTATE_VALUE_IDLE);
1349 if (mtask->hdr->itt == RESERVED_ITT) { 1348 if (mtask->hdr->itt == RESERVED_ITT) {
1350 struct iscsi_session *session = conn->session; 1349 struct iscsi_session *session = conn->session;
1351 1350
@@ -1365,7 +1364,7 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1365 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1364 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1366 int rc = 0; 1365 int rc = 0;
1367 1366
1368 if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_INIT) { 1367 if (test_bit(XMSTATE_BIT_CMD_HDR_INIT, &tcp_ctask->xmstate)) {
1369 tcp_ctask->sent = 0; 1368 tcp_ctask->sent = 0;
1370 tcp_ctask->sg_count = 0; 1369 tcp_ctask->sg_count = 0;
1371 tcp_ctask->exp_datasn = 0; 1370 tcp_ctask->exp_datasn = 0;
@@ -1390,21 +1389,21 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1390 if (conn->hdrdgst_en) 1389 if (conn->hdrdgst_en)
1391 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1390 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1392 (u8*)tcp_ctask->hdrext); 1391 (u8*)tcp_ctask->hdrext);
1393 tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_INIT; 1392 clear_bit(XMSTATE_BIT_CMD_HDR_INIT, &tcp_ctask->xmstate);
1394 tcp_ctask->xmstate |= XMSTATE_CMD_HDR_XMIT; 1393 set_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate);
1395 } 1394 }
1396 1395
1397 if (tcp_ctask->xmstate & XMSTATE_CMD_HDR_XMIT) { 1396 if (test_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate)) {
1398 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); 1397 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count);
1399 if (rc) 1398 if (rc)
1400 return rc; 1399 return rc;
1401 tcp_ctask->xmstate &= ~XMSTATE_CMD_HDR_XMIT; 1400 clear_bit(XMSTATE_BIT_CMD_HDR_XMIT, &tcp_ctask->xmstate);
1402 1401
1403 if (sc->sc_data_direction != DMA_TO_DEVICE) 1402 if (sc->sc_data_direction != DMA_TO_DEVICE)
1404 return 0; 1403 return 0;
1405 1404
1406 if (ctask->imm_count) { 1405 if (ctask->imm_count) {
1407 tcp_ctask->xmstate |= XMSTATE_IMM_DATA; 1406 set_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate);
1408 iscsi_set_padding(tcp_ctask, ctask->imm_count); 1407 iscsi_set_padding(tcp_ctask, ctask->imm_count);
1409 1408
1410 if (ctask->conn->datadgst_en) { 1409 if (ctask->conn->datadgst_en) {
@@ -1414,9 +1413,10 @@ iscsi_send_cmd_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1414 } 1413 }
1415 } 1414 }
1416 1415
1417 if (ctask->unsol_count) 1416 if (ctask->unsol_count) {
1418 tcp_ctask->xmstate |= 1417 set_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate);
1419 XMSTATE_UNS_HDR | XMSTATE_UNS_INIT; 1418 set_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
1419 }
1420 } 1420 }
1421 return rc; 1421 return rc;
1422} 1422}
@@ -1428,25 +1428,25 @@ iscsi_send_padding(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1428 struct iscsi_tcp_conn *tcp_conn = conn->dd_data; 1428 struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
1429 int sent = 0, rc; 1429 int sent = 0, rc;
1430 1430
1431 if (tcp_ctask->xmstate & XMSTATE_W_PAD) { 1431 if (test_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate)) {
1432 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, 1432 iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad,
1433 tcp_ctask->pad_count); 1433 tcp_ctask->pad_count);
1434 if (conn->datadgst_en) 1434 if (conn->datadgst_en)
1435 crypto_hash_update(&tcp_conn->tx_hash, 1435 crypto_hash_update(&tcp_conn->tx_hash,
1436 &tcp_ctask->sendbuf.sg, 1436 &tcp_ctask->sendbuf.sg,
1437 tcp_ctask->sendbuf.sg.length); 1437 tcp_ctask->sendbuf.sg.length);
1438 } else if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_PAD)) 1438 } else if (!test_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate))
1439 return 0; 1439 return 0;
1440 1440
1441 tcp_ctask->xmstate &= ~XMSTATE_W_PAD; 1441 clear_bit(XMSTATE_BIT_W_PAD, &tcp_ctask->xmstate);
1442 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_PAD; 1442 clear_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate);
1443 debug_scsi("sending %d pad bytes for itt 0x%x\n", 1443 debug_scsi("sending %d pad bytes for itt 0x%x\n",
1444 tcp_ctask->pad_count, ctask->itt); 1444 tcp_ctask->pad_count, ctask->itt);
1445 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, 1445 rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count,
1446 &sent); 1446 &sent);
1447 if (rc) { 1447 if (rc) {
1448 debug_scsi("padding send failed %d\n", rc); 1448 debug_scsi("padding send failed %d\n", rc);
1449 tcp_ctask->xmstate |= XMSTATE_W_RESEND_PAD; 1449 set_bit(XMSTATE_BIT_W_RESEND_PAD, &tcp_ctask->xmstate);
1450 } 1450 }
1451 return rc; 1451 return rc;
1452} 1452}
@@ -1465,11 +1465,11 @@ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1465 tcp_ctask = ctask->dd_data; 1465 tcp_ctask = ctask->dd_data;
1466 tcp_conn = conn->dd_data; 1466 tcp_conn = conn->dd_data;
1467 1467
1468 if (!(tcp_ctask->xmstate & XMSTATE_W_RESEND_DATA_DIGEST)) { 1468 if (!test_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate)) {
1469 crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest); 1469 crypto_hash_final(&tcp_conn->tx_hash, (u8*)digest);
1470 iscsi_buf_init_iov(buf, (char*)digest, 4); 1470 iscsi_buf_init_iov(buf, (char*)digest, 4);
1471 } 1471 }
1472 tcp_ctask->xmstate &= ~XMSTATE_W_RESEND_DATA_DIGEST; 1472 clear_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate);
1473 1473
1474 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent); 1474 rc = iscsi_sendpage(conn, buf, &tcp_ctask->digest_count, &sent);
1475 if (!rc) 1475 if (!rc)
@@ -1478,7 +1478,7 @@ iscsi_send_digest(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1478 else { 1478 else {
1479 debug_scsi("sending digest 0x%x failed for itt 0x%x!\n", 1479 debug_scsi("sending digest 0x%x failed for itt 0x%x!\n",
1480 *digest, ctask->itt); 1480 *digest, ctask->itt);
1481 tcp_ctask->xmstate |= XMSTATE_W_RESEND_DATA_DIGEST; 1481 set_bit(XMSTATE_BIT_W_RESEND_DATA_DIGEST, &tcp_ctask->xmstate);
1482 } 1482 }
1483 return rc; 1483 return rc;
1484} 1484}
@@ -1526,8 +1526,8 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1526 struct iscsi_data_task *dtask; 1526 struct iscsi_data_task *dtask;
1527 int rc; 1527 int rc;
1528 1528
1529 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1529 set_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
1530 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1530 if (test_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate)) {
1531 dtask = &tcp_ctask->unsol_dtask; 1531 dtask = &tcp_ctask->unsol_dtask;
1532 1532
1533 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr); 1533 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
@@ -1537,14 +1537,14 @@ iscsi_send_unsol_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1537 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1537 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1538 (u8*)dtask->hdrext); 1538 (u8*)dtask->hdrext);
1539 1539
1540 tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; 1540 clear_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
1541 iscsi_set_padding(tcp_ctask, ctask->data_count); 1541 iscsi_set_padding(tcp_ctask, ctask->data_count);
1542 } 1542 }
1543 1543
1544 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); 1544 rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count);
1545 if (rc) { 1545 if (rc) {
1546 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; 1546 clear_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
1547 tcp_ctask->xmstate |= XMSTATE_UNS_HDR; 1547 set_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate);
1548 return rc; 1548 return rc;
1549 } 1549 }
1550 1550
@@ -1565,16 +1565,15 @@ iscsi_send_unsol_pdu(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1565 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; 1565 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1566 int rc; 1566 int rc;
1567 1567
1568 if (tcp_ctask->xmstate & XMSTATE_UNS_HDR) { 1568 if (test_and_clear_bit(XMSTATE_BIT_UNS_HDR, &tcp_ctask->xmstate)) {
1569 BUG_ON(!ctask->unsol_count); 1569 BUG_ON(!ctask->unsol_count);
1570 tcp_ctask->xmstate &= ~XMSTATE_UNS_HDR;
1571send_hdr: 1570send_hdr:
1572 rc = iscsi_send_unsol_hdr(conn, ctask); 1571 rc = iscsi_send_unsol_hdr(conn, ctask);
1573 if (rc) 1572 if (rc)
1574 return rc; 1573 return rc;
1575 } 1574 }
1576 1575
1577 if (tcp_ctask->xmstate & XMSTATE_UNS_DATA) { 1576 if (test_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate)) {
1578 struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask; 1577 struct iscsi_data_task *dtask = &tcp_ctask->unsol_dtask;
1579 int start = tcp_ctask->sent; 1578 int start = tcp_ctask->sent;
1580 1579
@@ -1584,14 +1583,14 @@ send_hdr:
1584 ctask->unsol_count -= tcp_ctask->sent - start; 1583 ctask->unsol_count -= tcp_ctask->sent - start;
1585 if (rc) 1584 if (rc)
1586 return rc; 1585 return rc;
1587 tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; 1586 clear_bit(XMSTATE_BIT_UNS_DATA, &tcp_ctask->xmstate);
1588 /* 1587 /*
1589 * Done with the Data-Out. Next, check if we need 1588 * Done with the Data-Out. Next, check if we need
1590 * to send another unsolicited Data-Out. 1589 * to send another unsolicited Data-Out.
1591 */ 1590 */
1592 if (ctask->unsol_count) { 1591 if (ctask->unsol_count) {
1593 debug_scsi("sending more uns\n"); 1592 debug_scsi("sending more uns\n");
1594 tcp_ctask->xmstate |= XMSTATE_UNS_INIT; 1593 set_bit(XMSTATE_BIT_UNS_INIT, &tcp_ctask->xmstate);
1595 goto send_hdr; 1594 goto send_hdr;
1596 } 1595 }
1597 } 1596 }
@@ -1607,7 +1606,7 @@ static int iscsi_send_sol_pdu(struct iscsi_conn *conn,
1607 struct iscsi_data_task *dtask; 1606 struct iscsi_data_task *dtask;
1608 int left, rc; 1607 int left, rc;
1609 1608
1610 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR_INIT) { 1609 if (test_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate)) {
1611 if (!tcp_ctask->r2t) { 1610 if (!tcp_ctask->r2t) {
1612 spin_lock_bh(&session->lock); 1611 spin_lock_bh(&session->lock);
1613 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t, 1612 __kfifo_get(tcp_ctask->r2tqueue, (void*)&tcp_ctask->r2t,
@@ -1621,19 +1620,19 @@ send_hdr:
1621 if (conn->hdrdgst_en) 1620 if (conn->hdrdgst_en)
1622 iscsi_hdr_digest(conn, &r2t->headbuf, 1621 iscsi_hdr_digest(conn, &r2t->headbuf,
1623 (u8*)dtask->hdrext); 1622 (u8*)dtask->hdrext);
1624 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR_INIT; 1623 clear_bit(XMSTATE_BIT_SOL_HDR_INIT, &tcp_ctask->xmstate);
1625 tcp_ctask->xmstate |= XMSTATE_SOL_HDR; 1624 set_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate);
1626 } 1625 }
1627 1626
1628 if (tcp_ctask->xmstate & XMSTATE_SOL_HDR) { 1627 if (test_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate)) {
1629 r2t = tcp_ctask->r2t; 1628 r2t = tcp_ctask->r2t;
1630 dtask = &r2t->dtask; 1629 dtask = &r2t->dtask;
1631 1630
1632 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count); 1631 rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count);
1633 if (rc) 1632 if (rc)
1634 return rc; 1633 return rc;
1635 tcp_ctask->xmstate &= ~XMSTATE_SOL_HDR; 1634 clear_bit(XMSTATE_BIT_SOL_HDR, &tcp_ctask->xmstate);
1636 tcp_ctask->xmstate |= XMSTATE_SOL_DATA; 1635 set_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate);
1637 1636
1638 if (conn->datadgst_en) { 1637 if (conn->datadgst_en) {
1639 iscsi_data_digest_init(conn->dd_data, tcp_ctask); 1638 iscsi_data_digest_init(conn->dd_data, tcp_ctask);
@@ -1646,7 +1645,7 @@ send_hdr:
1646 r2t->sent); 1645 r2t->sent);
1647 } 1646 }
1648 1647
1649 if (tcp_ctask->xmstate & XMSTATE_SOL_DATA) { 1648 if (test_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate)) {
1650 r2t = tcp_ctask->r2t; 1649 r2t = tcp_ctask->r2t;
1651 dtask = &r2t->dtask; 1650 dtask = &r2t->dtask;
1652 1651
@@ -1655,7 +1654,7 @@ send_hdr:
1655 &dtask->digestbuf, &dtask->digest); 1654 &dtask->digestbuf, &dtask->digest);
1656 if (rc) 1655 if (rc)
1657 return rc; 1656 return rc;
1658 tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; 1657 clear_bit(XMSTATE_BIT_SOL_DATA, &tcp_ctask->xmstate);
1659 1658
1660 /* 1659 /*
1661 * Done with this Data-Out. Next, check if we have 1660 * Done with this Data-Out. Next, check if we have
@@ -1700,32 +1699,32 @@ send_hdr:
1700 * xmit stages. 1699 * xmit stages.
1701 * 1700 *
1702 *iscsi_send_cmd_hdr() 1701 *iscsi_send_cmd_hdr()
1703 * XMSTATE_CMD_HDR_INIT - prepare Header and Data buffers Calculate 1702 * XMSTATE_BIT_CMD_HDR_INIT - prepare Header and Data buffers Calculate
1704 * Header Digest 1703 * Header Digest
1705 * XMSTATE_CMD_HDR_XMIT - Transmit header in progress 1704 * XMSTATE_BIT_CMD_HDR_XMIT - Transmit header in progress
1706 * 1705 *
1707 *iscsi_send_padding 1706 *iscsi_send_padding
1708 * XMSTATE_W_PAD - Prepare and send pading 1707 * XMSTATE_BIT_W_PAD - Prepare and send pading
1709 * XMSTATE_W_RESEND_PAD - retry send pading 1708 * XMSTATE_BIT_W_RESEND_PAD - retry send pading
1710 * 1709 *
1711 *iscsi_send_digest 1710 *iscsi_send_digest
1712 * XMSTATE_W_RESEND_DATA_DIGEST - Finalize and send Data Digest 1711 * XMSTATE_BIT_W_RESEND_DATA_DIGEST - Finalize and send Data Digest
1713 * XMSTATE_W_RESEND_DATA_DIGEST - retry sending digest 1712 * XMSTATE_BIT_W_RESEND_DATA_DIGEST - retry sending digest
1714 * 1713 *
1715 *iscsi_send_unsol_hdr 1714 *iscsi_send_unsol_hdr
1716 * XMSTATE_UNS_INIT - prepare un-solicit data header and digest 1715 * XMSTATE_BIT_UNS_INIT - prepare un-solicit data header and digest
1717 * XMSTATE_UNS_HDR - send un-solicit header 1716 * XMSTATE_BIT_UNS_HDR - send un-solicit header
1718 * 1717 *
1719 *iscsi_send_unsol_pdu 1718 *iscsi_send_unsol_pdu
1720 * XMSTATE_UNS_DATA - send un-solicit data in progress 1719 * XMSTATE_BIT_UNS_DATA - send un-solicit data in progress
1721 * 1720 *
1722 *iscsi_send_sol_pdu 1721 *iscsi_send_sol_pdu
1723 * XMSTATE_SOL_HDR_INIT - solicit data header and digest initialize 1722 * XMSTATE_BIT_SOL_HDR_INIT - solicit data header and digest initialize
1724 * XMSTATE_SOL_HDR - send solicit header 1723 * XMSTATE_BIT_SOL_HDR - send solicit header
1725 * XMSTATE_SOL_DATA - send solicit data 1724 * XMSTATE_BIT_SOL_DATA - send solicit data
1726 * 1725 *
1727 *iscsi_tcp_ctask_xmit 1726 *iscsi_tcp_ctask_xmit
1728 * XMSTATE_IMM_DATA - xmit managment data (??) 1727 * XMSTATE_BIT_IMM_DATA - xmit managment data (??)
1729 **/ 1728 **/
1730static int 1729static int
1731iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) 1730iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
@@ -1742,13 +1741,13 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1742 if (ctask->sc->sc_data_direction != DMA_TO_DEVICE) 1741 if (ctask->sc->sc_data_direction != DMA_TO_DEVICE)
1743 return 0; 1742 return 0;
1744 1743
1745 if (tcp_ctask->xmstate & XMSTATE_IMM_DATA) { 1744 if (test_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate)) {
1746 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg, 1745 rc = iscsi_send_data(ctask, &tcp_ctask->sendbuf, &tcp_ctask->sg,
1747 &tcp_ctask->sent, &ctask->imm_count, 1746 &tcp_ctask->sent, &ctask->imm_count,
1748 &tcp_ctask->immbuf, &tcp_ctask->immdigest); 1747 &tcp_ctask->immbuf, &tcp_ctask->immdigest);
1749 if (rc) 1748 if (rc)
1750 return rc; 1749 return rc;
1751 tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; 1750 clear_bit(XMSTATE_BIT_IMM_DATA, &tcp_ctask->xmstate);
1752 } 1751 }
1753 1752
1754 rc = iscsi_send_unsol_pdu(conn, ctask); 1753 rc = iscsi_send_unsol_pdu(conn, ctask);
@@ -1981,7 +1980,7 @@ static void
1981iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) 1980iscsi_tcp_mgmt_init(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask)
1982{ 1981{
1983 struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; 1982 struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data;
1984 tcp_mtask->xmstate = XMSTATE_IMM_HDR_INIT; 1983 tcp_mtask->xmstate = 1 << XMSTATE_BIT_IMM_HDR_INIT;
1985} 1984}
1986 1985
1987static int 1986static int
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h
index 7eba44df0a7f..68c36cc8997e 100644
--- a/drivers/scsi/iscsi_tcp.h
+++ b/drivers/scsi/iscsi_tcp.h
@@ -32,21 +32,21 @@
32#define IN_PROGRESS_PAD_RECV 0x4 32#define IN_PROGRESS_PAD_RECV 0x4
33 33
34/* xmit state machine */ 34/* xmit state machine */
35#define XMSTATE_IDLE 0x0 35#define XMSTATE_VALUE_IDLE 0
36#define XMSTATE_CMD_HDR_INIT 0x1 36#define XMSTATE_BIT_CMD_HDR_INIT 0
37#define XMSTATE_CMD_HDR_XMIT 0x2 37#define XMSTATE_BIT_CMD_HDR_XMIT 1
38#define XMSTATE_IMM_HDR 0x4 38#define XMSTATE_BIT_IMM_HDR 2
39#define XMSTATE_IMM_DATA 0x8 39#define XMSTATE_BIT_IMM_DATA 3
40#define XMSTATE_UNS_INIT 0x10 40#define XMSTATE_BIT_UNS_INIT 4
41#define XMSTATE_UNS_HDR 0x20 41#define XMSTATE_BIT_UNS_HDR 5
42#define XMSTATE_UNS_DATA 0x40 42#define XMSTATE_BIT_UNS_DATA 6
43#define XMSTATE_SOL_HDR 0x80 43#define XMSTATE_BIT_SOL_HDR 7
44#define XMSTATE_SOL_DATA 0x100 44#define XMSTATE_BIT_SOL_DATA 8
45#define XMSTATE_W_PAD 0x200 45#define XMSTATE_BIT_W_PAD 9
46#define XMSTATE_W_RESEND_PAD 0x400 46#define XMSTATE_BIT_W_RESEND_PAD 10
47#define XMSTATE_W_RESEND_DATA_DIGEST 0x800 47#define XMSTATE_BIT_W_RESEND_DATA_DIGEST 11
48#define XMSTATE_IMM_HDR_INIT 0x1000 48#define XMSTATE_BIT_IMM_HDR_INIT 12
49#define XMSTATE_SOL_HDR_INIT 0x2000 49#define XMSTATE_BIT_SOL_HDR_INIT 13
50 50
51#define ISCSI_PAD_LEN 4 51#define ISCSI_PAD_LEN 4
52#define ISCSI_SG_TABLESIZE SG_ALL 52#define ISCSI_SG_TABLESIZE SG_ALL
@@ -122,7 +122,7 @@ struct iscsi_data_task {
122struct iscsi_tcp_mgmt_task { 122struct iscsi_tcp_mgmt_task {
123 struct iscsi_hdr hdr; 123 struct iscsi_hdr hdr;
124 char hdrext[sizeof(__u32)]; /* Header-Digest */ 124 char hdrext[sizeof(__u32)]; /* Header-Digest */
125 int xmstate; /* mgmt xmit progress */ 125 unsigned long xmstate; /* mgmt xmit progress */
126 struct iscsi_buf headbuf; /* header buffer */ 126 struct iscsi_buf headbuf; /* header buffer */
127 struct iscsi_buf sendbuf; /* in progress buffer */ 127 struct iscsi_buf sendbuf; /* in progress buffer */
128 int sent; 128 int sent;
@@ -150,7 +150,7 @@ struct iscsi_tcp_cmd_task {
150 int pad_count; /* padded bytes */ 150 int pad_count; /* padded bytes */
151 struct iscsi_buf headbuf; /* header buf (xmit) */ 151 struct iscsi_buf headbuf; /* header buf (xmit) */
152 struct iscsi_buf sendbuf; /* in progress buffer*/ 152 struct iscsi_buf sendbuf; /* in progress buffer*/
153 int xmstate; /* xmit xtate machine */ 153 unsigned long xmstate; /* xmit xtate machine */
154 int sent; 154 int sent;
155 struct scatterlist *sg; /* per-cmd SG list */ 155 struct scatterlist *sg; /* per-cmd SG list */
156 struct scatterlist *bad_sg; /* assert statement */ 156 struct scatterlist *bad_sg; /* assert statement */