diff options
author | Vijaya Mohan Guvva <vmohan@brocade.com> | 2013-05-13 05:33:26 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-26 16:12:19 -0400 |
commit | c679b599afa5dd38d20e058aa68bc94c1c1416a1 (patch) | |
tree | 605da11cd1b832a1254ba81ba6934482c87065df /drivers/scsi/bfa/bfa_ioc_ct.c | |
parent | f2a0cc3ffd5ee123086b8e76522a85a937d89878 (diff) |
[SCSI] bfa: kdump fix on 815 and 825 adapters
Root cause: When kernel crashes, On brocade 815/825 adapters,
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 fail
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: Vijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc_ct.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index a8e52a108710..bd53150e4ee0 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -43,6 +43,12 @@ static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); | |||
43 | static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); | 43 | static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); |
44 | static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); | 44 | static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); |
45 | static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc); | 45 | static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc); |
46 | static void bfa_ioc_ct_set_cur_ioc_fwstate( | ||
47 | struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); | ||
48 | static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); | ||
49 | static void bfa_ioc_ct_set_alt_ioc_fwstate( | ||
50 | struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); | ||
51 | static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); | ||
46 | 52 | ||
47 | static struct bfa_ioc_hwif_s hwif_ct; | 53 | static struct bfa_ioc_hwif_s hwif_ct; |
48 | static struct bfa_ioc_hwif_s hwif_ct2; | 54 | static struct bfa_ioc_hwif_s hwif_ct2; |
@@ -512,6 +518,10 @@ bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif) | |||
512 | hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; | 518 | hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; |
513 | hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; | 519 | hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; |
514 | hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; | 520 | hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; |
521 | hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate; | ||
522 | hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate; | ||
523 | hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate; | ||
524 | hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate; | ||
515 | } | 525 | } |
516 | 526 | ||
517 | /** | 527 | /** |
@@ -959,3 +969,29 @@ bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) | |||
959 | 969 | ||
960 | return BFA_STATUS_OK; | 970 | return BFA_STATUS_OK; |
961 | } | 971 | } |
972 | |||
973 | static void | ||
974 | bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, | ||
975 | enum bfi_ioc_state fwstate) | ||
976 | { | ||
977 | writel(fwstate, ioc->ioc_regs.ioc_fwstate); | ||
978 | } | ||
979 | |||
980 | static enum bfi_ioc_state | ||
981 | bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) | ||
982 | { | ||
983 | return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate); | ||
984 | } | ||
985 | |||
986 | static void | ||
987 | bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, | ||
988 | enum bfi_ioc_state fwstate) | ||
989 | { | ||
990 | writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate); | ||
991 | } | ||
992 | |||
993 | static enum bfi_ioc_state | ||
994 | bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) | ||
995 | { | ||
996 | return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate); | ||
997 | } | ||