Re: [PATCH v3 13/23] scsi: hisi_sas: add phy up/down/bcast and channel ISR

2017-06-01 Thread John Garry

On 01/06/2017 06:41, Christoph Hellwig wrote:

> +static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
> +{
> +  struct device *dev = hisi_hba->dev;
> +  struct pci_dev *pdev = hisi_hba->pci_dev;
> +  int vectors, i, irq, rc;
> +  int max_msi = HISI_SAS_MSI_COUNT_V3_HW;
> +  int msi_vectors[HISI_SAS_MSI_COUNT_V3_HW];
> +
> +  if (pdev->msi_enabled)
> +  pci_disable_msi(pdev);

How could MSIs be enabled at init time?  Even if so you should use
pci_free_irq_vectors.


Right, I don't think it could, so this can be removed.




> +  for (i = 0; i < vectors; i++)
> +  msi_vectors[i] = pdev->irq + i;

You should not need this array, just use pci_irq_vectors().



That should be ok.


.



Thanks,
John



Re: [PATCH v3 13/23] scsi: hisi_sas: add phy up/down/bcast and channel ISR

2017-05-31 Thread Christoph Hellwig
On Wed, May 31, 2017 at 10:33:05PM +0800, John Garry wrote:
> From: Xiang Chen 
> 
> Add code to initialise interrupts and add some interrupt handlers.
> 
> Signed-off-by: John Garry 
> Signed-off-by: Xiang Chen 
> ---
>  drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 281 
> +
>  1 file changed, 281 insertions(+)
> 
> diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c 
> b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> index 9651658..49f14d2 100644
> --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
> @@ -173,6 +173,13 @@ enum {
>   HISI_SAS_PHY_INT_NR
>  };
>  
> +static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
> +{
> + void __iomem *regs = hisi_hba->regs + off;
> +
> + return readl(regs);
> +}
> +
>  static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)
>  {
>   void __iomem *regs = hisi_hba->regs + off;
> @@ -397,6 +404,276 @@ static void sl_notify_v3_hw(struct hisi_hba *hisi_hba, 
> int phy_no)
>   hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
>  }
>  
> +static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
> +{
> + int i, res = 0;
> + u32 context, port_id, link_rate, hard_phy_linkrate;
> + struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
> + struct asd_sas_phy *sas_phy = &phy->sas_phy;
> + struct device *dev = hisi_hba->dev;
> +
> + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
> +
> + port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
> + port_id = (port_id >> (4 * phy_no)) & 0xf;
> + link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
> + link_rate = (link_rate >> (phy_no * 4)) & 0xf;
> +
> + if (port_id == 0xf) {
> + dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);
> + res = IRQ_NONE;
> + goto end;
> + }
> + sas_phy->linkrate = link_rate;
> + hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
> + HARD_PHY_LINKRATE);
> + phy->maximum_linkrate = hard_phy_linkrate & 0xf;
> + phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
> + phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
> +
> + /* Check for SATA dev */
> + context = hisi_sas_read32(hisi_hba, PHY_CONTEXT);
> + if (context & (1 << phy_no)) {
> + struct hisi_sas_initial_fis *initial_fis;
> + struct dev_to_host_fis *fis;
> + u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
> +
> + dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
> + initial_fis = &hisi_hba->initial_fis[phy_no];
> + fis = &initial_fis->fis;
> + sas_phy->oob_mode = SATA_OOB_MODE;
> + attached_sas_addr[0] = 0x50;
> + attached_sas_addr[7] = phy_no;
> + memcpy(sas_phy->attached_sas_addr,
> +attached_sas_addr,
> +SAS_ADDR_SIZE);
> + memcpy(sas_phy->frame_rcvd, fis,
> +sizeof(struct dev_to_host_fis));
> + phy->phy_type |= PORT_TYPE_SATA;
> + phy->identify.device_type = SAS_SATA_DEV;
> + phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
> + phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
> + } else {
> + u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;
> + struct sas_identify_frame *id =
> + (struct sas_identify_frame *)frame_rcvd;
> +
> + dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
> + for (i = 0; i < 6; i++) {
> + u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
> +RX_IDAF_DWORD0 + (i * 4));
> + frame_rcvd[i] = __swab32(idaf);
> + }
> + sas_phy->oob_mode = SAS_OOB_MODE;
> + memcpy(sas_phy->attached_sas_addr,
> +&id->sas_addr,
> +SAS_ADDR_SIZE);
> + phy->phy_type |= PORT_TYPE_SAS;
> + phy->identify.device_type = id->dev_type;
> + phy->frame_rcvd_size = sizeof(struct sas_identify_frame);
> + if (phy->identify.device_type == SAS_END_DEVICE)
> + phy->identify.target_port_protocols =
> + SAS_PROTOCOL_SSP;
> + else if (phy->identify.device_type != SAS_PHY_UNUSED)
> + phy->identify.target_port_protocols =
> + SAS_PROTOCOL_SMP;
> + }
> +
> + phy->port_id = port_id;
> + phy->phy_attached = 1;
> + queue_work(hisi_hba->wq, &phy->phyup_ws);
> +
> +end:
> + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
> +  CHL_INT0_SL_PHY_ENABLE_MSK);
> + hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0);
> +
> + return res;
> +}
> +
> +static int

