All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] pm80xx updates
@ 2015-01-30  6:06 Viswas G
  2015-01-30  6:06 ` [PATCH 1/6] pm80xx : redefine sas_identify_frame structure Viswas G
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

This patch set include some big fixes and enhancement for pm80xx driver. 

Viswas G (6):
  pm80xx : redefine sas_identify_frame structure
  pm80xx: ILA and inactive firmware version through sysfs
  pm80xx : Different SAS addresses for phys.
  pm80xx : Corrected SATA abort handling.
  pm80xx : panic on ncq error cleaning up the read log
  pm80xx : corrected linkrate value.

 drivers/scsi/pm8001/pm8001_ctl.c  |  55 +++++++++++++++++
 drivers/scsi/pm8001/pm8001_hwi.c  |  11 +++-
 drivers/scsi/pm8001/pm8001_hwi.h  |   2 +-
 drivers/scsi/pm8001/pm8001_init.c |  13 ++--
 drivers/scsi/pm8001/pm8001_sas.c  | 125 ++++++++++++++++++++++++++------------
 drivers/scsi/pm8001/pm8001_sas.h  | 105 ++++++++++++++++++++++++++++++++
 drivers/scsi/pm8001/pm80xx_hwi.c  |  61 +++++++++++++++----
 drivers/scsi/pm8001/pm80xx_hwi.h  |   6 +-
 8 files changed, 321 insertions(+), 57 deletions(-)

-- 
2.12.3

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

* [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:19   ` Jack Wang
  2015-01-30  6:06 ` [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs Viswas G
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

sas_identify structure defined by pm80xx doesn't have CRC field.
So added a new sas_identify structure without CRC.

Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
Signed-off-by: Viswas G <Viswas.G@microsemi.com>
---
 drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
 drivers/scsi/pm8001/pm8001_sas.h | 95 ++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
 3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index e4867e690c84..f4331afe9b0b 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -157,7 +157,7 @@ struct mpi_msg_hdr{
 struct phy_start_req {
 	__le32	tag;
 	__le32	ase_sh_lm_slr_phyid;
-	struct sas_identify_frame sas_identify;
+	struct sas_identify_frame_local sas_identify;
 	u32	reserved[5];
 } __attribute__((packed, aligned(4)));
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index e81a8fa7ef1a..2e17505ed5b8 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -118,6 +118,101 @@ extern const struct pm8001_dispatch pm8001_80xx_dispatch;
 struct pm8001_hba_info;
 struct pm8001_ccb_info;
 struct pm8001_device;
+#ifdef __LITTLE_ENDIAN_BITFIELD
+struct sas_identify_frame_local {
+	/* Byte 0 */
+	u8  frame_type:4;
+	u8  dev_type:3;
+	u8  _un0:1;
+
+	/* Byte 1 */
+	u8  _un1;
+
+	/* Byte 2 */
+	union {
+		struct {
+			u8  _un20:1;
+			u8  smp_iport:1;
+			u8  stp_iport:1;
+			u8  ssp_iport:1;
+			u8  _un247:4;
+		};
+		u8 initiator_bits;
+	};
+
+	/* Byte 3 */
+	union {
+		struct {
+			u8  _un30:1;
+			u8 smp_tport:1;
+			u8 stp_tport:1;
+			u8 ssp_tport:1;
+			u8 _un347:4;
+		};
+		u8 target_bits;
+	};
+
+	/* Byte 4 - 11 */
+	u8 _un4_11[8];
+
+	/* Byte 12 - 19 */
+	u8 sas_addr[SAS_ADDR_SIZE];
+
+	/* Byte 20 */
+	u8 phy_id;
+
+	u8 _un21_27[7];
+
+} __packed;
+
+#elif defined(__BIG_ENDIAN_BITFIELD)
+struct sas_identify_frame_local {
+	/* Byte 0 */
+	u8  _un0:1;
+	u8  dev_type:3;
+	u8  frame_type:4;
+
+	/* Byte 1 */
+	u8  _un1;
+
+	/* Byte 2 */
+	union {
+		struct {
+			u8  _un247:4;
+			u8  ssp_iport:1;
+			u8  stp_iport:1;
+			u8  smp_iport:1;
+			u8  _un20:1;
+		};
+		u8 initiator_bits;
+	};
+
+	/* Byte 3 */
+	union {
+		struct {
+			u8 _un347:4;
+			u8 ssp_tport:1;
+			u8 stp_tport:1;
+			u8 smp_tport:1;
+			u8 _un30:1;
+		};
+		u8 target_bits;
+	};
+
+	/* Byte 4 - 11 */
+	u8 _un4_11[8];
+
+	/* Byte 12 - 19 */
+	u8 sas_addr[SAS_ADDR_SIZE];
+
+	/* Byte 20 */
+	u8 phy_id;
+
+	u8 _un21_27[7];
+} __packed;
+#else
+#error "Bitfield order not defined!"
+#endif
 /* define task management IU */
 struct pm8001_tmf_task {
 	u8	tmf;
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 7a443bad6163..1ee2ec210065 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -248,7 +248,7 @@ struct mpi_msg_hdr {
 struct phy_start_req {
 	__le32	tag;
 	__le32	ase_sh_lm_slr_phyid;
-	struct sas_identify_frame sas_identify; /* 28 Bytes */
+	struct sas_identify_frame_local sas_identify; /* 28 Bytes */
 	__le32 spasti;
 	u32	reserved[21];
 } __attribute__((packed, aligned(4)));
-- 
2.12.3

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

* [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
  2015-01-30  6:06 ` [PATCH 1/6] pm80xx : redefine sas_identify_frame structure Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:26   ` Jack Wang
  2015-01-30  6:06 ` [PATCH 3/6] pm80xx : Different SAS addresses for phys Viswas G
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

Added support to read ILA version and inactive firmware version
from MPI configuration table and export through sysfs.

Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
Signed-off-by: Viswas G <Viswas.G@microsemi.com>
---
 drivers/scsi/pm8001/pm8001_ctl.c | 55 ++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/pm8001/pm8001_sas.h |  2 ++
 drivers/scsi/pm8001/pm80xx_hwi.c |  5 ++++
 drivers/scsi/pm8001/pm80xx_hwi.h |  2 ++
 4 files changed, 64 insertions(+)

diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index be8269c8d127..d278c807112f 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -98,6 +98,59 @@ static ssize_t pm8001_ctl_fw_version_show(struct device *cdev,
 	}
 }
 static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
+
+/**
+ * pm8001_ctl_ila_version_show - ila version
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_ila_version_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;
+
+	if (pm8001_ha->chip_id != chip_8001) {
+		return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 24),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 16),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 8),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version));
+	}
+	return 0;
+}
+static DEVICE_ATTR(ila_version, 0444, pm8001_ctl_ila_version_show, NULL);
+
+/**
+ * pm8001_ctl_inactive_fw_version_show - Inacative firmware version number
+ * @cdev: pointer to embedded class device
+ * @buf: the buffer returned
+ *
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t pm8001_ctl_inactive_fw_version_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;
+
+	if (pm8001_ha->chip_id != chip_8001) {
+		return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 24),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 16),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 8),
+		(u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version));
+	}
+	return 0;
+}
+static
+DEVICE_ATTR(inc_fw_ver, 0444, pm8001_ctl_inactive_fw_version_show, NULL);
+
+
 /**
  * pm8001_ctl_max_out_io_show - max outstanding io supported
  * @cdev: pointer to embedded class device
@@ -748,6 +801,8 @@ struct device_attribute *pm8001_host_attrs[] = {
 	&dev_attr_bios_version,
 	&dev_attr_ib_log,
 	&dev_attr_ob_log,
+	&dev_attr_ila_version,
+	&dev_attr_inc_fw_ver,
 	NULL,
 };
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 2e17505ed5b8..2eb3b670bf45 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -499,6 +499,8 @@ union main_cfg_table {
 	u32			port_recovery_timer;
 	u32			interrupt_reassertion_delay;
 	u32			fatal_n_non_fatal_dump;	        /* 0x28 */
+	u32			ila_version;
+	u32			inc_fw_version;
 	} pm80xx_tbl;
 };
 
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index eb4fee61df72..8fb5ddf08cc4 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -312,6 +312,11 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
 	/* read port recover and reset timeout */
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer =
 		pm8001_mr32(address, MAIN_PORT_RECOVERY_TIMER);
+	/* read ILA and inactive firmware version */
+	pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version =
+		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);
 }
 
 /**
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 1ee2ec210065..d8e5d81e83f1 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -1349,6 +1349,8 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
 #define MAIN_SAS_PHY_ATTR_TABLE_OFFSET	0x90 /* DWORD 0x24 */
 #define MAIN_PORT_RECOVERY_TIMER	0x94 /* DWORD 0x25 */
 #define MAIN_INT_REASSERTION_DELAY	0x98 /* DWORD 0x26 */
+#define MAIN_MPI_ILA_RELEASE_TYPE	0xA4 /* DWORD 0x29 */
+#define MAIN_MPI_INACTIVE_FW_VERSION	0XB0 /* DWORD 0x2C */
 
 /* Gereral Status Table offset - byte offset */
 #define GST_GSTLEN_MPIS_OFFSET		0x00
-- 
2.12.3

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

