| 
				
			 | 
			
			
				
				@@ -33,6 +33,8 @@ 
			 | 
		
		
	
		
			
			| 
				33
			 | 
			
				33
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				34
			 | 
			
				34
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				35
			 | 
			
				35
			 | 
			
			
				
				 static void iscsi_start_tx ( struct iscsi_session *iscsi ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				36
			 | 
			
			
				
				+static void iscsi_start_data_out ( struct iscsi_session *iscsi, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				37
			 | 
			
			
				
				+				   unsigned int datasn ); 
			 | 
		
		
	
		
			
			| 
				36
			 | 
			
				38
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				37
			 | 
			
				39
			 | 
			
			
				
				 /**************************************************************************** 
			 | 
		
		
	
		
			
			| 
				38
			 | 
			
				40
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -44,6 +46,11 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ); 
			 | 
		
		
	
		
			
			| 
				44
			 | 
			
				46
			 | 
			
			
				
				  * Build iSCSI SCSI command BHS 
			 | 
		
		
	
		
			
			| 
				45
			 | 
			
				47
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				46
			 | 
			
				48
			 | 
			
			
				
				  * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				49
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				50
			 | 
			
			
				
				+ * We don't currently support bidirectional commands (i.e. with both 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				51
			 | 
			
			
				
				+ * Data-In and Data-Out segments); these would require providing code 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				52
			 | 
			
			
				
				+ * to generate an AHS, and there doesn't seem to be any need for it at 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				53
			 | 
			
			
				
				+ * the moment. 
			 | 
		
		
	
		
			
			| 
				47
			 | 
			
				54
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				48
			 | 
			
				55
			 | 
			
			
				
				 static void iscsi_start_command ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				49
			 | 
			
				56
			 | 
			
			
				
				 	struct iscsi_bhs_scsi_command *command = &iscsi->tx_bhs.scsi_command; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -59,21 +66,49 @@ static void iscsi_start_command ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				59
			 | 
			
				66
			 | 
			
			
				
				 		command->flags |= ISCSI_COMMAND_FLAG_READ; 
			 | 
		
		
	
		
			
			| 
				60
			 | 
			
				67
			 | 
			
			
				
				 	if ( iscsi->command->data_out ) 
			 | 
		
		
	
		
			
			| 
				61
			 | 
			
				68
			 | 
			
			
				
				 		command->flags |= ISCSI_COMMAND_FLAG_WRITE; 
			 | 
		
		
	
		
			
			| 
				62
			 | 
			
				
			 | 
			
			
				
				-	ISCSI_SET_LENGTHS ( command->lengths, 0, iscsi->command->data_out_len); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				69
			 | 
			
			
				
				+	/* lengths left as zero */ 
			 | 
		
		
	
		
			
			| 
				63
			 | 
			
				70
			 | 
			
			
				
				 	command->lun = iscsi->lun; 
			 | 
		
		
	
		
			
			| 
				64
			 | 
			
				
			 | 
			
			
				
				-	command->itt = htonl ( iscsi->itt ); 
			 | 
		
		
	
		
			
			| 
				65
			 | 
			
				
			 | 
			
			
				
				-	command->exp_len = htonl ( iscsi->command->data_in_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				71
			 | 
			
			
				
				+	command->itt = htonl ( ++iscsi->itt ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				72
			 | 
			
			
				
				+	command->exp_len = htonl ( iscsi->command->data_in_len | 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				73
			 | 
			
			
				
				+				   iscsi->command->data_out_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				74
			 | 
			
			
				
				+	command->cmdsn = htonl ( iscsi->cmdsn ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				75
			 | 
			
			
				
				+	command->expstatsn = htonl ( iscsi->statsn + 1 ); 
			 | 
		
		
	
		
			
			| 
				66
			 | 
			
				76
			 | 
			
			
				
				 	memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb )); 
			 | 
		
		
	
		
			
			| 
				67
			 | 
			
				77
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				68
			 | 
			
				78
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				69
			 | 
			
				79
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				70
			 | 
			
				
			 | 
			
			
				
				- * Send iSCSI SCSI command data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				80
			 | 
			
			
				
				+ * Receive data segment of an iSCSI SCSI response PDU 
			 | 
		
		
	
		
			
			| 
				71
			 | 
			
				81
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				72
			 | 
			
				82
			 | 
			
			
				
				  * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				83
			 | 
			
			
				
				+ * @v data		Received data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				84
			 | 
			
			
				
				+ * @v len		Length of received data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				85
			 | 
			
			
				
				+ * @v remaining		Data remaining after this data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				86
			 | 
			
			
				
				+ *  
			 | 
		
		
	
		
			
			| 
				73
			 | 
			
				87
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				74
			 | 
			
				
			 | 
			
			
				
				-static void iscsi_tx_command ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				75
			 | 
			
				
			 | 
			
			
				
				-	tcp_send ( &iscsi->tcp, iscsi->command->data_out + iscsi->tx_offset, 
			 | 
		
		
	
		
			
			| 
				76
			 | 
			
				
			 | 
			
			
				
				-		   iscsi->command->data_out_len - iscsi->tx_offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				88
			 | 
			
			
				
				+static void iscsi_rx_scsi_response ( struct iscsi_session *iscsi, void *data, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				89
			 | 
			
			
				
				+				     size_t len, size_t remaining ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				90
			 | 
			
			
				
				+	struct iscsi_bhs_scsi_response *response 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				91
			 | 
			
			
				
				+		= &iscsi->rx_bhs.scsi_response; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				92
			 | 
			
			
				
				+	int sense_offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				93
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				94
			 | 
			
			
				
				+	/* Capture the sense response code as it floats past, if present */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				95
			 | 
			
			
				
				+	sense_offset = ISCSI_SENSE_RESPONSE_CODE_OFFSET - iscsi->rx_offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				96
			 | 
			
			
				
				+	if ( ( sense_offset >= 0 ) && len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				97
			 | 
			
			
				
				+		iscsi->command->sense_response = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				98
			 | 
			
			
				
				+			* ( ( char * ) data + sense_offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				99
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				100
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				101
			 | 
			
			
				
				+	/* Wait for whole SCSI response to arrive */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				102
			 | 
			
			
				
				+	if ( remaining ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				103
			 | 
			
			
				
				+		return; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				104
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				105
			 | 
			
			
				
				+	/* Record SCSI status code */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				106
			 | 
			
			
				
				+	iscsi->command->status = response->status; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				107
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				108
			 | 
			
			
				
				+	/* Mark as completed, with error if applicable */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				109
			 | 
			
			
				
				+	iscsi->status |= ISCSI_STATUS_DONE; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				110
			 | 
			
			
				
				+	if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				111
			 | 
			
			
				
				+		iscsi->status |= ISCSI_STATUS_ERR; 
			 | 
		
		
	
		
			
			| 
				77
			 | 
			
				112
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				78
			 | 
			
				113
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				79
			 | 
			
				114
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -86,7 +121,7 @@ static void iscsi_tx_command ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				86
			 | 
			
				121
			 | 
			
			
				
				  *  
			 | 
		
		
	
		
			
			| 
				87
			 | 
			
				122
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				88
			 | 
			
				123
			 | 
			
			
				
				 static void iscsi_rx_data_in ( struct iscsi_session *iscsi, void *data, 
			 | 
		
		
	
		
			
			| 
				89
			 | 
			
				
			 | 
			
			
				
				-			       size_t len, size_t remaining ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				124
			 | 
			
			
				
				+			       size_t len, size_t remaining __unused ) { 
			 | 
		
		
	
		
			
			| 
				90
			 | 
			
				125
			 | 
			
			
				
				 	struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in; 
			 | 
		
		
	
		
			
			| 
				91
			 | 
			
				126
			 | 
			
			
				
				 	unsigned long offset; 
			 | 
		
		
	
		
			
			| 
				92
			 | 
			
				127
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -97,9 +132,109 @@ static void iscsi_rx_data_in ( struct iscsi_session *iscsi, void *data, 
			 | 
		
		
	
		
			
			| 
				97
			 | 
			
				132
			 | 
			
			
				
				 	assert ( ( offset + len ) <= iscsi->command->data_in_len ); 
			 | 
		
		
	
		
			
			| 
				98
			 | 
			
				133
			 | 
			
			
				
				 	memcpy ( ( iscsi->command->data_in + offset ), data, len ); 
			 | 
		
		
	
		
			
			| 
				99
			 | 
			
				134
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				
				+	/* Record SCSI status, if present */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+	if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				137
			 | 
			
			
				
				+		iscsi->command->status = data_in->status; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				138
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				100
			 | 
			
				139
			 | 
			
			
				
				 	/* If this is the end, flag as complete */ 
			 | 
		
		
	
		
			
			| 
				101
			 | 
			
				
			 | 
			
			
				
				-	if ( ( data_in->flags & ISCSI_FLAG_FINAL ) && ( remaining == 0 ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+	if ( ( offset + len ) == iscsi->command->data_in_len ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+		assert ( data_in->flags & ISCSI_FLAG_FINAL ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				142
			 | 
			
			
				
				+		assert ( remaining == 0 ); 
			 | 
		
		
	
		
			
			| 
				102
			 | 
			
				143
			 | 
			
			
				
				 		iscsi->status |= ISCSI_STATUS_DONE; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				144
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				145
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				146
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				147
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				148
			 | 
			
			
				
				+ * Receive data segment of an iSCSI R2T PDU 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				149
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				150
			 | 
			
			
				
				+ * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				151
			 | 
			
			
				
				+ * @v data		Received data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				152
			 | 
			
			
				
				+ * @v len		Length of received data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				153
			 | 
			
			
				
				+ * @v remaining		Data remaining after this data 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				154
			 | 
			
			
				
				+ *  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				155
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				156
			 | 
			
			
				
				+static void iscsi_rx_r2t ( struct iscsi_session *iscsi, void *data __unused, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				157
			 | 
			
			
				
				+			   size_t len __unused, size_t remaining __unused ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				158
			 | 
			
			
				
				+	struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				159
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				160
			 | 
			
			
				
				+	/* Record transfer parameters and trigger first data-out */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				161
			 | 
			
			
				
				+	iscsi->ttt = ntohl ( r2t->ttt ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				162
			 | 
			
			
				
				+	iscsi->transfer_offset = ntohl ( r2t->offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				163
			 | 
			
			
				
				+	iscsi->transfer_len = ntohl ( r2t->len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				164
			 | 
			
			
				
				+	iscsi_start_data_out ( iscsi, 0 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				165
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				166
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				167
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				168
			 | 
			
			
				
				+ * Build iSCSI data-out BHS 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				169
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				170
			 | 
			
			
				
				+ * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				171
			 | 
			
			
				
				+ * @v datasn		Data sequence number within the transfer 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				172
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				173
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				174
			 | 
			
			
				
				+static void iscsi_start_data_out ( struct iscsi_session *iscsi, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				175
			 | 
			
			
				
				+				   unsigned int datasn ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				176
			 | 
			
			
				
				+	struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				177
			 | 
			
			
				
				+	unsigned long offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				178
			 | 
			
			
				
				+	unsigned long remaining; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				179
			 | 
			
			
				
				+	unsigned long len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				180
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				181
			 | 
			
			
				
				+	/* We always send 512-byte Data-Out PDUs; this removes the 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				182
			 | 
			
			
				
				+	 * need to worry about the target's MaxRecvDataSegmentLength. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				183
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				184
			 | 
			
			
				
				+	offset = datasn * 512; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				185
			 | 
			
			
				
				+	remaining = iscsi->transfer_len - offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				186
			 | 
			
			
				
				+	len = remaining; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				187
			 | 
			
			
				
				+	if ( len > 512 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				188
			 | 
			
			
				
				+		len = 512; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				189
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				190
			 | 
			
			
				
				+	/* Construct BHS and initiate transmission */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				191
			 | 
			
			
				
				+	iscsi_start_tx ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				192
			 | 
			
			
				
				+	data_out->opcode = ISCSI_OPCODE_DATA_OUT; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				193
			 | 
			
			
				
				+	if ( len == remaining ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				194
			 | 
			
			
				
				+		data_out->flags = ( ISCSI_FLAG_FINAL ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				195
			 | 
			
			
				
				+	ISCSI_SET_LENGTHS ( data_out->lengths, 0, len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				196
			 | 
			
			
				
				+	data_out->lun = iscsi->lun; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				197
			 | 
			
			
				
				+	data_out->itt = htonl ( iscsi->itt ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+	data_out->ttt = htonl ( iscsi->ttt ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+	data_out->expstatsn = htonl ( iscsi->statsn + 1 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				200
			 | 
			
			
				
				+	data_out->datasn = htonl ( datasn ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				201
			 | 
			
			
				
				+	data_out->offset = htonl ( iscsi->transfer_offset + offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				202
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				203
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				204
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				205
			 | 
			
			
				
				+ * Complete iSCSI data-out PDU transmission 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+ * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+static void iscsi_data_out_done ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+	struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				213
			 | 
			
			
				
				+	/* If we haven't reached the end of the sequence, start 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				214
			 | 
			
			
				
				+	 * sending the next data-out PDU. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				215
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				216
			 | 
			
			
				
				+	if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				217
			 | 
			
			
				
				+		iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				218
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				219
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				220
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				221
			 | 
			
			
				
				+ * Send iSCSI data-out data segment 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				222
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				223
			 | 
			
			
				
				+ * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				224
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				225
			 | 
			
			
				
				+static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				226
			 | 
			
			
				
				+	struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				227
			 | 
			
			
				
				+	unsigned long offset; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				228
			 | 
			
			
				
				+	unsigned long len; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				229
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				230
			 | 
			
			
				
				+	offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) + 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				231
			 | 
			
			
				
				+		   iscsi->tx_offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				232
			 | 
			
			
				
				+	len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				233
			 | 
			
			
				
				+	assert ( iscsi->command != NULL ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				234
			 | 
			
			
				
				+	assert ( iscsi->command->data_out != NULL ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				235
			 | 
			
			
				
				+	assert ( ( offset + len ) <= iscsi->command->data_out_len ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				236
			 | 
			
			
				
				+	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				237
			 | 
			
			
				
				+	tcp_send ( &iscsi->tcp, iscsi->command->data_out + offset, len ); 
			 | 
		
		
	
		
			
			| 
				103
			 | 
			
				238
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				104
			 | 
			
				239
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				105
			 | 
			
				240
			 | 
			
			
				
				 /**************************************************************************** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -121,11 +256,11 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi, 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				256
			 | 
			
			
				
				 	return snprintf ( data, len, 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				257
			 | 
			
			
				
				 			  "InitiatorName=%s%c" 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				258
			 | 
			
			
				
				 			  "TargetName=%s%c" 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				
			 | 
			
			
				
				-			  "MaxRecvDataSegmentLength=512%c" 
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				259
			 | 
			
			
				
				 			  "SessionType=Normal%c" 
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				260
			 | 
			
			
				
				 			  "DataDigest=None%c" 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				261
			 | 
			
			
				
				 			  "HeaderDigest=None%c" 
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				
			 | 
			
			
				
				-			  "ErrorRecoveryLevel=0%c", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				262
			 | 
			
			
				
				+			  "DefaultTime2Wait=0%c" 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				263
			 | 
			
			
				
				+			  "DefaultTime2Retain=0%c", 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				264
			 | 
			
			
				
				 			  iscsi->initiator, 0, iscsi->target, 0, 
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				265
			 | 
			
			
				
				 			  0, 0, 0, 0, 0 ); 
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				266
			 | 
			
			
				
				 } 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -134,7 +269,7 @@ static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi, 
			 | 
		
		
	
		
			
			| 
				134
			 | 
			
				269
			 | 
			
			
				
				  * Build iSCSI login request BHS 
			 | 
		
		
	
		
			
			| 
				135
			 | 
			
				270
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				136
			 | 
			
				271
			 | 
			
			
				
				  * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				137
			 | 
			
				
			 | 
			
			
				
				- * @v first		Login request is the first request of a session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				272
			 | 
			
			
				
				+ * @v first		Login request is the first in a sequence 
			 | 
		
		
	
		
			
			| 
				138
			 | 
			
				273
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				139
			 | 
			
				274
			 | 
			
			
				
				 static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) { 
			 | 
		
		
	
		
			
			| 
				140
			 | 
			
				275
			 | 
			
			
				
				 	struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -156,8 +291,12 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) { 
			 | 
		
		
	
		
			
			| 
				156
			 | 
			
				291
			 | 
			
			
				
				 					IANA_EN_FEN_SYSTEMS ); 
			 | 
		
		
	
		
			
			| 
				157
			 | 
			
				292
			 | 
			
			
				
				 	/* isid_iana_qual left as zero */ 
			 | 
		
		
	
		
			
			| 
				158
			 | 
			
				293
			 | 
			
			
				
				 	request->tsih = htons ( iscsi->tsih ); 
			 | 
		
		
	
		
			
			| 
				159
			 | 
			
				
			 | 
			
			
				
				-	/* itt left as zero */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				294
			 | 
			
			
				
				+	if ( first ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				295
			 | 
			
			
				
				+		iscsi->itt++; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				296
			 | 
			
			
				
				+	request->itt = htonl ( iscsi->itt ); 
			 | 
		
		
	
		
			
			| 
				160
			 | 
			
				297
			 | 
			
			
				
				 	/* cid left as zero */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				298
			 | 
			
			
				
				+	request->cmdsn = htonl ( iscsi->cmdsn ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				299
			 | 
			
			
				
				+	request->expstatsn = htonl ( iscsi->statsn + 1 ); 
			 | 
		
		
	
		
			
			| 
				161
			 | 
			
				300
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				162
			 | 
			
				301
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				163
			 | 
			
				302
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -240,8 +379,6 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				240
			 | 
			
				379
			 | 
			
			
				
				 	 
			 | 
		
		
	
		
			
			| 
				241
			 | 
			
				380
			 | 
			
			
				
				 	/* Initialise TX BHS */ 
			 | 
		
		
	
		
			
			| 
				242
			 | 
			
				381
			 | 
			
			
				
				 	memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) ); 
			 | 
		
		
	
		
			
			| 
				243
			 | 
			
				
			 | 
			
			
				
				-	iscsi->tx_bhs.common_request.cmdsn = htonl ( iscsi->cmdsn ); 
			 | 
		
		
	
		
			
			| 
				244
			 | 
			
				
			 | 
			
			
				
				-	iscsi->tx_bhs.common_request.expstatsn = htonl ( iscsi->statsn + 1 ); 
			 | 
		
		
	
		
			
			| 
				245
			 | 
			
				382
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				246
			 | 
			
				383
			 | 
			
			
				
				 	/* Flag TX engine to start transmitting */ 
			 | 
		
		
	
		
			
			| 
				247
			 | 
			
				384
			 | 
			
			
				
				 	iscsi->tx_state = ISCSI_TX_BHS; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -260,8 +397,8 @@ static void iscsi_tx_data ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				260
			 | 
			
				397
			 | 
			
			
				
				 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 
			 | 
		
		
	
		
			
			| 
				261
			 | 
			
				398
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				262
			 | 
			
				399
			 | 
			
			
				
				 	switch ( common->opcode & ISCSI_OPCODE_MASK ) { 
			 | 
		
		
	
		
			
			| 
				263
			 | 
			
				
			 | 
			
			
				
				-	case ISCSI_OPCODE_SCSI_COMMAND: 
			 | 
		
		
	
		
			
			| 
				264
			 | 
			
				
			 | 
			
			
				
				-		iscsi_tx_command ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				400
			 | 
			
			
				
				+	case ISCSI_OPCODE_DATA_OUT: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				401
			 | 
			
			
				
				+		iscsi_tx_data_out ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				265
			 | 
			
				402
			 | 
			
			
				
				 		break; 
			 | 
		
		
	
		
			
			| 
				266
			 | 
			
				403
			 | 
			
			
				
				 	case ISCSI_OPCODE_LOGIN_REQUEST: 
			 | 
		
		
	
		
			
			| 
				267
			 | 
			
				404
			 | 
			
			
				
				 		iscsi_tx_login_request ( iscsi ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -272,6 +409,27 @@ static void iscsi_tx_data ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				272
			 | 
			
				409
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				273
			 | 
			
				410
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				274
			 | 
			
				411
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				412
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				413
			 | 
			
			
				
				+ * Complete iSCSI PDU transmission 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				414
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				415
			 | 
			
			
				
				+ * @v iscsi		iSCSI session 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				416
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				417
			 | 
			
			
				
				+ * Called when a PDU has been completely transmitted and the TX state 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				418
			 | 
			
			
				
				+ * machine is about to enter the idle state.  iscsi::tx_bhs will be 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				419
			 | 
			
			
				
				+ * valid for the just-completed PDU when this is called. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				420
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				421
			 | 
			
			
				
				+static void iscsi_tx_done ( struct iscsi_session *iscsi ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				422
			 | 
			
			
				
				+	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				423
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				424
			 | 
			
			
				
				+	switch ( common->opcode & ISCSI_OPCODE_MASK ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				425
			 | 
			
			
				
				+	case ISCSI_OPCODE_DATA_OUT: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				426
			 | 
			
			
				
				+		iscsi_data_out_done ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				427
			 | 
			
			
				
				+	default: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				428
			 | 
			
			
				
				+		/* No action */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				429
			 | 
			
			
				
				+		break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				430
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				431
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				432
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				275
			 | 
			
				433
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				276
			 | 
			
				434
			 | 
			
			
				
				  * Handle TCP ACKs 
			 | 
		
		
	
		
			
			| 
				277
			 | 
			
				435
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -318,9 +476,14 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				318
			 | 
			
				476
			 | 
			
			
				
				 		 */ 
			 | 
		
		
	
		
			
			| 
				319
			 | 
			
				477
			 | 
			
			
				
				 		if ( iscsi->tx_offset != max_tx_offset ) 
			 | 
		
		
	
		
			
			| 
				320
			 | 
			
				478
			 | 
			
			
				
				 			return; 
			 | 
		
		
	
		
			
			| 
				321
			 | 
			
				
			 | 
			
			
				
				-		 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				479
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				480
			 | 
			
			
				
				+		/* Move to next state.  Call iscsi_tx_done() when PDU 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				481
			 | 
			
			
				
				+		 * transmission is complete. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				482
			 | 
			
			
				
				+		 */ 
			 | 
		
		
	
		
			
			| 
				322
			 | 
			
				483
			 | 
			
			
				
				 		iscsi->tx_state = next_state; 
			 | 
		
		
	
		
			
			| 
				323
			 | 
			
				484
			 | 
			
			
				
				 		iscsi->tx_offset = 0; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				485
			 | 
			
			
				
				+		if ( next_state == ISCSI_TX_IDLE ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				486
			 | 
			
			
				
				+			iscsi_tx_done ( iscsi ); 
			 | 
		
		
	
		
			
			| 
				324
			 | 
			
				487
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				325
			 | 
			
				488
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				326
			 | 
			
				489
			 | 
			
			
				
				  
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -381,17 +544,19 @@ static void iscsi_rx_data ( struct iscsi_session *iscsi, void *data, 
			 | 
		
		
	
		
			
			| 
				381
			 | 
			
				544
			 | 
			
			
				
				 	iscsi->cmdsn = ntohl ( response->expcmdsn ); 
			 | 
		
		
	
		
			
			| 
				382
			 | 
			
				545
			 | 
			
			
				
				 	iscsi->statsn = ntohl ( response->statsn ); 
			 | 
		
		
	
		
			
			| 
				383
			 | 
			
				546
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				384
			 | 
			
				
			 | 
			
			
				
				-	/* Increment itt when we receive a final response */ 
			 | 
		
		
	
		
			
			| 
				385
			 | 
			
				
			 | 
			
			
				
				-	if ( response->flags & ISCSI_FLAG_FINAL ) 
			 | 
		
		
	
		
			
			| 
				386
			 | 
			
				
			 | 
			
			
				
				-		iscsi->itt++; 
			 | 
		
		
	
		
			
			| 
				387
			 | 
			
				
			 | 
			
			
				
				- 
			 | 
		
		
	
		
			
			| 
				388
			 | 
			
				547
			 | 
			
			
				
				 	switch ( response->opcode & ISCSI_OPCODE_MASK ) { 
			 | 
		
		
	
		
			
			| 
				389
			 | 
			
				548
			 | 
			
			
				
				 	case ISCSI_OPCODE_LOGIN_RESPONSE: 
			 | 
		
		
	
		
			
			| 
				390
			 | 
			
				549
			 | 
			
			
				
				 		iscsi_rx_login_response ( iscsi, data, len, remaining ); 
			 | 
		
		
	
		
			
			| 
				391
			 | 
			
				550
			 | 
			
			
				
				 		break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				551
			 | 
			
			
				
				+	case ISCSI_OPCODE_SCSI_RESPONSE: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				552
			 | 
			
			
				
				+		iscsi_rx_scsi_response ( iscsi, data, len, remaining ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				553
			 | 
			
			
				
				+		break; 
			 | 
		
		
	
		
			
			| 
				392
			 | 
			
				554
			 | 
			
			
				
				 	case ISCSI_OPCODE_DATA_IN: 
			 | 
		
		
	
		
			
			| 
				393
			 | 
			
				555
			 | 
			
			
				
				 		iscsi_rx_data_in ( iscsi, data, len, remaining ); 
			 | 
		
		
	
		
			
			| 
				394
			 | 
			
				556
			 | 
			
			
				
				 		break; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				557
			 | 
			
			
				
				+	case ISCSI_OPCODE_R2T: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				558
			 | 
			
			
				
				+		iscsi_rx_r2t ( iscsi, data, len, remaining ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				559
			 | 
			
			
				
				+		break; 
			 | 
		
		
	
		
			
			| 
				395
			 | 
			
				560
			 | 
			
			
				
				 	default: 
			 | 
		
		
	
		
			
			| 
				396
			 | 
			
				561
			 | 
			
			
				
				 		printf ( "Unknown iSCSI opcode %02x\n", response->opcode ); 
			 | 
		
		
	
		
			
			| 
				397
			 | 
			
				562
			 | 
			
			
				
				 		iscsi->status |= ( ISCSI_STATUS_DONE | ISCSI_STATUS_ERR ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -521,6 +686,7 @@ static void iscsi_closed ( struct tcp_connection *conn, int status __unused ) { 
			 | 
		
		
	
		
			
			| 
				521
			 | 
			
				686
			 | 
			
			
				
				 	if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) { 
			 | 
		
		
	
		
			
			| 
				522
			 | 
			
				687
			 | 
			
			
				
				 		tcp_connect ( conn ); 
			 | 
		
		
	
		
			
			| 
				523
			 | 
			
				688
			 | 
			
			
				
				 	} else { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				689
			 | 
			
			
				
				+		printf ( "iSCSI retry count exceeded\n" ); 
			 | 
		
		
	
		
			
			| 
				524
			 | 
			
				690
			 | 
			
			
				
				 		iscsi->status |= ( ISCSI_STATUS_DONE | ISCSI_STATUS_ERR ); 
			 | 
		
		
	
		
			
			| 
				525
			 | 
			
				691
			 | 
			
			
				
				 	} 
			 | 
		
		
	
		
			
			| 
				526
			 | 
			
				692
			 | 
			
			
				
				 } 
			 |