summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoropen-iscsi <open-iscsi@d7303112-9cec-0310-bdd2-e83a94d6c2b6>2005-01-12 20:50:28 +0000
committeropen-iscsi <open-iscsi@d7303112-9cec-0310-bdd2-e83a94d6c2b6>2005-01-12 20:50:28 +0000
commit0a6ef24b39b51d897f965cc0ea2e0bfc7d4925bc (patch)
tree0569b065a25571d028d2f7f8a8a3415fedf35f33
parent298da1f38412711cfbb3dfbc15bf60deee63d4d2 (diff)
downloadopen-iscsi-0a6ef24b39b51d897f965cc0ea2e0bfc7d4925bc.tar.gz
iet target works
git-svn-id: svn://svn.berlios.de/open-iscsi@28 d7303112-9cec-0310-bdd2-e83a94d6c2b6
-rw-r--r--TODO3
-rw-r--r--iscsi.conf14
-rw-r--r--iscsi_control.c36
-rw-r--r--iscsi_control.h6
-rw-r--r--iscsi_if.h1
-rw-r--r--iscsi_tcp.c22
-rw-r--r--iscsi_tcp.h1
-rwxr-xr-xiscsiadm35
8 files changed, 75 insertions, 43 deletions
diff --git a/TODO b/TODO
index b874361..0350b2e 100644
--- a/TODO
+++ b/TODO
@@ -28,3 +28,6 @@ fixme:
processing.
* restructure header processing code into set of small functions.
* prefetch in tcp_copy_bits().
+* support residual_count in case of scatter-gather Data-In. As of today, only
+ non-sg Scsi_Cmnd's are working. But I can amazing some target which will
+ send residual_count in the middle of scatter-gather Data-In.
diff --git a/iscsi.conf b/iscsi.conf
index 97eee77..a7e7655 100644
--- a/iscsi.conf
+++ b/iscsi.conf
@@ -1,16 +1,16 @@
-target_name = iqn.2002-07.com.pyxtechnologies.target.s2io
-target_portal = 10.16.16.223:3260,1
+target_name = iqn.2001-04.com.example:storage.disk2.sys1.xyz
+target_portal = 10.16.16.227:3260,1
initiator_name = iqn.com.dima
initiator_alias = dima-um
-isid = '012345'
-first_burst = 8192
-max_recv_dlength = 8192
-max_burst = 4096
+isid = 0x80.0x0000.0x00.0x0001
+first_burst = 262144
+max_recv_dlength = 65536
+max_burst = 262144
max_r2t = 1
max_cnx = 1
erl = 0
initial_r2t_en = 0
-imm_data_en = 0
+imm_data_en = 1
hdrdgst_en = 0
datadgst_en = 0
ifmarker_en = 0
diff --git a/iscsi_control.c b/iscsi_control.c
index a51794d..c8547bc 100644
--- a/iscsi_control.c
+++ b/iscsi_control.c
@@ -27,7 +27,7 @@ static iscsi_provider_t provider_table[ISCSI_PROVIDER_MAX];
static iscsi_initiator_t initiator = {
.sp.initiator_name = "<not specified>",
.sp.initiator_alias = "<not specified>",
- .sp.isid = {0,0,0,0,0,0},
+ .sp.isid = 0x800000000000ULL,
.sp.target_name = "<not specified>",
.sp.target_alias = "<not specified>",
.sp.target_portal = "<not specified>",
@@ -60,7 +60,7 @@ static iscsi_initiator_t initiator = {
static iscsi_param_t param_table[] = {
{1, "initiator_name", &initiator.sp.initiator_name, 0, 0, 1},
{1, "initiator_alias", &initiator.sp.initiator_alias, 0, 0, 1},
- {1, "isid", &initiator.sp.isid, 0, 0, 0},
+ {2, "isid", &initiator.sp.isid, 1, 0x8fffffffffffULL, 0},
{1, "target_name", &initiator.sp.target_name, 0, 0, 0},
{1, "target_alias", &initiator.sp.target_alias, 0, 0, 0},
{1, "target_portal", &initiator.sp.target_portal, 0, 0, 0},
@@ -321,10 +321,11 @@ iscsi_host_class_parameters_show(struct class_device *cdev, char *buf)
session->p.target_address);
count += sprintf(buf+count, "tsih = %d\n", session->p.tsih);
count += sprintf(buf+count, "tpgt = %d\n", session->p.tpgt);
- count += sprintf(buf+count, "isid = %02x.%02x.%02x.%02x.%02x.%02x\n",
- session->p.isid[0], session->p.isid[1],
- session->p.isid[2], session->p.isid[3],
- session->p.isid[4], session->p.isid[5]);
+ count += sprintf(buf+count, "isid = 0x%02x.0x%04x.0x%02x.0x%04x\n",
+ (int)((session->p.isid & 0xffULL)),
+ (int)((session->p.isid & 0xffff00ULL)>>8),
+ (int)((session->p.isid & 0xff000000ULL)>>24),
+ (int)((session->p.isid & 0xffff00000000ULL)>>32));
count += sprintf(buf+count, "time2wait = %d\n",
session->p.time2wait);
count += sprintf(buf+count, "time2retain = %d\n",
@@ -587,9 +588,7 @@ iscsi_add_connection(iscsi_provider_t *provider, int host_no,
goto setparam_fail;
if (provider->ops.start_cnx(cnx->handle)) {
- provider->ops.destroy_cnx(cnx->handle);
- kfree(cnx);
- return -EIO;
+ goto start_cnx_fail;
}
cnx->cid = cid;
@@ -603,6 +602,7 @@ iscsi_add_connection(iscsi_provider_t *provider, int host_no,
return 0;
+start_cnx_fail:
setparam_fail:
provider->ops.destroy_cnx(cnx->handle);
bind_cnx_fail:
@@ -679,6 +679,11 @@ iscsi_control_recv_pdu(iscsi_cnx_h handle, iscsi_hdr_t *hdr, char *data)
iscsi_session_ctrl_t *session = cnx->session;
struct list_head *lh, *n;
+ /* ignore failure during cnx start */
+ if (!session) {
+ return ISCSI_ERR_SNX_FAILED;
+ }
+
/* free pending resources based on received statsn */
spin_lock(&session->freelock);
list_for_each_safe(lh, n, &session->freequeue) {
@@ -758,7 +763,10 @@ iscsi_host_class_initiator_parameters_show(struct class *class, char * buf)
if (p->type == 0) { /* int type */
count += sprintf(buf+count, "%s = %d\n", p->key,
*(int*)p->value);
- } else {
+ } else if (p->type == 2) { /* 64-bit int type */
+ count += sprintf(buf+count, "%s = %llu\n", p->key,
+ *(uint64_t*)p->value);
+ } else { /* string type */
count += sprintf(buf+count, "%s = %s\n", p->key,
(char*)p->value);
}
@@ -798,6 +806,14 @@ iscsi_host_class_initiator_parameters_store(struct class *class,
return count;
}
*(int*)p->value = ival;
+ } else if (p->type == 2) { /* 64-bit int type */
+ uint64_t ival = simple_strtoull(sval, NULL, 0);
+ if (ival < (uint64_t)p->min ||
+ ival > (uint64_t)p->max) {
+ printk("bad range '%s'\n", key);
+ return count;
+ }
+ *(uint64_t*)p->value = ival;
} else { /* string type */
strncpy((char*)p->value, sval, strlen(sval)+1);
}
diff --git a/iscsi_control.h b/iscsi_control.h
index 2fbdaa9..2fd6e90 100644
--- a/iscsi_control.h
+++ b/iscsi_control.h
@@ -98,7 +98,7 @@ typedef struct iscsi_cnx_ctrl {
typedef struct iscsi_session_params {
char initiator_name[ISCSI_NODE_NAME_MAX];
char initiator_alias[ISCSI_ALIAS_NAME_MAX];
- uint8_t isid[7];
+ uint64_t isid;
char target_name[ISCSI_NODE_NAME_MAX];
char target_alias[ISCSI_ALIAS_NAME_MAX];
char target_portal[ISCSI_PORTAL_MAX];
@@ -143,7 +143,7 @@ typedef struct iscsi_session_ctrl {
char target_address[ISCSI_PORTAL_MAX];
uint16_t tpgt;
uint16_t tsih;
- uint8_t isid[6];
+ uint64_t isid;
uint16_t max_cnx;
struct list_head connections; /* connections list */
@@ -174,7 +174,7 @@ typedef struct iscsi_param {
int type; /* 0 - int, 1 - string */
char key[32];
void *value;
- uint32_t min, max; /* range for int */
+ uint64_t min, max; /* ranges for uint and uint64 */
int show;
} iscsi_param_t;
diff --git a/iscsi_if.h b/iscsi_if.h
index d316227..4d2e83b 100644
--- a/iscsi_if.h
+++ b/iscsi_if.h
@@ -70,6 +70,7 @@ typedef enum {
ISCSI_ERR_BAD_ITT = ISCSI_DP_ERR_BASE + 11,
ISCSI_ERR_CNX_FAILED = ISCSI_DP_ERR_BASE + 12,
ISCSI_ERR_R2TSN = ISCSI_DP_ERR_BASE + 13,
+ ISCSI_ERR_SNX_FAILED = ISCSI_DP_ERR_BASE + 14,
} iscsi_err_e;
/*
diff --git a/iscsi_tcp.c b/iscsi_tcp.c
index 8d94dff..2816e71 100644
--- a/iscsi_tcp.c
+++ b/iscsi_tcp.c
@@ -24,8 +24,8 @@ MODULE_DESCRIPTION("iSCSI/TCP data-path");
MODULE_LICENSE("GPL");
#define DEBUG_PREV_PDU
-/* #define DEBUG_TCP */
-/* #define DEBUG_SCSI */
+#define DEBUG_TCP
+#define DEBUG_SCSI
#define DEBUG_ASSERT
#ifdef DEBUG_TCP
@@ -1103,11 +1103,11 @@ iscsi_data_recv(iscsi_conn_t *conn)
}
}
} else {
- if (iscsi_ctask_copy(conn, ctask, sc->request_buffer,
- sc->request_bufflen)) {
- rc = -EAGAIN;
+ if ((rc = iscsi_ctask_copy(conn, ctask, sc->request_buffer,
+ sc->request_bufflen)) == -EAGAIN) {
goto exit;
}
+ rc = 0;
}
/* check for nonexceptional status */
@@ -1297,10 +1297,7 @@ iscsi_cmd_rsp(iscsi_conn_t *conn, iscsi_cmd_task_t *ctask)
rc = ISCSI_ERR_BAD_TARGET;
goto fault;
} else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
- sc->result = host_byte(DID_ERROR) |
- status_byte(rhdr->cmd_status);
- rc = ISCSI_ERR_BAD_TARGET;
- goto fault;
+ sc->resid = ntohl(rhdr->residual_count);
}
}
} else {
@@ -1389,9 +1386,7 @@ iscsi_data_rsp(iscsi_conn_t *conn, iscsi_cmd_task_t *ctask)
rhdr->cmd_status;
return ISCSI_ERR_BAD_TARGET;
} else if (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW) {
- sc->result = (DID_ERROR << 16) |
- rhdr->cmd_status;
- return ISCSI_ERR_BAD_TARGET;
+ sc->resid = ntohl(rhdr->residual_count);
}
}
@@ -2050,8 +2045,7 @@ iscsi_conn_create(iscsi_snx_h snxh, iscsi_cnx_h handle,
}
/*
- * Do Logout request, terminate connection queus, free
- * all associated resources
+ * Terminate connection queues, free all associated resources
*/
static void
iscsi_conn_destroy(iscsi_cnx_h cnxh)
diff --git a/iscsi_tcp.h b/iscsi_tcp.h
index cd8ed7e..a736eff 100644
--- a/iscsi_tcp.h
+++ b/iscsi_tcp.h
@@ -191,7 +191,6 @@ typedef struct iscsi_session {
/* control data */
struct scsi_host_template sht;
struct Scsi_Host *host;
- uint8_t isid[6];
int id;
iscsi_conn_t *leadconn; /* Leading Conn. */
spinlock_t conn_lock;
diff --git a/iscsiadm b/iscsiadm
index b20d206..c203954 100755
--- a/iscsiadm
+++ b/iscsiadm
@@ -34,7 +34,7 @@ my $sysfs_path = "/sys/class/iscsi";
#
my $initiator_name = "iqn.com.dima";
my $initiator_alias = "dima-um";
-my @isid = ('0', '1', '2', '3', '4', '5');
+my @isid = (0x80, 0x0000, 0x00, 0x0001);
my $first_burst = 262144;
my $max_recv_dlength = 65536;
my $max_burst = 262144;
@@ -172,7 +172,7 @@ sub padding {
sub send_login_req {
my ($cmdsn, $exp_statsn, $flags, $cid, $data) = @_;
my $dlength = length($data);
- my $loginpdu = pack('CCCCCCCCccccccnNnccNNNNNN',
+ my $loginpdu = pack('CCCCCCCCCnCnnNnccNNNNNN',
0x43, # C: opcode: Login + Immediate
0x87, # C: flags T, OP, FF
0, # C: max ver
@@ -181,8 +181,7 @@ sub send_login_req {
($dlength >> 16) & 0xFF, # C: byte 0 of dlength
($dlength >> 8) & 0xFF, # C: byte 1 of dlength
$dlength & 0xFF, # C: byte 2 of dlength
- @isid[0],@isid[1],@isid[2],@isid[3],@isid[4],@isid[5],
- # cccccc: isid
+ $isid[0],$isid[1],$isid[2],$isid[3], # CnCn: CID
$tsih, # n: tsih
0, # N: itt
$cid, # n: cid
@@ -622,6 +621,24 @@ sub logout {
operation("tcp session remove $sid") || exit 1;
}
+sub read_isid {
+ my ($in_isid) = @_;
+ my @out_isid;
+
+ if ($in_isid =~
+ /(0x)?([0-9a-fA-F]+)\.(0x)?([0-9a-fA-F]+)\.(0x)?([0-9a-fA-F]+)\.(0x)?([0-9a-fA-F]+)/) {
+ $out_isid[0] = $1 ? hex($2) : $2+0;
+ $out_isid[1] = $3 ? hex($4) : $4+0;
+ $out_isid[2] = $5 ? hex($6) : $6+0;
+ $out_isid[3] = $7 ? hex($8) : $8+0;
+ } else {
+ fatal "can not recognize ISID format! ".
+ "Expecting 'A.B.C.D', got '$in_isid'";
+ }
+
+ return @out_isid;
+}
+
sub sysfs_save {
setparam(-1, "initiator_name", $initiator_name);
setparam(-1, "initiator_alias", $initiator_alias);
@@ -660,7 +677,7 @@ sub sysfs_restore {
$initiator_name = getparam(-1, "initiator_name");
$initiator_alias = getparam(-1, "initiator_alias");
- @isid = getparam($id, "isid");
+ @isid = read_isid(getparam($id, "isid"));
$tsih = getparam($id, "tsih");
$target_name = getparam($id, "target_name");
$target_alias = getparam($id, "target_alias");
@@ -701,7 +718,7 @@ sub config_read {
$target_portal = $conf{target_portal};
$initiator_name = $conf{initiator_name};
$initiator_alias = $conf{initiator_alias};
- @isid = $conf{isid};
+ @isid = read_isid($conf{isid});
$first_burst = $conf{first_burst};
$max_recv_dlength = $conf{max_recv_dlength};
$max_burst = $conf{max_burst};
@@ -895,16 +912,18 @@ if ($opt{v}) {
} else {
usage();
}
+ exit;
} else {
if ($opt{d}) {
#
# Do SendTargets method discovery
#
sendtargets_discovery(\&discovery_login_cb, $opt{d});
- } else {
- show_sessions();
+ exit;
}
}
if ($opt{l}) {
discovery_login_cb(0, $target_name, $target_portal);
+ exit;
}
+show_sessions();