linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39.
@ 2019-10-31  5:12 Deepak Ukey
  2019-10-31  5:12 ` [PATCH 01/12] pm80xx : Fix for SATA device discovery Deepak Ukey
                   ` (11 more replies)
  0 siblings, 12 replies; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Deepak Ukey <Deepak.Ukey@microchip.com>

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(-)

-- 
2.16.3


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/12] pm80xx : Fix for SATA device discovery.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-01  9:16   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 02/12] pm80xx : Initialize variable used as return status Deepak Ukey
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: peter chang <dpf@google.com>

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.

Signed-off-by: peter chang <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 73261902d75d..ee9c187d8caa 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 02/12] pm80xx : Initialize variable used as return status.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
  2019-10-31  5:12 ` [PATCH 01/12] pm80xx : Fix for SATA device discovery Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-01  9:17   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep Deepak Ukey
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: John Sperbeck <jsperbeck@google.com>

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 <jsperbeck@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 7e48154e11c3..81160e99c75e 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
  2019-10-31  5:12 ` [PATCH 01/12] pm80xx : Fix for SATA device discovery Deepak Ukey
  2019-10-31  5:12 ` [PATCH 02/12] pm80xx : Initialize variable used as return status Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-01  9:19   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 04/12] pm80xx : Squashed logging cleanup changes Deepak Ukey
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Vikram Auradkar <auradkar@google.com>

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.

Signed-off-by: Vikram Auradkar <auradkar@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index ee9c187d8caa..1a1adda15db8 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 04/12] pm80xx : Squashed logging cleanup changes.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (2 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:22   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check Deepak Ukey
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: peter chang <dpf@google.com>

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.

Signed-off-by: peter chang <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 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(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 68a8217032d0..2c1c722eca17 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -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);
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 3374f553c617..b7cc3d05a3e0 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -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)
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 81160e99c75e..447a66d60275 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -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;
 }
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index ff17c6aff63d..9e0da7bccb45 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -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
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 1a1adda15db8..6057610263c1 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (3 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 04/12] pm80xx : Squashed logging cleanup changes Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:24   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer Deepak Ukey
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: ianyar <ianyar@google.com>

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.

Signed-off-by: ianyar <ianyar@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++--
 drivers/scsi/pm8001/pm80xx_hwi.h | 3 +++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 6057610263c1..9d04e5cfffb4 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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);
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index dc9ab7689060..701951a0f715 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (4 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:28   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 07/12] pm80xx : Fix command issue sizing Deepak Ukey
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Vikram Auradkar <auradkar@google.com>

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.

Signed-off-by: Vikram Auradkar <auradkar@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 447a66d60275..4491de8d40fc 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 07/12] pm80xx : Fix command issue sizing.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (5 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:33   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 08/12] pm80xx : Cleanup command when a reset times out Deepak Ukey
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: peter chang <dpf@google.com>

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.

Signed-off-by: peter chang <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 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(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 2c1c722eca17..1cbcade747fe 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -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;
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 9e0da7bccb45..d64883b80da9 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -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,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 9d04e5cfffb4..09008db2efdc 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 08/12] pm80xx : Cleanup command when a reset times out.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (6 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 07/12] pm80xx : Fix command issue sizing Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:39   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 09/12] pm80xx : Do not request 12G sas speeds Deepak Ukey
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: peter chang <dpf@google.com>

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 <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_sas.c | 50 +++++++++++++++++++++++++++++-----------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index 4491de8d40fc..b562916a3d3d 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -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;
+				}
 			}
 
 			/*
-- 
2.16.3


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 09/12] pm80xx : Do not request 12G sas speeds.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (7 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 08/12] pm80xx : Cleanup command when a reset times out Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:43   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 10/12] pm80xx : Controller fatal error through sysfs Deepak Ukey
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: peter chang <dpf@google.com>

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 <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 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(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index b7cc3d05a3e0..86b619d10392 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -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)
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index d64883b80da9..f7be7b85624e 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -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;
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 09008db2efdc..5ca9732f4704 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (8 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 09/12] pm80xx : Do not request 12G sas speeds Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:49   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance Deepak Ukey
  2019-10-31  5:12 ` [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump Deepak Ukey
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Deepak Ukey <Deepak.Ukey@microchip.com>

Added support to check controller fatal error through sysfs.

Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 6b85016b4db3..fbdd0bf0e1ab 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -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,
-- 
2.16.3


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (9 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 10/12] pm80xx : Controller fatal error through sysfs Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-06 10:52   ` Jinpu Wang
  2019-10-31  5:12 ` [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump Deepak Ukey
  11 siblings, 1 reply; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Vikram Auradkar <auradkar@google.com>

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 <auradkar@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_init.c | 11 ++++++-----
 drivers/scsi/pm8001/pm8001_sas.h  |  2 ++
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 86b619d10392..485f0afc53f9 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -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;
 }
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index f7be7b85624e..a55b03bca529 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -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


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump.
  2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
                   ` (10 preceding siblings ...)
  2019-10-31  5:12 ` [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance Deepak Ukey
@ 2019-10-31  5:12 ` Deepak Ukey
  2019-11-02  2:52   ` kbuild test robot
  2019-11-06 21:25   ` kbuild test robot
  11 siblings, 2 replies; 28+ messages in thread
From: Deepak Ukey @ 2019-10-31  5:12 UTC (permalink / raw)
  To: linux-scsi
  Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

From: Deepak Ukey <Deepak.Ukey@microchip.com>

Added the correct method to collect the fatal dump.

Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
---
 drivers/scsi/pm8001/pm8001_sas.h |   3 +
 drivers/scsi/pm8001/pm80xx_hwi.c | 247 +++++++++++++++++++++++++++++----------
 2 files changed, 191 insertions(+), 59 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index a55b03bca529..93438c8f67da 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -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*/
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 5ca9732f4704..56d99921cbc1 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -76,7 +76,7 @@ void pm80xx_pci_mem_copy(struct pm8001_hba_info  *pm8001_ha, u32 soffset,
 	destination1 = (u32 *)destination;
 
 	for (index = 0; index < dw_count; index += 4, destination1++) {
-		offset = (soffset + index / 4);
+		offset = (soffset + index);
 		if (offset < (64 * 1024)) {
 			value = pm8001_cr32(pm8001_ha, bus_base_number, offset);
 			*destination1 =  cpu_to_le32(value);
@@ -93,9 +93,11 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 	struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
 	void __iomem *fatal_table_address = pm8001_ha->fatal_tbl_addr;
 	u32 accum_len , reg_val, index, *temp;
+	u32 status = 1;
 	unsigned long start;
 	u8 *direct_data;
 	char *fatal_error_data = buf;
+	u32 length_to_read;
 
 	pm8001_ha->forensic_info.data_buf.direct_data = buf;
 	if (pm8001_ha->chip_id == chip_8001) {
@@ -105,16 +107,35 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 		return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
 			(char *)buf;
 	}
+	/* initialize variables for very first call from host application */
 	if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
 		PM8001_IO_DBG(pm8001_ha,
 		pm8001_printk("forensic_info TYPE_NON_FATAL..............\n"));
 		direct_data = (u8 *)fatal_error_data;
 		pm8001_ha->forensic_info.data_type = TYPE_NON_FATAL;
 		pm8001_ha->forensic_info.data_buf.direct_len = SYSFS_OFFSET;
+		pm8001_ha->forensic_info.data_buf.direct_offset = 0;
 		pm8001_ha->forensic_info.data_buf.read_len = 0;
+		pm8001_ha->forensic_preserved_accumulated_transfer = 0;
 
-		pm8001_ha->forensic_info.data_buf.direct_data = direct_data;
+		/* Write signature to fatal dump table */
+		pm8001_mw32(fatal_table_address,
+				MPI_FATAL_EDUMP_TABLE_SIGNATURE, 0x1234abcd);
 
+		pm8001_ha->forensic_info.data_buf.direct_data = direct_data;
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("ossaHwCB: status1 %d\n", status));
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("ossaHwCB: read_len 0x%x\n",
+			pm8001_ha->forensic_info.data_buf.read_len));
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("ossaHwCB: direct_len 0x%x\n",
+			pm8001_ha->forensic_info.data_buf.direct_len));
+		PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("ossaHwCB: direct_offset 0x%x\n",
+			pm8001_ha->forensic_info.data_buf.direct_offset));
+	}
+	if (pm8001_ha->forensic_info.data_buf.direct_offset == 0) {
 		/* start to get data */
 		/* Program the MEMBASE II Shifting Register with 0x00.*/
 		pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
@@ -127,30 +148,66 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 	/* Read until accum_len is retrived */
 	accum_len = pm8001_mr32(fatal_table_address,
 				MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
-	PM8001_IO_DBG(pm8001_ha, pm8001_printk("accum_len 0x%x\n",
-						accum_len));
+	/* Determine length of data between previously stored transfer length
+	 * and current accumulated transfer length
+	 */
+	length_to_read =
+		accum_len - pm8001_ha->forensic_preserved_accumulated_transfer;
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: accum_len 0x%x\n", accum_len));
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: length_to_read 0x%x\n",
+		length_to_read));
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: last_offset 0x%x\n",
+		pm8001_ha->forensic_last_offset));
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: read_len 0x%x\n",
+		pm8001_ha->forensic_info.data_buf.read_len));
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv:: direct_len 0x%x\n",
+		pm8001_ha->forensic_info.data_buf.direct_len));
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv:: direct_offset 0x%x\n",
+		pm8001_ha->forensic_info.data_buf.direct_offset));
+
+	/* If accumulated length failed to read correctly fail the attempt.*/
 	if (accum_len == 0xFFFFFFFF) {
 		PM8001_IO_DBG(pm8001_ha,
 			pm8001_printk("Possible PCI issue 0x%x not expected\n",
-				accum_len));
-		return -EIO;
+			accum_len));
+		return status;
 	}
-	if (accum_len == 0 || accum_len >= 0x100000) {
+	/* If accumulated length is zero fail the attempt */
+	if (accum_len == 0) {
 		pm8001_ha->forensic_info.data_buf.direct_data +=
 			sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
-				"%08x ", 0xFFFFFFFF);
+			"%08x ", 0xFFFFFFFF);
 		return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
 			(char *)buf;
 	}
+	/* Accumulated length is good so start capturing the first data */
 	temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
 	if (pm8001_ha->forensic_fatal_step == 0) {
 moreData:
+		/* If data to read is less than SYSFS_OFFSET then reduce the
+		 * length of dataLen
+		 */
+		if (pm8001_ha->forensic_last_offset + SYSFS_OFFSET
+				> length_to_read) {
+			pm8001_ha->forensic_info.data_buf.direct_len =
+				length_to_read -
+				pm8001_ha->forensic_last_offset;
+		} else {
+			pm8001_ha->forensic_info.data_buf.direct_len =
+				SYSFS_OFFSET;
+		}
 		if (pm8001_ha->forensic_info.data_buf.direct_data) {
 			/* Data is in bar, copy to host memory */
-			pm80xx_pci_mem_copy(pm8001_ha, pm8001_ha->fatal_bar_loc,
-			 pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
-				pm8001_ha->forensic_info.data_buf.direct_len ,
-					1);
+			pm80xx_pci_mem_copy(pm8001_ha,
+			pm8001_ha->fatal_bar_loc,
+			pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr,
+			pm8001_ha->forensic_info.data_buf.direct_len, 1);
 		}
 		pm8001_ha->fatal_bar_loc +=
 			pm8001_ha->forensic_info.data_buf.direct_len;
@@ -161,21 +218,28 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 		pm8001_ha->forensic_info.data_buf.read_len =
 			pm8001_ha->forensic_info.data_buf.direct_len;
 
-		if (pm8001_ha->forensic_last_offset  >= accum_len) {
+		if (pm8001_ha->forensic_last_offset  >= length_to_read) {
 			pm8001_ha->forensic_info.data_buf.direct_data +=
 			sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
 				"%08x ", 3);
-			for (index = 0; index < (SYSFS_OFFSET / 4); index++) {
+			for (index = 0; index <
+				(pm8001_ha->forensic_info.data_buf.direct_len
+				 / 4); index++) {
 				pm8001_ha->forensic_info.data_buf.direct_data +=
-					sprintf(pm8001_ha->
-					 forensic_info.data_buf.direct_data,
-						"%08x ", *(temp + index));
+				sprintf(
+				pm8001_ha->forensic_info.data_buf.direct_data,
+				"%08x ", *(temp + index));
 			}
 
 			pm8001_ha->fatal_bar_loc = 0;
 			pm8001_ha->forensic_fatal_step = 1;
 			pm8001_ha->fatal_forensic_shift_offset = 0;
 			pm8001_ha->forensic_last_offset	= 0;
+			status = 0;
+			PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("get_fatal_spcv: return1 0x%lx\n",
+			((char *)pm8001_ha->forensic_info.data_buf.direct_data
+			- (char *)buf)));
 			return (char *)pm8001_ha->
 				forensic_info.data_buf.direct_data -
 				(char *)buf;
@@ -185,12 +249,19 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 				sprintf(pm8001_ha->
 					forensic_info.data_buf.direct_data,
 					"%08x ", 2);
-			for (index = 0; index < (SYSFS_OFFSET / 4); index++) {
-				pm8001_ha->forensic_info.data_buf.direct_data +=
-					sprintf(pm8001_ha->
+			for (index = 0; index <
+				(pm8001_ha->forensic_info.data_buf.direct_len
+				 / 4); index++) {
+				pm8001_ha->forensic_info.data_buf.direct_data
+					+= sprintf(pm8001_ha->
 					forensic_info.data_buf.direct_data,
 					"%08x ", *(temp + index));
 			}
+			status = 0;
+			PM8001_IO_DBG(pm8001_ha,
+			pm8001_printk("get_fatal_spcv: return2 0x%lx\n",
+			((char *)pm8001_ha->forensic_info.data_buf.direct_data
+			- (char *)buf)));
 			return (char *)pm8001_ha->
 				forensic_info.data_buf.direct_data -
 				(char *)buf;
@@ -200,63 +271,121 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
 		pm8001_ha->forensic_info.data_buf.direct_data +=
 			sprintf(pm8001_ha->forensic_info.data_buf.direct_data,
 				"%08x ", 2);
-		for (index = 0; index < 256; index++) {
+		for (index = 0; index <
+			(pm8001_ha->forensic_info.data_buf.direct_len
+			 / 4) ; index++) {
 			pm8001_ha->forensic_info.data_buf.direct_data +=
 				sprintf(pm8001_ha->
-					forensic_info.data_buf.direct_data,
-						"%08x ", *(temp + index));
+				forensic_info.data_buf.direct_data,
+				"%08x ", *(temp + index));
 		}
 		pm8001_ha->fatal_forensic_shift_offset += 0x100;
 		pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
 			pm8001_ha->fatal_forensic_shift_offset);
 		pm8001_ha->fatal_bar_loc = 0;
+		status = 0;
+		PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: return3 0x%lx\n",
+		((char *)pm8001_ha->forensic_info.data_buf.direct_data
+		- (char *)buf)));
 		return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
 			(char *)buf;
 	}
 	if (pm8001_ha->forensic_fatal_step == 1) {
-		pm8001_ha->fatal_forensic_shift_offset = 0;
-		/* Read 64K of the debug data. */
-		pm8001_cw32(pm8001_ha, 0, MEMBASE_II_SHIFT_REGISTER,
-			pm8001_ha->fatal_forensic_shift_offset);
-		pm8001_mw32(fatal_table_address,
-			MPI_FATAL_EDUMP_TABLE_HANDSHAKE,
+		/* store previous accumulated length before triggering next
+		 * accumulated length update
+		 */
+		pm8001_ha->forensic_preserved_accumulated_transfer =
+			pm8001_mr32(fatal_table_address,
+			MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
+
+		/* continue capturing the fatal log until Dump status is 0x3 */
+		if (pm8001_mr32(fatal_table_address,
+			MPI_FATAL_EDUMP_TABLE_STATUS) <
+			MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
+
+			/* reset fddstat bit by writing to zero*/
+			pm8001_mw32(fatal_table_address,
+					MPI_FATAL_EDUMP_TABLE_STATUS, 0x0);
+
+			/* set dump control value to '1' so that new data will
+			 * be transferred to shared memory
+			 */
+			pm8001_mw32(fatal_table_address,
+				MPI_FATAL_EDUMP_TABLE_HANDSHAKE,
 				MPI_FATAL_EDUMP_HANDSHAKE_RDY);
 
-		/* Poll FDDHSHK  until clear  */
-		start = jiffies + (2 * HZ); /* 2 sec */
+			/*Poll FDDHSHK  until clear */
+			start = jiffies + (2 * HZ); /* 2 sec */
 
-		do {
-			reg_val = pm8001_mr32(fatal_table_address,
+			do {
+				reg_val = pm8001_mr32(fatal_table_address,
 					MPI_FATAL_EDUMP_TABLE_HANDSHAKE);
-		} while ((reg_val) && time_before(jiffies, start));
+			} while ((reg_val) && time_before(jiffies, start));
 
-		if (reg_val != 0) {
-			PM8001_FAIL_DBG(pm8001_ha,
-			pm8001_printk("TIMEOUT:MEMBASE_II_SHIFT_REGISTER"
-			" = 0x%x\n", reg_val));
-			return -EIO;
-		}
-
-		/* Read the next 64K of the debug data. */
-		pm8001_ha->forensic_fatal_step = 0;
-		if (pm8001_mr32(fatal_table_address,
-			MPI_FATAL_EDUMP_TABLE_STATUS) !=
-				MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) {
-			pm8001_mw32(fatal_table_address,
-				MPI_FATAL_EDUMP_TABLE_HANDSHAKE, 0);
-			goto moreData;
-		} else {
-			pm8001_ha->forensic_info.data_buf.direct_data +=
-				sprintf(pm8001_ha->
-					forensic_info.data_buf.direct_data,
-						"%08x ", 4);
-			pm8001_ha->forensic_info.data_buf.read_len = 0xFFFFFFFF;
-			pm8001_ha->forensic_info.data_buf.direct_len =  0;
-			pm8001_ha->forensic_info.data_buf.direct_offset = 0;
-			pm8001_ha->forensic_info.data_buf.read_len = 0;
+			if (reg_val != 0) {
+				PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+				"TIMEOUT:MPI_FATAL_EDUMP_TABLE_HDSHAKE 0x%x\n",
+				reg_val));
+			       /* Fail the dump if a timeout occurs */
+				pm8001_ha->forensic_info.data_buf.direct_data +=
+				sprintf(
+				pm8001_ha->forensic_info.data_buf.direct_data,
+				"%08x ", 0xFFFFFFFF);
+				return((char *)
+				pm8001_ha->forensic_info.data_buf.direct_data
+				- (char *)buf);
+			}
+			/* Poll status register until set to 2 or
+			 * 3 for up to 2 seconds
+			 */
+			start = jiffies + (2 * HZ); /* 2 sec */
+
+			do {
+				reg_val = pm8001_mr32(fatal_table_address,
+					MPI_FATAL_EDUMP_TABLE_STATUS);
+			} while (((reg_val != 2) || (reg_val != 3)) &&
+					time_before(jiffies, start));
+
+			if (reg_val < 2) {
+				PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+				"TIMEOUT:MPI_FATAL_EDUMP_TABLE_STATUS = 0x%x\n",
+				reg_val));
+				/* Fail the dump if a timeout occurs */
+				pm8001_ha->forensic_info.data_buf.direct_data +=
+				sprintf(
+				pm8001_ha->forensic_info.data_buf.direct_data,
+				"%08x ", 0xFFFFFFFF);
+				pm8001_cw32(pm8001_ha, 0,
+					MEMBASE_II_SHIFT_REGISTER,
+					pm8001_ha->fatal_forensic_shift_offset);
+			}
+			/* Read the next block of the debug data.*/
+			length_to_read = pm8001_mr32(fatal_table_address,
+			MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) -
+			pm8001_ha->forensic_preserved_accumulated_transfer;
+			if (length_to_read != 0x0) {
+				pm8001_ha->forensic_fatal_step = 0;
+				goto moreData;
+			} else {
+				pm8001_ha->forensic_info.data_buf.direct_data +=
+				sprintf(
+				pm8001_ha->forensic_info.data_buf.direct_data,
+				"%08x ", 4);
+				pm8001_ha->forensic_info.data_buf.read_len
+								= 0xFFFFFFFF;
+				pm8001_ha->forensic_info.data_buf.direct_len
+								=  0;
+				pm8001_ha->forensic_info.data_buf.direct_offset
+								= 0;
+				pm8001_ha->forensic_info.data_buf.read_len = 0;
+			}
 		}
 	}
-
+	PM8001_IO_DBG(pm8001_ha,
+		pm8001_printk("get_fatal_spcv: return4 0x%lx\n",
+		((char *)pm8001_ha->forensic_info.data_buf.direct_data -
+		 (char *)buf)));
 	return (char *)pm8001_ha->forensic_info.data_buf.direct_data -
 		(char *)buf;
 }
-- 
2.16.3


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH 01/12] pm80xx : Fix for SATA device discovery.
  2019-10-31  5:12 ` [PATCH 01/12] pm80xx : Fix for SATA device discovery Deepak Ukey
@ 2019-11-01  9:16   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-01  9:16 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, auradkar, ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: peter chang <dpf@google.com>
>
> 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.
>
> Signed-off-by: peter chang <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
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
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 73261902d75d..ee9c187d8caa 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 02/12] pm80xx : Initialize variable used as return status.
  2019-10-31  5:12 ` [PATCH 02/12] pm80xx : Initialize variable used as return status Deepak Ukey
@ 2019-11-01  9:17   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-01  9:17 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, auradkar, ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: John Sperbeck <jsperbeck@google.com>
>
> 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 <jsperbeck@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks good, thanks.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 7e48154e11c3..81160e99c75e 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep.
  2019-10-31  5:12 ` [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep Deepak Ukey
@ 2019-11-01  9:19   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-01  9:19 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, auradkar, ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Vikram Auradkar <auradkar@google.com>
>
> 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.
>
> Signed-off-by: Vikram Auradkar <auradkar@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
looks good, thanks
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index ee9c187d8caa..1a1adda15db8 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump.
  2019-10-31  5:12 ` [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump Deepak Ukey
@ 2019-11-02  2:52   ` kbuild test robot
  2019-11-06 21:25   ` kbuild test robot
  1 sibling, 0 replies; 28+ messages in thread
From: kbuild test robot @ 2019-11-02  2:52 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: kbuild-all, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
	deepak.ukey, jinpu.wang, martin.petersen, dpf, jsperbeck,
	auradkar, ianyar

[-- Attachment #1: Type: text/plain, Size: 21490 bytes --]

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
Reported-by: kbuild test robot <lkp@intel.com>

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",
                                               ~~^
                                               %x

vim +/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

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 62121 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 04/12] pm80xx : Squashed logging cleanup changes.
  2019-10-31  5:12 ` [PATCH 04/12] pm80xx : Squashed logging cleanup changes Deepak Ukey
@ 2019-11-06 10:22   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:22 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: peter chang <dpf@google.com>
>
> 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.
>
> Signed-off-by: peter chang <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Thanks,

>
> ---
>  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(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 68a8217032d0..2c1c722eca17 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -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);
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index 3374f553c617..b7cc3d05a3e0 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -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)
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 81160e99c75e..447a66d60275 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -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;
>  }
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index ff17c6aff63d..9e0da7bccb45 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -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
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 1a1adda15db8..6057610263c1 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check.
  2019-10-31  5:12 ` [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check Deepak Ukey
@ 2019-11-06 10:24   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:24 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: ianyar <ianyar@google.com>
>
> 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.
>
> Signed-off-by: ianyar <ianyar@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 4 ++--
>  drivers/scsi/pm8001/pm80xx_hwi.h | 3 +++
>  2 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 6057610263c1..9d04e5cfffb4 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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);
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index dc9ab7689060..701951a0f715 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer.
  2019-10-31  5:12 ` [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer Deepak Ukey
@ 2019-11-06 10:28   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:28 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Vikram Auradkar <auradkar@google.com>
>
> 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.
>
> Signed-off-by: Vikram Auradkar <auradkar@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 447a66d60275..4491de8d40fc 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 07/12] pm80xx : Fix command issue sizing.
  2019-10-31  5:12 ` [PATCH 07/12] pm80xx : Fix command issue sizing Deepak Ukey
@ 2019-11-06 10:33   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:33 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: peter chang <dpf@google.com>
>
> 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.
>
> Signed-off-by: peter chang <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  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(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 2c1c722eca17..1cbcade747fe 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -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;
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 9e0da7bccb45..d64883b80da9 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -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,
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 9d04e5cfffb4..09008db2efdc 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/12] pm80xx : Cleanup command when a reset times out.
  2019-10-31  5:12 ` [PATCH 08/12] pm80xx : Cleanup command when a reset times out Deepak Ukey
