aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fnic/fnic.h
diff options
context:
space:
mode:
authorHiral Patel <hiralpat@cisco.com>2013-02-12 20:00:58 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-02-22 12:28:19 -0500
commit03298552cba38f7c805ed338826dc76c405465c7 (patch)
treec7a5fd280335ad68e8c69f4cbab36658fb616620 /drivers/scsi/fnic/fnic.h
parentbfb4809f7fff2f2db3d0de41ea4f49fd3f2f0aa4 (diff)
[SCSI] fnic: fixing issues in device and firmware reset code
1. Handling overlapped firmware resets This fix serialize multiple firmware resets to avoid situation where fnic device fails to come up for link up event, when firmware resets are issued back to back. If there are overlapped firmware resets are issued, the firmware reset operation checks whether there is any firmware reset in progress, if so it polls for its completion in a loop with 100ms delay. 2. Handling device reset timeout fnic_device_reset code has been modified to handle Device reset timeout: - Issue terminate on device reset timeout. - Introduced flags field (one of the scratch fields in scsi_cmnd). With this, device reset request would have DEVICE_RESET flag set for other routines to determine the type of the request. Also modified fnic_terminate_rport_io, fnic_rport_exch_rset, completion routines to handle SCSI commands with DEVICE_RESET flag. 3. LUN/Device Reset hangs when issued through IOCTL using utilities like sg_reset. Each SCSI command is associated with a valid tag, fnic uses this tag to retrieve associated scsi command on completion. the LUN/Device Reset issued through IOCTL resulting into a SCSI command that is not associated with a valid tag. So fnic fails to retrieve associated scsi command on completion, which causes hang. This fix allocates tag, associates it with the scsi command and frees the tag, when the operation completed. 4. Preventing IOs during firmware reset. Current fnic implementation allows IO submissions during firmware reset. This fix synchronizes IO submissions and firmware reset operations. It ensures that IOs issued to fnic prior to reset will be issued to the firmware before firmware reset. Signed-off-by: Narsimhulu Musini <nmusini@cisco.com> Signed-off-by: Hiral Patel <hiralpat@cisco.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/fnic/fnic.h')
-rw-r--r--drivers/scsi/fnic/fnic.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 95a5ba29320d..63b35c8e40bd 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -56,6 +56,19 @@
56#define FNIC_NO_TAG -1 56#define FNIC_NO_TAG -1
57 57
58/* 58/*
59 * Command flags to identify the type of command and for other future
60 * use.
61 */
62#define FNIC_NO_FLAGS 0
63#define FNIC_CDB_REQ BIT(1) /* All IOs with a valid CDB */
64#define FNIC_BLOCKING_REQ BIT(2) /* All blocking Requests */
65#define FNIC_DEVICE_RESET BIT(3) /* Device reset request */
66#define FNIC_DEV_RST_PENDING BIT(4) /* Device reset pending */
67#define FNIC_DEV_RST_TIMED_OUT BIT(5) /* Device reset timed out */
68#define FNIC_DEV_RST_TERM_ISSUED BIT(6) /* Device reset terminate */
69#define FNIC_DEV_RST_DONE BIT(7) /* Device reset done */
70
71/*
59 * Usage of the scsi_cmnd scratchpad. 72 * Usage of the scsi_cmnd scratchpad.
60 * These fields are locked by the hashed io_req_lock. 73 * These fields are locked by the hashed io_req_lock.
61 */ 74 */
@@ -64,6 +77,7 @@
64#define CMD_ABTS_STATUS(Cmnd) ((Cmnd)->SCp.Message) 77#define CMD_ABTS_STATUS(Cmnd) ((Cmnd)->SCp.Message)
65#define CMD_LR_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in) 78#define CMD_LR_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
66#define CMD_TAG(Cmnd) ((Cmnd)->SCp.sent_command) 79#define CMD_TAG(Cmnd) ((Cmnd)->SCp.sent_command)
80#define CMD_FLAGS(Cmnd) ((Cmnd)->SCp.Status)
67 81
68#define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ 82#define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */
69 83
@@ -71,9 +85,28 @@
71#define FNIC_HOST_RESET_TIMEOUT 10000 /* mSec */ 85#define FNIC_HOST_RESET_TIMEOUT 10000 /* mSec */
72#define FNIC_RMDEVICE_TIMEOUT 1000 /* mSec */ 86#define FNIC_RMDEVICE_TIMEOUT 1000 /* mSec */
73#define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */ 87#define FNIC_HOST_RESET_SETTLE_TIME 30 /* Sec */
88#define FNIC_ABT_TERM_DELAY_TIMEOUT 500 /* mSec */
74 89
75#define FNIC_MAX_FCP_TARGET 256 90#define FNIC_MAX_FCP_TARGET 256
76 91
92/**
93 * state_flags to identify host state along along with fnic's state
94 **/
95#define __FNIC_FLAGS_FWRESET BIT(0) /* fwreset in progress */
96#define __FNIC_FLAGS_BLOCK_IO BIT(1) /* IOs are blocked */
97
98#define FNIC_FLAGS_NONE (0)
99#define FNIC_FLAGS_FWRESET (__FNIC_FLAGS_FWRESET | \
100 __FNIC_FLAGS_BLOCK_IO)
101
102#define FNIC_FLAGS_IO_BLOCKED (__FNIC_FLAGS_BLOCK_IO)
103
104#define fnic_set_state_flags(fnicp, st_flags) \
105 __fnic_set_state_flags(fnicp, st_flags, 0)
106
107#define fnic_clear_state_flags(fnicp, st_flags) \
108 __fnic_set_state_flags(fnicp, st_flags, 1)
109
77extern unsigned int fnic_log_level; 110extern unsigned int fnic_log_level;
78 111
79#define FNIC_MAIN_LOGGING 0x01 112#define FNIC_MAIN_LOGGING 0x01
@@ -170,6 +203,9 @@ struct fnic {
170 203
171 struct completion *remove_wait; /* device remove thread blocks */ 204 struct completion *remove_wait; /* device remove thread blocks */
172 205
206 atomic_t in_flight; /* io counter */
207 u32 _reserved; /* fill hole */
208 unsigned long state_flags; /* protected by host lock */
173 enum fnic_state state; 209 enum fnic_state state;
174 spinlock_t fnic_lock; 210 spinlock_t fnic_lock;
175 211
@@ -267,4 +303,10 @@ const char *fnic_state_to_str(unsigned int state);
267void fnic_log_q_error(struct fnic *fnic); 303void fnic_log_q_error(struct fnic *fnic);
268void fnic_handle_link_event(struct fnic *fnic); 304void fnic_handle_link_event(struct fnic *fnic);
269 305
306static inline int
307fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags)
308{
309 return ((fnic->state_flags & st_flags) == st_flags);
310}
311void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long);
270#endif /* _FNIC_H_ */ 312#endif /* _FNIC_H_ */