* [PATCH 3/6] pm80xx : Different SAS addresses for phys.
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
  2015-01-30  6:06 ` [PATCH 1/6] pm80xx : redefine sas_identify_frame structure Viswas G
  2015-01-30  6:06 ` [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:25   ` Jack Wang
  2015-01-30  6:06 ` [PATCH 4/6] pm80xx : Corrected SATA abort handling Viswas G
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

Different SAS addresses are assigned for each set of phys.

Signed-off-by: Viswas G <Viswas.G@microsemi.com>
---
 drivers/scsi/pm8001/pm8001_init.c | 13 +++++++++----
 drivers/scsi/pm8001/pm80xx_hwi.c  |  3 +--
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 034b2f7d1135..d282f1562615 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -132,7 +132,7 @@ static void pm8001_phy_init(struct pm8001_hba_info *pm8001_ha, int phy_id)
 	sas_phy->oob_mode = OOB_NOT_CONNECTED;
 	sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
 	sas_phy->id = phy_id;
-	sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
+	sas_phy->sas_addr = (u8 *)&phy->dev_sas_addr;
 	sas_phy->frame_rcvd = &phy->frame_rcvd[0];
 	sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
 	sas_phy->lldd_phy = phy;
@@ -593,10 +593,12 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host *shost,
 	for (i = 0; i < chip_info->n_phy; i++) {
 		sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
 		sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
+		sha->sas_phy[i]->sas_addr =
+			(u8 *)&pm8001_ha->phy[i].dev_sas_addr;
 	}
 	sha->sas_ha_name = DRV_NAME;
 	sha->dev = pm8001_ha->dev;
-
+	sha->strict_wide_ports = 1;
 	sha->lldd_module = THIS_MODULE;
 	sha->sas_addr = &pm8001_ha->sas_addr[0];
 	sha->num_phys = chip_info->n_phy;
@@ -613,6 +615,7 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host *shost,
 static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
 {
 	u8 i, j;
+	u8 sas_add[8];
 #ifdef PM8001_READ_VPD
 	/* For new SPC controllers WWN is stored in flash vpd
 	*  For SPC/SPCve controllers WWN is stored in EEPROM
@@ -674,10 +677,12 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
 			pm8001_ha->sas_addr[j] =
 					payload.func_specific[0x804 + i];
 	}
-
+	memcpy(sas_add, pm8001_ha->sas_addr, SAS_ADDR_SIZE);
 	for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+		if (i && ((i % 4) == 0))
+			sas_add[7] = sas_add[7] + 4;
 		memcpy(&pm8001_ha->phy[i].dev_sas_addr,
-			pm8001_ha->sas_addr, SAS_ADDR_SIZE);
+			sas_add, SAS_ADDR_SIZE);
 		PM8001_INIT_DBG(pm8001_ha,
 			pm8001_printk("phy %d sas_addr = %016llx\n", i,
 			pm8001_ha->phy[i].dev_sas_addr));
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 8fb5ddf08cc4..a07b023c09bf 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3041,7 +3041,6 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	port->port_state = portstate;
 	phy->identify.device_type = 0;
 	phy->phy_attached = 0;
-	memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
 	switch (portstate) {
 	case PORT_VALID:
 		break;
@@ -4394,7 +4393,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->sas_addr, SAS_ADDR_SIZE);
+		&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);
 	return ret;
-- 
2.12.3

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

* [PATCH 4/6] pm80xx : Corrected SATA abort handling.
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
                   ` (2 preceding siblings ...)
  2015-01-30  6:06 ` [PATCH 3/6] pm80xx : Different SAS addresses for phys Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:46   ` Jack Wang
  2015-01-30  6:06 ` [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log Viswas G
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

Modified SATA abort handling with following steps:
1) Set device state as recovery.
2) Send phy reset.
3) Wait for reset completion.
4) After successful reset, abort all IO's to the device.
5) After aborting all IO's to device, set device state as operational.

Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
Signed-off-by: Viswas G <Viswas.G@microsemi.com>
---
 drivers/scsi/pm8001/pm8001_hwi.c |  11 +++-
 drivers/scsi/pm8001/pm8001_sas.c | 125 +++++++++++++++++++++++++++------------
 drivers/scsi/pm8001/pm8001_sas.h |   8 +++
 drivers/scsi/pm8001/pm80xx_hwi.c |  52 +++++++++++++---
 4 files changed, 148 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 10546faac58c..db88a8e7ee0e 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3198,19 +3198,28 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
 
 int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
 {
+	u32 tag;
 	struct local_phy_ctl_resp *pPayload =
 		(struct local_phy_ctl_resp *)(piomb + 4);
 	u32 status = le32_to_cpu(pPayload->status);
 	u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;
 	u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;
+	tag = le32_to_cpu(pPayload->tag);
 	if (status != 0) {
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk("%x phy execute %x phy op failed!\n",
 			phy_id, phy_op));
-	} else
+	} else {
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk("%x phy execute %x phy op success!\n",
 			phy_id, phy_op));
+		pm8001_ha->phy[phy_id].reset_success = true;
+	}
+	if (pm8001_ha->phy[phy_id].enable_completion) {
+		complete(pm8001_ha->phy[phy_id].enable_completion);
+		pm8001_ha->phy[phy_id].enable_completion = NULL;
+	}
+	pm8001_tag_free(pm8001_ha, tag);
 	return 0;
 }
 
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index ce584c31d36e..a409d3a6a3cb 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1159,40 +1159,47 @@ int pm8001_query_task(struct sas_task *task)
 int pm8001_abort_task(struct sas_task *task)
 {
 	unsigned long flags;
-	u32 tag = 0xdeadbeef;
+	u32 tag;
 	u32 device_id;
 	struct domain_device *dev ;
-	struct pm8001_hba_info *pm8001_ha = NULL;
+	struct pm8001_hba_info *pm8001_ha;
 	struct pm8001_ccb_info *ccb;
 	struct scsi_lun lun;
 	struct pm8001_device *pm8001_dev;
 	struct pm8001_tmf_task tmf_task;
-	int rc = TMF_RESP_FUNC_FAILED;
+	int rc = TMF_RESP_FUNC_FAILED, ret;
+	u32 phy_id;
+	struct sas_task_slow slow_task;
+
 	if (unlikely(!task || !task->lldd_task || !task->dev))
-		return rc;
+		return TMF_RESP_FUNC_FAILED;
+
+	dev = task->dev;
+	pm8001_dev = dev->lldd_dev;
+	pm8001_ha = pm8001_find_ha_by_dev(dev);
+	device_id = pm8001_dev->device_id;
+	phy_id = pm8001_dev->attached_phy;
+	rc = pm8001_find_tag(task, &tag);
+	if (rc == 0) {
+		pm8001_printk("no tag for task:%p\n", task);
+		return TMF_RESP_FUNC_FAILED;
+	}
 	spin_lock_irqsave(&task->task_state_lock, flags);
 	if (task->task_state_flags & SAS_TASK_STATE_DONE) {
 		spin_unlock_irqrestore(&task->task_state_lock, flags);
 		rc = TMF_RESP_FUNC_COMPLETE;
-		goto out;
+	}
+
+	task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+	if (task->slow_task == NULL) {
+		init_completion(&slow_task.completion);
+		task->slow_task = &slow_task;
 	}
 	spin_unlock_irqrestore(&task->task_state_lock, flags);
+
 	if (task->task_proto & SAS_PROTOCOL_SSP) {
 		struct scsi_cmnd *cmnd = task->uldd_task;
-		dev = task->dev;
-		ccb = task->lldd_task;
-		pm8001_dev = dev->lldd_dev;
-		pm8001_ha = pm8001_find_ha_by_dev(dev);
 		int_to_scsilun(cmnd->device->lun, &lun);
-		rc = pm8001_find_tag(task, &tag);
-		if (rc == 0) {
-			printk(KERN_INFO "No such tag in %s\n", __func__);
-			rc = TMF_RESP_FUNC_FAILED;
-			return rc;
-		}
-		device_id = pm8001_dev->device_id;
-		PM8001_EH_DBG(pm8001_ha,
-			pm8001_printk("abort io to deviceid= %d\n", device_id));
 		tmf_task.tmf = TMF_ABORT_TASK;
 		tmf_task.tag_of_task_to_be_managed = tag;
 		rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
@@ -1200,33 +1207,75 @@ int pm8001_abort_task(struct sas_task *task)
 			pm8001_dev->sas_device, 0, tag);
 	} else if (task->task_proto & SAS_PROTOCOL_SATA ||
 		task->task_proto & SAS_PROTOCOL_STP) {
-		dev = task->dev;
-		pm8001_dev = dev->lldd_dev;
-		pm8001_ha = pm8001_find_ha_by_dev(dev);
-		rc = pm8001_find_tag(task, &tag);
-		if (rc == 0) {
-			printk(KERN_INFO "No such tag in %s\n", __func__);
-			rc = TMF_RESP_FUNC_FAILED;
-			return rc;
+		if (pm8001_ha->chip_id == chip_8006) {
+			DECLARE_COMPLETION_ONSTACK(completion_reset);
+			DECLARE_COMPLETION_ONSTACK(completion);
+			struct pm8001_phy *phy = pm8001_ha->phy + phy_id;
+
+			/* 1. Set Device state as Recovery*/
+			pm8001_dev->setds_completion = &completion;
+			PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
+				pm8001_dev, 0x03);
+			wait_for_completion(&completion);
+
+			/* 2. Send Phy Control Hard Reset */
+			reinit_completion(&completion);
+			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)
+				goto out;
+
+			/* 3. Wait for Port Reset complete / 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)
+				goto out;
+
+			/* 4. SATA Abort ALL
+			 * we wait for the task to be aborted so that the task
+			 * is removed from the ccb. on success the caller is
+			 * going to free the task.
+			 */
+			ret = pm8001_exec_internal_task_abort(pm8001_ha,
+				pm8001_dev, pm8001_dev->sas_device, 1, tag);
+			if (ret)
+				goto out;
+			ret = wait_for_completion_timeout(
+				&task->slow_task->completion,
+				PM8001_TASK_TIMEOUT * HZ);
+			if (!ret)
+				goto out;
+
+			/* 5. Set Device State as Operational */
+			reinit_completion(&completion);
+			pm8001_dev->setds_completion = &completion;
+			PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
+				pm8001_dev, 0x01);
+			wait_for_completion(&completion);
+		} else {
+			rc = pm8001_exec_internal_task_abort(pm8001_ha,
+				pm8001_dev, pm8001_dev->sas_device, 0, tag);
 		}
-		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
-			pm8001_dev->sas_device, 0, tag);
+		rc = TMF_RESP_FUNC_COMPLETE;
 	} else if (task->task_proto & SAS_PROTOCOL_SMP) {
 		/* SMP */
-		dev = task->dev;
-		pm8001_dev = dev->lldd_dev;
-		pm8001_ha = pm8001_find_ha_by_dev(dev);
-		rc = pm8001_find_tag(task, &tag);
-		if (rc == 0) {
-			printk(KERN_INFO "No such tag in %s\n", __func__);
-			rc = TMF_RESP_FUNC_FAILED;
-			return rc;
-		}
 		rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
 			pm8001_dev->sas_device, 0, tag);
-
 	}
 out:
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (task->slow_task == &slow_task)
+		task->slow_task = NULL;
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
 	if (rc != TMF_RESP_FUNC_COMPLETE)
 		pm8001_printk("rc= %d\n", rc);
 	return rc;
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 2eb3b670bf45..e6c0da17966e 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -358,8 +358,15 @@ struct pm8001_phy {
 	u8			phy_state;
 	enum sas_linkrate	minimum_linkrate;
 	enum sas_linkrate	maximum_linkrate;
+	struct completion	*reset_completion;
+	bool			port_reset_status;
+	bool			reset_success;
 };
 
+/* port reset status */
+#define PORT_RESET_SUCCESS	0x00
+#define PORT_RESET_TMO		0x01
+
 struct pm8001_device {
 	enum sas_device_type	dev_type;
 	struct domain_device	*sas_device;
@@ -628,6 +635,7 @@ struct pm8001_hba_info {
 	u32			smp_exp_mode;
 	const struct firmware 	*fw_image;
 	struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
+	u32			reset_in_progress;
 };
 
 struct pm8001_work {
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index a07b023c09bf..ae9252cf1706 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -597,6 +597,12 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha)
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &= 0xffff0000;
 	pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
 							PORT_RECOVERY_TIMEOUT;
+	if (pm8001_ha->chip_id == chip_8006) {
+		pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &=
+								0x0000ffff;
+		pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
+								0x140000;
+	}
 	pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER,
 			pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);
 }
@@ -1775,6 +1781,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
 			"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);
@@ -3038,6 +3046,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
 
 	struct pm8001_port *port = &pm8001_ha->port[port_id];
 	struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
+	u32 port_sata = (phy->phy_type & PORT_TYPE_SATA);
 	port->port_state = portstate;
 	phy->identify.device_type = 0;
 	phy->phy_attached = 0;
@@ -3049,7 +3058,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
 			pm8001_printk(" PortInvalid portID %d\n", port_id));
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk(" Last phy Down and port invalid\n"));
-		if (phy->phy_type & PORT_TYPE_SATA) {
+		if (port_sata) {
 			phy->phy_type = 0;
 			port->port_attached = 0;
 			pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
@@ -3071,7 +3080,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
 			pm8001_printk(" Phy Down and PORT_LOSTCOMM\n"));
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk(" Last phy Down and port invalid\n"));
-		if (phy->phy_type & PORT_TYPE_SATA) {
+		if (port_sata) {
 			port->port_attached = 0;
 			phy->phy_type = 0;
 			pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
@@ -3087,6 +3096,11 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
 		break;
 
 	}
+	if (port_sata && (portstate != PORT_IN_RESET)) {
+		struct sas_ha_struct *sas_ha = pm8001_ha->sas;
+
+		sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
+	}
 }
 
 static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -3189,12 +3203,14 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	case HW_EVENT_PHY_DOWN:
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk("HW_EVENT_PHY_DOWN\n"));
-		if (phy->phy_type & PORT_TYPE_SATA)
-			sas_ha->notify_phy_event(&phy->sas_phy,
-				PHYE_LOSS_OF_SIGNAL);
+		hw_event_phy_down(pm8001_ha, piomb);
+		if (pm8001_ha->reset_in_progress) {
+			PM8001_MSG_DBG(pm8001_ha,
+				pm8001_printk("Reset in progress\n"));
+			return 0;
+		}
 		phy->phy_attached = 0;
 		phy->phy_state = 0;
-		hw_event_phy_down(pm8001_ha, piomb);
 		break;
 	case HW_EVENT_PORT_INVALID:
 		PM8001_MSG_DBG(pm8001_ha,
@@ -3301,9 +3317,17 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	case HW_EVENT_PORT_RESET_TIMER_TMO:
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n"));
+		pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
+			port_id, phy_id, 0, 0);
 		sas_phy_disconnected(sas_phy);
 		phy->phy_attached = 0;
 		sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
