pm80xx : Updates for the driver version 0.1.39.
Subsystems (2)
cover pm80xx : Updates for the driver version 0.1.39.
From: Deepak Ukey <[email protected]>
This patch set includes some bug fixes and features for pm80xx driver.
Deepak Ukey (2):
pm80xx : Controller fatal error through sysfs. pm80xx : Modified the logic to collect fatal dump.
John Sperbeck (1):
pm80xx : Initialize variable used as return status.
Vikram Auradkar (3):
pm80xx : Convert 'long' mdelay to msleep. pm80xx : Fix dereferencing dangling pointer. pm80xx : Tie the interrupt name to the module instance.
ianyar (1):
pm80xx : Increase timeout for pm80xx mpi_uninit_check.
peter chang (5):
pm80xx : Fix for SATA device discovery. pm80xx : Squashed logging cleanup changes. pm80xx : Fix command issue sizing. pm80xx : Cleanup command when a reset times out. pm80xx : Do not request 12G sas speeds.
drivers/scsi/pm8001/pm8001_ctl.c | 20 ++ drivers/scsi/pm8001/pm8001_hwi.c | 131 +++++++---- drivers/scsi/pm8001/pm8001_init.c | 34 ++- drivers/scsi/pm8001/pm8001_sas.c | 70 ++++-- drivers/scsi/pm8001/pm8001_sas.h | 24 +- drivers/scsi/pm8001/pm80xx_hwi.c | 447 ++++++++++++++++++++++++++++---------- drivers/scsi/pm8001/pm80xx_hwi.h | 3 + 7 files changed, 546 insertions(+), 183 deletions(-)
Signature · 1 line
2.16.3
PATCH 1/12 pm80xx : Fix for SATA device discovery.
From: peter chang <[email protected]>
Driver was missing complete() call in mpi_sata_completion which result in SATA abort error handling is timing out. That causes the device to be left in the in_recovery state so subsequent commands sent to the device fail and the OS removes access to it.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/scsi/pm8001/pm80xx_hwi.c +5 -1
@@ -2382,6 +2382,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_printk ("task 0x%p done with io_status 0x%x" " resp 0x%x stat 0x%x but aborted by upper layer!\n" , t, status, ts->resp, ts->stat)); +if (t->slow_task) +complete (&t->slow_task->completion);pm8001_ccb_task_free (pm8001_ha, t, ccb, tag); }else {spin_unlock_irqrestore (&t->task_state_lock, flags);
@@ -3130,8 +3132,10 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)if (status ==0 ) { phy->phy_state =PHY_LINK_DOWN ;if (pm8001_ha->flags ==PM8001F_RUN_TIME && - phy->enable_completion !=NULL ) + phy->enable_completion !=NULL ) {complete (phy->enable_completion); + phy->enable_completion =NULL ; + } }return 0 ;
Signature · 1 line
2.16.3
Jinpu Wang
maintainerRe: [PATCH 01/12] pm80xx : Fix for SATA device discovery.
Quoted 11 lines · Deepak Ukey
From: peter chang <[email protected]>
Driver was missing
complete()call inmpi_sata_completionwhich result in SATA abort error handling is timing out. That causes the device to be left in thein_recoverystate so subsequent commands sent to the device fail and the OS removes access to it.Signed-off-by peter chang <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Thanks for the patch, it looks good.
But the commit message doesn't explain the second part of the change, I suggest to split it to 2 patches.
Thanks
Quoted 32 lines
--- drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)drivers/scsi/pm8001/pm80xx_hwi.c +5
-2@@ -2382,6 +2382,8 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_printk ("task 0x%p done with io_status 0x%x" " resp 0x%x stat 0x%x but aborted by upper layer!\n" , t, status, ts->resp, ts->stat)); +if (t->slow_task) +complete (&t->slow_task->completion);pm8001_ccb_task_free (pm8001_ha, t, ccb, tag); }else {spin_unlock_irqrestore (&t->task_state_lock, flags);@@ -3130,8 +3132,10 @@ static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)if (status ==0 ) { phy->phy_state =PHY_LINK_DOWN ;if (pm8001_ha->flags ==PM8001F_RUN_TIME && - phy->enable_completion !=NULL ) + phy->enable_completion !=NULL ) {complete (phy->enable_completion); + phy->enable_completion =NULL ; + } }return 0 ; --2.16.3
PATCH 2/12 pm80xx : Initialize variable used as return status.
In reply to Deepak UkeyFrom: John Sperbeck <[email protected]>
In pm8001_task_exec(), if the PHY is down, then we return the current value of 'rc'. We need to make sure it's initialized.
--- drivers/scsi/pm8001/pm8001_sas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/pm8001/pm8001_sas.c +1 -1
@@ -384,7 +384,7 @@ static int pm8001_task_exec(struct sas_task *task,struct pm8001_port *port =NULL ;struct sas_task *t = task;struct pm8001_ccb_info *ccb; -u32 tag =0xdeadbeef , rc, n_elem =0 ; +u32 tag =0xdeadbeef , rc =0 , n_elem =0 ;unsigned long flags =0 ;if (!dev->port) {
Signature · 1 line
2.16.3
Re: [PATCH 02/12] pm80xx : Initialize variable used as return status.
Quoted 9 lines · Deepak Ukey
From: John Sperbeck <[email protected]>
In
pm8001_task_exec(), if the PHY is down, then we return the current value of 'rc'. We need to make sure it's initialized.Signed-off-by John Sperbeck <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks good, thanks.
Quoted 20 lines
--- drivers/scsi/pm8001/pm8001_sas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/scsi/pm8001/pm8001_sas.c +1
-2@@ -384,7 +384,7 @@ static int pm8001_task_exec(struct sas_task *task,struct pm8001_port *port =NULL ;struct sas_task *t = task;struct pm8001_ccb_info *ccb; -u32 tag =0xdeadbeef , rc, n_elem =0 ; +u32 tag =0xdeadbeef , rc =0 , n_elem =0 ;unsigned long flags =0 ;if (!dev->port) { --2.16.3
PATCH 3/12 pm80xx : Convert 'long' mdelay to msleep.
In reply to Deepak UkeyFrom: Vikram Auradkar <[email protected]>
For delays longer than 20ms [um]delay isn't recommended. pm80xx_chip_soft_rst starts off with a 500ms delay before it even gets around to checking for the results of the reset. As long as it's at least 500ms it doesn't matter what the scheduler is doing. The delay in the pm8001_exec_internal_task_abort does nothing, and theory is this is a delay to avoid a double-free.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm80xx_hwi.c +2 -2
@@ -1241,7 +1241,7 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) pm8001_printk("reset register before write : 0x%x\n", regval));pm8001_cw32 (pm8001_ha,0 ,SPC_REG_SOFT_RESET , SPCv_NORMAL_RESET_VALUE); -mdelay (500 ); +msleep (500 ); regval =pm8001_cr32 (pm8001_ha,0 ,SPC_REG_SOFT_RESET ); PM8001_INIT_DBG(pm8001_ha,
@@ -2986,7 +2986,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_get_attached_sas_addr (phy, phy->sas_phy.attached_sas_addr);spin_unlock_irqrestore (&phy->sas_phy.frame_rcvd_lock, flags);if (pm8001_ha->flags ==PM8001F_RUN_TIME ) -mdelay (200 );/*delay a moment to wait disk to spinup*/ +msleep (200 );/*delay a moment to wait disk to spinup*/ pm8001_bytes_dmaed (pm8001_ha, phy_id); }
Signature · 1 line
2.16.3
Re: [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep.
Quoted 10 lines · Deepak Ukey
From: Vikram Auradkar <[email protected]>
For delays longer than 20ms [um]delay isn't recommended.
pm80xx_chip_soft_rststarts off with a 500ms delay before it even gets around to checking for the results of the reset. As long as it's at least 500ms it doesn't matter what the scheduler is doing. The delay in thepm8001_exec_internal_task_abortdoes nothing, and theory is this is a delay to avoid a double-free.
Quoted 3 lines
Signed-off-by Vikram Auradkar <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
looks good, thanks
Quoted 29 lines
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/scsi/pm8001/pm80xx_hwi.c +2
-3@@ -1241,7 +1241,7 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha) pm8001_printk("reset register before write : 0x%x\n", regval));pm8001_cw32 (pm8001_ha,0 ,SPC_REG_SOFT_RESET , SPCv_NORMAL_RESET_VALUE); -mdelay (500 ); +msleep (500 ); regval =pm8001_cr32 (pm8001_ha,0 ,SPC_REG_SOFT_RESET ); PM8001_INIT_DBG(pm8001_ha,@@ -2986,7 +2986,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_get_attached_sas_addr (phy, phy->sas_phy.attached_sas_addr);spin_unlock_irqrestore (&phy->sas_phy.frame_rcvd_lock, flags);if (pm8001_ha->flags ==PM8001F_RUN_TIME ) -mdelay (200 );/*delay a moment to wait disk to spinup*/ +msleep (200 );/*delay a moment to wait disk to spinup*/ pm8001_bytes_dmaed (pm8001_ha, phy_id); } --2.16.3
PATCH 4/12 pm80xx : Squashed logging cleanup changes.
In reply to Deepak UkeyFrom: peter chang <[email protected]>
The default logging doesn't include the device name, so it's difficult to determine which controller is being logged about in error scenarios. The logging level was only settable via sysfs, which made it inconvenient for actual debugging. This changes the default to only cover error handling.
--- drivers/scsi/pm8001/pm8001_hwi.c | 62 ++++++++++++++------ drivers/scsi/pm8001/pm8001_init.c | 6 +- drivers/scsi/pm8001/pm8001_sas.c | 6 +- drivers/scsi/pm8001/pm8001_sas.h | 15 ++++- drivers/scsi/pm8001/pm80xx_hwi.c | 118 +++++++++++++++++++++++++++++++++----- 5 files changed, 170 insertions(+), 37 deletions(-)
drivers/scsi/pm8001/pm8001_hwi.c +44 -18
@@ -1364,7 +1364,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,/*Update the PI to the firmware*/ pm8001_cw32 (pm8001_ha, circularQ->pi_pci_bar, circularQ->pi_offset, circularQ->producer_idx); -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n" , responseQueue, opCode, circularQ->producer_idx, circularQ->consumer_index));
@@ -1436,6 +1436,10 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,/* read header */ header_tmp =pm8001_read_32 (msgHeader); msgHeader_tmp =cpu_to_le32 (header_tmp); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"outbound opcode msgheader:%x ci=%d pi=%d\n" , + msgHeader_tmp, circularQ->consumer_idx, + circularQ->producer_index));if (0 != (le32_to_cpu (msgHeader_tmp) &0x80000000 )) {if (OPC_OUB_SKIP_ENTRY != (le32_to_cpu (msgHeader_tmp) &0xfff )) {
@@ -1604,7 +1608,8 @@ void pm8001_work_fn(struct work_struct *work)break ;default : -pm8001_printk ("...query task failed!!!\n" ); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"...query task failed!!!\n" ));break ; });
@@ -1890,6 +1895,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)pm8001_printk ("SAS Address of IO Failure Drive:" "%016llx", SAS_ADDR(t->dev->sas_addr))); +if (status) +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ( +"status:0x%x, tag:0x%x, task:0x%p\n" , + status, tag, t)); +switch (status) {case IO_SUCCESS : PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS"
@@ -2072,7 +2082,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;
@@ -2125,7 +2135,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("port_id = %x,device_id = %x\n" , port_id, dev_id));switch (event) {
@@ -2263,7 +2273,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk(" IO_XFER_CMD_FRAME_ISSUED\n"));return ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , event));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;
@@ -2352,6 +2362,12 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("ts null\n"));return ; } + +if (status) +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ( +"status:0x%x, tag:0x%x, task::0x%p\n" , + status, tag, t)); +/* Print sas address of IO failed device */ if ((status !=IO_SUCCESS ) && (status !=IO_OVERFLOW ) && (status !=IO_UNDERFLOW )) {
@@ -2652,7 +2668,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;
@@ -2723,7 +2739,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha,pm8001_printk ( +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n" , port_id, dev_id, tag, event));switch (event) {
@@ -2872,7 +2888,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat =SAS_OPEN_TO ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , event));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;
@@ -2917,9 +2933,13 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) t = ccb->task; ts = &t->task_status; pm8001_dev = ccb->device; -if (status) +if (status) {PM8001_FAIL_DBG (pm8001_ha,pm8001_printk ("smp IO status 0x%x\n" , status)); +PM8001_IOERR_DBG (pm8001_ha, +pm8001_printk ("status:0x%x, tag:0x%x, task:0x%p\n" , + status, tag, t)); + }if (unlikely (!t || !t->lldd_task || !t->dev))return ;
@@ -3070,7 +3090,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status)); ts->resp =SAS_TASK_COMPLETE ; ts->stat =SAS_DEV_NO_RESPONSE ;
@@ -3416,7 +3436,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_get_lrate_mode (phy, link_rate);break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("unknown device type(%x)\n" , deviceType));break ; }
@@ -3463,7 +3483,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)struct sas_ha_struct *sas_ha = pm8001_ha->sas;struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];unsigned long flags; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("HW_EVENT_SATA_PHY_UP port id = %d," " phy id = %d\n" , port_id, phy_id)); port->port_state = portstate;
@@ -3541,7 +3561,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)break ;default : port->port_attached =0 ; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk (" phy Down and(default) = %x\n" , portstate));break ;
@@ -3689,7 +3709,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, pm8001_printk(": FLASH_UPDATE_DISABLED\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("No matched status = %d\n" , status));break ; }
@@ -3805,8 +3825,9 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)struct sas_ha_struct *sas_ha = pm8001_ha->sas;struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; -PM8001_MSG_DBG (pm8001_ha, -pm8001_printk ("outbound queue HW event & event type : " )); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n" , + port_id, phy_id, eventType, status));switch (eventType) {case HW_EVENT_PHY_START_STATUS : PM8001_MSG_DBG(pm8001_ha,
@@ -3990,7 +4011,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown event type = %x\n" , eventType));break ; }
@@ -4161,7 +4182,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown outbound Queue IOMB OPC = %x\n" , opc));break ;
@@ -4649,6 +4670,9 @@ static irqreturn_t pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) {pm8001_chip_interrupt_disable (pm8001_ha, vec); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"irq vec %d, ODMR:0x%x\n" , + vec,pm8001_cr32 (pm8001_ha,0 ,0x30 )));process_oq (pm8001_ha, vec);pm8001_chip_interrupt_enable (pm8001_ha, vec);return IRQ_HANDLED ;
@@ -4960,6 +4984,8 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,if (!fw_control_context)return -ENOMEM ; fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"dma fw_control context input length :%x\n" , fw_control->len));memcpy (buffer, fw_control->buffer, fw_control->len); flash_update_info.sgl.addr =cpu_to_le64 (phys_addr); flash_update_info.sgl.im_len.len =cpu_to_le32 (fw_control->len);
drivers/scsi/pm8001/pm8001_init.c +5 -1
@@ -42,6 +42,10 @@#include "pm8001_sas.h" #include "pm8001_chips.h" +static ulong logging_level =PM8001_FAIL_LOGGING |PM8001_IOERR_LOGGING ; +module_param (logging_level, ulong,0644 ); +MODULE_PARM_DESC (logging_level," bits for enabling logging info." ); +static struct scsi_transport_template *pm8001_stt;/**
@@ -466,7 +470,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->sas = sha; pm8001_ha->shost = shost; pm8001_ha->id = pm8001_id++; - pm8001_ha->logging_level =0x01 ; + pm8001_ha->logging_level = logging_level;sprintf (pm8001_ha->name,"%s%d" ,DRV_NAME , pm8001_ha->id);/* IOMB size is 128 for 8088/89 controllers */ if (pm8001_ha->chip_id != chip_8001)
drivers/scsi/pm8001/pm8001_sas.c +4 -2
@@ -119,7 +119,7 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr, mem_virt_alloc =dma_alloc_coherent (&pdev->dev, mem_size + align, &mem_dma_handle,GFP_KERNEL );if (!mem_virt_alloc) { -pm8001_printk ("memory allocation error\n" ); +pr_err ("pm80xx: memory allocation error\n" );return -1 ; } *pphys_addr = mem_dma_handle;
@@ -249,6 +249,8 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,spin_unlock_irqrestore (&pm8001_ha->lock, flags);return 0 ;default : +PM8001_DEVIO_DBG (pm8001_ha, +pm8001_printk ("func 0x%x\n" , func)); rc = -EOPNOTSUPP ; }msleep (300 );
@@ -1179,7 +1181,7 @@ int pm8001_query_task(struct sas_task *task)break ; } } -pm8001_printk (":rc= %d\n" , rc); +pr_err ("pm80xx: rc= %d\n" , rc);return rc; }
drivers/scsi/pm8001/pm8001_sas.h +13 -2
@@ -66,8 +66,11 @@#define PM8001_EH_LOGGING 0x10/* libsas EH function logging*/ #define PM8001_IOCTL_LOGGING 0x20/* IOCTL message logging */ #define PM8001_MSG_LOGGING 0x40/* misc message logging */ -#define pm8001_printk(format, arg...) printk(KERN_INFO "pm80xx %s %d:" \ - format, __func__, __LINE__, ## arg) +#define PM8001_DEV_LOGGING 0x80/* development message logging */ +#define PM8001_DEVIO_LOGGING 0x100/* development io message logging */ +#define PM8001_IOERR_LOGGING 0x200/* development io err message logging */ +#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \ + format, pm8001_ha->name, __func__, __LINE__, ## arg)#define PM8001_CHECK_LOGGING (HBA ,LEVEL ,CMD ) \ do { \ if (unlikely(HBA->logging_level & LEVEL)) \
@@ -97,6 +100,14 @@ do { \#define PM8001_MSG_DBG (HBA ,CMD ) \ PM8001_CHECK_LOGGING(HBA, PM8001_MSG_LOGGING, CMD) +#define PM8001_DEV_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_DEV_LOGGING, CMD) + +#define PM8001_DEVIO_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_DEVIO_LOGGING, CMD) + +#define PM8001_IOERR_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_IOERR_LOGGING, CMD)#define PM8001_USE_TASKLET #define PM8001_USE_MSIX
drivers/scsi/pm8001/pm80xx_hwi.c +104 -14
280 lines not on this page · raw message
Signature · 1 line
2.16.3
Re: [PATCH 04/12] pm80xx : Squashed logging cleanup changes.
Quoted 9 lines · Deepak Ukey
From: peter chang <[email protected]>
The default logging doesn't include the device name, so it's difficult to determine which controller is being logged about in error scenarios. The logging level was only settable via sysfs, which made it inconvenient for actual debugging. This changes the default to only cover error handling.
Quoted 3 lines
Signed-off-by peter chang <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Thanks,
Quoted 633 lines
--- drivers/scsi/pm8001/pm8001_hwi.c | 62 ++++++++++++++------ drivers/scsi/pm8001/pm8001_init.c | 6 +- drivers/scsi/pm8001/pm8001_sas.c | 6 +- drivers/scsi/pm8001/pm8001_sas.h | 15 ++++- drivers/scsi/pm8001/pm80xx_hwi.c | 118 +++++++++++++++++++++++++++++++++----- 5 files changed, 170 insertions(+), 37 deletions(-)drivers/scsi/pm8001/pm8001_hwi.c +44
-18@@ -1364,7 +1364,7 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,/*Update the PI to the firmware*/ pm8001_cw32 (pm8001_ha, circularQ->pi_pci_bar, circularQ->pi_offset, circularQ->producer_idx); -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("INB Q %x OPCODE:%x , UPDATED PI=%d CI=%d\n" , responseQueue, opCode, circularQ->producer_idx, circularQ->consumer_index));@@ -1436,6 +1436,10 @@ u32 pm8001_mpi_msg_consume(struct pm8001_hba_info *pm8001_ha,/* read header */ header_tmp =pm8001_read_32 (msgHeader); msgHeader_tmp =cpu_to_le32 (header_tmp); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"outbound opcode msgheader:%x ci=%d pi=%d\n" , + msgHeader_tmp, circularQ->consumer_idx, + circularQ->producer_index));if (0 != (le32_to_cpu (msgHeader_tmp) &0x80000000 )) {if (OPC_OUB_SKIP_ENTRY != (le32_to_cpu (msgHeader_tmp) &0xfff )) {@@ -1604,7 +1608,8 @@ void pm8001_work_fn(struct work_struct *work)break ;default : -pm8001_printk ("...query task failed!!!\n" ); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"...query task failed!!!\n" ));break ; });@@ -1890,6 +1895,11 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)pm8001_printk ("SAS Address of IO Failure Drive:" "%016llx", SAS_ADDR(t->dev->sas_addr))); +if (status) +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ( +"status:0x%x, tag:0x%x, task:0x%p\n" , + status, tag, t)); +switch (status) {case IO_SUCCESS : PM8001_IO_DBG(pm8001_ha, pm8001_printk("IO_SUCCESS"@@ -2072,7 +2082,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2125,7 +2135,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("port_id = %x,device_id = %x\n" , port_id, dev_id));switch (event) {@@ -2263,7 +2273,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk(" IO_XFER_CMD_FRAME_ISSUED\n"));return ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , event));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2352,6 +2362,12 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("ts null\n"));return ; } + +if (status) +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ( +"status:0x%x, tag:0x%x, task::0x%p\n" , + status, tag, t)); +/* Print sas address of IO failed device */ if ((status !=IO_SUCCESS ) && (status !=IO_OVERFLOW ) && (status !=IO_UNDERFLOW )) {@@ -2652,7 +2668,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2723,7 +2739,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha,pm8001_printk ( +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("port_id:0x%x, device_id:0x%x, tag:0x%x, event:0x%x\n" , port_id, dev_id, tag, event));switch (event) {@@ -2872,7 +2888,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat =SAS_OPEN_TO ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , event));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2917,9 +2933,13 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) t = ccb->task; ts = &t->task_status; pm8001_dev = ccb->device; -if (status) +if (status) {PM8001_FAIL_DBG (pm8001_ha,pm8001_printk ("smp IO status 0x%x\n" , status)); +PM8001_IOERR_DBG (pm8001_ha, +pm8001_printk ("status:0x%x, tag:0x%x, task:0x%p\n" , + status, tag, t)); + }if (unlikely (!t || !t->lldd_task || !t->dev))return ;@@ -3070,7 +3090,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status)); ts->resp =SAS_TASK_COMPLETE ; ts->stat =SAS_DEV_NO_RESPONSE ;@@ -3416,7 +3436,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_get_lrate_mode (phy, link_rate);break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("unknown device type(%x)\n" , deviceType));break ; }@@ -3463,7 +3483,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)struct sas_ha_struct *sas_ha = pm8001_ha->sas;struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];unsigned long flags; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("HW_EVENT_SATA_PHY_UP port id = %d," " phy id = %d\n" , port_id, phy_id)); port->port_state = portstate;@@ -3541,7 +3561,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)break ;default : port->port_attached =0 ; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk (" phy Down and(default) = %x\n" , portstate));break ;@@ -3689,7 +3709,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha, pm8001_printk(": FLASH_UPDATE_DISABLED\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("No matched status = %d\n" , status));break ; }@@ -3805,8 +3825,9 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)struct sas_ha_struct *sas_ha = pm8001_ha->sas;struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; -PM8001_MSG_DBG (pm8001_ha, -pm8001_printk ("outbound queue HW event & event type : " )); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"SPC HW event for portid:%d, phyid:%d, event:%x, status:%x\n" , + port_id, phy_id, eventType, status));switch (eventType) {case HW_EVENT_PHY_START_STATUS : PM8001_MSG_DBG(pm8001_ha,@@ -3990,7 +4011,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb) pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown event type = %x\n" , eventType));break ; }@@ -4161,7 +4182,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown outbound Queue IOMB OPC = %x\n" , opc));break ;@@ -4649,6 +4670,9 @@ static irqreturn_t pm8001_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) {pm8001_chip_interrupt_disable (pm8001_ha, vec); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"irq vec %d, ODMR:0x%x\n" , + vec,pm8001_cr32 (pm8001_ha,0 ,0x30 )));process_oq (pm8001_ha, vec);pm8001_chip_interrupt_enable (pm8001_ha, vec);return IRQ_HANDLED ;@@ -4960,6 +4984,8 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha,if (!fw_control_context)return -ENOMEM ; fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"dma fw_control context input length :%x\n" , fw_control->len));memcpy (buffer, fw_control->buffer, fw_control->len); flash_update_info.sgl.addr =cpu_to_le64 (phys_addr); flash_update_info.sgl.im_len.len =cpu_to_le32 (fw_control->len);drivers/scsi/pm8001/pm8001_init.c +5
-1@@ -42,6 +42,10 @@#include "pm8001_sas.h" #include "pm8001_chips.h" +static ulong logging_level =PM8001_FAIL_LOGGING |PM8001_IOERR_LOGGING ; +module_param (logging_level, ulong,0644 ); +MODULE_PARM_DESC (logging_level," bits for enabling logging info." ); +static struct scsi_transport_template *pm8001_stt;/** @@ -466,7 +470,7 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->sas = sha; pm8001_ha->shost = shost; pm8001_ha->id = pm8001_id++; - pm8001_ha->logging_level =0x01 ; + pm8001_ha->logging_level = logging_level;sprintf (pm8001_ha->name,"%s%d" ,DRV_NAME , pm8001_ha->id);/* IOMB size is 128 for 8088/89 controllers */ if (pm8001_ha->chip_id != chip_8001)drivers/scsi/pm8001/pm8001_sas.c +4
-2@@ -119,7 +119,7 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr, mem_virt_alloc =dma_alloc_coherent (&pdev->dev, mem_size + align, &mem_dma_handle,GFP_KERNEL );if (!mem_virt_alloc) { -pm8001_printk ("memory allocation error\n" ); +pr_err ("pm80xx: memory allocation error\n" );return -1 ; } *pphys_addr = mem_dma_handle;@@ -249,6 +249,8 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,spin_unlock_irqrestore (&pm8001_ha->lock, flags);return 0 ;default : +PM8001_DEVIO_DBG (pm8001_ha, +pm8001_printk ("func 0x%x\n" , func)); rc = -EOPNOTSUPP ; }msleep (300 );@@ -1179,7 +1181,7 @@ int pm8001_query_task(struct sas_task *task)break ; } } -pm8001_printk (":rc= %d\n" , rc); +pr_err ("pm80xx: rc= %d\n" , rc);return rc; }drivers/scsi/pm8001/pm8001_sas.h +13
-2@@ -66,8 +66,11 @@#define PM8001_EH_LOGGING 0x10/* libsas EH function logging*/ #define PM8001_IOCTL_LOGGING 0x20/* IOCTL message logging */ #define PM8001_MSG_LOGGING 0x40/* misc message logging */ -#define pm8001_printk(format, arg...) printk(KERN_INFO "pm80xx %s %d:" \ - format, __func__, __LINE__, ## arg) +#define PM8001_DEV_LOGGING 0x80/* development message logging */ +#define PM8001_DEVIO_LOGGING 0x100/* development io message logging */ +#define PM8001_IOERR_LOGGING 0x200/* development io err message logging */ +#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \ + format, pm8001_ha->name, __func__, __LINE__, ## arg)#define PM8001_CHECK_LOGGING (HBA ,LEVEL ,CMD ) \ do { \ if (unlikely(HBA->logging_level & LEVEL)) \@@ -97,6 +100,14 @@ do { \#define PM8001_MSG_DBG (HBA ,CMD ) \ PM8001_CHECK_LOGGING(HBA, PM8001_MSG_LOGGING, CMD) +#define PM8001_DEV_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_DEV_LOGGING, CMD) + +#define PM8001_DEVIO_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_DEVIO_LOGGING, CMD) + +#define PM8001_IOERR_DBG (HBA ,CMD ) \ + PM8001_CHECK_LOGGING(HBA, PM8001_IOERR_LOGGING, CMD)#define PM8001_USE_TASKLET #define PM8001_USE_MSIX drivers/scsi/pm8001/pm80xx_hwi.c +104
-15@@ -317,6 +317,25 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)pm8001_mr32 (address,MAIN_MPI_ILA_RELEASE_TYPE ); pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version =pm8001_mr32 (address,MAIN_MPI_INACTIVE_FW_VERSION ); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Main cfg table: sign:%x interface rev:%x fw_rev:%x\n" , + pm8001_ha->main_cfg_tbl.pm80xx_tbl.signature, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.interface_rev, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.firmware_rev)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"table offset: gst:%x iq:%x oq:%x int vec:%x phy attr:%x\n" , + pm8001_ha->main_cfg_tbl.pm80xx_tbl.gst_offset, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.inbound_queue_offset, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.outbound_queue_offset, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.int_vec_table_offset, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.phy_attr_table_offset)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Main cfg table; ila rev:%x Inactive fw rev:%x\n" , + pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version, + pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version)); }/** @@ -521,6 +540,11 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)pm8001_mr32 (addressib, (offsetib +0x18 )); pm8001_ha->inbnd_q_tbl[i].producer_idx =0 ; pm8001_ha->inbnd_q_tbl[i].consumer_index =0 ; + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"IQ %d pi_bar 0x%x pi_offset 0x%x\n" , i, + pm8001_ha->inbnd_q_tbl[i].pi_pci_bar, + pm8001_ha->inbnd_q_tbl[i].pi_offset)); }for (i =0 ; i <PM8001_MAX_SPCV_OUTB_NUM ; i++) { pm8001_ha->outbnd_q_tbl[i].element_size_cnt =@@ -549,6 +573,11 @@ static void init_default_table_values(struct pm8001_hba_info *pm8001_ha)pm8001_mr32 (addressob, (offsetob +0x18 )); pm8001_ha->outbnd_q_tbl[i].consumer_idx =0 ; pm8001_ha->outbnd_q_tbl[i].producer_index =0 ; + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"OQ %d ci_bar 0x%x ci_offset 0x%x\n" , i, + pm8001_ha->outbnd_q_tbl[i].ci_pci_bar, + pm8001_ha->outbnd_q_tbl[i].ci_offset)); } }@@ -582,6 +611,10 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) ((pm8001_ha->number_of_intr -1 ) <<8 );pm8001_mw32 (address,MAIN_FATAL_ERROR_INTERRUPT , pm8001_ha->main_cfg_tbl.pm80xx_tbl.fatal_err_interrupt); +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Updated Fatal error interrupt vector 0x%x\n" , +pm8001_mr32 (address,MAIN_FATAL_ERROR_INTERRUPT ))); +pm8001_mw32 (address,MAIN_EVENT_CRC_CHECK , pm8001_ha->main_cfg_tbl.pm80xx_tbl.crc_core_dump);@@ -591,6 +624,9 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha) pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping |=0x20000000 ;pm8001_mw32 (address,MAIN_GPIO_LED_FLAGS_OFFSET , pm8001_ha->main_cfg_tbl.pm80xx_tbl.gpio_led_mapping); +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Programming DW 0x21 in main cfg table with 0x%x\n" , +pm8001_mr32 (address,MAIN_GPIO_LED_FLAGS_OFFSET )));pm8001_mw32 (address,MAIN_PORT_RECOVERY_TIMER , pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);@@ -629,6 +665,21 @@ static void update_inbnd_queue_table(struct pm8001_hba_info *pm8001_ha, pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr);pm8001_mw32 (address, offset +IB_CI_BASE_ADDR_LO_OFFSET , pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"IQ %d: Element pri size 0x%x\n" , + number, + pm8001_ha->inbnd_q_tbl[number].element_pri_size_cnt)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"IQ upr base addr 0x%x IQ lwr base addr 0x%x\n" , + pm8001_ha->inbnd_q_tbl[number].upper_base_addr, + pm8001_ha->inbnd_q_tbl[number].lower_base_addr)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"CI upper base addr 0x%x CI lower base addr 0x%x\n" , + pm8001_ha->inbnd_q_tbl[number].ci_upper_base_addr, + pm8001_ha->inbnd_q_tbl[number].ci_lower_base_addr)); }/** @@ -652,6 +703,21 @@ static void update_outbnd_queue_table(struct pm8001_hba_info *pm8001_ha, pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr);pm8001_mw32 (address, offset +OB_INTERRUPT_COALES_OFFSET , pm8001_ha->outbnd_q_tbl[number].interrup_vec_cnt_delay); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"OQ %d: Element pri size 0x%x\n" , + number, + pm8001_ha->outbnd_q_tbl[number].element_size_cnt)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"OQ upr base addr 0x%x OQ lwr base addr 0x%x\n" , + pm8001_ha->outbnd_q_tbl[number].upper_base_addr, + pm8001_ha->outbnd_q_tbl[number].lower_base_addr)); + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"PI upper base addr 0x%x PI lower base addr 0x%x\n" , + pm8001_ha->outbnd_q_tbl[number].pi_upper_base_addr, + pm8001_ha->outbnd_q_tbl[number].pi_lower_base_addr)); }/** @@ -797,7 +863,7 @@ static void init_pci_device_addresses(struct pm8001_hba_info *pm8001_ha) value =pm8001_cr32 (pm8001_ha,0 ,MSGU_SCRATCH_PAD_0 ); offset = value &0x03FFFFFF ;/* scratch pad 0 TBL address */ -PM8001_INIT_DBG (pm8001_ha, +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ("Scratchpad 0 Offset: 0x%x value 0x%x\n" , offset, value)); pcilogic = (value &0xFC000000 ) >>26 ;@@ -885,6 +951,10 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha) (THERMAL_ENABLE <<8 ) | page_code; payload.cfg_pg[1 ] = (LTEMPHIL <<24 ) | (RTEMPHIL <<8 ); +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n" , + payload.cfg_pg[0 ], payload.cfg_pg[1 ])); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 );if (rc)pm8001_tag_free (pm8001_ha, tag);@@ -1090,6 +1160,10 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha) payload.new_curidx_ksop = ((1 <<24 ) | (1 <<16 ) | (1 <<8 ) |KEK_MGMT_SUBOP_KEYCARDUPDATE ); +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"Saving Encryption info to flash. payload 0x%x\n" , + payload.new_curidx_ksop)); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 );if (rc)pm8001_tag_free (pm8001_ha, tag);@@ -1570,6 +1644,10 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; + +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ( +"tag::0x%x, status::0x%x task::0x%p\n" , tag, status, t)); +/* Print sas address of IO failed device */ if ((status !=IO_SUCCESS ) && (status !=IO_OVERFLOW ) && (status !=IO_UNDERFLOW ))@@ -1772,7 +1850,7 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -1826,7 +1904,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha, +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ("port_id:0x%x, tag:0x%x, event:0x%x\n" , port_id, tag, event));switch (event) {@@ -1963,7 +2041,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) ts->stat =SAS_DATA_OVERRUN ;break ;case IO_XFER_ERROR_INTERNAL_CRC_ERROR : -PM8001_IO_DBG (pm8001_ha, +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ("IO_XFR_ERROR_INTERNAL_CRC_ERROR\n" ));/* TBC: used default set values */ ts->resp =SAS_TASK_COMPLETE ;@@ -1974,7 +2052,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha , void *piomb) pm8001_printk("IO_XFER_CMD_FRAME_ISSUED\n"));return ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , event));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2062,6 +2140,12 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("ts null\n"));return ; } + +if (unlikely (status)) +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ( +"status:0x%x, tag:0x%x, task::0x%p\n" , + status, tag, t)); +/* Print sas address of IO failed device */ if ((status !=IO_SUCCESS ) && (status !=IO_OVERFLOW ) && (status !=IO_UNDERFLOW )) {@@ -2365,7 +2449,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status));/* not allowed case. Therefore, return failed status */ ts->resp =SAS_TASK_COMPLETE ;@@ -2437,7 +2521,7 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha , void *piomb) } ts = &t->task_status; -PM8001_IO_DBG (pm8001_ha, +PM8001_IOERR_DBG (pm8001_ha,pm8001_printk ("port_id:0x%x, tag:0x%x, event:0x%x\n" , port_id, tag, event));switch (event) {@@ -2657,6 +2741,9 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)if (unlikely (!t || !t->lldd_task || !t->dev))return ; +PM8001_DEV_DBG (pm8001_ha, +pm8001_printk ("tag::0x%x status::0x%x\n" , tag, status)); +switch (status) {case IO_SUCCESS :@@ -2824,7 +2911,7 @@ mpi_smp_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) ts->open_rej_reason =SAS_OREJ_RSVD_RETRY ;break ;default : -PM8001_IO_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown status 0x%x\n" , status)); ts->resp =SAS_TASK_COMPLETE ; ts->stat =SAS_DEV_NO_RESPONSE ;@@ -2966,7 +3053,7 @@ hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_get_lrate_mode (phy, link_rate);break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("unknown device type(%x)\n" , deviceType));break ; }@@ -3015,7 +3102,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)struct sas_ha_struct *sas_ha = pm8001_ha->sas;struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];unsigned long flags; -PM8001_MSG_DBG (pm8001_ha,pm8001_printk ( +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("port id %d, phy id %d link_rate %d portstate 0x%x\n" , port_id, phy_id, link_rate, portstate));@@ -3103,7 +3190,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)break ;default : port->port_attached =0 ; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk (" Phy Down and(default) = 0x%x\n" , portstate));break ;@@ -3195,7 +3282,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];struct pm8001_port *port = &pm8001_ha->port[port_id];struct asd_sas_phy *sas_phy = sas_ha->sas_phy[phy_id]; -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEV_DBG (pm8001_ha,pm8001_printk ("portid:%d phyid:%d event:0x%x status:0x%x\n" , port_id, phy_id, eventType, status));@@ -3380,7 +3467,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("EVENT_BROADCAST_ASYNCH_EVENT\n"));break ;default : -PM8001_MSG_DBG (pm8001_ha, +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown event type 0x%x\n" , eventType));break ; }@@ -3762,7 +3849,7 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)ssp_coalesced_comp_resp (pm8001_ha, piomb);break ;default : -PM8001_MSG_DBG (pm8001_ha,pm8001_printk ( +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ("Unknown outbound Queue IOMB OPC = 0x%x\n" , opc));break ; }@@ -4645,6 +4732,9 @@ static irqreturn_t pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec) {pm80xx_chip_interrupt_disable (pm8001_ha, vec); +PM8001_DEVIO_DBG (pm8001_ha,pm8001_printk ( +"irq vec %d, ODMR:0x%x\n" , + vec,pm8001_cr32 (pm8001_ha,0 ,0x30 )));process_oq (pm8001_ha, vec);pm80xx_chip_interrupt_enable (pm8001_ha, vec);return IRQ_HANDLED ; --2.16.3
PATCH 5/12 pm80xx : Increase timeout for pm80xx mpi_uninit_check.
In reply to Deepak UkeyFrom: ianyar <[email protected]>
The function mpi_uninit_check takes longer for inbound doorbell register to be cleared. Increased the timeout substantially so that the driver does not fail to load.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- drivers/scsi/pm8001/pm80xx_hwi.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm80xx_hwi.c +2 -2
@@ -735,9 +735,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)pm8001_cw32 (pm8001_ha,0 ,MSGU_IBDB_SET , SPCv_MSGU_CFG_TABLE_UPDATE);/* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G (pm8001_ha->pdev)) { - max_wait_count =4 *1000 *1000 ;/* 4 sec */ + max_wait_count =SPCV_DOORBELL_CLEAR_TIMEOUT ; }else { - max_wait_count =2 *1000 *1000 ;/* 2 sec */ + max_wait_count =SPC_DOORBELL_CLEAR_TIMEOUT ; } do { udelay(1);
drivers/scsi/pm8001/pm80xx_hwi.h +3 -0
@@ -220,6 +220,9 @@#define SAS_DOPNRJT_RTRY_TMO 128#define SAS_COPNRJT_RTRY_TMO 128 +#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 1000 * 1000)/* 30 sec */ +#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 1000 * 1000)/* 15 sec */ +/* Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128
Signature · 1 line
2.16.3
Re: [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check.
Quoted 10 lines · Deepak Ukey
From: ianyar <[email protected]>
The function
mpi_uninit_checktakes longer for inbound doorbell register to be cleared. Increased the timeout substantially so that the driver does not fail to load.Signed-off-by ianyar <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Quoted 38 lines
--- drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++-- drivers/scsi/pm8001/pm80xx_hwi.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-)drivers/scsi/pm8001/pm80xx_hwi.c +2
-2@@ -735,9 +735,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)pm8001_cw32 (pm8001_ha,0 ,MSGU_IBDB_SET , SPCv_MSGU_CFG_TABLE_UPDATE);/* wait until Inbound DoorBell Clear Register toggled */ if (IS_SPCV_12G (pm8001_ha->pdev)) { - max_wait_count =4 *1000 *1000 ;/* 4 sec */ + max_wait_count =SPCV_DOORBELL_CLEAR_TIMEOUT ; }else { - max_wait_count =2 *1000 *1000 ;/* 2 sec */ + max_wait_count =SPC_DOORBELL_CLEAR_TIMEOUT ; } do { udelay(1);drivers/scsi/pm8001/pm80xx_hwi.h +3
-1@@ -220,6 +220,9 @@#define SAS_DOPNRJT_RTRY_TMO 128#define SAS_COPNRJT_RTRY_TMO 128 +#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 1000 * 1000)/* 30 sec */ +#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 1000 * 1000)/* 15 sec */ +/* Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. Assuming a bigger value 3 second, 3000000/128 = 23437.5 where 128 -- 2.16.3
PATCH 6/12 pm80xx : Fix dereferencing dangling pointer.
In reply to Deepak UkeyFrom: Vikram Auradkar <[email protected]>
sas_task structure should not be used after task_done is called. If the device is gone or not attached, we call task_done on t and continue to use in the sas_task in rest of the function. task_done is pointing to sas_ata_task_done, may free the memory associated with the task before returning.
--- drivers/scsi/pm8001/pm8001_sas.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/scsi/pm8001/pm8001_sas.c +6 -6
@@ -388,6 +388,7 @@ static int pm8001_task_exec(struct sas_task *task,struct pm8001_ccb_info *ccb;u32 tag =0xdeadbeef , rc =0 , n_elem =0 ;unsigned long flags =0 ; +enum sas_protocol task_proto = t->task_proto;if (!dev->port) {struct task_status_struct *tsm = &t->task_status;
@@ -412,7 +413,7 @@ static int pm8001_task_exec(struct sas_task *task, pm8001_dev = dev->lldd_dev; port = &pm8001_ha->port[sas_find_local_port_id (dev)];if (DEV_IS_GONE (pm8001_dev) || !port->port_attached) { -if (sas_protocol_ata (t->task_proto)) { +if (sas_protocol_ata (task_proto)) {struct task_status_struct *ts = &t->task_status; ts->resp =SAS_TASK_UNDELIVERED ; ts->stat =SAS_PHY_DOWN ;
@@ -434,7 +435,7 @@ static int pm8001_task_exec(struct sas_task *task, goto err_out; ccb = &pm8001_ha->ccb_info[tag]; -if (!sas_protocol_ata (t->task_proto)) { +if (!sas_protocol_ata (task_proto)) {if (t->num_scatter) { n_elem = dma_map_sg(pm8001_ha->dev, t->scatter,
@@ -454,7 +455,7 @@ static int pm8001_task_exec(struct sas_task *task, ccb->ccb_tag = tag; ccb->task = t; ccb->device = pm8001_dev; -switch (t->task_proto) { +switch (task_proto) {case SAS_PROTOCOL_SMP : rc =pm8001_task_prep_smp (pm8001_ha, ccb);break ;
@@ -471,8 +472,7 @@ static int pm8001_task_exec(struct sas_task *task,break ;default :dev_printk (KERN_ERR , pm8001_ha->dev, -"unknown sas_task proto: 0x%x\n" , - t->task_proto); +"unknown sas_task proto: 0x%x\n" , task_proto); rc = -EINVAL ;break ; }
@@ -495,7 +495,7 @@ static int pm8001_task_exec(struct sas_task *task,pm8001_tag_free (pm8001_ha, tag); err_out:dev_printk (KERN_ERR , pm8001_ha->dev,"pm8001 exec failed[%d]!\n" , rc); -if (!sas_protocol_ata (t->task_proto)) +if (!sas_protocol_ata (task_proto))if (n_elem)dma_unmap_sg (pm8001_ha->dev, t->scatter, t->num_scatter, t->data_dir);
Signature · 1 line
2.16.3
Re: [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer.
Quoted 9 lines · Deepak Ukey
From: Vikram Auradkar <[email protected]>
sas_taskstructure should not be used aftertask_doneis called. If the device is gone or not attached, we calltask_doneon t and continue to use in thesas_taskin rest of the function.task_doneis pointing tosas_ata_task_done, may free the memory associated with the task before returning.
Quoted 3 lines
Signed-off-by Vikram Auradkar <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Quoted 65 lines
--- drivers/scsi/pm8001/pm8001_sas.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)drivers/scsi/pm8001/pm8001_sas.c +6
-7@@ -388,6 +388,7 @@ static int pm8001_task_exec(struct sas_task *task,struct pm8001_ccb_info *ccb;u32 tag =0xdeadbeef , rc =0 , n_elem =0 ;unsigned long flags =0 ; +enum sas_protocol task_proto = t->task_proto;if (!dev->port) {struct task_status_struct *tsm = &t->task_status;@@ -412,7 +413,7 @@ static int pm8001_task_exec(struct sas_task *task, pm8001_dev = dev->lldd_dev; port = &pm8001_ha->port[sas_find_local_port_id (dev)];if (DEV_IS_GONE (pm8001_dev) || !port->port_attached) { -if (sas_protocol_ata (t->task_proto)) { +if (sas_protocol_ata (task_proto)) {struct task_status_struct *ts = &t->task_status; ts->resp =SAS_TASK_UNDELIVERED ; ts->stat =SAS_PHY_DOWN ;@@ -434,7 +435,7 @@ static int pm8001_task_exec(struct sas_task *task, goto err_out; ccb = &pm8001_ha->ccb_info[tag]; -if (!sas_protocol_ata (t->task_proto)) { +if (!sas_protocol_ata (task_proto)) {if (t->num_scatter) { n_elem = dma_map_sg(pm8001_ha->dev, t->scatter,@@ -454,7 +455,7 @@ static int pm8001_task_exec(struct sas_task *task, ccb->ccb_tag = tag; ccb->task = t; ccb->device = pm8001_dev; -switch (t->task_proto) { +switch (task_proto) {case SAS_PROTOCOL_SMP : rc =pm8001_task_prep_smp (pm8001_ha, ccb);break ;@@ -471,8 +472,7 @@ static int pm8001_task_exec(struct sas_task *task,break ;default :dev_printk (KERN_ERR , pm8001_ha->dev, -"unknown sas_task proto: 0x%x\n" , - t->task_proto); +"unknown sas_task proto: 0x%x\n" , task_proto); rc = -EINVAL ;break ; }@@ -495,7 +495,7 @@ static int pm8001_task_exec(struct sas_task *task,pm8001_tag_free (pm8001_ha, tag); err_out:dev_printk (KERN_ERR , pm8001_ha->dev,"pm8001 exec failed[%d]!\n" , rc); -if (!sas_protocol_ata (t->task_proto)) +if (!sas_protocol_ata (task_proto))if (n_elem)dma_unmap_sg (pm8001_ha->dev, t->scatter, t->num_scatter, t->data_dir); --2.16.3
PATCH 7/12 pm80xx : Fix command issue sizing.
In reply to Deepak UkeyFrom: peter chang <[email protected]>
The commands to the controller are sent in fixed sized chunks which are set per-chip-generation and stashed in iomb_size. The driver fills in structs matching the register layout and memcpy this to memory shared with the controller. however, there are two problem cases:
1)Things like phy_start_req are too large because they share the sas_identify_frame definition with libsas, and it includes the crc word. this means that it's overwriting the start of the next command block, that's ok except if it happens at the end of the shared memory area.
2)Things like set_nvm_data_req which are shared between the HAL layers. this means that it's sending 'random' data for things that are in the reserved area. so far we haven't found a case where the controller FW cares, but sending possible gibberish (for most of the structures this is in the reserved area so previously zeroed) is not recommended.
--- drivers/scsi/pm8001/pm8001_hwi.c | 69 ++++++++++++++++++++++++++-------------- drivers/scsi/pm8001/pm8001_sas.h | 3 +- drivers/scsi/pm8001/pm80xx_hwi.c | 47 +++++++++++++++++---------- 3 files changed, 79 insertions(+), 40 deletions(-)
drivers/scsi/pm8001/pm8001_hwi.c +46 -23
@@ -1336,10 +1336,13 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,* @circularQ: the inbound queue we want to transfer to HBA. * @opCode: the operation code represents commands which LLDD and fw recognized. * @payload: the command payload of each operation command. +* @nb: size in bytes of the command payload +* @responseQueue: queue to interrupt on w/ command response (if any) */ int pm8001_mpi_build_cmd (struct pm8001_hba_info *pm8001_ha,struct inbound_queue_table *circularQ, -u32 opCode,void *payload,u32 responseQueue) +u32 opCode,void *payload,size_t nb, +u32 responseQueue) {u32 Header =0 , hpriority =0 , bc =1 , category =0x02 ;void *pMessage;
@@ -1350,10 +1353,13 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, pm8001_printk("No free mpi buffer\n"));return -ENOMEM ; } -BUG_ON (!payload); -/*Copy to the payload*/ -memcpy (pMessage, payload, (pm8001_ha->iomb_size - -sizeof (struct mpi_msg_hdr ))); + +if (nb > (pm8001_ha->iomb_size -sizeof (struct mpi_msg_hdr ))) + nb = pm8001_ha->iomb_size -sizeof (struct mpi_msg_hdr ); +memcpy (pMessage, payload, nb); +if (nb +sizeof (struct mpi_msg_hdr ) < pm8001_ha->iomb_size) +memset (pMessage + nb,0 , pm8001_ha->iomb_size - + (nb +sizeof (struct mpi_msg_hdr )));/*Build the header*/ Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24)
@@ -1763,7 +1769,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, task_abort.device_id =cpu_to_le32 (pm8001_ha_dev->device_id); task_abort.tag =cpu_to_le32 (ccb_tag); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort, +sizeof (task_abort),0 );if (ret)pm8001_tag_free (pm8001_ha, ccb_tag);
@@ -1836,7 +1843,8 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, sata_cmd.ncqtag_atap_dir_m |= ((0x1 <<7 ) | (0x5 <<9 ));memcpy (&sata_cmd.sata_fis, &fis,sizeof (struct host_to_dev_fis )); - res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd,0 ); + res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd, +sizeof (sata_cmd),0 );if (res) {sas_free_task (task);pm8001_tag_free (pm8001_ha, ccb_tag);
@@ -3375,7 +3383,8 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, ((phyId & 0x0F) << 4) | (port_id & 0x0F)); payload.param0 =cpu_to_le32 (param0); payload.param1 =cpu_to_le32 (param1); -pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 ); } static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
@@ -4305,7 +4314,7 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 ((u32 )sg_dma_len (&task->smp_task.smp_resp)-4 );build_smp_cmd (pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, - (u32 *)&smp_cmd,0 ); + &smp_cmd,sizeof (smp_cmd),0 );if (rc) goto err_out_2;
@@ -4373,7 +4382,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.len =cpu_to_le32 (task->total_xfer_len); ssp_cmd.esgl =0 ; } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &ssp_cmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &ssp_cmd, +sizeof (ssp_cmd),0 );return ret; }
@@ -4482,7 +4492,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd, +sizeof (sata_cmd),0 );return ret; }
@@ -4517,7 +4528,8 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)memcpy (payload.sas_identify.sas_addr, pm8001_ha->sas_addr,SAS_ADDR_SIZE ); payload.sas_identify.phy_id = phy_id; - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }
@@ -4539,7 +4551,8 @@ static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,memset (&payload,0 ,sizeof (payload)); payload.tag =cpu_to_le32 (tag); payload.phy_id =cpu_to_le32 (phy_id); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }
@@ -4598,7 +4611,8 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 (ITNT | (firstBurstSize *0x10000 ));memcpy (payload.sas_addr, pm8001_dev->sas_device->sas_addr,SAS_ADDR_SIZE ); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return rc; }
@@ -4619,7 +4633,8 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, payload.device_id =cpu_to_le32 (device_id);PM8001_MSG_DBG (pm8001_ha,pm8001_printk ("unregister device device_id = %d\n" , device_id)); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }
@@ -4642,7 +4657,8 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, payload.tag =cpu_to_le32 (1 ); payload.phyop_phyid =cpu_to_le32 (((phy_op &0xff ) <<8 ) | (phyId &0x0F )); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }
@@ -4696,7 +4712,8 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, task_abort.device_id =cpu_to_le32 (dev_id); task_abort.tag =cpu_to_le32 (cmd_tag); } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort, +sizeof (task_abort),0 );return ret; }
@@ -4753,7 +4770,8 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,if (pm8001_ha->chip_id != chip_8001) sspTMCmd.ds_ads_m =0x08 ; circularQ = &pm8001_ha->inbnd_q_tbl[0 ]; - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sspTMCmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sspTMCmd, +sizeof (sspTMCmd),0 );return ret; }
@@ -4843,7 +4861,8 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,default :break ; } - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req, +sizeof (nvmd_req),0 );if (rc) {kfree (fw_control_context);pm8001_tag_free (pm8001_ha, tag);
@@ -4927,7 +4946,8 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,default :break ; } - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req, +sizeof (nvmd_req),0 );if (rc) {kfree (fw_control_context);pm8001_tag_free (pm8001_ha, tag);
@@ -4962,7 +4982,8 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 (lower_32_bits (le64_to_cpu (info->sgl.addr))); payload.sgl_addr_hi =cpu_to_le32 (upper_32_bits (le64_to_cpu (info->sgl.addr))); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }
@@ -5109,7 +5130,8 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, payload.tag =cpu_to_le32 (tag); payload.device_id =cpu_to_le32 (pm8001_dev->device_id); payload.nds =cpu_to_le32 (state); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return rc; }
@@ -5134,7 +5156,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) payload.SSAHOLT =cpu_to_le32 (0xd <<25 ); payload.sata_hol_tmo =cpu_to_le32 (80 ); payload.open_reject_cmdretries_data_retries =cpu_to_le32 (0xff00ff ); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);return rc;
drivers/scsi/pm8001/pm8001_sas.h +2 -1
@@ -674,7 +674,8 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,void pm8001_chip_iounmap (struct pm8001_hba_info *pm8001_ha);int pm8001_mpi_build_cmd (struct pm8001_hba_info *pm8001_ha,struct inbound_queue_table *circularQ, -u32 opCode,void *payload,u32 responseQueue); +u32 opCode,void *payload,size_t nb, +u32 responseQueue);int pm8001_mpi_msg_free_get (struct inbound_queue_table *circularQ,u16 messageSize,void **messagePtr); u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg,
drivers/scsi/pm8001/pm80xx_hwi.c +31 -16
137 lines not on this page · raw message
Signature · 1 line
2.16.3
Re: [PATCH 07/12] pm80xx : Fix command issue sizing.
Quoted 19 lines · Deepak Ukey
From: peter chang <[email protected]>
The commands to the controller are sent in fixed sized chunks which are set per-chip-generation and stashed in
iomb_size. The driver fills in structs matching the register layout and memcpy this to memory shared with the controller. however, there are two problem cases:
1)Things likephy_start_reqare too large because they share thesas_identify_framedefinition with libsas, and it includes the crc word. this means that it's overwriting the start of the next command block, that's ok except if it happens at the end of the shared memory area.
2)Things likeset_nvm_data_reqwhich are shared between the HAL layers. this means that it's sending 'random' data for things that are in the reserved area. so far we haven't found a case where the controller FW cares, but sending possible gibberish (for most of the structures this is in the reserved area so previously zeroed) is not recommended.
Quoted 3 lines
Signed-off-by peter chang <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Quoted 395 lines
--- drivers/scsi/pm8001/pm8001_hwi.c | 69 ++++++++++++++++++++++++++-------------- drivers/scsi/pm8001/pm8001_sas.h | 3 +- drivers/scsi/pm8001/pm80xx_hwi.c | 47 +++++++++++++++++---------- 3 files changed, 79 insertions(+), 40 deletions(-)drivers/scsi/pm8001/pm8001_hwi.c +46
-23@@ -1336,10 +1336,13 @@ int pm8001_mpi_msg_free_get(struct inbound_queue_table *circularQ,* @circularQ: the inbound queue we want to transfer to HBA. * @opCode: the operation code represents commands which LLDD and fw recognized. * @payload: the command payload of each operation command. +* @nb: size in bytes of the command payload +* @responseQueue: queue to interrupt on w/ command response (if any) */ int pm8001_mpi_build_cmd (struct pm8001_hba_info *pm8001_ha,struct inbound_queue_table *circularQ, -u32 opCode,void *payload,u32 responseQueue) +u32 opCode,void *payload,size_t nb, +u32 responseQueue) {u32 Header =0 , hpriority =0 , bc =1 , category =0x02 ;void *pMessage;@@ -1350,10 +1353,13 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, pm8001_printk("No free mpi buffer\n"));return -ENOMEM ; } -BUG_ON (!payload); -/*Copy to the payload*/ -memcpy (pMessage, payload, (pm8001_ha->iomb_size - -sizeof (struct mpi_msg_hdr ))); + +if (nb > (pm8001_ha->iomb_size -sizeof (struct mpi_msg_hdr ))) + nb = pm8001_ha->iomb_size -sizeof (struct mpi_msg_hdr ); +memcpy (pMessage, payload, nb); +if (nb +sizeof (struct mpi_msg_hdr ) < pm8001_ha->iomb_size) +memset (pMessage + nb,0 , pm8001_ha->iomb_size - + (nb +sizeof (struct mpi_msg_hdr )));/*Build the header*/ Header = ((1 << 31) | (hpriority << 30) | ((bc & 0x1f) << 24)@@ -1763,7 +1769,8 @@ static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, task_abort.device_id =cpu_to_le32 (pm8001_ha_dev->device_id); task_abort.tag =cpu_to_le32 (ccb_tag); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort, +sizeof (task_abort),0 );if (ret)pm8001_tag_free (pm8001_ha, ccb_tag);@@ -1836,7 +1843,8 @@ static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha, sata_cmd.ncqtag_atap_dir_m |= ((0x1 <<7 ) | (0x5 <<9 ));memcpy (&sata_cmd.sata_fis, &fis,sizeof (struct host_to_dev_fis )); - res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd,0 ); + res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd, +sizeof (sata_cmd),0 );if (res) {sas_free_task (task);pm8001_tag_free (pm8001_ha, ccb_tag);@@ -3375,7 +3383,8 @@ static void pm8001_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, ((phyId & 0x0F) << 4) | (port_id & 0x0F)); payload.param0 =cpu_to_le32 (param0); payload.param1 =cpu_to_le32 (param1); -pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 ); } static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,@@ -4305,7 +4314,7 @@ static int pm8001_chip_smp_req(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 ((u32 )sg_dma_len (&task->smp_task.smp_resp)-4 );build_smp_cmd (pm8001_dev->device_id, smp_cmd.tag, &smp_cmd); rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, - (u32 *)&smp_cmd,0 ); + &smp_cmd,sizeof (smp_cmd),0 );if (rc) goto err_out_2;@@ -4373,7 +4382,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ssp_cmd.len =cpu_to_le32 (task->total_xfer_len); ssp_cmd.esgl =0 ; } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &ssp_cmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &ssp_cmd, +sizeof (ssp_cmd),0 );return ret; }@@ -4482,7 +4492,8 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd, +sizeof (sata_cmd),0 );return ret; }@@ -4517,7 +4528,8 @@ pm8001_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)memcpy (payload.sas_identify.sas_addr, pm8001_ha->sas_addr,SAS_ADDR_SIZE ); payload.sas_identify.phy_id = phy_id; - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }@@ -4539,7 +4551,8 @@ static int pm8001_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,memset (&payload,0 ,sizeof (payload)); payload.tag =cpu_to_le32 (tag); payload.phy_id =cpu_to_le32 (phy_id); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }@@ -4598,7 +4611,8 @@ static int pm8001_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 (ITNT | (firstBurstSize *0x10000 ));memcpy (payload.sas_addr, pm8001_dev->sas_device->sas_addr,SAS_ADDR_SIZE ); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return rc; }@@ -4619,7 +4633,8 @@ int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, payload.device_id =cpu_to_le32 (device_id);PM8001_MSG_DBG (pm8001_ha,pm8001_printk ("unregister device device_id = %d\n" , device_id)); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }@@ -4642,7 +4657,8 @@ static int pm8001_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, payload.tag =cpu_to_le32 (1 ); payload.phyop_phyid =cpu_to_le32 (((phy_op &0xff ) <<8 ) | (phyId &0x0F )); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }@@ -4696,7 +4712,8 @@ static int send_task_abort(struct pm8001_hba_info *pm8001_ha, u32 opc, task_abort.device_id =cpu_to_le32 (dev_id); task_abort.tag =cpu_to_le32 (cmd_tag); } - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort, +sizeof (task_abort),0 );return ret; }@@ -4753,7 +4770,8 @@ int pm8001_chip_ssp_tm_req(struct pm8001_hba_info *pm8001_ha,if (pm8001_ha->chip_id != chip_8001) sspTMCmd.ds_ads_m =0x08 ; circularQ = &pm8001_ha->inbnd_q_tbl[0 ]; - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sspTMCmd,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sspTMCmd, +sizeof (sspTMCmd),0 );return ret; }@@ -4843,7 +4861,8 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,default :break ; } - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req, +sizeof (nvmd_req),0 );if (rc) {kfree (fw_control_context);pm8001_tag_free (pm8001_ha, tag);@@ -4927,7 +4946,8 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,default :break ; } - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &nvmd_req, +sizeof (nvmd_req),0 );if (rc) {kfree (fw_control_context);pm8001_tag_free (pm8001_ha, tag);@@ -4962,7 +4982,8 @@ pm8001_chip_fw_flash_update_build(struct pm8001_hba_info *pm8001_ha,cpu_to_le32 (lower_32_bits (le64_to_cpu (info->sgl.addr))); payload.sgl_addr_hi =cpu_to_le32 (upper_32_bits (le64_to_cpu (info->sgl.addr))); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return ret; }@@ -5109,7 +5130,8 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha, payload.tag =cpu_to_le32 (tag); payload.device_id =cpu_to_le32 (pm8001_dev->device_id); payload.nds =cpu_to_le32 (state); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );return rc; }@@ -5134,7 +5156,8 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha) payload.SSAHOLT =cpu_to_le32 (0xd <<25 ); payload.sata_hol_tmo =cpu_to_le32 (80 ); payload.open_reject_cmdretries_data_retries =cpu_to_le32 (0xff00ff ); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);return rc;drivers/scsi/pm8001/pm8001_sas.h +2
-1@@ -674,7 +674,8 @@ int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr,void pm8001_chip_iounmap (struct pm8001_hba_info *pm8001_ha);int pm8001_mpi_build_cmd (struct pm8001_hba_info *pm8001_ha,struct inbound_queue_table *circularQ, -u32 opCode,void *payload,u32 responseQueue); +u32 opCode,void *payload,size_t nb, +u32 responseQueue);int pm8001_mpi_msg_free_get (struct inbound_queue_table *circularQ,u16 messageSize,void **messagePtr); u32 pm8001_mpi_msg_free_set(struct pm8001_hba_info *pm8001_ha, void *pMsg,drivers/scsi/pm8001/pm80xx_hwi.c +31
-17@@ -955,7 +955,8 @@ pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha)"Setting up thermal config. cfg_pg 0 0x%x cfg_pg 1 0x%x\n" , payload.cfg_pg[0], payload.cfg_pg[1])); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);return rc;@@ -1037,7 +1038,8 @@ pm80xx_set_sas_protocol_timer_config(struct pm8001_hba_info *pm8001_ha)memcpy (&payload.cfg_pg, &SASConfigPage,sizeof (SASProtocolTimerConfig_t)); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);@@ -1164,7 +1166,8 @@ static int pm80xx_encrypt_update(struct pm8001_hba_info *pm8001_ha)"Saving Encryption info to flash. payload 0x%x\n" , payload.new_curidx_ksop)); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);@@ -1517,7 +1520,10 @@ static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha, task_abort.device_id =cpu_to_le32 (pm8001_ha_dev->device_id); task_abort.tag =cpu_to_le32 (ccb_tag); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &task_abort, +sizeof (task_abort),0 ); +PM8001_FAIL_DBG (pm8001_ha, +pm8001_printk ("Executing abort task end\n" ));if (ret) {sas_free_task (task);pm8001_tag_free (pm8001_ha, ccb_tag);@@ -1593,7 +1599,9 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha, sata_cmd.ncqtag_atap_dir_m_dad |= ((0x1 <<7 ) | (0x5 <<9 ));memcpy (&sata_cmd.sata_fis, &fis,sizeof (struct host_to_dev_fis )); - res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd,0 ); + res =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &sata_cmd, +sizeof (sata_cmd),0 ); +PM8001_FAIL_DBG (pm8001_ha,pm8001_printk ("Executing read log end\n" ));if (res) {sas_free_task (task);pm8001_tag_free (pm8001_ha, ccb_tag);@@ -2962,7 +2970,8 @@ static void pm80xx_hw_event_ack_req(struct pm8001_hba_info *pm8001_ha, ((phyId & 0xFF) << 24) | (port_id & 0xFF)); payload.param0 =cpu_to_le32 (param0); payload.param1 =cpu_to_le32 (param1); -pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 ); } static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,@@ -4082,8 +4091,8 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,build_smp_cmd (pm8001_dev->device_id, smp_cmd.tag, &smp_cmd, pm8001_ha->smp_exp_mode, length); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, - (u32 *)&smp_cmd,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &smp_cmd, +sizeof (smp_cmd),0 );if (rc) goto err_out_2;return 0 ;@@ -4291,7 +4300,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, } q_index = (u32) (pm8001_dev->id &0x00ffffff ) %PM8001_MAX_OUTB_NUM ; ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, - &ssp_cmd, q_index); + &ssp_cmd,sizeof (ssp_cmd), q_index);return ret; }@@ -4532,7 +4541,7 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, } q_index = (u32) (pm8001_ha_dev->id &0x00ffffff ) %PM8001_MAX_OUTB_NUM ; ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, - &sata_cmd, q_index); + &sata_cmd,sizeof (sata_cmd), q_index);return ret; }@@ -4587,7 +4596,8 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)memcpy (payload.sas_identify.sas_addr, &pm8001_ha->phy[phy_id].dev_sas_addr,SAS_ADDR_SIZE ); payload.sas_identify.phy_id = phy_id; - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }@@ -4609,7 +4619,8 @@ static int pm80xx_chip_phy_stop_req(struct pm8001_hba_info *pm8001_ha,memset (&payload,0 ,sizeof (payload)); payload.tag =cpu_to_le32 (tag); payload.phy_id =cpu_to_le32 (phy_id); - ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,0 ); + ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload, +sizeof (payload),0 );return ret; }@@ -4675,7 +4686,8 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,memcpy (payload.sas_addr, pm8001_dev->sas_device->sas_addr,SAS_ADDR_SIZE ); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag);@@ -4705,7 +4717,8 @@ static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha, payload.tag =cpu_to_le32 (tag); payload.phyop_phyid =cpu_to_le32 (((phy_op &0xFF ) <<8 ) | (phyId &0xFF )); -return pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +return pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 ); }static u32 pm80xx_chip_is_our_interrupt (struct pm8001_hba_info *pm8001_ha)@@ -4763,7 +4776,8 @@ void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha, payload.reserved[j] =cpu_to_le32 (*((u32 *)buf + i)); j++; } - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag); }@@ -4805,7 +4819,8 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,for (i =0 ; i < length; i++) payload.reserved[i] =cpu_to_le32 (*(buf + i)); - rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload, +sizeof (payload),0 );if (rc)pm8001_tag_free (pm8001_ha, tag); --2.16.3
PATCH 8/12 pm80xx : Cleanup command when a reset times out.
In reply to Deepak UkeyFrom: peter chang <[email protected]>
Added the fix so the if driver properly sent the abort it try to remove it from the firmware's list of outstanding commands regardless of the abort status. This means that the task gets free-ed 'now' rather than possibly getting free-ed later when the scsi layer thinks it's leaked but still valid.
--- drivers/scsi/pm8001/pm8001_sas.c | 50 +++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-)
drivers/scsi/pm8001/pm8001_sas.c +37 -13
@@ -1204,8 +1204,8 @@ int pm8001_abort_task(struct sas_task *task) pm8001_dev = dev->lldd_dev; pm8001_ha =pm8001_find_ha_by_dev (dev); phy_id = pm8001_dev->attached_phy; - rc =pm8001_find_tag (task, &tag); -if (rc ==0 ) { + ret =pm8001_find_tag (task, &tag); +if (ret ==0 ) {pm8001_printk ("no tag for task:%p\n" , task);return TMF_RESP_FUNC_FAILED ; }
@@ -1243,26 +1243,50 @@ int pm8001_abort_task(struct sas_task *task)/* 2. Send Phy Control Hard Reset */ reinit_completion (&completion); + phy->port_reset_status =PORT_RESET_TMO ; phy->reset_success = false; phy->enable_completion = &completion; phy->reset_completion = &completion_reset; ret =PM8001_CHIP_DISP ->phy_ctl_req (pm8001_ha, phy_id,PHY_HARD_RESET ); -if (ret) - goto out; -PM8001_MSG_DBG (pm8001_ha, -pm8001_printk ("Waiting for local phy ctl\n" )); -wait_for_completion (&completion); -if (!phy->reset_success) +if (ret) { + phy->enable_completion =NULL ; + phy->reset_completion =NULL ; goto out; + } -/* 3. Wait for Port Reset complete / Port reset TMO */ +/* In the case of the reset timeout/fail we still +* abort the command at the firmware. Yhe assumption +* here is that the drive is off doing something so +* that it's not processing requests, and we want to +* avoid getting a completion for this and either +* leaking the task in libsas or losing the race and +* getting a double free. +*/ PM8001_MSG_DBG (pm8001_ha, +pm8001_printk ("Waiting for local phy ctl\n" )); + ret =wait_for_completion_timeout (&completion, +PM8001_TASK_TIMEOUT *HZ ); +if (!ret || !phy->reset_success) { + phy->enable_completion =NULL ; + phy->reset_completion =NULL ; + }else { +/* 3. Wait for Port Reset complete or +* Port reset TMO +*/ +PM8001_MSG_DBG (pm8001_ha,pm8001_printk ("Waiting for Port reset\n" )); -wait_for_completion (&completion_reset); -if (phy->port_reset_status) { -pm8001_dev_gone_notify (dev); - goto out; + ret =wait_for_completion_timeout ( + &completion_reset, +PM8001_TASK_TIMEOUT *HZ ); +if (!ret) + phy->reset_completion =NULL ; +WARN_ON (phy->port_reset_status == +PORT_RESET_TMO ); +if (phy->port_reset_status ==PORT_RESET_TMO ) { +pm8001_dev_gone_notify (dev); + goto out; + } }/*
Signature · 1 line
2.16.3
Re: [PATCH 08/12] pm80xx : Cleanup command when a reset times out.
Quoted 46 lines · Deepak Ukey
From: peter chang <[email protected]>
Added the fix so the if driver properly sent the abort it try to remove it from the firmware's list of outstanding commands regardless of the abort status. This means that the task gets free-ed 'now' rather than possibly getting free-ed later when the scsi layer thinks it's leaked but still valid.
Signed-off-by peter chang <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>--- drivers/scsi/pm8001/pm8001_sas.c | 50 +++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-)drivers/scsi/pm8001/pm8001_sas.c +3
-7@@ -1204,8 +1204,8 @@ int pm8001_abort_task(struct sas_task *task) pm8001_dev = dev->lldd_dev; pm8001_ha =pm8001_find_ha_by_dev (dev); phy_id = pm8001_dev->attached_phy; - rc =pm8001_find_tag (task, &tag); -if (rc ==0 ) { + ret =pm8001_find_tag (task, &tag); +if (ret ==0 ) {pm8001_printk ("no tag for task:%p\n" , task);return TMF_RESP_FUNC_FAILED ; }@@ -1243,26 +1243,50 @@ int pm8001_abort_task(struct sas_task *task)/* 2. Send Phy Control Hard Reset */ reinit_completion (&completion); + phy->port_reset_status =PORT_RESET_TMO ; phy->reset_success = false; phy->enable_completion = &completion; phy->reset_completion = &completion_reset; ret =PM8001_CHIP_DISP ->phy_ctl_req (pm8001_ha, phy_id,PHY_HARD_RESET ); -if (ret) - goto out; -PM8001_MSG_DBG (pm8001_ha, -pm8001_printk ("Waiting for local phy ctl\n" )); -wait_for_completion (&completion);
drivers/scsi/pm8001/pm8001_sas.c int pm8001_abort_task(struct sas_task *task) · line 1259
Quoted 10 lines
drivers/scsi/pm8001/pm8001_sas.c +6
-2-if (!phy->reset_success) +if (ret) { + phy->enable_completion =NULL ; + phy->reset_completion =NULL ; goto out; + } -/* 3. Wait for Port Reset complete / Port reset TMO */ +/* In the case of the reset timeout/fail we still +* abort the command at the firmware. Yhe assumption
s/Yhe/The
Quoted 38 lines
drivers/scsi/pm8001/pm8001_sas.c +28
-5+* here is that the drive is off doing something so +* that it's not processing requests, and we want to +* avoid getting a completion for this and either +* leaking the task in libsas or losing the race and +* getting a double free. +*/ PM8001_MSG_DBG (pm8001_ha, +pm8001_printk ("Waiting for local phy ctl\n" )); + ret =wait_for_completion_timeout (&completion, +PM8001_TASK_TIMEOUT *HZ ); +if (!ret || !phy->reset_success) { + phy->enable_completion =NULL ; + phy->reset_completion =NULL ; + }else { +/* 3. Wait for Port Reset complete or +* Port reset TMO +*/ +PM8001_MSG_DBG (pm8001_ha,pm8001_printk ("Waiting for Port reset\n" )); -wait_for_completion (&completion_reset); -if (phy->port_reset_status) { -pm8001_dev_gone_notify (dev); - goto out; + ret =wait_for_completion_timeout ( + &completion_reset, +PM8001_TASK_TIMEOUT *HZ ); +if (!ret) + phy->reset_completion =NULL ; +WARN_ON (phy->port_reset_status == +PORT_RESET_TMO ); +if (phy->port_reset_status ==PORT_RESET_TMO ) { +pm8001_dev_gone_notify (dev); + goto out; + } }/* --
Quoted 2 lines
2.16.3
Patch looks fine, please fix the typo above.
PATCH 9/12 pm80xx : Do not request 12G sas speeds.
In reply to Deepak UkeyFrom: peter chang <[email protected]>
occasionally, 6G capable drives fail to train at 6G on links that look good from a signal-integrity perspective. PMC suggests configuring the port to not even expect 12G.
--- drivers/scsi/pm8001/pm8001_init.c | 17 +++++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 21 ++++----------------- 3 files changed, 22 insertions(+), 17 deletions(-)
drivers/scsi/pm8001/pm8001_init.c +17 -0
@@ -41,11 +41,20 @@#include <linux/slab.h> #include "pm8001_sas.h" #include "pm8001_chips.h" +#include "pm80xx_hwi.h" static ulong logging_level =PM8001_FAIL_LOGGING |PM8001_IOERR_LOGGING ;module_param (logging_level, ulong,0644 );MODULE_PARM_DESC (logging_level," bits for enabling logging info." ); +static ulong link_rate =LINKRATE_15 |LINKRATE_30 |LINKRATE_60 |LINKRATE_120 ; +module_param (link_rate, ulong,0644 ); +MODULE_PARM_DESC (link_rate,"Enable link rate.\n" +" 1: Link rate 1.5G\n" +" 2: Link rate 3.0G\n" +" 4: Link rate 6.0G\n" +" 8: Link rate 12.0G\n" ); +static struct scsi_transport_template *pm8001_stt;/**
@@ -471,6 +480,14 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->shost = shost; pm8001_ha->id = pm8001_id++; pm8001_ha->logging_level = logging_level; +if (link_rate >=1 && link_rate <=15 ) + pm8001_ha->link_rate = (link_rate <<8 ); +else { + pm8001_ha->link_rate =LINKRATE_15 |LINKRATE_30 | +LINKRATE_60 |LINKRATE_120 ; +PM8001_FAIL_DBG (pm8001_ha,pm8001_printk ( +"Setting link rate to default value\n" )); + }sprintf (pm8001_ha->name,"%s%d" ,DRV_NAME , pm8001_ha->id);/* IOMB size is 128 for 8088/89 controllers */ if (pm8001_ha->chip_id != chip_8001)
drivers/scsi/pm8001/pm8001_sas.h +1 -0
@@ -546,6 +546,7 @@ struct pm8001_hba_info {struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC ];#endif u32 logging_level; +u32 link_rate;u32 fw_status;u32 smp_exp_mode;bool controller_fatal_error;
drivers/scsi/pm8001/pm80xx_hwi.c +4 -17
@@ -37,6 +37,7 @@* POSSIBILITY OF SUCH DAMAGES. * */ +#include <linux/version.h> #include <linux/slab.h> #include "pm8001_sas.h" #include "pm80xx_hwi.h"
@@ -4565,23 +4566,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("PHY START REQ for phy_id %d\n" , phy_id)); -/* -** [0:7] PHY Identifier -** [8:11] link rate 1.5G, 3G, 6G -** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b Auto mode -** [14] 0b disable spin up hold; 1b enable spin up hold -** [15] ob no change in current PHY analig setup 1b enable using SPAST -*/ -if (!IS_SPCV_12G (pm8001_ha->pdev)) - payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | -LINKMODE_AUTO |LINKRATE_15 | -LINKRATE_30 |LINKRATE_60 | phy_id); -else - payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | -LINKMODE_AUTO |LINKRATE_15 | -LINKRATE_30 |LINKRATE_60 |LINKRATE_120 | - phy_id); + payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | +LINKMODE_AUTO | pm8001_ha->link_rate | phy_id);/* SSC Disable and SAS Analog ST configuration */ /** payload.ase_sh_lm_slr_phyid =
@@ -4594,7 +4581,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) payload.sas_identify.dev_type =SAS_END_DEVICE ; payload.sas_identify.initiator_bits =SAS_PROTOCOL_ALL ;memcpy (payload.sas_identify.sas_addr, - &pm8001_ha->phy[phy_id].dev_sas_addr,SAS_ADDR_SIZE ); + &pm8001_ha->sas_addr,SAS_ADDR_SIZE ); payload.sas_identify.phy_id = phy_id; ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,sizeof (payload),0 );
Signature · 1 line
2.16.3
Re: [PATCH 09/12] pm80xx : Do not request 12G sas speeds.
Quoted 10 lines · Deepak Ukey
From: peter chang <[email protected]>
occasionally, 6G capable drives fail to train at 6G on links that look good from a signal-integrity perspective. PMC suggests configuring the port to not even expect 12G.
Signed-off-by peter chang <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Quoted 108 lines
--- drivers/scsi/pm8001/pm8001_init.c | 17 +++++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 1 + drivers/scsi/pm8001/pm80xx_hwi.c | 21 ++++----------------- 3 files changed, 22 insertions(+), 17 deletions(-)drivers/scsi/pm8001/pm8001_init.c +17
-0@@ -41,11 +41,20 @@#include <linux/slab.h> #include "pm8001_sas.h" #include "pm8001_chips.h" +#include "pm80xx_hwi.h" static ulong logging_level =PM8001_FAIL_LOGGING |PM8001_IOERR_LOGGING ;module_param (logging_level, ulong,0644 );MODULE_PARM_DESC (logging_level," bits for enabling logging info." ); +static ulong link_rate =LINKRATE_15 |LINKRATE_30 |LINKRATE_60 |LINKRATE_120 ; +module_param (link_rate, ulong,0644 ); +MODULE_PARM_DESC (link_rate,"Enable link rate.\n" +" 1: Link rate 1.5G\n" +" 2: Link rate 3.0G\n" +" 4: Link rate 6.0G\n" +" 8: Link rate 12.0G\n" ); +static struct scsi_transport_template *pm8001_stt;/** @@ -471,6 +480,14 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->shost = shost; pm8001_ha->id = pm8001_id++; pm8001_ha->logging_level = logging_level; +if (link_rate >=1 && link_rate <=15 ) + pm8001_ha->link_rate = (link_rate <<8 ); +else { + pm8001_ha->link_rate =LINKRATE_15 |LINKRATE_30 | +LINKRATE_60 |LINKRATE_120 ; +PM8001_FAIL_DBG (pm8001_ha,pm8001_printk ( +"Setting link rate to default value\n" )); + }sprintf (pm8001_ha->name,"%s%d" ,DRV_NAME , pm8001_ha->id);/* IOMB size is 128 for 8088/89 controllers */ if (pm8001_ha->chip_id != chip_8001)drivers/scsi/pm8001/pm8001_sas.h +1
-0@@ -546,6 +546,7 @@ struct pm8001_hba_info {struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC ];#endif u32 logging_level; +u32 link_rate;u32 fw_status;u32 smp_exp_mode;bool controller_fatal_error;drivers/scsi/pm8001/pm80xx_hwi.c +4
-18@@ -37,6 +37,7 @@* POSSIBILITY OF SUCH DAMAGES. * */ +#include <linux/version.h> #include <linux/slab.h> #include "pm8001_sas.h" #include "pm80xx_hwi.h" @@ -4565,23 +4566,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("PHY START REQ for phy_id %d\n" , phy_id)); -/* -** [0:7] PHY Identifier -** [8:11] link rate 1.5G, 3G, 6G -** [12:13] link mode 01b SAS mode; 10b SATA mode; 11b Auto mode -** [14] 0b disable spin up hold; 1b enable spin up hold -** [15] ob no change in current PHY analig setup 1b enable using SPAST -*/ -if (!IS_SPCV_12G (pm8001_ha->pdev)) - payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | -LINKMODE_AUTO |LINKRATE_15 | -LINKRATE_30 |LINKRATE_60 | phy_id); -else - payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | -LINKMODE_AUTO |LINKRATE_15 | -LINKRATE_30 |LINKRATE_60 |LINKRATE_120 | - phy_id); + payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_DISABLE | +LINKMODE_AUTO | pm8001_ha->link_rate | phy_id);/* SSC Disable and SAS Analog ST configuration */ /** payload.ase_sh_lm_slr_phyid = @@ -4594,7 +4581,7 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) payload.sas_identify.dev_type =SAS_END_DEVICE ; payload.sas_identify.initiator_bits =SAS_PROTOCOL_ALL ;memcpy (payload.sas_identify.sas_addr, - &pm8001_ha->phy[phy_id].dev_sas_addr,SAS_ADDR_SIZE ); + &pm8001_ha->sas_addr,SAS_ADDR_SIZE ); payload.sas_identify.phy_id = phy_id; ret =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opcode, &payload,sizeof (payload),0 ); --2.16.3
PATCH 10/12 pm80xx : Controller fatal error through sysfs.
In reply to Deepak UkeyFrom: Deepak Ukey <[email protected]>
Added support to check controller fatal error through sysfs.
--- drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/scsi/pm8001/pm8001_ctl.c +20 -0
@@ -69,6 +69,25 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev,static DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL); +/** +* pm8001_ctl_controller_fatal_err - check controller is under fatal err +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read only' shost attribute. +*/ +static ssize_t controller_fatal_error_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; + +return snprintf (buf,PAGE_SIZE ,"%d\n" , + pm8001_ha->controller_fatal_error); +} +static DEVICE_ATTR_RO (controller_fatal_error); +/** * pm8001_ctl_fw_version_show - firmware version * @cdev: pointer to embedded class device
@@ -804,6 +823,7 @@ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP, pm8001_show_update_fw, pm8001_store_update_fw);struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, + &dev_attr_controller_fatal_error, &dev_attr_fw_version, &dev_attr_update_fw, &dev_attr_aap_log,
Signature · 1 line
2.16.3
Re: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
Quoted 18 lines · Deepak Ukey
From: Deepak Ukey <[email protected]>
Added support to check controller fatal error through sysfs.
Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>--- drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)drivers/scsi/pm8001/pm8001_ctl.c +0
-0@@ -69,6 +69,25 @@ static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev,static DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev, · line 80
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +9
-0+/** +* pm8001_ctl_controller_fatal_err - check controller is under fatal err +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read only' shost attribute. +*/ +static ssize_t controller_fatal_error_show (struct device *cdev, +struct device_attribute *attr,char *buf)
The kernel-doc doesn't match the function name, please fix it.
Quoted 22 lines
drivers/scsi/pm8001/pm8001_ctl.c +11
-1+{ +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; + +return snprintf (buf,PAGE_SIZE ,"%d\n" , + pm8001_ha->controller_fatal_error); +} +static DEVICE_ATTR_RO (controller_fatal_error); +/** * pm8001_ctl_fw_version_show - firmware version * @cdev: pointer to embedded class device @@ -804,6 +823,7 @@ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP, pm8001_show_update_fw, pm8001_store_update_fw);struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, + &dev_attr_controller_fatal_error, &dev_attr_fw_version, &dev_attr_update_fw, &dev_attr_aap_log, --
Quoted 2 lines
2.16.3
With the updated kernel-doc.
[email protected]
Acked-by Jack WangRE: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
Quoted 21 lines · Deepak Ukey
From: Deepak Ukey <[email protected]>
Added support to check controller fatal error through sysfs.
Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>--- drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)drivers/scsi/pm8001/pm8001_ctl.c +0
-0@@ -69,6 +69,25 @@ static ssize_tpm8001_ctl_mpi_interface_rev_show(struct device *cdev, static
DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev, · line 80
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+/** +* pm8001_ctl_controller_fatal_err - check controller is under fatal +err +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read only' shost attribute. +*/ +static ssize_t controller_fatal_error_show (struct device *cdev, +struct device_attribute *attr,char *buf)
The kernel-doc doesn't match the function name, please fix it.
--Can you please tell me which function name you are pointing out. Is it about the difference in function description in the comment (pm8001_ctl_controller_fatal_err) and actual function name (controller_fatal_error_show) ?
Quoted 21 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+{ +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; + +return snprintf (buf,PAGE_SIZE ,"%d\n" , + pm8001_ha->controller_fatal_error); +} +static DEVICE_ATTR_RO (controller_fatal_error); +/** * pm8001_ctl_fw_version_show - firmware version * @cdev: pointer to embedded class device @@ -804,6 +823,7 @@ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP,
pm8001_show_update_fw, pm8001_store_update_fw); struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, + &dev_attr_controller_fatal_error, &dev_attr_fw_version, &dev_attr_update_fw, &dev_attr_aap_log,
Quoted 3 lines
--
2.16.3
With the updated kernel-doc.
Jinpu Wang
maintainerRe: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
Quoted 23 lines · On Thu, Nov 7, 2019 at 7:20 AM <[email protected]> wrote:
Quoted 21 lines · Deepak Ukey
From: Deepak Ukey <[email protected]>
Added support to check controller fatal error through sysfs.
Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>--- drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)drivers/scsi/pm8001/pm8001_ctl.c +0
-0@@ -69,6 +69,25 @@ static ssize_tpm8001_ctl_mpi_interface_rev_show(struct device *cdev, static
DEVICE_ATTR(interface_rev, S_IRUGO, pm8001_ctl_mpi_interface_rev_show, NULL);
Quoted 13 lines
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t pm8001_ctl_mpi_interface_rev_show(struct device *cdev, · line 80
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+/** +* pm8001_ctl_controller_fatal_err - check controller is under fatal +err +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read only' shost attribute. +*/ +static ssize_t controller_fatal_error_show (struct device *cdev, +struct device_attribute *attr,char *buf)The kernel-doc doesn't match the function name, please fix it.
--Can you please tell me which function name you are pointing out. Is it about the difference in function description in the comment (pm8001_ctl_controller_fatal_err) and actual function name (controller_fatal_error_show) ?
Yes.
PATCH 11/12 pm80xx : Tie the interrupt name to the module instance.
In reply to Deepak UkeyFrom: Vikram Auradkar <[email protected]>
With msix enabled, the interrupt instances are <prefix><index> where the prefix is fixed for all module instances, making it a little harder to track down what's what.
--- drivers/scsi/pm8001/pm8001_init.c | 11 ++++++----- drivers/scsi/pm8001/pm8001_sas.h | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-)
drivers/scsi/pm8001/pm8001_init.c +6 -5
@@ -894,7 +894,6 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)u32 number_of_intr;int flag =0 ;int rc; -static char intr_drvname[PM8001_MAX_MSIX_VEC ][sizeof (DRV_NAME )+3 ];/* SPCv controllers supports 64 msi-x */ if (pm8001_ha->chip_id == chip_8001) {
@@ -915,14 +914,16 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) rc, pm8001_ha->number_of_intr));for (i =0 ; i < number_of_intr; i++) { -snprintf (intr_drvname[i],sizeof (intr_drvname[0 ]), -DRV_NAME "%d" , i); +snprintf (pm8001_ha->intr_drvname[i], +sizeof (pm8001_ha->intr_drvname[0 ]), +"%s-%d" , pm8001_ha->name, i); pm8001_ha->irq_vector[i].irq_id = i; pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; rc =request_irq (pci_irq_vector (pm8001_ha->pdev, i), pm8001_interrupt_handler_msix, flag, - intr_drvname[i], &(pm8001_ha->irq_vector[i])); + pm8001_ha->intr_drvname[i], + &(pm8001_ha->irq_vector[i]));if (rc) {for (j =0 ; j < i; j++) { free_irq(pci_irq_vector(pm8001_ha->pdev, i),
@@ -963,7 +964,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) pm8001_ha->irq_vector[0 ].irq_id =0 ; pm8001_ha->irq_vector[0 ].drv_inst = pm8001_ha; rc =request_irq (pdev->irq, pm8001_interrupt_handler_intx,IRQF_SHARED , -DRV_NAME ,SHOST_TO_SAS_HA (pm8001_ha->shost)); + pm8001_ha->name,SHOST_TO_SAS_HA (pm8001_ha->shost));return rc; }
drivers/scsi/pm8001/pm8001_sas.h +2 -0
@@ -541,6 +541,8 @@ struct pm8001_hba_info {struct pm8001_ccb_info *ccb_info;#ifdef PM8001_USE_MSIX int number_of_intr;/*will be used in remove()*/ +char intr_drvname[PM8001_MAX_MSIX_VEC ] + [PM8001_NAME_LENGTH +1 +3 +1 ];#endif #ifdef PM8001_USE_TASKLET struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC ];
Signature · 1 line
2.16.3
Re: [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance.
Quoted 10 lines · Deepak Ukey
From: Vikram Auradkar <[email protected]>
With msix enabled, the interrupt instances are <prefix><index> where the prefix is fixed for all module instances, making it a little harder to track down what's what.
Signed-off-by Vikram Auradkar <[email protected]>Signed-off-by Deepak Ukey <[email protected]>Signed-off-by Viswas G <[email protected]>
Looks fine.
Quoted 62 lines
--- drivers/scsi/pm8001/pm8001_init.c | 11 ++++++----- drivers/scsi/pm8001/pm8001_sas.h | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-)drivers/scsi/pm8001/pm8001_init.c +6
-5@@ -894,7 +894,6 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)u32 number_of_intr;int flag =0 ;int rc; -static char intr_drvname[PM8001_MAX_MSIX_VEC ][sizeof (DRV_NAME )+3 ];/* SPCv controllers supports 64 msi-x */ if (pm8001_ha->chip_id == chip_8001) {@@ -915,14 +914,16 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha) rc, pm8001_ha->number_of_intr));for (i =0 ; i < number_of_intr; i++) { -snprintf (intr_drvname[i],sizeof (intr_drvname[0 ]), -DRV_NAME "%d" , i); +snprintf (pm8001_ha->intr_drvname[i], +sizeof (pm8001_ha->intr_drvname[0 ]), +"%s-%d" , pm8001_ha->name, i); pm8001_ha->irq_vector[i].irq_id = i; pm8001_ha->irq_vector[i].drv_inst = pm8001_ha; rc =request_irq (pci_irq_vector (pm8001_ha->pdev, i), pm8001_interrupt_handler_msix, flag, - intr_drvname[i], &(pm8001_ha->irq_vector[i])); + pm8001_ha->intr_drvname[i], + &(pm8001_ha->irq_vector[i]));if (rc) {for (j =0 ; j < i; j++) { free_irq(pci_irq_vector(pm8001_ha->pdev, i),@@ -963,7 +964,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) pm8001_ha->irq_vector[0 ].irq_id =0 ; pm8001_ha->irq_vector[0 ].drv_inst = pm8001_ha; rc =request_irq (pdev->irq, pm8001_interrupt_handler_intx,IRQF_SHARED , -DRV_NAME ,SHOST_TO_SAS_HA (pm8001_ha->shost)); + pm8001_ha->name,SHOST_TO_SAS_HA (pm8001_ha->shost));return rc; }drivers/scsi/pm8001/pm8001_sas.h +2
-1@@ -541,6 +541,8 @@ struct pm8001_hba_info {struct pm8001_ccb_info *ccb_info;#ifdef PM8001_USE_MSIX int number_of_intr;/*will be used in remove()*/ +char intr_drvname[PM8001_MAX_MSIX_VEC ] + [PM8001_NAME_LENGTH +1 +3 +1 ];#endif #ifdef PM8001_USE_TASKLET struct tasklet_struct tasklet[PM8001_MAX_MSIX_VEC ]; --2.16.3
PATCH 12/12 pm80xx : Modified the logic to collect fatal dump.
In reply to Deepak UkeyFrom: Deepak Ukey <[email protected]>
Added the correct method to collect the fatal dump.
--- drivers/scsi/pm8001/pm8001_sas.h | 3 + drivers/scsi/pm8001/pm80xx_hwi.c | 247 +++++++++++++++++++++++++++++---------- 2 files changed, 191 insertions(+), 59 deletions(-)
drivers/scsi/pm8001/pm8001_sas.h +3 -0
@@ -152,6 +152,8 @@ struct pm8001_ioctl_payload {#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_TABLE_TOTAL_LEN 0x18/* TOTALLEN */ +#define MPI_FATAL_EDUMP_TABLE_SIGNATURE 0x1C/* SIGNITURE */ #define MPI_FATAL_EDUMP_HANDSHAKE_RDY 0x1#define MPI_FATAL_EDUMP_HANDSHAKE_BUSY 0x0#define MPI_FATAL_EDUMP_TABLE_STAT_RSVD 0x0
@@ -507,6 +509,7 @@ struct pm8001_hba_info {u32 forensic_last_offset;u32 fatal_forensic_shift_offset;u32 forensic_fatal_step; +u32 forensic_preserved_accumulated_transfer;u32 evtlog_ib_offset;u32 evtlog_ob_offset;void __iomem *msg_unit_tbl_addr;/*Message Unit Table Addr*/
drivers/scsi/pm8001/pm80xx_hwi.c +188 -59
346 lines not on this page · raw message
Signature · 1 line
2.16.3
kbuild test robot
build botRe: [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump.
Thank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[cannot apply to v5.4-rc5 next-20191031]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20191102-082024 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: mips-allmodconfig (attached as .config) compiler: mips-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=mips
If you fix the issue, kindly add following tag
All warnings (new ones prefixed by >>):
In file included from drivers/scsi/pm8001/pm80xx_hwi.c:42:0:
drivers/scsi/pm8001/pm80xx_hwi.c: In function 'pm80xx_get_fatal_dump':
>> include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
drivers/scsi/pm8001/pm8001_sas.h:78:4: note: in definition of macro 'PM8001_CHECK_LOGGING'
CMD; \
^~~
>> drivers/scsi/pm8001/pm80xx_hwi.c:239:4: note: in expansion of macro 'PM8001_IO_DBG'
PM8001_IO_DBG(pm8001_ha,
^~~~~~~~~~~~~
include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
#define KERN_INFO KERN_SOH "6" /* informational */
^~~~~~~~
include/linux/printk.h:311:9: note: in expansion of macro 'KERN_INFO'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~
>> drivers/scsi/pm8001/pm8001_sas.h:72:39: note: in expansion of macro 'pr_info'
#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \
^~~~~~~
>> drivers/scsi/pm8001/pm80xx_hwi.c:240:4: note: in expansion of macro 'pm8001_printk'
pm8001_printk("get_fatal_spcv: return1 0x%lx\n",
^~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:240:47: note: format string is defined here
pm8001_printk("get_fatal_spcv: return1 0x%lx\n",
~~^
%x
In file included from drivers/scsi/pm8001/pm80xx_hwi.c:42:0:
>> include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
drivers/scsi/pm8001/pm8001_sas.h:78:4: note: in definition of macro 'PM8001_CHECK_LOGGING'
CMD; \
^~~
drivers/scsi/pm8001/pm80xx_hwi.c:261:4: note: in expansion of macro 'PM8001_IO_DBG'
PM8001_IO_DBG(pm8001_ha,
^~~~~~~~~~~~~
include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
#define KERN_INFO KERN_SOH "6" /* informational */
^~~~~~~~
include/linux/printk.h:311:9: note: in expansion of macro 'KERN_INFO'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~
>> drivers/scsi/pm8001/pm8001_sas.h:72:39: note: in expansion of macro 'pr_info'
#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \
^~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:262:4: note: in expansion of macro 'pm8001_printk'
pm8001_printk("get_fatal_spcv: return2 0x%lx\n",
^~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:262:47: note: format string is defined here
pm8001_printk("get_fatal_spcv: return2 0x%lx\n",
~~^
%x
In file included from drivers/scsi/pm8001/pm80xx_hwi.c:42:0:
>> include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
drivers/scsi/pm8001/pm8001_sas.h:78:4: note: in definition of macro 'PM8001_CHECK_LOGGING'
CMD; \
^~~
drivers/scsi/pm8001/pm80xx_hwi.c:287:3: note: in expansion of macro 'PM8001_IO_DBG'
PM8001_IO_DBG(pm8001_ha,
^~~~~~~~~~~~~
include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
#define KERN_INFO KERN_SOH "6" /* informational */
^~~~~~~~
include/linux/printk.h:311:9: note: in expansion of macro 'KERN_INFO'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~
>> drivers/scsi/pm8001/pm8001_sas.h:72:39: note: in expansion of macro 'pr_info'
#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \
^~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:288:3: note: in expansion of macro 'pm8001_printk'
pm8001_printk("get_fatal_spcv: return3 0x%lx\n",
^~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:288:46: note: format string is defined here
pm8001_printk("get_fatal_spcv: return3 0x%lx\n",
~~^
%x
In file included from drivers/scsi/pm8001/pm80xx_hwi.c:42:0:
>> include/linux/kern_levels.h:5:18: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
#define KERN_SOH "\001" /* ASCII Start Of Header */
^
drivers/scsi/pm8001/pm8001_sas.h:78:4: note: in definition of macro 'PM8001_CHECK_LOGGING'
CMD; \
^~~
drivers/scsi/pm8001/pm80xx_hwi.c:385:2: note: in expansion of macro 'PM8001_IO_DBG'
PM8001_IO_DBG(pm8001_ha,
^~~~~~~~~~~~~
include/linux/kern_levels.h:14:19: note: in expansion of macro 'KERN_SOH'
#define KERN_INFO KERN_SOH "6" /* informational */
^~~~~~~~
include/linux/printk.h:311:9: note: in expansion of macro 'KERN_INFO'
printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~
>> drivers/scsi/pm8001/pm8001_sas.h:72:39: note: in expansion of macro 'pr_info'
#define pm8001_printk(format, arg...) pr_info("%s:: %s %d:" \
^~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:386:3: note: in expansion of macro 'pm8001_printk'
pm8001_printk("get_fatal_spcv: return4 0x%lx\n",
^~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:386:46: note: format string is defined here
pm8001_printk("get_fatal_spcv: return4 0x%lx\n",
~~^
%xvim +/PM8001_IO_DBG +239 drivers/scsi/pm8001/pm80xx_hwi.c
> 42 #include "pm8001_sas.h"
43 #include "pm80xx_hwi.h"
44 #include "pm8001_chips.h"
45 #include "pm8001_ctl.h"
46
47 #define SMP_DIRECT 1
48 #define SMP_INDIRECT 2
49
50
51 int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
52 {
53 u32 reg_val;
54 unsigned long start;
55 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER, shift_value);
56 /* confirm the setting is written */
57 start = jiffies + HZ; /* 1 sec */
58 do {
59 reg_val = pm8001_cr32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER);
60 } while ((reg_val != shift_value) && time_before(jiffies, start));
61 if (reg_val != shift_value) {
62 PM8001_FAIL_DBG(pm8001_ha,
63 pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
64 " = 0x%x\n", reg_val));
65 return -1;
66 }
67 return 0;
68 }
69
70 void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
71 const void *destination,
72 u32 dw_count, u32 bus_base_number)
73 {
74 u32 index, value, offset;
75 u32 *destination1;
76 destination1 = (u32 *)destination;
77
78 for (index = 0; index < dw_count; index += 4, destination1++) {
79 offset = (soffset + index);
80 if (offset < (64 * 1024)) {
81 value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
82 *destination1 = cpu_to_le32(value);
83 }
84 }
85 return;
86 }
87
88 ssize_t pm80xx_get_fatal_dump(struct device *cdev,
89 struct device_attribute *attr, char *buf)
90 {
91 struct Scsi_Host *shost = class_to_shost(cdev);
92 struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
93 struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
94 void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr;
95 u32 accum_len , reg_val, index, *temp;
96 u32 status = 1;
97 unsigned long start;
98 u8 *direct_data;
99 char *fatal_error_data = buf;
100 u32 length_to_read;
101
102 pm8001_ha->forensic_info.data_buf.direct_data = buf;
103 if (pm8001_ha->chip_id == chip_8001) {
104 pm8001_ha->forensic_info.data_buf.direct_data +=
105 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
106 "Not supported for SPC controller");
107 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
108 (char *)buf;
109 }
110 /* initialize variables for very first call from host application */
111 if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
112 PM8001_IO_DBG(pm8001_ha,
113 pm8001_printk("forensic_info TYPE_NON_FATAL..............\n"));
114 direct_data = (u8 *)fatal_error_data;
115 pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL;
116 pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET;
117 pm8001_ha->forensic_info.data_buf.direct_offset = 0;
118 pm8001_ha->forensic_info.data_buf.read_len = 0;
119 pm8001_ha->forensic_preserved_accumulated_transfer = 0;
120
121 /* Write signature to fatal dump table */
122 pm8001_mw32(fatal_table_address,
123 MPI_FATAL_EDUMP_TABLE_SIGNATURE, 0x1234abcd);
124
125 pm8001_ha->forensic_info.data_buf.direct_data = direct_data;
126 PM8001_IO_DBG(pm8001_ha,
127 pm8001_printk("ossaHwCB: status1 %d\n", status));
128 PM8001_IO_DBG(pm8001_ha,
129 pm8001_printk("ossaHwCB: read_len 0x%x\n",
130 pm8001_ha->forensic_info.data_buf.read_len));
131 PM8001_IO_DBG(pm8001_ha,
132 pm8001_printk("ossaHwCB: direct_len 0x%x\n",
133 pm8001_ha->forensic_info.data_buf.direct_len));
134 PM8001_IO_DBG(pm8001_ha,
135 pm8001_printk("ossaHwCB: direct_offset 0x%x\n",
136 pm8001_ha->forensic_info.data_buf.direct_offset));
137 }
138 if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
139 /* start to get data */
140 /* Program the MEMBASE II Shifting Register with 0x00.*/
141 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
142 pm8001_ha->fatal_forensic_shift_offset);
143 pm8001_ha->forensic_last_offset = 0;
144 pm8001_ha->forensic_fatal_step = 0;
145 pm8001_ha->fatal_bar_loc = 0;
146 }
147
148 /* Read until accum_len is retrived */
149 accum_len = pm8001_mr32(fatal_table_address,
150 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
151 /* Determine length of data between previously stored transfer length
152 * and current accumulated transfer length
153 */
154 length_to_read =
155 accum_len - pm8001_ha->forensic_preserved_accumulated_transfer;
156 PM8001_IO_DBG(pm8001_ha,
157 pm8001_printk("get_fatal_spcv: accum_len 0x%x\n", accum_len));
158 PM8001_IO_DBG(pm8001_ha,
159 pm8001_printk("get_fatal_spcv: length_to_read 0x%x\n",
160 length_to_read));
161 PM8001_IO_DBG(pm8001_ha,
162 pm8001_printk("get_fatal_spcv: last_offset 0x%x\n",
163 pm8001_ha->forensic_last_offset));
164 PM8001_IO_DBG(pm8001_ha,
165 pm8001_printk("get_fatal_spcv: read_len 0x%x\n",
166 pm8001_ha->forensic_info.data_buf.read_len));
167 PM8001_IO_DBG(pm8001_ha,
168 pm8001_printk("get_fatal_spcv:: direct_len 0x%x\n",
169 pm8001_ha->forensic_info.data_buf.direct_len));
170 PM8001_IO_DBG(pm8001_ha,
171 pm8001_printk("get_fatal_spcv:: direct_offset 0x%x\n",
172 pm8001_ha->forensic_info.data_buf.direct_offset));
173
174 /* If accumulated length failed to read correctly fail the attempt.*/
175 if (accum_len == 0xFFFFFFFF) {
176 PM8001_IO_DBG(pm8001_ha,
177 pm8001_printk("Possible PCI issue 0x%x not expected\n",
178 accum_len));
179 return status;
180 }
181 /* If accumulated length is zero fail the attempt */
182 if (accum_len == 0) {
183 pm8001_ha->forensic_info.data_buf.direct_data +=
184 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
185 "%08x ", 0xFFFFFFFF);
186 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
187 (char *)buf;
188 }
189 /* Accumulated length is good so start capturing the first data */
190 temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
191 if (pm8001_ha->forensic_fatal_step == 0) {
192 moreData:
193 /* If data to read is less than SYSFS_OFFSET then reduce the
194 * length of dataLen
195 */
196 if (pm8001_ha->forensic_last_offset + SYSFS_OFFSET
197 > length_to_read) {
198 pm8001_ha->forensic_info.data_buf.direct_len =
199 length_to_read -
200 pm8001_ha->forensic_last_offset;
201 } else {
202 pm8001_ha->forensic_info.data_buf.direct_len =
203 SYSFS_OFFSET;
204 }
205 if (pm8001_ha->forensic_info.data_buf.direct_data) {
206 /* Data is in bar, copy to host memory */
207 pm80xx_pci_mem_copy(pm8001_ha,
208 pm8001_ha->fatal_bar_loc,
209 pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
210 pm8001_ha->forensic_info.data_buf.direct_len, 1);
211 }
212 pm8001_ha->fatal_bar_loc +=
213 pm8001_ha->forensic_info.data_buf.direct_len;
214 pm8001_ha->forensic_info.data_buf.direct_offset +=
215 pm8001_ha->forensic_info.data_buf.direct_len;
216 pm8001_ha->forensic_last_offset +=
217 pm8001_ha->forensic_info.data_buf.direct_len;
218 pm8001_ha->forensic_info.data_buf.read_len =
219 pm8001_ha->forensic_info.data_buf.direct_len;
220
221 if (pm8001_ha->forensic_last_offset >= length_to_read) {
222 pm8001_ha->forensic_info.data_buf.direct_data +=
223 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
224 "%08x ", 3);
225 for (index = 0; index <
226 (pm8001_ha->forensic_info.data_buf.direct_len
227 / 4); index++) {
228 pm8001_ha->forensic_info.data_buf.direct_data +=
229 sprintf(
230 pm8001_ha->forensic_info.data_buf.direct_data,
231 "%08x ", *(temp + index));
232 }
233
234 pm8001_ha->fatal_bar_loc = 0;
235 pm8001_ha->forensic_fatal_step = 1;
236 pm8001_ha->fatal_forensic_shift_offset = 0;
237 pm8001_ha->forensic_last_offset = 0;
238 status = 0;
> 239 PM8001_IO_DBG(pm8001_ha,
> 240 pm8001_printk("get_fatal_spcv: return1 0x%lx\n", 241 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
242 - (char *)buf)));
243 return (char *)pm8001_ha->
244 forensic_info.data_buf.direct_data -
245 (char *)buf;
246 }
247 if (pm8001_ha->fatal_bar_loc < (64 * 1024)) {
248 pm8001_ha->forensic_info.data_buf.direct_data +=
249 sprintf(pm8001_ha->
250 forensic_info.data_buf.direct_data,
251 "%08x ", 2);
252 for (index = 0; index <
253 (pm8001_ha->forensic_info.data_buf.direct_len
254 / 4); index++) {
255 pm8001_ha->forensic_info.data_buf.direct_data
256 += sprintf(pm8001_ha->
257 forensic_info.data_buf.direct_data,
258 "%08x ", *(temp + index));
259 }
260 status = 0;
261 PM8001_IO_DBG(pm8001_ha,
262 pm8001_printk("get_fatal_spcv: return2 0x%lx\n",
263 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
264 - (char *)buf)));
265 return (char *)pm8001_ha->
266 forensic_info.data_buf.direct_data -
267 (char *)buf;
268 }
269
270 /* Increment the MEMBASE II Shifting Register value by 0x100.*/
271 pm8001_ha->forensic_info.data_buf.direct_data +=
272 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
273 "%08x ", 2);
274 for (index = 0; index <
275 (pm8001_ha->forensic_info.data_buf.direct_len
276 / 4) ; index++) {
277 pm8001_ha->forensic_info.data_buf.direct_data +=
278 sprintf(pm8001_ha->
279 forensic_info.data_buf.direct_data,
280 "%08x ", *(temp + index));
281 }
282 pm8001_ha->fatal_forensic_shift_offset += 0x100;
283 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
284 pm8001_ha->fatal_forensic_shift_offset);
285 pm8001_ha->fatal_bar_loc = 0;
286 status = 0;
287 PM8001_IO_DBG(pm8001_ha,
288 pm8001_printk("get_fatal_spcv: return3 0x%lx\n",
289 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
290 - (char *)buf)));
291 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
292 (char *)buf;
293 }
294 if (pm8001_ha->forensic_fatal_step == 1) {
295 /* store previous accumulated length before triggering next
296 * accumulated length update
297 */
298 pm8001_ha->forensic_preserved_accumulated_transfer =
299 pm8001_mr32(fatal_table_address,
300 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
301
302 /* continue capturing the fatal log until Dump status is 0x3 */
303 if (pm8001_mr32(fatal_table_address,
304 MPI_FATAL_EDUMP_TABLE_STATUS) <
305 MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
306
307 /* reset fddstat bit by writing to zero*/
308 pm8001_mw32(fatal_table_address,
309 MPI_FATAL_EDUMP_TABLE_STATUS, 0x0);
310
311 /* set dump control value to '1' so that new data will
312 * be transferred to shared memory
313 */
314 pm8001_mw32(fatal_table_address,
315 MPI_FATAL_EDUMP_TABLE_HANDSHAKE,
316 MPI_FATAL_EDUMP_HANDSHAKE_RDY);
317
318 /*Poll FDDHSHK until clear */
319 start = jiffies + (2 * HZ); /* 2 sec */
320
321 do {
322 reg_val = pm8001_mr32(fatal_table_address,
323 MPI_FATAL_EDUMP_TABLE_HANDSHAKE);
324 } while ((reg_val) && time_before(jiffies, start));
325
326 if (reg_val != 0) {
327 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
328 "TIMEOUT:MPI_FATAL_EDUMP_TABLE_HDSHAKE 0x%x\n",
329 reg_val));
330 /* Fail the dump if a timeout occurs */
331 pm8001_ha->forensic_info.data_buf.direct_data +=
332 sprintf(
333 pm8001_ha->forensic_info.data_buf.direct_data,
334 "%08x ", 0xFFFFFFFF);
335 return((char *)
336 pm8001_ha->forensic_info.data_buf.direct_data
337 - (char *)buf);
338 }
339 /* Poll status register until set to 2 or
340 * 3 for up to 2 seconds
341 */
342 start = jiffies + (2 * HZ); /* 2 sec */
343
344 do {
345 reg_val = pm8001_mr32(fatal_table_address,
346 MPI_FATAL_EDUMP_TABLE_STATUS);
347 } while (((reg_val != 2) || (reg_val != 3)) &&
348 time_before(jiffies, start));
349
350 if (reg_val < 2) {
351 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
352 "TIMEOUT:MPI_FATAL_EDUMP_TABLE_STATUS = 0x%x\n",
353 reg_val));
354 /* Fail the dump if a timeout occurs */
355 pm8001_ha->forensic_info.data_buf.direct_data +=
356 sprintf(
357 pm8001_ha->forensic_info.data_buf.direct_data,
358 "%08x ", 0xFFFFFFFF);
359 pm8001_cw32(pm8001_ha, 0,
360 MEMBASE_II_SHIFT_REGISTER,
361 pm8001_ha->fatal_forensic_shift_offset);
362 }
363 /* Read the next block of the debug data.*/
364 length_to_read = pm8001_mr32(fatal_table_address,
365 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -
366 pm8001_ha->forensic_preserved_accumulated_transfer;
367 if (length_to_read != 0x0) {
368 pm8001_ha->forensic_fatal_step = 0;
369 goto moreData;
370 } else {
371 pm8001_ha->forensic_info.data_buf.direct_data +=
372 sprintf(
373 pm8001_ha->forensic_info.data_buf.direct_data,
374 "%08x ", 4);
375 pm8001_ha->forensic_info.data_buf.read_len
376 = 0xFFFFFFFF;
377 pm8001_ha->forensic_info.data_buf.direct_len
378 = 0;
379 pm8001_ha->forensic_info.data_buf.direct_offset
380 = 0;
381 pm8001_ha->forensic_info.data_buf.read_len = 0;
382 }
383 }
384 }
385 PM8001_IO_DBG(pm8001_ha,
386 pm8001_printk("get_fatal_spcv: return4 0x%lx\n",
387 ((char *)pm8001_ha->forensic_info.data_buf.direct_data -
388 (char *)buf)));
389 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
390 (char *)buf;
391 }
392
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
kbuild test robot
build botRe: [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump.
In reply to Deepak UkeyThank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[cannot apply to v5.4-rc6 next-20191105]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20191102-082024 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: i386-randconfig-a004-201944 (attached as .config) compiler: gcc-4.9 (Debian 4.9.2-10+deb8u1) 4.9.2 reproduce: # save the attached .config to linux build tree make ARCH=i386
If you fix the issue, kindly add following tag
All warnings (new ones prefixed by >>):
drivers/scsi/pm8001/pm80xx_hwi.c: In function 'pm80xx_get_fatal_dump':
>> drivers/scsi/pm8001/pm80xx_hwi.c:239:4: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
PM8001_IO_DBG(pm8001_ha,
^
drivers/scsi/pm8001/pm80xx_hwi.c:261:4: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
PM8001_IO_DBG(pm8001_ha,
^
drivers/scsi/pm8001/pm80xx_hwi.c:287:3: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
PM8001_IO_DBG(pm8001_ha,
^
drivers/scsi/pm8001/pm80xx_hwi.c:385:2: warning: format '%lx' expects argument of type 'long unsigned int', but argument 5 has type 'int' [-Wformat=]
PM8001_IO_DBG(pm8001_ha,
^vim +239 drivers/scsi/pm8001/pm80xx_hwi.c
87
88 ssize_t pm80xx_get_fatal_dump(struct device *cdev,
89 struct device_attribute *attr, char *buf)
90 {
91 struct Scsi_Host *shost = class_to_shost(cdev);
92 struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
93 struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
94 void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr;
95 u32 accum_len , reg_val, index, *temp;
96 u32 status = 1;
97 unsigned long start;
98 u8 *direct_data;
99 char *fatal_error_data = buf;
100 u32 length_to_read;
101
102 pm8001_ha->forensic_info.data_buf.direct_data = buf;
103 if (pm8001_ha->chip_id == chip_8001) {
104 pm8001_ha->forensic_info.data_buf.direct_data +=
105 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
106 "Not supported for SPC controller");
107 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
108 (char *)buf;
109 }
110 /* initialize variables for very first call from host application */
111 if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
112 PM8001_IO_DBG(pm8001_ha,
113 pm8001_printk("forensic_info TYPE_NON_FATAL..............\n"));
114 direct_data = (u8 *)fatal_error_data;
115 pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL;
116 pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET;
117 pm8001_ha->forensic_info.data_buf.direct_offset = 0;
118 pm8001_ha->forensic_info.data_buf.read_len = 0;
119 pm8001_ha->forensic_preserved_accumulated_transfer = 0;
120
121 /* Write signature to fatal dump table */
122 pm8001_mw32(fatal_table_address,
123 MPI_FATAL_EDUMP_TABLE_SIGNATURE, 0x1234abcd);
124
125 pm8001_ha->forensic_info.data_buf.direct_data = direct_data;
126 PM8001_IO_DBG(pm8001_ha,
127 pm8001_printk("ossaHwCB: status1 %d\n", status));
128 PM8001_IO_DBG(pm8001_ha,
129 pm8001_printk("ossaHwCB: read_len 0x%x\n",
130 pm8001_ha->forensic_info.data_buf.read_len));
131 PM8001_IO_DBG(pm8001_ha,
132 pm8001_printk("ossaHwCB: direct_len 0x%x\n",
133 pm8001_ha->forensic_info.data_buf.direct_len));
134 PM8001_IO_DBG(pm8001_ha,
135 pm8001_printk("ossaHwCB: direct_offset 0x%x\n",
136 pm8001_ha->forensic_info.data_buf.direct_offset));
137 }
138 if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
139 /* start to get data */
140 /* Program the MEMBASE II Shifting Register with 0x00.*/
141 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
142 pm8001_ha->fatal_forensic_shift_offset);
143 pm8001_ha->forensic_last_offset = 0;
144 pm8001_ha->forensic_fatal_step = 0;
145 pm8001_ha->fatal_bar_loc = 0;
146 }
147
148 /* Read until accum_len is retrived */
149 accum_len = pm8001_mr32(fatal_table_address,
150 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
151 /* Determine length of data between previously stored transfer length
152 * and current accumulated transfer length
153 */
154 length_to_read =
155 accum_len - pm8001_ha->forensic_preserved_accumulated_transfer;
156 PM8001_IO_DBG(pm8001_ha,
157 pm8001_printk("get_fatal_spcv: accum_len 0x%x\n", accum_len));
158 PM8001_IO_DBG(pm8001_ha,
159 pm8001_printk("get_fatal_spcv: length_to_read 0x%x\n",
160 length_to_read));
161 PM8001_IO_DBG(pm8001_ha,
162 pm8001_printk("get_fatal_spcv: last_offset 0x%x\n",
163 pm8001_ha->forensic_last_offset));
164 PM8001_IO_DBG(pm8001_ha,
165 pm8001_printk("get_fatal_spcv: read_len 0x%x\n",
166 pm8001_ha->forensic_info.data_buf.read_len));
167 PM8001_IO_DBG(pm8001_ha,
168 pm8001_printk("get_fatal_spcv:: direct_len 0x%x\n",
169 pm8001_ha->forensic_info.data_buf.direct_len));
170 PM8001_IO_DBG(pm8001_ha,
171 pm8001_printk("get_fatal_spcv:: direct_offset 0x%x\n",
172 pm8001_ha->forensic_info.data_buf.direct_offset));
173
174 /* If accumulated length failed to read correctly fail the attempt.*/
175 if (accum_len == 0xFFFFFFFF) {
176 PM8001_IO_DBG(pm8001_ha,
177 pm8001_printk("Possible PCI issue 0x%x not expected\n",
178 accum_len));
179 return status;
180 }
181 /* If accumulated length is zero fail the attempt */
182 if (accum_len == 0) {
183 pm8001_ha->forensic_info.data_buf.direct_data +=
184 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
185 "%08x ", 0xFFFFFFFF);
186 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
187 (char *)buf;
188 }
189 /* Accumulated length is good so start capturing the first data */
190 temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
191 if (pm8001_ha->forensic_fatal_step == 0) {
192 moreData:
193 /* If data to read is less than SYSFS_OFFSET then reduce the
194 * length of dataLen
195 */
196 if (pm8001_ha->forensic_last_offset + SYSFS_OFFSET
197 > length_to_read) {
198 pm8001_ha->forensic_info.data_buf.direct_len =
199 length_to_read -
200 pm8001_ha->forensic_last_offset;
201 } else {
202 pm8001_ha->forensic_info.data_buf.direct_len =
203 SYSFS_OFFSET;
204 }
205 if (pm8001_ha->forensic_info.data_buf.direct_data) {
206 /* Data is in bar, copy to host memory */
207 pm80xx_pci_mem_copy(pm8001_ha,
208 pm8001_ha->fatal_bar_loc,
209 pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
210 pm8001_ha->forensic_info.data_buf.direct_len, 1);
211 }
212 pm8001_ha->fatal_bar_loc +=
213 pm8001_ha->forensic_info.data_buf.direct_len;
214 pm8001_ha->forensic_info.data_buf.direct_offset +=
215 pm8001_ha->forensic_info.data_buf.direct_len;
216 pm8001_ha->forensic_last_offset +=
217 pm8001_ha->forensic_info.data_buf.direct_len;
218 pm8001_ha->forensic_info.data_buf.read_len =
219 pm8001_ha->forensic_info.data_buf.direct_len;
220
221 if (pm8001_ha->forensic_last_offset >= length_to_read) {
222 pm8001_ha->forensic_info.data_buf.direct_data +=
223 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
224 "%08x ", 3);
225 for (index = 0; index <
226 (pm8001_ha->forensic_info.data_buf.direct_len
227 / 4); index++) {
228 pm8001_ha->forensic_info.data_buf.direct_data +=
229 sprintf(
230 pm8001_ha->forensic_info.data_buf.direct_data,
231 "%08x ", *(temp + index));
232 }
233
234 pm8001_ha->fatal_bar_loc = 0;
235 pm8001_ha->forensic_fatal_step = 1;
236 pm8001_ha->fatal_forensic_shift_offset = 0;
237 pm8001_ha->forensic_last_offset = 0;
238 status = 0;
> 239 PM8001_IO_DBG(pm8001_ha, 240 pm8001_printk("get_fatal_spcv: return1 0x%lx\n",
241 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
242 - (char *)buf)));
243 return (char *)pm8001_ha->
244 forensic_info.data_buf.direct_data -
245 (char *)buf;
246 }
247 if (pm8001_ha->fatal_bar_loc < (64 * 1024)) {
248 pm8001_ha->forensic_info.data_buf.direct_data +=
249 sprintf(pm8001_ha->
250 forensic_info.data_buf.direct_data,
251 "%08x ", 2);
252 for (index = 0; index <
253 (pm8001_ha->forensic_info.data_buf.direct_len
254 / 4); index++) {
255 pm8001_ha->forensic_info.data_buf.direct_data
256 += sprintf(pm8001_ha->
257 forensic_info.data_buf.direct_data,
258 "%08x ", *(temp + index));
259 }
260 status = 0;
261 PM8001_IO_DBG(pm8001_ha,
262 pm8001_printk("get_fatal_spcv: return2 0x%lx\n",
263 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
264 - (char *)buf)));
265 return (char *)pm8001_ha->
266 forensic_info.data_buf.direct_data -
267 (char *)buf;
268 }
269
270 /* Increment the MEMBASE II Shifting Register value by 0x100.*/
271 pm8001_ha->forensic_info.data_buf.direct_data +=
272 sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
273 "%08x ", 2);
274 for (index = 0; index <
275 (pm8001_ha->forensic_info.data_buf.direct_len
276 / 4) ; index++) {
277 pm8001_ha->forensic_info.data_buf.direct_data +=
278 sprintf(pm8001_ha->
279 forensic_info.data_buf.direct_data,
280 "%08x ", *(temp + index));
281 }
282 pm8001_ha->fatal_forensic_shift_offset += 0x100;
283 pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
284 pm8001_ha->fatal_forensic_shift_offset);
285 pm8001_ha->fatal_bar_loc = 0;
286 status = 0;
287 PM8001_IO_DBG(pm8001_ha,
288 pm8001_printk("get_fatal_spcv: return3 0x%lx\n",
289 ((char *)pm8001_ha->forensic_info.data_buf.direct_data
290 - (char *)buf)));
291 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
292 (char *)buf;
293 }
294 if (pm8001_ha->forensic_fatal_step == 1) {
295 /* store previous accumulated length before triggering next
296 * accumulated length update
297 */
298 pm8001_ha->forensic_preserved_accumulated_transfer =
299 pm8001_mr32(fatal_table_address,
300 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
301
302 /* continue capturing the fatal log until Dump status is 0x3 */
303 if (pm8001_mr32(fatal_table_address,
304 MPI_FATAL_EDUMP_TABLE_STATUS) <
305 MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
306
307 /* reset fddstat bit by writing to zero*/
308 pm8001_mw32(fatal_table_address,
309 MPI_FATAL_EDUMP_TABLE_STATUS, 0x0);
310
311 /* set dump control value to '1' so that new data will
312 * be transferred to shared memory
313 */
314 pm8001_mw32(fatal_table_address,
315 MPI_FATAL_EDUMP_TABLE_HANDSHAKE,
316 MPI_FATAL_EDUMP_HANDSHAKE_RDY);
317
318 /*Poll FDDHSHK until clear */
319 start = jiffies + (2 * HZ); /* 2 sec */
320
321 do {
322 reg_val = pm8001_mr32(fatal_table_address,
323 MPI_FATAL_EDUMP_TABLE_HANDSHAKE);
324 } while ((reg_val) && time_before(jiffies, start));
325
326 if (reg_val != 0) {
327 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
328 "TIMEOUT:MPI_FATAL_EDUMP_TABLE_HDSHAKE 0x%x\n",
329 reg_val));
330 /* Fail the dump if a timeout occurs */
331 pm8001_ha->forensic_info.data_buf.direct_data +=
332 sprintf(
333 pm8001_ha->forensic_info.data_buf.direct_data,
334 "%08x ", 0xFFFFFFFF);
335 return((char *)
336 pm8001_ha->forensic_info.data_buf.direct_data
337 - (char *)buf);
338 }
339 /* Poll status register until set to 2 or
340 * 3 for up to 2 seconds
341 */
342 start = jiffies + (2 * HZ); /* 2 sec */
343
344 do {
345 reg_val = pm8001_mr32(fatal_table_address,
346 MPI_FATAL_EDUMP_TABLE_STATUS);
347 } while (((reg_val != 2) || (reg_val != 3)) &&
348 time_before(jiffies, start));
349
350 if (reg_val < 2) {
351 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
352 "TIMEOUT:MPI_FATAL_EDUMP_TABLE_STATUS = 0x%x\n",
353 reg_val));
354 /* Fail the dump if a timeout occurs */
355 pm8001_ha->forensic_info.data_buf.direct_data +=
356 sprintf(
357 pm8001_ha->forensic_info.data_buf.direct_data,
358 "%08x ", 0xFFFFFFFF);
359 pm8001_cw32(pm8001_ha, 0,
360 MEMBASE_II_SHIFT_REGISTER,
361 pm8001_ha->fatal_forensic_shift_offset);
362 }
363 /* Read the next block of the debug data.*/
364 length_to_read = pm8001_mr32(fatal_table_address,
365 MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -
366 pm8001_ha->forensic_preserved_accumulated_transfer;
367 if (length_to_read != 0x0) {
368 pm8001_ha->forensic_fatal_step = 0;
369 goto moreData;
370 } else {
371 pm8001_ha->forensic_info.data_buf.direct_data +=
372 sprintf(
373 pm8001_ha->forensic_info.data_buf.direct_data,
374 "%08x ", 4);
375 pm8001_ha->forensic_info.data_buf.read_len
376 = 0xFFFFFFFF;
377 pm8001_ha->forensic_info.data_buf.direct_len
378 = 0;
379 pm8001_ha->forensic_info.data_buf.direct_offset
380 = 0;
381 pm8001_ha->forensic_info.data_buf.read_len = 0;
382 }
383 }
384 }
385 PM8001_IO_DBG(pm8001_ha,
386 pm8001_printk("get_fatal_spcv: return4 0x%lx\n",
387 ((char *)pm8001_ha->forensic_info.data_buf.direct_data -
388 (char *)buf)));
389 return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
390 (char *)buf;
391 }
392
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org Intel Corporation