pm80xx: Firmware logging support
Subsystems (2)
PATCH v2 10/10 pm80xx: Firmware logging support
Quoted 1 line
From
ab1b030500a835eacda3d86e5570366099b21311Mon Sep 17 00:00:00 2001
From: Anand Kumar Santhanam <[email protected]>
Date: Wed, 4 Sep 2013 12:57:00 +0530
Subject: [PATCH V2 10/10] pm80xx: Firmware logging support.
Supports below logging facilities,
Inbound outbound queues dump.
Non fatal dump in case of IO failures.
Fatal dump in case of firmware failure.
--- drivers/scsi/pm8001/pm8001_ctl.c | 129 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_ctl.h | 4 + drivers/scsi/pm8001/pm8001_defs.h | 3 +- drivers/scsi/pm8001/pm8001_hwi.c | 83 ++++++++++++++ drivers/scsi/pm8001/pm8001_hwi.h | 3 + drivers/scsi/pm8001/pm8001_init.c | 4 + drivers/scsi/pm8001/pm8001_sas.h | 68 +++++++++++ drivers/scsi/pm8001/pm80xx_hwi.c | 225 +++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 520 insertions(+), 1 deletions(-)
drivers/scsi/pm8001/pm8001_ctl.c +129 -0
@@ -309,6 +309,94 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, } static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);/** +* pm8001_ctl_ib_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ +static ssize_t pm8001_ctl_ib_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define IB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +#define IB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ib_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + +return str - buf; +} + +static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, NULL); +/** +* pm8001_ctl_ob_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ + +static ssize_t pm8001_ctl_ob_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define OB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +#define OB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ob_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + +return str - buf; +} +static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, NULL); +/** * pm8001_ctl_bios_version_show - Bios version Display * @cdev:pointer to embedded class device * @buf:the buffer returned
@@ -377,6 +465,43 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev, } static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL); +/** +** pm8001_ctl_fatal_log_show - fatal error logging +** @cdev:pointer to embedded class device +** @buf: the buffer returned +** +** A sysfs 'read-only' shost attribute. +**/ + +static ssize_t pm8001_ctl_fatal_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm80xx_get_fatal_dump (cdev, attr, buf); +return count; +} + +static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, NULL); + + +/** +** pm8001_ctl_gsm_log_show - gsm dump collection +** @cdev:pointer to embedded class device +** @buf: the buffer returned +**A sysfs 'read-only' shost attribute. +**/ +static ssize_t pm8001_ctl_gsm_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm8001_get_gsm_dump (cdev,SYSFS_OFFSET , buf); +return count; +} + +static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); +#define FLASH_CMD_NONE 0x00#define FLASH_CMD_UPDATE 0x01#define FLASH_CMD_SET_NVMD 0x02
@@ -636,6 +761,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_update_fw, &dev_attr_aap_log, &dev_attr_iop_log, + &dev_attr_fatal_log, + &dev_attr_gsm_log, &dev_attr_max_out_io, &dev_attr_max_devices, &dev_attr_max_sg_list,
@@ -643,6 +770,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_logging_level, &dev_attr_host_sas_address, &dev_attr_bios_version, + &dev_attr_ib_log, + &dev_attr_ob_log, NULL, };
drivers/scsi/pm8001/pm8001_ctl.h +4 -0
@@ -55,5 +55,9 @@#define FAIL_OUT_MEMORY 0x000c00#define FLASH_IN_PROGRESS 0x001000 +#define IB_OB_READ_TIMES 256 +#define SYSFS_OFFSET 1024 +#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) +#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)#endif /* PM8001_CTL_H_INCLUDED */
drivers/scsi/pm8001/pm8001_defs.h +2 -1
@@ -102,7 +102,8 @@ enum memory_region_num {NVMD ,/* NVM device */ DEV_MEM ,/* memory for devices */ CCB_MEM ,/* memory for command control block */ - FW_FLASH /* memory for fw flash update */ +FW_FLASH ,/* memory for fw flash update */ + FORENSIC_MEM /* memory for fw forensic data */ };#define PM8001_EVENT_LOG_SIZE (128 * 1024)
drivers/scsi/pm8001/pm8001_hwi.c +83 -0
89 lines not on this page · raw message
drivers/scsi/pm8001/pm8001_hwi.h +3 -0
@@ -1027,5 +1027,8 @@ struct set_dev_state_resp {#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 +#define GSM_BASE 0x4F0000 +#define SHIFT_REG_64K_MASK 0xffff0000 +#define SHIFT_REG_BIT_SHIFT 8#endif
drivers/scsi/pm8001/pm8001_init.c +4 -0
@@ -347,6 +347,10 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,/* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH ].total_len =4096 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].num_elements =1 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].total_len =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].element_size =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].alignment =0x10000 ;for (i =0 ; i <USI_MAX_MEMCNT ; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr,
drivers/scsi/pm8001/pm8001_sas.h +68 -0
98 lines not on this page · raw message
drivers/scsi/pm8001/pm80xx_hwi.c +225 -0
237 lines not on this page · raw message
drivers/scsi/pm8001/pm80xx_hwi.h +2 -0
@@ -1525,4 +1525,6 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 + +#define MEMBASE_II_SHIFT_REGISTER 0x1010#endif
Signature · 1 line
1.7.1
Quoted 11 lines · Anand
From
ab1b030500a835eacda3d86e5570366099b21311Mon Sep 17 00:00:00 2001
From: Anand Kumar Santhanam <[email protected]>
Date: Wed, 4 Sep 2013 12:57:00 +0530
Subject: [PATCH V2 10/10] pm80xx: Firmware logging support.Supports below logging facilities,
Inbound outbound queues dump.
Non fatal dump in case of IO failures.
Fatal dump in case of firmware failure.Signed-off-by [email protected]
Quoted 685 lines
--- drivers/scsi/pm8001/pm8001_ctl.c | 129 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_ctl.h | 4 + drivers/scsi/pm8001/pm8001_defs.h | 3 +- drivers/scsi/pm8001/pm8001_hwi.c | 83 ++++++++++++++ drivers/scsi/pm8001/pm8001_hwi.h | 3 + drivers/scsi/pm8001/pm8001_init.c | 4 + drivers/scsi/pm8001/pm8001_sas.h | 68 +++++++++++ drivers/scsi/pm8001/pm80xx_hwi.c | 225 +++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 520 insertions(+), 1 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +129
-0@@ -309,6 +309,94 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, } static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);/** +* pm8001_ctl_ib_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ +static ssize_t pm8001_ctl_ib_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define IB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +#define IB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ib_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + +return str - buf; +} + +static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, NULL); +/** +* pm8001_ctl_ob_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ + +static ssize_t pm8001_ctl_ob_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define OB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +#define OB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ob_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + +return str - buf; +} +static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, NULL); +/** * pm8001_ctl_bios_version_show - Bios version Display * @cdev:pointer to embedded class device * @buf:the buffer returned @@ -377,6 +465,43 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev, } static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL); +/** +** pm8001_ctl_fatal_log_show - fatal error logging +** @cdev:pointer to embedded class device +** @buf: the buffer returned +** +** A sysfs 'read-only' shost attribute. +**/ + +static ssize_t pm8001_ctl_fatal_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm80xx_get_fatal_dump (cdev, attr, buf); +return count; +} + +static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, NULL); + + +/** +** pm8001_ctl_gsm_log_show - gsm dump collection +** @cdev:pointer to embedded class device +** @buf: the buffer returned +**A sysfs 'read-only' shost attribute. +**/ +static ssize_t pm8001_ctl_gsm_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm8001_get_gsm_dump (cdev,SYSFS_OFFSET , buf); +return count; +} + +static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); +#define FLASH_CMD_NONE 0x00#define FLASH_CMD_UPDATE 0x01#define FLASH_CMD_SET_NVMD 0x02@@ -636,6 +761,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_update_fw, &dev_attr_aap_log, &dev_attr_iop_log, + &dev_attr_fatal_log, + &dev_attr_gsm_log, &dev_attr_max_out_io, &dev_attr_max_devices, &dev_attr_max_sg_list,@@ -643,6 +770,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_logging_level, &dev_attr_host_sas_address, &dev_attr_bios_version, + &dev_attr_ib_log, + &dev_attr_ob_log, NULL, };drivers/scsi/pm8001/pm8001_ctl.h +4
-0@@ -55,5 +55,9 @@#define FAIL_OUT_MEMORY 0x000c00#define FLASH_IN_PROGRESS 0x001000 +#define IB_OB_READ_TIMES 256 +#define SYSFS_OFFSET 1024 +#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) +#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)#endif /* PM8001_CTL_H_INCLUDED */ drivers/scsi/pm8001/pm8001_defs.h +2
-1@@ -102,7 +102,8 @@ enum memory_region_num {NVMD ,/* NVM device */ DEV_MEM ,/* memory for devices */ CCB_MEM ,/* memory for command control block */ - FW_FLASH /* memory for fw flash update */ +FW_FLASH ,/* memory for fw flash update */ + FORENSIC_MEM /* memory for fw forensic data */ };#define PM8001_EVENT_LOG_SIZE (128 * 1024)drivers/scsi/pm8001/pm8001_hwi.c +83
-0@@ -5015,6 +5015,89 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,return rc; } +ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 length,char * buf) +{ +u32 value, rem, offset =0 , bar =0 ; +u32 index, work_offset, dw_length; +u32 shift_value, gsm_base, gsm_dump_offset; +char *direct_data; +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + + direct_data = buf; + gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset; + +/* check max is 1 Mbytes */ +if ((length >0x100000 ) || (gsm_dump_offset &3 ) || + ((gsm_dump_offset + length) >0x1000000 )) +return 1 ; + +if (pm8001_ha->chip_id == chip_8001) + bar =2 ; +else + bar =1 ; + + work_offset = gsm_dump_offset &0xFFFF0000 ; + offset = gsm_dump_offset &0x0000FFFF ; + gsm_dump_offset = work_offset; +/* adjust length to dword boundary */ + rem = length &3 ; + dw_length = length >>2 ; + +for (index =0 ; index < dw_length; index++) { +if ((work_offset + offset) &0xFFFF0000 ) { +if (pm8001_ha->chip_id == chip_8001) + shift_value = ((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ); +else + shift_value = (((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ) >> +SHIFT_REG_BIT_SHIFT ); + +if (pm8001_ha->chip_id == chip_8001) { + gsm_base =GSM_BASE ; +if (-1 ==pm8001_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + }else { + gsm_base =0 ; +if (-1 ==pm80xx_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + } + gsm_dump_offset = (gsm_dump_offset + offset) & +0xFFFF0000 ; + work_offset =0 ; + offset = offset &0x0000FFFF ; + } + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); + direct_data +=sprintf (direct_data,"%08x " , value); + offset +=4 ; + } +if (rem !=0 ) { + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); +/* xfr for non_dw */ + direct_data +=sprintf (direct_data,"%08x " , value); + } +/* Shift back to BAR4 original address */ +if (pm8001_ha->chip_id == chip_8001) { +if (-1 ==pm8001_bar4_shift (pm8001_ha,0 )) +return 1 ; + }else { +if (-1 ==pm80xx_bar4_shift (pm8001_ha,0 )) +return 1 ; + } + pm8001_ha->fatal_forensic_shift_offset +=1024 ; + +if (pm8001_ha->fatal_forensic_shift_offset >=0x100000 ) + pm8001_ha->fatal_forensic_shift_offset =0 ; +return direct_data - buf; +} +int pm8001_chip_set_dev_state_req (struct pm8001_hba_info *pm8001_ha,struct pm8001_device *pm8001_dev,u32 state)drivers/scsi/pm8001/pm8001_hwi.h +3
-0@@ -1027,5 +1027,8 @@ struct set_dev_state_resp {#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 +#define GSM_BASE 0x4F0000 +#define SHIFT_REG_64K_MASK 0xffff0000 +#define SHIFT_REG_BIT_SHIFT 8#endif drivers/scsi/pm8001/pm8001_init.c +4
-0@@ -347,6 +347,10 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,/* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH ].total_len =4096 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].num_elements =1 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].total_len =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].element_size =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].alignment =0x10000 ;for (i =0 ; i <USI_MAX_MEMCNT ; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr,drivers/scsi/pm8001/pm8001_sas.h +68
-0@@ -132,6 +132,61 @@ struct pm8001_ioctl_payload {u8 *func_specific; }; +#define MPI_FATAL_ERROR_TABLE_OFFSET_MASK 0xFFFFFF +#define MPI_FATAL_ERROR_TABLE_SIZE (value) ((0xFF000000 & value) >> SHIFT24) +#define MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x00/* HNFBUFL */ +#define MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x04/* HNFBUFH */ +#define MPI_FATAL_EDUMP_TABLE_LENGTH 0x08/* HNFBLEN */ +#define MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x0C/* FDDHSHK */ +#define MPI_FATAL_EDUMP_TABLE_STATUS 0x10/* FDDTSTAT */ +#define MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x14/* ACCDDLEN */ +#define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1 +#define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED 0x1 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA 0x2 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE 0x3 +#define TYPE_GSM_SPACE 1 +#define TYPE_QUEUE 2 +#define TYPE_FATAL 3 +#define TYPE_NON_FATAL 4 +#define TYPE_INBOUND 1 +#define TYPE_OUTBOUND 2 +struct forensic_data { +u32 data_type; +union { +struct { +u32 direct_len; +u32 direct_offset; +void *direct_data; + } gsm_buf; +struct { +u16 queue_type; +u16 queue_index; +u32 direct_len; +void *direct_data; + } queue_buf; +struct { +u32 direct_len; +u32 direct_offset; +u32 read_len; +void *direct_data; + } data_buf; + }; +}; + +/* bit31-26 - mask bar */ +#define SCRATCH_PAD0_BAR_MASK 0xFC000000 +/* bit25-0 - offset mask */ +#define SCRATCH_PAD0_OFFSET_MASK 0x03FFFFFF +/* if AAP error state */ +#define SCRATCH_PAD0_AAPERR_MASK 0xFFFFFFFF +/* Inbound doorbell bit7 */ +#define SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP 0x80 +/* Inbound doorbell bit7 SPCV */ +#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80 +#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD 0x28) */ +struct pm8001_dispatch {char *name;int (*chip_init)(struct pm8001_hba_info *pm8001_ha);@@ -346,6 +401,7 @@ union main_cfg_table {u32 phy_attr_table_offset;u32 port_recovery_timer;u32 interrupt_reassertion_delay; +u32 fatal_n_non_fatal_dump;/* 0x28 */ } pm80xx_tbl; };@@ -420,6 +476,13 @@ struct pm8001_hba_info {struct pm8001_hba_memspace io_mem[6 ];struct mpi_mem_req memoryMap;struct encrypt encrypt_info;/* support encryption */ +struct forensic_data forensic_info; +u32 fatal_bar_loc; +u32 forensic_last_offset; +u32 fatal_forensic_shift_offset; +u32 forensic_fatal_step; +u32 evtlog_ib_offset; +u32 evtlog_ob_offset;void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *general_stat_tbl_addr;/*General Status Table Addr*/ @@ -428,6 +491,7 @@ struct pm8001_hba_info {void __iomem *pspa_q_tbl_addr;/*MPI SAS PHY attributes Queue Config Table Addr*/ void __iomem *ivt_tbl_addr;/*MPI IVT Table Addr */ +void __iomem *fatal_tbl_addr;/*MPI IVT Table Addr */ union main_cfg_table main_cfg_tbl;union general_status_table gs_tbl;struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_SPCV_INB_NUM ];@@ -634,6 +698,10 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);int pm8001_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);void pm8001_set_phy_profile (struct pm8001_hba_info *pm8001_ha,u32 length,u8 *buf); +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue); +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf); +ssize_t pm8001_get_gsm_dump (struct device *cdev,u32 ,char *buf);/* ctl shared API */ extern struct device_attribute *pm8001_host_attrs[];drivers/scsi/pm8001/pm80xx_hwi.c +225
-0@@ -45,6 +45,228 @@#define SMP_DIRECT 1#define SMP_INDIRECT 2 + + +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shift_value) +{ +u32 reg_val; +unsigned long start; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , shift_value); +/* confirm the setting is written */ + start = jiffies +HZ ;/* 1 sec */ +do { + reg_val =pm8001_cr32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER ); + }while ((reg_val != shift_value) &&time_before (jiffies, start)); +if (reg_val != shift_value) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } +return 0 ; +} + +void pm80xx_pci_mem_copy (struct pm8001_hba_info *pm8001_ha,u32 soffset, +const void *destination, +u32 dw_count,u32 bus_base_number) +{ +u32 index, value, offset; +u32 *destination1; + destination1 = (u32 *)destination; + +for (index =0 ; index < dw_count; index +=4 , destination1++) { + offset = (soffset + index /4 ); +if (offset < (64 *1024 )) { + value =pm8001_cr32 (pm8001_ha, bus_base_number, offset); + *destination1 =cpu_to_le32 (value); + } + } +return ; +} + +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr; +u32 status =1 ; +u32 accum_len , reg_val, index, *temp; +unsigned long start; +u8 *direct_data; +char *fatal_error_data = buf; + + pm8001_ha->forensic_info.data_buf.direct_data = buf; +if (pm8001_ha->chip_id == chip_8001) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"Not supported for SPC controller" ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("forensic_info TYPE_NON_FATAL..............\n" )); + direct_data = (u8 *)fatal_error_data; + pm8001_ha->forensic_info.data_type =TYPE_NON_FATAL ; + pm8001_ha->forensic_info.data_buf.direct_len =SYSFS_OFFSET ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + + pm8001_ha->forensic_info.data_buf.direct_data = direct_data; + } + +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +/* start to get data */ +/* Program the MEMBASE II Shifting Register with 0x00.*/ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->forensic_last_offset =0 ; + pm8001_ha->forensic_fatal_step =0 ; + pm8001_ha->fatal_bar_loc =0 ; + } +/* Read until accum_len is retrived */ + accum_len =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ); +PM8001_IO_DBG (pm8001_ha,pm8001_printk ("accum_len 0x%x\n" , + accum_len)); +if (accum_len ==0xFFFFFFFF ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("Possible PCI issue 0x%x not expected\n" , + accum_len)); +return status; + } +if (accum_len ==0 || accum_len >=0x100000 ) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,0xFFFFFFFF ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } + temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr; +if (pm8001_ha->forensic_fatal_step ==0 ) { +moreData: +if (pm8001_ha->forensic_info.data_buf.direct_data) { +/* Data is in bar, copy to host memory */ +pm80xx_pci_mem_copy (pm8001_ha, pm8001_ha->fatal_bar_loc, + pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr, + pm8001_ha->forensic_info.data_buf.direct_len , +1 ); + } + pm8001_ha->fatal_bar_loc += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.direct_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_last_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.read_len = + pm8001_ha->forensic_info.data_buf.direct_len; + +if (pm8001_ha->forensic_last_offset >= accum_len) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,3 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + + pm8001_ha->fatal_bar_loc =0 ; + pm8001_ha->forensic_fatal_step =1 ; + pm8001_ha->fatal_forensic_shift_offset =0 ; + pm8001_ha->forensic_last_offset =0 ; + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->fatal_bar_loc < (64 *1024 )) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } + +/* Increment the MEMBASE II Shifting Register value by 0x100.*/ + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index <256 ; index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + pm8001_ha->fatal_forensic_shift_offset +=0x100 ; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->fatal_bar_loc =0 ; + status =0 ; +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_fatal_step ==1 ) { + pm8001_ha->fatal_forensic_shift_offset =0 ; +/* Read 64K of the debug data. */ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE , +MPI_FATAL_EDUMP_HANDSHAKE_RDY ); + +/* Poll FDDHSHK until clear */ + start = jiffies + (2 *HZ );/* 2 sec */ + +do { + reg_val =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ); + }while ((reg_val) &&time_before (jiffies, start)); + +if (reg_val !=0 ) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } + +/* Read the next 64K of the debug data. */ + pm8001_ha->forensic_fatal_step =0 ; +if (pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_STATUS ) != +MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE ) { +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ,0 ); + goto moreData; + }else { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,4 ); + pm8001_ha->forensic_info.data_buf.read_len =0xFFFFFFFF ; + pm8001_ha->forensic_info.data_buf.direct_len =0 ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + status =0 ; + } + } + +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; +} +/** * read_main_config_table - read the configure table and save it. * @pm8001_ha: our hba card information @@ -583,6 +805,9 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) pm8001_ha->pspa_q_tbl_addr = base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0x90 ) &0xFFFFFF ); + pm8001_ha->fatal_tbl_addr = + base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0xA0 ) & +0xFFFFFF ); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("GST OFFSET 0x%x\n",drivers/scsi/pm8001/pm80xx_hwi.h +2
-0@@ -1525,4 +1525,6 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 + +#define MEMBASE_II_SHIFT_REGISTER 0x1010#endif
Quoted 45 lines · Anand
From
ab1b030500a835eacda3d86e5570366099b21311Mon Sep 17 00:00:00 2001
From: Anand Kumar Santhanam <[email protected]>
Date: Wed, 4 Sep 2013 12:57:00 +0530
Subject: [PATCH V2 10/10] pm80xx: Firmware logging support.Supports below logging facilities,
Inbound outbound queues dump.
Non fatal dump in case of IO failures.
Fatal dump in case of firmware failure.Signed-off-by [email protected]--- drivers/scsi/pm8001/pm8001_ctl.c | 129 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_ctl.h | 4 + drivers/scsi/pm8001/pm8001_defs.h | 3 +- drivers/scsi/pm8001/pm8001_hwi.c | 83 ++++++++++++++ drivers/scsi/pm8001/pm8001_hwi.h | 3 + drivers/scsi/pm8001/pm8001_init.c | 4 + drivers/scsi/pm8001/pm8001_sas.h | 68 +++++++++++ drivers/scsi/pm8001/pm80xx_hwi.c | 225 +++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 520 insertions(+), 1 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +13
-0@@ -309,6 +309,94 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, } static DEVICE_ATTR(aap_log, S_IRUGO, pm8001_ctl_aap_log_show, NULL);/** +* pm8001_ctl_ib_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ +static ssize_t pm8001_ctl_ib_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf;
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, · line 334
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+int start =0 ; +#define IB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +#define IB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c)))
The IB_MEMMAP and IB_MEMMAP_SPC seems to be exactly the same - is that intentional? and btw. why do you use macros, when they are used just once?
(In the function below there is a similar pattern - again two identical macros) Cheers, Tomas
Quoted 641 lines
drivers/scsi/pm8001/pm8001_ctl.c +106
-0+ +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ib_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + +return str - buf; +} + +static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, NULL); +/** +* pm8001_ctl_ob_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ + +static ssize_t pm8001_ctl_ob_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define OB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +#define OB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ob_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + +return str - buf; +} +static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, NULL); +/** * pm8001_ctl_bios_version_show - Bios version Display * @cdev:pointer to embedded class device * @buf:the buffer returned @@ -377,6 +465,43 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev, } static DEVICE_ATTR(iop_log, S_IRUGO, pm8001_ctl_iop_log_show, NULL); +/** +** pm8001_ctl_fatal_log_show - fatal error logging +** @cdev:pointer to embedded class device +** @buf: the buffer returned +** +** A sysfs 'read-only' shost attribute. +**/ + +static ssize_t pm8001_ctl_fatal_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm80xx_get_fatal_dump (cdev, attr, buf); +return count; +} + +static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, NULL); + + +/** +** pm8001_ctl_gsm_log_show - gsm dump collection +** @cdev:pointer to embedded class device +** @buf: the buffer returned +**A sysfs 'read-only' shost attribute. +**/ +static ssize_t pm8001_ctl_gsm_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +u32 count; + + count =pm8001_get_gsm_dump (cdev,SYSFS_OFFSET , buf); +return count; +} + +static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); +#define FLASH_CMD_NONE 0x00#define FLASH_CMD_UPDATE 0x01#define FLASH_CMD_SET_NVMD 0x02@@ -636,6 +761,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_update_fw, &dev_attr_aap_log, &dev_attr_iop_log, + &dev_attr_fatal_log, + &dev_attr_gsm_log, &dev_attr_max_out_io, &dev_attr_max_devices, &dev_attr_max_sg_list,@@ -643,6 +770,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_logging_level, &dev_attr_host_sas_address, &dev_attr_bios_version, + &dev_attr_ib_log, + &dev_attr_ob_log, NULL, };drivers/scsi/pm8001/pm8001_ctl.h +4
-0@@ -55,5 +55,9 @@#define FAIL_OUT_MEMORY 0x000c00#define FLASH_IN_PROGRESS 0x001000 +#define IB_OB_READ_TIMES 256 +#define SYSFS_OFFSET 1024 +#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) +#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)#endif /* PM8001_CTL_H_INCLUDED */ drivers/scsi/pm8001/pm8001_defs.h +2
-1@@ -102,7 +102,8 @@ enum memory_region_num {NVMD ,/* NVM device */ DEV_MEM ,/* memory for devices */ CCB_MEM ,/* memory for command control block */ - FW_FLASH /* memory for fw flash update */ +FW_FLASH ,/* memory for fw flash update */ + FORENSIC_MEM /* memory for fw forensic data */ };#define PM8001_EVENT_LOG_SIZE (128 * 1024)drivers/scsi/pm8001/pm8001_hwi.c +83
-0@@ -5015,6 +5015,89 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,return rc; } +ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 length,char * buf) +{ +u32 value, rem, offset =0 , bar =0 ; +u32 index, work_offset, dw_length; +u32 shift_value, gsm_base, gsm_dump_offset; +char *direct_data; +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + + direct_data = buf; + gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset; + +/* check max is 1 Mbytes */ +if ((length >0x100000 ) || (gsm_dump_offset &3 ) || + ((gsm_dump_offset + length) >0x1000000 )) +return 1 ; + +if (pm8001_ha->chip_id == chip_8001) + bar =2 ; +else + bar =1 ; + + work_offset = gsm_dump_offset &0xFFFF0000 ; + offset = gsm_dump_offset &0x0000FFFF ; + gsm_dump_offset = work_offset; +/* adjust length to dword boundary */ + rem = length &3 ; + dw_length = length >>2 ; + +for (index =0 ; index < dw_length; index++) { +if ((work_offset + offset) &0xFFFF0000 ) { +if (pm8001_ha->chip_id == chip_8001) + shift_value = ((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ); +else + shift_value = (((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ) >> +SHIFT_REG_BIT_SHIFT ); + +if (pm8001_ha->chip_id == chip_8001) { + gsm_base =GSM_BASE ; +if (-1 ==pm8001_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + }else { + gsm_base =0 ; +if (-1 ==pm80xx_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + } + gsm_dump_offset = (gsm_dump_offset + offset) & +0xFFFF0000 ; + work_offset =0 ; + offset = offset &0x0000FFFF ; + } + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); + direct_data +=sprintf (direct_data,"%08x " , value); + offset +=4 ; + } +if (rem !=0 ) { + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); +/* xfr for non_dw */ + direct_data +=sprintf (direct_data,"%08x " , value); + } +/* Shift back to BAR4 original address */ +if (pm8001_ha->chip_id == chip_8001) { +if (-1 ==pm8001_bar4_shift (pm8001_ha,0 )) +return 1 ; + }else { +if (-1 ==pm80xx_bar4_shift (pm8001_ha,0 )) +return 1 ; + } + pm8001_ha->fatal_forensic_shift_offset +=1024 ; + +if (pm8001_ha->fatal_forensic_shift_offset >=0x100000 ) + pm8001_ha->fatal_forensic_shift_offset =0 ; +return direct_data - buf; +} +int pm8001_chip_set_dev_state_req (struct pm8001_hba_info *pm8001_ha,struct pm8001_device *pm8001_dev,u32 state)drivers/scsi/pm8001/pm8001_hwi.h +3
-0@@ -1027,5 +1027,8 @@ struct set_dev_state_resp {#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 +#define GSM_BASE 0x4F0000 +#define SHIFT_REG_64K_MASK 0xffff0000 +#define SHIFT_REG_BIT_SHIFT 8#endif drivers/scsi/pm8001/pm8001_init.c +4
-0@@ -347,6 +347,10 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,/* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH ].total_len =4096 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].num_elements =1 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].total_len =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].element_size =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].alignment =0x10000 ;for (i =0 ; i <USI_MAX_MEMCNT ; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr,drivers/scsi/pm8001/pm8001_sas.h +68
-0@@ -132,6 +132,61 @@ struct pm8001_ioctl_payload {u8 *func_specific; }; +#define MPI_FATAL_ERROR_TABLE_OFFSET_MASK 0xFFFFFF +#define MPI_FATAL_ERROR_TABLE_SIZE (value) ((0xFF000000 & value) >> SHIFT24) +#define MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x00/* HNFBUFL */ +#define MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x04/* HNFBUFH */ +#define MPI_FATAL_EDUMP_TABLE_LENGTH 0x08/* HNFBLEN */ +#define MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x0C/* FDDHSHK */ +#define MPI_FATAL_EDUMP_TABLE_STATUS 0x10/* FDDTSTAT */ +#define MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x14/* ACCDDLEN */ +#define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1 +#define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED 0x1 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA 0x2 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE 0x3 +#define TYPE_GSM_SPACE 1 +#define TYPE_QUEUE 2 +#define TYPE_FATAL 3 +#define TYPE_NON_FATAL 4 +#define TYPE_INBOUND 1 +#define TYPE_OUTBOUND 2 +struct forensic_data { +u32 data_type; +union { +struct { +u32 direct_len; +u32 direct_offset; +void *direct_data; + } gsm_buf; +struct { +u16 queue_type; +u16 queue_index; +u32 direct_len; +void *direct_data; + } queue_buf; +struct { +u32 direct_len; +u32 direct_offset; +u32 read_len; +void *direct_data; + } data_buf; + }; +}; + +/* bit31-26 - mask bar */ +#define SCRATCH_PAD0_BAR_MASK 0xFC000000 +/* bit25-0 - offset mask */ +#define SCRATCH_PAD0_OFFSET_MASK 0x03FFFFFF +/* if AAP error state */ +#define SCRATCH_PAD0_AAPERR_MASK 0xFFFFFFFF +/* Inbound doorbell bit7 */ +#define SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP 0x80 +/* Inbound doorbell bit7 SPCV */ +#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80 +#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD 0x28) */ +struct pm8001_dispatch {char *name;int (*chip_init)(struct pm8001_hba_info *pm8001_ha);@@ -346,6 +401,7 @@ union main_cfg_table {u32 phy_attr_table_offset;u32 port_recovery_timer;u32 interrupt_reassertion_delay; +u32 fatal_n_non_fatal_dump;/* 0x28 */ } pm80xx_tbl; };@@ -420,6 +476,13 @@ struct pm8001_hba_info {struct pm8001_hba_memspace io_mem[6 ];struct mpi_mem_req memoryMap;struct encrypt encrypt_info;/* support encryption */ +struct forensic_data forensic_info; +u32 fatal_bar_loc; +u32 forensic_last_offset; +u32 fatal_forensic_shift_offset; +u32 forensic_fatal_step; +u32 evtlog_ib_offset; +u32 evtlog_ob_offset;void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *general_stat_tbl_addr;/*General Status Table Addr*/ @@ -428,6 +491,7 @@ struct pm8001_hba_info {void __iomem *pspa_q_tbl_addr;/*MPI SAS PHY attributes Queue Config Table Addr*/ void __iomem *ivt_tbl_addr;/*MPI IVT Table Addr */ +void __iomem *fatal_tbl_addr;/*MPI IVT Table Addr */ union main_cfg_table main_cfg_tbl;union general_status_table gs_tbl;struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_SPCV_INB_NUM ];@@ -634,6 +698,10 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);int pm8001_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);void pm8001_set_phy_profile (struct pm8001_hba_info *pm8001_ha,u32 length,u8 *buf); +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue); +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf); +ssize_t pm8001_get_gsm_dump (struct device *cdev,u32 ,char *buf);/* ctl shared API */ extern struct device_attribute *pm8001_host_attrs[];drivers/scsi/pm8001/pm80xx_hwi.c +225
-0@@ -45,6 +45,228 @@#define SMP_DIRECT 1#define SMP_INDIRECT 2 + + +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shift_value) +{ +u32 reg_val; +unsigned long start; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , shift_value); +/* confirm the setting is written */ + start = jiffies +HZ ;/* 1 sec */ +do { + reg_val =pm8001_cr32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER ); + }while ((reg_val != shift_value) &&time_before (jiffies, start)); +if (reg_val != shift_value) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } +return 0 ; +} + +void pm80xx_pci_mem_copy (struct pm8001_hba_info *pm8001_ha,u32 soffset, +const void *destination, +u32 dw_count,u32 bus_base_number) +{ +u32 index, value, offset; +u32 *destination1; + destination1 = (u32 *)destination; + +for (index =0 ; index < dw_count; index +=4 , destination1++) { + offset = (soffset + index /4 ); +if (offset < (64 *1024 )) { + value =pm8001_cr32 (pm8001_ha, bus_base_number, offset); + *destination1 =cpu_to_le32 (value); + } + } +return ; +} + +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr; +u32 status =1 ; +u32 accum_len , reg_val, index, *temp; +unsigned long start; +u8 *direct_data; +char *fatal_error_data = buf; + + pm8001_ha->forensic_info.data_buf.direct_data = buf; +if (pm8001_ha->chip_id == chip_8001) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"Not supported for SPC controller" ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("forensic_info TYPE_NON_FATAL..............\n" )); + direct_data = (u8 *)fatal_error_data; + pm8001_ha->forensic_info.data_type =TYPE_NON_FATAL ; + pm8001_ha->forensic_info.data_buf.direct_len =SYSFS_OFFSET ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + + pm8001_ha->forensic_info.data_buf.direct_data = direct_data; + } + +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +/* start to get data */ +/* Program the MEMBASE II Shifting Register with 0x00.*/ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->forensic_last_offset =0 ; + pm8001_ha->forensic_fatal_step =0 ; + pm8001_ha->fatal_bar_loc =0 ; + } +/* Read until accum_len is retrived */ + accum_len =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ); +PM8001_IO_DBG (pm8001_ha,pm8001_printk ("accum_len 0x%x\n" , + accum_len)); +if (accum_len ==0xFFFFFFFF ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("Possible PCI issue 0x%x not expected\n" , + accum_len)); +return status; + } +if (accum_len ==0 || accum_len >=0x100000 ) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,0xFFFFFFFF ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } + temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr; +if (pm8001_ha->forensic_fatal_step ==0 ) { +moreData: +if (pm8001_ha->forensic_info.data_buf.direct_data) { +/* Data is in bar, copy to host memory */ +pm80xx_pci_mem_copy (pm8001_ha, pm8001_ha->fatal_bar_loc, + pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr, + pm8001_ha->forensic_info.data_buf.direct_len , +1 ); + } + pm8001_ha->fatal_bar_loc += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.direct_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_last_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.read_len = + pm8001_ha->forensic_info.data_buf.direct_len; + +if (pm8001_ha->forensic_last_offset >= accum_len) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,3 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + + pm8001_ha->fatal_bar_loc =0 ; + pm8001_ha->forensic_fatal_step =1 ; + pm8001_ha->fatal_forensic_shift_offset =0 ; + pm8001_ha->forensic_last_offset =0 ; + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->fatal_bar_loc < (64 *1024 )) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } + +/* Increment the MEMBASE II Shifting Register value by 0x100.*/ + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index <256 ; index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + pm8001_ha->fatal_forensic_shift_offset +=0x100 ; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->fatal_bar_loc =0 ; + status =0 ; +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_fatal_step ==1 ) { + pm8001_ha->fatal_forensic_shift_offset =0 ; +/* Read 64K of the debug data. */ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE , +MPI_FATAL_EDUMP_HANDSHAKE_RDY ); + +/* Poll FDDHSHK until clear */ + start = jiffies + (2 *HZ );/* 2 sec */ + +do { + reg_val =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ); + }while ((reg_val) &&time_before (jiffies, start)); + +if (reg_val !=0 ) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } + +/* Read the next 64K of the debug data. */ + pm8001_ha->forensic_fatal_step =0 ; +if (pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_STATUS ) != +MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE ) { +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ,0 ); + goto moreData; + }else { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,4 ); + pm8001_ha->forensic_info.data_buf.read_len =0xFFFFFFFF ; + pm8001_ha->forensic_info.data_buf.direct_len =0 ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + status =0 ; + } + } + +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; +} +/** * read_main_config_table - read the configure table and save it. * @pm8001_ha: our hba card information @@ -583,6 +805,9 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) pm8001_ha->pspa_q_tbl_addr = base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0x90 ) &0xFFFFFF ); + pm8001_ha->fatal_tbl_addr = + base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0xA0 ) & +0xFFFFFF ); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("GST OFFSET 0x%x\n",drivers/scsi/pm8001/pm80xx_hwi.h +2
-0@@ -1525,4 +1525,6 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 + +#define MEMBASE_II_SHIFT_REGISTER 0x1010#endif
Hi Tomas,
We will remove duplicate macro and resubmit updated patch.
Thanks,
Sangeetha
-----Original Message-----
From: Tomas Henzl [mailto:[email protected]]
Sent: Friday, September 27, 2013 6:32 PM
To: Anand Kumar Santhanam
Cc: [email protected]; Sangeetha Gnanasekaran; Nikith Ganigarakoppal; Viswas G; [email protected]
Subject: Re: [PATCH V2 10/10] pm80xx: Firmware logging support
Quoted 12 lines · Anand
From
ab1b030500a835eacda3d86e5570366099b21311Mon Sep 17 00:00:00 2001
From: Anand Kumar Santhanam <[email protected]>
Date: Wed, 4 Sep 2013 12:57:00 +0530
Subject: [PATCH V2 10/10] pm80xx: Firmware logging support.Supports below logging facilities,
Inbound outbound queues dump.
Non fatal dump in case of IO failures.
Fatal dump in case of firmware failure.Signed-off-by [email protected]
Quoted 9 lines
--- drivers/scsi/pm8001/pm8001_ctl.c | 129 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_ctl.h | 4 + drivers/scsi/pm8001/pm8001_defs.h | 3 +- drivers/scsi/pm8001/pm8001_hwi.c | 83 ++++++++++++++ drivers/scsi/pm8001/pm8001_hwi.h | 3 + drivers/scsi/pm8001/pm8001_init.c | 4 + drivers/scsi/pm8001/pm8001_sas.h | 68 +++++++++++ drivers/scsi/pm8001/pm80xx_hwi.c | 225
+++++++++++++++++++++++++++++++++++++
Quoted 24 lines
drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 520 insertions(+), 1 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +12
-0@@ -309,6 +309,94 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, } static DEVICE_ATTR(aap_log, S_IRUGO,pm8001_ctl_aap_log_show ,NULL );/** +* pm8001_ctl_ib_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ +static ssize_t pm8001_ctl_ib_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf;
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct · line 333
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+int start =0 ; +#define IB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +#define IB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c)))
The IB_MEMMAP and IB_MEMMAP_SPC seems to be exactly the same - is that intentional?
and btw. why do you use macros, when they are used just once? (In the function below there is a similar pattern - again two identical macros) Cheers, Tomas
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 4 lines
drivers/scsi/pm8001/pm8001_ctl.c +4
-0+ +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str += sprintf(str, "0x%08x\n",
IB_MEMMAP(start));
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct · line 339
Quoted 2 lines
drivers/scsi/pm8001/pm8001_ctl.c +2
-0+else + str += sprintf(str, "0x%08x\n",
IB_MEMMAP_SPC(start));
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 4 lines
drivers/scsi/pm8001/pm8001_ctl.c +4
-0+ start = start +4 ; + } + pm8001_ha->evtlog_ib_offset +=SYSFS_OFFSET ; + if ((((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE))
== 0)
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 3 lines
drivers/scsi/pm8001/pm8001_ctl.c +3
-0+ && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + if ((((pm8001_ha->evtlog_ib_offset) % (PM8001_IB_OB_QUEUE_SIZE))
== 0)
Quoted 26 lines
drivers/scsi/pm8001/pm8001_ctl.c +26
-0+ && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + +return str - buf; +} + +static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, +NULL); +/** +* pm8001_ctl_ob_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ + +static ssize_t pm8001_ctl_ob_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define OB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+ pm8001_ha->evtlog_ob_offset + (c))) + +#define OB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str += sprintf(str, "0x%08x\n",
OB_MEMMAP(start));
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct · line 384
Quoted 2 lines
drivers/scsi/pm8001/pm8001_ctl.c +2
-0+else + str += sprintf(str, "0x%08x\n",
OB_MEMMAP_SPC(start));
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 4 lines
drivers/scsi/pm8001/pm8001_ctl.c +4
-0+ start = start +4 ; + } + pm8001_ha->evtlog_ob_offset +=SYSFS_OFFSET ; + if ((((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE))
== 0)
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct device *cdev,
Quoted 3 lines
drivers/scsi/pm8001/pm8001_ctl.c +3
-0+ && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + if ((((pm8001_ha->evtlog_ob_offset) % (PM8001_IB_OB_QUEUE_SIZE))
== 0)
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct
Quoted 108 lines
drivers/scsi/pm8001/pm8001_ctl.c +48
-0+ && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + +return str - buf; +} +static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, +NULL); +/** * pm8001_ctl_bios_version_show - Bios version Display * @cdev:pointer to embedded class device * @buf:the buffer returned @@ -377,6 +465,43 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev, } static DEVICE_ATTR(iop_log, S_IRUGO,pm8001_ctl_iop_log_show ,NULL ); +/** +** pm8001_ctl_fatal_log_show - fatal error logging +** @cdev:pointer to embedded class device +** @buf: the buffer returned +** +** A sysfs 'read-only' shost attribute. +**/ + +static ssize_t pm8001_ctl_fatal_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +u32 count; + + count =pm80xx_get_fatal_dump (cdev, attr, buf); +return count; +} + +static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, +NULL); + + +/** +** pm8001_ctl_gsm_log_show - gsm dump collection +** @cdev:pointer to embedded class device +** @buf: the buffer returned +**A sysfs 'read-only' shost attribute. +**/ +static ssize_t pm8001_ctl_gsm_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +u32 count; + + count =pm8001_get_gsm_dump (cdev,SYSFS_OFFSET , buf); +return count; +} + +static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); +#define FLASH_CMD_NONE 0x00#define FLASH_CMD_UPDATE 0x01#define FLASH_CMD_SET_NVMD 0x02@@ -636,6 +761,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_update_fw, &dev_attr_aap_log, &dev_attr_iop_log, + &dev_attr_fatal_log, + &dev_attr_gsm_log, &dev_attr_max_out_io, &dev_attr_max_devices, &dev_attr_max_sg_list,@@ -643,6 +770,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_logging_level, &dev_attr_host_sas_address, &dev_attr_bios_version, + &dev_attr_ib_log, + &dev_attr_ob_log, NULL, };drivers/scsi/pm8001/pm8001_ctl.h +4
-0@@ -55,5 +55,9 @@#define FAIL_OUT_MEMORY 0x000c00#define FLASH_IN_PROGRESS 0x001000 +#define IB_OB_READ_TIMES 256 +#define SYSFS_OFFSET 1024 +#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) +#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)#endif /* PM8001_CTL_H_INCLUDED */ drivers/scsi/pm8001/pm8001_defs.h +2
-1@@ -102,7 +102,8 @@ enum memory_region_num {NVMD ,/* NVM device */ DEV_MEM ,/* memory for devices */ CCB_MEM ,/* memory for command control block */ - FW_FLASH /* memory for fw flash update */ +FW_FLASH ,/* memory for fw flash update */ + FORENSIC_MEM /* memory for fw forensic data */ };#define PM8001_EVENT_LOG_SIZE (128 * 1024)drivers/scsi/pm8001/pm8001_hwi.c +0
-0@@ -5015,6 +5015,89 @@ pm8001_chip_fw_flash_update_req(struct
pm8001_hba_info *pm8001_ha,
Quoted 27 lines
drivers/scsi/pm8001/pm8001_hwi.c +24
-0return rc; } +ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 length,char * buf) { +u32 value, rem, offset =0 , bar =0 ; +u32 index, work_offset, dw_length; +u32 shift_value, gsm_base, gsm_dump_offset; +char *direct_data; +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + + direct_data = buf; + gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset; + +/* check max is 1 Mbytes */ +if ((length >0x100000 ) || (gsm_dump_offset &3 ) || + ((gsm_dump_offset + length) >0x1000000 )) +return 1 ; + +if (pm8001_ha->chip_id == chip_8001) + bar =2 ; +else + bar =1 ; + + work_offset = gsm_dump_offset &0xFFFF0000 ;
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 10 lines
drivers/scsi/pm8001/pm8001_hwi.c +10
-0+ offset = gsm_dump_offset &0x0000FFFF ; + gsm_dump_offset = work_offset; +/* adjust length to dword boundary */ + rem = length &3 ; + dw_length = length >>2 ; + +for (index =0 ; index < dw_length; index++) { +if ((work_offset + offset) &0xFFFF0000 ) { +if (pm8001_ha->chip_id == chip_8001) + shift_value = ((gsm_dump_offset +
offset) &
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 3 lines
drivers/scsi/pm8001/pm8001_hwi.c +3
-0+ SHIFT_REG_64K_MASK); + else + shift_value = (((gsm_dump_offset +
offset) &
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 7 lines
drivers/scsi/pm8001/pm8001_hwi.c +7
-0+ SHIFT_REG_64K_MASK) >> + SHIFT_REG_BIT_SHIFT); + + if (pm8001_ha->chip_id == chip_8001) { + gsm_base = GSM_BASE; + if (-1 == pm8001_bar4_shift(pm8001_ha, + (gsm_base +
shift_value)))
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 5 lines
drivers/scsi/pm8001/pm8001_hwi.c +5
-0+return 1 ; + } else { + gsm_base =0 ; + if (-1 == pm80xx_bar4_shift(pm8001_ha, + (gsm_base +
shift_value)))
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 8 lines
drivers/scsi/pm8001/pm8001_hwi.c +8
-0+return 1 ; + } + gsm_dump_offset = (gsm_dump_offset + offset) & +0xFFFF0000 ; + work_offset =0 ; + offset = offset &0x0000FFFF ; + } + value = pm8001_cr32(pm8001_ha, bar, (work_offset +
offset) &
drivers/scsi/pm8001/pm8001_hwi.c pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,
Quoted 6 lines
drivers/scsi/pm8001/pm8001_hwi.c +6
-0+ 0x0000FFFF); + direct_data +=sprintf (direct_data,"%08x " , value); + offset +=4 ; + } +if (rem !=0 ) { + value = pm8001_cr32(pm8001_ha, bar, (work_offset +
offset) &
drivers/scsi/pm8001/pm8001_init.c static int pm8001_alloc(struct pm8001_hba_info
Quoted 41 lines
drivers/scsi/pm8001/pm8001_hwi.c +19
-0+ 0x0000FFFF); +/* xfr for non_dw */ + direct_data +=sprintf (direct_data,"%08x " , value); + } +/* Shift back to BAR4 original address */ +if (pm8001_ha->chip_id == chip_8001) { +if (-1 ==pm8001_bar4_shift (pm8001_ha,0 )) +return 1 ; + }else { +if (-1 ==pm80xx_bar4_shift (pm8001_ha,0 )) +return 1 ; + } + pm8001_ha->fatal_forensic_shift_offset +=1024 ; + +if (pm8001_ha->fatal_forensic_shift_offset >=0x100000 ) + pm8001_ha->fatal_forensic_shift_offset =0 ; +return direct_data - buf; +} + int pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u32 state) diff --git
a/drivers/scsi/pm8001/pm8001_hwi.hb/drivers/scsi/pm8001/pm8001_hwi.hindex d7c1e20..6d91e24 100644drivers/scsi/pm8001/pm8001_hwi.h +3
-0@@ -1027,5 +1027,8 @@ struct set_dev_state_resp {#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 +#define GSM_BASE 0x4F0000 +#define SHIFT_REG_64K_MASK 0xffff0000 +#define SHIFT_REG_BIT_SHIFT 8#endif drivers/scsi/pm8001/pm8001_init.c +0
-0@@ -347,6 +347,10 @@ static int pm8001_alloc(struct pm8001_hba_info
*pm8001_ha,
drivers/scsi/pm8001/pm8001_init.c static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,
Quoted 6 lines
drivers/scsi/pm8001/pm8001_init.c +3
-0/* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH ].total_len =4096 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].num_elements =1 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].total_len =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM].element_size =
0x10000;
Quoted 10 lines
drivers/scsi/pm8001/pm8001_init.c +1
-0+ pm8001_ha->memoryMap.region[FORENSIC_MEM ].alignment =0x10000 ;for (i =0 ; i <USI_MAX_MEMCNT ; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr,drivers/scsi/pm8001/pm8001_sas.h +0
-0
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 137
Quoted 6 lines
drivers/scsi/pm8001/pm8001_sas.h +3
-0@@ -132,6 +132,61 @@ struct pm8001_ioctl_payload {u8 *func_specific; }; +#define MPI_FATAL_ERROR_TABLE_OFFSET_MASK 0xFFFFFF #define +MPI_FATAL_ERROR_TABLE_SIZE(value) ((0xFF000000 & value) >> SHIFT24) +#define MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x00/*
HNFBUFL */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 138
Quoted 1 line
drivers/scsi/pm8001/pm8001_sas.h +1
-0+#define MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x04/*
HNFBUFH */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 139
Quoted 1 line
drivers/scsi/pm8001/pm8001_sas.h +1
-0+#define MPI_FATAL_EDUMP_TABLE_LENGTH 0x08/*
HNFBLEN */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 140
Quoted 1 line
drivers/scsi/pm8001/pm8001_sas.h +1
-0+#define MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x0C/*
FDDHSHK */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 141
Quoted 1 line
drivers/scsi/pm8001/pm8001_sas.h +1
-0+#define MPI_FATAL_EDUMP_TABLE_STATUS 0x10/*
FDDTSTAT */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload { · line 142
Quoted 1 line
drivers/scsi/pm8001/pm8001_sas.h +1
-0+#define MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x14/*
ACCDDLEN */
Quoted 36 lines
drivers/scsi/pm8001/pm8001_sas.h +36
-0+#define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1 +#define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED 0x1 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA 0x2 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE 0x3 +#define TYPE_GSM_SPACE 1 +#define TYPE_QUEUE 2 +#define TYPE_FATAL 3 +#define TYPE_NON_FATAL 4 +#define TYPE_INBOUND 1 +#define TYPE_OUTBOUND 2 +struct forensic_data { +u32 data_type; +union { +struct { +u32 direct_len; +u32 direct_offset; +void *direct_data; + } gsm_buf; +struct { +u16 queue_type; +u16 queue_index; +u32 direct_len; +void *direct_data; + } queue_buf; +struct { +u32 direct_len; +u32 direct_offset; +u32 read_len; +void *direct_data; + } data_buf; + }; +}; + +/* bit31-26 - mask bar */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload {
Quoted 10 lines
drivers/scsi/pm8001/pm8001_sas.h +10
-0+#define SCRATCH_PAD0_BAR_MASK 0xFC000000 +/* bit25-0 - offset mask */ +#define SCRATCH_PAD0_OFFSET_MASK 0x03FFFFFF +/* if AAP error state */ +#define SCRATCH_PAD0_AAPERR_MASK 0xFFFFFFFF +/* Inbound doorbell bit7 */ +#define SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP 0x80 +/* Inbound doorbell bit7 SPCV */ +#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80 +#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD
0x28) */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_ioctl_payload {
Quoted 9 lines
drivers/scsi/pm8001/pm8001_sas.h +3
-0+struct pm8001_dispatch {char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); @@ -346,6 +401,7 @@ union main_cfg_table {u32 phy_attr_table_offset;u32 port_recovery_timer;u32 interrupt_reassertion_delay; +u32 fatal_n_non_fatal_dump;/* 0x28
*/
Quoted 7 lines
drivers/scsi/pm8001/pm8001_sas.h +0
-0} pm80xx_tbl; };@@ -420,6 +476,13 @@ struct pm8001_hba_info {struct pm8001_hba_memspace io_mem[6 ];struct mpi_mem_req memoryMap;struct encrypt encrypt_info;/* support encryption */
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_hba_info { · line 488
Quoted 10 lines
drivers/scsi/pm8001/pm8001_sas.h +7
-0+struct forensic_data forensic_info; +u32 fatal_bar_loc; +u32 forensic_last_offset; +u32 fatal_forensic_shift_offset; +u32 forensic_fatal_step; +u32 evtlog_ib_offset; +u32 evtlog_ob_offset;void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *general_stat_tbl_addr;/*General Status Table
Addr*/
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_hba_info { · line 492
Quoted 3 lines
drivers/scsi/pm8001/pm8001_sas.h +0
-0@@ -428,6 +491,7 @@ struct pm8001_hba_info {void __iomem *pspa_q_tbl_addr;/*MPI SAS PHY attributes Queue Config Table
Addr*/
drivers/scsi/pm8001/pm8001_sas.h struct pm8001_hba_info {
Quoted 5 lines
drivers/scsi/pm8001/pm8001_sas.h +1
-0void __iomem *ivt_tbl_addr;/*MPI IVT Table Addr */ +void __iomem *fatal_tbl_addr;/*MPI IVT Table Addr */ union main_cfg_table main_cfg_tbl;union general_status_table gs_tbl;struct inbound_queue_table
inbnd_q_tbl[PM8001_MAX_SPCV_INB_NUM];
Quoted 3 lines
drivers/scsi/pm8001/pm8001_sas.h +0
-0@@ -634,6 +698,10 @@ int pm80xx_set_thermal_config(struct
pm8001_hba_info*pm8001_ha); intpm8001_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shiftValue); void
pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha,
Quoted 14 lines
drivers/scsi/pm8001/pm8001_sas.h +4
-0u32 length, u8 *buf); +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 +shiftValue);ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf);ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 ,char *buf);/* ctl shared API */ extern struct device_attribute *pm8001_host_attrs[];drivers/scsi/pm8001/pm80xx_hwi.c +0
-0
drivers/scsi/pm8001/pm80xx_hwi.c line 54
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +7
-0@@ -45,6 +45,228 @@#define SMP_DIRECT 1#define SMP_INDIRECT 2 + + +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 +shift_value) { +u32 reg_val; +unsigned long start; + pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
shift_value);
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 4 lines
drivers/scsi/pm8001/pm80xx_hwi.c +4
-0+/* confirm the setting is written */ + start = jiffies +HZ ;/* 1 sec */ + do { + reg_val = pm8001_cr32(pm8001_ha, 0,
MEMBASE_II_SHIFT_REGISTER);
drivers/scsi/pm8001/pm80xx_hwi.c line 59
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ } while ((reg_val != shift_value) && time_before(jiffies,
start));
drivers/scsi/pm8001/pm80xx_hwi.c line 68
Quoted 3 lines
drivers/scsi/pm8001/pm80xx_hwi.c +3
-0+if (reg_val != shift_value) { + PM8001_FAIL_DBG(pm8001_ha, +
pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 7 lines
drivers/scsi/pm8001/pm80xx_hwi.c +7
-0+ " = 0x%x\n", reg_val)); +return -1 ; + } +return 0 ; +} + +void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32
soffset,
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+ const void *destination, + u32 dw_count, u32 bus_base_number) { + u32 index, value, offset; + u32 *destination1; + destination1 = (u32 *)destination; + + for (index = 0; index < dw_count; index += 4, destination1++) { + offset = (soffset + index / 4); + if (offset < (64 * 1024)) { + value = pm8001_cr32(pm8001_ha, bus_base_number,
offset);
Quoted 12 lines
drivers/scsi/pm8001/pm80xx_hwi.c +12
-0+ *destination1 =cpu_to_le32 (value); + } + } +return ; +} + +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr;
drivers/scsi/pm8001/pm80xx_hwi.c line 116
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+u32 status =1 ; +u32 accum_len , reg_val, index, *temp; +unsigned long start; +u8 *direct_data; +char *fatal_error_data = buf; + + pm8001_ha->forensic_info.data_buf.direct_data = buf; +if (pm8001_ha->chip_id == chip_8001) { + pm8001_ha->forensic_info.data_buf.direct_data += +
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 103
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ "Not supported for SPC controller"); + return (char
*)pm8001_ha->forensic_info.data_buf.direct_data -
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 5 lines
drivers/scsi/pm8001/pm80xx_hwi.c +5
-0+ (char *)buf; + } +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { + PM8001_IO_DBG(pm8001_ha, + pm8001_printk("forensic_info
TYPE_NON_FATAL..............\n"));
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 3 lines
drivers/scsi/pm8001/pm80xx_hwi.c +3
-0+ direct_data = (u8 *)fatal_error_data; + pm8001_ha->forensic_info.data_type =TYPE_NON_FATAL ; + pm8001_ha->forensic_info.data_buf.direct_len =
SYSFS_OFFSET;
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 4 lines
drivers/scsi/pm8001/pm80xx_hwi.c +4
-0+ pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + + pm8001_ha->forensic_info.data_buf.direct_data =
direct_data;
Quoted 9 lines
drivers/scsi/pm8001/pm80xx_hwi.c +9
-0+ } + +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +/* start to get data */ +/* Program the MEMBASE II Shifting Register with 0x00.*/ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->forensic_last_offset =0 ; + pm8001_ha->forensic_fatal_step =0 ;
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+ pm8001_ha->fatal_bar_loc =0 ; + } +/* Read until accum_len is retrived */ + accum_len =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ); +PM8001_IO_DBG (pm8001_ha,pm8001_printk ("accum_len 0x%x\n" , + accum_len)); +if (accum_len ==0xFFFFFFFF ) { + PM8001_IO_DBG(pm8001_ha, + pm8001_printk("Possible PCI issue 0x%x not
expected\n",
drivers/scsi/pm8001/pm80xx_hwi.c line 165
Quoted 6 lines
drivers/scsi/pm8001/pm80xx_hwi.c +6
-0+ accum_len)); +return status; + } +if (accum_len ==0 || accum_len >=0x100000 ) { + pm8001_ha->forensic_info.data_buf.direct_data += +
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 142
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ "%08x ", 0xFFFFFFFF); + return (char
*)pm8001_ha->forensic_info.data_buf.direct_data -
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 3 lines
drivers/scsi/pm8001/pm80xx_hwi.c +3
-0+ (char *)buf; + } + temp = (u32
*)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 5 lines
drivers/scsi/pm8001/pm80xx_hwi.c +5
-0+if (pm8001_ha->forensic_fatal_step ==0 ) { +moreData: +if (pm8001_ha->forensic_info.data_buf.direct_data) { +/* Data is in bar, copy to host memory */ + pm80xx_pci_mem_copy(pm8001_ha,
pm8001_ha->fatal_bar_loc,
drivers/scsi/pm8001/pm80xx_hwi.c line 151
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+
pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
drivers/scsi/pm8001/pm80xx_hwi.c line 152
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+
pm8001_ha->forensic_info.data_buf.direct_len ,
Quoted 4 lines
drivers/scsi/pm8001/pm80xx_hwi.c +4
-0+ 1); + } + pm8001_ha->fatal_bar_loc += + pm8001_ha->forensic_info.data_buf.direct_len;
drivers/scsi/pm8001/pm80xx_hwi.c line 176
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+ pm8001_ha->forensic_info.data_buf.direct_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_last_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.read_len = + pm8001_ha->forensic_info.data_buf.direct_len; + +if (pm8001_ha->forensic_last_offset >= accum_len) { + pm8001_ha->forensic_info.data_buf.direct_data += +
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 168
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ "%08x ", 3); + for (index = 0; index < (SYSFS_OFFSET / 4);
index++) {
drivers/scsi/pm8001/pm80xx_hwi.c line 169
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+
pm8001_ha->forensic_info.data_buf.direct_data +=
drivers/scsi/pm8001/pm80xx_hwi.c line 171
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ sprintf(pm8001_ha-> +
forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 172
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ "%08x ", *(temp +
index));
Quoted 5 lines
drivers/scsi/pm8001/pm80xx_hwi.c +5
-0+ } + + pm8001_ha->fatal_bar_loc =0 ; + pm8001_ha->forensic_fatal_step =1 ; + pm8001_ha->fatal_forensic_shift_offset =0 ;
drivers/scsi/pm8001/pm80xx_hwi.c line 202
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+ pm8001_ha->forensic_last_offset =0 ; + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->fatal_bar_loc < (64 *1024 )) { + pm8001_ha->forensic_info.data_buf.direct_data += + sprintf(pm8001_ha-> +
forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 189
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ "%08x ", 2); + for (index = 0; index < (SYSFS_OFFSET / 4);
index++) {
drivers/scsi/pm8001/pm80xx_hwi.c line 190
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+
pm8001_ha->forensic_info.data_buf.direct_data +=
drivers/scsi/pm8001/pm80xx_hwi.c line 192
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ sprintf(pm8001_ha-> +
forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 9 lines
drivers/scsi/pm8001/pm80xx_hwi.c +9
-0+ "%08x ", *(temp + index)); + } + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } + +/* Increment the MEMBASE II Shifting Register value by
0x100.*/
drivers/scsi/pm8001/pm80xx_hwi.c line 203
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ pm8001_ha->forensic_info.data_buf.direct_data += +
sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 229
Quoted 5 lines
drivers/scsi/pm8001/pm80xx_hwi.c +5
-0+ "%08x ", 2); +for (index =0 ; index <256 ; index++) { + pm8001_ha->forensic_info.data_buf.direct_data += + sprintf(pm8001_ha-> +
forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 209
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ "%08x ", *(temp +
index));
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 7 lines
drivers/scsi/pm8001/pm80xx_hwi.c +7
-0+ } + pm8001_ha->fatal_forensic_shift_offset +=0x100 ; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->fatal_bar_loc =0 ; + status =0 ; + return (char
*)pm8001_ha->forensic_info.data_buf.direct_data -
Quoted 7 lines
drivers/scsi/pm8001/pm80xx_hwi.c +7
-0+ (char *)buf; + } +if (pm8001_ha->forensic_fatal_step ==1 ) { + pm8001_ha->fatal_forensic_shift_offset =0 ; +/* Read 64K of the debug data. */ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset);
drivers/scsi/pm8001/pm80xx_hwi.c line 237
Quoted 10 lines
drivers/scsi/pm8001/pm80xx_hwi.c +10
-0+pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE , +MPI_FATAL_EDUMP_HANDSHAKE_RDY ); + +/* Poll FDDHSHK until clear */ + start = jiffies + (2 *HZ );/* 2 sec */ + + do { + reg_val = pm8001_mr32(fatal_table_address, +
MPI_FATAL_EDUMP_TABLE_HANDSHAKE);
drivers/scsi/pm8001/pm80xx_hwi.c line 244
Quoted 5 lines
drivers/scsi/pm8001/pm80xx_hwi.c +5
-0+ }while ((reg_val) &&time_before (jiffies, start)); + +if (reg_val !=0 ) { + PM8001_FAIL_DBG(pm8001_ha, +
pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
drivers/scsi/pm8001/pm80xx_hwi.c line 265
Quoted 9 lines
drivers/scsi/pm8001/pm80xx_hwi.c +9
-0+ " = 0x%x\n", reg_val)); +return -1 ; + } + +/* Read the next 64K of the debug data. */ + pm8001_ha->forensic_fatal_step =0 ; + if (pm8001_mr32(fatal_table_address, + MPI_FATAL_EDUMP_TABLE_STATUS) != +
MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
drivers/scsi/pm8001/pm80xx_hwi.c line 265
Quoted 7 lines
drivers/scsi/pm8001/pm80xx_hwi.c +7
-0+pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ,0 ); + goto moreData; + }else { + pm8001_ha->forensic_info.data_buf.direct_data += + sprintf(pm8001_ha-> +
forensic_info.data_buf.direct_data,
drivers/scsi/pm8001/pm80xx_hwi.c line 256
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-0+ "%08x ", 4); + pm8001_ha->forensic_info.data_buf.read_len =
0xFFFFFFFF;
drivers/scsi/pm8001/pm80xx_hwi.c line 257
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ pm8001_ha->forensic_info.data_buf.direct_len =
0;
drivers/scsi/pm8001/pm80xx_hwi.c line 258
Quoted 1 line
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ pm8001_ha->forensic_info.data_buf.direct_offset
= 0;
Quoted 13 lines
drivers/scsi/pm8001/pm80xx_hwi.c +9
-0+ pm8001_ha->forensic_info.data_buf.read_len =0 ; + status =0 ; + } + } + +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; +} +/** * read_main_config_table - read the configure table and save it. * @pm8001_ha: our hba card information @@ -583,6 +805,9 @@ static void
init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
drivers/scsi/pm8001/pm80xx_hwi.c
Quoted 2 lines
drivers/scsi/pm8001/pm80xx_hwi.c +0
-0pm8001_ha->pspa_q_tbl_addr = base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset +
0x90) &
drivers/scsi/pm8001/pm80xx_hwi.c static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)
Quoted 3 lines
drivers/scsi/pm8001/pm80xx_hwi.c +2
-00xFFFFFF); + pm8001_ha->fatal_tbl_addr = + base_addr + (pm8001_cr32(pm8001_ha, pcibar, offset +
0xA0) &
drivers/scsi/pm8001/pm80xx_hwi.h typedef struct SASProtocolTimerConfig
Quoted 9 lines
drivers/scsi/pm8001/pm80xx_hwi.c +1
-0+ 0xFFFFFF); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("GST OFFSET 0x%x\n", diff --git
a/drivers/scsi/pm8001/pm80xx_hwi.hb/drivers/scsi/pm8001/pm80xx_hwi.hindex 872d5cf..c86816b 100644drivers/scsi/pm8001/pm80xx_hwi.h +0
-0@@ -1525,4 +1525,6 @@ typedef struct SASProtocolTimerConfig
SASProtocolTimerConfig_t;
Quoted 6 lines
drivers/scsi/pm8001/pm80xx_hwi.h +2
-0#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 + +#define MEMBASE_II_SHIFT_REGISTER 0x1010#endif
Tomas,
Pls see replies inline.
Regards
Anand
-----Original Message-----
From: Tomas Henzl [mailto:[email protected]]
Sent: Friday, September 27, 2013 6:32 PM
To: Anand Kumar Santhanam
Cc: [email protected]; Sangeetha Gnanasekaran; Nikith Ganigarakoppal; Viswas G; [email protected]
Subject: Re: [PATCH V2 10/10] pm80xx: Firmware logging support
Quoted 45 lines · Anand
From
ab1b030500a835eacda3d86e5570366099b21311Mon Sep 17 00:00:00 2001
From: Anand Kumar Santhanam <[email protected]>
Date: Wed, 4 Sep 2013 12:57:00 +0530
Subject: [PATCH V2 10/10] pm80xx: Firmware logging support.Supports below logging facilities,
Inbound outbound queues dump.
Non fatal dump in case of IO failures.
Fatal dump in case of firmware failure.Signed-off-by [email protected]--- drivers/scsi/pm8001/pm8001_ctl.c | 129 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_ctl.h | 4 + drivers/scsi/pm8001/pm8001_defs.h | 3 +- drivers/scsi/pm8001/pm8001_hwi.c | 83 ++++++++++++++ drivers/scsi/pm8001/pm8001_hwi.h | 3 + drivers/scsi/pm8001/pm8001_init.c | 4 + drivers/scsi/pm8001/pm8001_sas.h | 68 +++++++++++ drivers/scsi/pm8001/pm80xx_hwi.c | 225 +++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 520 insertions(+), 1 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +12
-0@@ -309,6 +309,94 @@ static ssize_t pm8001_ctl_aap_log_show(struct device *cdev, } static DEVICE_ATTR(aap_log, S_IRUGO,pm8001_ctl_aap_log_show ,NULL );/** +* pm8001_ctl_ib_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ +static ssize_t pm8001_ctl_ib_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf;
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_aap_log_show(struct · line 333
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+int start =0 ; +#define IB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c))) + +#define IB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[IB].virt_ptr + \ + pm8001_ha->evtlog_ib_offset + (c)))
The IB_MEMMAP and IB_MEMMAP_SPC seems to be exactly the same - is that intentional? and btw. why do you use macros, when they are used just once?
(In the function below there is a similar pattern - again two identical macros) Cheers, Tomas
Anand> The updated patch has been submitted.
We are using macro for better readability.
Quoted 644 lines
drivers/scsi/pm8001/pm8001_ctl.c +106
-0+ +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,IB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ib_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; +if ((((pm8001_ha->evtlog_ib_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ib_offset =0 ; + +return str - buf; +} + +static DEVICE_ATTR(ib_log, S_IRUGO, pm8001_ctl_ib_queue_log_show, +NULL); +/** +* pm8001_ctl_ob_queue_log_show - Out bound Queue log +* @cdev:pointer to embedded class device +* @buf: the buffer returned +* A sysfs 'read-only' shost attribute. +*/ + +static ssize_t pm8001_ctl_ob_queue_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int offset; +char *str = buf; +int start =0 ; +#define OB_MEMMAP (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +#define OB_MEMMAP_SPC (c) \ + (*(u32 *)((u8 *)pm8001_ha-> \ + memoryMap.region[OB].virt_ptr + \ + pm8001_ha->evtlog_ob_offset + (c))) + +for (offset =0 ; offset <IB_OB_READ_TIMES ; offset++) { +if (pm8001_ha->chip_id != chip_8001) + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP (start)); +else + str +=sprintf (str,"0x%08x\n" ,OB_MEMMAP_SPC (start)); + start = start +4 ; + } + pm8001_ha->evtlog_ob_offset +=SYSFS_OFFSET ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM80XX_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id != chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; +if ((((pm8001_ha->evtlog_ob_offset) % (PM8001_IB_OB_QUEUE_SIZE )) ==0 ) + && (pm8001_ha->chip_id == chip_8001)) + pm8001_ha->evtlog_ob_offset =0 ; + +return str - buf; +} +static DEVICE_ATTR(ob_log, S_IRUGO, pm8001_ctl_ob_queue_log_show, +NULL); +/** * pm8001_ctl_bios_version_show - Bios version Display * @cdev:pointer to embedded class device * @buf:the buffer returned @@ -377,6 +465,43 @@ static ssize_t pm8001_ctl_iop_log_show(struct device *cdev, } static DEVICE_ATTR(iop_log, S_IRUGO,pm8001_ctl_iop_log_show ,NULL ); +/** +** pm8001_ctl_fatal_log_show - fatal error logging +** @cdev:pointer to embedded class device +** @buf: the buffer returned +** +** A sysfs 'read-only' shost attribute. +**/ + +static ssize_t pm8001_ctl_fatal_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +u32 count; + + count =pm80xx_get_fatal_dump (cdev, attr, buf); +return count; +} + +static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, +NULL); + + +/** +** pm8001_ctl_gsm_log_show - gsm dump collection +** @cdev:pointer to embedded class device +** @buf: the buffer returned +**A sysfs 'read-only' shost attribute. +**/ +static ssize_t pm8001_ctl_gsm_log_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +u32 count; + + count =pm8001_get_gsm_dump (cdev,SYSFS_OFFSET , buf); +return count; +} + +static DEVICE_ATTR(gsm_log, S_IRUGO, pm8001_ctl_gsm_log_show, NULL); +#define FLASH_CMD_NONE 0x00#define FLASH_CMD_UPDATE 0x01#define FLASH_CMD_SET_NVMD 0x02@@ -636,6 +761,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_update_fw, &dev_attr_aap_log, &dev_attr_iop_log, + &dev_attr_fatal_log, + &dev_attr_gsm_log, &dev_attr_max_out_io, &dev_attr_max_devices, &dev_attr_max_sg_list,@@ -643,6 +770,8 @@ struct device_attribute *pm8001_host_attrs[] = { &dev_attr_logging_level, &dev_attr_host_sas_address, &dev_attr_bios_version, + &dev_attr_ib_log, + &dev_attr_ob_log, NULL, };drivers/scsi/pm8001/pm8001_ctl.h +4
-0@@ -55,5 +55,9 @@#define FAIL_OUT_MEMORY 0x000c00#define FLASH_IN_PROGRESS 0x001000 +#define IB_OB_READ_TIMES 256 +#define SYSFS_OFFSET 1024 +#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024) +#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)#endif /* PM8001_CTL_H_INCLUDED */ drivers/scsi/pm8001/pm8001_defs.h +2
-1@@ -102,7 +102,8 @@ enum memory_region_num {NVMD ,/* NVM device */ DEV_MEM ,/* memory for devices */ CCB_MEM ,/* memory for command control block */ - FW_FLASH /* memory for fw flash update */ +FW_FLASH ,/* memory for fw flash update */ + FORENSIC_MEM /* memory for fw forensic data */ };#define PM8001_EVENT_LOG_SIZE (128 * 1024)drivers/scsi/pm8001/pm8001_hwi.c +82
-0@@ -5015,6 +5015,89 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,return rc; } +ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 length,char * buf) { +u32 value, rem, offset =0 , bar =0 ; +u32 index, work_offset, dw_length; +u32 shift_value, gsm_base, gsm_dump_offset; +char *direct_data; +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + + direct_data = buf; + gsm_dump_offset = pm8001_ha->fatal_forensic_shift_offset; + +/* check max is 1 Mbytes */ +if ((length >0x100000 ) || (gsm_dump_offset &3 ) || + ((gsm_dump_offset + length) >0x1000000 )) +return 1 ; + +if (pm8001_ha->chip_id == chip_8001) + bar =2 ; +else + bar =1 ; + + work_offset = gsm_dump_offset &0xFFFF0000 ; + offset = gsm_dump_offset &0x0000FFFF ; + gsm_dump_offset = work_offset; +/* adjust length to dword boundary */ + rem = length &3 ; + dw_length = length >>2 ; + +for (index =0 ; index < dw_length; index++) { +if ((work_offset + offset) &0xFFFF0000 ) { +if (pm8001_ha->chip_id == chip_8001) + shift_value = ((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ); +else + shift_value = (((gsm_dump_offset + offset) & +SHIFT_REG_64K_MASK ) >> +SHIFT_REG_BIT_SHIFT ); + +if (pm8001_ha->chip_id == chip_8001) { + gsm_base =GSM_BASE ; +if (-1 ==pm8001_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + }else { + gsm_base =0 ; +if (-1 ==pm80xx_bar4_shift (pm8001_ha, + (gsm_base + shift_value))) +return 1 ; + } + gsm_dump_offset = (gsm_dump_offset + offset) & +0xFFFF0000 ; + work_offset =0 ; + offset = offset &0x0000FFFF ; + } + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); + direct_data +=sprintf (direct_data,"%08x " , value); + offset +=4 ; + } +if (rem !=0 ) { + value =pm8001_cr32 (pm8001_ha, bar, (work_offset + offset) & +0x0000FFFF ); +/* xfr for non_dw */ + direct_data +=sprintf (direct_data,"%08x " , value); + } +/* Shift back to BAR4 original address */ +if (pm8001_ha->chip_id == chip_8001) { +if (-1 ==pm8001_bar4_shift (pm8001_ha,0 )) +return 1 ; + }else { +if (-1 ==pm80xx_bar4_shift (pm8001_ha,0 )) +return 1 ; + } + pm8001_ha->fatal_forensic_shift_offset +=1024 ; + +if (pm8001_ha->fatal_forensic_shift_offset >=0x100000 ) + pm8001_ha->fatal_forensic_shift_offset =0 ; +return direct_data - buf; +} + int pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_device *pm8001_dev, u32 state) diff --git
a/drivers/scsi/pm8001/pm8001_hwi.hb/drivers/scsi/pm8001/pm8001_hwi.hindex d7c1e20..6d91e24 100644drivers/scsi/pm8001/pm8001_hwi.h +3
-0@@ -1027,5 +1027,8 @@ struct set_dev_state_resp {#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 +#define GSM_BASE 0x4F0000 +#define SHIFT_REG_64K_MASK 0xffff0000 +#define SHIFT_REG_BIT_SHIFT 8#endif drivers/scsi/pm8001/pm8001_init.c +4
-0@@ -347,6 +347,10 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha,/* Memory region for fw flash */ pm8001_ha->memoryMap.region[FW_FLASH ].total_len =4096 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].num_elements =1 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].total_len =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].element_size =0x10000 ; + pm8001_ha->memoryMap.region[FORENSIC_MEM ].alignment =0x10000 ;for (i =0 ; i <USI_MAX_MEMCNT ; i++) { if (pm8001_mem_alloc(pm8001_ha->pdev, &pm8001_ha->memoryMap.region[i].virt_ptr,drivers/scsi/pm8001/pm8001_sas.h +65
-0@@ -132,6 +132,61 @@ struct pm8001_ioctl_payload {u8 *func_specific; }; +#define MPI_FATAL_ERROR_TABLE_OFFSET_MASK 0xFFFFFF #define +MPI_FATAL_ERROR_TABLE_SIZE(value) ((0xFF000000 & value) >> SHIFT24) +#define MPI_FATAL_EDUMP_TABLE_LO_OFFSET 0x00/* HNFBUFL */ +#define MPI_FATAL_EDUMP_TABLE_HI_OFFSET 0x04/* HNFBUFH */ +#define MPI_FATAL_EDUMP_TABLE_LENGTH 0x08/* HNFBLEN */ +#define MPI_FATAL_EDUMP_TABLE_HANDSHAKE 0x0C/* FDDHSHK */ +#define MPI_FATAL_EDUMP_TABLE_STATUS 0x10/* FDDTSTAT */ +#define MPI_FATAL_EDUMP_TABLE_ACCUM_LEN 0x14/* ACCDDLEN */ +#define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1 +#define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0 +#define MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED 0x1 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA 0x2 +#define MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE 0x3 +#define TYPE_GSM_SPACE 1 +#define TYPE_QUEUE 2 +#define TYPE_FATAL 3 +#define TYPE_NON_FATAL 4 +#define TYPE_INBOUND 1 +#define TYPE_OUTBOUND 2 +struct forensic_data { +u32 data_type; +union { +struct { +u32 direct_len; +u32 direct_offset; +void *direct_data; + } gsm_buf; +struct { +u16 queue_type; +u16 queue_index; +u32 direct_len; +void *direct_data; + } queue_buf; +struct { +u32 direct_len; +u32 direct_offset; +u32 read_len; +void *direct_data; + } data_buf; + }; +}; + +/* bit31-26 - mask bar */ +#define SCRATCH_PAD0_BAR_MASK 0xFC000000 +/* bit25-0 - offset mask */ +#define SCRATCH_PAD0_OFFSET_MASK 0x03FFFFFF +/* if AAP error state */ +#define SCRATCH_PAD0_AAPERR_MASK 0xFFFFFFFF +/* Inbound doorbell bit7 */ +#define SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP 0x80 +/* Inbound doorbell bit7 SPCV */ +#define SPCV_MSGU_CFG_TABLE_TRANSFER_DEBUG_INFO 0x80 +#define MAIN_MERRDCTO_MERRDCES 0xA0/* DWORD 0x28) */ +struct pm8001_dispatch {char *name; int (*chip_init)(struct pm8001_hba_info *pm8001_ha); @@ -346,6 +401,7 @@ union main_cfg_table {u32 phy_attr_table_offset;u32 port_recovery_timer;u32 interrupt_reassertion_delay; +u32 fatal_n_non_fatal_dump;/* 0x28 */ } pm80xx_tbl; };@@ -420,6 +476,13 @@ struct pm8001_hba_info {struct pm8001_hba_memspace io_mem[6 ];struct mpi_mem_req memoryMap;struct encrypt encrypt_info;/* support encryption */ +struct forensic_data forensic_info; +u32 fatal_bar_loc; +u32 forensic_last_offset; +u32 fatal_forensic_shift_offset; +u32 forensic_fatal_step; +u32 evtlog_ib_offset; +u32 evtlog_ob_offset;void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/ void __iomem *main_cfg_tbl_addr;/*Main Config Table Addr*/ void __iomem *general_stat_tbl_addr;/*General Status Table Addr*/ @@ -428,6 +491,7 @@ struct pm8001_hba_info {void __iomem *pspa_q_tbl_addr;/*MPI SAS PHY attributes Queue Config Table Addr*/ void __iomem *ivt_tbl_addr;/*MPI IVT Table Addr */ +void __iomem *fatal_tbl_addr;/*MPI IVT Table Addr */ union main_cfg_table main_cfg_tbl;union general_status_table gs_tbl;struct inbound_queue_table inbnd_q_tbl[PM8001_MAX_SPCV_INB_NUM ];@@ -634,6 +698,10 @@ int pm80xx_set_thermal_config(struct
pm8001_hba_info*pm8001_ha); int pm8001_bar4_shift(structpm8001_hba_info*pm8001_ha, u32 shiftValue); void pm8001_set_phy_profile(structpm8001_hba_info*pm8001_ha,drivers/scsi/pm8001/pm8001_sas.h +4
-0u32 length, u8 *buf); +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 +shiftValue);ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf);ssize_t +pm8001_get_gsm_dump (struct device *cdev,u32 ,char *buf);/* ctl shared API */ extern struct device_attribute *pm8001_host_attrs[];drivers/scsi/pm8001/pm80xx_hwi.c +220
-0@@ -45,6 +45,228 @@#define SMP_DIRECT 1#define SMP_INDIRECT 2 + + +int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 +shift_value) { +u32 reg_val; +unsigned long start; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , shift_value); +/* confirm the setting is written */ + start = jiffies +HZ ;/* 1 sec */ +do { + reg_val =pm8001_cr32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER ); + }while ((reg_val != shift_value) &&time_before (jiffies, start)); +if (reg_val != shift_value) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } +return 0 ; +} + +void pm80xx_pci_mem_copy (struct pm8001_hba_info *pm8001_ha,u32 soffset, +const void *destination, +u32 dw_count,u32 bus_base_number) { +u32 index, value, offset; +u32 *destination1; + destination1 = (u32 *)destination; + +for (index =0 ; index < dw_count; index +=4 , destination1++) { + offset = (soffset + index /4 ); +if (offset < (64 *1024 )) { + value =pm8001_cr32 (pm8001_ha, bus_base_number, offset); + *destination1 =cpu_to_le32 (value); + } + } +return ; +} + +ssize_t pm80xx_get_fatal_dump (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr; +u32 status =1 ; +u32 accum_len , reg_val, index, *temp; +unsigned long start; +u8 *direct_data; +char *fatal_error_data = buf; + + pm8001_ha->forensic_info.data_buf.direct_data = buf; +if (pm8001_ha->chip_id == chip_8001) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"Not supported for SPC controller" ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("forensic_info TYPE_NON_FATAL..............\n" )); + direct_data = (u8 *)fatal_error_data; + pm8001_ha->forensic_info.data_type =TYPE_NON_FATAL ; + pm8001_ha->forensic_info.data_buf.direct_len =SYSFS_OFFSET ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + + pm8001_ha->forensic_info.data_buf.direct_data = direct_data; + } + +if (pm8001_ha->forensic_info.data_buf.direct_offset ==0 ) { +/* start to get data */ +/* Program the MEMBASE II Shifting Register with 0x00.*/ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->forensic_last_offset =0 ; + pm8001_ha->forensic_fatal_step =0 ; + pm8001_ha->fatal_bar_loc =0 ; + } +/* Read until accum_len is retrived */ + accum_len =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_ACCUM_LEN ); +PM8001_IO_DBG (pm8001_ha,pm8001_printk ("accum_len 0x%x\n" , + accum_len)); +if (accum_len ==0xFFFFFFFF ) { +PM8001_IO_DBG (pm8001_ha, +pm8001_printk ("Possible PCI issue 0x%x not expected\n" , + accum_len)); +return status; + } +if (accum_len ==0 || accum_len >=0x100000 ) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,0xFFFFFFFF ); +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } + temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr; +if (pm8001_ha->forensic_fatal_step ==0 ) { +moreData: +if (pm8001_ha->forensic_info.data_buf.direct_data) { +/* Data is in bar, copy to host memory */ +pm80xx_pci_mem_copy (pm8001_ha, pm8001_ha->fatal_bar_loc, + pm8001_ha->memoryMap.region[FORENSIC_MEM ].virt_ptr, + pm8001_ha->forensic_info.data_buf.direct_len , +1 ); + } + pm8001_ha->fatal_bar_loc += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.direct_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_last_offset += + pm8001_ha->forensic_info.data_buf.direct_len; + pm8001_ha->forensic_info.data_buf.read_len = + pm8001_ha->forensic_info.data_buf.direct_len; + +if (pm8001_ha->forensic_last_offset >= accum_len) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,3 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + + pm8001_ha->fatal_bar_loc =0 ; + pm8001_ha->forensic_fatal_step =1 ; + pm8001_ha->fatal_forensic_shift_offset =0 ; + pm8001_ha->forensic_last_offset =0 ; + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->fatal_bar_loc < (64 *1024 )) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index < (SYSFS_OFFSET /4 ); index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + status =0 ; +return (char *)pm8001_ha-> + forensic_info.data_buf.direct_data - + (char *)buf; + } + +/* Increment the MEMBASE II Shifting Register value by 0x100.*/ + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha->forensic_info.data_buf.direct_data, +"%08x " ,2 ); +for (index =0 ; index <256 ; index++) { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " , *(temp + index)); + } + pm8001_ha->fatal_forensic_shift_offset +=0x100 ; +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); + pm8001_ha->fatal_bar_loc =0 ; + status =0 ; +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; + } +if (pm8001_ha->forensic_fatal_step ==1 ) { + pm8001_ha->fatal_forensic_shift_offset =0 ; +/* Read 64K of the debug data. */ +pm8001_cw32 (pm8001_ha,0 ,MEMBASE_II_SHIFT_REGISTER , + pm8001_ha->fatal_forensic_shift_offset); +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE , +MPI_FATAL_EDUMP_HANDSHAKE_RDY ); + +/* Poll FDDHSHK until clear */ + start = jiffies + (2 *HZ );/* 2 sec */ + +do { + reg_val =pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ); + }while ((reg_val) &&time_before (jiffies, start)); + +if (reg_val !=0 ) { +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("TIMEOUT:MEMBASE_II_SHIFT_REGISTER" +" = 0x%x\n" , reg_val)); +return -1 ; + } + +/* Read the next 64K of the debug data. */ + pm8001_ha->forensic_fatal_step =0 ; +if (pm8001_mr32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_STATUS ) != +MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE ) { +pm8001_mw32 (fatal_table_address, +MPI_FATAL_EDUMP_TABLE_HANDSHAKE ,0 ); + goto moreData; + }else { + pm8001_ha->forensic_info.data_buf.direct_data += +sprintf (pm8001_ha-> + forensic_info.data_buf.direct_data, +"%08x " ,4 ); + pm8001_ha->forensic_info.data_buf.read_len =0xFFFFFFFF ; + pm8001_ha->forensic_info.data_buf.direct_len =0 ; + pm8001_ha->forensic_info.data_buf.direct_offset =0 ; + pm8001_ha->forensic_info.data_buf.read_len =0 ; + status =0 ; + } + } + +return (char *)pm8001_ha->forensic_info.data_buf.direct_data - + (char *)buf; +} +/** * read_main_config_table - read the configure table and save it. * @pm8001_ha: our hba card information @@ -583,6 +805,9 @@ static void
init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha)drivers/scsi/pm8001/pm80xx_hwi.c +3
-0pm8001_ha->pspa_q_tbl_addr = base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0x90 ) &0xFFFFFF ); + pm8001_ha->fatal_tbl_addr = + base_addr + (pm8001_cr32 (pm8001_ha, pcibar, offset +0xA0 ) & +0xFFFFFF ); PM8001_INIT_DBG(pm8001_ha, pm8001_printk("GST OFFSET 0x%x\n", diff --git
a/drivers/scsi/pm8001/pm80xx_hwi.hb/drivers/scsi/pm8001/pm80xx_hwi.hindex 872d5cf..c86816b 100644drivers/scsi/pm8001/pm80xx_hwi.h +2
-0@@ -1525,4 +1525,6 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;#define DEVREG_FAILURE_PORT_NOT_VALID_STATE 0x06#define DEVREG_FAILURE_DEVICE_TYPE_NOT_VALID 0x07 + +#define MEMBASE_II_SHIFT_REGISTER 0x1010#endif