|
@@ -104,24 +104,6 @@ static void iscsi_done ( struct iscsi_session *iscsi, int rc ) {
|
104
|
104
|
async_done ( &iscsi->aop, rc );
|
105
|
105
|
}
|
106
|
106
|
|
107
|
|
-/**
|
108
|
|
- * Mark iSCSI operation as complete, and close TCP connection
|
109
|
|
- *
|
110
|
|
- * @v iscsi iSCSI session
|
111
|
|
- * @v rc Return status code
|
112
|
|
- */
|
113
|
|
-static void iscsi_close ( struct iscsi_session *iscsi, int rc ) {
|
114
|
|
-
|
115
|
|
- /* Clear session status */
|
116
|
|
- iscsi->status = 0;
|
117
|
|
-
|
118
|
|
- /* Close TCP connection */
|
119
|
|
- tcp_close ( &iscsi->tcp );
|
120
|
|
-
|
121
|
|
- /* Mark iSCSI operation as complete */
|
122
|
|
- iscsi_done ( iscsi, rc );
|
123
|
|
-}
|
124
|
|
-
|
125
|
107
|
/****************************************************************************
|
126
|
108
|
*
|
127
|
109
|
* iSCSI SCSI command issuing
|
|
@@ -564,7 +546,7 @@ static void iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
|
564
|
546
|
/* Prepare for CHAP with MD5 */
|
565
|
547
|
if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
|
566
|
548
|
DBG ( "iSCSI %p could not initialise CHAP\n", iscsi );
|
567
|
|
- iscsi_close ( iscsi, rc );
|
|
549
|
+ iscsi_done ( iscsi, rc );
|
568
|
550
|
}
|
569
|
551
|
}
|
570
|
552
|
|
|
@@ -722,7 +704,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
|
722
|
704
|
/* Buffer up the PDU data */
|
723
|
705
|
if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
|
724
|
706
|
DBG ( "iSCSI %p could not buffer login response\n", iscsi );
|
725
|
|
- iscsi_close ( iscsi, rc );
|
|
707
|
+ iscsi_done ( iscsi, rc );
|
726
|
708
|
return;
|
727
|
709
|
}
|
728
|
710
|
if ( remaining )
|
|
@@ -747,7 +729,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
|
747
|
729
|
if ( response->status_class != 0 ) {
|
748
|
730
|
printf ( "iSCSI login failure: class %02x detail %02x\n",
|
749
|
731
|
response->status_class, response->status_detail );
|
750
|
|
- iscsi_close ( iscsi, -EPERM );
|
|
732
|
+ iscsi_done ( iscsi, -EPERM );
|
751
|
733
|
return;
|
752
|
734
|
}
|
753
|
735
|
|
|
@@ -765,7 +747,7 @@ static void iscsi_rx_login_response ( struct iscsi_session *iscsi, void *data,
|
765
|
747
|
default:
|
766
|
748
|
DBG ( "iSCSI %p got invalid response flags %02x\n",
|
767
|
749
|
iscsi, response->flags );
|
768
|
|
- iscsi_close ( iscsi, -EIO );
|
|
750
|
+ iscsi_done ( iscsi, -EIO );
|
769
|
751
|
return;
|
770
|
752
|
}
|
771
|
753
|
}
|
|
@@ -1122,10 +1104,17 @@ static void iscsi_newdata ( struct tcp_connection *conn, void *data,
|
1122
|
1104
|
*/
|
1123
|
1105
|
static void iscsi_closed ( struct tcp_connection *conn, int status ) {
|
1124
|
1106
|
struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
|
|
1107
|
+ int session_status = iscsi->status;
|
1125
|
1108
|
|
1126
|
1109
|
/* Clear session status */
|
1127
|
1110
|
iscsi->status = 0;
|
1128
|
1111
|
|
|
1112
|
+ /* If we are deliberately closing down, exit cleanly */
|
|
1113
|
+ if ( session_status & ISCSI_STATUS_CLOSING ) {
|
|
1114
|
+ iscsi_done ( iscsi, status );
|
|
1115
|
+ return;
|
|
1116
|
+ }
|
|
1117
|
+
|
1129
|
1118
|
/* Retry connection if within the retry limit, otherwise fail */
|
1130
|
1119
|
if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
|
1131
|
1120
|
DBG ( "iSCSI %p retrying connection\n", iscsi );
|
|
@@ -1192,3 +1181,17 @@ struct async_operation * iscsi_issue ( struct iscsi_session *iscsi,
|
1192
|
1181
|
|
1193
|
1182
|
return &iscsi->aop;
|
1194
|
1183
|
}
|
|
1184
|
+
|
|
1185
|
+/**
|
|
1186
|
+ * Close down iSCSI session
|
|
1187
|
+ *
|
|
1188
|
+ * @v iscsi iSCSI session
|
|
1189
|
+ * @ret aop Asynchronous operation
|
|
1190
|
+ */
|
|
1191
|
+struct async_operation * iscsi_shutdown ( struct iscsi_session *iscsi ) {
|
|
1192
|
+ if ( iscsi->status ) {
|
|
1193
|
+ iscsi->status |= ISCSI_STATUS_CLOSING;
|
|
1194
|
+ tcp_close ( &iscsi->tcp );
|
|
1195
|
+ }
|
|
1196
|
+ return &iscsi->aop;
|
|
1197
|
+}
|