[PATCH v3 13/23] scsi: hisi_sas: add phy up/down/bcast and channel ISR

2017-05-31 Thread John Garry
From: Xiang Chen 

Add code to initialise interrupts and add some interrupt handlers.

Signed-off-by: John Garry 
Signed-off-by: Xiang Chen 
---
 drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 281 +
 1 file changed, 281 insertions(+)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c 
b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index 9651658..49f14d2 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -173,6 +173,13 @@ enum {
HISI_SAS_PHY_INT_NR
 };
 
+static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+{
+   void __iomem *regs = hisi_hba->regs + off;
+
+   return readl(regs);
+}
+
 static void hisi_sas_write32(struct hisi_hba *hisi_hba, u32 off, u32 val)
 {
void __iomem *regs = hisi_hba->regs + off;
@@ -397,6 +404,276 @@ static void sl_notify_v3_hw(struct hisi_hba *hisi_hba, 
int phy_no)
hisi_sas_phy_write32(hisi_hba, phy_no, SL_CONTROL, sl_control);
 }
 
+static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+{
+   int i, res = 0;
+   u32 context, port_id, link_rate, hard_phy_linkrate;
+   struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
+   struct asd_sas_phy *sas_phy = &phy->sas_phy;
+   struct device *dev = hisi_hba->dev;
+
+   hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 1);
+
+   port_id = hisi_sas_read32(hisi_hba, PHY_PORT_NUM_MA);
+   port_id = (port_id >> (4 * phy_no)) & 0xf;
+   link_rate = hisi_sas_read32(hisi_hba, PHY_CONN_RATE);
+   link_rate = (link_rate >> (phy_no * 4)) & 0xf;
+
+   if (port_id == 0xf) {
+   dev_err(dev, "phyup: phy%d invalid portid\n", phy_no);
+   res = IRQ_NONE;
+   goto end;
+   }
+   sas_phy->linkrate = link_rate;
+   hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no,
+   HARD_PHY_LINKRATE);
+   phy->maximum_linkrate = hard_phy_linkrate & 0xf;
+   phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf;
+   phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
+
+   /* Check for SATA dev */
+   context = hisi_sas_read32(hisi_hba, PHY_CONTEXT);
+   if (context & (1 << phy_no)) {
+   struct hisi_sas_initial_fis *initial_fis;
+   struct dev_to_host_fis *fis;
+   u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
+
+   dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+   initial_fis = &hisi_hba->initial_fis[phy_no];
+   fis = &initial_fis->fis;
+   sas_phy->oob_mode = SATA_OOB_MODE;
+   attached_sas_addr[0] = 0x50;
+   attached_sas_addr[7] = phy_no;
+   memcpy(sas_phy->attached_sas_addr,
+  attached_sas_addr,
+  SAS_ADDR_SIZE);
+   memcpy(sas_phy->frame_rcvd, fis,
+  sizeof(struct dev_to_host_fis));
+   phy->phy_type |= PORT_TYPE_SATA;
+   phy->identify.device_type = SAS_SATA_DEV;
+   phy->frame_rcvd_size = sizeof(struct dev_to_host_fis);
+   phy->identify.target_port_protocols = SAS_PROTOCOL_SATA;
+   } else {
+   u32 *frame_rcvd = (u32 *)sas_phy->frame_rcvd;
+   struct sas_identify_frame *id =
+   (struct sas_identify_frame *)frame_rcvd;
+
+   dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate);
+   for (i = 0; i < 6; i++) {
+   u32 idaf = hisi_sas_phy_read32(hisi_hba, phy_no,
+  RX_IDAF_DWORD0 + (i * 4));
+   frame_rcvd[i] = __swab32(idaf);
+   }
+   sas_phy->oob_mode = SAS_OOB_MODE;
+   memcpy(sas_phy->attached_sas_addr,
+  &id->sas_addr,
+  SAS_ADDR_SIZE);
+   phy->phy_type |= PORT_TYPE_SAS;
+   phy->identify.device_type = id->dev_type;
+   phy->frame_rcvd_size = sizeof(struct sas_identify_frame);
+   if (phy->identify.device_type == SAS_END_DEVICE)
+   phy->identify.target_port_protocols =
+   SAS_PROTOCOL_SSP;
+   else if (phy->identify.device_type != SAS_PHY_UNUSED)
+   phy->identify.target_port_protocols =
+   SAS_PROTOCOL_SMP;
+   }
+
+   phy->port_id = port_id;
+   phy->phy_attached = 1;
+   queue_work(hisi_hba->wq, &phy->phyup_ws);
+
+end:
+   hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0,
+CHL_INT0_SL_PHY_ENABLE_MSK);
+   hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_PHY_ENA_MSK, 0);
+
+   return res;
+}
+
+static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
+{
+   int res = 0;
+   u32 phy_state, sl_ctrl, txid_auto;
+   struct device *dev =