diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2010-07-21 18:54:53 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-07-28 10:05:34 -0400 |
commit | e9b911935033ea9e28a2f7a274c9a81db1f8d91a (patch) | |
tree | e7e050c9e3ed9b4368305624834f930c29550c8a /drivers/scsi/be2iscsi | |
parent | 5db3f33d687c5a4ba589bf3af98c786399c6e213 (diff) |
[SCSI] be2iscsi: Adding crashdump support
These changes allow the driver to support crashdump. We need to reset the
chip incase of a crashdump
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.c | 80 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 3 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 50 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 9 |
4 files changed, 141 insertions, 1 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 9cc1f5573150..7c7537335c88 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c | |||
@@ -19,6 +19,86 @@ | |||
19 | #include "be_mgmt.h" | 19 | #include "be_mgmt.h" |
20 | #include "be_main.h" | 20 | #include "be_main.h" |
21 | 21 | ||
22 | int beiscsi_pci_soft_reset(struct beiscsi_hba *phba) | ||
23 | { | ||
24 | u32 sreset; | ||
25 | u8 *pci_reset_offset = 0; | ||
26 | u8 *pci_online0_offset = 0; | ||
27 | u8 *pci_online1_offset = 0; | ||
28 | u32 pconline0 = 0; | ||
29 | u32 pconline1 = 0; | ||
30 | u32 i; | ||
31 | |||
32 | pci_reset_offset = (u8 *)phba->pci_va + BE2_SOFT_RESET; | ||
33 | pci_online0_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE0; | ||
34 | pci_online1_offset = (u8 *)phba->pci_va + BE2_PCI_ONLINE1; | ||
35 | sreset = readl((void *)pci_reset_offset); | ||
36 | sreset |= BE2_SET_RESET; | ||
37 | writel(sreset, (void *)pci_reset_offset); | ||
38 | |||
39 | i = 0; | ||
40 | while (sreset & BE2_SET_RESET) { | ||
41 | if (i > 64) | ||
42 | break; | ||
43 | msleep(100); | ||
44 | sreset = readl((void *)pci_reset_offset); | ||
45 | i++; | ||
46 | } | ||
47 | |||
48 | if (sreset & BE2_SET_RESET) { | ||
49 | printk(KERN_ERR "Soft Reset did not deassert\n"); | ||
50 | return -EIO; | ||
51 | } | ||
52 | pconline1 = BE2_MPU_IRAM_ONLINE; | ||
53 | writel(pconline0, (void *)pci_online0_offset); | ||
54 | writel(pconline1, (void *)pci_online1_offset); | ||
55 | |||
56 | sreset = BE2_SET_RESET; | ||
57 | writel(sreset, (void *)pci_reset_offset); | ||
58 | |||
59 | i = 0; | ||
60 | while (sreset & BE2_SET_RESET) { | ||
61 | if (i > 64) | ||
62 | break; | ||
63 | msleep(1); | ||
64 | sreset = readl((void *)pci_reset_offset); | ||
65 | i++; | ||
66 | } | ||
67 | if (sreset & BE2_SET_RESET) { | ||
68 | printk(KERN_ERR "MPU Online Soft Reset did not deassert\n"); | ||
69 | return -EIO; | ||
70 | } | ||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int be_chk_reset_complete(struct beiscsi_hba *phba) | ||
75 | { | ||
76 | unsigned int num_loop; | ||
77 | u8 *mpu_sem = 0; | ||
78 | u32 status; | ||
79 | |||
80 | num_loop = 1000; | ||
81 | mpu_sem = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; | ||
82 | msleep(5000); | ||
83 | |||
84 | while (num_loop) { | ||
85 | status = readl((void *)mpu_sem); | ||
86 | |||
87 | if ((status & 0x80000000) || (status & 0x0000FFFF) == 0xC000) | ||
88 | break; | ||
89 | msleep(60); | ||
90 | num_loop--; | ||
91 | } | ||
92 | |||
93 | if ((status & 0x80000000) || (!num_loop)) { | ||
94 | printk(KERN_ERR "Failed in be_chk_reset_complete" | ||
95 | "status = 0x%x\n", status); | ||
96 | return -EIO; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
101 | |||
22 | void be_mcc_notify(struct beiscsi_hba *phba) | 102 | void be_mcc_notify(struct beiscsi_hba *phba) |
23 | { | 103 | { |
24 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | 104 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; |
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 30a293f52ef7..0df19cb58a39 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -901,6 +901,9 @@ struct be_fw_cfg { | |||
901 | * the cxn | 901 | * the cxn |
902 | */ | 902 | */ |
903 | 903 | ||
904 | int beiscsi_pci_soft_reset(struct beiscsi_hba *phba); | ||
905 | int be_chk_reset_complete(struct beiscsi_hba *phba); | ||
906 | |||
904 | void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, | 907 | void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, |
905 | bool embedded, u8 sge_cnt); | 908 | bool embedded, u8 sge_cnt); |
906 | 909 | ||
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 67a7e3f7bae6..1a22125f5202 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -41,6 +41,8 @@ | |||
41 | static unsigned int be_iopoll_budget = 10; | 41 | static unsigned int be_iopoll_budget = 10; |
42 | static unsigned int be_max_phys_size = 64; | 42 | static unsigned int be_max_phys_size = 64; |
43 | static unsigned int enable_msix = 1; | 43 | static unsigned int enable_msix = 1; |
44 | static unsigned int gcrashmode = 0; | ||
45 | static unsigned int num_hba = 0; | ||
44 | 46 | ||
45 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); | 47 | MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); |
46 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); | 48 | MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); |
@@ -3731,6 +3733,8 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
3731 | struct hwi_context_memory *phwi_context; | 3733 | struct hwi_context_memory *phwi_context; |
3732 | struct be_eq_obj *pbe_eq; | 3734 | struct be_eq_obj *pbe_eq; |
3733 | unsigned int i, msix_vec; | 3735 | unsigned int i, msix_vec; |
3736 | u8 *real_offset = 0; | ||
3737 | u32 value = 0; | ||
3734 | 3738 | ||
3735 | phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); | 3739 | phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev); |
3736 | if (!phba) { | 3740 | if (!phba) { |
@@ -3759,6 +3763,14 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
3759 | 3763 | ||
3760 | beiscsi_clean_port(phba); | 3764 | beiscsi_clean_port(phba); |
3761 | beiscsi_free_mem(phba); | 3765 | beiscsi_free_mem(phba); |
3766 | real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; | ||
3767 | |||
3768 | value = readl((void *)real_offset); | ||
3769 | |||
3770 | if (value & 0x00010000) { | ||
3771 | value &= 0xfffeffff; | ||
3772 | writel(value, (void *)real_offset); | ||
3773 | } | ||
3762 | beiscsi_unmap_pci_function(phba); | 3774 | beiscsi_unmap_pci_function(phba); |
3763 | pci_free_consistent(phba->pcidev, | 3775 | pci_free_consistent(phba->pcidev, |
3764 | phba->ctrl.mbox_mem_alloced.size, | 3776 | phba->ctrl.mbox_mem_alloced.size, |
@@ -3792,6 +3804,8 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3792 | struct hwi_context_memory *phwi_context; | 3804 | struct hwi_context_memory *phwi_context; |
3793 | struct be_eq_obj *pbe_eq; | 3805 | struct be_eq_obj *pbe_eq; |
3794 | int ret, num_cpus, i; | 3806 | int ret, num_cpus, i; |
3807 | u8 *real_offset = 0; | ||
3808 | u32 value = 0; | ||
3795 | 3809 | ||
3796 | ret = beiscsi_enable_pci(pcidev); | 3810 | ret = beiscsi_enable_pci(pcidev); |
3797 | if (ret < 0) { | 3811 | if (ret < 0) { |
@@ -3837,6 +3851,33 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3837 | goto hba_free; | 3851 | goto hba_free; |
3838 | } | 3852 | } |
3839 | 3853 | ||
3854 | if (!num_hba) { | ||
3855 | real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; | ||
3856 | value = readl((void *)real_offset); | ||
3857 | if (value & 0x00010000) { | ||
3858 | gcrashmode++; | ||
3859 | shost_printk(KERN_ERR, phba->shost, | ||
3860 | "Loading Driver in crashdump mode\n"); | ||
3861 | ret = beiscsi_pci_soft_reset(phba); | ||
3862 | if (ret) { | ||
3863 | shost_printk(KERN_ERR, phba->shost, | ||
3864 | "Reset Failed. Aborting Crashdump\n"); | ||
3865 | goto hba_free; | ||
3866 | } | ||
3867 | ret = be_chk_reset_complete(phba); | ||
3868 | if (ret) { | ||
3869 | shost_printk(KERN_ERR, phba->shost, | ||
3870 | "Failed to get out of reset." | ||
3871 | "Aborting Crashdump\n"); | ||
3872 | goto hba_free; | ||
3873 | } | ||
3874 | } else { | ||
3875 | value |= 0x00010000; | ||
3876 | writel(value, (void *)real_offset); | ||
3877 | num_hba++; | ||
3878 | } | ||
3879 | } | ||
3880 | |||
3840 | spin_lock_init(&phba->io_sgl_lock); | 3881 | spin_lock_init(&phba->io_sgl_lock); |
3841 | spin_lock_init(&phba->mgmt_sgl_lock); | 3882 | spin_lock_init(&phba->mgmt_sgl_lock); |
3842 | spin_lock_init(&phba->isr_lock); | 3883 | spin_lock_init(&phba->isr_lock); |
@@ -3907,6 +3948,15 @@ free_twq: | |||
3907 | beiscsi_clean_port(phba); | 3948 | beiscsi_clean_port(phba); |
3908 | beiscsi_free_mem(phba); | 3949 | beiscsi_free_mem(phba); |
3909 | free_port: | 3950 | free_port: |
3951 | real_offset = (u8 *)phba->csr_va + MPU_EP_SEMAPHORE; | ||
3952 | |||
3953 | value = readl((void *)real_offset); | ||
3954 | |||
3955 | if (value & 0x00010000) { | ||
3956 | value &= 0xfffeffff; | ||
3957 | writel(value, (void *)real_offset); | ||
3958 | } | ||
3959 | |||
3910 | pci_free_consistent(phba->pcidev, | 3960 | pci_free_consistent(phba->pcidev, |
3911 | phba->ctrl.mbox_mem_alloced.size, | 3961 | phba->ctrl.mbox_mem_alloced.size, |
3912 | phba->ctrl.mbox_mem_alloced.va, | 3962 | phba->ctrl.mbox_mem_alloced.va, |
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index e6ddddbbae7a..05ad76e48d80 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -69,7 +69,14 @@ | |||
69 | #define BEISCSI_NUM_DEVICES_SUPPORTED 0x01 | 69 | #define BEISCSI_NUM_DEVICES_SUPPORTED 0x01 |
70 | #define BEISCSI_MAX_FRAGS_INIT 192 | 70 | #define BEISCSI_MAX_FRAGS_INIT 192 |
71 | #define BE_NUM_MSIX_ENTRIES 1 | 71 | #define BE_NUM_MSIX_ENTRIES 1 |
72 | #define MPU_EP_SEMAPHORE 0xac | 72 | |
73 | #define MPU_EP_CONTROL 0 | ||
74 | #define MPU_EP_SEMAPHORE 0xac | ||
75 | #define BE2_SOFT_RESET 0x5c | ||
76 | #define BE2_PCI_ONLINE0 0xb0 | ||
77 | #define BE2_PCI_ONLINE1 0xb4 | ||
78 | #define BE2_SET_RESET 0x80 | ||
79 | #define BE2_MPU_IRAM_ONLINE 0x00000080 | ||
73 | 80 | ||
74 | #define BE_SENSE_INFO_SIZE 258 | 81 | #define BE_SENSE_INFO_SIZE 258 |
75 | #define BE_ISCSI_PDU_HEADER_SIZE 64 | 82 | #define BE_ISCSI_PDU_HEADER_SIZE 64 |