@ 2019-11-06 10:39   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:39 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: peter chang <dpf@google.com>
>
> 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 <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> ---
>  drivers/scsi/pm8001/pm8001_sas.c | 50 +++++++++++++++++++++++++++++-----------
>  1 file changed, 37 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index 4491de8d40fc..b562916a3d3d 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -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
s/Yhe/The
> +                        * 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;
> +                               }
>                         }
>
>                         /*
> --
> 2.16.3
>
Patch looks fine, please fix the typo above.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 09/12] pm80xx : Do not request 12G sas speeds.
  2019-10-31  5:12 ` [PATCH 09/12] pm80xx : Do not request 12G sas speeds Deepak Ukey
@ 2019-11-06 10:43   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:43 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: peter chang <dpf@google.com>
>
> 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 <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  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(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index b7cc3d05a3e0..86b619d10392 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -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)
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index d64883b80da9..f7be7b85624e 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -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;
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 09008db2efdc..5ca9732f4704 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
  2019-10-31  5:12 ` [PATCH 10/12] pm80xx : Controller fatal error through sysfs Deepak Ukey
@ 2019-11-06 10:49   ` Jinpu Wang
  2019-11-07  6:20     ` Deepak.Ukey
  0 siblings, 1 reply; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:49 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Deepak Ukey <Deepak.Ukey@microchip.com>
>
> Added support to check controller fatal error through sysfs.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> ---
>  drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
> index 6b85016b4db3..fbdd0bf0e1ab 100644
> --- a/drivers/scsi/pm8001/pm8001_ctl.c
> +++ b/drivers/scsi/pm8001/pm8001_ctl.c
> @@ -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)
The kernel-doc doesn't match the function name, please fix it.
> +{
> +       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,
> --
> 2.16.3
>
With the updated kernel-doc.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance.
  2019-10-31  5:12 ` [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance Deepak Ukey
@ 2019-11-06 10:52   ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-06 10:52 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Vikram Auradkar <auradkar@google.com>
>
> 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 <auradkar@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
> ---
>  drivers/scsi/pm8001/pm8001_init.c | 11 ++++++-----
>  drivers/scsi/pm8001/pm8001_sas.h  |  2 ++
>  2 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index 86b619d10392..485f0afc53f9 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -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;
>  }
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index f7be7b85624e..a55b03bca529 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -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
>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump.
  2019-10-31  5:12 ` [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump Deepak Ukey
  2019-11-02  2:52   ` kbuild test robot
@ 2019-11-06 21:25   ` kbuild test robot
  1 sibling, 0 replies; 28+ messages in thread
From: kbuild test robot @ 2019-11-06 21:25 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: kbuild-all, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
	deepak.ukey, jinpu.wang, martin.petersen, dpf, jsperbeck,
	auradkar, ianyar

[-- Attachment #1: Type: text/plain, Size: 14774 bytes --]

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
Reported-by: kbuild test robot <lkp@intel.com>

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@lists.01.org Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34343 bytes --]

^ permalink raw reply	[flat|nested] 28+ messages in thread

* RE: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
  2019-11-06 10:49   ` Jinpu Wang
@ 2019-11-07  6:20     ` Deepak.Ukey
  2019-11-07  8:36       ` Jinpu Wang
  0 siblings, 1 reply; 28+ messages in thread
From: Deepak.Ukey @ 2019-11-07  6:20 UTC (permalink / raw)
  To: jinpu.wang
  Cc: linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G, jinpu.wang,
	martin.petersen, dpf, jsperbeck, auradkar, ianyar

On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Deepak Ukey <Deepak.Ukey@microchip.com>
>
> Added support to check controller fatal error through sysfs.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> ---
>  drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/drivers/scsi/pm8001/pm8001_ctl.c 
> b/drivers/scsi/pm8001/pm8001_ctl.c
> index 6b85016b4db3..fbdd0bf0e1ab 100644
> --- a/drivers/scsi/pm8001/pm8001_ctl.c
> +++ b/drivers/scsi/pm8001/pm8001_ctl.c
> @@ -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)
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) ?
> +{
> +       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,
> --
> 2.16.3
>
With the updated kernel-doc.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 10/12] pm80xx : Controller fatal error through sysfs.
  2019-11-07  6:20     ` Deepak.Ukey
@ 2019-11-07  8:36       ` Jinpu Wang
  0 siblings, 0 replies; 28+ messages in thread
From: Jinpu Wang @ 2019-11-07  8:36 UTC (permalink / raw)
  To: Deepak Ukey
  Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas.G,
	Jack Wang, Martin K. Petersen, dpf, jsperbeck, Vikram Auradkar,
	ianyar

On Thu, Nov 7, 2019 at 7:20 AM <Deepak.Ukey@microchip.com> wrote:
>
> On Thu, Oct 31, 2019 at 6:12 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> >
> > From: Deepak Ukey <Deepak.Ukey@microchip.com>
> >
> > Added support to check controller fatal error through sysfs.
> >
> > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > ---
> >  drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_ctl.c
> > b/drivers/scsi/pm8001/pm8001_ctl.c
> > index 6b85016b4db3..fbdd0bf0e1ab 100644
> > --- a/drivers/scsi/pm8001/pm8001_ctl.c
> > +++ b/drivers/scsi/pm8001/pm8001_ctl.c
> > @@ -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)
> 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.

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2019-11-07  8:36 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-31  5:12 [PATCH 00/12] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
2019-10-31  5:12 ` [PATCH 01/12] pm80xx : Fix for SATA device discovery Deepak Ukey
2019-11-01  9:16   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 02/12] pm80xx : Initialize variable used as return status Deepak Ukey
2019-11-01  9:17   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 03/12] pm80xx : Convert 'long' mdelay to msleep Deepak Ukey
2019-11-01  9:19   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 04/12] pm80xx : Squashed logging cleanup changes Deepak Ukey
2019-11-06 10:22   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 05/12] pm80xx : Increase timeout for pm80xx mpi_uninit_check Deepak Ukey
2019-11-06 10:24   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 06/12] pm80xx : Fix dereferencing dangling pointer Deepak Ukey
2019-11-06 10:28   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 07/12] pm80xx : Fix command issue sizing Deepak Ukey
2019-11-06 10:33   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 08/12] pm80xx : Cleanup command when a reset times out Deepak Ukey
2019-11-06 10:39   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 09/12] pm80xx : Do not request 12G sas speeds Deepak Ukey
2019-11-06 10:43   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 10/12] pm80xx : Controller fatal error through sysfs Deepak Ukey
2019-11-06 10:49   ` Jinpu Wang
2019-11-07  6:20     ` Deepak.Ukey
2019-11-07  8:36       ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 11/12] pm80xx : Tie the interrupt name to the module instance Deepak Ukey
2019-11-06 10:52   ` Jinpu Wang
2019-10-31  5:12 ` [PATCH 12/12] pm80xx : Modified the logic to collect fatal dump Deepak Ukey
2019-11-02  2:52   ` kbuild test robot
2019-11-06 21:25   ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).