pm80xx : Updates for the driver version 0.1.39.
Subsystems (2)
v2 cover pm80xx : Updates for the driver version 0.1.39.
From: Deepak Ukey <[email protected]>
This patch set includes some bug fixes and features for pm80xx driver.
Changes from V1:
For "Support for get phy profile functionality."
-Initalized the completion and removed the phy_prof_resp structure.
For "Staggered spin up support."
-Removed the lock_flags from pm8001_hba_info structure.
For "Wait for PHY startup before draining libsas queue."
-Moved the completion initalization in first patch. -Added module parameter to wait for phy startup.
Viswas G (2):
pm80xx : Support for get phy profile functionality. pm80xx : Staggered spin up support.
peter chang (1):
pm80xx : Wait for PHY startup before draining libsas queue.
drivers/scsi/pm8001/pm8001_ctl.c | 36 ++++++ drivers/scsi/pm8001/pm8001_ctl.h | 20 +++ drivers/scsi/pm8001/pm8001_defs.h | 9 +- drivers/scsi/pm8001/pm8001_hwi.c | 14 ++- drivers/scsi/pm8001/pm8001_init.c | 77 +++++++++++- drivers/scsi/pm8001/pm8001_sas.c | 103 +++++++++++++++- drivers/scsi/pm8001/pm8001_sas.h | 22 ++++ drivers/scsi/pm8001/pm80xx_hwi.c | 253 +++++++++++++++++++++++++++++++++++--- drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 9 files changed, 505 insertions(+), 31 deletions(-)
Signature · 1 line
2.16.3
PATCH v2 1/3 pm80xx : Support for get phy profile functionality.
From: Viswas G <[email protected]>
Added the support to get the phy profile which gives information about the phy states, port and errors on phy.
--- drivers/scsi/pm8001/pm8001_ctl.h | 20 ++++++++++ drivers/scsi/pm8001/pm8001_init.c | 2 + drivers/scsi/pm8001/pm8001_sas.h | 5 +++ drivers/scsi/pm8001/pm80xx_hwi.c | 83 ++++++++++++++++++++++++++++++++++++++- drivers/scsi/pm8001/pm80xx_hwi.h | 2 + 5 files changed, 110 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm8001_ctl.h +20 -0
@@ -41,6 +41,26 @@#ifndef PM8001_CTL_H_INCLUDED #define PM8001_CTL_H_INCLUDED +struct phy_status { +char phy_id; +unsigned int phy_state:4 ; +unsigned int nlr:4 ; +unsigned int plr:4 ; +unsigned int reserved1:12 ; +unsigned char port_id; +unsigned int prts:4 ; +unsigned int reserved2:20 ; +} __packed; + +struct phy_errcnt { +unsigned int InvalidDword; +unsigned int runningDisparityError; +unsigned int codeViolation; +unsigned int LossOfSyncDW; +unsigned int phyResetProblem; +unsigned int inboundCRCError; +}; +#define IOCTL_BUF_SIZE 4096#define HEADER_LEN 28#define SIZE_OFFSET 16
drivers/scsi/pm8001/pm8001_init.c +2 -0
@@ -397,6 +397,8 @@ static int pm8001_alloc(struct pm8001_hba_info *pm8001_ha, pm8001_ha->ccb_info[i].task =NULL ; pm8001_ha->ccb_info[i].ccb_tag =0xffffffff ; pm8001_ha->ccb_info[i].device =NULL ; + pm8001_ha->ccb_info[i].completion =NULL ; + pm8001_ha->ccb_info[i].resp_buf =NULL ; ++pm8001_ha->tags_num; } pm8001_ha->flags =PM8001F_INIT_TIME ;
drivers/scsi/pm8001/pm8001_sas.h +5 -0
@@ -56,6 +56,7 @@#include <scsi/sas_ata.h> #include <linux/atomic.h> #include "pm8001_defs.h" +#include "pm8001_ctl.h" #define DRV_NAME "pm80xx"#define DRV_VERSION "0.1.39"
@@ -244,6 +245,8 @@ struct pm8001_dispatch {int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,u32 state);int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha); +int (*get_phy_profile_req)(struct pm8001_hba_info *pm8001_ha, +int phy,int page,struct completion *comp,void *buf); };struct pm8001_chip_info {
@@ -318,6 +321,8 @@ struct pm8001_ccb_info {struct pm8001_prd buf_prd[PM8001_MAX_DMA_SG ];struct fw_control_ex *fw_control_context;u8 open_retry; +struct completion *completion; +void *resp_buf; };struct mpi_mem {
drivers/scsi/pm8001/pm80xx_hwi.c +81 -2
107 lines not on this page · raw message
drivers/scsi/pm8001/pm80xx_hwi.h +2 -0
@@ -175,7 +175,9 @@#define PHY_STOP_ERR_DEVICE_ATTACHED 0x1046/* phy_profile */ +#define SAS_PHY_ERR_COUNTERS_PAGE 0x01#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04 +#define SAS_PHY_GENERAL_STATUS_PAGE 0x05#define PHY_DWORD_LENGTH 0xC/* Thermal related */
Signature · 1 line
2.16.3
kernel test robot
build botRe: [PATCH V2 1/3] pm80xx : Support for get phy profile functionality.
Thank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next v5.8-rc2 next-20200624] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20200624-195528 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: x86_64-rhel-7.6 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce (this is a W=1 build): # save the attached .config to linux build tree make W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
drivers/scsi/pm8001/pm80xx_hwi.c:69:6: warning: no previous prototype for 'pm80xx_pci_mem_copy' [-Wmissing-prototypes]
69 | void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
| ^~~~~~~~~~~~~~~~~~~
>> drivers/scsi/pm8001/pm80xx_hwi.c:5064:5: warning: no previous prototype for 'pm8001_chip_get_phy_profile' [-Wmissing-prototypes]
5064 | int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:5094:6: warning: no previous prototype for 'mpi_set_phy_profile_req' [-Wmissing-prototypes]
5094 | void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
| ^~~~~~~~~~~~~~~~~~~~~~~vim +/pm8001_chip_get_phy_profile +5064 drivers/scsi/pm8001/pm80xx_hwi.c
5063
> 5064 int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
5065 int page_code, struct completion *comp, void *buf)
5066 {
5067 u32 tag;
5068 struct get_phy_profile_req payload;
5069 struct inbound_queue_table *circularQ;
5070 struct pm8001_ccb_info *ccb;
5071 int rc, ppc_phyid;
5072 u32 opc = OPC_INB_GET_PHY_PROFILE;
5073
5074 memset(&payload, 0, sizeof(payload));
5075
5076 rc = pm8001_tag_alloc(pm8001_ha, &tag);
5077 if (rc)
5078 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
5079
5080 ccb = &pm8001_ha->ccb_info[tag];
5081 ccb->completion = comp;
5082 ccb->resp_buf = buf;
5083 circularQ = &pm8001_ha->inbnd_q_tbl[0];
5084
5085 payload.tag = cpu_to_le32(tag);
5086 ppc_phyid = (page_code & 0xFF) << 8 | (phy_id & 0xFF);
5087 payload.ppc_phyid = cpu_to_le32(ppc_phyid);
5088
5089 pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
5090 sizeof(payload), 0);
5091 return rc;
5092 }
5093
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
kernel test robot
build botRe: [PATCH V2 1/3] pm80xx : Support for get phy profile functionality.
In reply to Deepak UkeyThank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next v5.8-rc2 next-20200624] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20200624-195528 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: x86_64-allyesconfig (attached as .config) compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 1d4c87335d5236ea1f35937e1014980ba961ae34)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
drivers/scsi/pm8001/pm80xx_hwi.c:69:6: warning: no previous prototype for function 'pm80xx_pci_mem_copy' [-Wmissing-prototypes] void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
^
drivers/scsi/pm8001/pm80xx_hwi.c:69:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
^
static
>> drivers/scsi/pm8001/pm80xx_hwi.c:5064:5: warning: no previous prototype for function 'pm8001_chip_get_phy_profile' [-Wmissing-prototypes]
int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
^
drivers/scsi/pm8001/pm80xx_hwi.c:5064:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
^
static
drivers/scsi/pm8001/pm80xx_hwi.c:5094:6: warning: no previous prototype for function 'mpi_set_phy_profile_req' [-Wmissing-prototypes]
void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
^ drivers/scsi/pm8001/pm80xx_hwi.c:5094:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
^
static
3 warnings generated.
vim +/pm8001_chip_get_phy_profile +5064 drivers/scsi/pm8001/pm80xx_hwi.c
5063
> 5064 int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
5065 int page_code, struct completion *comp, void *buf)
5066 {
5067 u32 tag;
5068 struct get_phy_profile_req payload;
5069 struct inbound_queue_table *circularQ;
5070 struct pm8001_ccb_info *ccb;
5071 int rc, ppc_phyid;
5072 u32 opc = OPC_INB_GET_PHY_PROFILE;
5073
5074 memset(&payload, 0, sizeof(payload));
5075
5076 rc = pm8001_tag_alloc(pm8001_ha, &tag);
5077 if (rc)
5078 PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
5079
5080 ccb = &pm8001_ha->ccb_info[tag];
5081 ccb->completion = comp;
5082 ccb->resp_buf = buf;
5083 circularQ = &pm8001_ha->inbnd_q_tbl[0];
5084
5085 payload.tag = cpu_to_le32(tag);
5086 ppc_phyid = (page_code & 0xFF) << 8 | (phy_id & 0xFF);
5087 payload.ppc_phyid = cpu_to_le32(ppc_phyid);
5088
5089 pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
5090 sizeof(payload), 0);
5091 return rc;
5092 }
5093
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]
kernel test robot
build bot[RFC PATCH] pm80xx : pm8001_chip_get_phy_profile() can be static
In reply to Deepak UkeySigned-off-by: kernel test robot <[email protected]>
--- pm80xx_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/pm8001/pm80xx_hwi.c +1 -1
@@ -5061,7 +5061,7 @@ pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)return IRQ_HANDLED ; } -int pm8001_chip_get_phy_profile (struct pm8001_hba_info *pm8001_ha,int phy_id, +static int pm8001_chip_get_phy_profile (struct pm8001_hba_info *pm8001_ha,int phy_id,int page_code,struct completion *comp,void *buf) {u32 tag;
PATCH v2 2/3 pm80xx : Staggered spin up support.
In reply to Deepak UkeyFrom: Viswas G <[email protected]>
As a part of drive discovery, driver will initaite the drive spin up. If all drives do spin up together, it will result in large power consumption. To reduce the power consumption, driver provide an option to make a small group of drives (say 3 or 4 drives together) to do the spin up. The delay between two spin up group and no of drives to spin up (group) can be programmed by the customer in seeprom and driver will use it to control the spinup.
--- drivers/scsi/pm8001/pm8001_defs.h | 3 + drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++- drivers/scsi/pm8001/pm8001_init.c | 53 +++++++++++++++- drivers/scsi/pm8001/pm8001_sas.c | 36 ++++++++++- drivers/scsi/pm8001/pm8001_sas.h | 13 ++++ drivers/scsi/pm8001/pm80xx_hwi.c | 125 +++++++++++++++++++++++++++++++++----- 6 files changed, 221 insertions(+), 23 deletions(-)
drivers/scsi/pm8001/pm8001_defs.h +3 -0
@@ -101,6 +101,9 @@ enum port_type {#define USI_MAX_MEMCNT (PI + PM8001_MAX_SPCV_OUTB_NUM)#define CONFIG_SCSI_PM8001_MAX_DMA_SG 528#define PM8001_MAX_DMA_SG CONFIG_SCSI_PM8001_MAX_DMA_SG +#define SPINUP_DELAY_OFFSET 0x890/* 0x890 - delay */ +#define SPINUP_GROUP_OFFSET 0x892/* 0x892 - group */ +#define PM80XX_MAX_SPINUP_DELAY 10000/* 10000 ms */ enum memory_region_num {AAP1 =0x0 ,/* application acceleration processor */ IOP ,/* IO processor */
drivers/scsi/pm8001/pm8001_hwi.c +12 -2
@@ -3237,7 +3237,7 @@ int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb) (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 ; +u32 phy_op = (le32_to_cpu (pPayload->phyop_phyid) &OP_BITS ) >>8 ; tag =le32_to_cpu (pPayload->tag);if (status !=0 ) { PM8001_MSG_DBG(pm8001_ha,
@@ -3248,6 +3248,13 @@ int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)pm8001_printk ("%x phy execute %x phy op success!\n" , phy_id, phy_op)); pm8001_ha->phy[phy_id].reset_success = true; +if (phy_op ==PHY_NOTIFY_ENABLE_SPINUP && + !pm8001_ha->reset_in_progress){ +/* Notify the sas layer to discover +* the the whole sas domain +*/ +pm8001_bytes_dmaed (pm8001_ha, phy_id); + } }if (pm8001_ha->phy[phy_id].enable_completion) {complete (pm8001_ha->phy[phy_id].enable_completion);
@@ -3643,7 +3650,10 @@ int pm8001_mpi_reg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) pm8001_printk("DEVREG_FAILURE_DEVICE_TYPE_NOT_SUPPORTED\n"));break ; } -complete (pm8001_dev->dcompletion); +if (pm8001_dev->dcompletion) { +complete (pm8001_dev->dcompletion); + pm8001_dev->dcompletion =NULL ; + } ccb->task =NULL ; ccb->ccb_tag =0xFFFFFFFF ;pm8001_tag_free (pm8001_ha, htag);
drivers/scsi/pm8001/pm8001_init.c +50 -3
89 lines not on this page · raw message
drivers/scsi/pm8001/pm8001_sas.c +34 -2
@@ -265,14 +265,39 @@ int pm8001_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,void pm8001_scan_start (struct Scsi_Host *shost) {int i; +unsigned long lock_flags;struct pm8001_hba_info *pm8001_ha;struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +DECLARE_COMPLETION (comp); pm8001_ha = sha->lldd_ha;/* SAS_RE_INITIALIZATION not available in SPCv/ve */ if (pm8001_ha->chip_id == chip_8001)PM8001_CHIP_DISP ->sas_re_init_req (pm8001_ha); -for (i =0 ; i < pm8001_ha->chip->n_phy; ++i) -PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, i); + +if (pm8001_ha->pdev->device ==0x8001 || + pm8001_ha->pdev->device ==0x8081 || + (pm8001_ha->spinup_interval !=0 )) { +for (i =0 ; i < pm8001_ha->chip->n_phy; ++i) +PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, i); + }else { +for (i =0 ; i < pm8001_ha->chip->n_phy; ++i) { +spin_lock_irqsave (&pm8001_ha->lock, lock_flags); + pm8001_ha->phy_started = i; + pm8001_ha->scan_completion = ∁ + pm8001_ha->phystart_timedout =1 ; +spin_unlock_irqrestore (&pm8001_ha->lock, lock_flags); +PM8001_CHIP_DISP ->phy_start_req (pm8001_ha, i); +wait_for_completion_timeout (&comp, +msecs_to_jiffies (500 )); +if (pm8001_ha->phystart_timedout) +PM8001_MSG_DBG (pm8001_ha,pm8001_printk ( +"Timeout happened for phyid = %d\n" , i)); + } +spin_lock_irqsave (&pm8001_ha->lock, lock_flags); + pm8001_ha->phy_started =-1 ; + pm8001_ha->scan_completion =NULL ; +spin_unlock_irqrestore (&pm8001_ha->lock, lock_flags); + } }int pm8001_scan_finished (struct Scsi_Host *shost,unsigned long time)
@@ -662,6 +687,13 @@ static int pm8001_dev_found_notify(struct domain_device *dev) flag =1 ;/* directly sata */ } }/*register this device to HBA*/ + +if (pm8001_ha->phy_started == pm8001_device->attached_phy) { +if (pm8001_ha->scan_completion !=NULL ) { + pm8001_ha->phystart_timedout =0 ; +complete (pm8001_ha->scan_completion); + } + }PM8001_DISC_DBG (pm8001_ha,pm8001_printk ("Found device\n" ));PM8001_CHIP_DISP ->reg_dev_req (pm8001_ha, pm8001_device, flag);spin_unlock_irqrestore (&pm8001_ha->lock, flags);
drivers/scsi/pm8001/pm8001_sas.h +13 -0
@@ -261,6 +261,7 @@ struct pm8001_port {u8 port_attached;u16 wide_port_phymap;u8 port_state; +u8 port_id;struct list_head list; };
@@ -566,6 +567,17 @@ struct pm8001_hba_info {u32 reset_in_progress;u32 non_fatal_count;u32 non_fatal_read_length; +bool staggered_spinup; +struct completion *scan_completion; +u32 phy_started; +u16 phystart_timedout; +int spinup_group; +int spinup_interval; +int phy_up[PM8001_MAX_PHYS ]; +struct timer_list spinup_timer; +int phy_head; +int phy_tail; +spinlock_t phy_q_lock; };struct pm8001_work {
@@ -684,6 +696,7 @@ void pm8001_open_reject_retry(int pm8001_mem_alloc (struct pci_dev *pdev,void **virt_addr,dma_addr_t *pphys_addr,u32 *pphys_addr_hi,u32 *pphys_addr_lo,u32 mem_size,u32 align); +void pm8001_spinup_timedout (struct timer_list *t);void pm8001_chip_iounmap (struct pm8001_hba_info *pm8001_ha); int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha,
drivers/scsi/pm8001/pm80xx_hwi.c +109 -16
201 lines not on this page · raw message
Signature · 1 line
2.16.3
kernel test robot
build botRe: [PATCH V2 2/3] pm80xx : Staggered spin up support.
Thank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next v5.8-rc2 next-20200624] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20200624-195528 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: x86_64-rhel-7.6 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce (this is a W=1 build): # save the attached .config to linux build tree make W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
>> drivers/scsi/pm8001/pm80xx_hwi.c:52:7: warning: no previous prototype for 'pm8001_queue_phyup' [-Wmissing-prototypes]
52 | void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha, int phy_id)
| ^~~~~~~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:135:6: warning: no previous prototype for 'pm80xx_pci_mem_copy' [-Wmissing-prototypes]
135 | void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
| ^~~~~~~~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:5157:5: warning: no previous prototype for 'pm8001_chip_get_phy_profile' [-Wmissing-prototypes]
5157 | int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/scsi/pm8001/pm80xx_hwi.c:5187:6: warning: no previous prototype for 'mpi_set_phy_profile_req' [-Wmissing-prototypes]
5187 | void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
| ^~~~~~~~~~~~~~~~~~~~~~~vim +/pm8001_queue_phyup +52 drivers/scsi/pm8001/pm80xx_hwi.c
48
49 static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
50 u32 phyId, u32 phy_op);
51
> 52 void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha, int phy_id)
53 {
54 int i;
55
56 if (pm8001_ha->phy_head == -1) {
57 pm8001_ha->phy_head = pm8001_ha->phy_tail = 0;
58 } else {
59 /* If the phy id is already queued , discard the phy up */
60 for (i = 0; i < pm8001_ha->chip->n_phy; i++)
61 if (pm8001_ha->phy_up[i] == phy_id)
62 return;
63 pm8001_ha->phy_tail =
64 (pm8001_ha->phy_tail + 1) % PM8001_MAX_PHYS;
65 }
66 pm8001_ha->phy_up[pm8001_ha->phy_tail] = phy_id;
67 }
68 ---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
kernel test robot
build botRe: [PATCH V2 2/3] pm80xx : Staggered spin up support.
In reply to Deepak UkeyThank you for the patch! Perhaps something to improve:
Hi Deepak,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next v5.8-rc2 next-20200624] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Deepak-Ukey/pm80xx-Updates-for-the-driver-version-0-1-39/20200624-195528 base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next config: x86_64-allyesconfig (attached as .config) compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 1d4c87335d5236ea1f35937e1014980ba961ae34)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
All warnings (new ones prefixed by >>):
>> drivers/scsi/pm8001/pm80xx_hwi.c:52:7: warning: no previous prototype for function 'pm8001_queue_phyup' [-Wmissing-prototypes]
void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha, int phy_id)
^
drivers/scsi/pm8001/pm80xx_hwi.c:52:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha, int phy_id)
^
static
drivers/scsi/pm8001/pm80xx_hwi.c:135:6: warning: no previous prototype for function 'pm80xx_pci_mem_copy' [-Wmissing-prototypes]
void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
^
drivers/scsi/pm8001/pm80xx_hwi.c:135:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void pm80xx_pci_mem_copy(struct pm8001_hba_info *pm8001_ha, u32 soffset,
^
static
drivers/scsi/pm8001/pm80xx_hwi.c:5157:5: warning: no previous prototype for function 'pm8001_chip_get_phy_profile' [-Wmissing-prototypes]
int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
^
drivers/scsi/pm8001/pm80xx_hwi.c:5157:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha, int phy_id,
^
static
drivers/scsi/pm8001/pm80xx_hwi.c:5187:6: warning: no previous prototype for function 'mpi_set_phy_profile_req' [-Wmissing-prototypes]
void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
^ drivers/scsi/pm8001/pm80xx_hwi.c:5187:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
^
static
4 warnings generated.
vim +/pm8001_queue_phyup +52 drivers/scsi/pm8001/pm80xx_hwi.c
48
49 static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
50 u32 phyId, u32 phy_op);
51
> 52 void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha, int phy_id)
53 {
54 int i;
55
56 if (pm8001_ha->phy_head == -1) {
57 pm8001_ha->phy_head = pm8001_ha->phy_tail = 0;
58 } else {
59 /* If the phy id is already queued , discard the phy up */
60 for (i = 0; i < pm8001_ha->chip->n_phy; i++)
61 if (pm8001_ha->phy_up[i] == phy_id)
62 return;
63 pm8001_ha->phy_tail =
64 (pm8001_ha->phy_tail + 1) % PM8001_MAX_PHYS;
65 }
66 pm8001_ha->phy_up[pm8001_ha->phy_tail] = phy_id;
67 }
68 ---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
kernel test robot
build bot[RFC PATCH] pm80xx : pm8001_queue_phyup() can be static
In reply to Deepak UkeySigned-off-by: kernel test robot <[email protected]>
--- pm80xx_hwi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/pm8001/pm80xx_hwi.c +1 -1
@@ -49,7 +49,7 @@static int pm80xx_chip_phy_ctl_req (struct pm8001_hba_info *pm8001_ha,u32 phyId,u32 phy_op); -void pm8001_queue_phyup (struct pm8001_hba_info *pm8001_ha,int phy_id) +static void pm8001_queue_phyup (struct pm8001_hba_info *pm8001_ha,int phy_id) {int i;
PATCH v2 3/3 pm80xx : Wait for PHY startup before draining libsas queue.
In reply to Deepak UkeyFrom: peter chang <[email protected]>
The host's scan finish waits for the libsas queue to drain. However, if the PHYs are still in the process of starting then the queue will be empty. This means that we declare the scan finished before it has even started. Here we wait for various events from the firmware-side.
The wait behavior can be configured using the module parameter "wait_for_phy_startup", if the parameter is enabled, the driver will wait for the phy event from the firmware, before proceeding with load.
--- drivers/scsi/pm8001/pm8001_ctl.c | 36 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_defs.h | 6 ++-- drivers/scsi/pm8001/pm8001_init.c | 22 +++++++++++++ drivers/scsi/pm8001/pm8001_sas.c | 67 +++++++++++++++++++++++++++++++++++++-- drivers/scsi/pm8001/pm8001_sas.h | 4 +++ drivers/scsi/pm8001/pm80xx_hwi.c | 67 ++++++++++++++++++++++++++++++++------- 6 files changed, 185 insertions(+), 17 deletions(-)
drivers/scsi/pm8001/pm8001_ctl.c +36 -0
@@ -88,6 +88,41 @@ static ssize_t controller_fatal_error_show(struct device *cdev, }static DEVICE_ATTR_RO (controller_fatal_error); +/** +* phy_startup_timeout_show - per-phy discovery timeout +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read/write' shost attribute. +*/ +static ssize_t phy_startup_timeout_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + +return snprintf (buf,PAGE_SIZE ,"%08xh\n" , + pm8001_ha->phy_startup_timeout /HZ ); +} + +static ssize_t phy_startup_timeout_store (struct device *cdev, +struct device_attribute *attr,const char *buf,size_t count) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int val =0 ; + +if (kstrtoint (buf,0 , &val) <0 ) +return -EINVAL ; + + pm8001_ha->phy_startup_timeout = val *HZ ; +return strlen (buf); +} + +static DEVICE_ATTR_RW (phy_startup_timeout); +/** * pm8001_ctl_fw_version_show - firmware version * @cdev: pointer to embedded class device
@@ -867,6 +902,7 @@ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP,struct device_attribute *pm8001_host_attrs[] = { &dev_attr_interface_rev, &dev_attr_controller_fatal_error, + &dev_attr_phy_startup_timeout, &dev_attr_fw_version, &dev_attr_update_fw, &dev_attr_aap_log,
drivers/scsi/pm8001/pm8001_defs.h +4 -2
@@ -141,7 +141,9 @@ enum pm8001_hba_info_flags {*/ #define PHY_LINK_DISABLE 0x00#define PHY_LINK_DOWN 0x01 -#define PHY_STATE_LINK_UP_SPCV 0x2 -#define PHY_STATE_LINK_UP_SPC 0x1 +#define PHY_STATE_LINK_UP_SPCV 0x02 +#define PHY_STATE_LINK_UP_SPC 0x01 +#define PHY_STATE_LINK_RESET 0x03 +#define PHY_STATE_HARD_RESET 0x04#endif
drivers/scsi/pm8001/pm8001_init.c +22 -0
@@ -61,6 +61,26 @@ MODULE_PARM_DESC(staggered_spinup, "enable the staggered spinup feature.\n"" 0/N: false\n" " 1/Y: true\n"); +static bool wait_for_phy_startup; +module_param (wait_for_phy_startup, bool,0644 ); +MODULE_PARM_DESC (wait_for_phy_startup,"wait for phy start.\n" +" 0/N: disable\n" +" 1/Y: enable\n" ); + +/* if nothing is detected, the PHYs will reset continuously once they +* are started. we don't have a good way of differentiating a trained +* but waiting-on-signature from one that's never going to train +* (nothing attached or dead drive), so we wait an possibly +* unreasonable amount of time. this is stuck in start_timeout, and +* checked in the host's scan_finished callback for PHYs that haven't +* yet come up. +* +*/ +static ulong phy_startup_timeout =60 ; +module_param (phy_startup_timeout, ulong,0644 ); +MODULE_PARM_DESC (phy_startup_timeout_s, +" seconds to wait for discovery, per-PHY." ); +static struct scsi_transport_template *pm8001_stt;/**
@@ -495,6 +515,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev, pm8001_ha->id = pm8001_id++; pm8001_ha->logging_level = logging_level; pm8001_ha->staggered_spinup = staggered_spinup; + pm8001_ha->phy_startup_timeout = phy_startup_timeout *HZ ; + pm8001_ha->wait_for_phy_startup = wait_for_phy_startup; pm8001_ha->non_fatal_count =0 ;if (link_rate >=1 && link_rate <=15 ) pm8001_ha->link_rate = (link_rate <<8 );
drivers/scsi/pm8001/pm8001_sas.c +64 -3
93 lines not on this page · raw message
drivers/scsi/pm8001/pm8001_sas.h +4 -0
@@ -283,6 +283,7 @@ struct pm8001_phy {struct completion *reset_completion;bool port_reset_status;bool reset_success; +unsigned long start_timeout; };/* port reset status */
@@ -578,6 +579,9 @@ struct pm8001_hba_info {int phy_head;int phy_tail;spinlock_t phy_q_lock; +unsigned long phy_mask; +u32 phy_startup_timeout; +bool wait_for_phy_startup; };struct pm8001_work {
drivers/scsi/pm8001/pm80xx_hwi.c +55 -12
93 lines not on this page · raw message
Signature · 1 line
2.16.3
Re: [PATCH V2 3/3] pm80xx : Wait for PHY startup before draining libsas queue.
Quoted 6 lines · Deepak Ukey
From: peter chang <[email protected]>
The host's scan finish waits for the libsas queue to drain. However, if the PHYs are still in the process of starting then the queue will be empty. This means that we declare the scan finished before it has even started. Here we wait for various events from the firmware-side.
But we still report the phy up even to libsas later, so should revalidate the domain and discover the device.
Quoted 4 lines
The wait behavior can be configured using the module parameter "
wait_for_phy_startup", if the parameter is enabled, the driver will wait for the phy event from the firmware, before proceeding with load.
If this is to circumvent a deficiency in udev (which you mentioned in the v1 in this series, but fail to mention here), then better to fix udev.
Quoted 2 lines
Signed-off-by Viswas G <[email protected]>
Author != first Signed-off-by
Quoted 41 lines
Signed-off-by peter chang <[email protected]>Signed-off-by Radha Ramachandran <[email protected]>Signed-off-by Deepak Ukey <[email protected]>--- drivers/scsi/pm8001/pm8001_ctl.c | 36 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_defs.h | 6 ++-- drivers/scsi/pm8001/pm8001_init.c | 22 +++++++++++++ drivers/scsi/pm8001/pm8001_sas.c | 67 +++++++++++++++++++++++++++++++++++++-- drivers/scsi/pm8001/pm8001_sas.h | 4 +++ drivers/scsi/pm8001/pm80xx_hwi.c | 67 ++++++++++++++++++++++++++++++++------- 6 files changed, 185 insertions(+), 17 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +21
-0@@ -88,6 +88,41 @@ static ssize_t controller_fatal_error_show(struct device *cdev, }static DEVICE_ATTR_RO (controller_fatal_error); +/** +* phy_startup_timeout_show - per-phy discovery timeout +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read/write' shost attribute. +*/ +static ssize_t phy_startup_timeout_show (struct device *cdev, +struct device_attribute *attr,char *buf) +{ +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + +return snprintf (buf,PAGE_SIZE ,"%08xh\n" , + pm8001_ha->phy_startup_timeout /HZ ); +} + +static ssize_t phy_startup_timeout_store (struct device *cdev, +struct device_attribute *attr,const char *buf,size_t count) +{
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t controller_fatal_error_show(struct device *cdev, · line 121
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int val =0 ; + +if (kstrtoint (buf,0 , &val) <0 ) +return -EINVAL ; + + pm8001_ha->phy_startup_timeout = val *HZ ; +return strlen (buf);
I don't see how this can be used.
Quoted 8 lines
drivers/scsi/pm8001/pm8001_ctl.c +4
-0+} + +static DEVICE_ATTR_RW (phy_startup_timeout); +case HW_EVENT_SAS_PHY_UP :
drivers/scsi/pm8001/pm8001_ctl.c pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +3
-1@@ -4975,6 +5015,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id)PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("PHY START REQ for phy_id %d\n" , phy_id)); +set_bit (phy_id, &pm8001_ha->phy_mask); + pm8001_ha->phy[phy_id].start_timeout = + jiffies + pm8001_ha->phy_startup_timeout; payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_ENABLE |LINKMODE_AUTO | pm8001_ha->link_rate | phy_id); --
If there is nothing attached to the phy, then it would never come up, right? If so, how do you handle this?
Thanks,
john
RE: [PATCH V2 3/3] pm80xx : Wait for PHY startup before draining libsas queue.
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
Quoted 6 lines · Deepak Ukey
From: peter chang <[email protected]>
The host's scan finish waits for the libsas queue to drain. However, if the PHYs are still in the process of starting then the queue will be empty. This means that we declare the scan finished before it has even started. Here we wait for various events from the firmware-side.
But we still report the phy up even to libsas later, so should revalidate the domain and discover the device.
- The scsi_host scan_finished callback polls the phy state in pm8001_update_phy_mask. If the phy fails to come up - - after phy->start_timeout, we declare the scan as finished and proceed.
Quoted 4 lines
The wait behavior can be configured using the module parameter "
wait_for_phy_startup", if the parameter is enabled, the driver will wait for the phy event from the firmware, before proceeding with load.
If this is to circumvent a deficiency in udev (which you mentioned in the v1 in this series, but fail to mention here), then better to fix udev.
- According to recommendation to fix this using udev. It looks like upstreaming this patch is not possible. We will - investigate using udev for fixing this issue and submit this patch later in future.
Quoted 2 lines
Signed-off-by Viswas G <[email protected]>
Author != first Signed-off-by
Quoted 39 lines
Signed-off-by peter chang <[email protected]>Signed-off-by Radha Ramachandran <[email protected]>Signed-off-by Deepak Ukey <[email protected]>--- drivers/scsi/pm8001/pm8001_ctl.c | 36 +++++++++++++++++++++ drivers/scsi/pm8001/pm8001_defs.h | 6 ++-- drivers/scsi/pm8001/pm8001_init.c | 22 +++++++++++++ drivers/scsi/pm8001/pm8001_sas.c | 67 +++++++++++++++++++++++++++++++++++++-- drivers/scsi/pm8001/pm8001_sas.h | 4 +++ drivers/scsi/pm8001/pm80xx_hwi.c | 67 ++++++++++++++++++++++++++++++++------- 6 files changed, 185 insertions(+), 17 deletions(-)drivers/scsi/pm8001/pm8001_ctl.c +18
-0@@ -88,6 +88,41 @@ static ssize_t controller_fatal_error_show(struct device *cdev, }static DEVICE_ATTR_RO (controller_fatal_error); +/** +* phy_startup_timeout_show - per-phy discovery timeout +* @cdev: pointer to embedded class device +* @buf: the buffer returned +* +* A sysfs 'read/write' shost attribute. +*/ +static ssize_t phy_startup_timeout_show (struct device *cdev, +struct device_attribute *attr,char *buf) { +struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; + +return snprintf (buf,PAGE_SIZE ,"%08xh\n" , + pm8001_ha->phy_startup_timeout /HZ ); } + +static ssize_t phy_startup_timeout_store (struct device *cdev, +struct device_attribute *attr,const char *buf,size_t count) {
drivers/scsi/pm8001/pm8001_ctl.c static ssize_t controller_fatal_error_show(struct device *cdev, · line 118
Quoted 10 lines
drivers/scsi/pm8001/pm8001_ctl.c +10
-0+struct Scsi_Host *shost =class_to_shost (cdev); +struct sas_ha_struct *sha =SHOST_TO_SAS_HA (shost); +struct pm8001_hba_info *pm8001_ha = sha->lldd_ha; +int val =0 ; + +if (kstrtoint (buf,0 , &val) <0 ) +return -EINVAL ; + + pm8001_ha->phy_startup_timeout = val *HZ ; +return strlen (buf);
I don't see how this can be used.
Quoted 8 lines
drivers/scsi/pm8001/pm8001_ctl.c +4
-0+} + +static DEVICE_ATTR_RW (phy_startup_timeout); +case HW_EVENT_SAS_PHY_UP :
drivers/scsi/pm8001/pm8001_ctl.c pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) > · line 4980
Quoted 9 lines
drivers/scsi/pm8001/pm8001_ctl.c +3
-1@@ -4975,6 +5015,9 @@ pm80xx_chip_phy_start_req(struct pm8001_hba_info *pm8001_ha, u8 phy_id) >PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("PHY START REQ for phy_id %d\n" , phy_id)); +set_bit (phy_id, &pm8001_ha->phy_mask); + pm8001_ha->phy[phy_id].start_timeout = + jiffies + pm8001_ha->phy_startup_timeout; payload.ase_sh_lm_slr_phyid =cpu_to_le32 (SPINHOLD_ENABLE |LINKMODE_AUTO | pm8001_ha->link_rate | phy_id); --
If there is nothing attached to the phy, then it would never come up, right? If so, how do you handle this?
Thanks,
john