+		if (pm8001_ha->phy[phy_id].reset_completion) {
+			pm8001_ha->phy[phy_id].port_reset_status =
+							PORT_RESET_TMO;
+			complete(pm8001_ha->phy[phy_id].reset_completion);
+			pm8001_ha->phy[phy_id].reset_completion = NULL;
+		}
 		break;
 	case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
 		PM8001_MSG_DBG(pm8001_ha,
@@ -3328,6 +3352,12 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
 	case HW_EVENT_PORT_RESET_COMPLETE:
 		PM8001_MSG_DBG(pm8001_ha,
 			pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n"));
+		if (pm8001_ha->phy[phy_id].reset_completion) {
+			pm8001_ha->phy[phy_id].port_reset_status =
+							PORT_RESET_SUCCESS;
+			complete(pm8001_ha->phy[phy_id].reset_completion);
+			pm8001_ha->phy[phy_id].reset_completion = NULL;
+		}
 		break;
 	case EVENT_BROADCAST_ASYNCH_EVENT:
 		PM8001_MSG_DBG(pm8001_ha,
@@ -4500,17 +4530,21 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
 static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
 	u32 phyId, u32 phy_op)
 {
+	u32 tag;
+	int rc;
 	struct local_phy_ctl_req payload;
 	struct inbound_queue_table *circularQ;
 	int ret;
 	u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
 	memset(&payload, 0, sizeof(payload));
+	rc = pm8001_tag_alloc(pm8001_ha, &tag);
+	if (rc)
+		return rc;
 	circularQ = &pm8001_ha->inbnd_q_tbl[0];
-	payload.tag = cpu_to_le32(1);
+	payload.tag = cpu_to_le32(tag);
 	payload.phyop_phyid =
 		cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
-	ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
-	return ret;
+	return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
 }
 
 static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha)
-- 
2.12.3

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

* [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
                   ` (3 preceding siblings ...)
  2015-01-30  6:06 ` [PATCH 4/6] pm80xx : Corrected SATA abort handling Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:49   ` Jack Wang
  2015-01-30  6:06 ` [PATCH 6/6] pm80xx : corrected linkrate value Viswas G
  2017-08-25 21:47 ` [PATCH 0/6] pm80xx updates Martin K. Petersen
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

when there's an error in 'ncq mode' the host has to read the ncq
error log (10h) to clear the error state. however, the ccb that
is setup for doing this doesn't setup the ccb so that the
previous state is cleared. if the ccb was previously used for an IO
n_elems is set and pm8001_ccb_task_free() treats this as the signal
to go free a scatter-gather list (that's already been free-ed).

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

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index ae9252cf1706..e75b0aa497f0 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1489,6 +1489,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
 	ccb->device = pm8001_ha_dev;
 	ccb->ccb_tag = ccb_tag;
 	ccb->task = task;
+	ccb->n_elem = 0;
 	pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
 	pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
 
-- 
2.12.3

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

* [PATCH 6/6] pm80xx : corrected linkrate value.
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
                   ` (4 preceding siblings ...)
  2015-01-30  6:06 ` [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log Viswas G
@ 2015-01-30  6:06 ` Viswas G
  2017-08-29 11:08   ` Jack Wang
  2017-08-25 21:47 ` [PATCH 0/6] pm80xx updates Martin K. Petersen
  6 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2015-01-30  6:06 UTC (permalink / raw)
  To: linux-scsi; +Cc: xjtuwjp, Vasanthalakshmi.Tharmarajan, Viswas.G

Corrected the value defined for LINKRATE_60 (6 Gig).

Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
Signed-off-by: Viswas G <viswas.g@microsemi.com>
---
 drivers/scsi/pm8001/pm80xx_hwi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index d8e5d81e83f1..71dee83aeef0 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -167,7 +167,7 @@
 #define LINKMODE_AUTO			(0x03 << 12)
 #define LINKRATE_15			(0x01 << 8)
 #define LINKRATE_30			(0x02 << 8)
-#define LINKRATE_60			(0x06 << 8)
+#define LINKRATE_60			(0x04 << 8)
 #define LINKRATE_120			(0x08 << 8)
 
 /* phy_profile */
-- 
2.12.3

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

* Re: [PATCH 0/6] pm80xx updates
  2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
                   ` (5 preceding siblings ...)
  2015-01-30  6:06 ` [PATCH 6/6] pm80xx : corrected linkrate value Viswas G
@ 2017-08-25 21:47 ` Martin K. Petersen
  2017-08-26  5:27   ` Viswas G
  6 siblings, 1 reply; 22+ messages in thread
From: Martin K. Petersen @ 2017-08-25 21:47 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, xjtuwjp, Vasanthalakshmi.Tharmarajan


Viswas,

> This patch set include some big fixes and enhancement for pm80xx
> driver.

This patch set is dated January 2015!?!

-- 
Martin K. Petersen	Oracle Linux Engineering

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

* RE: [PATCH 0/6] pm80xx updates
  2017-08-25 21:47 ` [PATCH 0/6] pm80xx updates Martin K. Petersen
@ 2017-08-26  5:27   ` Viswas G
  0 siblings, 0 replies; 22+ messages in thread
From: Viswas G @ 2017-08-26  5:27 UTC (permalink / raw)
  To: Martin K. Petersen; +Cc: linux-scsi, xjtuwjp, Vasanthalakshmi Tharmarajan

Thanks Martin,

My system date was wrong.

I will correct the date when I send V1 for this patch set.

Regards,
Viswas G

-----Original Message-----
From: Martin K. Petersen [mailto:martin.petersen@oracle.com] 
Sent: Saturday, August 26, 2017 3:18 AM
To: Viswas G <viswas.g@microsemi.com>
Cc: linux-scsi@vger.kernel.org; xjtuwjp@gmail.com; Vasanthalakshmi Tharmarajan <vasanthalakshmi.thar@microsemi.com>
Subject: Re: [PATCH 0/6] pm80xx updates

EXTERNAL EMAIL


Viswas,

> This patch set include some big fixes and enhancement for pm80xx 
> driver.

This patch set is dated January 2015!?!

--
Martin K. Petersen      Oracle Linux Engineering

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

* Re: [PATCH 6/6] pm80xx : corrected linkrate value.
  2015-01-30  6:06 ` [PATCH 6/6] pm80xx : corrected linkrate value Viswas G
@ 2017-08-29 11:08   ` Jack Wang
  2017-08-30  1:32     ` Martin K. Petersen
  0 siblings, 1 reply; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:08 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> Corrected the value defined for LINKRATE_60 (6 Gig).
>
> Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
> Signed-off-by: Viswas G <viswas.g@microsemi.com>
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index d8e5d81e83f1..71dee83aeef0 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -167,7 +167,7 @@
>  #define LINKMODE_AUTO                  (0x03 << 12)
>  #define LINKRATE_15                    (0x01 << 8)
>  #define LINKRATE_30                    (0x02 << 8)
> -#define LINKRATE_60                    (0x06 << 8)
> +#define LINKRATE_60                    (0x04 << 8)
>  #define LINKRATE_120                   (0x08 << 8)
>
>  /* phy_profile */
> --
> 2.12.3
>
Thanks Viswas, how did this happen, checked pm8001_hwi.h, it's right.
Anyway, looks good to me!
Acked-by: Jack Wang <jinpu.wang@profitbricks.com>

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

* Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
  2015-01-30  6:06 ` [PATCH 1/6] pm80xx : redefine sas_identify_frame structure Viswas G
@ 2017-08-29 11:19   ` Jack Wang
  2017-08-30 15:41     ` Viswas G
  0 siblings, 1 reply; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:19 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> sas_identify structure defined by pm80xx doesn't have CRC field.
> So added a new sas_identify structure without CRC.
>
> Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
> Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> ---
>  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
>  drivers/scsi/pm8001/pm8001_sas.h | 95 ++++++++++++++++++++++++++++++++++++++++
>  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
>  3 files changed, 97 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
> index e4867e690c84..f4331afe9b0b 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.h
> +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
>  struct phy_start_req {
>         __le32  tag;
>         __le32  ase_sh_lm_slr_phyid;
> -       struct sas_identify_frame sas_identify;
> +       struct sas_identify_frame_local sas_identify;
>         u32     reserved[5];
>  } __attribute__((packed, aligned(4)));
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index e81a8fa7ef1a..2e17505ed5b8 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch pm8001_80xx_dispatch;
>  struct pm8001_hba_info;
>  struct pm8001_ccb_info;
>  struct pm8001_device;
> +#ifdef __LITTLE_ENDIAN_BITFIELD
> +struct sas_identify_frame_local {
> +       /* Byte 0 */
> +       u8  frame_type:4;
> +       u8  dev_type:3;
> +       u8  _un0:1;
> +
> +       /* Byte 1 */
> +       u8  _un1;
> +
> +       /* Byte 2 */
> +       union {
> +               struct {
> +                       u8  _un20:1;
> +                       u8  smp_iport:1;
> +                       u8  stp_iport:1;
> +                       u8  ssp_iport:1;
> +                       u8  _un247:4;
> +               };
> +               u8 initiator_bits;
> +       };
> +
> +       /* Byte 3 */
> +       union {
> +               struct {
> +                       u8  _un30:1;
> +                       u8 smp_tport:1;
> +                       u8 stp_tport:1;
> +                       u8 ssp_tport:1;
> +                       u8 _un347:4;
> +               };
> +               u8 target_bits;
> +       };
> +
> +       /* Byte 4 - 11 */
> +       u8 _un4_11[8];
> +
> +       /* Byte 12 - 19 */
> +       u8 sas_addr[SAS_ADDR_SIZE];
> +
> +       /* Byte 20 */
> +       u8 phy_id;
> +
> +       u8 _un21_27[7];
> +
> +} __packed;
> +
> +#elif defined(__BIG_ENDIAN_BITFIELD)
> +struct sas_identify_frame_local {
> +       /* Byte 0 */
> +       u8  _un0:1;
> +       u8  dev_type:3;
> +       u8  frame_type:4;
> +
> +       /* Byte 1 */
> +       u8  _un1;
> +
> +       /* Byte 2 */
> +       union {
> +               struct {
> +                       u8  _un247:4;
> +                       u8  ssp_iport:1;
> +                       u8  stp_iport:1;
> +                       u8  smp_iport:1;
> +                       u8  _un20:1;
> +               };
> +               u8 initiator_bits;
> +       };
> +
> +       /* Byte 3 */
> +       union {
> +               struct {
> +                       u8 _un347:4;
> +                       u8 ssp_tport:1;
> +                       u8 stp_tport:1;
> +                       u8 smp_tport:1;
> +                       u8 _un30:1;
> +               };
> +               u8 target_bits;
> +       };
> +
> +       /* Byte 4 - 11 */
> +       u8 _un4_11[8];
> +
> +       /* Byte 12 - 19 */
> +       u8 sas_addr[SAS_ADDR_SIZE];
> +
> +       /* Byte 20 */
> +       u8 phy_id;
> +
> +       u8 _un21_27[7];
> +} __packed;
> +#else
> +#error "Bitfield order not defined!"
> +#endif
>  /* define task management IU */
>  struct pm8001_tmf_task {
>         u8      tmf;
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index 7a443bad6163..1ee2ec210065 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -248,7 +248,7 @@ struct mpi_msg_hdr {
>  struct phy_start_req {
>         __le32  tag;
>         __le32  ase_sh_lm_slr_phyid;
> -       struct sas_identify_frame sas_identify; /* 28 Bytes */
> +       struct sas_identify_frame_local sas_identify; /* 28 Bytes */
>         __le32 spasti;
>         u32     reserved[21];
>  } __attribute__((packed, aligned(4)));
> --
> 2.12.3
>
Did this cause any trouble? I guest not, as we does memset for
phy_start_req,  why bother?

Jack

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

* Re: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
  2015-01-30  6:06 ` [PATCH 3/6] pm80xx : Different SAS addresses for phys Viswas G
@ 2017-08-29 11:25   ` Jack Wang
  2017-08-30 16:55     ` Viswas G
  0 siblings, 1 reply; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:25 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> Different SAS addresses are assigned for each set of phys.
>
> Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> ---
>  drivers/scsi/pm8001/pm8001_init.c | 13 +++++++++----
>  drivers/scsi/pm8001/pm80xx_hwi.c  |  3 +--
>  2 files changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> index 034b2f7d1135..d282f1562615 100644
> --- a/drivers/scsi/pm8001/pm8001_init.c
> +++ b/drivers/scsi/pm8001/pm8001_init.c
> @@ -132,7 +132,7 @@ static void pm8001_phy_init(struct pm8001_hba_info *pm8001_ha, int phy_id)
>         sas_phy->oob_mode = OOB_NOT_CONNECTED;
>         sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
>         sas_phy->id = phy_id;
> -       sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
> +       sas_phy->sas_addr = (u8 *)&phy->dev_sas_addr;
>         sas_phy->frame_rcvd = &phy->frame_rcvd[0];
>         sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
>         sas_phy->lldd_phy = phy;
> @@ -593,10 +593,12 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host *shost,
>         for (i = 0; i < chip_info->n_phy; i++) {
>                 sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
>                 sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
> +               sha->sas_phy[i]->sas_addr =
> +                       (u8 *)&pm8001_ha->phy[i].dev_sas_addr;
>         }
>         sha->sas_ha_name = DRV_NAME;
>         sha->dev = pm8001_ha->dev;
> -
> +       sha->strict_wide_ports = 1;
>         sha->lldd_module = THIS_MODULE;
>         sha->sas_addr = &pm8001_ha->sas_addr[0];
>         sha->num_phys = chip_info->n_phy;
> @@ -613,6 +615,7 @@ static void  pm8001_post_sas_ha_init(struct Scsi_Host *shost,
>  static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
>  {
>         u8 i, j;
> +       u8 sas_add[8];
>  #ifdef PM8001_READ_VPD
>         /* For new SPC controllers WWN is stored in flash vpd
>         *  For SPC/SPCve controllers WWN is stored in EEPROM
> @@ -674,10 +677,12 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
>                         pm8001_ha->sas_addr[j] =
>                                         payload.func_specific[0x804 + i];
>         }
> -
> +       memcpy(sas_add, pm8001_ha->sas_addr, SAS_ADDR_SIZE);
>         for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
> +               if (i && ((i % 4) == 0))
> +                       sas_add[7] = sas_add[7] + 4;
>                 memcpy(&pm8001_ha->phy[i].dev_sas_addr,
> -                       pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> +                       sas_add, SAS_ADDR_SIZE);
>                 PM8001_INIT_DBG(pm8001_ha,
>                         pm8001_printk("phy %d sas_addr = %016llx\n", i,
>                         pm8001_ha->phy[i].dev_sas_addr));
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index 8fb5ddf08cc4..a07b023c09bf 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -3041,7 +3041,6 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         port->port_state = portstate;
>         phy->identify.device_type = 0;
>         phy->phy_attached = 0;
> -       memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
>         switch (portstate) {
>         case PORT_VALID:
>                 break;
> @@ -4394,7 +4393,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->sas_addr, SAS_ADDR_SIZE);
> +               &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);
>         return ret;
> --
> 2.12.3
>
This removes the possibility to form a wide port, why do you want to do it?

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

* Re: [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs
  2015-01-30  6:06 ` [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs Viswas G
@ 2017-08-29 11:26   ` Jack Wang
  0 siblings, 0 replies; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:26 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> Added support to read ILA version and inactive firmware version
> from MPI configuration table and export through sysfs.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
> Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> ---
>  drivers/scsi/pm8001/pm8001_ctl.c | 55 ++++++++++++++++++++++++++++++++++++++++
>  drivers/scsi/pm8001/pm8001_sas.h |  2 ++
>  drivers/scsi/pm8001/pm80xx_hwi.c |  5 ++++
>  drivers/scsi/pm8001/pm80xx_hwi.h |  2 ++
>  4 files changed, 64 insertions(+)
>
> diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
> index be8269c8d127..d278c807112f 100644
> --- a/drivers/scsi/pm8001/pm8001_ctl.c
> +++ b/drivers/scsi/pm8001/pm8001_ctl.c
> @@ -98,6 +98,59 @@ static ssize_t pm8001_ctl_fw_version_show(struct device *cdev,
>         }
>  }
>  static DEVICE_ATTR(fw_version, S_IRUGO, pm8001_ctl_fw_version_show, NULL);
> +
> +/**
> + * pm8001_ctl_ila_version_show - ila version
> + * @cdev: pointer to embedded class device
> + * @buf: the buffer returned
> + *
> + * A sysfs 'read-only' shost attribute.
> + */
> +static ssize_t pm8001_ctl_ila_version_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;
> +
> +       if (pm8001_ha->chip_id != chip_8001) {
> +               return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 24),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 16),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version >> 8),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version));
> +       }
> +       return 0;
> +}
> +static DEVICE_ATTR(ila_version, 0444, pm8001_ctl_ila_version_show, NULL);
> +
> +/**
> + * pm8001_ctl_inactive_fw_version_show - Inacative firmware version number
> + * @cdev: pointer to embedded class device
> + * @buf: the buffer returned
> + *
> + * A sysfs 'read-only' shost attribute.
> + */
> +static ssize_t pm8001_ctl_inactive_fw_version_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;
> +
> +       if (pm8001_ha->chip_id != chip_8001) {
> +               return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 24),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 16),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version >> 8),
> +               (u8)(pm8001_ha->main_cfg_tbl.pm80xx_tbl.inc_fw_version));
> +       }
> +       return 0;
> +}
> +static
> +DEVICE_ATTR(inc_fw_ver, 0444, pm8001_ctl_inactive_fw_version_show, NULL);
> +
> +
>  /**
>   * pm8001_ctl_max_out_io_show - max outstanding io supported
>   * @cdev: pointer to embedded class device
> @@ -748,6 +801,8 @@ struct device_attribute *pm8001_host_attrs[] = {
>         &dev_attr_bios_version,
>         &dev_attr_ib_log,
>         &dev_attr_ob_log,
> +       &dev_attr_ila_version,
> +       &dev_attr_inc_fw_ver,
>         NULL,
>  };
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 2e17505ed5b8..2eb3b670bf45 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -499,6 +499,8 @@ union main_cfg_table {
>         u32                     port_recovery_timer;
>         u32                     interrupt_reassertion_delay;
>         u32                     fatal_n_non_fatal_dump;         /* 0x28 */
> +       u32                     ila_version;
> +       u32                     inc_fw_version;
>         } pm80xx_tbl;
>  };
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index eb4fee61df72..8fb5ddf08cc4 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -312,6 +312,11 @@ static void read_main_config_table(struct pm8001_hba_info *pm8001_ha)
>         /* read port recover and reset timeout */
>         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer =
>                 pm8001_mr32(address, MAIN_PORT_RECOVERY_TIMER);
> +       /* read ILA and inactive firmware version */
> +       pm8001_ha->main_cfg_tbl.pm80xx_tbl.ila_version =
> +               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);
>  }
>
>  /**
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
> index 1ee2ec210065..d8e5d81e83f1 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> @@ -1349,6 +1349,8 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
>  #define MAIN_SAS_PHY_ATTR_TABLE_OFFSET 0x90 /* DWORD 0x24 */
>  #define MAIN_PORT_RECOVERY_TIMER       0x94 /* DWORD 0x25 */
>  #define MAIN_INT_REASSERTION_DELAY     0x98 /* DWORD 0x26 */
> +#define MAIN_MPI_ILA_RELEASE_TYPE      0xA4 /* DWORD 0x29 */
> +#define MAIN_MPI_INACTIVE_FW_VERSION   0XB0 /* DWORD 0x2C */
>
>  /* Gereral Status Table offset - byte offset */
>  #define GST_GSTLEN_MPIS_OFFSET         0x00
> --
> 2.12.3
>
Thanks, looks good to me.
Acked-by: Jack Wang <jinpu.wang@profitbricks.com>

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

* Re: [PATCH 4/6] pm80xx : Corrected SATA abort handling.
  2015-01-30  6:06 ` [PATCH 4/6] pm80xx : Corrected SATA abort handling Viswas G
@ 2017-08-29 11:46   ` Jack Wang
  2017-08-30 15:48     ` Viswas G
  0 siblings, 1 reply; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:46 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> Modified SATA abort handling with following steps:
> 1) Set device state as recovery.
> 2) Send phy reset.
> 3) Wait for reset completion.
> 4) After successful reset, abort all IO's to the device.
> 5) After aborting all IO's to device, set device state as operational.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
> Signed-off-by: Viswas G <Viswas.G@microsemi.com>
This one includes more than described above.
Would be good to split it better.
comments inline.

