diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2008-01-31 14:36:43 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-07 19:02:34 -0500 |
commit | 6eabafbe6616266e8de61980a7dac5ecc1ba1113 (patch) | |
tree | f5533027fac576acf4db08210ea5815db3a15e50 /drivers/scsi/libiscsi.c | |
parent | 84ac86ca8c6787f9efff28bc04b1b65fe0a5c310 (diff) |
[SCSI] iscsi class, libiscsi: add iscsi sysfs session state file
This adds a iscsi session state file which exports the session
state for both software and hardware iscsi. It also hooks libiscsi
in.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index e7942628ac4a..c8c00e173414 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -996,6 +996,7 @@ enum { | |||
996 | FAILURE_SESSION_IN_RECOVERY, | 996 | FAILURE_SESSION_IN_RECOVERY, |
997 | FAILURE_SESSION_RECOVERY_TIMEOUT, | 997 | FAILURE_SESSION_RECOVERY_TIMEOUT, |
998 | FAILURE_SESSION_LOGGING_OUT, | 998 | FAILURE_SESSION_LOGGING_OUT, |
999 | FAILURE_SESSION_NOT_READY, | ||
999 | }; | 1000 | }; |
1000 | 1001 | ||
1001 | int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | 1002 | int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) |
@@ -1016,6 +1017,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
1016 | session = iscsi_hostdata(host->hostdata); | 1017 | session = iscsi_hostdata(host->hostdata); |
1017 | spin_lock(&session->lock); | 1018 | spin_lock(&session->lock); |
1018 | 1019 | ||
1020 | reason = iscsi_session_chkready(session_to_cls(session)); | ||
1021 | if (reason) { | ||
1022 | sc->result = reason; | ||
1023 | goto fault; | ||
1024 | } | ||
1025 | |||
1019 | /* | 1026 | /* |
1020 | * ISCSI_STATE_FAILED is a temp. state. The recovery | 1027 | * ISCSI_STATE_FAILED is a temp. state. The recovery |
1021 | * code will decide what is best to do with command queued | 1028 | * code will decide what is best to do with command queued |
@@ -1032,18 +1039,23 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
1032 | switch (session->state) { | 1039 | switch (session->state) { |
1033 | case ISCSI_STATE_IN_RECOVERY: | 1040 | case ISCSI_STATE_IN_RECOVERY: |
1034 | reason = FAILURE_SESSION_IN_RECOVERY; | 1041 | reason = FAILURE_SESSION_IN_RECOVERY; |
1035 | goto reject; | 1042 | sc->result = DID_IMM_RETRY << 16; |
1043 | break; | ||
1036 | case ISCSI_STATE_LOGGING_OUT: | 1044 | case ISCSI_STATE_LOGGING_OUT: |
1037 | reason = FAILURE_SESSION_LOGGING_OUT; | 1045 | reason = FAILURE_SESSION_LOGGING_OUT; |
1038 | goto reject; | 1046 | sc->result = DID_IMM_RETRY << 16; |
1047 | break; | ||
1039 | case ISCSI_STATE_RECOVERY_FAILED: | 1048 | case ISCSI_STATE_RECOVERY_FAILED: |
1040 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; | 1049 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; |
1050 | sc->result = DID_NO_CONNECT << 16; | ||
1041 | break; | 1051 | break; |
1042 | case ISCSI_STATE_TERMINATE: | 1052 | case ISCSI_STATE_TERMINATE: |
1043 | reason = FAILURE_SESSION_TERMINATE; | 1053 | reason = FAILURE_SESSION_TERMINATE; |
1054 | sc->result = DID_NO_CONNECT << 16; | ||
1044 | break; | 1055 | break; |
1045 | default: | 1056 | default: |
1046 | reason = FAILURE_SESSION_FREED; | 1057 | reason = FAILURE_SESSION_FREED; |
1058 | sc->result = DID_NO_CONNECT << 16; | ||
1047 | } | 1059 | } |
1048 | goto fault; | 1060 | goto fault; |
1049 | } | 1061 | } |
@@ -1051,6 +1063,7 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
1051 | conn = session->leadconn; | 1063 | conn = session->leadconn; |
1052 | if (!conn) { | 1064 | if (!conn) { |
1053 | reason = FAILURE_SESSION_FREED; | 1065 | reason = FAILURE_SESSION_FREED; |
1066 | sc->result = DID_NO_CONNECT << 16; | ||
1054 | goto fault; | 1067 | goto fault; |
1055 | } | 1068 | } |
1056 | 1069 | ||
@@ -1090,9 +1103,7 @@ reject: | |||
1090 | 1103 | ||
1091 | fault: | 1104 | fault: |
1092 | spin_unlock(&session->lock); | 1105 | spin_unlock(&session->lock); |
1093 | printk(KERN_ERR "iscsi: cmd 0x%x is not queued (%d)\n", | 1106 | debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason); |
1094 | sc->cmnd[0], reason); | ||
1095 | sc->result = (DID_NO_CONNECT << 16); | ||
1096 | scsi_set_resid(sc, scsi_bufflen(sc)); | 1107 | scsi_set_resid(sc, scsi_bufflen(sc)); |
1097 | sc->scsi_done(sc); | 1108 | sc->scsi_done(sc); |
1098 | spin_lock(host->host_lock); | 1109 | spin_lock(host->host_lock); |
@@ -1238,7 +1249,8 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, | |||
1238 | * Fail commands. session lock held and recv side suspended and xmit | 1249 | * Fail commands. session lock held and recv side suspended and xmit |
1239 | * thread flushed | 1250 | * thread flushed |
1240 | */ | 1251 | */ |
1241 | static void fail_all_commands(struct iscsi_conn *conn, unsigned lun) | 1252 | static void fail_all_commands(struct iscsi_conn *conn, unsigned lun, |
1253 | int error) | ||
1242 | { | 1254 | { |
1243 | struct iscsi_cmd_task *ctask, *tmp; | 1255 | struct iscsi_cmd_task *ctask, *tmp; |
1244 | 1256 | ||
@@ -1250,7 +1262,7 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun) | |||
1250 | if (lun == ctask->sc->device->lun || lun == -1) { | 1262 | if (lun == ctask->sc->device->lun || lun == -1) { |
1251 | debug_scsi("failing pending sc %p itt 0x%x\n", | 1263 | debug_scsi("failing pending sc %p itt 0x%x\n", |
1252 | ctask->sc, ctask->itt); | 1264 | ctask->sc, ctask->itt); |
1253 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | 1265 | fail_command(conn, ctask, error << 16); |
1254 | } | 1266 | } |
1255 | } | 1267 | } |
1256 | 1268 | ||
@@ -1258,7 +1270,7 @@ static void fail_all_commands(struct iscsi_conn *conn, unsigned lun) | |||
1258 | if (lun == ctask->sc->device->lun || lun == -1) { | 1270 | if (lun == ctask->sc->device->lun || lun == -1) { |
1259 | debug_scsi("failing requeued sc %p itt 0x%x\n", | 1271 | debug_scsi("failing requeued sc %p itt 0x%x\n", |
1260 | ctask->sc, ctask->itt); | 1272 | ctask->sc, ctask->itt); |
1261 | fail_command(conn, ctask, DID_BUS_BUSY << 16); | 1273 | fail_command(conn, ctask, error << 16); |
1262 | } | 1274 | } |
1263 | } | 1275 | } |
1264 | 1276 | ||
@@ -1572,7 +1584,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
1572 | /* need to grab the recv lock then session lock */ | 1584 | /* need to grab the recv lock then session lock */ |
1573 | write_lock_bh(conn->recv_lock); | 1585 | write_lock_bh(conn->recv_lock); |
1574 | spin_lock(&session->lock); | 1586 | spin_lock(&session->lock); |
1575 | fail_all_commands(conn, sc->device->lun); | 1587 | fail_all_commands(conn, sc->device->lun, DID_ERROR); |
1576 | conn->tmf_state = TMF_INITIAL; | 1588 | conn->tmf_state = TMF_INITIAL; |
1577 | spin_unlock(&session->lock); | 1589 | spin_unlock(&session->lock); |
1578 | write_unlock_bh(conn->recv_lock); | 1590 | write_unlock_bh(conn->recv_lock); |
@@ -2018,11 +2030,7 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
2018 | conn->stop_stage = 0; | 2030 | conn->stop_stage = 0; |
2019 | conn->tmf_state = TMF_INITIAL; | 2031 | conn->tmf_state = TMF_INITIAL; |
2020 | session->age++; | 2032 | session->age++; |
2021 | spin_unlock_bh(&session->lock); | 2033 | break; |
2022 | |||
2023 | iscsi_unblock_session(session_to_cls(session)); | ||
2024 | wake_up(&conn->ehwait); | ||
2025 | return 0; | ||
2026 | case STOP_CONN_TERM: | 2034 | case STOP_CONN_TERM: |
2027 | conn->stop_stage = 0; | 2035 | conn->stop_stage = 0; |
2028 | break; | 2036 | break; |
@@ -2031,6 +2039,8 @@ int iscsi_conn_start(struct iscsi_cls_conn *cls_conn) | |||
2031 | } | 2039 | } |
2032 | spin_unlock_bh(&session->lock); | 2040 | spin_unlock_bh(&session->lock); |
2033 | 2041 | ||
2042 | iscsi_unblock_session(session_to_cls(session)); | ||
2043 | wake_up(&conn->ehwait); | ||
2034 | return 0; | 2044 | return 0; |
2035 | } | 2045 | } |
2036 | EXPORT_SYMBOL_GPL(iscsi_conn_start); | 2046 | EXPORT_SYMBOL_GPL(iscsi_conn_start); |
@@ -2122,7 +2132,8 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
2122 | * flush queues. | 2132 | * flush queues. |
2123 | */ | 2133 | */ |
2124 | spin_lock_bh(&session->lock); | 2134 | spin_lock_bh(&session->lock); |
2125 | fail_all_commands(conn, -1); | 2135 | fail_all_commands(conn, -1, |
2136 | STOP_CONN_RECOVER ? DID_BUS_BUSY : DID_ERROR); | ||
2126 | flush_control_queues(session, conn); | 2137 | flush_control_queues(session, conn); |
2127 | spin_unlock_bh(&session->lock); | 2138 | spin_unlock_bh(&session->lock); |
2128 | mutex_unlock(&session->eh_mutex); | 2139 | mutex_unlock(&session->eh_mutex); |