diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/iscsi_tcp.c | 30 | ||||
-rw-r--r-- | drivers/scsi/iscsi_tcp.h | 1 | ||||
-rw-r--r-- | drivers/scsi/libiscsi.c | 25 |
3 files changed, 24 insertions, 32 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 058f094f945a..a97a3a4e99eb 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
@@ -1264,19 +1264,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask, | |||
1264 | r2t->data_count); | 1264 | r2t->data_count); |
1265 | } | 1265 | } |
1266 | 1266 | ||
1267 | static void | ||
1268 | iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | ||
1269 | { | ||
1270 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | ||
1271 | struct iscsi_data_task *dtask; | ||
1272 | |||
1273 | dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; | ||
1274 | iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr, | ||
1275 | tcp_ctask->r2t_data_count); | ||
1276 | iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, | ||
1277 | sizeof(struct iscsi_hdr)); | ||
1278 | } | ||
1279 | |||
1280 | /** | 1267 | /** |
1281 | * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands | 1268 | * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands |
1282 | * @conn: iscsi connection | 1269 | * @conn: iscsi connection |
@@ -1326,14 +1313,11 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask) | |||
1326 | if (ctask->unsol_count) | 1313 | if (ctask->unsol_count) |
1327 | tcp_ctask->xmstate |= XMSTATE_UNS_HDR | | 1314 | tcp_ctask->xmstate |= XMSTATE_UNS_HDR | |
1328 | XMSTATE_UNS_INIT; | 1315 | XMSTATE_UNS_INIT; |
1329 | tcp_ctask->r2t_data_count = ctask->total_length - | ||
1330 | ctask->imm_count - | ||
1331 | ctask->unsol_count; | ||
1332 | 1316 | ||
1333 | debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " | 1317 | debug_scsi("cmd [itt 0x%x total %d imm_data %d " |
1334 | "r2t_data %d]\n", | 1318 | "unsol count %d, unsol offset %d]\n", |
1335 | ctask->itt, ctask->total_length, ctask->imm_count, | 1319 | ctask->itt, ctask->total_length, ctask->imm_count, |
1336 | ctask->unsol_count, tcp_ctask->r2t_data_count); | 1320 | ctask->unsol_count, ctask->unsol_offset); |
1337 | } else | 1321 | } else |
1338 | tcp_ctask->xmstate = XMSTATE_R_HDR; | 1322 | tcp_ctask->xmstate = XMSTATE_R_HDR; |
1339 | 1323 | ||
@@ -1531,8 +1515,10 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
1531 | 1515 | ||
1532 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; | 1516 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; |
1533 | if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { | 1517 | if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { |
1534 | iscsi_unsolicit_data_init(conn, ctask); | 1518 | dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask; |
1535 | dtask = tcp_ctask->dtask; | 1519 | iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr); |
1520 | iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr, | ||
1521 | sizeof(struct iscsi_hdr)); | ||
1536 | if (conn->hdrdgst_en) | 1522 | if (conn->hdrdgst_en) |
1537 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, | 1523 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, |
1538 | (u8*)dtask->hdrext); | 1524 | (u8*)dtask->hdrext); |
@@ -1720,7 +1706,6 @@ data_out_done: | |||
1720 | * Done with this R2T. Check if there are more | 1706 | * Done with this R2T. Check if there are more |
1721 | * outstanding R2Ts ready to be processed. | 1707 | * outstanding R2Ts ready to be processed. |
1722 | */ | 1708 | */ |
1723 | BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0); | ||
1724 | if (conn->datadgst_en) { | 1709 | if (conn->datadgst_en) { |
1725 | rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, | 1710 | rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, |
1726 | &dtask->digest, 1); | 1711 | &dtask->digest, 1); |
@@ -1732,7 +1717,6 @@ data_out_done: | |||
1732 | debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); | 1717 | debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); |
1733 | } | 1718 | } |
1734 | 1719 | ||
1735 | tcp_ctask->r2t_data_count -= r2t->data_length; | ||
1736 | tcp_ctask->r2t = NULL; | 1720 | tcp_ctask->r2t = NULL; |
1737 | spin_lock_bh(&session->lock); | 1721 | spin_lock_bh(&session->lock); |
1738 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); | 1722 | __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); |
diff --git a/drivers/scsi/iscsi_tcp.h b/drivers/scsi/iscsi_tcp.h index 6a4ee704e46e..aace8f70dfd7 100644 --- a/drivers/scsi/iscsi_tcp.h +++ b/drivers/scsi/iscsi_tcp.h | |||
@@ -157,7 +157,6 @@ struct iscsi_tcp_cmd_task { | |||
157 | struct scatterlist *bad_sg; /* assert statement */ | 157 | struct scatterlist *bad_sg; /* assert statement */ |
158 | int sg_count; /* SG's to process */ | 158 | int sg_count; /* SG's to process */ |
159 | uint32_t exp_r2tsn; | 159 | uint32_t exp_r2tsn; |
160 | int r2t_data_count; /* R2T Data-Out bytes */ | ||
161 | int data_offset; | 160 | int data_offset; |
162 | struct iscsi_r2t_info *r2t; /* in progress R2T */ | 161 | struct iscsi_r2t_info *r2t; /* in progress R2T */ |
163 | struct iscsi_queue r2tpool; | 162 | struct iscsi_queue r2tpool; |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5884cd26d53a..a7c6e70f4ef8 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -68,8 +68,7 @@ iscsi_check_assign_cmdsn(struct iscsi_session *session, struct iscsi_nopin *hdr) | |||
68 | EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn); | 68 | EXPORT_SYMBOL_GPL(iscsi_check_assign_cmdsn); |
69 | 69 | ||
70 | void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, | 70 | void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, |
71 | struct iscsi_data *hdr, | 71 | struct iscsi_data *hdr) |
72 | int transport_data_cnt) | ||
73 | { | 72 | { |
74 | struct iscsi_conn *conn = ctask->conn; | 73 | struct iscsi_conn *conn = ctask->conn; |
75 | 74 | ||
@@ -82,14 +81,12 @@ void iscsi_prep_unsolicit_data_pdu(struct iscsi_cmd_task *ctask, | |||
82 | 81 | ||
83 | hdr->itt = ctask->hdr->itt; | 82 | hdr->itt = ctask->hdr->itt; |
84 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); | 83 | hdr->exp_statsn = cpu_to_be32(conn->exp_statsn); |
85 | 84 | hdr->offset = cpu_to_be32(ctask->unsol_offset); | |
86 | hdr->offset = cpu_to_be32(ctask->total_length - | ||
87 | transport_data_cnt - | ||
88 | ctask->unsol_count); | ||
89 | 85 | ||
90 | if (ctask->unsol_count > conn->max_xmit_dlength) { | 86 | if (ctask->unsol_count > conn->max_xmit_dlength) { |
91 | hton24(hdr->dlength, conn->max_xmit_dlength); | 87 | hton24(hdr->dlength, conn->max_xmit_dlength); |
92 | ctask->data_count = conn->max_xmit_dlength; | 88 | ctask->data_count = conn->max_xmit_dlength; |
89 | ctask->unsol_offset += ctask->data_count; | ||
93 | hdr->flags = 0; | 90 | hdr->flags = 0; |
94 | } else { | 91 | } else { |
95 | hton24(hdr->dlength, ctask->unsol_count); | 92 | hton24(hdr->dlength, ctask->unsol_count); |
@@ -125,6 +122,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
125 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); | 122 | memcpy(hdr->cdb, sc->cmnd, sc->cmd_len); |
126 | memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); | 123 | memset(&hdr->cdb[sc->cmd_len], 0, MAX_COMMAND_SIZE - sc->cmd_len); |
127 | 124 | ||
125 | ctask->data_count = 0; | ||
128 | if (sc->sc_data_direction == DMA_TO_DEVICE) { | 126 | if (sc->sc_data_direction == DMA_TO_DEVICE) { |
129 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; | 127 | hdr->flags |= ISCSI_FLAG_CMD_WRITE; |
130 | /* | 128 | /* |
@@ -143,6 +141,7 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
143 | */ | 141 | */ |
144 | ctask->imm_count = 0; | 142 | ctask->imm_count = 0; |
145 | ctask->unsol_count = 0; | 143 | ctask->unsol_count = 0; |
144 | ctask->unsol_offset = 0; | ||
146 | ctask->unsol_datasn = 0; | 145 | ctask->unsol_datasn = 0; |
147 | 146 | ||
148 | if (session->imm_data_en) { | 147 | if (session->imm_data_en) { |
@@ -156,9 +155,12 @@ static void iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask) | |||
156 | } else | 155 | } else |
157 | zero_data(ctask->hdr->dlength); | 156 | zero_data(ctask->hdr->dlength); |
158 | 157 | ||
159 | if (!session->initial_r2t_en) | 158 | if (!session->initial_r2t_en) { |
160 | ctask->unsol_count = min(session->first_burst, | 159 | ctask->unsol_count = min(session->first_burst, |
161 | ctask->total_length) - ctask->imm_count; | 160 | ctask->total_length) - ctask->imm_count; |
161 | ctask->unsol_offset = ctask->imm_count; | ||
162 | } | ||
163 | |||
162 | if (!ctask->unsol_count) | 164 | if (!ctask->unsol_count) |
163 | /* No unsolicit Data-Out's */ | 165 | /* No unsolicit Data-Out's */ |
164 | ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 166 | ctask->hdr->flags |= ISCSI_FLAG_CMD_FINAL; |
@@ -1520,11 +1522,18 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
1520 | struct iscsi_conn *conn = cls_conn->dd_data; | 1522 | struct iscsi_conn *conn = cls_conn->dd_data; |
1521 | struct iscsi_session *session = conn->session; | 1523 | struct iscsi_session *session = conn->session; |
1522 | 1524 | ||
1523 | if (session == NULL) { | 1525 | if (!session) { |
1524 | printk(KERN_ERR "iscsi: can't start unbound connection\n"); | 1526 | printk(KERN_ERR "iscsi: can't start unbound connection\n"); |
1525 | return -EPERM; | 1527 | return -EPERM; |
1526 | } | 1528 | } |
1527 | 1529 | ||
1530 | if (session->first_burst > session->max_burst) { | ||
1531 | printk("iscsi: invalid burst lengths: " | ||
1532 | "first_burst %d max_burst %d\n", | ||
1533 | session->first_burst, session->max_burst); | ||
1534 | return -EINVAL; | ||
1535 | } | ||
1536 | |||
1528 | spin_lock_bh(&session->lock); | 1537 | spin_lock_bh(&session->lock); |
1529 | conn->c_stage = ISCSI_CONN_STARTED; | 1538 | conn->c_stage = ISCSI_CONN_STARTED; |
1530 | session->state = ISCSI_STATE_LOGGED_IN; | 1539 | session->state = ISCSI_STATE_LOGGED_IN; |