> ---
>  drivers/scsi/pm8001/pm8001_hwi.c |  11 +++-
>  drivers/scsi/pm8001/pm8001_sas.c | 125 +++++++++++++++++++++++++++------------
>  drivers/scsi/pm8001/pm8001_sas.h |   8 +++
>  drivers/scsi/pm8001/pm80xx_hwi.c |  52 +++++++++++++---
>  4 files changed, 148 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
> index 10546faac58c..db88a8e7ee0e 100644
> --- a/drivers/scsi/pm8001/pm8001_hwi.c
> +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> @@ -3198,19 +3198,28 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
>
>  int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
>  {
> +       u32 tag;
>         struct local_phy_ctl_resp *pPayload =
>                 (struct local_phy_ctl_resp *)(piomb + 4);
>         u32 status = le32_to_cpu(pPayload->status);
>         u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;
>         u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;
> +       tag = le32_to_cpu(pPayload->tag);
>         if (status != 0) {
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk("%x phy execute %x phy op failed!\n",
>                         phy_id, phy_op));
> -       } else
> +       } else {
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk("%x phy execute %x phy op success!\n",
>                         phy_id, phy_op));
> +               pm8001_ha->phy[phy_id].reset_success = true;
> +       }
> +       if (pm8001_ha->phy[phy_id].enable_completion) {
> +               complete(pm8001_ha->phy[phy_id].enable_completion);
> +               pm8001_ha->phy[phy_id].enable_completion = NULL;
> +       }
> +       pm8001_tag_free(pm8001_ha, tag);
>         return 0;
>  }
>
> diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
> index ce584c31d36e..a409d3a6a3cb 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.c
> +++ b/drivers/scsi/pm8001/pm8001_sas.c
> @@ -1159,40 +1159,47 @@ int pm8001_query_task(struct sas_task *task)
>  int pm8001_abort_task(struct sas_task *task)
>  {
>         unsigned long flags;
> -       u32 tag = 0xdeadbeef;
> +       u32 tag;
>         u32 device_id;
>         struct domain_device *dev ;
> -       struct pm8001_hba_info *pm8001_ha = NULL;
> +       struct pm8001_hba_info *pm8001_ha;
>         struct pm8001_ccb_info *ccb;
>         struct scsi_lun lun;
>         struct pm8001_device *pm8001_dev;
>         struct pm8001_tmf_task tmf_task;
> -       int rc = TMF_RESP_FUNC_FAILED;
> +       int rc = TMF_RESP_FUNC_FAILED, ret;
> +       u32 phy_id;
> +       struct sas_task_slow slow_task;
> +
>         if (unlikely(!task || !task->lldd_task || !task->dev))
> -               return rc;
> +               return TMF_RESP_FUNC_FAILED;
> +
> +       dev = task->dev;
> +       pm8001_dev = dev->lldd_dev;
> +       pm8001_ha = pm8001_find_ha_by_dev(dev);
> +       device_id = pm8001_dev->device_id;
> +       phy_id = pm8001_dev->attached_phy;
> +       rc = pm8001_find_tag(task, &tag);
> +       if (rc == 0) {
> +               pm8001_printk("no tag for task:%p\n", task);
> +               return TMF_RESP_FUNC_FAILED;
> +       }

This part is cleanup.
>         spin_lock_irqsave(&task->task_state_lock, flags);
>         if (task->task_state_flags & SAS_TASK_STATE_DONE) {
>                 spin_unlock_irqrestore(&task->task_state_lock, flags);
>                 rc = TMF_RESP_FUNC_COMPLETE;
> -               goto out;
> +       }
> +
> +       task->task_state_flags |= SAS_TASK_STATE_ABORTED;
> +       if (task->slow_task == NULL) {
> +               init_completion(&slow_task.completion);
> +               task->slow_task = &slow_task;
>         }
>         spin_unlock_irqrestore(&task->task_state_lock, flags);
> +
>         if (task->task_proto & SAS_PROTOCOL_SSP) {
>                 struct scsi_cmnd *cmnd = task->uldd_task;
> -               dev = task->dev;
> -               ccb = task->lldd_task;
> -               pm8001_dev = dev->lldd_dev;
> -               pm8001_ha = pm8001_find_ha_by_dev(dev);
>                 int_to_scsilun(cmnd->device->lun, &lun);
> -               rc = pm8001_find_tag(task, &tag);
> -               if (rc == 0) {
> -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> -                       rc = TMF_RESP_FUNC_FAILED;
> -                       return rc;
> -               }
> -               device_id = pm8001_dev->device_id;
> -               PM8001_EH_DBG(pm8001_ha,
> -                       pm8001_printk("abort io to deviceid= %d\n", device_id));
>                 tmf_task.tmf = TMF_ABORT_TASK;
>                 tmf_task.tag_of_task_to_be_managed = tag;
>                 rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
> @@ -1200,33 +1207,75 @@ int pm8001_abort_task(struct sas_task *task)
>                         pm8001_dev->sas_device, 0, tag);
>         } else if (task->task_proto & SAS_PROTOCOL_SATA ||
>                 task->task_proto & SAS_PROTOCOL_STP) {
> -               dev = task->dev;
> -               pm8001_dev = dev->lldd_dev;
> -               pm8001_ha = pm8001_find_ha_by_dev(dev);
> -               rc = pm8001_find_tag(task, &tag);
> -               if (rc == 0) {
> -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> -                       rc = TMF_RESP_FUNC_FAILED;
> -                       return rc;
> +               if (pm8001_ha->chip_id == chip_8006) {
> +                       DECLARE_COMPLETION_ONSTACK(completion_reset);
> +                       DECLARE_COMPLETION_ONSTACK(completion);
> +                       struct pm8001_phy *phy = pm8001_ha->phy + phy_id;
> +
> +                       /* 1. Set Device state as Recovery*/
> +                       pm8001_dev->setds_completion = &completion;
> +                       PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
> +                               pm8001_dev, 0x03);
> +                       wait_for_completion(&completion);
> +
> +                       /* 2. Send Phy Control Hard Reset */
> +                       reinit_completion(&completion);
> +                       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)
> +                               goto out;
> +
> +                       /* 3. Wait for Port Reset complete / 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)
> +                               goto out;
> +
> +                       /* 4. SATA Abort ALL
> +                        * we wait for the task to be aborted so that the task
> +                        * is removed from the ccb. on success the caller is
> +                        * going to free the task.
> +                        */
> +                       ret = pm8001_exec_internal_task_abort(pm8001_ha,
> +                               pm8001_dev, pm8001_dev->sas_device, 1, tag);
> +                       if (ret)
> +                               goto out;
> +                       ret = wait_for_completion_timeout(
> +                               &task->slow_task->completion,
> +                               PM8001_TASK_TIMEOUT * HZ);
> +                       if (!ret)
> +                               goto out;
> +
> +                       /* 5. Set Device State as Operational */
> +                       reinit_completion(&completion);
> +                       pm8001_dev->setds_completion = &completion;
> +                       PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
> +                               pm8001_dev, 0x01);
> +                       wait_for_completion(&completion);
> +               } else {
> +                       rc = pm8001_exec_internal_task_abort(pm8001_ha,
> +                               pm8001_dev, pm8001_dev->sas_device, 0, tag);
>                 }
> -               rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
> -                       pm8001_dev->sas_device, 0, tag);
> +               rc = TMF_RESP_FUNC_COMPLETE;
>         } else if (task->task_proto & SAS_PROTOCOL_SMP) {
>                 /* SMP */
> -               dev = task->dev;
> -               pm8001_dev = dev->lldd_dev;
> -               pm8001_ha = pm8001_find_ha_by_dev(dev);
> -               rc = pm8001_find_tag(task, &tag);
> -               if (rc == 0) {
> -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> -                       rc = TMF_RESP_FUNC_FAILED;
> -                       return rc;
> -               }
>                 rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
>                         pm8001_dev->sas_device, 0, tag);
> -
>         }
>  out:
> +       spin_lock_irqsave(&task->task_state_lock, flags);
> +       if (task->slow_task == &slow_task)
> +               task->slow_task = NULL;
> +       spin_unlock_irqrestore(&task->task_state_lock, flags);
>         if (rc != TMF_RESP_FUNC_COMPLETE)
>                 pm8001_printk("rc= %d\n", rc);
>         return rc;
> diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> index 2eb3b670bf45..e6c0da17966e 100644
> --- a/drivers/scsi/pm8001/pm8001_sas.h
> +++ b/drivers/scsi/pm8001/pm8001_sas.h
> @@ -358,8 +358,15 @@ struct pm8001_phy {
>         u8                      phy_state;
>         enum sas_linkrate       minimum_linkrate;
>         enum sas_linkrate       maximum_linkrate;
> +       struct completion       *reset_completion;
> +       bool                    port_reset_status;
> +       bool                    reset_success;
>  };
>
> +/* port reset status */
> +#define PORT_RESET_SUCCESS     0x00
> +#define PORT_RESET_TMO         0x01
> +
>  struct pm8001_device {
>         enum sas_device_type    dev_type;
>         struct domain_device    *sas_device;
> @@ -628,6 +635,7 @@ struct pm8001_hba_info {
>         u32                     smp_exp_mode;
>         const struct firmware   *fw_image;
>         struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
> +       u32                     reset_in_progress;
Is this used?

>  };
>
>  struct pm8001_work {
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index a07b023c09bf..ae9252cf1706 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -597,6 +597,12 @@ static void update_main_config_table(struct pm8001_hba_info *pm8001_ha)
>         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &= 0xffff0000;
>         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
>                                                         PORT_RECOVERY_TIMEOUT;
> +       if (pm8001_ha->chip_id == chip_8006) {
> +               pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &=
> +                                                               0x0000ffff;
> +               pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
> +                                                               0x140000;
> +       }
Could be in a seperate patch with reason for 8006

>         pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER,
>                         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);
>  }
> @@ -1775,6 +1781,8 @@ mpi_ssp_completion(struct pm8001_hba_info *pm8001_ha , void *piomb)
>                         "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);
> @@ -3038,6 +3046,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
>
>         struct pm8001_port *port = &pm8001_ha->port[port_id];
>         struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
> +       u32 port_sata = (phy->phy_type & PORT_TYPE_SATA);
>         port->port_state = portstate;
>         phy->identify.device_type = 0;
>         phy->phy_attached = 0;
> @@ -3049,7 +3058,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                         pm8001_printk(" PortInvalid portID %d\n", port_id));
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk(" Last phy Down and port invalid\n"));
> -               if (phy->phy_type & PORT_TYPE_SATA) {
> +               if (port_sata) {
>                         phy->phy_type = 0;
>                         port->port_attached = 0;
>                         pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
> @@ -3071,7 +3080,7 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                         pm8001_printk(" Phy Down and PORT_LOSTCOMM\n"));
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk(" Last phy Down and port invalid\n"));
> -               if (phy->phy_type & PORT_TYPE_SATA) {
> +               if (port_sata) {
>                         port->port_attached = 0;
>                         phy->phy_type = 0;
>                         pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
> @@ -3087,6 +3096,11 @@ hw_event_phy_down(struct pm8001_hba_info *pm8001_ha, void *piomb)
>                 break;
>
>         }
> +       if (port_sata && (portstate != PORT_IN_RESET)) {
> +               struct sas_ha_struct *sas_ha = pm8001_ha->sas;
> +
> +               sas_ha->notify_phy_event(&phy->sas_phy, PHYE_LOSS_OF_SIGNAL);
> +       }
>  }
>
>  static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
> @@ -3189,12 +3203,14 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         case HW_EVENT_PHY_DOWN:
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk("HW_EVENT_PHY_DOWN\n"));
> -               if (phy->phy_type & PORT_TYPE_SATA)
> -                       sas_ha->notify_phy_event(&phy->sas_phy,
> -                               PHYE_LOSS_OF_SIGNAL);
> +               hw_event_phy_down(pm8001_ha, piomb);
> +               if (pm8001_ha->reset_in_progress) {
> +                       PM8001_MSG_DBG(pm8001_ha,
> +                               pm8001_printk("Reset in progress\n"));
> +                       return 0;
> +               }
>                 phy->phy_attached = 0;
>                 phy->phy_state = 0;
> -               hw_event_phy_down(pm8001_ha, piomb);
>                 break;
>         case HW_EVENT_PORT_INVALID:
>                 PM8001_MSG_DBG(pm8001_ha,
> @@ -3301,9 +3317,17 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         case HW_EVENT_PORT_RESET_TIMER_TMO:
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n"));
> +               pm80xx_hw_event_ack_req(pm8001_ha, 0, HW_EVENT_PHY_DOWN,
> +                       port_id, phy_id, 0, 0);
>                 sas_phy_disconnected(sas_phy);
>                 phy->phy_attached = 0;
>                 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
> +               if (pm8001_ha->phy[phy_id].reset_completion) {
> +                       pm8001_ha->phy[phy_id].port_reset_status =
> +                                                       PORT_RESET_TMO;
> +                       complete(pm8001_ha->phy[phy_id].reset_completion);
> +                       pm8001_ha->phy[phy_id].reset_completion = NULL;
> +               }
>                 break;
>         case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
>                 PM8001_MSG_DBG(pm8001_ha,
> @@ -3328,6 +3352,12 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
>         case HW_EVENT_PORT_RESET_COMPLETE:
>                 PM8001_MSG_DBG(pm8001_ha,
>                         pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n"));
> +               if (pm8001_ha->phy[phy_id].reset_completion) {
> +                       pm8001_ha->phy[phy_id].port_reset_status =
> +                                                       PORT_RESET_SUCCESS;
> +                       complete(pm8001_ha->phy[phy_id].reset_completion);
> +                       pm8001_ha->phy[phy_id].reset_completion = NULL;
> +               }
>                 break;
>         case EVENT_BROADCAST_ASYNCH_EVENT:
>                 PM8001_MSG_DBG(pm8001_ha,
> @@ -4500,17 +4530,21 @@ static int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
>  static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
>         u32 phyId, u32 phy_op)
>  {
> +       u32 tag;
> +       int rc;
>         struct local_phy_ctl_req payload;
>         struct inbound_queue_table *circularQ;
>         int ret;
>         u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
>         memset(&payload, 0, sizeof(payload));
> +       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> +       if (rc)
> +               return rc;
>         circularQ = &pm8001_ha->inbnd_q_tbl[0];
> -       payload.tag = cpu_to_le32(1);
> +       payload.tag = cpu_to_le32(tag);
>         payload.phyop_phyid =
>                 cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
> -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
> -       return ret;
> +       return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload, 0);
>  }
>
>  static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info *pm8001_ha)
> --
> 2.12.3
>

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

* Re: [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log
  2015-01-30  6:06 ` [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log Viswas G
@ 2017-08-29 11:49   ` Jack Wang
  0 siblings, 0 replies; 22+ messages in thread
From: Jack Wang @ 2017-08-29 11:49 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi.Tharmarajan

2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> when there's an error in 'ncq mode' the host has to read the ncq
> error log (10h) to clear the error state. however, the ccb that
> is setup for doing this doesn't setup the ccb so that the
> previous state is cleared. if the ccb was previously used for an IO
> n_elems is set and pm8001_ccb_task_free() treats this as the signal
> to go free a scatter-gather list (that's already been free-ed).
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
> Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> ---
>  drivers/scsi/pm8001/pm80xx_hwi.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> index ae9252cf1706..e75b0aa497f0 100644
> --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> @@ -1489,6 +1489,7 @@ static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
>         ccb->device = pm8001_ha_dev;
>         ccb->ccb_tag = ccb_tag;
>         ccb->task = task;
> +       ccb->n_elem = 0;
>         pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
>         pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
>
> --
> 2.12.3
>
Thanks.
Looks good to me!
Acked-by: Jack Wang <jinpu.wang@profitbricks.com>

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

* Re: [PATCH 6/6] pm80xx : corrected linkrate value.
  2017-08-29 11:08   ` Jack Wang
@ 2017-08-30  1:32     ` Martin K. Petersen
  0 siblings, 0 replies; 22+ messages in thread
From: Martin K. Petersen @ 2017-08-30  1:32 UTC (permalink / raw)
  To: Viswas G; +Cc: Jack Wang, linux-scsi, Vasanthalakshmi.Tharmarajan


Viswas,

Please send a v2 with correct dates and Jack's review tags added to each
patch.

Thank you!

-- 
Martin K. Petersen	Oracle Linux Engineering

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

* RE: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
  2017-08-29 11:19   ` Jack Wang
@ 2017-08-30 15:41     ` Viswas G
  2017-08-30 16:03       ` Jack Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2017-08-30 15:41 UTC (permalink / raw)
  To: Jack Wang; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

Hi Jack,

The firmware expectation is that there is no 4 byte CRC. This causes the IOMB to be generated incorrectly for PHY_START. Local structure for SAS Identify included in the driver so that it matches the Programmer's Manual and Firmware expectations.

The sas_identify struct from the kernel includes the checksum word (32-bits) . So it is 32 bytes rather than 28 bytes. The changed size for the sas identify frame means that the "spasti" field for PHY_START is at a different offset than documented, word 11 rather than word 10. We're not changing the phy analog settings so this doesn't really matter, but the docs indicate that the sas frame's crc isn't included. So having a local definition will be better than taking the system definition. 

Regards,
Viswas G

> -----Original Message-----
> From: Jack Wang [mailto:xjtuwjp@gmail.com]
> Sent: Tuesday, August 29, 2017 4:49 PM
> To: Viswas G <viswas.g@microsemi.com>
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> <vasanthalakshmi.thar@microsemi.com>
> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> > sas_identify structure defined by pm80xx doesn't have CRC field.
> > So added a new sas_identify structure without CRC.
> >
> > Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> > ---
> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
> >  drivers/scsi/pm8001/pm8001_sas.h | 95
> ++++++++++++++++++++++++++++++++++++++++
> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
> >  3 files changed, 97 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
> b/drivers/scsi/pm8001/pm8001_hwi.h
> > index e4867e690c84..f4331afe9b0b 100644
> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
> >  struct phy_start_req {
> >         __le32  tag;
> >         __le32  ase_sh_lm_slr_phyid;
> > -       struct sas_identify_frame sas_identify;
> > +       struct sas_identify_frame_local sas_identify;
> >         u32     reserved[5];
> >  } __attribute__((packed, aligned(4)));
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
> b/drivers/scsi/pm8001/pm8001_sas.h
> > index e81a8fa7ef1a..2e17505ed5b8 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
> pm8001_80xx_dispatch;
> >  struct pm8001_hba_info;
> >  struct pm8001_ccb_info;
> >  struct pm8001_device;
> > +#ifdef __LITTLE_ENDIAN_BITFIELD
> > +struct sas_identify_frame_local {
> > +       /* Byte 0 */
> > +       u8  frame_type:4;
> > +       u8  dev_type:3;
> > +       u8  _un0:1;
> > +
> > +       /* Byte 1 */
> > +       u8  _un1;
> > +
> > +       /* Byte 2 */
> > +       union {
> > +               struct {
> > +                       u8  _un20:1;
> > +                       u8  smp_iport:1;
> > +                       u8  stp_iport:1;
> > +                       u8  ssp_iport:1;
> > +                       u8  _un247:4;
> > +               };
> > +               u8 initiator_bits;
> > +       };
> > +
> > +       /* Byte 3 */
> > +       union {
> > +               struct {
> > +                       u8  _un30:1;
> > +                       u8 smp_tport:1;
> > +                       u8 stp_tport:1;
> > +                       u8 ssp_tport:1;
> > +                       u8 _un347:4;
> > +               };
> > +               u8 target_bits;
> > +       };
> > +
> > +       /* Byte 4 - 11 */
> > +       u8 _un4_11[8];
> > +
> > +       /* Byte 12 - 19 */
> > +       u8 sas_addr[SAS_ADDR_SIZE];
> > +
> > +       /* Byte 20 */
> > +       u8 phy_id;
> > +
> > +       u8 _un21_27[7];
> > +
> > +} __packed;
> > +
> > +#elif defined(__BIG_ENDIAN_BITFIELD)
> > +struct sas_identify_frame_local {
> > +       /* Byte 0 */
> > +       u8  _un0:1;
> > +       u8  dev_type:3;
> > +       u8  frame_type:4;
> > +
> > +       /* Byte 1 */
> > +       u8  _un1;
> > +
> > +       /* Byte 2 */
> > +       union {
> > +               struct {
> > +                       u8  _un247:4;
> > +                       u8  ssp_iport:1;
> > +                       u8  stp_iport:1;
> > +                       u8  smp_iport:1;
> > +                       u8  _un20:1;
> > +               };
> > +               u8 initiator_bits;
> > +       };
> > +
> > +       /* Byte 3 */
> > +       union {
> > +               struct {
> > +                       u8 _un347:4;
> > +                       u8 ssp_tport:1;
> > +                       u8 stp_tport:1;
> > +                       u8 smp_tport:1;
> > +                       u8 _un30:1;
> > +               };
> > +               u8 target_bits;
> > +       };
> > +
> > +       /* Byte 4 - 11 */
> > +       u8 _un4_11[8];
> > +
> > +       /* Byte 12 - 19 */
> > +       u8 sas_addr[SAS_ADDR_SIZE];
> > +
> > +       /* Byte 20 */
> > +       u8 phy_id;
> > +
> > +       u8 _un21_27[7];
> > +} __packed;
> > +#else
> > +#error "Bitfield order not defined!"
> > +#endif
> >  /* define task management IU */
> >  struct pm8001_tmf_task {
> >         u8      tmf;
> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h
> b/drivers/scsi/pm8001/pm80xx_hwi.h
> > index 7a443bad6163..1ee2ec210065 100644
> > --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> > @@ -248,7 +248,7 @@ struct mpi_msg_hdr {
> >  struct phy_start_req {
> >         __le32  tag;
> >         __le32  ase_sh_lm_slr_phyid;
> > -       struct sas_identify_frame sas_identify; /* 28 Bytes */
> > +       struct sas_identify_frame_local sas_identify; /* 28 Bytes */
> >         __le32 spasti;
> >         u32     reserved[21];
> >  } __attribute__((packed, aligned(4)));
> > --
> > 2.12.3
> >
> Did this cause any trouble? I guest not, as we does memset for
> phy_start_req,  why bother?
> 
> Jack

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

* RE: [PATCH 4/6] pm80xx : Corrected SATA abort handling.
  2017-08-29 11:46   ` Jack Wang
@ 2017-08-30 15:48     ` Viswas G
  0 siblings, 0 replies; 22+ messages in thread
From: Viswas G @ 2017-08-30 15:48 UTC (permalink / raw)
  To: Jack Wang; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

Thanks Jack. We will split this patch as you suggested and send V2.

Regards,
Viswas G

> -----Original Message-----
> From: Jack Wang [mailto:xjtuwjp@gmail.com]
> Sent: Tuesday, August 29, 2017 5:16 PM
> To: Viswas G <viswas.g@microsemi.com>
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> <vasanthalakshmi.thar@microsemi.com>
> Subject: Re: [PATCH 4/6] pm80xx : Corrected SATA abort handling.
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> > Modified SATA abort handling with following steps:
> > 1) Set device state as recovery.
> > 2) Send phy reset.
> > 3) Wait for reset completion.
> > 4) After successful reset, abort all IO's to the device.
> > 5) After aborting all IO's to device, set device state as operational.
> >
> > Signed-off-by: Deepak Ukey <deepak.ukey@microsemi.com>
> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> This one includes more than described above.
> Would be good to split it better.
> comments inline.
> 
> > ---
> >  drivers/scsi/pm8001/pm8001_hwi.c |  11 +++-
> >  drivers/scsi/pm8001/pm8001_sas.c | 125
> +++++++++++++++++++++++++++------------
> >  drivers/scsi/pm8001/pm8001_sas.h |   8 +++
> >  drivers/scsi/pm8001/pm80xx_hwi.c |  52 +++++++++++++---
> >  4 files changed, 148 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c
> b/drivers/scsi/pm8001/pm8001_hwi.c
> > index 10546faac58c..db88a8e7ee0e 100644
> > --- a/drivers/scsi/pm8001/pm8001_hwi.c
> > +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> > @@ -3198,19 +3198,28 @@ pm8001_mpi_get_nvmd_resp(struct
> pm8001_hba_info *pm8001_ha, void *piomb)
> >
> >  int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void
> *piomb)
> >  {
> > +       u32 tag;
> >         struct local_phy_ctl_resp *pPayload =
> >                 (struct local_phy_ctl_resp *)(piomb + 4);
> >         u32 status = le32_to_cpu(pPayload->status);
> >         u32 phy_id = le32_to_cpu(pPayload->phyop_phyid) & ID_BITS;
> >         u32 phy_op = le32_to_cpu(pPayload->phyop_phyid) & OP_BITS;
> > +       tag = le32_to_cpu(pPayload->tag);
> >         if (status != 0) {
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk("%x phy execute %x phy op failed!\n",
> >                         phy_id, phy_op));
> > -       } else
> > +       } else {
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk("%x phy execute %x phy op success!\n",
> >                         phy_id, phy_op));
> > +               pm8001_ha->phy[phy_id].reset_success = true;
> > +       }
> > +       if (pm8001_ha->phy[phy_id].enable_completion) {
> > +               complete(pm8001_ha->phy[phy_id].enable_completion);
> > +               pm8001_ha->phy[phy_id].enable_completion = NULL;
> > +       }
> > +       pm8001_tag_free(pm8001_ha, tag);
> >         return 0;
> >  }
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.c
> b/drivers/scsi/pm8001/pm8001_sas.c
> > index ce584c31d36e..a409d3a6a3cb 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.c
> > +++ b/drivers/scsi/pm8001/pm8001_sas.c
> > @@ -1159,40 +1159,47 @@ int pm8001_query_task(struct sas_task *task)
> >  int pm8001_abort_task(struct sas_task *task)
> >  {
> >         unsigned long flags;
> > -       u32 tag = 0xdeadbeef;
> > +       u32 tag;
> >         u32 device_id;
> >         struct domain_device *dev ;
> > -       struct pm8001_hba_info *pm8001_ha = NULL;
> > +       struct pm8001_hba_info *pm8001_ha;
> >         struct pm8001_ccb_info *ccb;
> >         struct scsi_lun lun;
> >         struct pm8001_device *pm8001_dev;
> >         struct pm8001_tmf_task tmf_task;
> > -       int rc = TMF_RESP_FUNC_FAILED;
> > +       int rc = TMF_RESP_FUNC_FAILED, ret;
> > +       u32 phy_id;
> > +       struct sas_task_slow slow_task;
> > +
> >         if (unlikely(!task || !task->lldd_task || !task->dev))
> > -               return rc;
> > +               return TMF_RESP_FUNC_FAILED;
> > +
> > +       dev = task->dev;
> > +       pm8001_dev = dev->lldd_dev;
> > +       pm8001_ha = pm8001_find_ha_by_dev(dev);
> > +       device_id = pm8001_dev->device_id;
> > +       phy_id = pm8001_dev->attached_phy;
> > +       rc = pm8001_find_tag(task, &tag);
> > +       if (rc == 0) {
> > +               pm8001_printk("no tag for task:%p\n", task);
> > +               return TMF_RESP_FUNC_FAILED;
> > +       }
> 
> This part is cleanup.
> >         spin_lock_irqsave(&task->task_state_lock, flags);
> >         if (task->task_state_flags & SAS_TASK_STATE_DONE) {
> >                 spin_unlock_irqrestore(&task->task_state_lock, flags);
> >                 rc = TMF_RESP_FUNC_COMPLETE;
> > -               goto out;
> > +       }
> > +
> > +       task->task_state_flags |= SAS_TASK_STATE_ABORTED;
> > +       if (task->slow_task == NULL) {
> > +               init_completion(&slow_task.completion);
> > +               task->slow_task = &slow_task;
> >         }
> >         spin_unlock_irqrestore(&task->task_state_lock, flags);
> > +
> >         if (task->task_proto & SAS_PROTOCOL_SSP) {
> >                 struct scsi_cmnd *cmnd = task->uldd_task;
> > -               dev = task->dev;
> > -               ccb = task->lldd_task;
> > -               pm8001_dev = dev->lldd_dev;
> > -               pm8001_ha = pm8001_find_ha_by_dev(dev);
> >                 int_to_scsilun(cmnd->device->lun, &lun);
> > -               rc = pm8001_find_tag(task, &tag);
> > -               if (rc == 0) {
> > -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> > -                       rc = TMF_RESP_FUNC_FAILED;
> > -                       return rc;
> > -               }
> > -               device_id = pm8001_dev->device_id;
> > -               PM8001_EH_DBG(pm8001_ha,
> > -                       pm8001_printk("abort io to deviceid= %d\n", device_id));
> >                 tmf_task.tmf = TMF_ABORT_TASK;
> >                 tmf_task.tag_of_task_to_be_managed = tag;
> >                 rc = pm8001_issue_ssp_tmf(dev, lun.scsi_lun, &tmf_task);
> > @@ -1200,33 +1207,75 @@ int pm8001_abort_task(struct sas_task *task)
> >                         pm8001_dev->sas_device, 0, tag);
> >         } else if (task->task_proto & SAS_PROTOCOL_SATA ||
> >                 task->task_proto & SAS_PROTOCOL_STP) {
> > -               dev = task->dev;
> > -               pm8001_dev = dev->lldd_dev;
> > -               pm8001_ha = pm8001_find_ha_by_dev(dev);
> > -               rc = pm8001_find_tag(task, &tag);
> > -               if (rc == 0) {
> > -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> > -                       rc = TMF_RESP_FUNC_FAILED;
> > -                       return rc;
> > +               if (pm8001_ha->chip_id == chip_8006) {
> > +                       DECLARE_COMPLETION_ONSTACK(completion_reset);
> > +                       DECLARE_COMPLETION_ONSTACK(completion);
> > +                       struct pm8001_phy *phy = pm8001_ha->phy + phy_id;
> > +
> > +                       /* 1. Set Device state as Recovery*/
> > +                       pm8001_dev->setds_completion = &completion;
> > +                       PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
> > +                               pm8001_dev, 0x03);
> > +                       wait_for_completion(&completion);
> > +
> > +                       /* 2. Send Phy Control Hard Reset */
> > +                       reinit_completion(&completion);
> > +                       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)
> > +                               goto out;
> > +
> > +                       /* 3. Wait for Port Reset complete / 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)
> > +                               goto out;
> > +
> > +                       /* 4. SATA Abort ALL
> > +                        * we wait for the task to be aborted so that the task
> > +                        * is removed from the ccb. on success the caller is
> > +                        * going to free the task.
> > +                        */
> > +                       ret = pm8001_exec_internal_task_abort(pm8001_ha,
> > +                               pm8001_dev, pm8001_dev->sas_device, 1, tag);
> > +                       if (ret)
> > +                               goto out;
> > +                       ret = wait_for_completion_timeout(
> > +                               &task->slow_task->completion,
> > +                               PM8001_TASK_TIMEOUT * HZ);
> > +                       if (!ret)
> > +                               goto out;
> > +
> > +                       /* 5. Set Device State as Operational */
> > +                       reinit_completion(&completion);
> > +                       pm8001_dev->setds_completion = &completion;
> > +                       PM8001_CHIP_DISP->set_dev_state_req(pm8001_ha,
> > +                               pm8001_dev, 0x01);
> > +                       wait_for_completion(&completion);
> > +               } else {
> > +                       rc = pm8001_exec_internal_task_abort(pm8001_ha,
> > +                               pm8001_dev, pm8001_dev->sas_device, 0, tag);
> >                 }
> > -               rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
> > -                       pm8001_dev->sas_device, 0, tag);
> > +               rc = TMF_RESP_FUNC_COMPLETE;
> >         } else if (task->task_proto & SAS_PROTOCOL_SMP) {
> >                 /* SMP */
> > -               dev = task->dev;
> > -               pm8001_dev = dev->lldd_dev;
> > -               pm8001_ha = pm8001_find_ha_by_dev(dev);
> > -               rc = pm8001_find_tag(task, &tag);
> > -               if (rc == 0) {
> > -                       printk(KERN_INFO "No such tag in %s\n", __func__);
> > -                       rc = TMF_RESP_FUNC_FAILED;
> > -                       return rc;
> > -               }
> >                 rc = pm8001_exec_internal_task_abort(pm8001_ha, pm8001_dev,
> >                         pm8001_dev->sas_device, 0, tag);
> > -
> >         }
> >  out:
> > +       spin_lock_irqsave(&task->task_state_lock, flags);
> > +       if (task->slow_task == &slow_task)
> > +               task->slow_task = NULL;
> > +       spin_unlock_irqrestore(&task->task_state_lock, flags);
> >         if (rc != TMF_RESP_FUNC_COMPLETE)
> >                 pm8001_printk("rc= %d\n", rc);
> >         return rc;
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
> b/drivers/scsi/pm8001/pm8001_sas.h
> > index 2eb3b670bf45..e6c0da17966e 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> > @@ -358,8 +358,15 @@ struct pm8001_phy {
> >         u8                      phy_state;
> >         enum sas_linkrate       minimum_linkrate;
> >         enum sas_linkrate       maximum_linkrate;
> > +       struct completion       *reset_completion;
> > +       bool                    port_reset_status;
> > +       bool                    reset_success;
> >  };
> >
> > +/* port reset status */
> > +#define PORT_RESET_SUCCESS     0x00
> > +#define PORT_RESET_TMO         0x01
> > +
> >  struct pm8001_device {
> >         enum sas_device_type    dev_type;
> >         struct domain_device    *sas_device;
> > @@ -628,6 +635,7 @@ struct pm8001_hba_info {
> >         u32                     smp_exp_mode;
> >         const struct firmware   *fw_image;
> >         struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
> > +       u32                     reset_in_progress;
> Is this used?
> 
> >  };
> >
> >  struct pm8001_work {
> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c
> b/drivers/scsi/pm8001/pm80xx_hwi.c
> > index a07b023c09bf..ae9252cf1706 100644
> > --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> > @@ -597,6 +597,12 @@ static void update_main_config_table(struct
> pm8001_hba_info *pm8001_ha)
> >         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &=
> 0xffff0000;
> >         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
> >                                                         PORT_RECOVERY_TIMEOUT;
> > +       if (pm8001_ha->chip_id == chip_8006) {
> > +               pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer &=
> > +                                                               0x0000ffff;
> > +               pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer |=
> > +                                                               0x140000;
> > +       }
> Could be in a seperate patch with reason for 8006
> 
> >         pm8001_mw32(address, MAIN_PORT_RECOVERY_TIMER,
> >                         pm8001_ha->main_cfg_tbl.pm80xx_tbl.port_recovery_timer);
> >  }
> > @@ -1775,6 +1781,8 @@ mpi_ssp_completion(struct pm8001_hba_info
> *pm8001_ha , void *piomb)
> >                         "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);
> > @@ -3038,6 +3046,7 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> >
> >         struct pm8001_port *port = &pm8001_ha->port[port_id];
> >         struct pm8001_phy *phy = &pm8001_ha->phy[phy_id];
> > +       u32 port_sata = (phy->phy_type & PORT_TYPE_SATA);
> >         port->port_state = portstate;
> >         phy->identify.device_type = 0;
> >         phy->phy_attached = 0;
> > @@ -3049,7 +3058,7 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> >                         pm8001_printk(" PortInvalid portID %d\n", port_id));
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk(" Last phy Down and port invalid\n"));
> > -               if (phy->phy_type & PORT_TYPE_SATA) {
> > +               if (port_sata) {
> >                         phy->phy_type = 0;
> >                         port->port_attached = 0;
> >                         pm80xx_hw_event_ack_req(pm8001_ha, 0,
> HW_EVENT_PHY_DOWN,
> > @@ -3071,7 +3080,7 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> >                         pm8001_printk(" Phy Down and PORT_LOSTCOMM\n"));
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk(" Last phy Down and port invalid\n"));
> > -               if (phy->phy_type & PORT_TYPE_SATA) {
> > +               if (port_sata) {
> >                         port->port_attached = 0;
> >                         phy->phy_type = 0;
> >                         pm80xx_hw_event_ack_req(pm8001_ha, 0,
> HW_EVENT_PHY_DOWN,
> > @@ -3087,6 +3096,11 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> >                 break;
> >
> >         }
> > +       if (port_sata && (portstate != PORT_IN_RESET)) {
> > +               struct sas_ha_struct *sas_ha = pm8001_ha->sas;
> > +
> > +               sas_ha->notify_phy_event(&phy->sas_phy,
> PHYE_LOSS_OF_SIGNAL);
> > +       }
> >  }
> >
> >  static int mpi_phy_start_resp(struct pm8001_hba_info *pm8001_ha, void
> *piomb)
> > @@ -3189,12 +3203,14 @@ static int mpi_hw_event(struct
> pm8001_hba_info *pm8001_ha, void *piomb)
> >         case HW_EVENT_PHY_DOWN:
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk("HW_EVENT_PHY_DOWN\n"));
> > -               if (phy->phy_type & PORT_TYPE_SATA)
> > -                       sas_ha->notify_phy_event(&phy->sas_phy,
> > -                               PHYE_LOSS_OF_SIGNAL);
> > +               hw_event_phy_down(pm8001_ha, piomb);
> > +               if (pm8001_ha->reset_in_progress) {
> > +                       PM8001_MSG_DBG(pm8001_ha,
> > +                               pm8001_printk("Reset in progress\n"));
> > +                       return 0;
> > +               }
> >                 phy->phy_attached = 0;
> >                 phy->phy_state = 0;
> > -               hw_event_phy_down(pm8001_ha, piomb);
> >                 break;
> >         case HW_EVENT_PORT_INVALID:
> >                 PM8001_MSG_DBG(pm8001_ha,
> > @@ -3301,9 +3317,17 @@ static int mpi_hw_event(struct
> pm8001_hba_info *pm8001_ha, void *piomb)
> >         case HW_EVENT_PORT_RESET_TIMER_TMO:
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk("HW_EVENT_PORT_RESET_TIMER_TMO\n"));
> > +               pm80xx_hw_event_ack_req(pm8001_ha, 0,
> HW_EVENT_PHY_DOWN,
> > +                       port_id, phy_id, 0, 0);
> >                 sas_phy_disconnected(sas_phy);
> >                 phy->phy_attached = 0;
> >                 sas_ha->notify_port_event(sas_phy, PORTE_LINK_RESET_ERR);
> > +               if (pm8001_ha->phy[phy_id].reset_completion) {
> > +                       pm8001_ha->phy[phy_id].port_reset_status =
> > +                                                       PORT_RESET_TMO;
> > +                       complete(pm8001_ha->phy[phy_id].reset_completion);
> > +                       pm8001_ha->phy[phy_id].reset_completion = NULL;
> > +               }
> >                 break;
> >         case HW_EVENT_PORT_RECOVERY_TIMER_TMO:
> >                 PM8001_MSG_DBG(pm8001_ha,
> > @@ -3328,6 +3352,12 @@ static int mpi_hw_event(struct
> pm8001_hba_info *pm8001_ha, void *piomb)
> >         case HW_EVENT_PORT_RESET_COMPLETE:
> >                 PM8001_MSG_DBG(pm8001_ha,
> >                         pm8001_printk("HW_EVENT_PORT_RESET_COMPLETE\n"));
> > +               if (pm8001_ha->phy[phy_id].reset_completion) {
> > +                       pm8001_ha->phy[phy_id].port_reset_status =
> > +                                                       PORT_RESET_SUCCESS;
> > +                       complete(pm8001_ha->phy[phy_id].reset_completion);
> > +                       pm8001_ha->phy[phy_id].reset_completion = NULL;
> > +               }
> >                 break;
> >         case EVENT_BROADCAST_ASYNCH_EVENT:
> >                 PM8001_MSG_DBG(pm8001_ha,
> > @@ -4500,17 +4530,21 @@ static int pm80xx_chip_reg_dev_req(struct
> pm8001_hba_info *pm8001_ha,
> >  static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info
> *pm8001_ha,
> >         u32 phyId, u32 phy_op)
> >  {
> > +       u32 tag;
> > +       int rc;
> >         struct local_phy_ctl_req payload;
> >         struct inbound_queue_table *circularQ;
> >         int ret;
> >         u32 opc = OPC_INB_LOCAL_PHY_CONTROL;
> >         memset(&payload, 0, sizeof(payload));
> > +       rc = pm8001_tag_alloc(pm8001_ha, &tag);
> > +       if (rc)
> > +               return rc;
> >         circularQ = &pm8001_ha->inbnd_q_tbl[0];
> > -       payload.tag = cpu_to_le32(1);
> > +       payload.tag = cpu_to_le32(tag);
> >         payload.phyop_phyid =
> >                 cpu_to_le32(((phy_op & 0xFF) << 8) | (phyId & 0xFF));
> > -       ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> 0);
> > -       return ret;
> > +       return pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
> 0);
> >  }
> >
> >  static u32 pm80xx_chip_is_our_interupt(struct pm8001_hba_info
> *pm8001_ha)
> > --
> > 2.12.3
> >

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

* Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
  2017-08-30 15:41     ` Viswas G
@ 2017-08-30 16:03       ` Jack Wang
  2017-08-30 16:28         ` Viswas G
  0 siblings, 1 reply; 22+ messages in thread
From: Jack Wang @ 2017-08-30 16:03 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

2017-08-30 17:41 GMT+02:00 Viswas G <viswas.g@microsemi.com>:
> Hi Jack,
>
> The firmware expectation is that there is no 4 byte CRC. This causes the IOMB to be generated incorrectly for PHY_START. Local structure for SAS Identify included in the driver so that it matches the Programmer's Manual and Firmware expectations.
>
> The sas_identify struct from the kernel includes the checksum word (32-bits) . So it is 32 bytes rather than 28 bytes. The changed size for the sas identify frame means that the "spasti" field for PHY_START is at a different offset than documented, word 11 rather than word 10. We're not changing the phy analog settings so this doesn't really matter, but the docs indicate that the sas frame's crc isn't included. So having a local definition will be better than taking the system definition.
>
> Regards,
> Viswas G

Hi Viswas,

The spasti field is only for pm80xx, not for pm8001, I think it's
better to move sas_identify_frame_local to pm80xx_hwi.h.

Regards,
Jack


>
>> -----Original Message-----
>> From: Jack Wang [mailto:xjtuwjp@gmail.com]
>> Sent: Tuesday, August 29, 2017 4:49 PM
>> To: Viswas G <viswas.g@microsemi.com>
>> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
>> <vasanthalakshmi.thar@microsemi.com>
>> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
>>
>> EXTERNAL EMAIL
>>
>>
>> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
>> > sas_identify structure defined by pm80xx doesn't have CRC field.
>> > So added a new sas_identify structure without CRC.
>> >
>> > Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
>> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
>> > ---
>> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
>> >  drivers/scsi/pm8001/pm8001_sas.h | 95
>> ++++++++++++++++++++++++++++++++++++++++
>> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
>> >  3 files changed, 97 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
>> b/drivers/scsi/pm8001/pm8001_hwi.h
>> > index e4867e690c84..f4331afe9b0b 100644
>> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
>> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
>> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
>> >  struct phy_start_req {
>> >         __le32  tag;
>> >         __le32  ase_sh_lm_slr_phyid;
>> > -       struct sas_identify_frame sas_identify;
>> > +       struct sas_identify_frame_local sas_identify;
>> >         u32     reserved[5];
>> >  } __attribute__((packed, aligned(4)));
>> >
>> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
>> b/drivers/scsi/pm8001/pm8001_sas.h
>> > index e81a8fa7ef1a..2e17505ed5b8 100644
>> > --- a/drivers/scsi/pm8001/pm8001_sas.h
>> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
>> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
>> pm8001_80xx_dispatch;
>> >  struct pm8001_hba_info;
>> >  struct pm8001_ccb_info;
>> >  struct pm8001_device;
>> > +#ifdef __LITTLE_ENDIAN_BITFIELD
>> > +struct sas_identify_frame_local {
>> > +       /* Byte 0 */
>> > +       u8  frame_type:4;
>> > +       u8  dev_type:3;
>> > +       u8  _un0:1;
>> > +
>> > +       /* Byte 1 */
>> > +       u8  _un1;
>> > +
>> > +       /* Byte 2 */
>> > +       union {
>> > +               struct {
>> > +                       u8  _un20:1;
>> > +                       u8  smp_iport:1;
>> > +                       u8  stp_iport:1;
>> > +                       u8  ssp_iport:1;
>> > +                       u8  _un247:4;
>> > +               };
>> > +               u8 initiator_bits;
>> > +       };
>> > +
>> > +       /* Byte 3 */
>> > +       union {
>> > +               struct {
>> > +                       u8  _un30:1;
>> > +                       u8 smp_tport:1;
>> > +                       u8 stp_tport:1;
>> > +                       u8 ssp_tport:1;
>> > +                       u8 _un347:4;
>> > +               };
>> > +               u8 target_bits;
>> > +       };
>> > +
>> > +       /* Byte 4 - 11 */
>> > +       u8 _un4_11[8];
>> > +
>> > +       /* Byte 12 - 19 */
>> > +       u8 sas_addr[SAS_ADDR_SIZE];
>> > +
>> > +       /* Byte 20 */
>> > +       u8 phy_id;
>> > +
>> > +       u8 _un21_27[7];
>> > +
>> > +} __packed;
>> > +
>> > +#elif defined(__BIG_ENDIAN_BITFIELD)
>> > +struct sas_identify_frame_local {
>> > +       /* Byte 0 */
>> > +       u8  _un0:1;
>> > +       u8  dev_type:3;
>> > +       u8  frame_type:4;
>> > +
>> > +       /* Byte 1 */
>> > +       u8  _un1;
>> > +
>> > +       /* Byte 2 */
>> > +       union {
>> > +               struct {
>> > +                       u8  _un247:4;
>> > +                       u8  ssp_iport:1;
>> > +                       u8  stp_iport:1;
>> > +                       u8  smp_iport:1;
>> > +                       u8  _un20:1;
>> > +               };
>> > +               u8 initiator_bits;
>> > +       };
>> > +
>> > +       /* Byte 3 */
>> > +       union {
>> > +               struct {
>> > +                       u8 _un347:4;
>> > +                       u8 ssp_tport:1;
>> > +                       u8 stp_tport:1;
>> > +                       u8 smp_tport:1;
>> > +                       u8 _un30:1;
>> > +               };
>> > +               u8 target_bits;
>> > +       };
>> > +
>> > +       /* Byte 4 - 11 */
>> > +       u8 _un4_11[8];
>> > +
>> > +       /* Byte 12 - 19 */
>> > +       u8 sas_addr[SAS_ADDR_SIZE];
>> > +
>> > +       /* Byte 20 */
>> > +       u8 phy_id;
>> > +
>> > +       u8 _un21_27[7];
>> > +} __packed;
>> > +#else
>> > +#error "Bitfield order not defined!"
>> > +#endif
>> >  /* define task management IU */
>> >  struct pm8001_tmf_task {
>> >         u8      tmf;
>> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h
>> b/drivers/scsi/pm8001/pm80xx_hwi.h
>> > index 7a443bad6163..1ee2ec210065 100644
>> > --- a/drivers/scsi/pm8001/pm80xx_hwi.h
>> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
>> > @@ -248,7 +248,7 @@ struct mpi_msg_hdr {
>> >  struct phy_start_req {
>> >         __le32  tag;
>> >         __le32  ase_sh_lm_slr_phyid;
>> > -       struct sas_identify_frame sas_identify; /* 28 Bytes */
>> > +       struct sas_identify_frame_local sas_identify; /* 28 Bytes */
>> >         __le32 spasti;
>> >         u32     reserved[21];
>> >  } __attribute__((packed, aligned(4)));
>> > --
>> > 2.12.3
>> >
>> Did this cause any trouble? I guest not, as we does memset for
>> phy_start_req,  why bother?
>>
>> Jack

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

* RE: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
  2017-08-30 16:03       ` Jack Wang
@ 2017-08-30 16:28         ` Viswas G
  0 siblings, 0 replies; 22+ messages in thread
From: Viswas G @ 2017-08-30 16:28 UTC (permalink / raw)
  To: Jack Wang; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

Thanks. We will move that to pm80xx_hwi.h.

Regards,
Viswas G

> -----Original Message-----
> From: Jack Wang [mailto:xjtuwjp@gmail.com]
> Sent: Wednesday, August 30, 2017 9:34 PM
> To: Viswas G <viswas.g@microsemi.com>
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> <vasanthalakshmi.thar@microsemi.com>
> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> 
> EXTERNAL EMAIL
> 
> 
> 2017-08-30 17:41 GMT+02:00 Viswas G <viswas.g@microsemi.com>:
> > Hi Jack,
> >
> > The firmware expectation is that there is no 4 byte CRC. This causes the
> IOMB to be generated incorrectly for PHY_START. Local structure for SAS
> Identify included in the driver so that it matches the Programmer's Manual
> and Firmware expectations.
> >
> > The sas_identify struct from the kernel includes the checksum word (32-
> bits) . So it is 32 bytes rather than 28 bytes. The changed size for the sas
> identify frame means that the "spasti" field for PHY_START is at a different
> offset than documented, word 11 rather than word 10. We're not changing
> the phy analog settings so this doesn't really matter, but the docs indicate
> that the sas frame's crc isn't included. So having a local definition will be
> better than taking the system definition.
> >
> > Regards,
> > Viswas G
> 
> Hi Viswas,
> 
> The spasti field is only for pm80xx, not for pm8001, I think it's
> better to move sas_identify_frame_local to pm80xx_hwi.h.
> 
> Regards,
> Jack
> 
> 
> >
> >> -----Original Message-----
> >> From: Jack Wang [mailto:xjtuwjp@gmail.com]
> >> Sent: Tuesday, August 29, 2017 4:49 PM
> >> To: Viswas G <viswas.g@microsemi.com>
> >> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> >> <vasanthalakshmi.thar@microsemi.com>
> >> Subject: Re: [PATCH 1/6] pm80xx : redefine sas_identify_frame structure
> >>
> >> EXTERNAL EMAIL
> >>
> >>
> >> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> >> > sas_identify structure defined by pm80xx doesn't have CRC field.
> >> > So added a new sas_identify structure without CRC.
> >> >
> >> > Signed-off-by: Raj Dinesh <Raj.Dinesh@microsemi.com>
> >> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> >> > ---
> >> >  drivers/scsi/pm8001/pm8001_hwi.h |  2 +-
> >> >  drivers/scsi/pm8001/pm8001_sas.h | 95
> >> ++++++++++++++++++++++++++++++++++++++++
> >> >  drivers/scsi/pm8001/pm80xx_hwi.h |  2 +-
> >> >  3 files changed, 97 insertions(+), 2 deletions(-)
> >> >
> >> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.h
> >> b/drivers/scsi/pm8001/pm8001_hwi.h
> >> > index e4867e690c84..f4331afe9b0b 100644
> >> > --- a/drivers/scsi/pm8001/pm8001_hwi.h
> >> > +++ b/drivers/scsi/pm8001/pm8001_hwi.h
> >> > @@ -157,7 +157,7 @@ struct mpi_msg_hdr{
> >> >  struct phy_start_req {
> >> >         __le32  tag;
> >> >         __le32  ase_sh_lm_slr_phyid;
> >> > -       struct sas_identify_frame sas_identify;
> >> > +       struct sas_identify_frame_local sas_identify;
> >> >         u32     reserved[5];
> >> >  } __attribute__((packed, aligned(4)));
> >> >
> >> > diff --git a/drivers/scsi/pm8001/pm8001_sas.h
> >> b/drivers/scsi/pm8001/pm8001_sas.h
> >> > index e81a8fa7ef1a..2e17505ed5b8 100644
> >> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> >> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> >> > @@ -118,6 +118,101 @@ extern const struct pm8001_dispatch
> >> pm8001_80xx_dispatch;
> >> >  struct pm8001_hba_info;
> >> >  struct pm8001_ccb_info;
> >> >  struct pm8001_device;
> >> > +#ifdef __LITTLE_ENDIAN_BITFIELD
> >> > +struct sas_identify_frame_local {
> >> > +       /* Byte 0 */
> >> > +       u8  frame_type:4;
> >> > +       u8  dev_type:3;
> >> > +       u8  _un0:1;
> >> > +
> >> > +       /* Byte 1 */
> >> > +       u8  _un1;
> >> > +
> >> > +       /* Byte 2 */
> >> > +       union {
> >> > +               struct {
> >> > +                       u8  _un20:1;
> >> > +                       u8  smp_iport:1;
> >> > +                       u8  stp_iport:1;
> >> > +                       u8  ssp_iport:1;
> >> > +                       u8  _un247:4;
> >> > +               };
> >> > +               u8 initiator_bits;
> >> > +       };
> >> > +
> >> > +       /* Byte 3 */
> >> > +       union {
> >> > +               struct {
> >> > +                       u8  _un30:1;
> >> > +                       u8 smp_tport:1;
> >> > +                       u8 stp_tport:1;
> >> > +                       u8 ssp_tport:1;
> >> > +                       u8 _un347:4;
> >> > +               };
> >> > +               u8 target_bits;
> >> > +       };
> >> > +
> >> > +       /* Byte 4 - 11 */
> >> > +       u8 _un4_11[8];
> >> > +
> >> > +       /* Byte 12 - 19 */
> >> > +       u8 sas_addr[SAS_ADDR_SIZE];
> >> > +
> >> > +       /* Byte 20 */
> >> > +       u8 phy_id;
> >> > +
> >> > +       u8 _un21_27[7];
> >> > +
> >> > +} __packed;
> >> > +
> >> > +#elif defined(__BIG_ENDIAN_BITFIELD)
> >> > +struct sas_identify_frame_local {
> >> > +       /* Byte 0 */
> >> > +       u8  _un0:1;
> >> > +       u8  dev_type:3;
> >> > +       u8  frame_type:4;
> >> > +
> >> > +       /* Byte 1 */
> >> > +       u8  _un1;
> >> > +
> >> > +       /* Byte 2 */
> >> > +       union {
> >> > +               struct {
> >> > +                       u8  _un247:4;
> >> > +                       u8  ssp_iport:1;
> >> > +                       u8  stp_iport:1;
> >> > +                       u8  smp_iport:1;
> >> > +                       u8  _un20:1;
> >> > +               };
> >> > +               u8 initiator_bits;
> >> > +       };
> >> > +
> >> > +       /* Byte 3 */
> >> > +       union {
> >> > +               struct {
> >> > +                       u8 _un347:4;
> >> > +                       u8 ssp_tport:1;
> >> > +                       u8 stp_tport:1;
> >> > +                       u8 smp_tport:1;
> >> > +                       u8 _un30:1;
> >> > +               };
> >> > +               u8 target_bits;
> >> > +       };
> >> > +
> >> > +       /* Byte 4 - 11 */
> >> > +       u8 _un4_11[8];
> >> > +
> >> > +       /* Byte 12 - 19 */
> >> > +       u8 sas_addr[SAS_ADDR_SIZE];
> >> > +
> >> > +       /* Byte 20 */
> >> > +       u8 phy_id;
> >> > +
> >> > +       u8 _un21_27[7];
> >> > +} __packed;
> >> > +#else
> >> > +#error "Bitfield order not defined!"
> >> > +#endif
> >> >  /* define task management IU */
> >> >  struct pm8001_tmf_task {
> >> >         u8      tmf;
> >> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h
> >> b/drivers/scsi/pm8001/pm80xx_hwi.h
> >> > index 7a443bad6163..1ee2ec210065 100644
> >> > --- a/drivers/scsi/pm8001/pm80xx_hwi.h
> >> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h
> >> > @@ -248,7 +248,7 @@ struct mpi_msg_hdr {
> >> >  struct phy_start_req {
> >> >         __le32  tag;
> >> >         __le32  ase_sh_lm_slr_phyid;
> >> > -       struct sas_identify_frame sas_identify; /* 28 Bytes */
> >> > +       struct sas_identify_frame_local sas_identify; /* 28 Bytes */
> >> >         __le32 spasti;
> >> >         u32     reserved[21];
> >> >  } __attribute__((packed, aligned(4)));
> >> > --
> >> > 2.12.3
> >> >
> >> Did this cause any trouble? I guest not, as we does memset for
> >> phy_start_req,  why bother?
> >>
> >> Jack

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

* RE: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
  2017-08-29 11:25   ` Jack Wang
@ 2017-08-30 16:55     ` Viswas G
  2017-09-01  8:52       ` Jack Wang
  0 siblings, 1 reply; 22+ messages in thread
From: Viswas G @ 2017-08-30 16:55 UTC (permalink / raw)
  To: Jack Wang; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

Hi Jack,

This is a customer requirement. Since the SAS addresses of all the phys were same , when the attached SAS addresses are different, it was forming only one domain.  If we assign different SAS addresses, this will cause duplicate domain unless we set the strict_wide_port to 1.

Regards,
Viswas G


> -----Original Message-----
> From: Jack Wang [mailto:xjtuwjp@gmail.com]
> Sent: Tuesday, August 29, 2017 4:55 PM
> To: Viswas G <viswas.g@microsemi.com>
> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
> <vasanthalakshmi.thar@microsemi.com>
> Subject: Re: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
> 
> EXTERNAL EMAIL
> 
> 
> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
> > Different SAS addresses are assigned for each set of phys.
> >
> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
> > ---
> >  drivers/scsi/pm8001/pm8001_init.c | 13 +++++++++----
> >  drivers/scsi/pm8001/pm80xx_hwi.c  |  3 +--
> >  2 files changed, 10 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_init.c
> b/drivers/scsi/pm8001/pm8001_init.c
> > index 034b2f7d1135..d282f1562615 100644
> > --- a/drivers/scsi/pm8001/pm8001_init.c
> > +++ b/drivers/scsi/pm8001/pm8001_init.c
> > @@ -132,7 +132,7 @@ static void pm8001_phy_init(struct
> pm8001_hba_info *pm8001_ha, int phy_id)
> >         sas_phy->oob_mode = OOB_NOT_CONNECTED;
> >         sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
> >         sas_phy->id = phy_id;
> > -       sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
> > +       sas_phy->sas_addr = (u8 *)&phy->dev_sas_addr;
> >         sas_phy->frame_rcvd = &phy->frame_rcvd[0];
> >         sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
> >         sas_phy->lldd_phy = phy;
> > @@ -593,10 +593,12 @@ static void  pm8001_post_sas_ha_init(struct
> Scsi_Host *shost,
> >         for (i = 0; i < chip_info->n_phy; i++) {
> >                 sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
> >                 sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
> > +               sha->sas_phy[i]->sas_addr =
> > +                       (u8 *)&pm8001_ha->phy[i].dev_sas_addr;
> >         }
> >         sha->sas_ha_name = DRV_NAME;
> >         sha->dev = pm8001_ha->dev;
> > -
> > +       sha->strict_wide_ports = 1;
> >         sha->lldd_module = THIS_MODULE;
> >         sha->sas_addr = &pm8001_ha->sas_addr[0];
> >         sha->num_phys = chip_info->n_phy;
> > @@ -613,6 +615,7 @@ static void  pm8001_post_sas_ha_init(struct
> Scsi_Host *shost,
> >  static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
> >  {
> >         u8 i, j;
> > +       u8 sas_add[8];
> >  #ifdef PM8001_READ_VPD
> >         /* For new SPC controllers WWN is stored in flash vpd
> >         *  For SPC/SPCve controllers WWN is stored in EEPROM
> > @@ -674,10 +677,12 @@ static void pm8001_init_sas_add(struct
> pm8001_hba_info *pm8001_ha)
> >                         pm8001_ha->sas_addr[j] =
> >                                         payload.func_specific[0x804 + i];
> >         }
> > -
> > +       memcpy(sas_add, pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> >         for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
> > +               if (i && ((i % 4) == 0))
> > +                       sas_add[7] = sas_add[7] + 4;
> >                 memcpy(&pm8001_ha->phy[i].dev_sas_addr,
> > -                       pm8001_ha->sas_addr, SAS_ADDR_SIZE);
> > +                       sas_add, SAS_ADDR_SIZE);
> >                 PM8001_INIT_DBG(pm8001_ha,
> >                         pm8001_printk("phy %d sas_addr = %016llx\n", i,
> >                         pm8001_ha->phy[i].dev_sas_addr));
> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c
> b/drivers/scsi/pm8001/pm80xx_hwi.c
> > index 8fb5ddf08cc4..a07b023c09bf 100644
> > --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> > @@ -3041,7 +3041,6 @@ hw_event_phy_down(struct pm8001_hba_info
> *pm8001_ha, void *piomb)
> >         port->port_state = portstate;
> >         phy->identify.device_type = 0;
> >         phy->phy_attached = 0;
> > -       memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
> >         switch (portstate) {
> >         case PORT_VALID:
> >                 break;
> > @@ -4394,7 +4393,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->sas_addr, SAS_ADDR_SIZE);
> > +               &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);
> >         return ret;
> > --
> > 2.12.3
> >
> This removes the possibility to form a wide port, why do you want to do it?

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

* Re: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
  2017-08-30 16:55     ` Viswas G
@ 2017-09-01  8:52       ` Jack Wang
  0 siblings, 0 replies; 22+ messages in thread
From: Jack Wang @ 2017-09-01  8:52 UTC (permalink / raw)
  To: Viswas G; +Cc: linux-scsi, Vasanthalakshmi Tharmarajan

2017-08-30 18:55 GMT+02:00 Viswas G <viswas.g@microsemi.com>:
> Hi Jack,
>
> This is a customer requirement. Since the SAS addresses of all the phys were same , when the attached SAS addresses are different, it was forming only one domain.  If we assign different SAS addresses, this will cause duplicate domain unless we set the strict_wide_port to 1.
>
> Regards,
> Viswas G

Ok, understand now!

Acked-by: Jack Wang <jinpu.wang@profitbricks.com>
Thanks!
>
>
>> -----Original Message-----
>> From: Jack Wang [mailto:xjtuwjp@gmail.com]
>> Sent: Tuesday, August 29, 2017 4:55 PM
>> To: Viswas G <viswas.g@microsemi.com>
>> Cc: linux-scsi@vger.kernel.org; Vasanthalakshmi Tharmarajan
>> <vasanthalakshmi.thar@microsemi.com>
>> Subject: Re: [PATCH 3/6] pm80xx : Different SAS addresses for phys.
>>
>> EXTERNAL EMAIL
>>
>>
>> 2015-01-30 7:06 GMT+01:00 Viswas G <Viswas.G@microsemi.com>:
>> > Different SAS addresses are assigned for each set of phys.
>> >
>> > Signed-off-by: Viswas G <Viswas.G@microsemi.com>
>> > ---
>> >  drivers/scsi/pm8001/pm8001_init.c | 13 +++++++++----
>> >  drivers/scsi/pm8001/pm80xx_hwi.c  |  3 +--
>> >  2 files changed, 10 insertions(+), 6 deletions(-)
>> >
>> > diff --git a/drivers/scsi/pm8001/pm8001_init.c
>> b/drivers/scsi/pm8001/pm8001_init.c
>> > index 034b2f7d1135..d282f1562615 100644
>> > --- a/drivers/scsi/pm8001/pm8001_init.c
>> > +++ b/drivers/scsi/pm8001/pm8001_init.c
>> > @@ -132,7 +132,7 @@ static void pm8001_phy_init(struct
>> pm8001_hba_info *pm8001_ha, int phy_id)
>> >         sas_phy->oob_mode = OOB_NOT_CONNECTED;
>> >         sas_phy->linkrate = SAS_LINK_RATE_UNKNOWN;
>> >         sas_phy->id = phy_id;
>> > -       sas_phy->sas_addr = &pm8001_ha->sas_addr[0];
>> > +       sas_phy->sas_addr = (u8 *)&phy->dev_sas_addr;
>> >         sas_phy->frame_rcvd = &phy->frame_rcvd[0];
>> >         sas_phy->ha = (struct sas_ha_struct *)pm8001_ha->shost->hostdata;
>> >         sas_phy->lldd_phy = phy;
>> > @@ -593,10 +593,12 @@ static void  pm8001_post_sas_ha_init(struct
>> Scsi_Host *shost,
>> >         for (i = 0; i < chip_info->n_phy; i++) {
>> >                 sha->sas_phy[i] = &pm8001_ha->phy[i].sas_phy;
>> >                 sha->sas_port[i] = &pm8001_ha->port[i].sas_port;
>> > +               sha->sas_phy[i]->sas_addr =
>> > +                       (u8 *)&pm8001_ha->phy[i].dev_sas_addr;
>> >         }
>> >         sha->sas_ha_name = DRV_NAME;
>> >         sha->dev = pm8001_ha->dev;
>> > -
>> > +       sha->strict_wide_ports = 1;
>> >         sha->lldd_module = THIS_MODULE;
>> >         sha->sas_addr = &pm8001_ha->sas_addr[0];
>> >         sha->num_phys = chip_info->n_phy;
>> > @@ -613,6 +615,7 @@ static void  pm8001_post_sas_ha_init(struct
>> Scsi_Host *shost,
>> >  static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
>> >  {
>> >         u8 i, j;
>> > +       u8 sas_add[8];
>> >  #ifdef PM8001_READ_VPD
>> >         /* For new SPC controllers WWN is stored in flash vpd
>> >         *  For SPC/SPCve controllers WWN is stored in EEPROM
>> > @@ -674,10 +677,12 @@ static void pm8001_init_sas_add(struct
>> pm8001_hba_info *pm8001_ha)
>> >                         pm8001_ha->sas_addr[j] =
>> >                                         payload.func_specific[0x804 + i];
>> >         }
>> > -
>> > +       memcpy(sas_add, pm8001_ha->sas_addr, SAS_ADDR_SIZE);
>> >         for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
>> > +               if (i && ((i % 4) == 0))
>> > +                       sas_add[7] = sas_add[7] + 4;
>> >                 memcpy(&pm8001_ha->phy[i].dev_sas_addr,
>> > -                       pm8001_ha->sas_addr, SAS_ADDR_SIZE);
>> > +                       sas_add, SAS_ADDR_SIZE);
>> >                 PM8001_INIT_DBG(pm8001_ha,
>> >                         pm8001_printk("phy %d sas_addr = %016llx\n", i,
>> >                         pm8001_ha->phy[i].dev_sas_addr));
>> > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c
>> b/drivers/scsi/pm8001/pm80xx_hwi.c
>> > index 8fb5ddf08cc4..a07b023c09bf 100644
>> > --- a/drivers/scsi/pm8001/pm80xx_hwi.c
>> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
>> > @@ -3041,7 +3041,6 @@ hw_event_phy_down(struct pm8001_hba_info
>> *pm8001_ha, void *piomb)
>> >         port->port_state = portstate;
>> >         phy->identify.device_type = 0;
>> >         phy->phy_attached = 0;
>> > -       memset(&phy->dev_sas_addr, 0, SAS_ADDR_SIZE);
>> >         switch (portstate) {
>> >         case PORT_VALID:
>> >                 break;
>> > @@ -4394,7 +4393,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->sas_addr, SAS_ADDR_SIZE);
>> > +               &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);
>> >         return ret;
>> > --
>> > 2.12.3
>> >
>> This removes the possibility to form a wide port, why do you want to do it?

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

end of thread, other threads:[~2017-09-01  8:52 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-30  6:06 [PATCH 0/6] pm80xx updates Viswas G
2015-01-30  6:06 ` [PATCH 1/6] pm80xx : redefine sas_identify_frame structure Viswas G
2017-08-29 11:19   ` Jack Wang
2017-08-30 15:41     ` Viswas G
2017-08-30 16:03       ` Jack Wang
2017-08-30 16:28         ` Viswas G
2015-01-30  6:06 ` [PATCH 2/6] pm80xx: ILA and inactive firmware version through sysfs Viswas G
2017-08-29 11:26   ` Jack Wang
2015-01-30  6:06 ` [PATCH 3/6] pm80xx : Different SAS addresses for phys Viswas G
2017-08-29 11:25   ` Jack Wang
2017-08-30 16:55     ` Viswas G
2017-09-01  8:52       ` Jack Wang
2015-01-30  6:06 ` [PATCH 4/6] pm80xx : Corrected SATA abort handling Viswas G
2017-08-29 11:46   ` Jack Wang
2017-08-30 15:48     ` Viswas G
2015-01-30  6:06 ` [PATCH 5/6] pm80xx : panic on ncq error cleaning up the read log Viswas G
2017-08-29 11:49   ` Jack Wang
2015-01-30  6:06 ` [PATCH 6/6] pm80xx : corrected linkrate value Viswas G
2017-08-29 11:08   ` Jack Wang
2017-08-30  1:32     ` Martin K. Petersen
2017-08-25 21:47 ` [PATCH 0/6] pm80xx updates Martin K. Petersen
2017-08-26  5:27   ` Viswas G

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.