pm80xx: Add ATTO 12Gb HBA support and fix various issues
Subsystems (2)
cover pm80xx: Add ATTO 12Gb HBA support and fix various issues
The following series of patches are primarily aimed at adding support for ATTO's 12Gb SAS adapters, which are based off of the PMC-Sierra 8070/8072 series chips. I have also addressed other various issues that were discovered during our testing and verification phase, mainly with resume-from-sleep, configuring PHY profiles, and using legacy interrupts.
Diffstat:
drivers/scsi/pm8001/pm8001_defs.h | 2 ++ drivers/scsi/pm8001/pm8001_init.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- drivers/scsi/pm8001/pm8001_sas.h | 6 +++- drivers/scsi/pm8001/pm80xx_hwi.c | 34 ++++++++++++++++++++++ 4 files changed, 241 insertions(+), 13 deletions(-)
PATCH 1/8 pm80xx: configure PHY settings based on subsystem vendor ID
Previuosly, all PMC Sierra 80xx controllers are assumed to be a motherboard controller, except if the subsystem vendor ID was equal to PCI_VENDOR_ID_ADAPTEC. The driver then attempts to load PHY settings from NVRAM. While this may be correct behavior for most controllers, it does not work with Adaptec and ATTO controllers since they do not store PHY settings in NVRAM and choose to use either custom PHY settings or chip defaults. Loading random values from NVRAM may cause the controllers to malfunction in this edge case.
--- drivers/scsi/pm8001/pm8001_init.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/scsi/pm8001/pm8001_init.c +20 -6
@@ -720,6 +720,23 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)return 0 ; } +/** +* pm8001_configure_phy_settings : Configures PHY settings based on vendor ID. +* @pm8001_ha : our hba. +*/ +static int pm8001_configure_phy_settings (struct pm8001_hba_info *pm8001_ha) +{ +switch (pm8001_ha->pdev->subsystem_vendor) { +case PCI_VENDOR_ID_ATTO : +case PCI_VENDOR_ID_ADAPTEC2 : +case 0 : +return 0 ; + +default : +return pm8001_get_phy_settings_info (pm8001_ha); + } +} +#ifdef PM8001_USE_MSIX /** * pm8001_setup_msix - enable MSI-X interrupt
@@ -902,12 +919,9 @@ static int pm8001_pci_probe(struct pci_dev *pdev,pm8001_init_sas_add (pm8001_ha);/* phy setting support for motherboard controller */ -if (pdev->subsystem_vendor !=PCI_VENDOR_ID_ADAPTEC2 && - pdev->subsystem_vendor !=0 ) { - rc =pm8001_get_phy_settings_info (pm8001_ha); -if (rc) - goto err_out_shost; - } +if (pm8001_configure_phy_settings (pm8001_ha)) + goto err_out_shost; +pm8001_post_sas_ha_init (shost, chip); rc =sas_register_ha (SHOST_TO_SAS_HA (shost));if (rc)
Signature · 1 line
2.4.3
Re: [PATCH 1/8] pm80xx: configure PHY settings based on subsystem vendor ID
Quoted 9 lines · Benjamin Rood
Previuosly, all PMC Sierra 80xx controllers are assumed to be a motherboard controller, except if the subsystem vendor ID was equal to
PCI_VENDOR_ID_ADAPTEC. The driver then attempts to load PHY settings from NVRAM. While this may be correct behavior for most controllers, it does not work with Adaptec and ATTO controllers since they do not store PHY settings in NVRAM and choose to use either custom PHY settings or chip defaults. Loading random values from NVRAM may cause the controllers to malfunction in this edge case.
Quoted 5 lines
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/8] pm80xx: configure PHY settings based on subsystem vendor ID
In reply to Benjamin RoodThanks
Jack
2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 61 lines
Previuosly, all PMC Sierra 80xx controllers are assumed to be a motherboard controller, except if the subsystem vendor ID was equal to
PCI_VENDOR_ID_ADAPTEC. The driver then attempts to load PHY settings from NVRAM. While this may be correct behavior for most controllers, it does not work with Adaptec and ATTO controllers since they do not store PHY settings in NVRAM and choose to use either custom PHY settings or chip defaults. Loading random values from NVRAM may cause the controllers to malfunction in this edge case.Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)drivers/scsi/pm8001/pm8001_init.c +20
-7@@ -720,6 +720,23 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)return 0 ; } +/** +* pm8001_configure_phy_settings : Configures PHY settings based on vendor ID. +* @pm8001_ha : our hba. +*/ +static int pm8001_configure_phy_settings (struct pm8001_hba_info *pm8001_ha) +{ +switch (pm8001_ha->pdev->subsystem_vendor) { +case PCI_VENDOR_ID_ATTO : +case PCI_VENDOR_ID_ADAPTEC2 : +case 0 : +return 0 ; + +default : +return pm8001_get_phy_settings_info (pm8001_ha); + } +} +#ifdef PM8001_USE_MSIX /** * pm8001_setup_msix - enable MSI-X interrupt @@ -902,12 +919,9 @@ static int pm8001_pci_probe(struct pci_dev *pdev,pm8001_init_sas_add (pm8001_ha);/* phy setting support for motherboard controller */ -if (pdev->subsystem_vendor !=PCI_VENDOR_ID_ADAPTEC2 && - pdev->subsystem_vendor !=0 ) { - rc =pm8001_get_phy_settings_info (pm8001_ha); -if (rc) - goto err_out_shost; - } +if (pm8001_configure_phy_settings (pm8001_ha)) + goto err_out_shost; +pm8001_post_sas_ha_init (shost, chip); rc =sas_register_ha (SHOST_TO_SAS_HA (shost));if (rc) --2.4.3
PATCH 2/8 pm80xx: add support for PMC Sierra 8070 and PMC Sierra 8072 SAS controllers
In reply to Benjamin RoodThese SAS controllers support speeds up to 12Gb.
--- drivers/scsi/pm8001/pm8001_defs.h | 2 ++ drivers/scsi/pm8001/pm8001_init.c | 4 +++- drivers/scsi/pm8001/pm8001_sas.h | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)
drivers/scsi/pm8001/pm8001_defs.h +2 -0
@@ -51,6 +51,8 @@ enum chip_flavors { chip_8076, chip_8077, chip_8006, + chip_8070, + chip_8072 }; enum phy_speed {
drivers/scsi/pm8001/pm8001_init.c +3 -1
@@ -58,6 +58,8 @@ static const struct pm8001_chip_info pm8001_chips[] = { [chip_8076] = {0, 16, &pm8001_80xx_dispatch,}, [chip_8077] = {0, 16, &pm8001_80xx_dispatch,}, [chip_8006] = {0, 16, &pm8001_80xx_dispatch,}, + [chip_8070] = {0, 8, &pm8001_80xx_dispatch,}, + [chip_8072] = {0, 16, &pm8001_80xx_dispatch,}, };static int pm8001_id;
@@ -1234,7 +1236,7 @@ MODULE_AUTHOR("Anand Kumar Santhanam <[email protected]>");MODULE_AUTHOR ("Sangeetha Gnanasekaran <[email protected]>" );MODULE_AUTHOR ("Nikith Ganigarakoppal <[email protected]>" );MODULE_DESCRIPTION ( -"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077 " +"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077/8070/8072 " "SAS/SATA controller driver" );MODULE_VERSION (DRV_VERSION );MODULE_LICENSE ("GPL" );
drivers/scsi/pm8001/pm8001_sas.h +3 -1
@@ -106,7 +106,9 @@ do { \#define DEV_IS_EXPANDER (type) ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))#define IS_SPCV_12G (dev) ((dev->device == 0X8074) \ || (dev->device == 0X8076) \ - || (dev->device == 0X8077)) + || (dev->device == 0X8077) \ + || (dev->device == 0X8070) \ + || (dev->device == 0X8072))#define PM8001_NAME_LENGTH 32/* generic length of strings */ extern struct list_head hba_list;
Signature · 1 line
2.4.3
Re: [PATCH 2/8] pm80xx: add support for PMC Sierra 8070 and PMC Sierra 8072 SAS controllers
Quoted 9 lines · Benjamin Rood
These SAS controllers support speeds up to 12Gb.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_defs.h | 2 ++ drivers/scsi/pm8001/pm8001_init.c | 4 +++- drivers/scsi/pm8001/pm8001_sas.h | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/8] pm80xx: add support for PMC Sierra 8070 and PMC Sierra 8072 SAS controllers
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 60 lines
These SAS controllers support speeds up to 12Gb.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_defs.h | 2 ++ drivers/scsi/pm8001/pm8001_init.c | 4 +++- drivers/scsi/pm8001/pm8001_sas.h | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-)drivers/scsi/pm8001/pm8001_defs.h +2
-0@@ -51,6 +51,8 @@ enum chip_flavors { chip_8076, chip_8077, chip_8006, + chip_8070, + chip_8072 }; enum phy_speed {drivers/scsi/pm8001/pm8001_init.c +3
-1@@ -58,6 +58,8 @@ static const struct pm8001_chip_info pm8001_chips[] = { [chip_8076] = {0, 16, &pm8001_80xx_dispatch,}, [chip_8077] = {0, 16, &pm8001_80xx_dispatch,}, [chip_8006] = {0, 16, &pm8001_80xx_dispatch,}, + [chip_8070] = {0, 8, &pm8001_80xx_dispatch,}, + [chip_8072] = {0, 16, &pm8001_80xx_dispatch,}, };static int pm8001_id;@@ -1234,7 +1236,7 @@ MODULE_AUTHOR("Anand Kumar Santhanam <[email protected]>");MODULE_AUTHOR ("Sangeetha Gnanasekaran <[email protected]>" );MODULE_AUTHOR ("Nikith Ganigarakoppal <[email protected]>" );MODULE_DESCRIPTION ( -"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077 " +"PMC-Sierra PM8001/8006/8081/8088/8089/8074/8076/8077/8070/8072 " "SAS/SATA controller driver" );MODULE_VERSION (DRV_VERSION );MODULE_LICENSE ("GPL" );drivers/scsi/pm8001/pm8001_sas.h +3
-2@@ -106,7 +106,9 @@ do { \#define DEV_IS_EXPANDER (type) ((type == SAS_EDGE_EXPANDER_DEVICE) || (type == SAS_FANOUT_EXPANDER_DEVICE))#define IS_SPCV_12G (dev) ((dev->device == 0X8074) \ || (dev->device == 0X8076) \ - || (dev->device == 0X8077)) + || (dev->device == 0X8077) \ + || (dev->device == 0X8070) \ + || (dev->device == 0X8072))#define PM8001_NAME_LENGTH 32/* generic length of strings */ extern struct list_head hba_list; --
Quoted 2 lines
2.4.3
Thanks
Jack
PATCH 3/8 pm80xx: add ATTO PCI IDs to pm8001_pci_table
In reply to Benjamin RoodThese PCI IDs allow the pm8001 driver to load against ATTO 12Gb SAS controllers that use PMC Sierra 8070 and PMC Sierra 8072 SAS chips.
--- drivers/scsi/pm8001/pm8001_init.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +14 -0
@@ -1181,6 +1181,20 @@ static struct pci_device_id pm8001_pci_table[] = { PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8077 }, {PCI_VENDOR_ID_ADAPTEC2 ,0x8074 , PCI_VENDOR_ID_ADAPTEC2, 0x0404, 0, 0, chip_8074 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0070, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0071, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0072, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0073, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0080, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0081, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0082, 0, 0, chip_8072 }, {} /* terminate list */ };
Signature · 1 line
2.4.3
Re: [PATCH 3/8] pm80xx: add ATTO PCI IDs to pm8001_pci_table
Quoted 8 lines · Benjamin Rood
These PCI IDs allow the pm8001 driver to load against ATTO 12Gb SAS controllers that use PMC Sierra 8070 and PMC Sierra 8072 SAS chips.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/8] pm80xx: add ATTO PCI IDs to pm8001_pci_table
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 34 lines
These PCI IDs allow the pm8001 driver to load against ATTO 12Gb SAS controllers that use PMC Sierra 8070 and PMC Sierra 8072 SAS chips.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)drivers/scsi/pm8001/pm8001_init.c +14
-1@@ -1181,6 +1181,20 @@ static struct pci_device_id pm8001_pci_table[] = { PCI_VENDOR_ID_ADAPTEC2, 0x0808, 0, 0, chip_8077 }, {PCI_VENDOR_ID_ADAPTEC2 ,0x8074 , PCI_VENDOR_ID_ADAPTEC2, 0x0404, 0, 0, chip_8074 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0070, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0071, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0072, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0073, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8070, + PCI_VENDOR_ID_ATTO, 0x0080, 0, 0, chip_8070 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0081, 0, 0, chip_8072 }, + { PCI_VENDOR_ID_ATTO, 0x8072, + PCI_VENDOR_ID_ATTO, 0x0082, 0, 0, chip_8072 }, {} /* terminate list */ }; --
Quoted 2 lines
2.4.3
Thanks
Jack
PATCH 4/8 pm80xx: add support for ATTO devices during SAS address initiailization
In reply to Benjamin RoodATTO SAS controllers retrieve the SAS address from the NVRAM in a location different from non-ATTO PMC Sierra SAS controllers. This patch makes the necessary adjustments in order to retrieve the SAS address on these types of adapters.
--- drivers/scsi/pm8001/pm8001_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +10 -0
@@ -636,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) payload.minor_function =0 ; payload.length =128 ; } + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + payload.minor_function =4 ; + payload.length =4096 ; }else { payload.minor_function =1 ; payload.length =4096 ;
@@ -662,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)else if (deviceid ==0x0042 ) pm8001_ha->sas_addr[j] = payload.func_specific[0x010 + i]; + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + pm8001_ha->sas_addr[j] = + payload.func_specific[0x010 + i]; }else pm8001_ha->sas_addr[j] = payload.func_specific[0x804 + i];
Signature · 1 line
2.4.3
Re: [PATCH 4/8] pm80xx: add support for ATTO devices during SAS address initiailization
Quoted 29 lines · Benjamin Rood
ATTO SAS controllers retrieve the SAS address from the NVRAM in a location different from non-ATTO PMC Sierra SAS controllers. This patch makes the necessary adjustments in order to retrieve the SAS address on these types of adapters.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+)drivers/scsi/pm8001/pm8001_init.c +5
-0@@ -636,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) payload.minor_function =0 ; payload.length =128 ; } + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + payload.minor_function =4 ; + payload.length =4096 ; }else { payload.minor_function =1 ; payload.length =4096 ;@@ -662,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)else if (deviceid ==0x0042 )
drivers/scsi/pm8001/pm8001_init.c static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) · line 677
Quoted 10 lines
drivers/scsi/pm8001/pm8001_init.c +5
-0pm8001_ha->sas_addr[j] = payload.func_specific[0x010 + i]; + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + pm8001_ha->sas_addr[j] = + payload.func_specific[0x010 + i]; }else pm8001_ha->sas_addr[j] = payload.func_specific[0x804 + i];
The indentation is a bit skewed here.
Other than that:
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Jack Wang
Reviewed-byRe: [PATCH 4/8] pm80xx: add support for ATTO devices during SAS address initiailization
2015-11-02 8:53 GMT+01:00 Hannes Reinecke <[email protected]>:
Quoted 43 lines · Benjamin Rood
Quoted 29 lines
ATTO SAS controllers retrieve the SAS address from the NVRAM in a location different from non-ATTO PMC Sierra SAS controllers. This patch makes the necessary adjustments in order to retrieve the SAS address on these types of adapters.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+)drivers/scsi/pm8001/pm8001_init.c +5
-0@@ -636,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) payload.minor_function =0 ; payload.length =128 ; } + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + payload.minor_function =4 ; + payload.length =4096 ; }else { payload.minor_function =1 ; payload.length =4096 ;@@ -662,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)else if (deviceid ==0x0042 )drivers/scsi/pm8001/pm8001_init.c static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) · line 677
Quoted 10 lines
drivers/scsi/pm8001/pm8001_init.c +5
-0pm8001_ha->sas_addr[j] = payload.func_specific[0x010 + i]; + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + pm8001_ha->sas_addr[j] = + payload.func_specific[0x010 + i]; }else pm8001_ha->sas_addr[j] = payload.func_specific[0x804 + i];The indentation is a bit skewed here.
Other than that:
Quoted 5 lines
Reviewed-by Hannes Reinecke <[email protected]>Cheers,
Hannes
Agree with Hannes :), please fix this if you post V2.
Thanks
Jack
PATCH v2 4/9 pm80xx: add support for ATTO devices during SAS address initiailization
ATTO SAS controllers retrieve the SAS address from the NVRAM in a location different from non-ATTO PMC Sierra SAS controllers. This patch makes the necessary adjustments in order to retrieve the SAS address on these types of adapters.
---
Changes from v1 -> v2:
-Fixed indentation issues noted by Hannes and Jack
drivers/scsi/pm8001/pm8001_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +10 -0
@@ -636,6 +636,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha) payload.minor_function =0 ; payload.length =128 ; } + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + payload.minor_function =4 ; + payload.length =4096 ; }else { payload.minor_function =1 ; payload.length =4096 ;
@@ -662,6 +667,11 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)else if (deviceid ==0x0042 ) pm8001_ha->sas_addr[j] = payload.func_specific[0x010 + i]; + }else if ((pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) && + pm8001_ha->pdev->subsystem_vendor ==PCI_VENDOR_ID_ATTO ) { + pm8001_ha->sas_addr[j] = + payload.func_specific[0x010 + i]; }else pm8001_ha->sas_addr[j] = payload.func_specific[0x804 + i];
Signature · 1 line
2.4.3
PATCH 5/8 pm80xx: set PHY profiles for ATTO 12Gb SAS controllers
In reply to Benjamin RoodPHY profiles are not saved in NVRAM on ATTO 12Gb SAS controllers. Therefore, in order for the controller to function in a wide range of configurations, the PHY profiles must be statically set. This patch provides the necessary functionality to do so.
--- drivers/scsi/pm8001/pm8001_init.c | 130 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 2 + drivers/scsi/pm8001/pm80xx_hwi.c | 32 ++++++++++ 3 files changed, 164 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +130 -0
@@ -732,6 +732,131 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)return 0 ; } +struct pm8001_mpi3_phy_pg_trx_config { +u32 LaneLosCfg; +u32 LanePgaCfg1; +u32 LanePisoCfg1; +u32 LanePisoCfg2; +u32 LanePisoCfg3; +u32 LanePisoCfg4; +u32 LanePisoCfg5; +u32 LanePisoCfg6; +u32 LaneBctCtrl; +}; + +/** +* pm8001_get_internal_phy_settings : Retrieves the internal PHY settings +* @pm8001_ha : our adapter +* @phycfg : PHY config page to populate +*/ +static +void pm8001_get_internal_phy_settings (struct pm8001_hba_info *pm8001_ha, +struct pm8001_mpi3_phy_pg_trx_config *phycfg) +{ + phycfg->LaneLosCfg =0x00000132 ; + phycfg->LanePgaCfg1 =0x00203949 ; + phycfg->LanePisoCfg1 =0x000000FF ; + phycfg->LanePisoCfg2 =0xFF000001 ; + phycfg->LanePisoCfg3 =0xE7011300 ; + phycfg->LanePisoCfg4 =0x631C40C0 ; + phycfg->LanePisoCfg5 =0xF8102036 ; + phycfg->LanePisoCfg6 =0xF74A1000 ; + phycfg->LaneBctCtrl =0x00FB33F8 ; +} + +/** +* pm8001_get_external_phy_settings : Retrieves the external PHY settings +* @pm8001_ha : our adapter +* @phycfg : PHY config page to populate +*/ +static +void pm8001_get_external_phy_settings (struct pm8001_hba_info *pm8001_ha, +struct pm8001_mpi3_phy_pg_trx_config *phycfg) +{ + phycfg->LaneLosCfg =0x00000132 ; + phycfg->LanePgaCfg1 =0x00203949 ; + phycfg->LanePisoCfg1 =0x000000FF ; + phycfg->LanePisoCfg2 =0xFF000001 ; + phycfg->LanePisoCfg3 =0xE7011300 ; + phycfg->LanePisoCfg4 =0x63349140 ; + phycfg->LanePisoCfg5 =0xF8102036 ; + phycfg->LanePisoCfg6 =0xF80D9300 ; + phycfg->LaneBctCtrl =0x00FB33F8 ; +} + +/** +* pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext +* @pm8001_ha : our adapter +* @phymask : The PHY mask +*/ +static +void pm8001_get_phy_mask (struct pm8001_hba_info *pm8001_ha,int *phymask) +{ +switch (pm8001_ha->pdev->subsystem_device) { +case 0x0070 :/* H1280 - 8 external 0 internal */ +case 0x0072 :/* H12F0 - 16 external 0 internal */ + *phymask =0x0000 ; +break ; + +case 0x0071 :/* H1208 - 0 external 8 internal */ +case 0x0073 :/* H120F - 0 external 16 internal */ + *phymask =0xFFFF ; +break ; + +case 0x0080 :/* H1244 - 4 external 4 internal */ + *phymask =0x00F0 ; +break ; + +case 0x0081 :/* H1248 - 4 external 8 internal */ + *phymask =0x0FF0 ; +break ; + +case 0x0082 :/* H1288 - 8 external 8 internal */ + *phymask =0xFF00 ; +break ; + +default : +PM8001_INIT_DBG (pm8001_ha, +pm8001_printk ("Unknown subsystem device=0x%.04x" , + pm8001_ha->pdev->subsystem_device)); + } +} + +/** +* pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings +* @pm8001_ha : our adapter +*/ +static +int pm8001_set_phy_settings_ven_117c_12G (struct pm8001_hba_info *pm8001_ha) +{ +struct pm8001_mpi3_phy_pg_trx_config phycfg_int; +struct pm8001_mpi3_phy_pg_trx_config phycfg_ext; +int phymask =0 ; +int i =0 ; + +memset (&phycfg_int,0 ,sizeof (phycfg_int)); +memset (&phycfg_ext,0 ,sizeof (phycfg_ext)); + +pm8001_get_internal_phy_settings (pm8001_ha, &phycfg_int); +pm8001_get_external_phy_settings (pm8001_ha, &phycfg_ext); +pm8001_get_phy_mask (pm8001_ha, &phymask); + +for (i =0 ; i < pm8001_ha->chip->n_phy; i++) { +if (phymask & (1 << i)) {/* Internal PHY */ +pm8001_set_phy_profile_single (pm8001_ha, i, +sizeof (phycfg_int) /sizeof (u32), + (u32 *)&phycfg_int); + + }else {/* External PHY */ +pm8001_set_phy_profile_single (pm8001_ha, i, +sizeof (phycfg_ext) /sizeof (u32), + (u32 *)&phycfg_ext); + } + } + +return 0 ; +} +/** * pm8001_configure_phy_settings : Configures PHY settings based on vendor ID. * @pm8001_ha : our hba.
@@ -740,6 +865,11 @@ static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha) {switch (pm8001_ha->pdev->subsystem_vendor) {case PCI_VENDOR_ID_ATTO : +if (pm8001_ha->pdev->device ==0x0042 )/* 6Gb */ +return 0 ; +else +return pm8001_set_phy_settings_ven_117c_12G (pm8001_ha); +case PCI_VENDOR_ID_ADAPTEC2 :case 0 :return 0 ;
drivers/scsi/pm8001/pm8001_sas.h +2 -0
@@ -710,6 +710,8 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);int pm8001_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);void pm8001_set_phy_profile (struct pm8001_hba_info *pm8001_ha,u32 length,u8 *buf); +void pm8001_set_phy_profile_single (struct pm8001_hba_info *pm8001_ha, +u32 phy,u32 length,u32 *buf);int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);ssize_t pm80xx_get_fatal_dump (struct device *cdev,struct device_attribute *attr,char *buf);
drivers/scsi/pm8001/pm80xx_hwi.c +32 -0
@@ -4576,6 +4576,38 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha, }PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("phy settings completed\n" )); } + +void pm8001_set_phy_profile_single (struct pm8001_hba_info *pm8001_ha, +u32 phy,u32 length,u32 *buf) +{ +u32 tag, opc; +int rc, i; +struct set_phy_profile_req payload; +struct inbound_queue_table *circularQ; + +memset (&payload,0 ,sizeof (payload)); + + rc =pm8001_tag_alloc (pm8001_ha, &tag); +if (rc) +PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("Invalid tag" )); + + circularQ = &pm8001_ha->inbnd_q_tbl[0 ]; + opc =OPC_INB_SET_PHY_PROFILE ; + + payload.tag =cpu_to_le32 (tag); + payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE &0xF ) <<8 ) + | (phy &0xFF )); + +for (i =0 ; i < length; i++) + payload.reserved[i] =cpu_to_le32 (*(buf + i)); + + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +if (rc) +pm8001_tag_free (pm8001_ha, tag); + +PM8001_INIT_DBG (pm8001_ha, +pm8001_printk ("PHY %d settings applied" , phy)); +}const struct pm8001_dispatch pm8001_80xx_dispatch = { .name ="pmc80xx" , .chip_init = pm80xx_chip_init,
Signature · 1 line
2.4.3
Re: [PATCH 5/8] pm80xx: set PHY profiles for ATTO 12Gb SAS controllers
Quoted 5 lines · Benjamin Rood
PHY profiles are not saved in NVRAM on ATTO 12Gb SAS controllers. Therefore, in order for the controller to function in a wide range of configurations, the PHY profiles must be statically set. This patch provides the necessary functionality to do so.
Quoted 7 lines
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 130 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 2 + drivers/scsi/pm8001/pm80xx_hwi.c | 32 ++++++++++ 3 files changed, 164 insertions(+)
Hmm. Can't say I like compiling in magic constants, but I guess there's no easy way out here.
So:
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/8] pm80xx: set PHY profiles for ATTO 12Gb SAS controllers
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 217 lines
PHY profiles are not saved in NVRAM on ATTO 12Gb SAS controllers. Therefore, in order for the controller to function in a wide range of configurations, the PHY profiles must be statically set. This patch provides the necessary functionality to do so.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 130 ++++++++++++++++++++++++++++++++++++++ drivers/scsi/pm8001/pm8001_sas.h | 2 + drivers/scsi/pm8001/pm80xx_hwi.c | 32 ++++++++++ 3 files changed, 164 insertions(+)drivers/scsi/pm8001/pm8001_init.c +130
-0@@ -732,6 +732,131 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)return 0 ; } +struct pm8001_mpi3_phy_pg_trx_config { +u32 LaneLosCfg; +u32 LanePgaCfg1; +u32 LanePisoCfg1; +u32 LanePisoCfg2; +u32 LanePisoCfg3; +u32 LanePisoCfg4; +u32 LanePisoCfg5; +u32 LanePisoCfg6; +u32 LaneBctCtrl; +}; + +/** +* pm8001_get_internal_phy_settings : Retrieves the internal PHY settings +* @pm8001_ha : our adapter +* @phycfg : PHY config page to populate +*/ +static +void pm8001_get_internal_phy_settings (struct pm8001_hba_info *pm8001_ha, +struct pm8001_mpi3_phy_pg_trx_config *phycfg) +{ + phycfg->LaneLosCfg =0x00000132 ; + phycfg->LanePgaCfg1 =0x00203949 ; + phycfg->LanePisoCfg1 =0x000000FF ; + phycfg->LanePisoCfg2 =0xFF000001 ; + phycfg->LanePisoCfg3 =0xE7011300 ; + phycfg->LanePisoCfg4 =0x631C40C0 ; + phycfg->LanePisoCfg5 =0xF8102036 ; + phycfg->LanePisoCfg6 =0xF74A1000 ; + phycfg->LaneBctCtrl =0x00FB33F8 ; +} + +/** +* pm8001_get_external_phy_settings : Retrieves the external PHY settings +* @pm8001_ha : our adapter +* @phycfg : PHY config page to populate +*/ +static +void pm8001_get_external_phy_settings (struct pm8001_hba_info *pm8001_ha, +struct pm8001_mpi3_phy_pg_trx_config *phycfg) +{ + phycfg->LaneLosCfg =0x00000132 ; + phycfg->LanePgaCfg1 =0x00203949 ; + phycfg->LanePisoCfg1 =0x000000FF ; + phycfg->LanePisoCfg2 =0xFF000001 ; + phycfg->LanePisoCfg3 =0xE7011300 ; + phycfg->LanePisoCfg4 =0x63349140 ; + phycfg->LanePisoCfg5 =0xF8102036 ; + phycfg->LanePisoCfg6 =0xF80D9300 ; + phycfg->LaneBctCtrl =0x00FB33F8 ; +} + +/** +* pm8001_get_phy_mask : Retrieves the mask that denotes if a PHY is int/ext +* @pm8001_ha : our adapter +* @phymask : The PHY mask +*/ +static +void pm8001_get_phy_mask (struct pm8001_hba_info *pm8001_ha,int *phymask) +{ +switch (pm8001_ha->pdev->subsystem_device) { +case 0x0070 :/* H1280 - 8 external 0 internal */ +case 0x0072 :/* H12F0 - 16 external 0 internal */ + *phymask =0x0000 ; +break ; + +case 0x0071 :/* H1208 - 0 external 8 internal */ +case 0x0073 :/* H120F - 0 external 16 internal */ + *phymask =0xFFFF ; +break ; + +case 0x0080 :/* H1244 - 4 external 4 internal */ + *phymask =0x00F0 ; +break ; + +case 0x0081 :/* H1248 - 4 external 8 internal */ + *phymask =0x0FF0 ; +break ; + +case 0x0082 :/* H1288 - 8 external 8 internal */ + *phymask =0xFF00 ; +break ; + +default : +PM8001_INIT_DBG (pm8001_ha, +pm8001_printk ("Unknown subsystem device=0x%.04x" , + pm8001_ha->pdev->subsystem_device)); + } +} + +/** +* pm8001_set_phy_settings_ven_117c_12Gb : Configure ATTO 12Gb PHY settings +* @pm8001_ha : our adapter +*/ +static +int pm8001_set_phy_settings_ven_117c_12G (struct pm8001_hba_info *pm8001_ha) +{ +struct pm8001_mpi3_phy_pg_trx_config phycfg_int; +struct pm8001_mpi3_phy_pg_trx_config phycfg_ext; +int phymask =0 ; +int i =0 ; + +memset (&phycfg_int,0 ,sizeof (phycfg_int)); +memset (&phycfg_ext,0 ,sizeof (phycfg_ext)); + +pm8001_get_internal_phy_settings (pm8001_ha, &phycfg_int); +pm8001_get_external_phy_settings (pm8001_ha, &phycfg_ext); +pm8001_get_phy_mask (pm8001_ha, &phymask); + +for (i =0 ; i < pm8001_ha->chip->n_phy; i++) { +if (phymask & (1 << i)) {/* Internal PHY */ +pm8001_set_phy_profile_single (pm8001_ha, i, +sizeof (phycfg_int) /sizeof (u32), + (u32 *)&phycfg_int); + + }else {/* External PHY */ +pm8001_set_phy_profile_single (pm8001_ha, i, +sizeof (phycfg_ext) /sizeof (u32), + (u32 *)&phycfg_ext); + } + } + +return 0 ; +} +/** * pm8001_configure_phy_settings : Configures PHY settings based on vendor ID. * @pm8001_ha : our hba. @@ -740,6 +865,11 @@ static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha) {switch (pm8001_ha->pdev->subsystem_vendor) {case PCI_VENDOR_ID_ATTO : +if (pm8001_ha->pdev->device ==0x0042 )/* 6Gb */ +return 0 ; +else +return pm8001_set_phy_settings_ven_117c_12G (pm8001_ha); +case PCI_VENDOR_ID_ADAPTEC2 :case 0 :return 0 ;drivers/scsi/pm8001/pm8001_sas.h +2
-0@@ -710,6 +710,8 @@ int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);int pm8001_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);void pm8001_set_phy_profile (struct pm8001_hba_info *pm8001_ha,u32 length,u8 *buf); +void pm8001_set_phy_profile_single (struct pm8001_hba_info *pm8001_ha, +u32 phy,u32 length,u32 *buf);int pm80xx_bar4_shift (struct pm8001_hba_info *pm8001_ha,u32 shiftValue);ssize_t pm80xx_get_fatal_dump (struct device *cdev,struct device_attribute *attr,char *buf);drivers/scsi/pm8001/pm80xx_hwi.c +32
-1@@ -4576,6 +4576,38 @@ void pm8001_set_phy_profile(struct pm8001_hba_info *pm8001_ha, }PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("phy settings completed\n" )); } + +void pm8001_set_phy_profile_single (struct pm8001_hba_info *pm8001_ha, +u32 phy,u32 length,u32 *buf) +{ +u32 tag, opc; +int rc, i; +struct set_phy_profile_req payload; +struct inbound_queue_table *circularQ; + +memset (&payload,0 ,sizeof (payload)); + + rc =pm8001_tag_alloc (pm8001_ha, &tag); +if (rc) +PM8001_INIT_DBG (pm8001_ha,pm8001_printk ("Invalid tag" )); + + circularQ = &pm8001_ha->inbnd_q_tbl[0 ]; + opc =OPC_INB_SET_PHY_PROFILE ; + + payload.tag =cpu_to_le32 (tag); + payload.ppc_phyid = (((SAS_PHY_ANALOG_SETTINGS_PAGE &0xF ) <<8 ) + | (phy &0xFF )); + +for (i =0 ; i < length; i++) + payload.reserved[i] =cpu_to_le32 (*(buf + i)); + + rc =pm8001_mpi_build_cmd (pm8001_ha, circularQ, opc, &payload,0 ); +if (rc) +pm8001_tag_free (pm8001_ha, tag); + +PM8001_INIT_DBG (pm8001_ha, +pm8001_printk ("PHY %d settings applied" , phy)); +}const struct pm8001_dispatch pm8001_80xx_dispatch = { .name ="pmc80xx" , .chip_init = pm80xx_chip_init, --
Quoted 2 lines
2.4.3
Thanks
Jack
PATCH 6/8 pm80xx: do not examine registers for iButton feature if ATTO adapter
In reply to Benjamin RoodATTO adapters do not support this feature. If the firmware fails to be ready, it should not check the examined registers in order to examine the state of the feature in order to prevent undefined behavior.
--- drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/pm8001/pm80xx_hwi.c +2 -0
@@ -1267,6 +1267,8 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)/* check iButton feature support for motherboard controller */ if (pm8001_ha->pdev->subsystem_vendor !=PCI_VENDOR_ID_ADAPTEC2 && + pm8001_ha->pdev->subsystem_vendor != +PCI_VENDOR_ID_ATTO && pm8001_ha->pdev->subsystem_vendor !=0 ) { ibutton0 =pm8001_cr32 (pm8001_ha,0 ,MSGU_HOST_SCRATCH_PAD_6 );
Signature · 1 line
2.4.3
Re: [PATCH 6/8] pm80xx: do not examine registers for iButton feature if ATTO adapter
Quoted 9 lines · Benjamin Rood
ATTO adapters do not support this feature. If the firmware fails to be ready, it should not check the examined registers in order to examine the state of the feature in order to prevent undefined behavior.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ 1 file changed, 2 insertions(+)
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/8] pm80xx: do not examine registers for iButton feature if ATTO adapter
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 23 lines
ATTO adapters do not support this feature. If the firmware fails to be ready, it should not check the examined registers in order to examine the state of the feature in order to prevent undefined behavior.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm80xx_hwi.c | 2 ++ 1 file changed, 2 insertions(+)drivers/scsi/pm8001/pm80xx_hwi.c +2
-1@@ -1267,6 +1267,8 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)/* check iButton feature support for motherboard controller */ if (pm8001_ha->pdev->subsystem_vendor !=PCI_VENDOR_ID_ADAPTEC2 && + pm8001_ha->pdev->subsystem_vendor != +PCI_VENDOR_ID_ATTO && pm8001_ha->pdev->subsystem_vendor !=0 ) { ibutton0 =pm8001_cr32 (pm8001_ha,0 ,MSGU_HOST_SCRATCH_PAD_6 ); --
Quoted 2 lines
2.4.3
Thanks
Jack
PATCH 7/8 pm80xx: wait a minimum of 500ms before issuing commands to SPCv
In reply to Benjamin RoodThe documentation for the 8070 and 8072 SPCv chip explicitly states that a minimum of 500ms must elapse before issuing commands, otherwise the SPCv may not process them and the firmware may get into an unrecoverable state requiring a reboot. While the Linux guys will probably think this is 'racy', it is called out in the chip documentation and inserting this delay makes power management function properly.
--- drivers/scsi/pm8001/pm8001_init.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +12 -0
@@ -1190,6 +1190,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)int rc;u8 i =0 , j;u32 device_state; +u32 wait_count;DECLARE_COMPLETION_ONSTACK (completion); pm8001_ha = sha->lldd_ha; device_state = pdev->current_state;
@@ -1243,6 +1244,17 @@ static int pm8001_pci_resume(struct pci_dev *pdev)for (i =1 ; i < pm8001_ha->number_of_intr; i++)PM8001_CHIP_DISP ->interrupt_enable (pm8001_ha, i); } + +if (pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) { + wait_count =500 ; +do { +mdelay (1 ); + }while (--wait_count); + } + +/* Spin up the PHYs */ + pm8001_ha->flags =PM8001F_RUN_TIME ;for (i =0 ; i < pm8001_ha->chip->n_phy; i++) { pm8001_ha->phy[i].enable_completion = &completion;
Signature · 1 line
2.4.3
Re: [PATCH 7/8] pm80xx: wait a minimum of 500ms before issuing commands to SPCv
Quoted 7 lines · Benjamin Rood
The documentation for the 8070 and 8072 SPCv chip explicitly states that a minimum of 500ms must elapse before issuing commands, otherwise the SPCv may not process them and the firmware may get into an unrecoverable state requiring a reboot. While the Linux guys will probably think this is 'racy', it is called out in the chip documentation and inserting this delay makes power management function properly.
Quoted 5 lines
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
Can you please add a comment in the code, too?
Just to clarify why this is done, lest that someone else tries to 'optimize' this away.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 7/8] pm80xx: wait a minimum of 500ms before issuing commands to SPCv
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 43 lines
The documentation for the 8070 and 8072 SPCv chip explicitly states that a minimum of 500ms must elapse before issuing commands, otherwise the SPCv may not process them and the firmware may get into an unrecoverable state requiring a reboot. While the Linux guys will probably think this is 'racy', it is called out in the chip documentation and inserting this delay makes power management function properly.
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)drivers/scsi/pm8001/pm8001_init.c +12
-1@@ -1190,6 +1190,7 @@ static int pm8001_pci_resume(struct pci_dev *pdev)int rc;u8 i =0 , j;u32 device_state; +u32 wait_count;DECLARE_COMPLETION_ONSTACK (completion); pm8001_ha = sha->lldd_ha; device_state = pdev->current_state;@@ -1243,6 +1244,17 @@ static int pm8001_pci_resume(struct pci_dev *pdev)for (i =1 ; i < pm8001_ha->number_of_intr; i++)PM8001_CHIP_DISP ->interrupt_enable (pm8001_ha, i); } + +if (pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) { + wait_count =500 ; +do { +mdelay (1 ); + }while (--wait_count); + } + +/* Spin up the PHYs */ + pm8001_ha->flags =PM8001F_RUN_TIME ;for (i =0 ; i < pm8001_ha->chip->n_phy; i++) { pm8001_ha->phy[i].enable_completion = &completion; --
Quoted 2 lines
2.4.3
Could we simply mdelay(500) instead the loop?
Also better to add a comment around.
Thanks,
Jack
PATCH v2 7/9 pm80xx: wait a minimum of 500ms before issuing commands to SPCv
The documentation for the 8070 and 8072 SPCv chip explicitly states that a minimum of 500ms must elapse before issuing commands, otherwise the SPCv may not process them and the firmware may get into an unrecoverable state requiring a reboot. While the Linux guys will probably think this is 'racy', it is called out in the chip documentation and inserting this delay makes power management function properly.
---
Changes from v1 -> v2:
-Used mdelay(500) instead of a loop to facilitate required delay -Added comment as to why this behavior exists
drivers/scsi/pm8001/pm8001_init.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
drivers/scsi/pm8001/pm8001_init.c +13 -0
@@ -1243,6 +1243,19 @@ static int pm8001_pci_resume(struct pci_dev *pdev)for (i =1 ; i < pm8001_ha->number_of_intr; i++)PM8001_CHIP_DISP ->interrupt_enable (pm8001_ha, i); } + +/* Chip documentation for the 8070 and 8072 SPCv */ +/* states that a 500ms minimum delay is required */ +/* before issuing commands. Otherwise, the firmare */ +/* will enter an unrecoverable state. */ + +if (pm8001_ha->chip_id == chip_8070 || + pm8001_ha->chip_id == chip_8072) { +mdelay (500 ); + } + +/* Spin up the PHYs */ + pm8001_ha->flags =PM8001F_RUN_TIME ;for (i =0 ; i < pm8001_ha->chip->n_phy; i++) { pm8001_ha->phy[i].enable_completion = &completion;
Signature · 1 line
2.4.3
PATCH 8/8 pm80xx: avoid a panic if MSI(X) interrupts are disabled
In reply to Benjamin RoodIf MSI(X) interrupts are disabled via the kernel command line (pci=nomsi), the pm8001 driver will kernel panic because it does not detect that MSI interrupts are disabled and will soldier on and attempt to configure MSI interrupts anyways. This leads to a kernel panic, most likely because a required data structure is not available down the line. Using the pci_msi_enabled() function in order to detect if MSI interrupts are enabled before configuring them resolves this issue and avoids a kernel panic when the module is loaded. Additionally, the irq_vector structure must be initialized when legacy interrupts are being used otherwise legacy interrupts will simply not function and result in another panic.
--- drivers/scsi/pm8001/pm8001_init.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/scsi/pm8001/pm8001_init.c +11 -5
@@ -482,7 +482,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,#ifdef PM8001_USE_TASKLET /* Tasklet for non msi-x interrupt handler */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) + || (pm8001_ha->chip_id == chip_8001))tasklet_init (&pm8001_ha->tasklet[0 ], pm8001_tasklet, (unsigned long )&(pm8001_ha->irq_vector[0 ]));else
@@ -951,7 +952,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) pdev = pm8001_ha->pdev;#ifdef PM8001_USE_MSIX -if (pdev->msix_cap) +if (pdev->msix_cap &&pci_msi_enabled ())return pm8001_setup_msix (pm8001_ha);else { PM8001_INIT_DBG(pm8001_ha,
@@ -962,6 +963,8 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) intx:/* initialize the INT-X interrupt */ + pm8001_ha->irq_vector[0 ].irq_id =0 ; + pm8001_ha->irq_vector[0 ].drv_inst = pm8001_ha; rc =request_irq (pdev->irq, pm8001_interrupt_handler_intx,IRQF_SHARED ,DRV_NAME ,SHOST_TO_SAS_HA (pm8001_ha->shost));return rc;
@@ -1112,7 +1115,8 @@ static void pm8001_pci_remove(struct pci_dev *pdev)#endif #ifdef PM8001_USE_TASKLET /* For non-msix and msix interrupts */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_kill (&pm8001_ha->tasklet[0 ]);else for (j =0 ; j <PM8001_MAX_MSIX_VEC ; j++)
@@ -1161,7 +1165,8 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)#endif #ifdef PM8001_USE_TASKLET /* For non-msix and msix interrupts */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_kill (&pm8001_ha->tasklet[0 ]);else for (j =0 ; j <PM8001_MAX_MSIX_VEC ; j++)
@@ -1231,7 +1236,8 @@ static int pm8001_pci_resume(struct pci_dev *pdev) goto err_out_disable;#ifdef PM8001_USE_TASKLET /* Tasklet for non msi-x interrupt handler */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_init (&pm8001_ha->tasklet[0 ], pm8001_tasklet, (unsigned long )&(pm8001_ha->irq_vector[0 ]));else
Signature · 1 line
2.4.3
Re: [PATCH 8/8] pm80xx: avoid a panic if MSI(X) interrupts are disabled
Quoted 12 lines · Benjamin Rood
If MSI(X) interrupts are disabled via the kernel command line (pci=nomsi), the pm8001 driver will kernel panic because it does not detect that MSI interrupts are disabled and will soldier on and attempt to configure MSI interrupts anyways. This leads to a kernel panic, most likely because a required data structure is not available down the line. Using the
pci_msi_enabled()function in order to detect if MSI interrupts are enabled before configuring them resolves this issue and avoids a kernel panic when the module is loaded. Additionally, theirq_vectorstructure must be initialized when legacy interrupts are being used otherwise legacy interrupts will simply not function and result in another panic.
Quoted 5 lines
Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 8/8] pm80xx: avoid a panic if MSI(X) interrupts are disabled
In reply to Benjamin Rood2015-10-30 15:53 GMT+01:00 Benjamin Rood <[email protected]>:
Quoted 80 lines
If MSI(X) interrupts are disabled via the kernel command line (pci=nomsi), the pm8001 driver will kernel panic because it does not detect that MSI interrupts are disabled and will soldier on and attempt to configure MSI interrupts anyways. This leads to a kernel panic, most likely because a required data structure is not available down the line. Using the
pci_msi_enabled()function in order to detect if MSI interrupts are enabled before configuring them resolves this issue and avoids a kernel panic when the module is loaded. Additionally, theirq_vectorstructure must be initialized when legacy interrupts are being used otherwise legacy interrupts will simply not function and result in another panic.Signed-off-by Benjamin Rood <[email protected]>--- drivers/scsi/pm8001/pm8001_init.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)drivers/scsi/pm8001/pm8001_init.c +11
-6@@ -482,7 +482,8 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,#ifdef PM8001_USE_TASKLET /* Tasklet for non msi-x interrupt handler */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) + || (pm8001_ha->chip_id == chip_8001))tasklet_init (&pm8001_ha->tasklet[0 ], pm8001_tasklet, (unsigned long )&(pm8001_ha->irq_vector[0 ]));else @@ -951,7 +952,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) pdev = pm8001_ha->pdev;#ifdef PM8001_USE_MSIX -if (pdev->msix_cap) +if (pdev->msix_cap &&pci_msi_enabled ())return pm8001_setup_msix (pm8001_ha);else { PM8001_INIT_DBG(pm8001_ha,@@ -962,6 +963,8 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) intx:/* initialize the INT-X interrupt */ + pm8001_ha->irq_vector[0 ].irq_id =0 ; + pm8001_ha->irq_vector[0 ].drv_inst = pm8001_ha; rc =request_irq (pdev->irq, pm8001_interrupt_handler_intx,IRQF_SHARED ,DRV_NAME ,SHOST_TO_SAS_HA (pm8001_ha->shost));return rc;@@ -1112,7 +1115,8 @@ static void pm8001_pci_remove(struct pci_dev *pdev)#endif #ifdef PM8001_USE_TASKLET /* For non-msix and msix interrupts */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_kill (&pm8001_ha->tasklet[0 ]);else for (j =0 ; j <PM8001_MAX_MSIX_VEC ; j++)@@ -1161,7 +1165,8 @@ static int pm8001_pci_suspend(struct pci_dev *pdev, pm_message_t state)#endif #ifdef PM8001_USE_TASKLET /* For non-msix and msix interrupts */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_kill (&pm8001_ha->tasklet[0 ]);else for (j =0 ; j <PM8001_MAX_MSIX_VEC ; j++)@@ -1231,7 +1236,8 @@ static int pm8001_pci_resume(struct pci_dev *pdev) goto err_out_disable;#ifdef PM8001_USE_TASKLET /* Tasklet for non msi-x interrupt handler */ -if ((!pdev->msix_cap) || (pm8001_ha->chip_id == chip_8001)) +if ((!pdev->msix_cap || !pci_msi_enabled ()) || + (pm8001_ha->chip_id == chip_8001))tasklet_init (&pm8001_ha->tasklet[0 ], pm8001_tasklet, (unsigned long )&(pm8001_ha->irq_vector[0 ]));else --
Quoted 2 lines
2.4.3
Thanks
Jack
Martin K. Petersen
AppliedQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Benjamin" == Benjamin Rood <[email protected]> writes:
Benjamin> The following series of patches are primarily aimed at adding Benjamin> support for ATTO's 12Gb SAS adapters, which are based off of Benjamin> the PMC-Sierra 8070/8072 series chips. I have also addressed Benjamin> other various issues that were discovered during our testing Benjamin> and verification phase, mainly with resume-from-sleep, Benjamin> configuring PHY profiles, and using legacy interrupts.
Applied.
Signature · 1 line
Martin K. Petersen Oracle Linux Engineering