> From: Viswas G <Viswas.G@xxxxxxxxxxxxx> > > 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@xxxxxxxxxxxxx> > Signed-off-by: Radha Ramachandran <radha@xxxxxxxxxx> > Signed-off-by: Deepak Ukey <Deepak.Ukey@xxxxxxxxxxxxx> > --- > 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 | 37 ++++++++++- > drivers/scsi/pm8001/pm8001_sas.h | 14 +++++ > drivers/scsi/pm8001/pm80xx_hwi.c | 125 > +++++++++++++++++++++++++++++++++----- > 6 files changed, 223 insertions(+), 23 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 fb9848e1d481..6378c8e8d6b2 100644 > --- a/drivers/scsi/pm8001/pm8001_hwi.c > +++ b/drivers/scsi/pm8001/pm8001_hwi.c > @@ -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); diff --git > a/drivers/scsi/pm8001/pm8001_init.c > b/drivers/scsi/pm8001/pm8001_init.c > index 68005d0cb33d..6cbb8fa74456 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, > @@ -486,6 +492,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); @@ -620,7 > +627,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]; > @@ -706,6 +714,45 @@ 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)); > } > > /* > @@ -1104,7 +1151,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 3a69d8d1d52e..806845203602 100644 > --- a/drivers/scsi/pm8001/pm8001_sas.c > +++ b/drivers/scsi/pm8001/pm8001_sas.c > @@ -267,12 +267,38 @@ void pm8001_scan_start(struct Scsi_Host *shost) > int i; > 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, > + pm8001_ha->lock_flags); > + pm8001_ha->phy_started = i; > + pm8001_ha->scan_completion = ∁ > + pm8001_ha->phystart_timedout = 1; > + spin_unlock_irqrestore(&pm8001_ha->lock, > + pm8001_ha->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, pm8001_ha->lock_flags); > + pm8001_ha->phy_started = -1; > + pm8001_ha->scan_completion = NULL; > + spin_unlock_irqrestore(&pm8001_ha->lock, pm8001_ha->lock_flags); > + } > } > > int pm8001_scan_finished(struct Scsi_Host *shost, unsigned long time) > @@ -663,6 +689,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 cba4e9b95c58..df02c6cd116a 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; > }; > > @@ -503,6 +504,7 @@ struct pm8001_hba_info { > unsigned long flags; > spinlock_t lock;/* host-wide lock */ > spinlock_t bitmap_lock; > + unsigned long lock_flags; This seems fine, only one question: why do you need this lock_flags in hba? [DU] Thanks for comment. I will remove the lok_flags from hba structure and add it locally. > struct pci_dev *pdev;/* our device */ > struct device *dev; > struct pm8001_hba_memspace io_mem[6]; @@ -566,6 +568,17 @@ > struct pm8001_hba_info { > u32 non_fatal_read_length; > struct completion *phyprofile_completion; > struct phy_prof_resp phy_profile_resp; > + 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 +697,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 0f4f18b0e480..0040bb4e1b71 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); > + > +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) { @@ -3302,11 +3368,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, @@ -3314,8 +3381,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; > @@ -3351,9 +3422,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); > + } > } > > /** > @@ -3388,11 +3460,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)); @@ -3401,7 +3479,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); > } > > /** > @@ -3497,12 +3576,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; > > } > @@ -3580,7 +3661,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, @@ -4889,7 +4977,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 */ > /** > @@ -4951,6 +5039,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)); @@ -4982,8 +5072,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 >