* [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
* 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 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 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
* [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
* 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
* [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
* 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 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
* [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
* 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 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
* [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
* 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
* [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 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 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 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
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.