aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@serverengines.com>2010-07-21 18:54:53 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-07-28 10:05:34 -0400
commite9b911935033ea9e28a2f7a274c9a81db1f8d91a (patch)
treee7e050c9e3ed9b4368305624834f930c29550c8a /drivers/scsi
parent5db3f33d687c5a4ba589bf3af98c786399c6e213 (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')
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.c80
-rw-r--r--drivers/scsi/be2iscsi/be_cmds.h3
-rw-r--r--drivers/scsi/be2iscsi/be_main.c50
-rw-r--r--drivers/scsi/be2iscsi/be_main.h9
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
22int 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
74int 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
22void be_mcc_notify(struct beiscsi_hba *phba) 102void 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
904int beiscsi_pci_soft_reset(struct beiscsi_hba *phba);
905int be_chk_reset_complete(struct beiscsi_hba *phba);
906
904void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, 907void 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 @@
41static unsigned int be_iopoll_budget = 10; 41static unsigned int be_iopoll_budget = 10;
42static unsigned int be_max_phys_size = 64; 42static unsigned int be_max_phys_size = 64;
43static unsigned int enable_msix = 1; 43static unsigned int enable_msix = 1;
44static unsigned int gcrashmode = 0;
45static unsigned int num_hba = 0;
44 46
45MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table); 47MODULE_DEVICE_TABLE(pci, beiscsi_pci_id_table);
46MODULE_DESCRIPTION(DRV_DESC " " BUILD_STR); 48MODULE_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);
3909free_port: 3950free_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