From: Jinpu Wang <jinpu.wang@cloud.ionos.com>
To: Viswas G <Viswas.G@microchip.com>,
Vasanthalakshmi.Tharmarajan@microchip.com,
Vikram Auradkar <auradkar@google.com>,
Linux SCSI Mailinglist <linux-scsi@vger.kernel.org>,
"Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Jinpu Wang <jinpu.wang@profitbricks.com>
Subject: Re: [PATCH v8 2/2] pm80xx : Staggered spin up support.
Date: Wed, 2 Sep 2020 16:05:15 +0200 [thread overview]
Message-ID: <CAMGffE=LbTGy9agYqD0Z9=AgdiPm24sq=Awj=-5JzC04YKabJQ@mail.gmail.com> (raw)
In-Reply-To: <SN6PR11MB348877970A45BA993C95D14D9D5B0@SN6PR11MB3488.namprd11.prod.outlook.com>
> > From: Viswas G <Viswas.G@microchip.com>
> >
> > 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.
> >
> > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > Signed-off-by: Deepak Ukey <Deepak.Ukey@microchip.com>
> > Signed-off-by: Radha Ramachandran <radha@google.com>
> > Signed-off-by: kernel test robot <lkp@intel.com>
> > Reported-by: kernel test robot <lkp@intel.com>
Sorry for late reply, was on vacation.
Please still check the possibility to implement in libsas as suggested
by Christoph.
Looks fine.
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.come>
> > ---
> > drivers/scsi/pm8001/pm8001_defs.h | 3 +
> > drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++-
> > drivers/scsi/pm8001/pm8001_init.c | 56 +++++++++++++++--
> > drivers/scsi/pm8001/pm8001_sas.c | 36 ++++++++++-
> > drivers/scsi/pm8001/pm8001_sas.h | 13 ++++
> > drivers/scsi/pm8001/pm80xx_hwi.c | 125
> > +++++++++++++++++++++++++++++++++-----
> > 6 files changed, 223 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> > b/drivers/scsi/pm8001/pm8001_defs.h
> > index 1c7f15fd69ce..fd700ce5e80c 100644
> > --- a/drivers/scsi/pm8001/pm8001_defs.h
> > +++ b/drivers/scsi/pm8001/pm8001_defs.h
> > @@ -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 */
> > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c
> > b/drivers/scsi/pm8001/pm8001_hwi.c
> > index e9a939230b15..475cb2b6815f 100644
> > --- a/drivers/scsi/pm8001/pm8001_hwi.c
> > +++ b/drivers/scsi/pm8001/pm8001_hwi.c
> > @@ -3243,7 +3243,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, @@ -3254,6 +3254,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 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);
> > @@ -3649,7 +3656,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); diff --git
> > a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
> > index 2587dfa5c111..bd2e48b71b3d 100644
> > --- a/drivers/scsi/pm8001/pm8001_init.c
> > +++ b/drivers/scsi/pm8001/pm8001_init.c
> > @@ -55,6 +55,12 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n"
> > " 4: Link rate 6.0G\n"
> > " 8: Link rate 12.0G\n");
> >
> > +bool staggered_spinup;
> > +module_param(staggered_spinup, bool, 0644);
> > +MODULE_PARM_DESC(staggered_spinup, "enable the staggered spinup
> > feature.\n"
> > + " 0/N: false\n"
> > + " 1/Y: true\n");
> > +
> > static struct scsi_transport_template *pm8001_stt;
> >
> > /*
> > @@ -164,7 +170,7 @@ static void pm8001_free(struct pm8001_hba_info
> > *pm8001_ha)
> >
> > if (!pm8001_ha)
> > return;
> > -
> > + del_timer(&pm8001_ha->spinup_timer);
> > for (i = 0; i < USI_MAX_MEMCNT; i++) {
> > if (pm8001_ha->memoryMap.region[i].virt_ptr != NULL) {
> > dma_free_coherent(&pm8001_ha->pdev->dev,
> > @@ -490,6 +496,7 @@ static struct pm8001_hba_info
> > *pm8001_pci_alloc(struct pci_dev *pdev,
> > pm8001_ha->shost = shost;
> > pm8001_ha->id = pm8001_id++;
> > pm8001_ha->logging_level = logging_level;
> > + pm8001_ha->staggered_spinup = staggered_spinup;
> > pm8001_ha->non_fatal_count = 0;
> > if (link_rate >= 1 && link_rate <= 15)
> > pm8001_ha->link_rate = (link_rate << 8); @@ -623,7 +630,8 @@
> > static void pm8001_post_sas_ha_init(struct Scsi_Host *shost,
> > * Currently we just set the fixed SAS address to our HBA,for manufacture,
> > * it should read from the EEPROM
> > */
> > -static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
> > +static void pm8001_init_sas_add_and_spinup_config
> > + (struct pm8001_hba_info *pm8001_ha)
> > {
> > u8 i, j;
> > u8 sas_add[8];
> > @@ -698,7 +706,6 @@ static void pm8001_init_sas_add(struct
> > pm8001_hba_info *pm8001_ha)
> > pm8001_printk("phy %d sas_addr = %016llx\n", i,
> > pm8001_ha->phy[i].dev_sas_addr));
> > }
> > - kfree(payload.func_specific);
> > #else
> > for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
> > pm8001_ha->phy[i].dev_sas_addr = 0x50010c600047f9d0ULL; @@
> > -709,6 +716,47 @@ static void pm8001_init_sas_add(struct
> > pm8001_hba_info *pm8001_ha)
> > memcpy(pm8001_ha->sas_addr, &pm8001_ha->phy[0].dev_sas_addr,
> > SAS_ADDR_SIZE);
> > #endif
> > +
> > + /* For spinning up drives in group */
> > + pm8001_ha->phy_head = -1;
> > + pm8001_ha->phy_tail = -1;
> > +
> > + for (i = 0; i < PM8001_MAX_PHYS; i++)
> > + pm8001_ha->phy_up[i] = 0xff;
> > +
> > + timer_setup(&pm8001_ha->spinup_timer,
> > + (void *)pm8001_spinup_timedout, 0);
> > +
> > + if (pm8001_ha->staggered_spinup == true) {
> > + /* spinup interval in unit of 100 ms */
> > + pm8001_ha->spinup_interval =
> > + payload.func_specific[SPINUP_DELAY_OFFSET] * 100;
> > + pm8001_ha->spinup_group =
> > + payload.func_specific[SPINUP_GROUP_OFFSET];
> > + } else {
> > + pm8001_ha->spinup_interval = 0;
> > + pm8001_ha->spinup_group = pm8001_ha->chip->n_phy;
> > + }
> > +
> > + if (pm8001_ha->spinup_interval > PM80XX_MAX_SPINUP_DELAY) {
> > + PM8001_DISC_DBG(pm8001_ha, pm8001_printk(
> > + "Spinup delay from Seeprom is %d ms, reset to %d ms\n",
> > + pm8001_ha->spinup_interval * 100,
> > PM80XX_MAX_SPINUP_DELAY));
> > + pm8001_ha->spinup_interval = PM80XX_MAX_SPINUP_DELAY;
> > + }
> > +
> > + if (pm8001_ha->spinup_group > pm8001_ha->chip->n_phy) {
> > + PM8001_DISC_DBG(pm8001_ha, pm8001_printk(
> > + "Spinup group from Seeprom is %d, reset to %d\n",
> > + pm8001_ha->spinup_group, pm8001_ha->chip->n_phy));
> > + pm8001_ha->spinup_group = pm8001_ha->chip->n_phy;
> > + }
> > +
> > + PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
> > + "Spinup interval : %d Spinup group %d\n",
> > + pm8001_ha->spinup_interval, pm8001_ha->spinup_group));
> > +
> > + kfree(payload.func_specific);
> > }
> >
> > /*
> > @@ -1106,7 +1154,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
> > pm80xx_set_thermal_config(pm8001_ha);
> > }
> >
> > - pm8001_init_sas_add(pm8001_ha);
> > + pm8001_init_sas_add_and_spinup_config(pm8001_ha);
> > /* phy setting support for motherboard controller */
> > if (pm8001_configure_phy_settings(pm8001_ha))
> > goto err_out_shost;
> > diff --git a/drivers/scsi/pm8001/pm8001_sas.c
> > b/drivers/scsi/pm8001/pm8001_sas.c
> > index 337e79d6837f..defa5de1deec 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.c
> > +++ b/drivers/scsi/pm8001/pm8001_sas.c
> > @@ -266,14 +266,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_ONSTACK(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); diff --git
> > a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
> > index 488af79dec47..d2d73cba7f41 100644
> > --- a/drivers/scsi/pm8001/pm8001_sas.h
> > +++ b/drivers/scsi/pm8001/pm8001_sas.h
> > @@ -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, diff --git
> > a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
> > index 62b50596b320..5dbb0fd2599d 100644
> > --- a/drivers/scsi/pm8001/pm80xx_hwi.c
> > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c
> > @@ -46,6 +46,72 @@
> > #define SMP_DIRECT 1
> > #define SMP_INDIRECT 2
> >
> > +static int pm80xx_chip_phy_ctl_req(struct pm8001_hba_info *pm8001_ha,
> > + u32 phyId, u32 phy_op);
> > +
> > +static void pm8001_queue_phyup(struct pm8001_hba_info *pm8001_ha,
> > int
> > +phy_id) {
> > + int i;
> > +
> > + if (pm8001_ha->phy_head == -1) {
> > + pm8001_ha->phy_head = pm8001_ha->phy_tail = 0;
> > + } else {
> > + /* If the phy id is already queued , discard the phy up */
> > + for (i = 0; i < pm8001_ha->chip->n_phy; i++)
> > + if (pm8001_ha->phy_up[i] == phy_id)
> > + return;
> > + pm8001_ha->phy_tail =
> > + (pm8001_ha->phy_tail + 1) % PM8001_MAX_PHYS;
> > + }
> > + pm8001_ha->phy_up[pm8001_ha->phy_tail] = phy_id; }
> > +
> > +void pm8001_spinup_timedout(struct timer_list *t) {
> > + struct pm8001_hba_info *pm8001_ha =
> > + from_timer(pm8001_ha, t, spinup_timer);
> > + struct pm8001_phy *phy;
> > + unsigned long flags;
> > + int i = 0, phy_id = 0xff;
> > +
> > + spin_lock_irqsave(&pm8001_ha->phy_q_lock, flags);
> > +
> > + do {
> > + if (i++ >= pm8001_ha->spinup_group && pm8001_ha-
> > >spinup_group)
> > + break;
> > +
> > + if (pm8001_ha->phy_head == -1 || pm8001_ha->reset_in_progress)
> > + break; /* No phys to spinup */
> > +
> > + phy_id = pm8001_ha->phy_up[pm8001_ha->phy_head];
> > + /* Processed phy id, make it invalid 0xff for
> > + * checking repeated phy ups
> > + */
> > + pm8001_ha->phy_up[pm8001_ha->phy_head] = 0xff;
> > + if (pm8001_ha->phy_head == pm8001_ha->phy_tail) {
> > + pm8001_ha->phy_head = pm8001_ha->phy_tail = -1;
> > + } else {
> > + pm8001_ha->phy_head =
> > + (pm8001_ha->phy_head+1) % PM8001_MAX_PHYS;
> > + }
> > +
> > + if (phy_id == 0xff)
> > + break;
> > + phy = &pm8001_ha->phy[phy_id];
> > + if (phy->phy_type & PORT_TYPE_SAS) {
> > + PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
> > + PHY_NOTIFY_ENABLE_SPINUP);
> > + } else {
> > + PM8001_CHIP_DISP->phy_ctl_req(pm8001_ha, phy_id,
> > + PHY_LINK_RESET);
> > + }
> > + } while (1);
> > +
> > + if (pm8001_ha->phy_head != -1 && pm8001_ha->spinup_group)
> > + mod_timer(&pm8001_ha->spinup_timer,
> > + jiffies + msecs_to_jiffies(pm8001_ha->spinup_interval));
> > + spin_unlock_irqrestore(&pm8001_ha->phy_q_lock, flags); }
> >
> > int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32
> > shift_value) { @@ -3306,11 +3372,12 @@ hw_event_sas_phy_up(struct
> > pm8001_hba_info *pm8001_ha, void *piomb)
> > port->port_state = portstate;
> > port->wide_port_phymap |= (1U << phy_id);
> > phy->phy_state = PHY_STATE_LINK_UP_SPCV;
> > + phy->port = port;
> > PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
> > "portid:%d; phyid:%d; linkrate:%d; "
> > "portstate:%x; devicetype:%x\n",
> > port_id, phy_id, link_rate, portstate, deviceType));
> > -
> > + port->port_id = port_id;
> > switch (deviceType) {
> > case SAS_PHY_UNUSED:
> > PM8001_MSG_DBG(pm8001_ha, @@ -3318,8 +3385,12 @@
> > hw_event_sas_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
> > break;
> > case SAS_END_DEVICE:
> > PM8001_MSG_DBG(pm8001_ha, pm8001_printk("end device.\n"));
> > - pm80xx_chip_phy_ctl_req(pm8001_ha, phy_id,
> > - PHY_NOTIFY_ENABLE_SPINUP);
> > + spin_lock_irqsave(&pm8001_ha->phy_q_lock, flags);
> > + pm8001_queue_phyup(pm8001_ha, phy_id);
> > + spin_unlock_irqrestore(&pm8001_ha->phy_q_lock, flags);
> > + if (!timer_pending(&pm8001_ha->spinup_timer))
> > + mod_timer(&pm8001_ha->spinup_timer,
> > + jiffies +
> > + msecs_to_jiffies(pm8001_ha->spinup_interval));
> > port->port_attached = 1;
> > pm8001_get_lrate_mode(phy, link_rate);
> > break;
> > @@ -3355,9 +3426,10 @@ hw_event_sas_phy_up(struct pm8001_hba_info
> > *pm8001_ha, void *piomb)
> > phy->frame_rcvd_size = sizeof(struct sas_identify_frame) - 4;
> > pm8001_get_attached_sas_addr(phy, phy-
> > >sas_phy.attached_sas_addr);
> > spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
> > - if (pm8001_ha->flags == PM8001F_RUN_TIME)
> > - msleep(200);/*delay a moment to wait disk to spinup*/
> > - pm8001_bytes_dmaed(pm8001_ha, phy_id);
> > + if (!pm8001_ha->reset_in_progress) {
> > + if (deviceType != SAS_END_DEVICE)
> > + pm8001_bytes_dmaed(pm8001_ha, phy_id);
> > + }
> > }
> >
> > /**
> > @@ -3392,11 +3464,17 @@ hw_event_sata_phy_up(struct
> > pm8001_hba_info *pm8001_ha, void *piomb)
> > port->port_state = portstate;
> > phy->phy_state = PHY_STATE_LINK_UP_SPCV;
> > port->port_attached = 1;
> > + phy->port = port;
> > + port->port_id = port_id;
> > pm8001_get_lrate_mode(phy, link_rate);
> > phy->phy_type |= PORT_TYPE_SATA;
> > phy->phy_attached = 1;
> > phy->sas_phy.oob_mode = SATA_OOB_MODE;
> > - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
> > + if (!pm8001_ha->reset_in_progress) {
> > + sas_ha->notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE);
> > + } else
> > + PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
> > + "HW_EVENT_PHY_UP: not notified to host\n"));
> > spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags);
> > memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4),
> > sizeof(struct dev_to_host_fis)); @@ -3405,7 +3483,8 @@
> > hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb)
> > phy->identify.device_type = SAS_SATA_DEV;
> > pm8001_get_attached_sas_addr(phy, phy-
> > >sas_phy.attached_sas_addr);
> > spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
> > - pm8001_bytes_dmaed(pm8001_ha, phy_id);
> > + if (!pm8001_ha->reset_in_progress)
> > + pm8001_bytes_dmaed(pm8001_ha, phy_id);
> > }
> >
> > /**
> > @@ -3501,12 +3580,14 @@ static int mpi_phy_start_resp(struct
> > pm8001_hba_info *pm8001_ha, void *piomb)
> > status, phy_id));
> > if (status == 0) {
> > phy->phy_state = PHY_LINK_DOWN;
> > - if (pm8001_ha->flags == PM8001F_RUN_TIME &&
> > - phy->enable_completion != NULL) {
> > - complete(phy->enable_completion);
> > - phy->enable_completion = NULL;
> > - }
> > }
> > +
> > + if (pm8001_ha->flags == PM8001F_RUN_TIME &&
> > + phy->enable_completion != NULL) {
> > + complete(phy->enable_completion);
> > + phy->enable_completion = NULL;
> > + }
> > +
> > return 0;
> >
> > }
> > @@ -3584,7 +3665,14 @@ static int mpi_hw_event(struct pm8001_hba_info
> > *pm8001_ha, void *piomb)
> > case HW_EVENT_SATA_SPINUP_HOLD:
> > PM8001_MSG_DBG(pm8001_ha,
> > pm8001_printk("HW_EVENT_SATA_SPINUP_HOLD\n"));
> > - sas_ha->notify_phy_event(&phy->sas_phy, PHYE_SPINUP_HOLD);
> > + spin_lock_irqsave(&pm8001_ha->phy_q_lock, flags);
> > + pm8001_queue_phyup(pm8001_ha, phy_id);
> > + spin_unlock_irqrestore(&pm8001_ha->phy_q_lock, flags);
> > +
> > + /* Start the timer if not started */
> > + if (!timer_pending(&pm8001_ha->spinup_timer))
> > + mod_timer(&pm8001_ha->spinup_timer,
> > + jiffies +
> > + msecs_to_jiffies(pm8001_ha->spinup_interval));
> > break;
> > case HW_EVENT_PHY_DOWN:
> > PM8001_MSG_DBG(pm8001_ha, @@ -4896,7 +4984,7 @@
> > 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));
> >
> > - payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_DISABLE |
> > + payload.ase_sh_lm_slr_phyid = cpu_to_le32(SPINHOLD_ENABLE |
> > LINKMODE_AUTO | pm8001_ha->link_rate | phy_id);
> > /* SSC Disable and SAS Analog ST configuration */
> > /**
> > @@ -4957,6 +5045,8 @@ static int pm80xx_chip_reg_dev_req(struct
> > pm8001_hba_info *pm8001_ha,
> > u16 ITNT = 2000;
> > struct domain_device *dev = pm8001_dev->sas_device;
> > struct domain_device *parent_dev = dev->parent;
> > + struct pm8001_phy *phy;
> > + struct pm8001_port *port;
> > circularQ = &pm8001_ha->inbnd_q_tbl[0];
> >
> > memset(&payload, 0, sizeof(payload)); @@ -4988,8 +5078,11 @@ static
> > int pm80xx_chip_reg_dev_req(struct pm8001_hba_info *pm8001_ha,
> > linkrate = (pm8001_dev->sas_device->linkrate < dev->port->linkrate) ?
> > pm8001_dev->sas_device->linkrate : dev->port->linkrate;
> >
> > + phy = &pm8001_ha->phy[phy_id];
> > + port = phy->port;
> > +
> > payload.phyid_portid =
> > - cpu_to_le32(((pm8001_dev->sas_device->port->id) & 0xFF) |
> > + cpu_to_le32(((port->port_id) & 0xFF) |
> > ((phy_id & 0xFF) << 8));
> >
> > payload.dtype_dlr_mcn_ir_retry = cpu_to_le32((retryFlag & 0x01) |
> > --
> > 2.16.3
>
prev parent reply other threads:[~2020-09-02 14:49 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-20 18:51 [PATCH v8 0/2] pm80xx : Updates for the driver version 0.1.39 Viswas G
2020-08-20 18:51 ` [PATCH v8 1/2] pm80xx : Support for get phy profile functionality Viswas G
2020-09-02 1:19 ` Martin K. Petersen
2020-09-02 6:35 ` Viswas.G
2020-09-03 1:17 ` Martin K. Petersen
2020-09-09 10:15 ` Viswas.G
2020-08-20 18:51 ` [PATCH v8 2/2] pm80xx : Staggered spin up support Viswas G
2020-09-02 1:20 ` Martin K. Petersen
2020-09-02 6:38 ` Viswas.G
2020-09-11 5:41 ` Viswas.G
2020-09-11 7:30 ` John Garry
[not found] ` <SN6PR11MB348877970A45BA993C95D14D9D5B0@SN6PR11MB3488.namprd11.prod.outlook.com>
2020-09-02 14:05 ` Jinpu Wang [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAMGffE=LbTGy9agYqD0Z9=AgdiPm24sq=Awj=-5JzC04YKabJQ@mail.gmail.com' \
--to=jinpu.wang@cloud.ionos.com \
--cc=Vasanthalakshmi.Tharmarajan@microchip.com \
--cc=Viswas.G@microchip.com \
--cc=auradkar@google.com \
--cc=jinpu.wang@profitbricks.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).