summaryrefslogtreecommitdiffstats
path: root/src/net/tcp/iscsi.c
diff options
context:
space:
mode:
authorMichael Brown2006-12-21 18:17:47 +0100
committerMichael Brown2006-12-21 18:17:47 +0100
commitab242a760d66064ff14b83daaa2eef0a895c8d2b (patch)
treecbf40f86cc848448bb366db05da55bb6595e6811 /src/net/tcp/iscsi.c
parentDefault to port 0 (sic). (diff)
downloadipxe-ab242a760d66064ff14b83daaa2eef0a895c8d2b.tar.gz
ipxe-ab242a760d66064ff14b83daaa2eef0a895c8d2b.tar.xz
ipxe-ab242a760d66064ff14b83daaa2eef0a895c8d2b.zip
Add ability to shut down iSCSI connection
Diffstat (limited to 'src/net/tcp/iscsi.c')
-rw-r--r--src/net/tcp/iscsi.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
index 665b9765..59b8819a 100644
--- a/src/net/tcp/iscsi.c
+++ b/src/net/tcp/iscsi.c
@@ -104,24 +104,6 @@ static void iscsi_done ( struct iscsi_session *iscsi, int rc ) {
async_done ( &iscsi->aop, rc );
}
-/**
- * Mark iSCSI operation as complete, and close TCP connection
- *
- * @v iscsi iSCSI session
- * @v rc Return status code
- */
-static void iscsi_close ( struct iscsi_session *iscsi, int rc ) {
-
- /* Clear session status */
- iscsi->status = 0;
-
- /* Close TCP connection */
- tcp_close ( &iscsi->tcp );
-
- /* Mark iSCSI operation as complete */
- iscsi_done ( iscsi, rc );
-}
-
/****************************************************************************
*
* iSCSI SCSI command issuing
@@ -564,7 +546,7 @@ static void iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
/* Prepare for CHAP with MD5 */
if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
DBG ( "iSCSI %p could not initialise CHAP\n", iscsi );
- iscsi_close ( iscsi, rc );
+ iscsi_done ( iscsi, rc );
}
}
@@ -722,7 +704,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
/* Buffer up the PDU data */
if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
DBG ( "iSCSI %p could not buffer login response\n", iscsi );
- iscsi_close ( iscsi, rc );
+ iscsi_done ( iscsi, rc );
return;
}
if ( remaining )
@@ -747,7 +729,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
if ( response->status_class != 0 ) {
printf ( "iSCSI login failure: class %02x detail %02x\n",
response->status_class, response->status_detail );
- iscsi_close ( iscsi, -EPERM );
+ iscsi_done ( iscsi, -EPERM );
return;
}
@@ -765,7 +747,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
default:
DBG ( "iSCSI %p got invalid response flags %02x\n",
iscsi, response->flags );
- iscsi_close ( iscsi, -EIO );
+ iscsi_done ( iscsi, -EIO );
return;
}
}
@@ -1122,10 +1104,17 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
*/
static void iscsi_closed ( struct tcp_connection *conn, int status ) {
struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
+ int session_status = iscsi->status;
/* Clear session status */
iscsi->status = 0;
+ /* If we are deliberately closing down, exit cleanly */
+ if ( session_status & ISCSI_STATUS_CLOSING ) {
+ iscsi_done ( iscsi, status );
+ return;
+ }
+
/* Retry connection if within the retry limit, otherwise fail */
if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
DBG ( "iSCSI %p retrying connection\n", iscsi );
@@ -1192,3 +1181,17 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
return &iscsi->aop;
}
+
+/**
+ * Close down iSCSI session
+ *
+ * @v iscsi iSCSI session
+ * @ret aop Asynchronous operation
+ */
+struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) {
+ if ( iscsi->status ) {
+ iscsi->status |= ISCSI_STATUS_CLOSING;
+ tcp_close ( &iscsi->tcp );
+ }
+ return &iscsi->aop;
+}