* [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39.
@ 2020-01-17 7:19 Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
` (12 more replies)
0 siblings, 13 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
This patch set includes some bug fixes and features for pm80xx driver.
Changes from V1:
For "Increase request sg length" patch.
- Fix the compilation warning generated on xtensa architecture.
For "Support for char device" patch.
- Modified the description of patch.
For "IOCTL functionality to get phy profile." patch.
- Split the patch in two different patches.
IOCTL functionality to get phy status and
IOCTL functionality to get phy error.
For "IOCTL functionality for SGPIO" patch.
- Fixed the compilation warning generated on x86_64 architecture.
For "sysfs attribute for non fatal dump" patch.
- Modified the description of patch.
For "IOCTL functionality for TWI device" patch.
- Modified the description of patch.
Deepak Ukey (5):
pm80xx : Support for char device.
pm80xx : IOCTL functionality for GPIO.
pm80xx : IOCTL functionality for SGPIO.
pm80xx : sysfs attribute for non fatal dump.
pm80xx : IOCTL functionality for TWI device.
Peter Chang (2):
pm80xx : Increase request sg length.
pm80xx : Cleanup initialization loading fail path.
Vikram Auradkar (1):
pm80xx : Deal with kexec reboots.
Viswas G (4):
pm80xx : sysfs attribute for number of phys.
pm80xx : IOCTL functionality to get phy status.
pm80xx : IOCTL functionality to get phy error.
pm80xx : Introduce read and write length for IOCTL payload structure.
yuuzheng (1):
pm80xx : Free the tag when mpi_set_phy_profile_resp is received.
drivers/scsi/pm8001/pm8001_ctl.c | 662 +++++++++++++++++++++++++++++++++++++-
drivers/scsi/pm8001/pm8001_ctl.h | 185 +++++++++++
drivers/scsi/pm8001/pm8001_defs.h | 5 +-
drivers/scsi/pm8001/pm8001_hwi.c | 303 +++++++++++++++--
drivers/scsi/pm8001/pm8001_hwi.h | 18 ++
drivers/scsi/pm8001/pm8001_init.c | 104 ++++--
drivers/scsi/pm8001/pm8001_sas.c | 37 +++
drivers/scsi/pm8001/pm8001_sas.h | 70 +++-
drivers/scsi/pm8001/pm80xx_hwi.c | 390 +++++++++++++++++++++-
drivers/scsi/pm8001/pm80xx_hwi.h | 55 ++++
10 files changed, 1767 insertions(+), 62 deletions(-)
--
2.16.3
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 14:08 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 02/13] pm80xx : Deal with kexec reboots Deepak Ukey
` (11 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Peter Chang <dpf@google.com>
Increasing the per-request size maximum (max_sectors_kb) runs into
the per-device dma scatter gather list limit (max_segments) for
users of the io vector system calls (eg, readv and writev). This is
because the kernel combines io vectors into dma segments when
possible, but it doesn't work for our user because the vectors in the
buffer cache get scrambled.
This change bumps the advertised max scatter gather length to 528 to
cover 2M w/ x86's 4k pages and some extra for the user checksum.
It trims the size of some of the tables we don't care about and
exposes all of the command slots upstream to the scsi layer
Signed-off-by: Peter Chang <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Reported-by: kbuild test robot <lkp@intel.com>
---
drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
drivers/scsi/pm8001/pm8001_init.c | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h
index 48e0624ecc68..1c7f15fd69ce 100644
--- a/drivers/scsi/pm8001/pm8001_defs.h
+++ b/drivers/scsi/pm8001/pm8001_defs.h
@@ -75,7 +75,7 @@ enum port_type {
};
/* driver compile-time configuration */
-#define PM8001_MAX_CCB 512 /* max ccbs supported */
+#define PM8001_MAX_CCB 256 /* max ccbs supported */
#define PM8001_MPI_QUEUE 1024 /* maximum mpi queue entries */
#define PM8001_MAX_INB_NUM 1
#define PM8001_MAX_OUTB_NUM 1
@@ -99,7 +99,8 @@ enum port_type {
#define OB (CI + PM8001_MAX_SPCV_INB_NUM)
#define PI (OB + PM8001_MAX_SPCV_OUTB_NUM)
#define USI_MAX_MEMCNT (PI + PM8001_MAX_SPCV_OUTB_NUM)
-#define PM8001_MAX_DMA_SG SG_ALL
+#define CONFIG_SCSI_PM8001_MAX_DMA_SG 528
+#define PM8001_MAX_DMA_SG CONFIG_SCSI_PM8001_MAX_DMA_SG
enum memory_region_num {
AAP1 = 0x0, /* application acceleration processor */
IOP, /* IO processor */
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index ff618ad80ebd..3f1e755c52c6 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -95,7 +95,7 @@ static struct scsi_host_template pm8001_sht = {
.bios_param = sas_bios_param,
.can_queue = 1,
.this_id = -1,
- .sg_tablesize = SG_ALL,
+ .sg_tablesize = PM8001_MAX_DMA_SG,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_target_reset_handler = sas_eh_target_reset_handler,
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 02/13] pm80xx : Deal with kexec reboots.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 03/13] pm80xx : Free the tag when mpi_set_phy_profile_resp is received Deepak Ukey
` (10 subsequent siblings)
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Vikram Auradkar <auradkar@google.com>
A kexec reboot causes the controller fw to assert. This assertion
shows up in two ways, the controller doesn't show up as ready and
an interrupt is waiting as soon as the handler is registered. To
resolve this added below fix:
-split the interrupt handling setup into two parts, setup and
request.
-If the controller ready register indicates not-ready, but that the
not readiness is only on the IOC units we can still try a reset to
bring the system back to the pre-reboot state.
Signed-off-by: Vikram Auradkar <auradkar@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
drivers/scsi/pm8001/pm8001_init.c | 48 +++++++++++++++++++++++++++++++++++----
drivers/scsi/pm8001/pm80xx_hwi.c | 15 ++++++++----
2 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 3f1e755c52c6..a002eb5a3fe4 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -248,6 +248,9 @@ static irqreturn_t pm8001_interrupt_handler_intx(int irq, void *dev_id)
return ret;
}
+static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha);
+static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha);
+
/**
* pm8001_alloc - initiate our hba structure and 6 DMAs area.
* @pm8001_ha:our hba structure.
@@ -890,9 +893,7 @@ static int pm8001_configure_phy_settings(struct pm8001_hba_info *pm8001_ha)
*/
static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
{
- u32 i = 0, j = 0;
u32 number_of_intr;
- int flag = 0;
int rc;
/* SPCv controllers supports 64 msi-x */
@@ -900,11 +901,11 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
number_of_intr = 1;
} else {
number_of_intr = PM8001_MAX_MSIX_VEC;
- flag &= ~IRQF_SHARED;
}
rc = pci_alloc_irq_vectors(pm8001_ha->pdev, number_of_intr,
number_of_intr, PCI_IRQ_MSIX);
+ number_of_intr = rc;
if (rc < 0)
return rc;
pm8001_ha->number_of_intr = number_of_intr;
@@ -912,8 +913,22 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
PM8001_INIT_DBG(pm8001_ha, pm8001_printk(
"pci_alloc_irq_vectors request ret:%d no of intr %d\n",
rc, pm8001_ha->number_of_intr));
+ return 0;
+}
+
+static u32 pm8001_request_msix(struct pm8001_hba_info *pm8001_ha)
+{
+ u32 i = 0, j = 0;
+ int flag = 0, rc = 0;
- for (i = 0; i < number_of_intr; i++) {
+ if (pm8001_ha->chip_id != chip_8001)
+ flag &= ~IRQF_SHARED;
+
+ PM8001_INIT_DBG(pm8001_ha,
+ pm8001_printk("pci_enable_msix request number of intr %d\n",
+ pm8001_ha->number_of_intr));
+
+ for (i = 0; i < pm8001_ha->number_of_intr; i++) {
snprintf(pm8001_ha->intr_drvname[i],
sizeof(pm8001_ha->intr_drvname[0]),
"%s-%d", pm8001_ha->name, i);
@@ -938,6 +953,21 @@ static u32 pm8001_setup_msix(struct pm8001_hba_info *pm8001_ha)
}
#endif
+static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha)
+{
+ struct pci_dev *pdev;
+
+ pdev = pm8001_ha->pdev;
+
+#ifdef PM8001_USE_MSIX
+ if (pci_find_capability(pdev, PCI_CAP_ID_MSIX))
+ return pm8001_setup_msix(pm8001_ha);
+ PM8001_INIT_DBG(pm8001_ha,
+ pm8001_printk("MSIX not supported!!!\n"));
+#endif
+ return 0;
+}
+
/**
* pm8001_request_irq - register interrupt
* @chip_info: our ha struct.
@@ -951,7 +981,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha)
#ifdef PM8001_USE_MSIX
if (pdev->msix_cap && pci_msi_enabled())
- return pm8001_setup_msix(pm8001_ha);
+ return pm8001_request_msix(pm8001_ha);
else {
PM8001_INIT_DBG(pm8001_ha,
pm8001_printk("MSIX not supported!!!\n"));
@@ -1033,6 +1063,13 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
rc = -ENOMEM;
goto err_out_free;
}
+ /* Setup Interrupt */
+ rc = pm8001_setup_irq(pm8001_ha);
+ if (rc) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "pm8001_setup_irq failed [ret: %d]\n", rc));
+ goto err_out_shost;
+ }
list_add_tail(&pm8001_ha->list, &hba_list);
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
@@ -1045,6 +1082,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
rc = scsi_add_host(shost, &pdev->dev);
if (rc)
goto err_out_ha_free;
+ /* Request Interrupt */
rc = pm8001_request_irq(pm8001_ha);
if (rc) {
PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 98dcdbd146d5..d805fd036ddf 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -1438,11 +1438,18 @@ pm80xx_chip_soft_rst(struct pm8001_hba_info *pm8001_ha)
if (!pm8001_ha->controller_fatal_error) {
/* Check if MPI is in ready state to reset */
if (mpi_uninit_check(pm8001_ha) != 0) {
- regval = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+ u32 r0 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_0);
+ u32 r1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+ u32 r2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
+ u32 r3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
- "MPI state is not ready scratch1 :0x%x\n",
- regval));
- return -1;
+ "MPI state is not ready scratch: %x:%x:%x:%x\n",
+ r0, r1, r2, r3));
+ /* if things aren't ready but the bootloader is ok then
+ * try the reset anyway.
+ */
+ if (r1 & SCRATCH_PAD1_BOOTSTATE_MASK)
+ return -1;
}
}
/* checked for reset register normal state; 0x0 */
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 03/13] pm80xx : Free the tag when mpi_set_phy_profile_resp is received.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 02/13] pm80xx : Deal with kexec reboots Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 04/13] pm80xx : Cleanup initialization loading fail path Deepak Ukey
` (9 subsequent siblings)
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: yuuzheng <yuuzheng@google.com>
In pm80xx driver, the command mpi_set_phy_profile_req is sent by host
during boot to configure the phy profile such as analog setting page,
rate control page. However, the tag is not freed when its response is
received. As a result, 16 tags are missing for each HBA after boot.
When NCQ is enabled with queue depth 16, it needs at least, 15 * 16 =
240 tags for each HBA to achieve the best performance. In current
pm80xx driver with setting CCB_MAX = 256, the total number of tags in
each HBA is 255 for data IO. Hence, without returning those tags to the
pool after boot, some device will finally be forced to non-ncq mode by
ATA layer due to excessive errors (i.e. LLDD cannot allocate tag for
queued task).
Signed-off-by: yuuzheng <yuuzheng@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
drivers/scsi/pm8001/pm80xx_hwi.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index d805fd036ddf..37b82d7aa3d7 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3715,28 +3715,32 @@ static int mpi_flash_op_ext_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
static int mpi_set_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
+ u32 tag;
u8 page_code;
+ int rc = 0;
struct set_phy_profile_resp *pPayload =
(struct set_phy_profile_resp *)(piomb + 4);
u32 ppc_phyid = le32_to_cpu(pPayload->ppc_phyid);
u32 status = le32_to_cpu(pPayload->status);
+ tag = le32_to_cpu(pPayload->tag);
page_code = (u8)((ppc_phyid & 0xFF00) >> 8);
if (status) {
/* status is FAILED */
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("PhyProfile command failed with status "
"0x%08X \n", status));
- return -1;
+ rc = -1;
} else {
if (page_code != SAS_PHY_ANALOG_SETTINGS_PAGE) {
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Invalid page code 0x%X\n",
page_code));
- return -1;
+ rc = -1;
}
}
- return 0;
+ pm8001_tag_free(pm8001_ha, tag);
+ return rc;
}
/**
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 04/13] pm80xx : Cleanup initialization loading fail path.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (2 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 03/13] pm80xx : Free the tag when mpi_set_phy_profile_resp is received Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 05/13] pm80xx : Support for char device Deepak Ukey
` (8 subsequent siblings)
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Peter Chang <dpf@google.com>
1)Move the instance tracking down after we think the instance is
good to go. avoids having a use-after free.
2)There are goto targets for trying to cleanup if the hw fails to
initialize, but there's some overlap depending on who thinks they
own the sub-structures.
Signed-off-by: Peter Chang <dpf@google.com>
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
drivers/scsi/pm8001/pm8001_init.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index a002eb5a3fe4..775517f9b39d 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1016,6 +1016,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
struct pm8001_hba_info *pm8001_ha;
struct Scsi_Host *shost = NULL;
const struct pm8001_chip_info *chip;
+ struct sas_ha_struct *sha;
dev_printk(KERN_INFO, &pdev->dev,
"pm80xx: driver version %s\n", DRV_VERSION);
@@ -1044,12 +1045,12 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
goto err_out_regions;
}
chip = &pm8001_chips[ent->driver_data];
- SHOST_TO_SAS_HA(shost) =
- kzalloc(sizeof(struct sas_ha_struct), GFP_KERNEL);
- if (!SHOST_TO_SAS_HA(shost)) {
+ sha = kzalloc(sizeof(struct sas_ha_struct), GFP_KERNEL);
+ if (!sha) {
rc = -ENOMEM;
goto err_out_free_host;
}
+ SHOST_TO_SAS_HA(shost) = sha;
rc = pm8001_prep_sas_ha_init(shost, chip);
if (rc) {
@@ -1070,7 +1071,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
"pm8001_setup_irq failed [ret: %d]\n", rc));
goto err_out_shost;
}
- list_add_tail(&pm8001_ha->list, &hba_list);
+
PM8001_CHIP_DISP->chip_soft_rst(pm8001_ha);
rc = PM8001_CHIP_DISP->chip_init(pm8001_ha);
if (rc) {
@@ -1105,8 +1106,12 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
pm8001_post_sas_ha_init(shost, chip);
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
- if (rc)
+ if (rc) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "sas_register_ha failed [ret: %d]\n", rc));
goto err_out_shost;
+ }
+ list_add_tail(&pm8001_ha->list, &hba_list);
scsi_scan_host(pm8001_ha->shost);
pm8001_ha->flags = PM8001F_RUN_TIME;
return 0;
@@ -1116,7 +1121,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
err_out_ha_free:
pm8001_free(pm8001_ha);
err_out_free:
- kfree(SHOST_TO_SAS_HA(shost));
+ kfree(sha);
err_out_free_host:
scsi_host_put(shost);
err_out_regions:
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (3 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 04/13] pm80xx : Cleanup initialization loading fail path Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 14:15 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys Deepak Ukey
` (7 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
Added the support to register the char device for pm80xx module so that
management utility fetch the different information from driver with the
help of IOCTL. Also added the IOCTL functionality to get driver info so
that management utility can fetch the information about driver like
driver name, driver major number, driver minor number and build number.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 148 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 33 +++++++++
drivers/scsi/pm8001/pm8001_init.c | 5 ++
drivers/scsi/pm8001/pm8001_sas.h | 6 ++
4 files changed, 192 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 7c6be2ec110d..69458b318a20 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -41,6 +41,7 @@
#include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_ctl.h"
+int pm80xx_major = -1;
/* scsi host attributes */
@@ -845,3 +846,150 @@ struct device_attribute *pm8001_host_attrs[] = {
NULL,
};
+/*
+ * pm8001_open - open the configuration file
+ * @inode: inode being opened
+ * @file: file handle attached
+ *
+ * Called when the configuration device is opened. Does the needed
+ * set up on the handle and then returns
+ *
+ */
+static int pm8001_open(struct inode *inode, struct file *file)
+{
+ struct pm8001_hba_info *pm8001_ha;
+ unsigned int minor_number = iminor(inode);
+ int err = -ENODEV;
+
+ list_for_each_entry(pm8001_ha, &hba_list, list) {
+ if (pm8001_ha->id == minor_number) {
+ file->private_data = pm8001_ha;
+ err = 0;
+ break;
+ }
+ }
+
+ return err;
+}
+
+/**
+ * pm8001_close - close the configuration file
+ * @inode: inode being opened
+ * @file: file handle attached
+ *
+ * Called when the configuration device is closed. Does the needed
+ * set up on the handle and then returns
+ *
+ */
+static int pm8001_close(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static long pm8001_info_ioctl(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ u32 ret = 0;
+ struct ioctl_info_buffer info_buf;
+
+ strcpy(info_buf.information.sz_name, DRV_NAME);
+
+ info_buf.information.usmajor_revision = DRV_MAJOR;
+ info_buf.information.usminor_revision = DRV_MINOR;
+ info_buf.information.usbuild_revision = DRV_BUILD;
+ if (pm8001_ha->chip_id == chip_8001) {
+ info_buf.information.maxoutstandingIO =
+ pm8001_ha->main_cfg_tbl.pm8001_tbl.max_out_io;
+ info_buf.information.maxdevices =
+ (pm8001_ha->main_cfg_tbl.pm8001_tbl.max_sgl >> 16) &
+ 0xFFFF;
+ } else {
+ info_buf.information.maxoutstandingIO =
+ pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_out_io;
+ info_buf.information.maxdevices =
+ (pm8001_ha->main_cfg_tbl.pm80xx_tbl.max_sgl >> 16) &
+ 0xFFFF;
+ }
+ info_buf.header.return_code = ADPT_IOCTL_CALL_SUCCESS;
+
+ if (copy_to_user((void *)arg, (void *)&info_buf,
+ sizeof(struct ioctl_info_buffer))) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ return ret;
+}
+
+/**
+ * pm8001_ioctl - pm8001 configuration request
+ * @inode: inode of device
+ * @file: file handle
+ * @cmd: ioctl command code
+ * @arg: argument
+ *
+ * Handles a configuration ioctl.
+ *
+ */
+static long pm8001_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ u32 ret = -EACCES;
+ struct pm8001_hba_info *pm8001_ha;
+ struct ioctl_header header;
+
+ pm8001_ha = file->private_data;
+
+ switch (cmd) {
+ case ADPT_IOCTL_INFO:
+ ret = pm8001_info_ioctl(pm8001_ha, arg);
+ break;
+ default:
+ ret = ADPT_IOCTL_CALL_INVALID_CODE;
+ }
+
+ if (ret == 0)
+ return ret;
+ header.return_code = ret;
+ ret = -EACCES;
+ if (copy_to_user((void *)arg, (void *)&header,
+ sizeof(struct ioctl_header))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_to_user failed\n"));
+ }
+ return ret;
+}
+
+static const struct file_operations pm8001_fops = {
+ .owner = THIS_MODULE,
+ .open = pm8001_open,
+ .release = pm8001_close,
+ .unlocked_ioctl = pm8001_ioctl,
+};
+
+/**
+ * pm8001_setup_chrdev - register char device
+ * Return value:
+ * 0 in case of success, otherwise non-zero value
+ */
+int pm8001_setup_chrdev(void)
+{
+ pm80xx_major = register_chrdev(0, DRV_NAME, &pm8001_fops);
+ if (pm80xx_major < 0) {
+ pr_warn("pm8001: unable to register %s device.\n",
+ DRV_NAME);
+ return pm80xx_major;
+ }
+ return 0;
+}
+
+/**
+ * pm8001_release_chrdev - unregisters per-adapter management interface
+ * Return value:
+ * none
+ */
+void pm8001_release_chrdev(void)
+{
+ if (pm80xx_major > -1) {
+ unregister_chrdev(pm80xx_major, DRV_NAME);
+ pm80xx_major = -1;
+ }
+}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index d0d43a250b9e..f0f8b1deae27 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -59,5 +59,38 @@
#define SYSFS_OFFSET 1024
#define PM80XX_IB_OB_QUEUE_SIZE (32 * 1024)
#define PM8001_IB_OB_QUEUE_SIZE (16 * 1024)
+
+#define ADPT_IOCTL_CALL_SUCCESS 0x00
+#define ADPT_IOCTL_CALL_FAILED 0x01
+#define ADPT_IOCTL_CALL_INVALID_CODE 0x03
+
+struct ioctl_header {
+ u32 io_controller_num;
+ u32 length;
+ u32 return_code;
+ u32 timeout;
+ u16 direction;
+};
+
+struct ioctl_drv_info {
+ u8 sz_name[64];
+ u16 usmajor_revision;
+ u16 usminor_revision;
+ u16 usbuild_revision;
+ u16 reserved0;
+ u32 maxdevices;
+ u32 maxoutstandingIO;
+ u32 reserved[16];
+};
+
+struct ioctl_info_buffer {
+ struct ioctl_header header;
+ struct ioctl_drv_info information;
+};
+
+#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
+
+#define ADPT_MAGIC_NUMBER 'm'
+
#endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 775517f9b39d..25e74f1dbd0c 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -1421,6 +1421,9 @@ static int __init pm8001_init(void)
pm8001_stt = sas_domain_attach_transport(&pm8001_transport_ops);
if (!pm8001_stt)
goto err_wq;
+ rc = pm8001_setup_chrdev();
+ if (rc)
+ goto err_ctl;
rc = pci_register_driver(&pm8001_pci_driver);
if (rc)
goto err_tp;
@@ -1428,6 +1431,8 @@ static int __init pm8001_init(void)
err_tp:
sas_release_transport(pm8001_stt);
+err_ctl:
+ pm8001_release_chrdev();
err_wq:
destroy_workqueue(pm8001_wq);
err:
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 93438c8f67da..479aac34d7cc 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -59,6 +59,9 @@
#define DRV_NAME "pm80xx"
#define DRV_VERSION "0.1.39"
+#define DRV_MAJOR 1
+#define DRV_MINOR 3
+#define DRV_BUILD 0
#define PM8001_FAIL_LOGGING 0x01 /* Error message logging */
#define PM8001_INIT_LOGGING 0x02 /* driver init logging */
#define PM8001_DISC_LOGGING 0x04 /* discovery layer logging */
@@ -745,6 +748,9 @@ ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
/* ctl shared API */
extern struct device_attribute *pm8001_host_attrs[];
+int pm8001_setup_chrdev(void);
+void pm8001_release_chrdev(void);
+
static inline void
pm8001_ccb_task_free_done(struct pm8001_hba_info *pm8001_ha,
struct sas_task *task, struct pm8001_ccb_info *ccb,
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (4 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 05/13] pm80xx : Support for char device Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 14:21 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status Deepak Ukey
` (6 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Viswas G <Viswas.G@microchip.com>
Added sysfs attribute to show number of phys.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 69458b318a20..8091e78a04b0 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -89,6 +89,25 @@ static ssize_t controller_fatal_error_show(struct device *cdev,
}
static DEVICE_ATTR_RO(controller_fatal_error);
+/**
+ * num_phys_show - Number of phys
+ * @cdev:pointer to embedded class device
+ * @buf:the buffer returned
+ * A sysfs 'read-only' shost attribute.
+ */
+static ssize_t num_phys_show(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+ struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+ ret = sprintf(buf, "%d", pm8001_ha->chip->n_phy);
+ return ret;
+}
+static DEVICE_ATTR_RO(num_phys);
+
/**
* pm8001_ctl_fw_version_show - firmware version
* @cdev: pointer to embedded class device
@@ -825,6 +844,7 @@ static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP,
struct device_attribute *pm8001_host_attrs[] = {
&dev_attr_interface_rev,
&dev_attr_controller_fatal_error,
+ &dev_attr_num_phys,
&dev_attr_fw_version,
&dev_attr_update_fw,
&dev_attr_aap_log,
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (5 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 14:35 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error Deepak Ukey
` (5 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Viswas G <Viswas.G@microchip.com>
Added the IOCTL functionality for phy status so that management
utility can get the information like phy id, phy status, port id
and port status from driver using get phy profile command.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 90 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 23 +++++++++-
drivers/scsi/pm8001/pm8001_sas.h | 7 ++++
drivers/scsi/pm8001/pm80xx_hwi.c | 68 ++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm80xx_hwi.h | 1 +
5 files changed, 188 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 8091e78a04b0..eb64566b2274 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -41,6 +41,8 @@
#include <linux/slab.h>
#include "pm8001_sas.h"
#include "pm8001_ctl.h"
+#include "pm80xx_hwi.h"
+
int pm80xx_major = -1;
/* scsi host attributes */
@@ -939,6 +941,91 @@ static long pm8001_info_ioctl(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ struct phy_profile phy_prof[MAX_NUM_PHYS];
+ int nphys;
+ DECLARE_COMPLETION_ONSTACK(completion);
+ unsigned long timeout = msecs_to_jiffies(2000);
+ u32 ret = 0, i;
+ int page_code = SAS_PHY_GENERAL_STATUS_PAGE;
+
+ if (pm8001_ha->pdev->device == 0x8001 ||
+ pm8001_ha->pdev->device == 0x8081) {
+ return ADPT_IOCTL_CALL_INVALID_DEVICE;
+ }
+
+ if (copy_from_user(&phy_prof[0], (struct phy_profile *)arg,
+ sizeof(struct phy_profile))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_from_user failed\n"));
+ return ADPT_IOCTL_CALL_FAILED;
+ }
+
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+ nphys = phy_prof[0].phy_id;
+ if (nphys == -1) {
+ for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+ pm8001_ha->ioctl_completion = &completion;
+ ret = PM8001_CHIP_DISP->get_phy_profile_req(pm8001_ha,
+ i, page_code);
+ if (ret != 0) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "Get phy profile request failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ timeout = wait_for_completion_timeout(&completion,
+ timeout);
+ if (timeout == 0) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ memcpy((void *)&phy_prof[i],
+ (void *)&pm8001_ha->phy_profile_resp,
+ sizeof(struct phy_profile));
+ }
+
+ if (copy_to_user((void *)arg, (void *)&phy_prof,
+ sizeof(struct phy_profile) * (i))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_to_user failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ } else {
+ pm8001_ha->ioctl_completion = &completion;
+ ret = PM8001_CHIP_DISP->get_phy_profile_req(pm8001_ha,
+ nphys, page_code);
+ if (ret != 0) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "Get phy profile request failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ timeout = wait_for_completion_timeout(&completion,
+ timeout);
+ if (timeout == 0) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+
+ if (copy_to_user((void *)arg,
+ (void *)&pm8001_ha->phy_profile_resp,
+ sizeof(struct phy_profile))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_to_user failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ }
+exit:
+ spin_lock_irq(&pm8001_ha->ioctl_lock);
+ pm8001_ha->ioctl_completion = NULL;
+ spin_unlock_irq(&pm8001_ha->ioctl_lock);
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+ return ret;
+}
+
/**
* pm8001_ioctl - pm8001 configuration request
* @inode: inode of device
@@ -962,6 +1049,9 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_INFO:
ret = pm8001_info_ioctl(pm8001_ha, arg);
break;
+ case ADPT_IOCTL_GET_PHY_PROFILE:
+ ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
+ return ret;
default:
ret = ADPT_IOCTL_CALL_INVALID_CODE;
}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index f0f8b1deae27..226fab82845f 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -63,6 +63,9 @@
#define ADPT_IOCTL_CALL_SUCCESS 0x00
#define ADPT_IOCTL_CALL_FAILED 0x01
#define ADPT_IOCTL_CALL_INVALID_CODE 0x03
+#define ADPT_IOCTL_CALL_INVALID_DEVICE 0x04
+
+#define MAX_NUM_PHYS 16
struct ioctl_header {
u32 io_controller_num;
@@ -88,8 +91,26 @@ struct ioctl_info_buffer {
struct ioctl_drv_info information;
};
-#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
+struct phy_profile {
+ char phy_id;
+ unsigned int phys:4;
+ unsigned int nlr:4;
+ unsigned int plr:4;
+ unsigned int reserved1:12;
+ unsigned char port_id;
+ unsigned int prts:4;
+ unsigned int reserved2:20;
+} __packed;
+struct phy_prof_resp {
+ union {
+ struct phy_profile status;
+ } phy;
+};
+
+#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
+#define ADPT_IOCTL_GET_PHY_PROFILE _IOWR(ADPT_MAGIC_NUMBER, 8, \
+ struct phy_profile*)
#define ADPT_MAGIC_NUMBER 'm'
#endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 479aac34d7cc..87d676810a18 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -56,6 +56,7 @@
#include <scsi/sas_ata.h>
#include <linux/atomic.h>
#include "pm8001_defs.h"
+#include "pm8001_ctl.h"
#define DRV_NAME "pm80xx"
#define DRV_VERSION "0.1.39"
@@ -246,6 +247,8 @@ struct pm8001_dispatch {
int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
u32 state);
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
+ int (*get_phy_profile_req)(struct pm8001_hba_info *pm8001_ha,
+ int phy, int page);
};
struct pm8001_chip_info {
@@ -560,6 +563,10 @@ struct pm8001_hba_info {
bool controller_fatal_error;
const struct firmware *fw_image;
struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
+ spinlock_t ioctl_lock;
+ struct mutex ioctl_mutex;
+ struct completion *ioctl_completion;
+ struct phy_prof_resp phy_profile_resp;
u32 reset_in_progress;
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 37b82d7aa3d7..0a36c5d5e2c2 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3688,9 +3688,48 @@ static int mpi_get_controller_config_resp(struct pm8001_hba_info *pm8001_ha,
static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb)
{
+ u32 tag, page_code;
+ struct phy_profile *phy_profile, *phy_prof;
+ struct get_phy_profile_resp *pPayload =
+ (struct get_phy_profile_resp *)(piomb + 4);
+ u32 status = le32_to_cpu(pPayload->status);
+
+ page_code = (u8)((pPayload->ppc_phyid & 0xFF00) >> 8);
+
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk(" pm80xx_addition_functionality\n"));
+ if (status) {
+ /* status is FAILED */
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "mpiGetPhyProfileReq failed with status 0x%08x\n",
+ status));
+ }
+
+ tag = le32_to_cpu(pPayload->tag);
+
+ spin_lock(&pm8001_ha->ioctl_lock);
+ if (pm8001_ha->ioctl_completion != NULL) {
+ if (status) {
+ /* signal fail status */
+ memset(&pm8001_ha->phy_profile_resp, 0xff,
+ sizeof(pm8001_ha->phy_profile_resp));
+ } else if (page_code == SAS_PHY_GENERAL_STATUS_PAGE) {
+ phy_profile =
+ (struct phy_profile *)&pm8001_ha->phy_profile_resp;
+ phy_prof =
+ (struct phy_profile *)pPayload->ppc_specific_rsp;
+ phy_profile->phy_id = le32_to_cpu(phy_prof->phy_id);
+ phy_profile->phys = le32_to_cpu(phy_prof->phys);
+ phy_profile->plr = le32_to_cpu(phy_prof->plr);
+ phy_profile->nlr = le32_to_cpu(phy_prof->nlr);
+ phy_profile->port_id = le32_to_cpu(phy_prof->port_id);
+ phy_profile->prts = le32_to_cpu(phy_prof->prts);
+ }
+ complete(pm8001_ha->ioctl_completion);
+ }
+ spin_unlock(&pm8001_ha->ioctl_lock);
+ pm8001_tag_free(pm8001_ha, tag);
return 0;
}
@@ -4883,6 +4922,34 @@ pm80xx_chip_isr(struct pm8001_hba_info *pm8001_ha, u8 vec)
return IRQ_HANDLED;
}
+int pm8001_chip_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
+ int phy_id, int page_code)
+{
+
+ u32 tag;
+ struct get_phy_profile_req payload;
+ struct inbound_queue_table *circularQ;
+ int rc, ppc_phyid;
+ u32 opc = OPC_INB_GET_PHY_PROFILE;
+
+ memset(&payload, 0, sizeof(payload));
+
+ rc = pm8001_tag_alloc(pm8001_ha, &tag);
+ if (rc)
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk("Invalid tag\n"));
+
+ circularQ = &pm8001_ha->inbnd_q_tbl[0];
+
+ payload.tag = cpu_to_le32(tag);
+ ppc_phyid = (page_code & 0xFF) << 8 | (phy_id & 0xFF);
+ payload.ppc_phyid = cpu_to_le32(ppc_phyid);
+
+ pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+ sizeof(payload), 0);
+
+ return rc;
+}
+
void mpi_set_phy_profile_req(struct pm8001_hba_info *pm8001_ha,
u32 operation, u32 phyid, u32 length, u32 *buf)
{
@@ -4983,4 +5050,5 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {
.set_nvmd_req = pm8001_chip_set_nvmd_req,
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
.set_dev_state_req = pm8001_chip_set_dev_state_req,
+ .get_phy_profile_req = pm8001_chip_get_phy_profile,
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 701951a0f715..230877caeed4 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -176,6 +176,7 @@
/* phy_profile */
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
+#define SAS_PHY_GENERAL_STATUS_PAGE 0x05
#define PHY_DWORD_LENGTH 0xC
/* Thermal related */
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (6 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 09/13] pm80xx : IOCTL functionality for GPIO Deepak Ukey
` (4 subsequent siblings)
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Viswas G <Viswas.G@microchip.com>
Added the IOCTL functionality for phy error so that management utility
can get the information like Invalid dword count, Disparity error count,
Loss of sync dword count, phy reset count from driver using get phy
profile command.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 54 ++++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 12 +++++++++
drivers/scsi/pm8001/pm80xx_hwi.c | 14 +++++++++++
drivers/scsi/pm8001/pm80xx_hwi.h | 1 +
4 files changed, 81 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index eb64566b2274..7f45e114a31a 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1026,6 +1026,57 @@ static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static int pm8001_ioctl_get_phy_err(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ struct phy_errcnt phy_err[MAX_NUM_PHYS];
+ DECLARE_COMPLETION_ONSTACK(completion);
+ unsigned long timeout = msecs_to_jiffies(2000);
+ u32 ret = 0, i;
+ int page_code = SAS_PHY_ERR_COUNTERS_PAGE;
+ /*6H card does not support phyerr*/
+ if (pm8001_ha->pdev->device == 0x8001 ||
+ pm8001_ha->pdev->device == 0x8081) {
+ return ADPT_IOCTL_CALL_INVALID_DEVICE;
+ }
+
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+
+ for (i = 0; i < pm8001_ha->chip->n_phy; i++) {
+ pm8001_ha->ioctl_completion = &completion;
+ ret = PM8001_CHIP_DISP->get_phy_profile_req(pm8001_ha,
+ i, page_code);
+ if (ret != 0) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk(
+ "Get phy profile request failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ timeout = wait_for_completion_timeout(&completion,
+ timeout);
+ if (timeout == 0) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ memcpy((void *)&phy_err[i],
+ (void *)&pm8001_ha->phy_profile_resp,
+ sizeof(struct phy_errcnt));
+ }
+
+ if (copy_to_user((void *)arg, (void *)&phy_err,
+ sizeof(struct phy_errcnt) * (i))) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("copy_to_user failed\n"));
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+exit:
+ spin_lock_irq(&pm8001_ha->ioctl_lock);
+ pm8001_ha->ioctl_completion = NULL;
+ spin_unlock_irq(&pm8001_ha->ioctl_lock);
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+ return ret;
+}
+
/**
* pm8001_ioctl - pm8001 configuration request
* @inode: inode of device
@@ -1052,6 +1103,9 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_GET_PHY_PROFILE:
ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
return ret;
+ case ADPT_IOCTL_GET_PHY_ERR_CNT:
+ ret = pm8001_ioctl_get_phy_err(pm8001_ha, arg);
+ break;
default:
ret = ADPT_IOCTL_CALL_INVALID_CODE;
}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index 226fab82845f..686ad69f0e0c 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -102,15 +102,27 @@ struct phy_profile {
unsigned int reserved2:20;
} __packed;
+struct phy_errcnt {
+ unsigned int InvalidDword;
+ unsigned int runningDisparityError;
+ unsigned int codeViolation;
+ unsigned int LossOfSyncDW;
+ unsigned int phyResetProblem;
+ unsigned int inboundCRCError;
+};
+
struct phy_prof_resp {
union {
struct phy_profile status;
+ struct phy_errcnt errcnt;
} phy;
};
#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
#define ADPT_IOCTL_GET_PHY_PROFILE _IOWR(ADPT_MAGIC_NUMBER, 8, \
struct phy_profile*)
+#define ADPT_IOCTL_GET_PHY_ERR_CNT _IOWR(ADPT_MAGIC_NUMBER, 9, \
+ struct phy_err*)
#define ADPT_MAGIC_NUMBER 'm'
#endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 0a36c5d5e2c2..e8af262976d6 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3690,6 +3690,7 @@ static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
{
u32 tag, page_code;
struct phy_profile *phy_profile, *phy_prof;
+ struct phy_errcnt *phy_err, *phy_err_cnt;
struct get_phy_profile_resp *pPayload =
(struct get_phy_profile_resp *)(piomb + 4);
u32 status = le32_to_cpu(pPayload->status);
@@ -3725,6 +3726,19 @@ static int mpi_get_phy_profile_resp(struct pm8001_hba_info *pm8001_ha,
phy_profile->nlr = le32_to_cpu(phy_prof->nlr);
phy_profile->port_id = le32_to_cpu(phy_prof->port_id);
phy_profile->prts = le32_to_cpu(phy_prof->prts);
+ } else if (page_code == SAS_PHY_ERR_COUNTERS_PAGE) {
+ phy_err =
+ (struct phy_errcnt *)&pm8001_ha->phy_profile_resp;
+ phy_err_cnt =
+ (struct phy_errcnt *)pPayload->ppc_specific_rsp;
+ phy_err->InvalidDword =
+ le32_to_cpu(phy_err_cnt->InvalidDword);
+ phy_err->runningDisparityError =
+ le32_to_cpu(phy_err_cnt->runningDisparityError);
+ phy_err->LossOfSyncDW =
+ le32_to_cpu(phy_err_cnt->LossOfSyncDW);
+ phy_err->phyResetProblem =
+ le32_to_cpu(phy_err_cnt->phyResetProblem);
}
complete(pm8001_ha->ioctl_completion);
}
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 230877caeed4..b5119c5479da 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -175,6 +175,7 @@
#define PHY_STOP_ERR_DEVICE_ATTACHED 0x1046
/* phy_profile */
+#define SAS_PHY_ERR_COUNTERS_PAGE 0x01
#define SAS_PHY_ANALOG_SETTINGS_PAGE 0x04
#define SAS_PHY_GENERAL_STATUS_PAGE 0x05
#define PHY_DWORD_LENGTH 0xC
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 09/13] pm80xx : IOCTL functionality for GPIO.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (7 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO Deepak Ukey
` (3 subsequent siblings)
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
Added IOCTL functionality for GPIO.
The SPCv controller provides 24 GPIO signals. The first 12 signals
[11:0] and the last 4 signals [23:20] are for customer use. Eight
signals [19:12] are reserved for the SPCv controller firmware.
Whenever the host performs GPIO setup or a read/write operation
using the GPIO command the host needs to make sure that it does
not disturb the GPIO configuration for the bits [19:12].
Each signal can be configured either as an input or as an output.
When configured as an output, the host can use the GPIO Command to
set the desired level. GPIO inputs can also be configured so that
the SPCv controller sends the GPIO Event notification when specific
GPIO events occur.
Different GPIO features implemented:
1) GPIO Pin Setup
2) GPIO Event Setup
3) GPIO Read
4) GPIO Write
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 95 ++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 24 +++++++++
drivers/scsi/pm8001/pm8001_init.c | 6 +++
drivers/scsi/pm8001/pm8001_sas.h | 17 ++++++
drivers/scsi/pm8001/pm80xx_hwi.c | 106 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm80xx_hwi.h | 49 ++++++++++++++++++
6 files changed, 297 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 7f45e114a31a..cadb5be394b6 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -39,6 +39,7 @@
*/
#include <linux/firmware.h>
#include <linux/slab.h>
+#include <linux/poll.h>
#include "pm8001_sas.h"
#include "pm8001_ctl.h"
#include "pm80xx_hwi.h"
@@ -941,6 +942,73 @@ static long pm8001_info_ioctl(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static long pm8001_gpio_ioctl(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ struct gpio_buffer buffer;
+ struct pm8001_gpio *payload;
+ struct gpio_ioctl_resp *gpio_resp;
+ DECLARE_COMPLETION_ONSTACK(completion);
+ unsigned long timeout;
+ u32 ret = 0, operation;
+
+ if (pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ADAPTEC2)
+ return ADPT_IOCTL_CALL_INVALID_DEVICE;
+
+ if (copy_from_user(&buffer, (struct gpio_buffer *)arg,
+ sizeof(struct gpio_buffer))) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+ pm8001_ha->ioctl_completion = &completion;
+ payload = &buffer.gpio_payload;
+ operation = payload->operation;
+ ret = PM8001_CHIP_DISP->gpio_req(pm8001_ha, payload);
+ if (ret != 0) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+
+ timeout = (unsigned long)buffer.header.timeout * 1000;
+ if (timeout < 2000)
+ timeout = 2000;
+
+ timeout = wait_for_completion_timeout(&completion,
+ msecs_to_jiffies(timeout));
+ if (timeout == 0) {
+ ret = ADPT_IOCTL_CALL_TIMEOUT;
+ goto exit;
+ }
+ gpio_resp = &pm8001_ha->gpio_resp;
+ buffer.header.return_code = ADPT_IOCTL_CALL_SUCCESS;
+
+ if (operation == GPIO_READ) {
+ payload->rd_wr_val = gpio_resp->gpio_rd_val;
+ payload->input_enable = gpio_resp->gpio_in_enabled;
+ payload->pinsetup1 = gpio_resp->gpio_pinsetup1;
+ payload->pinsetup2 = gpio_resp->gpio_pinsetup2;
+ payload->event_level = gpio_resp->gpio_evt_change;
+ payload->event_rising_edge = gpio_resp->gpio_evt_rise;
+ payload->event_falling_edge = gpio_resp->gpio_evt_fall;
+
+ if (copy_to_user((void *)arg, (void *)&buffer,
+ sizeof(struct gpio_buffer))) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ } else {
+ if (copy_to_user((void *)arg, (void *)&buffer.header,
+ sizeof(struct ioctl_header))) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ }
+exit:
+ spin_lock_irq(&pm8001_ha->ioctl_lock);
+ pm8001_ha->ioctl_completion = NULL;
+ spin_unlock_irq(&pm8001_ha->ioctl_lock);
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+ return ret;
+}
+
static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
unsigned long arg)
{
@@ -1100,6 +1168,9 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_INFO:
ret = pm8001_info_ioctl(pm8001_ha, arg);
break;
+ case ADPT_IOCTL_GPIO:
+ ret = pm8001_gpio_ioctl(pm8001_ha, arg);
+ break;
case ADPT_IOCTL_GET_PHY_PROFILE:
ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
return ret;
@@ -1122,11 +1193,35 @@ static long pm8001_ioctl(struct file *file,
return ret;
}
+/**
+ *pm8001_poll - pm8001 poll request function
+ *@file: file handle
+ *@wait: poll table to wait
+ *Handles a poll request.
+ */
+__poll_t pm8001_poll(struct file *file, poll_table *wait)
+{
+ struct pm8001_hba_info *pm8001_ha;
+ __poll_t mask = 0;
+
+ pm8001_ha = file->private_data;
+
+ poll_wait(file, &pm8001_ha->pollq, wait);
+
+ if (pm8001_ha->gpio_event_occurred == 1) {
+ pm8001_ha->gpio_event_occurred = 0;
+ mask |= POLLIN | POLLRDNORM;
+ }
+
+ return mask;
+}
+
static const struct file_operations pm8001_fops = {
.owner = THIS_MODULE,
.open = pm8001_open,
.release = pm8001_close,
.unlocked_ioctl = pm8001_ioctl,
+ .poll = pm8001_poll,
};
/**
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index 686ad69f0e0c..5be43b2672d4 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -64,6 +64,7 @@
#define ADPT_IOCTL_CALL_FAILED 0x01
#define ADPT_IOCTL_CALL_INVALID_CODE 0x03
#define ADPT_IOCTL_CALL_INVALID_DEVICE 0x04
+#define ADPT_IOCTL_CALL_TIMEOUT 0x08
#define MAX_NUM_PHYS 16
@@ -86,11 +87,33 @@ struct ioctl_drv_info {
u32 reserved[16];
};
+#define GPIO_READ 0
+#define GPIO_WRITE 1
+#define GPIO_PINSETUP 2
+#define GPIO_EVENTSETUP 3
+
+struct pm8001_gpio {
+ u32 operation;
+ u32 mask;
+ u32 rd_wr_val;
+ u32 input_enable;
+ u32 pinsetup1;
+ u32 pinsetup2;
+ u32 event_level;
+ u32 event_rising_edge;
+ u32 event_falling_edge;
+};
+
struct ioctl_info_buffer {
struct ioctl_header header;
struct ioctl_drv_info information;
};
+struct gpio_buffer {
+ struct ioctl_header header;
+ struct pm8001_gpio gpio_payload;
+};
+
struct phy_profile {
char phy_id;
unsigned int phys:4;
@@ -119,6 +142,7 @@ struct phy_prof_resp {
};
#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
+#define ADPT_IOCTL_GPIO _IOWR(ADPT_MAGIC_NUMBER, 1, struct gpio_buffer *)
#define ADPT_IOCTL_GET_PHY_PROFILE _IOWR(ADPT_MAGIC_NUMBER, 8, \
struct phy_profile*)
#define ADPT_IOCTL_GET_PHY_ERR_CNT _IOWR(ADPT_MAGIC_NUMBER, 9, \
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 25e74f1dbd0c..6e2512aa5f6e 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -498,6 +498,12 @@ static struct pm8001_hba_info *pm8001_pci_alloc(struct pci_dev *pdev,
else
pm8001_ha->iomb_size = IOMB_SIZE_SPC;
+ mutex_init(&pm8001_ha->ioctl_mutex);
+ pm8001_ha->ioctl_completion = NULL;
+ init_waitqueue_head(&pm8001_ha->pollq);
+ pm8001_ha->gpio_event_occurred = 0;
+ spin_lock_init(&pm8001_ha->ioctl_lock);
+
#ifdef PM8001_USE_TASKLET
/* Tasklet for non msi-x interrupt handler */
if ((!pdev->msix_cap || !pci_msi_enabled())
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 87d676810a18..7d9920376fb7 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -132,6 +132,18 @@ extern const struct pm8001_dispatch pm8001_80xx_dispatch;
struct pm8001_hba_info;
struct pm8001_ccb_info;
struct pm8001_device;
+
+struct gpio_ioctl_resp {
+ u32 tag;
+ u32 gpio_rd_val;
+ u32 gpio_in_enabled;
+ u32 gpio_pinsetup1;
+ u32 gpio_pinsetup2;
+ u32 gpio_evt_change;
+ u32 gpio_evt_rise;
+ u32 gpio_evt_fall;
+};
+
/* define task management IU */
struct pm8001_tmf_task {
u8 tmf;
@@ -247,6 +259,8 @@ struct pm8001_dispatch {
int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
u32 state);
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
+ int (*gpio_req)(struct pm8001_hba_info *pm8001_ha,
+ struct pm8001_gpio *gpio_payload);
int (*get_phy_profile_req)(struct pm8001_hba_info *pm8001_ha,
int phy, int page);
};
@@ -562,6 +576,9 @@ struct pm8001_hba_info {
u32 smp_exp_mode;
bool controller_fatal_error;
const struct firmware *fw_image;
+ struct gpio_ioctl_resp gpio_resp;
+ u32 gpio_event_occurred;
+ wait_queue_head_t pollq;
struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
spinlock_t ioctl_lock;
struct mutex ioctl_mutex;
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index e8af262976d6..2cdcb1c64970 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -3845,6 +3845,50 @@ static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha,
return 0;
}
+static int mpi_gpio_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+ u32 tag;
+ struct gpio_ioctl_resp *pgpio_resp;
+ struct gpio_resp *ppayload = (struct gpio_resp *)(piomb + 4);
+
+ tag = le32_to_cpu(ppayload->tag);
+ spin_lock(&pm8001_ha->ioctl_lock);
+ if (pm8001_ha->ioctl_completion != NULL) {
+ pgpio_resp = &pm8001_ha->gpio_resp;
+ pgpio_resp->gpio_rd_val = le32_to_cpu(ppayload->gpio_rd_val);
+ pgpio_resp->gpio_in_enabled =
+ le32_to_cpu(ppayload->gpio_in_enabled);
+ pgpio_resp->gpio_pinsetup1 =
+ le32_to_cpu(ppayload->gpio_pinsetup1);
+ pgpio_resp->gpio_pinsetup2 =
+ le32_to_cpu(ppayload->gpio_pinsetup2);
+ pgpio_resp->gpio_evt_change =
+ le32_to_cpu(ppayload->gpio_evt_change);
+ pgpio_resp->gpio_evt_rise =
+ le32_to_cpu(ppayload->gpio_evt_rise);
+ pgpio_resp->gpio_evt_fall =
+ le32_to_cpu(ppayload->gpio_evt_fall);
+
+ complete(pm8001_ha->ioctl_completion);
+ }
+ spin_unlock(&pm8001_ha->ioctl_lock);
+ pm8001_tag_free(pm8001_ha, tag);
+ return 0;
+}
+
+static int mpi_gpio_event(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+ u32 gpio_event = 0;
+ struct gpio_event *ppayload = (struct gpio_event *)(piomb + 4);
+
+ gpio_event = le32_to_cpu(ppayload->gpio_event);
+ PM8001_MSG_DBG(pm8001_ha,
+ pm8001_printk("GPIO event: 0x%X\n", gpio_event));
+ pm8001_ha->gpio_event_occurred = 1;
+ wake_up_interruptible(&pm8001_ha->pollq);
+ return 0;
+}
+
/**
* process_one_iomb - process one outbound Queue memory block
* @pm8001_ha: our hba card information
@@ -3931,10 +3975,12 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
case OPC_OUB_GPIO_RESPONSE:
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk("OPC_OUB_GPIO_RESPONSE\n"));
+ mpi_gpio_resp(pm8001_ha, piomb);
break;
case OPC_OUB_GPIO_EVENT:
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk("OPC_OUB_GPIO_EVENT\n"));
+ mpi_gpio_event(pm8001_ha, piomb);
break;
case OPC_OUB_GENERAL_EVENT:
PM8001_MSG_DBG(pm8001_ha,
@@ -5038,6 +5084,65 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
PM8001_INIT_DBG(pm8001_ha,
pm8001_printk("PHY %d settings applied", phy));
}
+
+/**
+ * pm80xx_chip_gpio_req - support for GPIO operation
+ * @pm8001_ha: our hba card information.
+ * @ioctl_payload: the payload for the GPIO operation
+ */
+int pm80xx_chip_gpio_req(struct pm8001_hba_info *pm8001_ha,
+ struct pm8001_gpio *gpio_payload)
+{
+ struct gpio_req payload;
+ struct inbound_queue_table *circularQ;
+ int ret;
+ u32 tag;
+ u32 opc = OPC_INB_GPIO;
+
+ if (pm8001_ha->pdev->subsystem_vendor == PCI_VENDOR_ID_ADAPTEC2)
+ return -1;
+
+ ret = pm8001_tag_alloc(pm8001_ha, &tag);
+ if (ret)
+ return -1;
+
+ memset(&payload, 0, sizeof(payload));
+ circularQ = &pm8001_ha->inbnd_q_tbl[0];
+ payload.tag = cpu_to_le32(tag);
+
+ switch (gpio_payload->operation) {
+ case GPIO_READ:
+ payload.eobid_ge_gs_gr_gw = cpu_to_le32(GPIO_GR_BIT);
+ break;
+ case GPIO_WRITE:
+ payload.eobid_ge_gs_gr_gw = cpu_to_le32(GPIO_GW_BIT);
+ payload.gpio_wr_msk = cpu_to_le32(gpio_payload->mask);
+ payload.gpio_wr_val = cpu_to_le32(gpio_payload->rd_wr_val);
+ break;
+ case GPIO_PINSETUP:
+ payload.eobid_ge_gs_gr_gw = cpu_to_le32(GPIO_GS_BIT);
+ payload.gpio_in_enabled =
+ cpu_to_le32(gpio_payload->input_enable);
+ payload.gpio_pinsetup1 = cpu_to_le32(gpio_payload->pinsetup1);
+ payload.gpio_pinsetup2 = cpu_to_le32(gpio_payload->pinsetup2);
+ break;
+ case GPIO_EVENTSETUP:
+ payload.eobid_ge_gs_gr_gw = cpu_to_le32(GPIO_GE_BIT);
+ payload.gpio_evt_change =
+ cpu_to_le32(gpio_payload->event_level);
+ payload.gpio_evt_rise =
+ cpu_to_le32(gpio_payload->event_rising_edge);
+ payload.gpio_evt_fall =
+ cpu_to_le32(gpio_payload->event_falling_edge);
+ break;
+ }
+ ret = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+ sizeof(payload), 0);
+ if (ret != 0)
+ pm8001_tag_free(pm8001_ha, tag);
+ return ret;
+}
+
const struct pm8001_dispatch pm8001_80xx_dispatch = {
.name = "pmc80xx",
.chip_init = pm80xx_chip_init,
@@ -5064,5 +5169,6 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {
.set_nvmd_req = pm8001_chip_set_nvmd_req,
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
.set_dev_state_req = pm8001_chip_set_dev_state_req,
+ .gpio_req = pm80xx_chip_gpio_req,
.get_phy_profile_req = pm8001_chip_get_phy_profile,
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index b5119c5479da..fed193df93d6 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -529,6 +529,55 @@ struct hw_event_ack_req {
u32 reserved1[27];
} __attribute__((packed, aligned(4)));
+/*
+ * brief the data structure of GPIO Commannd
+ * use to control MPI GPIOs (64 bytes)
+ */
+struct gpio_req {
+ __le32 tag;
+ __le32 eobid_ge_gs_gr_gw;
+ __le32 gpio_wr_msk;
+ __le32 gpio_wr_val;
+ __le32 gpio_in_enabled;
+ __le32 gpio_pinsetup1;
+ __le32 gpio_pinsetup2;
+ __le32 gpio_evt_change;
+ __le32 gpio_evt_rise;
+ __le32 gpio_evt_fall;
+ u32 reserved[5];
+} __packed __aligned(4);
+
+#define GPIO_GW_BIT 0x1
+#define GPIO_GR_BIT 0x2
+#define GPIO_GS_BIT 0x4
+#define GPIO_GE_BIT 0x8
+
+/*
+ * brief the data structure of GPIO Response
+ * indicates the completion of GPIO command (64 bytes)
+ */
+struct gpio_resp {
+ __le32 tag;
+ u32 reserved[2];
+ __le32 gpio_rd_val;
+ __le32 gpio_in_enabled;
+ __le32 gpio_pinsetup1;
+ __le32 gpio_pinsetup2;
+ __le32 gpio_evt_change;
+ __le32 gpio_evt_rise;
+ __le32 gpio_evt_fall;
+ u32 reserved1[5];
+} __packed __aligned(4);
+
+/*
+ * brief the data structure of GPIO Event
+ * indicates the generation of GPIO event (64 bytes)
+ */
+struct gpio_event {
+ __le32 gpio_event;
+ u32 reserved[14];
+} __packed __aligned(4);
+
/*
* brief the data structure of PHY_START Response Command
* indicates the completion of PHY_START command (64 bytes)
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (8 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 09/13] pm80xx : IOCTL functionality for GPIO Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-22 8:59 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump Deepak Ukey
` (2 subsequent siblings)
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
Added the IOCTL functionality for SGPIO through which management
utility can controls SGPIO LEDs on the enclosure of locally attached
drives only. It is used to read from/write into SGPIO registers and
sets one or more SGPIO registers.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Reported-by: kbuild test robot <lkp@intel.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 71 ++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 72 ++++++++++++++++
drivers/scsi/pm8001/pm8001_hwi.c | 172 +++++++++++++++++++++++++++++++++++++-
drivers/scsi/pm8001/pm8001_hwi.h | 17 ++++
drivers/scsi/pm8001/pm8001_init.c | 3 +
drivers/scsi/pm8001/pm8001_sas.c | 37 ++++++++
drivers/scsi/pm8001/pm8001_sas.h | 20 +++++
drivers/scsi/pm8001/pm80xx_hwi.c | 6 ++
drivers/scsi/pm8001/pm80xx_hwi.h | 3 +
9 files changed, 400 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index cadb5be394b6..d557b423edf6 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1009,6 +1009,74 @@ static long pm8001_gpio_ioctl(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static long pm8001_sgpio_ioctl(struct pm8001_hba_info *pm8001_ha,
+ unsigned long arg)
+{
+ struct sgpio_buffer buffer;
+ struct read_write_req_resp *req = &buffer.sgpio_req;
+ struct sgpio_req payload;
+ struct sgpio_ioctl_resp *sgpio_resp;
+ DECLARE_COMPLETION_ONSTACK(completion);
+ unsigned long timeout;
+ u32 ret = 0, i;
+
+ if (copy_from_user(&buffer, (struct sgpio_buffer *)arg,
+ sizeof(struct sgpio_buffer))) {
+ return ADPT_IOCTL_CALL_FAILED;
+ }
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+ pm8001_ha->ioctl_completion = &completion;
+
+ payload.func_reg_index = cpu_to_le32((req->register_index << 24) |
+ (req->register_type << 16) | (req->function << 8) |
+ SMP_FRAME_REQ);
+ payload.count = req->register_count;
+
+ if (req->function == WRITE_SGPIO_REGISTER) {
+ if (req->register_count > MAX_SGPIO_REQ_PAYLOAD) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+ for (i = 0; i < req->register_count; i++)
+ payload.value[i] = req->read_write_data[i];
+ }
+
+ ret = PM8001_CHIP_DISP->sgpio_req(pm8001_ha, &payload);
+ if (ret != 0) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ goto exit;
+ }
+
+ timeout = wait_for_completion_timeout(&completion,
+ msecs_to_jiffies(2000));
+ if (timeout == 0) {
+ ret = ADPT_IOCTL_CALL_TIMEOUT;
+ goto exit;
+ }
+
+ sgpio_resp = &pm8001_ha->sgpio_resp;
+ req->frame_type = sgpio_resp->func_result & 0xff;
+ req->function = (sgpio_resp->func_result >> 8) & 0xff;
+ req->function_result = (sgpio_resp->func_result >> 16) & 0xff;
+ if (req->function == READ_SGPIO_REGISTER) {
+ for (i = 0; i < req->register_count; i++)
+ req->read_write_data[i] = sgpio_resp->value[i];
+ }
+ ret = ADPT_IOCTL_CALL_SUCCESS;
+exit:
+ spin_lock_irq(&pm8001_ha->ioctl_lock);
+ pm8001_ha->ioctl_completion = NULL;
+ spin_unlock_irq(&pm8001_ha->ioctl_lock);
+ buffer.header.return_code = ret;
+ if (copy_to_user((void *)arg, (void *)&buffer,
+ sizeof(struct sgpio_buffer))) {
+ ret = ADPT_IOCTL_CALL_FAILED;
+ }
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+
+ return ret;
+}
+
static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
unsigned long arg)
{
@@ -1171,6 +1239,9 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_GPIO:
ret = pm8001_gpio_ioctl(pm8001_ha, arg);
break;
+ case ADPT_IOCTL_SGPIO:
+ ret = pm8001_sgpio_ioctl(pm8001_ha, arg);
+ break;
case ADPT_IOCTL_GET_PHY_PROFILE:
ret = pm8001_ioctl_get_phy_profile(pm8001_ha, arg);
return ret;
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index 5be43b2672d4..b1be0bc065d5 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -68,6 +68,39 @@
#define MAX_NUM_PHYS 16
+/************************************************************
+ * SGPIO Function and Register type
+ ************************************************************/
+#define READ_SGPIO_REGISTER 0x02
+#define WRITE_SGPIO_REGISTER 0x82
+
+#define SMP_FRAME_REQ 0x40
+#define SMP_FRAME_RESP 0x41
+
+#define SGPIO_CONFIG_REG 0x0
+#define SGPIO_DRIVE_BY_DRIVE_RECEIVE_REG 0x1
+#define SGPIO_GENERAL_PURPOSE_RECEIVE_REG 0x2
+#define SGPIO_DRIVE_BY_DRIVE_TRANSMIT_REG 0x3
+#define SGPIO_GENERAL_PURPOSE_TRANSMIT_REG 0x4
+
+/************************************************************
+ * SGPIO Function result
+ ************************************************************/
+#define SGPIO_COMMAND_SUCCESS 0x00
+#define SGPIO_CMD_ERROR_WRONG_FRAME_TYPE 0x01
+#define SGPIO_CMD_ERROR_WRONG_REG_TYPE 0x02
+#define SGPIO_CMD_ERROR_WRONG_REG_INDEX 0x03
+#define SGPIO_CMD_ERROR_WRONG_REG_COUNT 0x04
+#define SGPIO_CMD_ERROR_WRONG_FRAME_REG_TYPE 0x05
+#define SGPIO_CMD_ERROR_WRONG_FUNCTION 0x06
+#define SGPIO_CMD_ERROR_WRONG_FRAME_TYPE_REG_INDEX 0x19
+#define SGPIO_CMD_ERROR_WRONG_FRAME_TYPE_REG_CNT 0x81
+#define SGPIO_CMD_ERROR_WRONG_REG_TYPE_REG_INDEX 0x1A
+#define SGPIO_CMD_ERROR_WRONG_REG_TYPE_REG_COUNT 0x82
+#define SGPIO_CMD_ERROR_WRONG_REG_INDEX_REG_COUNT 0x83
+#define SGPIO_CMD_ERROR_WRONG_FRAME_REG_TYPE_REG_INDEX 0x1D
+#define SGPIO_CMD_ERROR_WRONG_ALL_HEADER_PARAMS 0x9D
+
struct ioctl_header {
u32 io_controller_num;
u32 length;
@@ -104,6 +137,39 @@ struct pm8001_gpio {
u32 event_falling_edge;
};
+#define MAX_SGPIO_REQ_PAYLOAD 12
+#define MAX_SGPIO_RESP_PAYLOAD 13
+
+struct read_write_req_resp {
+ u8 frame_type; /* =0x40 */
+ u8 function; /* 0x02 for read, 0x82 for write */
+ u8 register_type;
+ u8 register_index;
+ u8 register_count;
+ u8 function_result;
+ u32 read_write_data[MAX_SGPIO_RESP_PAYLOAD];
+};
+
+struct sgpio_cfg_0 {
+ u8 reserved;
+ u8 version:4;
+ u8 reserved1:4;
+ u8 gp_register_count:4;
+ u8 cfg_register_count:3;
+ u8 enable:1;
+ u8 supported_drive_cnt;
+};
+
+struct sgpio_cfg_1 {
+ u8 reserved;
+ u8 blink_gen_a:4;
+ u8 blink_gen_b:4;
+ u8 max_act_on:4;
+ u8 forced_act_off:4;
+ u8 stretch_act_on:4;
+ u8 stretch_act_off:4;
+};
+
struct ioctl_info_buffer {
struct ioctl_header header;
struct ioctl_drv_info information;
@@ -114,6 +180,11 @@ struct gpio_buffer {
struct pm8001_gpio gpio_payload;
};
+struct sgpio_buffer {
+ struct ioctl_header header;
+ struct read_write_req_resp sgpio_req;
+};
+
struct phy_profile {
char phy_id;
unsigned int phys:4;
@@ -143,6 +214,7 @@ struct phy_prof_resp {
#define ADPT_IOCTL_INFO _IOR(ADPT_MAGIC_NUMBER, 0, struct ioctl_info_buffer *)
#define ADPT_IOCTL_GPIO _IOWR(ADPT_MAGIC_NUMBER, 1, struct gpio_buffer *)
+#define ADPT_IOCTL_SGPIO _IOWR(ADPT_MAGIC_NUMBER, 2, struct sgpio_buffer *)
#define ADPT_IOCTL_GET_PHY_PROFILE _IOWR(ADPT_MAGIC_NUMBER, 8, \
struct phy_profile*)
#define ADPT_IOCTL_GET_PHY_ERR_CNT _IOWR(ADPT_MAGIC_NUMBER, 9, \
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 2328ff1349ac..f9395d9fd530 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3666,6 +3666,49 @@ int pm8001_mpi_dereg_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
return 0;
}
+/**
+ *pm8001_sgpio_resp - pm8001 SGPIO response
+ *@pm8001_ha: HBA controller information
+ *@piomb: SGPIO payload
+ *Handles SGPIO response from HBA.
+ */
+
+int pm8001_sgpio_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
+{
+ u32 func_result;
+ u32 tag, i;
+ u32 value;
+ struct sgpio_ioctl_resp *sgpio_resp;
+ struct sgpio_reg_resp *registerRespPayload =
+ (struct sgpio_reg_resp *)(piomb + 4);
+
+ tag = le32_to_cpu(registerRespPayload->tag);
+ func_result = le32_to_cpu(registerRespPayload->func_result);
+ value = le32_to_cpu(registerRespPayload->value[0]);
+
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
+ "SGPIO func result = 0x%x tag %x value %x\n",
+ func_result, tag, value));
+
+ spin_lock(&pm8001_ha->ioctl_lock);
+ if (pm8001_ha->ioctl_completion != NULL) {
+ sgpio_resp = &pm8001_ha->sgpio_resp;
+ sgpio_resp->func_result = func_result;
+ PM8001_MSG_DBG(pm8001_ha,
+ pm8001_printk("SGPIO response value hexdump\n"));
+ for (i = 0; i < MAX_SGPIO_RESP_PAYLOAD; i++) {
+ sgpio_resp->value[i] =
+ le32_to_cpu(registerRespPayload->value[i]);
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
+ "value[%d] = %08x\n", i, sgpio_resp->value[i]));
+ }
+ complete(pm8001_ha->ioctl_completion);
+ }
+ spin_unlock(&pm8001_ha->ioctl_lock);
+ pm8001_tag_free(pm8001_ha, tag);
+ return 0;
+}
+
/**
* fw_flash_update_resp - Response from FW for flash update command.
* @pm8001_ha: our hba card information
@@ -4035,7 +4078,7 @@ static int mpi_hw_event(struct pm8001_hba_info *pm8001_ha, void* piomb)
static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
{
__le32 pHeader = *(__le32 *)piomb;
- u8 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF);
+ u16 opc = (u8)((le32_to_cpu(pHeader)) & 0xFFF);
PM8001_MSG_DBG(pm8001_ha, pm8001_printk("process_one_iomb:"));
@@ -4190,6 +4233,11 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
PM8001_MSG_DBG(pm8001_ha,
pm8001_printk("OPC_OUB_SAS_RE_INITIALIZE\n"));
break;
+ case OPC_OUB_SGPIO_RESP:
+ PM8001_MSG_DBG(pm8001_ha,
+ pm8001_printk("OPC_OUB_SGPIO RESPONSE\n"));
+ pm8001_sgpio_resp(pm8001_ha, piomb);
+ break;
default:
PM8001_DEVIO_DBG(pm8001_ha,
pm8001_printk("Unknown outbound Queue IOMB OPC = %x\n",
@@ -5136,6 +5184,88 @@ pm8001_chip_set_dev_state_req(struct pm8001_hba_info *pm8001_ha,
}
+/**
+ *pm8001_setup_sgpio - Setup SGPIO configuration for SPC/SPCv controllers
+ *pm8001_ha - controller information
+ */
+int pm8001_setup_sgpio(struct pm8001_hba_info *pm8001_ha)
+{
+ struct sgpio_req payload;
+ struct sgpio_cfg_0 *cfg_0;
+ struct sgpio_cfg_1 *cfg_1;
+ int rc, index = 0, i;
+ u32 value = 0;
+ DECLARE_COMPLETION_ONSTACK(completion);
+
+ pm8001_ha->ioctl_completion = &completion;
+ payload.func_reg_index = ((index << 24) | (SGPIO_CONFIG_REG << 16)
+ | (WRITE_SGPIO_REGISTER << 8) | SMP_FRAME_REQ);
+ payload.count = 2;
+
+ cfg_0 = (struct sgpio_cfg_0 *)(&value);
+ cfg_0->enable = 0x1;
+ payload.value[0] = value;
+
+ /*Initialize GPIO CFG 1 register to default as per SFF-8485 spec*/
+ cfg_1 = (struct sgpio_cfg_1 *)(&value);
+ cfg_1->blink_gen_a = 0;
+ cfg_1->blink_gen_b = 0;
+ cfg_1->max_act_on = 0x2;
+ cfg_1->forced_act_off = 0x1;
+ cfg_1->stretch_act_on = 0;
+ cfg_1->stretch_act_off = 0;
+
+ payload.value[1] = value;
+ PM8001_INIT_DBG(pm8001_ha,
+ pm8001_printk("Setting up sgpio. index %x count %x\n",
+ payload.func_reg_index, payload.count));
+
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+ pm8001_ha->ioctl_completion = &completion;
+ rc = PM8001_CHIP_DISP->sgpio_req(pm8001_ha, &payload);
+ if (rc) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("failed sgpio_req:%d\n", rc));
+ goto exit;
+ }
+ rc = wait_for_completion_timeout(&completion, msecs_to_jiffies(2000));
+ if (rc == 0) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("failed sgpio_req timeout\n"));
+ rc = ADPT_IOCTL_CALL_TIMEOUT;
+ goto exit;
+ }
+ payload.func_reg_index = ((index << 24) |
+ (SGPIO_DRIVE_BY_DRIVE_TRANSMIT_REG << 16) |
+ (WRITE_SGPIO_REGISTER << 8) | SMP_FRAME_REQ);
+ payload.count = pm8001_ha->chip->n_phy/4;
+ value = 0xA0A0A0A0; //Activity=0x5, Locate=0, Error=0
+ for (i = 0; i < payload.count; i++)
+ payload.value[i] = value;
+ reinit_completion(&completion);
+ pm8001_ha->ioctl_completion = &completion;
+ rc = PM8001_CHIP_DISP->sgpio_req(pm8001_ha, &payload);
+ if (rc) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("failed sgpio_req:%d\n", rc));
+ goto exit;
+ }
+ rc = wait_for_completion_timeout(&completion, msecs_to_jiffies(2000));
+ if (rc == 0) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("failed sgpio_req timeout\n"));
+ rc = ADPT_IOCTL_CALL_TIMEOUT;
+ goto exit;
+ }
+
+exit:
+ spin_lock(&pm8001_ha->ioctl_lock);
+ pm8001_ha->ioctl_completion = NULL;
+ spin_unlock(&pm8001_ha->ioctl_lock);
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+ return rc;
+}
+
static int
pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
{
@@ -5164,6 +5294,45 @@ pm8001_chip_sas_re_initialization(struct pm8001_hba_info *pm8001_ha)
}
+/**
+ * pm8001_chip_sgpio_req - support for SGPIO operation
+ * @pm8001_ha: our hba card information.
+ * @ioctl_payload: the payload for the SGPIO operation
+ */
+int pm8001_chip_sgpio_req(struct pm8001_hba_info *pm8001_ha,
+ struct sgpio_req *sgpio_payload)
+{
+ struct sgpio_reg_req payload;
+ struct inbound_queue_table *circularQ;
+ int rc, i;
+ u32 tag;
+ u32 opc = OPC_INB_SGPIO_REG;
+
+ memset(&payload, 0, sizeof(struct sgpio_reg_req));
+ rc = pm8001_tag_alloc(pm8001_ha, &tag);
+ if (rc)
+ return -1;
+
+ circularQ = &pm8001_ha->inbnd_q_tbl[0];
+ payload.tag = cpu_to_le32(tag);
+ payload.func_reg_index = cpu_to_le32(sgpio_payload->func_reg_index);
+ payload.count = cpu_to_le32(sgpio_payload->count);
+
+ for (i = 0; i < sgpio_payload->count; i++)
+ payload.value[i] = cpu_to_le32(sgpio_payload->value[i]);
+
+ PM8001_MSG_DBG(pm8001_ha,
+ pm8001_printk("sgpio operation. tag %x index %x count %x\n",
+ tag, sgpio_payload->func_reg_index, sgpio_payload->count));
+
+ rc = pm8001_mpi_build_cmd(pm8001_ha, circularQ, opc, &payload,
+ sizeof(payload), 0);
+ if (rc != 0)
+ pm8001_tag_free(pm8001_ha, tag);
+
+ return rc;
+}
+
const struct pm8001_dispatch pm8001_8001_dispatch = {
.name = "pmc8001",
.chip_init = pm8001_chip_init,
@@ -5191,4 +5360,5 @@ const struct pm8001_dispatch pm8001_8001_dispatch = {
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
.set_dev_state_req = pm8001_chip_set_dev_state_req,
.sas_re_init_req = pm8001_chip_sas_re_initialization,
+ .sgpio_req = pm8001_chip_sgpio_req,
};
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index 6d91e2446542..aad2322467d2 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -82,6 +82,7 @@
#define OPC_INB_GET_DEVICE_STATE 43 /* 0x02B */
#define OPC_INB_SET_DEV_INFO 44 /* 0x02C */
#define OPC_INB_SAS_RE_INITIALIZE 45 /* 0x02D */
+#define OPC_INB_SGPIO_REG 46 /* 0x02E */
/* for Response Opcode of IOMB */
#define OPC_OUB_ECHO 1 /* 0x001 */
@@ -120,6 +121,7 @@
#define OPC_OUB_GET_DEVICE_STATE 39 /* 0x027 */
#define OPC_OUB_SET_DEV_INFO 40 /* 0x028 */
#define OPC_OUB_SAS_RE_INITIALIZE 41 /* 0x029 */
+#define OPC_OUB_SGPIO_RESP 2094 /* 0x82E */
/* for phy start*/
#define SPINHOLD_DISABLE (0x00 << 14)
@@ -697,6 +699,18 @@ struct set_dev_state_resp {
u32 reserved[11];
} __attribute__((packed, aligned(4)));
+struct sgpio_reg_req {
+ __le32 tag;
+ __le32 func_reg_index;
+ __le32 count;
+ __le32 value[12];
+} __packed __aligned(4);
+
+struct sgpio_reg_resp {
+ __le32 tag;
+ __le32 func_result;
+ __le32 value[13];
+} __packed __aligned(4);
#define NDS_BITS 0x0F
#define PDS_BITS 0xF0
@@ -922,6 +936,9 @@ struct set_dev_state_resp {
#define MAIN_HDA_FLAGS_OFFSET 0x84/* DWORD 0x21 */
#define MAIN_ANALOG_SETUP_OFFSET 0x88/* DWORD 0x22 */
+/*FATAL ERROR INTERRUPT bit definition*/
+#define MAIN_CFG_SGPIO_ENABLE (0x1 << 2)
+
/* Gereral Status Table offset - byte offset */
#define GST_GSTLEN_MPIS_OFFSET 0x00
#define GST_IQ_FREEZE_STATE0_OFFSET 0x04
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 6e2512aa5f6e..c8414f1b9652 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -122,6 +122,7 @@ static struct sas_domain_function_template pm8001_transport_ops = {
.lldd_I_T_nexus_reset = pm8001_I_T_nexus_reset,
.lldd_lu_reset = pm8001_lu_reset,
.lldd_query_task = pm8001_query_task,
+ .lldd_write_gpio = pm8001_write_sgpio,
};
/**
@@ -1110,6 +1111,8 @@ static int pm8001_pci_probe(struct pci_dev *pdev,
if (pm8001_configure_phy_settings(pm8001_ha))
goto err_out_shost;
+ pm8001_setup_sgpio(pm8001_ha);
+
pm8001_post_sas_ha_init(shost, chip);
rc = sas_register_ha(SHOST_TO_SAS_HA(shost));
if (rc) {
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c
index b7cbc312843e..1d03c62d8c99 100644
--- a/drivers/scsi/pm8001/pm8001_sas.c
+++ b/drivers/scsi/pm8001/pm8001_sas.c
@@ -1361,3 +1361,40 @@ int pm8001_clear_task_set(struct domain_device *dev, u8 *lun)
return pm8001_issue_ssp_tmf(dev, lun, &tmf_task);
}
+int pm8001_write_sgpio(struct sas_ha_struct *sas_ha, u8 reg_type,
+ u8 reg_index, u8 reg_count, u8 *write_data)
+{
+ struct pm8001_hba_info *pm8001_ha = sas_ha->lldd_ha;
+ struct sgpio_req payload;
+ u32 ret = 0, i, j, value;
+
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
+ "reg_type=%x, reg_index:%x, reg_count:%x\n",
+ reg_type, reg_index, reg_count));
+
+ mutex_lock(&pm8001_ha->ioctl_mutex);
+
+ payload.func_reg_index = cpu_to_le32((reg_index << 24) |
+ (reg_type << 16) | (WRITE_SGPIO_REGISTER << 8) |
+ SMP_FRAME_REQ);
+
+ payload.count = reg_count;
+
+ for (i = 0; i < reg_count; i++) {
+ value = 0;
+ for (j = 0; j < 4; j++) {
+ value |= (u32)(*write_data) << (24-(j*8));
+ write_data++;
+ }
+ payload.value[i] = value;
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
+ "payload value: %x\n", payload.value[i]));
+ }
+
+ ret = PM8001_CHIP_DISP->sgpio_req(pm8001_ha, &payload);
+ if (ret != 0)
+ ret = -1;
+
+ mutex_unlock(&pm8001_ha->ioctl_mutex);
+ return ret;
+}
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 7d9920376fb7..4c6c7d86f75e 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -144,6 +144,17 @@ struct gpio_ioctl_resp {
u32 gpio_evt_fall;
};
+struct sgpio_req {
+ u32 func_reg_index;
+ u32 count;
+ u32 value[MAX_SGPIO_REQ_PAYLOAD];
+};
+
+struct sgpio_ioctl_resp {
+ u32 func_result;
+ u32 value[MAX_SGPIO_RESP_PAYLOAD];
+};
+
/* define task management IU */
struct pm8001_tmf_task {
u8 tmf;
@@ -261,6 +272,8 @@ struct pm8001_dispatch {
int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
int (*gpio_req)(struct pm8001_hba_info *pm8001_ha,
struct pm8001_gpio *gpio_payload);
+ int (*sgpio_req)(struct pm8001_hba_info *pm8001_ha,
+ struct sgpio_req *sgpio_payload);
int (*get_phy_profile_req)(struct pm8001_hba_info *pm8001_ha,
int phy, int page);
};
@@ -583,6 +596,7 @@ struct pm8001_hba_info {
spinlock_t ioctl_lock;
struct mutex ioctl_mutex;
struct completion *ioctl_completion;
+ struct sgpio_ioctl_resp sgpio_resp;
struct phy_prof_resp phy_profile_resp;
u32 reset_in_progress;
};
@@ -696,6 +710,8 @@ int pm8001_lu_reset(struct domain_device *dev, u8 *lun);
int pm8001_I_T_nexus_reset(struct domain_device *dev);
int pm8001_I_T_nexus_event_handler(struct domain_device *dev);
int pm8001_query_task(struct sas_task *task);
+int pm8001_write_sgpio(struct sas_ha_struct *sas_ha, u8 reg_type,
+ u8 reg_index, u8 reg_count, u8 *write_data);
void pm8001_open_reject_retry(
struct pm8001_hba_info *pm8001_ha,
struct sas_task *task_to_close,
@@ -731,6 +747,8 @@ int pm8001_chip_abort_task(struct pm8001_hba_info *pm8001_ha,
struct pm8001_device *pm8001_dev,
u8 flag, u32 task_tag, u32 cmd_tag);
int pm8001_chip_dereg_dev_req(struct pm8001_hba_info *pm8001_ha, u32 device_id);
+int pm8001_chip_sgpio_req(struct pm8001_hba_info *pm8001_ha,
+ struct sgpio_req *sgpio_payload);
void pm8001_chip_make_sg(struct scatterlist *scatter, int nr, void *prd);
void pm8001_work_fn(struct work_struct *work);
int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha,
@@ -752,6 +770,7 @@ int pm8001_mpi_fw_flash_update_resp(struct pm8001_hba_info *pm8001_ha,
void *piomb);
int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha , void *piomb);
int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb);
+int pm8001_sgpio_resp(struct pm8001_hba_info *pm8001_ha, void *piomb);
struct sas_task *pm8001_alloc_task(void);
void pm8001_task_done(struct sas_task *task);
void pm8001_free_task(struct sas_task *task);
@@ -759,6 +778,7 @@ void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag);
struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
u32 device_id);
int pm80xx_set_thermal_config(struct pm8001_hba_info *pm8001_ha);
+int pm8001_setup_sgpio(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,
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index 2cdcb1c64970..e4746fd9c09f 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -4100,6 +4100,11 @@ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, void *piomb)
"OPC_OUB_SSP_COALESCED_COMP_RESP opcode:%x\n", opc));
ssp_coalesced_comp_resp(pm8001_ha, piomb);
break;
+ case OPC_OUB_SGPIO_RESP:
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk(
+ "OPC_OUB_SGPIO RESPONSE opcode: %x\n", opc));
+ pm8001_sgpio_resp(pm8001_ha, piomb);
+ break;
default:
PM8001_DEVIO_DBG(pm8001_ha, pm8001_printk(
"Unknown outbound Queue IOMB OPC = 0x%x\n", opc));
@@ -5170,5 +5175,6 @@ const struct pm8001_dispatch pm8001_80xx_dispatch = {
.fw_flash_update_req = pm8001_chip_fw_flash_update_req,
.set_dev_state_req = pm8001_chip_set_dev_state_req,
.gpio_req = pm80xx_chip_gpio_req,
+ .sgpio_req = pm8001_chip_sgpio_req,
.get_phy_profile_req = pm8001_chip_get_phy_profile,
};
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index fed193df93d6..2d7f67b1cd93 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -1509,6 +1509,9 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
#define MAIN_MPI_ILA_RELEASE_TYPE 0xA4 /* DWORD 0x29 */
#define MAIN_MPI_INACTIVE_FW_VERSION 0XB0 /* DWORD 0x2C */
+/*FATAL ERROR INTERRUPT bit definition*/
+#define MAIN_CFG_SGPIO_ENABLE (0x1 << 2)
+
/* Gereral Status Table offset - byte offset */
#define GST_GSTLEN_MPIS_OFFSET 0x00
#define GST_IQ_FREEZE_STATE0_OFFSET 0x04
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (9 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 14:26 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 12/13] pm80xx : Introduce read and write length for IOCTL payload structure Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 13/13] pm80xx : IOCTL functionality for TWI device Deepak Ukey
12 siblings, 1 reply; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
Added the sysfs attribute for non fatal log so that management utility
can get the non fatal dump from driver. The non-fatal error is an error
condition or abnormal behavior detected by the host, or detected and
reported by the controller to the host.The non-fatal error does not stop
the controller firmware and enables it to still respond to host requests.
A typical example of a non-fatal error is an I/O timeout or an unusual
error notification from the controller. Since the firmware is operational,
the error dump information is pushed to host memory (by firmware) upon
request from the host.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 45 +++++++++++++
drivers/scsi/pm8001/pm8001_init.c | 1 +
drivers/scsi/pm8001/pm8001_sas.h | 4 ++
drivers/scsi/pm8001/pm80xx_hwi.c | 130 ++++++++++++++++++++++++++++++++++++++
4 files changed, 180 insertions(+)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index d557b423edf6..9fce19024945 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -577,6 +577,49 @@ static ssize_t pm8001_ctl_fatal_log_show(struct device *cdev,
static DEVICE_ATTR(fatal_log, S_IRUGO, pm8001_ctl_fatal_log_show, NULL);
+/**
+ ** non_fatal_log_show - non fatal error logging
+ ** @cdev:pointer to embedded class device
+ ** @buf: the buffer returned
+ **
+ ** A sysfs 'read-only' shost attribute.
+ **/
+static ssize_t non_fatal_log_show(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ u32 count;
+
+ count = pm80xx_get_non_fatal_dump(cdev, attr, buf);
+ return count;
+}
+static DEVICE_ATTR_RO(non_fatal_log);
+
+static ssize_t non_fatal_count_show(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+ struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+
+ return snprintf(buf, PAGE_SIZE, "%08x",
+ pm8001_ha->non_fatal_count);
+}
+
+static ssize_t non_fatal_count_store(struct device *cdev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+ struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+ int val = 0;
+
+ if (kstrtoint(buf, 16, &val) != 0)
+ return -EINVAL;
+
+ pm8001_ha->non_fatal_count = val;
+ return strlen(buf);
+}
+static DEVICE_ATTR_RW(non_fatal_count);
/**
** pm8001_ctl_gsm_log_show - gsm dump collection
@@ -853,6 +896,8 @@ struct device_attribute *pm8001_host_attrs[] = {
&dev_attr_aap_log,
&dev_attr_iop_log,
&dev_attr_fatal_log,
+ &dev_attr_non_fatal_log,
+ &dev_attr_non_fatal_count,
&dev_attr_gsm_log,
&dev_attr_max_out_io,
&dev_attr_max_devices,
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index c8414f1b9652..b74282bc1ed0 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -484,6 +484,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->non_fatal_count = 0;
if (link_rate >= 1 && link_rate <= 15)
pm8001_ha->link_rate = (link_rate << 8);
else {
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 4c6c7d86f75e..ae5f880dd9bb 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -599,6 +599,8 @@ struct pm8001_hba_info {
struct sgpio_ioctl_resp sgpio_resp;
struct phy_prof_resp phy_profile_resp;
u32 reset_in_progress;
+ u32 non_fatal_count;
+ u32 non_fatal_read_length;
};
struct pm8001_work {
@@ -788,6 +790,8 @@ void pm8001_set_phy_profile_single(struct pm8001_hba_info *pm8001_ha,
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);
+ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
+ struct device_attribute *attr, char *buf);
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
/* ctl shared API */
extern struct device_attribute *pm8001_host_attrs[];
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index e4746fd9c09f..a4e265292d17 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -393,6 +393,136 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
(char *)buf;
}
+/* pm80xx_get_non_fatal_dump - dump the nonfatal data from the dma
+ * location by the firmware.
+ */
+ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(cdev);
+ struct sas_ha_struct *sha = SHOST_TO_SAS_HA(shost);
+ struct pm8001_hba_info *pm8001_ha = sha->lldd_ha;
+ void __iomem *nonfatal_table_address = pm8001_ha->fatal_tbl_addr;
+ u32 accum_len = 0;
+ u32 total_len = 0;
+ u32 reg_val = 0;
+ u32 *temp = NULL;
+ u32 index = 0;
+ u32 output_length;
+ unsigned long start = 0;
+ char *buf_copy = buf;
+
+ temp = (u32 *)pm8001_ha->memoryMap.region[FORENSIC_MEM].virt_ptr;
+ if (++pm8001_ha->non_fatal_count == 1) {
+ if (pm8001_ha->chip_id == chip_8001) {
+ snprintf(pm8001_ha->forensic_info.data_buf.direct_data,
+ PAGE_SIZE, "Not supported for SPC controller");
+ return 0;
+ }
+ PM8001_IO_DBG(pm8001_ha,
+ pm8001_printk("forensic_info TYPE_NON_FATAL...\n"));
+ /*
+ * Step 1: Write the host buffer parameters in the MPI Fatal and
+ * Non-Fatal Error Dump Capture Table.This is the buffer
+ * where debug data will be DMAed to.
+ */
+ pm8001_mw32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_LO_OFFSET,
+ pm8001_ha->memoryMap.region[FORENSIC_MEM].phys_addr_lo);
+
+ pm8001_mw32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_HI_OFFSET,
+ pm8001_ha->memoryMap.region[FORENSIC_MEM].phys_addr_hi);
+
+ pm8001_mw32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_LENGTH, SYSFS_OFFSET);
+
+ /* Optionally, set the DUMPCTRL bit to 1 if the host
+ * keeps sending active I/Os while capturing the non-fatal
+ * debug data. Otherwise, leave this bit set to zero
+ */
+ pm8001_mw32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_HANDSHAKE, MPI_FATAL_EDUMP_HANDSHAKE_RDY);
+
+ /*
+ * Step 2: Clear Accumulative Length of Debug Data Transferred
+ * [ACCDDLEN] field in the MPI Fatal and Non-Fatal Error Dump
+ * Capture Table to zero.
+ */
+ pm8001_mw32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN, 0);
+
+ /* initiallize previous accumulated length to 0 */
+ pm8001_ha->forensic_preserved_accumulated_transfer = 0;
+ pm8001_ha->non_fatal_read_length = 0;
+ }
+
+ total_len = pm8001_mr32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_TOTAL_LEN);
+ /*
+ * Step 3:Clear Fatal/Non-Fatal Debug Data Transfer Status [FDDTSTAT]
+ * field and then request that the SPCv controller transfer the debug
+ * data by setting bit 7 of the Inbound Doorbell Set Register.
+ */
+ pm8001_mw32(nonfatal_table_address, MPI_FATAL_EDUMP_TABLE_STATUS, 0);
+ pm8001_cw32(pm8001_ha, 0, MSGU_IBDB_SET,
+ SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP);
+
+ /*
+ * Step 4.1: Read back the Inbound Doorbell Set Register (by polling for
+ * 2 seconds) until register bit 7 is cleared.
+ * This step only indicates the request is accepted by the controller.
+ */
+ start = jiffies + (2 * HZ); /* 2 sec */
+ do {
+ reg_val = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET) &
+ SPCv_MSGU_CFG_TABLE_NONFATAL_DUMP;
+ } while ((reg_val != 0) && time_before(jiffies, start));
+
+ /* Step 4.2: To check the completion of the transfer, poll the Fatal/Non
+ * Fatal Debug Data Transfer Status [FDDTSTAT] field for 2 seconds in
+ * the MPI Fatal and Non-Fatal Error Dump Capture Table.
+ */
+ start = jiffies + (2 * HZ); /* 2 sec */
+ do {
+ reg_val = pm8001_mr32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_STATUS);
+ } while ((!reg_val) && time_before(jiffies, start));
+
+ if ((reg_val == 0x00) ||
+ (reg_val == MPI_FATAL_EDUMP_TABLE_STAT_DMA_FAILED) ||
+ (reg_val > MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE)) {
+ pm8001_ha->non_fatal_read_length = 0;
+ buf_copy += snprintf(buf_copy, PAGE_SIZE, "%08x ", 0xFFFFFFFF);
+ pm8001_ha->non_fatal_count = 0;
+ return (buf_copy - buf);
+ } else if (reg_val ==
+ MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_MORE_DATA) {
+ buf_copy += snprintf(buf_copy, PAGE_SIZE, "%08x ", 2);
+ } else if ((reg_val == MPI_FATAL_EDUMP_TABLE_STAT_NF_SUCCESS_DONE) ||
+ (pm8001_ha->non_fatal_read_length >= total_len)) {
+ pm8001_ha->non_fatal_read_length = 0;
+ buf_copy += snprintf(buf_copy, PAGE_SIZE, "%08x ", 4);
+ pm8001_ha->non_fatal_count = 0;
+ }
+ accum_len = pm8001_mr32(nonfatal_table_address,
+ MPI_FATAL_EDUMP_TABLE_ACCUM_LEN);
+ output_length = accum_len -
+ pm8001_ha->forensic_preserved_accumulated_transfer;
+
+ for (index = 0; index < output_length/4; index++)
+ buf_copy += snprintf(buf_copy, PAGE_SIZE,
+ "%08x ", *(temp+index));
+
+ pm8001_ha->non_fatal_read_length += output_length;
+
+ /* store current accumulated length to use in next iteration as
+ * the previous accumulated length
+ */
+ pm8001_ha->forensic_preserved_accumulated_transfer = accum_len;
+ return (buf_copy - buf);
+}
+
/**
* read_main_config_table - read the configure table and save it.
* @pm8001_ha: our hba card information
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 12/13] pm80xx : Introduce read and write length for IOCTL payload structure.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (10 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 13/13] pm80xx : IOCTL functionality for TWI device Deepak Ukey
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Viswas G <Viswas.G@microchip.com>
Removed the common length and introduce read and write length for
IOCTL payload structure.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 6 +++---
drivers/scsi/pm8001/pm8001_hwi.c | 22 +++++++++++-----------
drivers/scsi/pm8001/pm8001_init.c | 12 ++++++------
drivers/scsi/pm8001/pm8001_sas.h | 3 ++-
4 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 9fce19024945..887a15ee69f6 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -486,7 +486,7 @@ static ssize_t pm8001_ctl_bios_version_show(struct device *cdev,
pm8001_ha->nvmd_completion = &completion;
payload.minor_function = 7;
payload.offset = 0;
- payload.length = 4096;
+ payload.rd_length = 4096;
payload.func_specific = kzalloc(4096, GFP_KERNEL);
if (!payload.func_specific)
return -ENOMEM;
@@ -697,7 +697,7 @@ static int pm8001_set_nvmd(struct pm8001_hba_info *pm8001_ha)
payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
memcpy((u8 *)&payload->func_specific, (u8 *)pm8001_ha->fw_image->data,
pm8001_ha->fw_image->size);
- payload->length = pm8001_ha->fw_image->size;
+ payload->wr_length = pm8001_ha->fw_image->size;
payload->id = 0;
payload->minor_function = 0x1;
pm8001_ha->nvmd_completion = &completion;
@@ -743,7 +743,7 @@ static int pm8001_update_flash(struct pm8001_hba_info *pm8001_ha)
IOCTL_BUF_SIZE);
for (loopNumber = 0; loopNumber < loopcount; loopNumber++) {
payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
- payload->length = 1024*16;
+ payload->wr_length = 1024*16;
payload->id = 0;
fwControl =
(struct fw_control_info *)&payload->func_specific;
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index f9395d9fd530..16dc7a92ad68 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -4841,7 +4841,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
if (!fw_control_context)
return -ENOMEM;
fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific;
- fw_control_context->len = ioctl_payload->length;
+ fw_control_context->len = ioctl_payload->rd_length;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memset(&nvmd_req, 0, sizeof(nvmd_req));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
@@ -4862,7 +4862,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
twi_page_size << 8 | TWI_DEVICE);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
@@ -4871,7 +4871,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
}
case C_SEEPROM: {
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
@@ -4880,7 +4880,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
}
case VPD_FLASH: {
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
@@ -4889,7 +4889,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
}
case EXPAN_ROM: {
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
@@ -4898,7 +4898,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
}
case IOP_RDUMP: {
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | IOP_RDUMP);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
@@ -4938,7 +4938,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
circularQ = &pm8001_ha->inbnd_q_tbl[0];
memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
&ioctl_payload->func_specific,
- ioctl_payload->length);
+ ioctl_payload->wr_length);
memset(&nvmd_req, 0, sizeof(nvmd_req));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
if (rc) {
@@ -4957,7 +4957,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
twi_page_size << 8 | TWI_DEVICE);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
nvmd_req.resp_addr_lo =
@@ -4966,7 +4966,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
}
case C_SEEPROM:
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | C_SEEPROM);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);
nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
@@ -4975,7 +4975,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
break;
case VPD_FLASH:
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | VPD_FLASH);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);
nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
@@ -4984,7 +4984,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
break;
case EXPAN_ROM:
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | EXPAN_ROM);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->length);
+ nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);
nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index b74282bc1ed0..6e037638656d 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -643,22 +643,22 @@ static void pm8001_init_sas_add(struct pm8001_hba_info *pm8001_ha)
if (pm8001_ha->chip_id == chip_8001) {
if (deviceid == 0x8081 || deviceid == 0x0042) {
payload.minor_function = 4;
- payload.length = 4096;
+ payload.rd_length = 4096;
} else {
payload.minor_function = 0;
- payload.length = 128;
+ payload.rd_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;
+ payload.rd_length = 4096;
} else {
payload.minor_function = 1;
- payload.length = 4096;
+ payload.rd_length = 4096;
}
payload.offset = 0;
- payload.func_specific = kzalloc(payload.length, GFP_KERNEL);
+ payload.func_specific = kzalloc(payload.rd_length, GFP_KERNEL);
if (!payload.func_specific) {
PM8001_INIT_DBG(pm8001_ha, pm8001_printk("mem alloc fail\n"));
return;
@@ -728,7 +728,7 @@ static int pm8001_get_phy_settings_info(struct pm8001_hba_info *pm8001_ha)
/* SAS ADDRESS read from flash / EEPROM */
payload.minor_function = 6;
payload.offset = 0;
- payload.length = 4096;
+ payload.rd_length = 4096;
payload.func_specific = kzalloc(4096, GFP_KERNEL);
if (!payload.func_specific)
return -ENOMEM;
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index ae5f880dd9bb..13d7813b8d74 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -164,10 +164,11 @@ struct pm8001_ioctl_payload {
u32 signature;
u16 major_function;
u16 minor_function;
- u16 length;
u16 status;
u16 offset;
u16 id;
+ u32 wr_length;
+ u32 rd_length;
u8 *func_specific;
};
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH V2 13/13] pm80xx : IOCTL functionality for TWI device.
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
` (11 preceding siblings ...)
2020-01-17 7:19 ` [PATCH V2 12/13] pm80xx : Introduce read and write length for IOCTL payload structure Deepak Ukey
@ 2020-01-17 7:19 ` Deepak Ukey
12 siblings, 0 replies; 38+ messages in thread
From: Deepak Ukey @ 2020-01-17 7:19 UTC (permalink / raw)
To: linux-scsi
Cc: Vasanthalakshmi.Tharmarajan, Viswas.G, deepak.ukey, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
From: Deepak Ukey <Deepak.Ukey@microchip.com>
Added the IOCTL functionality for TWI device so that management
utility can manage the TWI device attached to the controller's
TWI. The TWI device includes (but not limited to) the SEEPROM
device. When NVME field set to 0000b (TWI devices), this command
also allows the host to specify:
a. TWI device address
b. TWI Bus number
c. TWI device page size (1, 8, 16 or 32 bytes)
d. TWI device address size (1 or 2 bytes)
Also added the module parameter for TWI device address and page
size in order to add support for different TWI devices.
Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
Signed-off-by: Viswas G <Viswas.G@microchip.com>
Signed-off-by: Radha Ramachandran <radha@google.com>
---
drivers/scsi/pm8001/pm8001_ctl.c | 133 ++++++++++++++++++++++++++++++++++++++
drivers/scsi/pm8001/pm8001_ctl.h | 23 +++++++
drivers/scsi/pm8001/pm8001_hwi.c | 113 ++++++++++++++++++++++++++------
drivers/scsi/pm8001/pm8001_hwi.h | 1 +
drivers/scsi/pm8001/pm8001_init.c | 10 +++
drivers/scsi/pm8001/pm8001_sas.h | 13 ++++
drivers/scsi/pm8001/pm80xx_hwi.c | 41 ++++++++++++
drivers/scsi/pm8001/pm80xx_hwi.h | 1 +
8 files changed, 314 insertions(+), 21 deletions(-)
diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c
index 887a15ee69f6..ce9d1ee5e995 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.c
+++ b/drivers/scsi/pm8001/pm8001_ctl.c
@@ -1122,6 +1122,126 @@ static long pm8001_sgpio_ioctl(struct pm8001_hba_info *pm8001_ha,
return ret;
}
+static int icotl_twi_wr_request(int twi_wr,
+ struct pm8001_hba_info *pm8001_ha, unsigned long arg)
+{
+ int ret = 0;
+ unsigned char *buf;
+ int bus;
+ int addr;
+ bool addr_mode_7bit = true;
+ int rd_size = 0;
+ int wr_size = 0;
+ int offset = 0;
+ bool direct_addr = true;
+ struct twi_ioctl_payload *twi_ioctl;
+
+ twi_ioctl = kmalloc(sizeof(struct twi_ioctl_payload), GFP_KERNEL);
+ if (!twi_ioctl) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("Failed to allocate ioctl\n"));
+ return -ENOMEM;
+ }
+ ret = copy_from_user(twi_ioctl, (u8 *)arg, sizeof(*twi_ioctl));
+ if (ret) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("Failed to get ioctl args\n"));
+ return -EIO;
+ }
+
+ bus = twi_ioctl->bus;
+ addr = twi_ioctl->addr;
+
+ switch (twi_wr) {
+ case TW_WRITE:
+ wr_size = twi_ioctl->wr_size;
+ /* first 1K read/write is not possible,
+ * from 2k we have customer specific seeprom
+ */
+ offset = twi_ioctl->offset;
+ if (wr_size > 48)
+ direct_addr = false;
+ buf = kzalloc(wr_size, GFP_KERNEL);
+
+ if (buf == NULL) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("No Memory for write\n"));
+ return -ENOMEM;
+ }
+ ret = copy_from_user(buf, (u8 *)twi_ioctl->buf, wr_size);
+ if (!ret) {
+ ret = pm80xx_twi_wr_request(pm8001_ha, bus, addr,
+ addr_mode_7bit, rd_size, wr_size, offset,
+ direct_addr, buf);
+ } else {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("Failed to get data from buffer\n"));
+ return -EIO;
+ }
+ kfree(buf);
+ break;
+ case TW_READ:
+ rd_size = twi_ioctl->rd_size;
+ offset = twi_ioctl->offset;
+ if (rd_size > 48)
+ direct_addr = false;
+ buf = kzalloc(rd_size, GFP_KERNEL);
+ if (buf == NULL) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("No Memory for read\n"));
+ return -ENOMEM;
+ }
+ ret = pm80xx_twi_wr_request(pm8001_ha, bus, addr,
+ addr_mode_7bit, rd_size, wr_size, offset,
+ direct_addr, buf);
+ if (!ret) {
+ ret = copy_to_user((u8 *)twi_ioctl->buf, buf, rd_size);
+ kfree(buf);
+ } else {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("pm80xx_twi_wr_request failed !!!\n"));
+ return -EIO;
+ }
+ break;
+ case TW_WRITE_READ:
+ rd_size = twi_ioctl->rd_size;
+ wr_size = twi_ioctl->wr_size;
+ offset = twi_ioctl->offset;
+ if (wr_size > 48 || rd_size > 48)
+ direct_addr = false;
+ buf = kzalloc(max_t(int, wr_size, rd_size), GFP_KERNEL);
+ if (buf == NULL) {
+ PM8001_FAIL_DBG(pm8001_ha,
+ pm8001_printk("No Memory for read\n"));
+ return -ENOMEM;
+ }
+ ret = copy_from_user(buf, (u8 *)twi_ioctl->buf, wr_size);
+ if (!ret) {
+ ret = pm80xx_twi_wr_request(pm8001_ha, bus, addr,
+ addr_mode_7bit, rd_size, wr_size, offset,
+ direct_addr, buf);
+ if (!ret)
+ ret = copy_to_user((u8 *)twi_ioctl->buf,
+ buf, rd_size);
+ else {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("Failed to copy data to read buffer\n"));
+ ret = -EIO;
+ }
+ } else {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("Failed to get data from write buffer\n"));
+ return -ENOMEM;
+ }
+ break;
+ default:
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("Invalid twi operation\n"));
+ return -EINVAL;
+ }
+ return ret;
+}
+
static int pm8001_ioctl_get_phy_profile(struct pm8001_hba_info *pm8001_ha,
unsigned long arg)
{
@@ -1274,6 +1394,7 @@ static long pm8001_ioctl(struct file *file,
u32 ret = -EACCES;
struct pm8001_hba_info *pm8001_ha;
struct ioctl_header header;
+ u8 twi_wr = 0;
pm8001_ha = file->private_data;
@@ -1293,6 +1414,18 @@ static long pm8001_ioctl(struct file *file,
case ADPT_IOCTL_GET_PHY_ERR_CNT:
ret = pm8001_ioctl_get_phy_err(pm8001_ha, arg);
break;
+ case ADPT_IOCTL_TWI_WRITE:
+ twi_wr = 0x01;
+ ret = icotl_twi_wr_request(twi_wr, pm8001_ha, arg);
+ return ret;
+ case ADPT_IOCTL_TWI_READ:
+ twi_wr = 0x02;
+ ret = icotl_twi_wr_request(twi_wr, pm8001_ha, arg);
+ return ret;
+ case ADPT_IOCTL_TWI_WRITE_READ:
+ twi_wr = 0x03;
+ ret = icotl_twi_wr_request(twi_wr, pm8001_ha, arg);
+ return ret;
default:
ret = ADPT_IOCTL_CALL_INVALID_CODE;
}
diff --git a/drivers/scsi/pm8001/pm8001_ctl.h b/drivers/scsi/pm8001/pm8001_ctl.h
index b1be0bc065d5..57bf597aa9c3 100644
--- a/drivers/scsi/pm8001/pm8001_ctl.h
+++ b/drivers/scsi/pm8001/pm8001_ctl.h
@@ -101,6 +101,26 @@
#define SGPIO_CMD_ERROR_WRONG_FRAME_REG_TYPE_REG_INDEX 0x1D
#define SGPIO_CMD_ERROR_WRONG_ALL_HEADER_PARAMS 0x9D
+#define TWI_SEEPROM_BUS_NUMBER 0
+#define TWI_SEEPROM_DEV_ADDR 0xa0
+#define TWI_SEEPROM_READ_SIZE 1024
+#define TWI_SEEPROM_WRITE_SIZE 1024
+
+#define TW_IOCTL_STATUS_SUCCESS 0
+#define TW_IOCTL_STATUS_FAILURE 1
+#define TW_IOCTL_STATUS_WRONG_ADDR 0xA
+
+struct twi_ioctl_payload {
+ u32 bus;
+ u32 addr;
+ u32 rd_size;
+ u32 wr_size;
+ u32 offset;
+ u8 addr_mode;
+ u8 *buf;
+ u32 status;
+};
+
struct ioctl_header {
u32 io_controller_num;
u32 length;
@@ -219,6 +239,9 @@ struct phy_prof_resp {
struct phy_profile*)
#define ADPT_IOCTL_GET_PHY_ERR_CNT _IOWR(ADPT_MAGIC_NUMBER, 9, \
struct phy_err*)
+#define ADPT_IOCTL_TWI_READ _IOR('m', 10, char *)
+#define ADPT_IOCTL_TWI_WRITE _IOW('m', 11, char *)
+#define ADPT_IOCTL_TWI_WRITE_READ _IOWR('m', 12, char *)
#define ADPT_MAGIC_NUMBER 'm'
#endif /* PM8001_CTL_H_INCLUDED */
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c
index 16dc7a92ad68..0736c4b8cf7b 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.c
+++ b/drivers/scsi/pm8001/pm8001_hwi.c
@@ -3152,13 +3152,34 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
u32 tag = le32_to_cpu(pPayload->tag);
struct pm8001_ccb_info *ccb = &pm8001_ha->ccb_info[tag];
u32 dlen_status = le32_to_cpu(pPayload->dlen_status);
- complete(pm8001_ha->nvmd_completion);
- PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n"));
+ u32 *nvmd_data_addr;
+ u32 ir_tds_bn_dps_das_nvm =
+ le32_to_cpu(pPayload->ir_tda_bn_dps_das_nvm);
+ int tw_wr = (ir_tds_bn_dps_das_nvm & TR_MASK) >> 29;
+ struct fw_control_ex *fw_control_context;
+
+ fw_control_context = ccb->fw_control_context;
if ((dlen_status & NVMD_STAT) != 0) {
PM8001_FAIL_DBG(pm8001_ha,
pm8001_printk("Set nvm data error!\n"));
+ complete(pm8001_ha->nvmd_completion);
return;
}
+
+ if ((ir_tds_bn_dps_das_nvm & NVMD_TYPE) == TWI_DEVICE) {
+ if (tw_wr == TW_READ || tw_wr == TW_WRITE_READ) {
+ if (ir_tds_bn_dps_das_nvm & IPMode) {
+ nvmd_data_addr =
+ pm8001_ha->memoryMap.region[NVMD].virt_ptr;
+ } else {
+ nvmd_data_addr = pPayload->nvm_data;
+ }
+ memcpy(fw_control_context->usrAddr, nvmd_data_addr,
+ fw_control_context->len);
+ }
+ }
+ complete(pm8001_ha->nvmd_completion);
+ PM8001_MSG_DBG(pm8001_ha, pm8001_printk("Set nvm data complete!\n"));
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
pm8001_tag_free(pm8001_ha, tag);
@@ -3223,11 +3244,11 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb)
memcpy(fw_control_context->usrAddr,
pm8001_ha->memoryMap.region[NVMD].virt_ptr,
fw_control_context->len);
+ complete(pm8001_ha->nvmd_completion);
kfree(ccb->fw_control_context);
ccb->task = NULL;
ccb->ccb_tag = 0xFFFFFFFF;
pm8001_tag_free(pm8001_ha, tag);
- complete(pm8001_ha->nvmd_completion);
}
int pm8001_mpi_local_phy_ctl(struct pm8001_hba_info *pm8001_ha, void *piomb)
@@ -4856,12 +4877,17 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha,
switch (nvmd_type) {
case TWI_DEVICE: {
- u32 twi_addr, twi_page_size;
- twi_addr = 0xa8;
- twi_page_size = 2;
+ u32 twi_addr, twi_page_size, twi_addr_size, twi_busno;
+
+ twi_addr = pm8001_ha->twi_address;
+ twi_page_size = pm8001_ha->twi_page_size;
+ twi_addr_size = 1;
+ twi_busno = 0;
nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
- twi_page_size << 8 | TWI_DEVICE);
+ twi_busno << 12 | twi_page_size << 8 |
+ twi_addr_size << 4 | TWI_DEVICE);
+ nvmd_req.vpd_offset = cpu_to_le32(ioctl_payload->offset);
nvmd_req.resp_len = cpu_to_le32(ioctl_payload->rd_length);
nvmd_req.resp_addr_hi =
cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
@@ -4936,32 +4962,77 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha,
if (!fw_control_context)
return -ENOMEM;
circularQ = &pm8001_ha->inbnd_q_tbl[0];
- memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
- &ioctl_payload->func_specific,
- ioctl_payload->wr_length);
+ if (nvmd_type != TWI_DEVICE) {
+ memcpy(pm8001_ha->memoryMap.region[NVMD].virt_ptr,
+ &ioctl_payload->func_specific,
+ ioctl_payload->wr_length);
+ }
memset(&nvmd_req, 0, sizeof(nvmd_req));
rc = pm8001_tag_alloc(pm8001_ha, &tag);
if (rc) {
kfree(fw_control_context);
- return -EBUSY;
+ return rc;
}
ccb = &pm8001_ha->ccb_info[tag];
ccb->fw_control_context = fw_control_context;
ccb->ccb_tag = tag;
nvmd_req.tag = cpu_to_le32(tag);
+
switch (nvmd_type) {
case TWI_DEVICE: {
- u32 twi_addr, twi_page_size;
- twi_addr = 0xa8;
- twi_page_size = 2;
+ u32 twi_addr, twi_page_size, twi_addr_size, twi_busno;
+ u32 addr_mode;
+ u8 *nvmd_data_addr;
+ u8 tr = 0, d_len = 0;
+ u32 ipdl = 0;//indirect data payload len
+ u32 tr_dl = 0; //twi read data len
+
+ addr_mode = (ioctl_payload->twi_direct_addr == true) ?
+ 0 : IPMode;
+ if (ioctl_payload->rd_length) {
+ tr_dl = ioctl_payload->rd_length;
+ fw_control_context->usrAddr =
+ (u8 *)ioctl_payload->func_specific;
+ fw_control_context->len = ioctl_payload->rd_length;
+ tr = TW_READ;
+ }
+ if (ioctl_payload->wr_length) {
+ if (addr_mode == 0) {
+ d_len = ioctl_payload->wr_length;
+ nvmd_data_addr = (u8 *)&(nvmd_req.reserved[0]);
+ } else {
+ ipdl = ioctl_payload->wr_length;
+ nvmd_data_addr =
+ pm8001_ha->memoryMap.region[NVMD].virt_ptr;
+ }
+ memcpy(nvmd_data_addr, ioctl_payload->func_specific,
+ ioctl_payload->wr_length);
+ tr = TW_WRITE;
+ }
+ if (ioctl_payload->wr_length && ioctl_payload->rd_length)
+ tr = TW_WRITE_READ;
+ twi_addr = ioctl_payload->twi_addr;
+ if (twi_addr == TWI_SEEPROM_DEV_ADDR)
+ tr = 0;//Reserved for SEEPROM access ,as by fw
+ twi_page_size = 0;
+ twi_addr_size = 1;
+ twi_busno = ioctl_payload->bus;
nvmd_req.reserved[0] = cpu_to_le32(0xFEDCBA98);
- nvmd_req.len_ir_vpdd = cpu_to_le32(IPMode | twi_addr << 16 |
- twi_page_size << 8 | TWI_DEVICE);
- nvmd_req.resp_len = cpu_to_le32(ioctl_payload->wr_length);
- nvmd_req.resp_addr_hi =
- cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
- nvmd_req.resp_addr_lo =
- cpu_to_le32(pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+ nvmd_req.len_ir_vpdd = cpu_to_le32(addr_mode | (tr << 29) |
+ twi_addr << 16 | twi_busno << 12 |
+ twi_page_size << 8 | twi_addr_size << 4 |
+ TWI_DEVICE);
+ nvmd_req.vpd_offset = cpu_to_le32(d_len << 24 |
+ ioctl_payload->offset);
+ nvmd_req.resp_len = cpu_to_le32(ipdl);
+
+ if (addr_mode == IPMode) {
+ nvmd_req.resp_addr_hi = cpu_to_le32
+ (pm8001_ha->memoryMap.region[NVMD].phys_addr_hi);
+ nvmd_req.resp_addr_lo = cpu_to_le32
+ (pm8001_ha->memoryMap.region[NVMD].phys_addr_lo);
+ }
+ nvmd_req.tr_dl = cpu_to_le32(tr_dl);
break;
}
case C_SEEPROM:
diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h
index aad2322467d2..98e9ea6a4d6e 100644
--- a/drivers/scsi/pm8001/pm8001_hwi.h
+++ b/drivers/scsi/pm8001/pm8001_hwi.h
@@ -634,6 +634,7 @@ struct set_nvm_data_req {
__le32 resp_addr_hi;
__le32 resp_len;
u32 reserved1;
+ __le32 tr_dl;
} __attribute__((packed, aligned(4)));
diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c
index 6e037638656d..61fb9f622a5d 100644
--- a/drivers/scsi/pm8001/pm8001_init.c
+++ b/drivers/scsi/pm8001/pm8001_init.c
@@ -55,6 +55,14 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n"
" 4: Link rate 6.0G\n"
" 8: Link rate 12.0G\n");
+static ulong twi_address = 0xa0;
+module_param(twi_address, ulong, 0644);
+MODULE_PARM_DESC(twi_address, "set the address of twi device.");
+
+static ulong twi_page_size;
+module_param(twi_page_size, ulong, 0644);
+MODULE_PARM_DESC(twi_page_size, "set the page size of twi device.");
+
static struct scsi_transport_template *pm8001_stt;
/**
@@ -484,6 +492,8 @@ 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->twi_address = twi_address;
+ pm8001_ha->twi_page_size = twi_page_size;
pm8001_ha->non_fatal_count = 0;
if (link_rate >= 1 && link_rate <= 15)
pm8001_ha->link_rate = (link_rate << 8);
diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h
index 13d7813b8d74..9074c3a14120 100644
--- a/drivers/scsi/pm8001/pm8001_sas.h
+++ b/drivers/scsi/pm8001/pm8001_sas.h
@@ -169,6 +169,9 @@ struct pm8001_ioctl_payload {
u16 id;
u32 wr_length;
u32 rd_length;
+ bool twi_direct_addr;
+ u8 bus;
+ u8 twi_addr;
u8 *func_specific;
};
@@ -586,6 +589,8 @@ struct pm8001_hba_info {
#endif
u32 logging_level;
u32 link_rate;
+ u32 twi_address;
+ u32 twi_page_size;
u32 fw_status;
u32 smp_exp_mode;
bool controller_fatal_error;
@@ -648,6 +653,11 @@ struct pm8001_fw_image_header {
#define DS_IN_ERROR 0x04
#define DS_NON_OPERATIONAL 0x07
+#define TR_MASK 0x60000000
+#define TW_WRITE 0x01
+#define TW_READ 0x02
+#define TW_WRITE_READ 0x03
+
/**
* brief param structure for firmware flash update.
*/
@@ -794,6 +804,9 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev,
ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
struct device_attribute *attr, char *buf);
ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
+int pm80xx_twi_wr_request(struct pm8001_hba_info *pm8001_ha, int bus, int addr,
+ bool addr_mode_7bit, int rd_size, int wr_size,
+ int offset, bool direct_addr, unsigned char *buf);
/* ctl shared API */
extern struct device_attribute *pm8001_host_attrs[];
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c
index a4e265292d17..767914688b8a 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.c
+++ b/drivers/scsi/pm8001/pm80xx_hwi.c
@@ -46,6 +46,47 @@
#define SMP_DIRECT 1
#define SMP_INDIRECT 2
+int pm80xx_twi_wr_request(struct pm8001_hba_info *pm8001_ha, int bus, int addr,
+ bool addr_mode_7bit, int rd_size, int wr_size,
+ int offset, bool direct_addr, unsigned char *buf)
+{
+ struct pm8001_ioctl_payload *payload;
+ u8 *ioctlbuffer = NULL;
+ int length, ret;
+ DECLARE_COMPLETION_ONSTACK(completion);
+
+ if ((wr_size > 48 || rd_size > 48) && direct_addr == true) {
+ PM8001_FAIL_DBG(pm8001_ha, pm8001_printk
+ ("Direct addressing mode used if payload size < 48\n"));
+ return -EINVAL;
+ }
+
+ length = sizeof(*payload);
+ ioctlbuffer = kzalloc(length, GFP_KERNEL);
+ if (!ioctlbuffer)
+ return -ENOMEM;
+ payload = (struct pm8001_ioctl_payload *)ioctlbuffer;
+
+ pm8001_ha->nvmd_completion = &completion;
+ payload->minor_function = 0;
+
+ payload->rd_length = rd_size;
+ payload->wr_length = wr_size;
+ payload->bus = bus;
+ payload->twi_addr = addr;
+ payload->twi_direct_addr = direct_addr;
+ payload->offset = offset;
+
+ payload->func_specific = buf;
+
+ ret = PM8001_CHIP_DISP->set_nvmd_req(pm8001_ha, payload);
+
+ wait_for_completion(&completion);
+
+ kfree(ioctlbuffer);
+
+ return ret;
+}
int pm80xx_bar4_shift(struct pm8001_hba_info *pm8001_ha, u32 shift_value)
{
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h
index 2d7f67b1cd93..ba49d0abd6f4 100644
--- a/drivers/scsi/pm8001/pm80xx_hwi.h
+++ b/drivers/scsi/pm8001/pm80xx_hwi.h
@@ -966,6 +966,7 @@ struct set_nvm_data_req {
__le32 resp_addr_hi;
__le32 resp_len;
u32 reserved1[17];
+ __le32 tr_dl;
} __attribute__((packed, aligned(4)));
/**
--
2.16.3
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
@ 2020-01-17 14:08 ` Jinpu Wang
2020-01-17 15:50 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 14:08 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Peter Chang <dpf@google.com>
>
> Increasing the per-request size maximum (max_sectors_kb) runs into
> the per-device dma scatter gather list limit (max_segments) for
> users of the io vector system calls (eg, readv and writev). This is
> because the kernel combines io vectors into dma segments when
> possible, but it doesn't work for our user because the vectors in the
> buffer cache get scrambled.
> This change bumps the advertised max scatter gather length to 528 to
> cover 2M w/ x86's 4k pages and some extra for the user checksum.
> It trims the size of some of the tables we don't care about and
> exposes all of the command slots upstream to the scsi layer
>
> Signed-off-by: Peter Chang <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
> Reported-by: kbuild test robot <lkp@intel.com>
> ---
> drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> drivers/scsi/pm8001/pm8001_init.c | 2 +-
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h
> index 48e0624ecc68..1c7f15fd69ce 100644
> --- a/drivers/scsi/pm8001/pm8001_defs.h
> +++ b/drivers/scsi/pm8001/pm8001_defs.h
> @@ -75,7 +75,7 @@ enum port_type {
> };
>
> /* driver compile-time configuration */
> -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> +#define PM8001_MAX_CCB 256 /* max ccbs supported */
Hi Deepack,
Why do you reduce PM8001_MAX_CCB?
The patch itself looks fine.
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-17 7:19 ` [PATCH V2 05/13] pm80xx : Support for char device Deepak Ukey
@ 2020-01-17 14:15 ` Jinpu Wang
2020-01-21 0:24 ` Martin K. Petersen
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 14:15 UTC (permalink / raw)
To: Deepak Ukey, Martin K. Petersen, James E.J. Bottomley
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, yuuzheng, Vikram Auradkar, vishakhavc, bjashnani,
Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Deepak Ukey <Deepak.Ukey@microchip.com>
>
> Added the support to register the char device for pm80xx module so that
> management utility fetch the different information from driver with the
> help of IOCTL. Also added the IOCTL functionality to get driver info so
> that management utility can fetch the information about driver like
> driver name, driver major number, driver minor number and build number.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
Thanks for the commit message, looks much better. In the past, people
are against IOCTL, suggesting netlink,
have you considered that?
Martin, James, what do you think?
Regards,
Jack
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys.
2020-01-17 7:19 ` [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys Deepak Ukey
@ 2020-01-17 14:21 ` Jinpu Wang
2020-01-20 4:50 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 14:21 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Viswas G <Viswas.G@microchip.com>
>
> Added sysfs attribute to show number of phys.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
I agree with John Gary, the mgmt tool can get the info from
/sys/class/sas_phy, no need to add an extra sysfs.
I suggest dropping the patch.
Thanks!
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump.
2020-01-17 7:19 ` [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump Deepak Ukey
@ 2020-01-17 14:26 ` Jinpu Wang
0 siblings, 0 replies; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 14:26 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Deepak Ukey <Deepak.Ukey@microchip.com>
>
> Added the sysfs attribute for non fatal log so that management utility
> can get the non fatal dump from driver. The non-fatal error is an error
> condition or abnormal behavior detected by the host, or detected and
> reported by the controller to the host.The non-fatal error does not stop
> the controller firmware and enables it to still respond to host requests.
> A typical example of a non-fatal error is an I/O timeout or an unusual
> error notification from the controller. Since the firmware is operational,
> the error dump information is pushed to host memory (by firmware) upon
> request from the host.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status.
2020-01-17 7:19 ` [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status Deepak Ukey
@ 2020-01-17 14:35 ` Jinpu Wang
0 siblings, 0 replies; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 14:35 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
> struct pm8001_chip_info {
> @@ -560,6 +563,10 @@ struct pm8001_hba_info {
> bool controller_fatal_error;
> const struct firmware *fw_image;
> struct isr_param irq_vector[PM8001_MAX_MSIX_VEC];
> + spinlock_t ioctl_lock;
> + struct mutex ioctl_mutex;
did you ever initial both lock? why do you need both? I failed to find them.
> + struct completion *ioctl_completion;
> + struct phy_prof_resp phy_profile_resp;
> u32 reset_in_progress;
> };
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-17 14:08 ` Jinpu Wang
@ 2020-01-17 15:50 ` Deepak.Ukey
2020-01-17 15:53 ` Jinpu Wang
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-17 15:50 UTC (permalink / raw)
To: jinpu.wang
Cc: linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Peter Chang <dpf@google.com>
>
> Increasing the per-request size maximum (max_sectors_kb) runs into the
> per-device dma scatter gather list limit (max_segments) for users of
> the io vector system calls (eg, readv and writev). This is because the
> kernel combines io vectors into dma segments when possible, but it
> doesn't work for our user because the vectors in the buffer cache get
> scrambled.
> This change bumps the advertised max scatter gather length to 528 to
> cover 2M w/ x86's 4k pages and some extra for the user checksum.
> It trims the size of some of the tables we don't care about and
> exposes all of the command slots upstream to the scsi layer
>
> Signed-off-by: Peter Chang <dpf@google.com>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
> Reported-by: kbuild test robot <lkp@intel.com>
> ---
> drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> drivers/scsi/pm8001/pm8001_init.c | 2 +-
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> b/drivers/scsi/pm8001/pm8001_defs.h
> index 48e0624ecc68..1c7f15fd69ce 100644
> --- a/drivers/scsi/pm8001/pm8001_defs.h
> +++ b/drivers/scsi/pm8001/pm8001_defs.h
> @@ -75,7 +75,7 @@ enum port_type {
> };
>
> /* driver compile-time configuration */
> -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> +#define PM8001_MAX_CCB 256 /* max ccbs supported */
Hi Deepack,
Why do you reduce PM8001_MAX_CCB?
--- PM8001 driver has a memory limit in the machine. If we increase the sg length, we need to trade-off it by decreasing PM8001_MAX_CCB. PM8001_MAX_CCB = 256 does not have any influence on normal use.
The patch itself looks fine.
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-17 15:50 ` Deepak.Ukey
@ 2020-01-17 15:53 ` Jinpu Wang
2020-01-20 4:20 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-01-17 15:53 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 4:50 PM <Deepak.Ukey@microchip.com> wrote:
>
> On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> >
> > From: Peter Chang <dpf@google.com>
> >
> > Increasing the per-request size maximum (max_sectors_kb) runs into the
> > per-device dma scatter gather list limit (max_segments) for users of
> > the io vector system calls (eg, readv and writev). This is because the
> > kernel combines io vectors into dma segments when possible, but it
> > doesn't work for our user because the vectors in the buffer cache get
> > scrambled.
> > This change bumps the advertised max scatter gather length to 528 to
> > cover 2M w/ x86's 4k pages and some extra for the user checksum.
> > It trims the size of some of the tables we don't care about and
> > exposes all of the command slots upstream to the scsi layer
> >
> > Signed-off-by: Peter Chang <dpf@google.com>
> > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > Signed-off-by: Radha Ramachandran <radha@google.com>
> > Reported-by: kbuild test robot <lkp@intel.com>
> > ---
> > drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> > drivers/scsi/pm8001/pm8001_init.c | 2 +-
> > 2 files changed, 4 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> > b/drivers/scsi/pm8001/pm8001_defs.h
> > index 48e0624ecc68..1c7f15fd69ce 100644
> > --- a/drivers/scsi/pm8001/pm8001_defs.h
> > +++ b/drivers/scsi/pm8001/pm8001_defs.h
> > @@ -75,7 +75,7 @@ enum port_type {
> > };
> >
> > /* driver compile-time configuration */
> > -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> > +#define PM8001_MAX_CCB 256 /* max ccbs supported */
> Hi Deepack,
>
> Why do you reduce PM8001_MAX_CCB?
> --- PM8001 driver has a memory limit in the machine.
which limit, do you see allocation failure from kernel?
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-17 15:53 ` Jinpu Wang
@ 2020-01-20 4:20 ` Deepak.Ukey
2020-01-20 8:47 ` Jinpu Wang
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-20 4:20 UTC (permalink / raw)
To: jinpu.wang
Cc: linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On Fri, Jan 17, 2020 at 4:50 PM <Deepak.Ukey@microchip.com> wrote:
>
> On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> >
> > From: Peter Chang <dpf@google.com>
> >
> > Increasing the per-request size maximum (max_sectors_kb) runs into
> > the per-device dma scatter gather list limit (max_segments) for
> > users of the io vector system calls (eg, readv and writev). This is
> > because the kernel combines io vectors into dma segments when
> > possible, but it doesn't work for our user because the vectors in
> > the buffer cache get scrambled.
> > This change bumps the advertised max scatter gather length to 528 to
> > cover 2M w/ x86's 4k pages and some extra for the user checksum.
> > It trims the size of some of the tables we don't care about and
> > exposes all of the command slots upstream to the scsi layer
> >
> > Signed-off-by: Peter Chang <dpf@google.com>
> > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > Signed-off-by: Radha Ramachandran <radha@google.com>
> > Reported-by: kbuild test robot <lkp@intel.com>
> > ---
> > drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> > drivers/scsi/pm8001/pm8001_init.c | 2 +-
> > 2 files changed, 4 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> > b/drivers/scsi/pm8001/pm8001_defs.h
> > index 48e0624ecc68..1c7f15fd69ce 100644
> > --- a/drivers/scsi/pm8001/pm8001_defs.h
> > +++ b/drivers/scsi/pm8001/pm8001_defs.h
> > @@ -75,7 +75,7 @@ enum port_type {
> > };
> >
> > /* driver compile-time configuration */
> > -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> > +#define PM8001_MAX_CCB 256 /* max ccbs supported */
> Hi Deepack,
>
> Why do you reduce PM8001_MAX_CCB?
> --- PM8001 driver has a memory limit in the machine.
which limit, do you see allocation failure from kernel?
-- I think it depends on machine's capability. For our machines, PM8001_MAX_CCB = 512 caused kernel installation failure. I saw it when I was debugging ncq feature
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys.
2020-01-17 14:21 ` Jinpu Wang
@ 2020-01-20 4:50 ` Deepak.Ukey
2020-01-21 7:55 ` Jinpu Wang
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-20 4:50 UTC (permalink / raw)
To: jinpu.wang
Cc: linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Viswas G <Viswas.G@microchip.com>
>
> Added sysfs attribute to show number of phys.
>
> Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> Signed-off-by: Viswas G <Viswas.G@microchip.com>
> Signed-off-by: Radha Ramachandran <radha@google.com>
I agree with John Gary, the mgmt tool can get the info from /sys/class/sas_phy, no need to add an extra sysfs.
I suggest dropping the patch.
> We have HBA application already in use by customer which uses this sysfs entry. So is it fine to keep this patch?
Thanks!
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-20 4:20 ` Deepak.Ukey
@ 2020-01-20 8:47 ` Jinpu Wang
2020-01-29 9:02 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-01-20 8:47 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Mon, Jan 20, 2020 at 5:20 AM <Deepak.Ukey@microchip.com> wrote:
>
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> On Fri, Jan 17, 2020 at 4:50 PM <Deepak.Ukey@microchip.com> wrote:
> >
> > On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> > >
> > > From: Peter Chang <dpf@google.com>
> > >
> > > Increasing the per-request size maximum (max_sectors_kb) runs into
> > > the per-device dma scatter gather list limit (max_segments) for
> > > users of the io vector system calls (eg, readv and writev). This is
> > > because the kernel combines io vectors into dma segments when
> > > possible, but it doesn't work for our user because the vectors in
> > > the buffer cache get scrambled.
> > > This change bumps the advertised max scatter gather length to 528 to
> > > cover 2M w/ x86's 4k pages and some extra for the user checksum.
> > > It trims the size of some of the tables we don't care about and
> > > exposes all of the command slots upstream to the scsi layer
> > >
> > > Signed-off-by: Peter Chang <dpf@google.com>
> > > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > > Signed-off-by: Radha Ramachandran <radha@google.com>
> > > Reported-by: kbuild test robot <lkp@intel.com>
> > > ---
> > > drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> > > drivers/scsi/pm8001/pm8001_init.c | 2 +-
> > > 2 files changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> > > b/drivers/scsi/pm8001/pm8001_defs.h
> > > index 48e0624ecc68..1c7f15fd69ce 100644
> > > --- a/drivers/scsi/pm8001/pm8001_defs.h
> > > +++ b/drivers/scsi/pm8001/pm8001_defs.h
> > > @@ -75,7 +75,7 @@ enum port_type {
> > > };
> > >
> > > /* driver compile-time configuration */
> > > -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> > > +#define PM8001_MAX_CCB 256 /* max ccbs supported */
> > Hi Deepack,
> >
> > Why do you reduce PM8001_MAX_CCB?
> > --- PM8001 driver has a memory limit in the machine.
> which limit, do you see allocation failure from kernel?
> -- I think it depends on machine's capability. For our machines, PM8001_MAX_CCB = 512 caused kernel installation failure. I saw it when I was debugging ncq feature
> Thanks
Ok, would be helpful to put this info to commit message.
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-17 14:15 ` Jinpu Wang
@ 2020-01-21 0:24 ` Martin K. Petersen
2020-01-21 5:33 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: Martin K. Petersen @ 2020-01-21 0:24 UTC (permalink / raw)
To: Jinpu Wang
Cc: Deepak Ukey, Martin K. Petersen, James E.J. Bottomley,
Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, yuuzheng, Vikram Auradkar, vishakhavc, bjashnani,
Radha Ramachandran, akshatzen
Jinpu,
> Thanks for the commit message, looks much better. In the past, people
> are against IOCTL, suggesting netlink, have you considered that?
Not so keen on adding more ioctls. It's 2020 and all...
Given the nature of the exported information, what's wrong with putting
it in sysfs?
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-21 0:24 ` Martin K. Petersen
@ 2020-01-21 5:33 ` Deepak.Ukey
2020-01-21 12:39 ` John Garry
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-21 5:33 UTC (permalink / raw)
To: martin.petersen, jinpu.wang
Cc: jejb, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani, radha,
akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
Martin,
> Thanks for the commit message, looks much better. In the past, people
> are against IOCTL, suggesting netlink, have you considered that?
Not so keen on adding more ioctls. It's 2020 and all...
Given the nature of the exported information, what's wrong with putting it in sysfs?
-- We have some upcoming patches which uses this IOCTL interface and that cannot be supported through sysfs.
Below are the patches in this patchset which requires IOCTL interface.
0007-pm80xx-IOCTL-functionality-to-get-phy-status
0008-pm80xx-IOCTL-functionality-to-get-phy-error
0009-pm80xx-IOCTL-functionality-for-GPIO
0010-pm80xx-IOCTL-functionality-for-SGPIO
0013-pm80xx-IOCTL-functionality-for-TWI-device
Regards,
Deepak
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys.
2020-01-20 4:50 ` Deepak.Ukey
@ 2020-01-21 7:55 ` Jinpu Wang
0 siblings, 0 replies; 38+ messages in thread
From: Jinpu Wang @ 2020-01-21 7:55 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Mon, Jan 20, 2020 at 5:50 AM <Deepak.Ukey@microchip.com> wrote:
>
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> >
> > From: Viswas G <Viswas.G@microchip.com>
> >
> > Added sysfs attribute to show number of phys.
> >
> > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > Signed-off-by: Radha Ramachandran <radha@google.com>
> I agree with John Gary, the mgmt tool can get the info from /sys/class/sas_phy, no need to add an extra sysfs.
>
> I suggest dropping the patch.
> > We have HBA application already in use by customer which uses this sysfs entry. So is it fine to keep this patch?
> Thanks!
How much effort to convert the HBA application to use general sas_phy
information? IMHO converting HBA application to use general interface
is the right way to go.
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-21 5:33 ` Deepak.Ukey
@ 2020-01-21 12:39 ` John Garry
2020-01-22 8:50 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: John Garry @ 2020-01-21 12:39 UTC (permalink / raw)
To: Deepak.Ukey, martin.petersen, jinpu.wang
Cc: jejb, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani, radha,
akshatzen
On 21/01/2020 05:33, Deepak.Ukey@microchip.com wrote:
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> Martin,
>
>> Thanks for the commit message, looks much better. In the past, people
>> are against IOCTL, suggesting netlink, have you considered that?
>
> Not so keen on adding more ioctls. It's 2020 and all...
>
> Given the nature of the exported information, what's wrong with putting it in sysfs?
> -- We have some upcoming patches which uses this IOCTL interface and that cannot be supported through sysfs.
> Below are the patches in this patchset which requires IOCTL interface.
> 0007-pm80xx-IOCTL-functionality-to-get-phy-status
> 0008-pm80xx-IOCTL-functionality-to-get-phy-error
Please note that there definitely seems to be replication of what sysfs
already provides in some of these patches:
- 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like
Programmed Link Rate, Negotiated Link Rate, PHY Identifier
- 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things
like Invalid Dword Error Count, Disparity Error Count
See ***:
root@ubuntu:/sys/class/sas_phy/phy-0:0# ls -l
total 0
lrwxrwxrwx 1 root root 0 Jan 21 12:05 device -> ../../../phy-0:0
-r--r--r-- 1 root root 4096 Jan 21 12:05 device_type
-rw-r--r-- 1 root root 4096 Jan 21 12:05 enable ***
--w------- 1 root root 4096 Jan 21 12:05 hard_reset
-r--r--r-- 1 root root 4096 Jan 21 12:05 initiator_port_protocols
-r--r--r-- 1 root root 4096 Jan 21 12:05 invalid_dword_count ***
--w------- 1 root root 4096 Jan 21 12:05 link_reset
-r--r--r-- 1 root root 4096 Jan 21 12:05 loss_of_dword_sync_count ***
-rw-r--r-- 1 root root 4096 Jan 21 12:05 maximum_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 maximum_linkrate_hw ***
-rw-r--r-- 1 root root 4096 Jan 21 12:05 minimum_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 minimum_linkrate_hw ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 negotiated_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 11:58 phy_identifier ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 phy_reset_problem_count ***
drwxr-xr-x 2 root root 0 Jan 21 12:05 power
-r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
../../../../../../../class/sas_phy
-r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
-rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
Maybe the other stuff provided in the patches are useful, I don't know.
But debugfs seems better for that.
> 0009-pm80xx-IOCTL-functionality-for-GPIO
> 0010-pm80xx-IOCTL-functionality-for-SGPIO
I don't know why an ioctl is required here.
> 0013-pm80xx-IOCTL-functionality-for-TWI-device
Thanks,
John
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-21 12:39 ` John Garry
@ 2020-01-22 8:50 ` Deepak.Ukey
2020-01-22 12:38 ` John Garry
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-22 8:50 UTC (permalink / raw)
To: john.garry, martin.petersen, jinpu.wang
Cc: jejb, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani, radha,
akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On 21/01/2020 05:33, Deepak.Ukey@microchip.com wrote:
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know
> the content is safe
>
> Martin,
>
>> Thanks for the commit message, looks much better. In the past, people
>> are against IOCTL, suggesting netlink, have you considered that?
>
> Not so keen on adding more ioctls. It's 2020 and all...
>
> Given the nature of the exported information, what's wrong with putting it in sysfs?
> -- We have some upcoming patches which uses this IOCTL interface and that cannot be supported through sysfs.
> Below are the patches in this patchset which requires IOCTL interface.
> 0007-pm80xx-IOCTL-functionality-to-get-phy-status
> 0008-pm80xx-IOCTL-functionality-to-get-phy-error
Please note that there definitely seems to be replication of what sysfs already provides in some of these patches:
- 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
- 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
See ***:
root@ubuntu:/sys/class/sas_phy/phy-0:0# ls -l total 0
lrwxrwxrwx 1 root root 0 Jan 21 12:05 device -> ../../../phy-0:0
-r--r--r-- 1 root root 4096 Jan 21 12:05 device_type
-rw-r--r-- 1 root root 4096 Jan 21 12:05 enable ***
--w------- 1 root root 4096 Jan 21 12:05 hard_reset
-r--r--r-- 1 root root 4096 Jan 21 12:05 initiator_port_protocols
-r--r--r-- 1 root root 4096 Jan 21 12:05 invalid_dword_count ***
--w------- 1 root root 4096 Jan 21 12:05 link_reset
-r--r--r-- 1 root root 4096 Jan 21 12:05 loss_of_dword_sync_count ***
-rw-r--r-- 1 root root 4096 Jan 21 12:05 maximum_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 maximum_linkrate_hw ***
-rw-r--r-- 1 root root 4096 Jan 21 12:05 minimum_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 minimum_linkrate_hw ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 negotiated_linkrate ***
-r--r--r-- 1 root root 4096 Jan 21 11:58 phy_identifier ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 phy_reset_problem_count ***
drwxr-xr-x 2 root root 0 Jan 21 12:05 power
-r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count ***
-r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
../../../../../../../class/sas_phy
-r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
-rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
Maybe the other stuff provided in the patches are useful, I don't know.
But debugfs seems better for that.
- 0006-pm80xx-sysfs-attribute-for-number-of-phys
- 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
- 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
- Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
> 0009-pm80xx-IOCTL-functionality-for-GPIO
> 0010-pm80xx-IOCTL-functionality-for-SGPIO
I don't know why an ioctl is required here.
> 0013-pm80xx-IOCTL-functionality-for-TWI-device
- 0009-pm80xx-IOCTL-functionality-for-GPIO
- 0010-pm80xx-IOCTL-functionality-for-SGPIO
- 0013-pm80xx-IOCTL-functionality-for-TWI-device
- For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
Regards,
Deepak
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO.
2020-01-17 7:19 ` [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO Deepak Ukey
@ 2020-01-22 8:59 ` Jinpu Wang
0 siblings, 0 replies; 38+ messages in thread
From: Jinpu Wang @ 2020-01-22 8:59 UTC (permalink / raw)
To: Deepak Ukey
Cc: Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, Martin K. Petersen, yuuzheng, Vikram Auradkar,
vishakhavc, bjashnani, Radha Ramachandran, akshatzen
On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
>
> From: Deepak Ukey <Deepak.Ukey@microchip.com>
>
> Added the IOCTL functionality for SGPIO through which management
> utility can controls SGPIO LEDs on the enclosure of locally attached
> drives only. It is used to read from/write into SGPIO registers and
> sets one or more SGPIO registers.
Hi,
Thanks for addressing my comments.
another question:
Is it enough to only hook lldd_write_gpio without IOCTL to control SGPIO LED?
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-22 8:50 ` Deepak.Ukey
@ 2020-01-22 12:38 ` John Garry
2020-01-28 9:43 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: John Garry @ 2020-01-22 12:38 UTC (permalink / raw)
To: Deepak.Ukey, martin.petersen, jinpu.wang
Cc: jejb, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani, radha,
akshatzen
On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
> -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count ***
> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
> ../../../../../../../class/sas_phy
> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
>
> Maybe the other stuff provided in the patches are useful, I don't know.
> But debugfs seems better for that.
>
> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
>
> > 0009-pm80xx-IOCTL-functionality-for-GPIO
> > 0010-pm80xx-IOCTL-functionality-for-SGPIO
>
> I don't know why an ioctl is required here.
>
> > 0013-pm80xx-IOCTL-functionality-for-TWI-device
>
> - 0009-pm80xx-IOCTL-functionality-for-GPIO
> - 0010-pm80xx-IOCTL-functionality-for-SGPIO
> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
So I specifically questioned the SGPIO patch and why it would have an
IOCTL, as this function is supported in kernel libsas/SAS transport code
as an SMP function.
For the GPIO IOCTL, could you use register a gpio driver to provide a
gpiolib sysfs?
As for TWI, it seems to be for serial EEPROM, so you could ask these
experts about how to handle it properly in the kernel for standard sysfs
interfaces:
:~/linux$ ./scripts/get_maintainer.pl -f drivers/misc/eeprom/eeprom.c
Jean Delvare <jdelvare@suse.com> (maintainer:LEGACY EEPROM DRIVER)
Arnd Bergmann <arnd@arndb.de> (supporter:CHAR and MISC DRIVERS)
Greg Kroah-Hartman <gregkh@linuxfoundation.org> (supporter:CHAR and MISC
DRIVERS)
Thanks,
John
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-22 12:38 ` John Garry
@ 2020-01-28 9:43 ` Deepak.Ukey
2020-03-11 17:08 ` Jinpu Wang
0 siblings, 1 reply; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-28 9:43 UTC (permalink / raw)
To: john.garry, martin.petersen, jinpu.wang
Cc: jejb, linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G,
jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani, radha,
akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
> -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count
> ***
> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
> ../../../../../../../class/sas_phy
> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
>
> Maybe the other stuff provided in the patches are useful, I don't know.
> But debugfs seems better for that.
>
> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
>
> > 0009-pm80xx-IOCTL-functionality-for-GPIO
> > 0010-pm80xx-IOCTL-functionality-for-SGPIO
>
> I don't know why an ioctl is required here.
>
> > 0013-pm80xx-IOCTL-functionality-for-TWI-device
>
> - 0009-pm80xx-IOCTL-functionality-for-GPIO
> - 0010-pm80xx-IOCTL-functionality-for-SGPIO
> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
> Thank you for your suggestions. We will make use of function supported in libsas.
For the GPIO IOCTL, could you use register a gpio driver to provide a gpiolib sysfs?
> We cannot use GPIO driver to provide gpiolib sysfs. There are 24 GPIO signals pin provided by the SPCV controller out of which 16 signals pin are used by customer. The host application perform different operations on that pins for example pin setup, event setup and read/write GPIO pins.
> For this, applications passes different combination of values to execute the specific operation with help of a payload structure and application passes that structure to driver using IOCTL.
> Driver fetch the information like input enable pin setup, typepart1/typepart2 pin setup, gpio event level setup, gpio rising / falling edge setup, gpio pin mask setup passed by application and then send with specific command format to execute the gpio operation.
As for TWI, it seems to be for serial EEPROM, so you could ask these experts about how to handle it properly in the kernel for standard sysfs
interfaces:
> Driver supports different TWI devices not limited to the Serial EEPROM. Application passes the address of the attached TWI device to read and write the TWI binary along with the payload structure which contains information like offset, address mode, read/write size.
> Drivers fetch the information passed by application and then send with specific command format to execute operation.
:~/linux$ ./scripts/get_maintainer.pl -f drivers/misc/eeprom/eeprom.c Jean Delvare <jdelvare@suse.com> (maintainer:LEGACY EEPROM DRIVER) Arnd Bergmann <arnd@arndb.de> (supporter:CHAR and MISC DRIVERS) Greg Kroah-Hartman <gregkh@linuxfoundation.org> (supporter:CHAR and MISC
DRIVERS)
Thanks,
Deepak
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 01/13] pm80xx : Increase request sg length.
2020-01-20 8:47 ` Jinpu Wang
@ 2020-01-29 9:02 ` Deepak.Ukey
0 siblings, 0 replies; 38+ messages in thread
From: Deepak.Ukey @ 2020-01-29 9:02 UTC (permalink / raw)
To: jinpu.wang
Cc: linux-scsi, Vasanthalakshmi.Tharmarajan, Viswas.G, jinpu.wang,
martin.petersen, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On Mon, Jan 20, 2020 at 5:20 AM <Deepak.Ukey@microchip.com> wrote:
>
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know
> the content is safe
>
> On Fri, Jan 17, 2020 at 4:50 PM <Deepak.Ukey@microchip.com> wrote:
> >
> > On Fri, Jan 17, 2020 at 8:10 AM Deepak Ukey <deepak.ukey@microchip.com> wrote:
> > >
> > > From: Peter Chang <dpf@google.com>
> > >
> > > Increasing the per-request size maximum (max_sectors_kb) runs into
> > > the per-device dma scatter gather list limit (max_segments) for
> > > users of the io vector system calls (eg, readv and writev). This
> > > is because the kernel combines io vectors into dma segments when
> > > possible, but it doesn't work for our user because the vectors in
> > > the buffer cache get scrambled.
> > > This change bumps the advertised max scatter gather length to 528
> > > to cover 2M w/ x86's 4k pages and some extra for the user checksum.
> > > It trims the size of some of the tables we don't care about and
> > > exposes all of the command slots upstream to the scsi layer
> > >
> > > Signed-off-by: Peter Chang <dpf@google.com>
> > > Signed-off-by: Deepak Ukey <deepak.ukey@microchip.com>
> > > Signed-off-by: Viswas G <Viswas.G@microchip.com>
> > > Signed-off-by: Radha Ramachandran <radha@google.com>
> > > Reported-by: kbuild test robot <lkp@intel.com>
> > > ---
> > > drivers/scsi/pm8001/pm8001_defs.h | 5 +++--
> > > drivers/scsi/pm8001/pm8001_init.c | 2 +-
> > > 2 files changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/drivers/scsi/pm8001/pm8001_defs.h
> > > b/drivers/scsi/pm8001/pm8001_defs.h
> > > index 48e0624ecc68..1c7f15fd69ce 100644
> > > --- a/drivers/scsi/pm8001/pm8001_defs.h
> > > +++ b/drivers/scsi/pm8001/pm8001_defs.h
> > > @@ -75,7 +75,7 @@ enum port_type { };
> > >
> > > /* driver compile-time configuration */
> > > -#define PM8001_MAX_CCB 512 /* max ccbs supported */
> > > +#define PM8001_MAX_CCB 256 /* max ccbs supported */
> > Hi Deepack,
> >
> > Why do you reduce PM8001_MAX_CCB?
> > --- PM8001 driver has a memory limit in the machine.
> which limit, do you see allocation failure from kernel?
> -- I think it depends on machine's capability. For our machines,
> PM8001_MAX_CCB = 512 caused kernel installation failure. I saw it when
> I was debugging ncq feature Thanks
Ok, would be helpful to put this info to commit message.
> Thanks. I will add this in version 3 of the patchest.
Thanks
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-01-28 9:43 ` Deepak.Ukey
@ 2020-03-11 17:08 ` Jinpu Wang
2020-03-11 22:13 ` Douglas Gilbert
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-03-11 17:08 UTC (permalink / raw)
To: Deepak Ukey
Cc: John Garry, Martin K. Petersen, James E.J. Bottomley,
Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, yuuzheng, Vikram Auradkar, vishakhavc, bjashnani,
Radha Ramachandran, akshatzen
On Tue, Jan 28, 2020 at 10:43 AM <Deepak.Ukey@microchip.com> wrote:
>
>
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
> > -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count
> > ***
> > -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
> > lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
> > ../../../../../../../class/sas_phy
> > -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
> > -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
> >
> > Maybe the other stuff provided in the patches are useful, I don't know.
> > But debugfs seems better for that.
> >
> > - 0006-pm80xx-sysfs-attribute-for-number-of-phys
> > - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
> > - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
> > - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
> >
> >
> > - 0009-pm80xx-IOCTL-functionality-for-GPIO
> > - 0013-pm80xx-IOCTL-functionality-for-TWI-device
> > - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
>
> So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
> > Thank you for your suggestions. We will make use of function supported in libsas.
So basically you only need IOCTL for GPIO and TWI devices, others can
implement via libsas interface or from sysfs directly.
I would like to suggest you do send out other changes without the
IOCTL parts first, and consider again Is it really needed by the user
to control GPIO and TWI, and if there is other way to do it?
Sorry, I don't have a better suggestion!
Regards,
Jack Wang
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-03-11 17:08 ` Jinpu Wang
@ 2020-03-11 22:13 ` Douglas Gilbert
2020-03-12 8:49 ` Jinpu Wang
0 siblings, 1 reply; 38+ messages in thread
From: Douglas Gilbert @ 2020-03-11 22:13 UTC (permalink / raw)
To: Jinpu Wang, Deepak Ukey
Cc: John Garry, Martin K. Petersen, James E.J. Bottomley,
Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, yuuzheng, Vikram Auradkar, vishakhavc, bjashnani,
Radha Ramachandran, akshatzen
On 2020-03-11 1:08 p.m., Jinpu Wang wrote:
> On Tue, Jan 28, 2020 at 10:43 AM <Deepak.Ukey@microchip.com> wrote:
>>
>>
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>
>> On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count
>>> ***
>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
>>> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
>>> ../../../../../../../class/sas_phy
>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
>>> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
>>>
>>> Maybe the other stuff provided in the patches are useful, I don't know.
>>> But debugfs seems better for that.
>>>
>>> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
>>> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
>>> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
>>> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
>>>
>
>>>
>>> - 0009-pm80xx-IOCTL-functionality-for-GPIO
>>> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
>>> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
>>
>> So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
>>> Thank you for your suggestions. We will make use of function supported in libsas.
>
> So basically you only need IOCTL for GPIO and TWI devices, others can
> implement via libsas interface or from sysfs directly.
>
> I would like to suggest you do send out other changes without the
> IOCTL parts first, and consider again Is it really needed by the user
> to control GPIO and TWI, and if there is other way to do it?
>
> Sorry, I don't have a better suggestion!
LSI SAS HBAs (LSI now owned by Broadcom) implement an internal ** SMP
target. It can be seen here:
# ls /dev/bsg
3:0:0:0 3:0:3:0 8:0:0:0 8:0:0:3 end_device-3:1 expander-3:0
3:0:1:0 4:0:0:0 8:0:0:1 8:0:0:4 end_device-3:1:0 expander-3:1
3:0:2:0 7:0:0:0 8:0:0:2 end_device-3:0:1 end_device-3:2 sas_host3
It is the last device node: "sas_host3". How do I know it is a SMP target?
Because this works:
# smp_read_gpio /dev/bsg/sas_host3
Read GPIO register response:
GPIO_CFG[0]:
version: 0
GPIO enable: 1
cfg register count: 2
gp register count: 1
supported drive count: 16
When you work out what LSI are doing with this, perhaps you could write
an article about it and make it publicly available.
It is always a good idea to see how your competitors solve problems :-)
Doug Gilbert
** I call it "internal" because it is not seen when doing a SMP DISCOVER
on a SAS expander to which that SAS HBA is connected.
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-03-11 22:13 ` Douglas Gilbert
@ 2020-03-12 8:49 ` Jinpu Wang
2020-03-12 10:58 ` John Garry
0 siblings, 1 reply; 38+ messages in thread
From: Jinpu Wang @ 2020-03-12 8:49 UTC (permalink / raw)
To: Doug Gilbert, Deepak Ukey
Cc: John Garry, Martin K. Petersen, James E.J. Bottomley,
Linux SCSI Mailinglist, Vasanthalakshmi.Tharmarajan, Viswas G,
Jack Wang, yuuzheng, Vikram Auradkar, vishakhavc, bjashnani,
Radha Ramachandran, akshatzen
On Wed, Mar 11, 2020 at 11:13 PM Douglas Gilbert <dgilbert@interlog.com> wrote:
>
> On 2020-03-11 1:08 p.m., Jinpu Wang wrote:
> > On Tue, Jan 28, 2020 at 10:43 AM <Deepak.Ukey@microchip.com> wrote:
> >>
> >>
> >> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> >>
> >> On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
> >>> -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count
> >>> ***
> >>> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
> >>> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
> >>> ../../../../../../../class/sas_phy
> >>> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
> >>> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
> >>>
> >>> Maybe the other stuff provided in the patches are useful, I don't know.
> >>> But debugfs seems better for that.
> >>>
> >>> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
> >>> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
> >>> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
> >>> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
> >>>
> >
> >>>
> >>> - 0009-pm80xx-IOCTL-functionality-for-GPIO
> >>> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
> >>> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
> >>
> >> So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
> >>> Thank you for your suggestions. We will make use of function supported in libsas.
> >
> > So basically you only need IOCTL for GPIO and TWI devices, others can
> > implement via libsas interface or from sysfs directly.
> >
> > I would like to suggest you do send out other changes without the
> > IOCTL parts first, and consider again Is it really needed by the user
> > to control GPIO and TWI, and if there is other way to do it?
> >
> > Sorry, I don't have a better suggestion!
>
> LSI SAS HBAs (LSI now owned by Broadcom) implement an internal ** SMP
> target. It can be seen here:
>
> # ls /dev/bsg
> 3:0:0:0 3:0:3:0 8:0:0:0 8:0:0:3 end_device-3:1 expander-3:0
> 3:0:1:0 4:0:0:0 8:0:0:1 8:0:0:4 end_device-3:1:0 expander-3:1
> 3:0:2:0 7:0:0:0 8:0:0:2 end_device-3:0:1 end_device-3:2 sas_host3
>
> It is the last device node: "sas_host3". How do I know it is a SMP target?
> Because this works:
>
> # smp_read_gpio /dev/bsg/sas_host3
> Read GPIO register response:
> GPIO_CFG[0]:
> version: 0
> GPIO enable: 1
> cfg register count: 2
> gp register count: 1
> supported drive count: 16
>
> When you work out what LSI are doing with this, perhaps you could write
> an article about it and make it publicly available.
> It is always a good idea to see how your competitors solve problems :-)
This sounds indeed a better solution, thanks for the info, Doug
@Deepak Ukey can you check if you guys can also do it this way?
Regards,
Jack Wang
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH V2 05/13] pm80xx : Support for char device.
2020-03-12 8:49 ` Jinpu Wang
@ 2020-03-12 10:58 ` John Garry
2020-03-16 6:22 ` Deepak.Ukey
0 siblings, 1 reply; 38+ messages in thread
From: John Garry @ 2020-03-12 10:58 UTC (permalink / raw)
To: Jinpu Wang, Doug Gilbert, Deepak Ukey
Cc: Martin K. Petersen, James E.J. Bottomley, Linux SCSI Mailinglist,
Vasanthalakshmi.Tharmarajan, Viswas G, Jack Wang, yuuzheng,
Vikram Auradkar, vishakhavc, bjashnani, Radha Ramachandran,
akshatzen
On 12/03/2020 08:49, Jinpu Wang wrote:
> On Wed, Mar 11, 2020 at 11:13 PM Douglas Gilbert <dgilbert@interlog.com> wrote:
>>
>> On 2020-03-11 1:08 p.m., Jinpu Wang wrote:
>>> On Tue, Jan 28, 2020 at 10:43 AM <Deepak.Ukey@microchip.com> wrote:
>>>>
>>>>
>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>>
>>>> On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 running_disparity_error_count
>>>>> ***
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
>>>>> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
>>>>> ../../../../../../../class/sas_phy
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
>>>>> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
>>>>>
>>>>> Maybe the other stuff provided in the patches are useful, I don't know.
>>>>> But debugfs seems better for that.
>>>>>
>>>>> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
>>>>> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
>>>>> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
>>>>> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
>>>>>
>>>
>>>>>
>>>>> - 0009-pm80xx-IOCTL-functionality-for-GPIO
>>>>> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
>>>>> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
>>>>
>>>> So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
>>>>> Thank you for your suggestions. We will make use of function supported in libsas.
>>>
>>> So basically you only need IOCTL for GPIO and TWI devices, others can
>>> implement via libsas interface or from sysfs directly.
>>>
>>> I would like to suggest you do send out other changes without the
>>> IOCTL parts first, and consider again Is it really needed by the user
>>> to control GPIO and TWI, and if there is other way to do it?
>>>
>>> Sorry, I don't have a better suggestion!
>>
>> LSI SAS HBAs (LSI now owned by Broadcom) implement an internal ** SMP
>> target. It can be seen here:
>>
>> # ls /dev/bsg
>> 3:0:0:0 3:0:3:0 8:0:0:0 8:0:0:3 end_device-3:1 expander-3:0
>> 3:0:1:0 4:0:0:0 8:0:0:1 8:0:0:4 end_device-3:1:0 expander-3:1
>> 3:0:2:0 7:0:0:0 8:0:0:2 end_device-3:0:1 end_device-3:2 sas_host3
>>
>> It is the last device node: "sas_host3". How do I know it is a SMP target?
>> Because this works:
>>
>> # smp_read_gpio /dev/bsg/sas_host3
>> Read GPIO register response:
>> GPIO_CFG[0]:
>> version: 0
>> GPIO enable: 1
>> cfg register count: 2
>> gp register count: 1
>> supported drive count: 16
>>
JFYI, that specific command is not implemented for libsas SMP host
handler (see
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/libsas/sas_host_smp.c?h=v5.6-rc5#n278),
but the write command should be ok
>> When you work out what LSI are doing with this, perhaps you could write
>> an article about it and make it publicly available.
Firmware magic...
>> It is always a good idea to see how your competitors solve problems :-)
> This sounds indeed a better solution, thanks for the info, Doug
>
> @Deepak Ukey can you check if you guys can also do it this way?
>
> Regards,
> Jack Wang
> .
>
^ permalink raw reply [flat|nested] 38+ messages in thread
* RE: [PATCH V2 05/13] pm80xx : Support for char device.
2020-03-12 10:58 ` John Garry
@ 2020-03-16 6:22 ` Deepak.Ukey
0 siblings, 0 replies; 38+ messages in thread
From: Deepak.Ukey @ 2020-03-16 6:22 UTC (permalink / raw)
To: john.garry, jinpu.wang, dgilbert
Cc: martin.petersen, jejb, linux-scsi, Vasanthalakshmi.Tharmarajan,
Viswas.G, jinpu.wang, yuuzheng, auradkar, vishakhavc, bjashnani,
radha, akshatzen
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
On 12/03/2020 08:49, Jinpu Wang wrote:
> On Wed, Mar 11, 2020 at 11:13 PM Douglas Gilbert <dgilbert@interlog.com> wrote:
>>
>> On 2020-03-11 1:08 p.m., Jinpu Wang wrote:
>>> On Tue, Jan 28, 2020 at 10:43 AM <Deepak.Ukey@microchip.com> wrote:
>>>>
>>>>
>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you
>>>> know the content is safe
>>>>
>>>> On 22/01/2020 08:50, Deepak.Ukey@microchip.com wrote:
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05
>>>>> running_disparity_error_count
>>>>> ***
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 sas_address
>>>>> lrwxrwxrwx 1 root root 0 Jan 21 11:45 subsystem ->
>>>>> ../../../../../../../class/sas_phy
>>>>> -r--r--r-- 1 root root 4096 Jan 21 12:05 target_port_protocols
>>>>> -rw-r--r-- 1 root root 4096 Jan 21 11:45 uevent
>>>>>
>>>>> Maybe the other stuff provided in the patches are useful, I don't know.
>>>>> But debugfs seems better for that.
>>>>>
>>>>> - 0006-pm80xx-sysfs-attribute-for-number-of-phys
>>>>> - 0007-pm80xx-IOCTL-functionality-to-get-phy-status gets things like Programmed Link Rate, Negotiated Link Rate, PHY Identifier
>>>>> - 0008-pm80xx-IOCTL-functionality-to-get-phy-error provides other things like Invalid Dword Error Count, Disparity Error Count
>>>>> - Thanks for addressing it. We can get this info from /sys/class/sas_phy and /sys/class/sas_port so we will drop these above mentioned three patches from the next - patch series.
>>>>>
>>>
>>>>>
>>>>> - 0009-pm80xx-IOCTL-functionality-for-GPIO
>>>>> - 0013-pm80xx-IOCTL-functionality-for-TWI-device
>>>>> - For the above patches management utility passes command specific information to driver through IOCTL structure, which used by driver to frame the command and - send to FW. We are using the IOCTL interface for the same. Please let us know your thought.
>>>>
>>>> So I specifically questioned the SGPIO patch and why it would have an IOCTL, as this function is supported in kernel libsas/SAS transport code as an SMP function.
>>>>> Thank you for your suggestions. We will make use of function supported in libsas.
>>>
>>> So basically you only need IOCTL for GPIO and TWI devices, others
>>> can implement via libsas interface or from sysfs directly.
>>>
>>> I would like to suggest you do send out other changes without the
>>> IOCTL parts first, and consider again Is it really needed by the
>>> user to control GPIO and TWI, and if there is other way to do it?
>>>
>>> Sorry, I don't have a better suggestion!
>>
>> LSI SAS HBAs (LSI now owned by Broadcom) implement an internal ** SMP
>> target. It can be seen here:
>>
>> # ls /dev/bsg
>> 3:0:0:0 3:0:3:0 8:0:0:0 8:0:0:3 end_device-3:1 expander-3:0
>> 3:0:1:0 4:0:0:0 8:0:0:1 8:0:0:4 end_device-3:1:0 expander-3:1
>> 3:0:2:0 7:0:0:0 8:0:0:2 end_device-3:0:1 end_device-3:2 sas_host3
>>
>> It is the last device node: "sas_host3". How do I know it is a SMP target?
>> Because this works:
>>
>> # smp_read_gpio /dev/bsg/sas_host3
>> Read GPIO register response:
>> GPIO_CFG[0]:
>> version: 0
>> GPIO enable: 1
>> cfg register count: 2
>> gp register count: 1
>> supported drive count: 16
>>
JFYI, that specific command is not implemented for libsas SMP host handler (see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/scsi/libsas/sas_host_smp.c?h=v5.6-rc5#n278),
but the write command should be ok
>> When you work out what LSI are doing with this, perhaps you could
>> write an article about it and make it publicly available.
Firmware magic...
>> It is always a good idea to see how your competitors solve problems
>> :-)
> This sounds indeed a better solution, thanks for the info, Doug
>
> @Deepak Ukey can you check if you guys can also do it this way?
We are going to submit the version 3 of the patchset without IOCTL patches and in future we will come up with the different solution for IOCTL patches. Also we will go through the solution suggested by Doug.
>
> Regards,
> Deepak
> .
>
^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2020-03-16 6:22 UTC | newest]
Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-17 7:19 [PATCH V2 00/13] pm80xx : Updates for the driver version 0.1.39 Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 01/13] pm80xx : Increase request sg length Deepak Ukey
2020-01-17 14:08 ` Jinpu Wang
2020-01-17 15:50 ` Deepak.Ukey
2020-01-17 15:53 ` Jinpu Wang
2020-01-20 4:20 ` Deepak.Ukey
2020-01-20 8:47 ` Jinpu Wang
2020-01-29 9:02 ` Deepak.Ukey
2020-01-17 7:19 ` [PATCH V2 02/13] pm80xx : Deal with kexec reboots Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 03/13] pm80xx : Free the tag when mpi_set_phy_profile_resp is received Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 04/13] pm80xx : Cleanup initialization loading fail path Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 05/13] pm80xx : Support for char device Deepak Ukey
2020-01-17 14:15 ` Jinpu Wang
2020-01-21 0:24 ` Martin K. Petersen
2020-01-21 5:33 ` Deepak.Ukey
2020-01-21 12:39 ` John Garry
2020-01-22 8:50 ` Deepak.Ukey
2020-01-22 12:38 ` John Garry
2020-01-28 9:43 ` Deepak.Ukey
2020-03-11 17:08 ` Jinpu Wang
2020-03-11 22:13 ` Douglas Gilbert
2020-03-12 8:49 ` Jinpu Wang
2020-03-12 10:58 ` John Garry
2020-03-16 6:22 ` Deepak.Ukey
2020-01-17 7:19 ` [PATCH V2 06/13] pm80xx : sysfs attribute for number of phys Deepak Ukey
2020-01-17 14:21 ` Jinpu Wang
2020-01-20 4:50 ` Deepak.Ukey
2020-01-21 7:55 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 07/13] pm80xx : IOCTL functionality to get phy status Deepak Ukey
2020-01-17 14:35 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 08/13] pm80xx : IOCTL functionality to get phy error Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 09/13] pm80xx : IOCTL functionality for GPIO Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 10/13] pm80xx : IOCTL functionality for SGPIO Deepak Ukey
2020-01-22 8:59 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 11/13] pm80xx : sysfs attribute for non fatal dump Deepak Ukey
2020-01-17 14:26 ` Jinpu Wang
2020-01-17 7:19 ` [PATCH V2 12/13] pm80xx : Introduce read and write length for IOCTL payload structure Deepak Ukey
2020-01-17 7:19 ` [PATCH V2 13/13] pm80xx : IOCTL functionality for TWI device Deepak Ukey
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.