summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2008-02-07 23:46:26 +0100
committerMichael Brown2008-02-07 23:46:26 +0100
commit428c6342bcdc61008b9cd07f6becf19d29da1564 (patch)
tree8b589a608b899b9962994e6728099a1449b52afa
parentStart restructuring pxe_tftp.c to cope with multicast (MTFTP) receives. (diff)
downloadipxe-428c6342bcdc61008b9cd07f6becf19d29da1564.tar.gz
ipxe-428c6342bcdc61008b9cd07f6becf19d29da1564.tar.xz
ipxe-428c6342bcdc61008b9cd07f6becf19d29da1564.zip
Fixes for EqualLogic iSCSI targets:
Allow port numbers in iSCSI redirection. Wait for SCSI status, not just the final data-in (which may be followed by an explicit SCSI Response PDU if the S bit is not set).
-rw-r--r--src/net/tcp/iscsi.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index ff1478e4..cf6c7f5f 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -270,7 +270,7 @@ static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi,
*/
static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
const void *data, size_t len,
- size_t remaining __unused ) {
+ size_t remaining ) {
struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
unsigned long offset;
@@ -281,14 +281,16 @@ static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
assert ( ( offset + len ) <= iscsi->command->data_in_len );
copy_to_user ( iscsi->command->data_in, offset, data, len );
- /* Record SCSI status, if present */
- if ( data_in->flags & ISCSI_DATA_FLAG_STATUS )
- iscsi->command->status = data_in->status;
+ /* Wait for whole SCSI response to arrive */
+ if ( remaining )
+ return 0;
- /* If this is the end, flag as complete */
- if ( ( offset + len ) == iscsi->command->data_in_len ) {
+ /* Mark as completed if status is present */
+ if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
+ assert ( ( offset + len ) == iscsi->command->data_in_len );
assert ( data_in->flags & ISCSI_FLAG_FINAL );
- assert ( remaining == 0 );
+ iscsi->command->status = data_in->status;
+ /* iSCSI cannot return an error status via a data-in */
iscsi_scsi_done ( iscsi, 0 );
}
@@ -568,6 +570,7 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
*/
static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
const char *value ) {
+ char *separator;
DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
@@ -576,6 +579,15 @@ static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
iscsi->target_address = strdup ( value );
if ( ! iscsi->target_address )
return -ENOMEM;
+
+ /* Replace target port */
+ iscsi->target_port = htons ( ISCSI_PORT );
+ separator = strchr ( iscsi->target_address, ':' );
+ if ( separator ) {
+ *separator = '\0';
+ iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
+ }
+
return 0;
}