diff options
author | Jing Huang <huangj@brocade.com> | 2011-04-13 14:45:53 -0400 |
---|---|---|
committer | James Bottomley <jbottomley@parallels.com> | 2011-05-24 12:38:02 -0400 |
commit | 45d7f0cc58183062adea0a1de3d8cba768134138 (patch) | |
tree | 1977a1b1a1452a53f5e6504674168235f32ce23a /drivers/scsi/bfa/bfa_ioc_cb.c | |
parent | a5442ba4a428081ebac7090f46c62ffaa17ca951 (diff) |
[SCSI] bfa: kdump fix
Root cause: When kernel crashes, bfa IOC state machine and FW doesn't get
a notification and hence are not cleanly shutdown. So registers holding
driver/IOC state information are not reset back to valid disabled/parking
values. This causes subsequent driver initialization to hang during kdump
kernel boot.
Fix description: during the initialization of first PCI function, reset
corresponding register when unclean shutown is detect by reading chip
registers. This will make sure that ioc/fw gets clean re-initialization.
Signed-off-by: Jing Huang <huangj@brocade.com>
Signed-off-by: James Bottomley <jbottomley@parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc_cb.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_cb.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc_cb.c b/drivers/scsi/bfa/bfa_ioc_cb.c index e4a0713185b6..89ae4c8f95a2 100644 --- a/drivers/scsi/bfa/bfa_ioc_cb.c +++ b/drivers/scsi/bfa/bfa_ioc_cb.c | |||
@@ -32,6 +32,7 @@ static void bfa_ioc_cb_map_port(struct bfa_ioc_s *ioc); | |||
32 | static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); | 32 | static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix); |
33 | static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc); | 33 | static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc); |
34 | static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); | 34 | static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc); |
35 | static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc); | ||
35 | static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); | 36 | static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc); |
36 | static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); | 37 | static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc); |
37 | static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); | 38 | static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc); |
@@ -53,6 +54,7 @@ bfa_ioc_set_cb_hwif(struct bfa_ioc_s *ioc) | |||
53 | hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set; | 54 | hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set; |
54 | hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail; | 55 | hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail; |
55 | hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset; | 56 | hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset; |
57 | hwif_cb.ioc_sync_start = bfa_ioc_cb_sync_start; | ||
56 | hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join; | 58 | hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join; |
57 | hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; | 59 | hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave; |
58 | hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; | 60 | hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack; |
@@ -195,6 +197,15 @@ bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) | |||
195 | } | 197 | } |
196 | 198 | ||
197 | /* | 199 | /* |
200 | * Synchronized IOC failure processing routines | ||
201 | */ | ||
202 | static bfa_boolean_t | ||
203 | bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc) | ||
204 | { | ||
205 | return bfa_ioc_cb_sync_complete(ioc); | ||
206 | } | ||
207 | |||
208 | /* | ||
198 | * Cleanup hw semaphore and usecnt registers | 209 | * Cleanup hw semaphore and usecnt registers |
199 | */ | 210 | */ |
200 | static void | 211 | static void |