[PATCH 2.6.29-rc] iscsi - add offset and count to alloc_pdu().
From: Karen Xie
Hi, Mike,
I looked through libiscsi.c, libiscsi_tcp.c and iscsi_tcp.c. It does seem to be
a little messy to merge the two functions. Especially the BHS is constructed
after pdu_alloc(), and iscsi_tcp uses the BHS fields in init_pdu().
So I only added the offset and count as additional parameters to alloc_pdu().
So that the pdu payload is known at the time of pdu memory allocation.
Thanks,
Karen
Signed-off-by: Karen Xie
---
drivers/scsi/iscsi_tcp.c|3 +
drivers/scsi/libiscsi.c | 93 +--
drivers/scsi/libiscsi_tcp.c |6 ++
include/scsi/libiscsi.h | 12 +
include/scsi/scsi_transport_iscsi.h |3 +
5 files changed, 67 insertions(+), 50 deletions(-)
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 23808df..7fe0c68 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -458,7 +458,8 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
return 0;
}
-static int iscsi_sw_tcp_pdu_alloc(struct iscsi_task *task, uint8_t opcode)
+static int iscsi_sw_tcp_pdu_alloc(struct iscsi_task *task, uint8_t opcode,
+unsigned int offset, unsigned int count)
{
struct iscsi_tcp_task *tcp_task = task->dd_data;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 257c241..81956ac 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -104,7 +104,6 @@ void iscsi_prep_data_out_pdu(struct iscsi_task *task,
struct iscsi_r2t_info *r2t
struct iscsi_data *hdr)
{
struct iscsi_conn *conn = task->conn;
- unsigned int left = r2t->data_length - r2t->sent;
task->hdr_len = sizeof(struct iscsi_data);
@@ -117,15 +116,11 @@ void iscsi_prep_data_out_pdu(struct iscsi_task *task,
struct iscsi_r2t_info *r2t
hdr->itt = task->hdr_itt;
hdr->exp_statsn = r2t->exp_statsn;
hdr->offset = cpu_to_be32(r2t->data_offset + r2t->sent);
- if (left > conn->max_xmit_dlength) {
- hton24(hdr->dlength, conn->max_xmit_dlength);
- r2t->data_count = conn->max_xmit_dlength;
- hdr->flags = 0;
- } else {
- hton24(hdr->dlength, left);
- r2t->data_count = left;
+ hton24(hdr->dlength, r2t->data_count);
+ if (r2t->data_length == (r2t->sent + r2t->data_count))
hdr->flags = ISCSI_FLAG_CMD_FINAL;
- }
+ else
+ hdr->flags = 0;
conn->dataout_pdus_cnt++;
}
EXPORT_SYMBOL_GPL(iscsi_prep_data_out_pdu);
@@ -225,7 +220,45 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
itt_t itt;
int rc;
- rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD);
+ if (sc->sc_data_direction == DMA_TO_DEVICE) {
+ unsigned out_len = scsi_out(sc)->length;
+ struct iscsi_r2t_info *r2t = &task->unsol_r2t;
+
+ /*
+* Write counters:
+*
+* imm_count bytes to be sent right after
+* SCSI PDU Header
+*
+* unsol_count bytes(as Data-Out) to be sent
+* without R2T ack right after
+* immediate data
+*
+* r2t data_length bytes to be sent via R2T ack's
+*
+* pad_count bytes to be sent as zero-padding
+*/
+ if (session->imm_data_en) {
+ if (out_len >= session->first_burst)
+ task->imm_count = min(session->first_burst,
+ conn->max_xmit_dlength);
+ else
+ task->imm_count = min(out_len,
+ conn->max_xmit_dlength);
+ }
+
+ memset(r2t, 0, sizeof(*r2t));
+ if (!session->initial_r2t_en) {
+ r2t->data_length = min(session->first_burst, out_len) -
+ task->imm_count;
+ r2t->data_offset = task->imm_count;
+ r2t->ttt = cpu_to_be32(ISCSI_RESERVED_TAG);
+ r2t->exp_statsn = cpu_to_be32(conn->exp_statsn);
+ }
+ }
+
+ rc = conn->session->tt->alloc_pdu(task, ISCSI_OP_SCSI_CMD, 0,
+ task->imm_count);
if (rc)
return rc;
hdr = (struct iscsi_cmd *) task->h