Message ID | 20201230045743.14694-1-Viswas.G@microchip.com.com |
---|---|
Headers | show |
Series | pm80xx updates. | expand |
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: akshatzen <akshatzen@google.com> > > We do not need to busy wait during mpi_init_check. I confirmed that > mpi_init_check is not being invoked in an ATOMIC context. It is being > called from pm8001_pci_resume, pm8001_pci_probe. Hence we are > replacing the udelay which busy waits with msleep. > > Signed-off-by: akshatzen <akshatzen@google.com> > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> > Signed-off-by: Radha Ramachandran <radha@google.com> Thanks akshatzen! Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> > --- > drivers/scsi/pm8001/pm80xx_hwi.c | 6 +++--- > drivers/scsi/pm8001/pm80xx_hwi.h | 4 ++-- > 2 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c > index 6772b0924dac..9c4b8b374ab8 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -997,7 +997,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) > max_wait_count = SPC_DOORBELL_CLEAR_TIMEOUT; > } > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > value = pm8001_cr32(pm8001_ha, 0, MSGU_IBDB_SET); > value &= SPCv_MSGU_CFG_TABLE_UPDATE; > } while ((value != 0) && (--max_wait_count)); > @@ -1010,9 +1010,9 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) > return -EBUSY; > } > /* check the MPI-State for initialization upto 100ms*/ > - max_wait_count = 100 * 1000;/* 100 msec */ > + max_wait_count = 5;/* 100 msec */ > do { > - udelay(1); > + msleep(FW_READY_INTERVAL); > gst_len_mpistate = > pm8001_mr32(pm8001_ha->general_stat_tbl_addr, > GST_GSTLEN_MPIS_OFFSET); > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h > index ec48bc276de6..2b6b52551968 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.h > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h > @@ -220,8 +220,8 @@ > #define SAS_DOPNRJT_RTRY_TMO 128 > #define SAS_COPNRJT_RTRY_TMO 128 > > -#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 1000 * 1000) /* 30 sec */ > -#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 1000 * 1000) /* 15 sec */ > +#define SPCV_DOORBELL_CLEAR_TIMEOUT (30 * 50) /* 30 sec */ > +#define SPC_DOORBELL_CLEAR_TIMEOUT (15 * 50) /* 15 sec */ > > /* > Making ORR bigger than IT NEXUS LOSS which is 2000000us = 2 second. > -- > 2.16.3 >
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: akshatzen <akshatzen@google.com> > > When controller runs into fatal error, commands which expect > response get stuck due to no response. If the controller is > in fatal error state, abort request issued to the controller > gets hung too. Hence we should fail it without trying. > > Signed-off-by: akshatzen <akshatzen@google.com> > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> > Signed-off-by: Radha Ramachandran <radha@google.com> Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> Thx > --- > drivers/scsi/pm8001/pm8001_hwi.c | 1 + > drivers/scsi/pm8001/pm8001_sas.c | 9 +++++++++ > drivers/scsi/pm8001/pm8001_sas.h | 2 ++ > drivers/scsi/pm8001/pm80xx_hwi.c | 36 ++++++++++++++++++++++++++++++++++++ > drivers/scsi/pm8001/pm80xx_hwi.h | 13 +++++++++++++ > 5 files changed, 61 insertions(+) > > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c > index c8d4d87c5473..f147193d67bd 100644 > --- a/drivers/scsi/pm8001/pm8001_hwi.c > +++ b/drivers/scsi/pm8001/pm8001_hwi.c > @@ -4998,4 +4998,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, > + .fatal_errors = pm80xx_fatal_errors, > }; > diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c > index d1e9dba2ef19..f8d142f9b9ad 100644 > --- a/drivers/scsi/pm8001/pm8001_sas.c > +++ b/drivers/scsi/pm8001/pm8001_sas.c > @@ -1183,12 +1183,21 @@ int pm8001_abort_task(struct sas_task *task) > int rc = TMF_RESP_FUNC_FAILED, ret; > u32 phy_id; > struct sas_task_slow slow_task; > + > if (unlikely(!task || !task->lldd_task || !task->dev)) > return TMF_RESP_FUNC_FAILED; > + > dev = task->dev; > pm8001_dev = dev->lldd_dev; > pm8001_ha = pm8001_find_ha_by_dev(dev); > phy_id = pm8001_dev->attached_phy; > + > + if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) { > + // If the controller is seeing fatal errors > + // abort task will not get a response from the controller > + return TMF_RESP_FUNC_FAILED; > + } > + > ret = pm8001_find_tag(task, &tag); > if (ret == 0) { > pm8001_info(pm8001_ha, "no tag for task:%p\n", task); > diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h > index f2c8cbad3853..039ed91e9841 100644 > --- a/drivers/scsi/pm8001/pm8001_sas.h > +++ b/drivers/scsi/pm8001/pm8001_sas.h > @@ -215,6 +215,7 @@ 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 (*fatal_errors)(struct pm8001_hba_info *pm8001_ha); > }; > > struct pm8001_chip_info { > @@ -725,6 +726,7 @@ 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_fatal_errors(struct pm8001_hba_info *pm8001_ha); > /* 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 9c4b8b374ab8..86a3d483749c 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -1525,6 +1525,41 @@ static int mpi_uninit_check(struct pm8001_hba_info *pm8001_ha) > return 0; > } > > +/** > + * pm80xx_fatal_errors - returns non zero *ONLY* when fatal errors > + * @pm8001_ha: our hba card information > + * > + * Fatal errors are recoverable only after a host reboot. > + */ > +int > +pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha) > +{ > + int ret = 0; > + u32 scratch_pad_rsvd0 = pm8001_cr32(pm8001_ha, 0, > + MSGU_HOST_SCRATCH_PAD_6); > + u32 scratch_pad_rsvd1 = pm8001_cr32(pm8001_ha, 0, > + MSGU_HOST_SCRATCH_PAD_7); > + u32 scratch_pad1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); > + u32 scratch_pad2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2); > + u32 scratch_pad3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3); > + > + if (pm8001_ha->chip_id != chip_8006 && > + pm8001_ha->chip_id != chip_8074 && > + pm8001_ha->chip_id != chip_8076) { > + return 0; > + } > + > + if (MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(scratch_pad1)) { > + pm8001_dbg(pm8001_ha, FAIL, > + "Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n", > + scratch_pad1, scratch_pad2, scratch_pad3, > + scratch_pad_rsvd0, scratch_pad_rsvd1); > + ret = 1; > + } > + > + return ret; > +} > + > /** > * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all > * the FW register status to the originated status. > @@ -4959,4 +4994,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, > + .fatal_errors = pm80xx_fatal_errors, > }; > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h > index 2b6b52551968..2c8e85cfdbc4 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.h > +++ b/drivers/scsi/pm8001/pm80xx_hwi.h > @@ -1368,6 +1368,19 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; > #define MSGU_HOST_SCRATCH_PAD_6 0x6C > #define MSGU_HOST_SCRATCH_PAD_7 0x70 > > +#define MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ((x & 0x3) == 0x2) > +#define MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) (((x >> 2) & 0x3) == 0x2) > +#define MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ((((x >> 4) & 0x7) == 0x7) || \ > + (((x >> 4) & 0x7) == 0x4)) > +#define MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) (((x >> 10) & 0x3) == 0x2) > +#define MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x) (((x >> 12) & 0x3) == 0x2) > +#define MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(x) \ > + (MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) || \ > + MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) || \ > + MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) || \ > + MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) || \ > + MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x)) > + > /* bit definition for ODMR register */ > #define ODMR_MASK_ALL 0xFFFFFFFF/* mask all > interrupt vector */ > -- > 2.16.3 >
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: akshatzen <akshatzen@google.com> > > Tag is not free'd in NVMD get/set data request failure scenario, > which would have caused tag leak each time the request fails. > > Signed-off-by: akshatzen <akshatzen@google.com> > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> > Signed-off-by: Radha Ramachandran <radha@google.com> Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> Thx > --- > drivers/scsi/pm8001/pm8001_hwi.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c > index f147193d67bd..9cd6a654f8b2 100644 > --- a/drivers/scsi/pm8001/pm8001_hwi.c > +++ b/drivers/scsi/pm8001/pm8001_hwi.c > @@ -3038,8 +3038,8 @@ void pm8001_mpi_set_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) > complete(pm8001_ha->nvmd_completion); > pm8001_dbg(pm8001_ha, MSG, "Set nvm data complete!\n"); > if ((dlen_status & NVMD_STAT) != 0) { > - pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error!\n"); > - return; > + pm8001_dbg(pm8001_ha, FAIL, "Set nvm data error %x\n", > + dlen_status); > } > ccb->task = NULL; > ccb->ccb_tag = 0xFFFFFFFF; > @@ -3062,11 +3062,17 @@ pm8001_mpi_get_nvmd_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) > > pm8001_dbg(pm8001_ha, MSG, "Get nvm data complete!\n"); > if ((dlen_status & NVMD_STAT) != 0) { > - pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error!\n"); > + pm8001_dbg(pm8001_ha, FAIL, "Get nvm data error %x\n", > + dlen_status); > complete(pm8001_ha->nvmd_completion); > + /* We should free tag during failure also, the tag is not being > + * free'd by requesting path anywhere. > + */ > + ccb->task = NULL; > + ccb->ccb_tag = 0xFFFFFFFF; > + pm8001_tag_free(pm8001_ha, tag); > return; > } > - > if (ir_tds_bn_dps_das_nvm & IPMode) { > /* indirect mode - IR bit set */ > pm8001_dbg(pm8001_ha, MSG, "Get NVMD success, IR=1\n"); > -- > 2.16.3 >
On Wed, Dec 30, 2020 at 5:47 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: Viswas G <Viswas.G@microchip.com> > > The fatal dump function pm80xx_get_fatal_dump() has two issues that > result in the fatal dump not being completed successfully. > > 1. When trying collect fatal_logs from the application it is getting > failed, because we are not shifting MEMBASE-II register properly. > Once we read 64K region of data we have to shift the MEMBASE-II register > and read the next chunk of data, then only we would be able to get > complete data. > > 2. If timeout occurs our application will get stuck because we are not > handling this case. In this patch it resolves all these issues. > > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> > Signed-off-by: Ashokkumar N <Ashokkumar.N@microchip.com> Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> Thx > --- > drivers/scsi/pm8001/pm80xx_hwi.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c > index 7d0eada11d3c..407c0cf6ab5f 100644 > --- a/drivers/scsi/pm8001/pm80xx_hwi.c > +++ b/drivers/scsi/pm8001/pm80xx_hwi.c > @@ -349,10 +349,15 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, > sprintf( > pm8001_ha->forensic_info.data_buf.direct_data, > "%08x ", 0xFFFFFFFF); > - pm8001_cw32(pm8001_ha, 0, > + return((char *)pm8001_ha->forensic_info.data_buf.direct_data - > + (char *)buf); > + } > + /* reset fatal_forensic_shift_offset back to zero and reset MEMBASE 2 register to zero */ > + pm8001_ha->fatal_forensic_shift_offset = 0; /* location in 64k region */ > + pm8001_cw32(pm8001_ha, 0, > MEMBASE_II_SHIFT_REGISTER, > pm8001_ha->fatal_forensic_shift_offset); > - } > + } > /* Read the next block of the debug data.*/ > length_to_read = pm8001_mr32(fatal_table_address, > MPI_FATAL_EDUMP_TABLE_ACCUM_LEN) - > @@ -373,13 +378,12 @@ ssize_t pm80xx_get_fatal_dump(struct device *cdev, > = 0; > pm8001_ha->forensic_info.data_buf.read_len = 0; > } > - } > } > offset = (int)((char *)pm8001_ha->forensic_info.data_buf.direct_data > - (char *)buf); > pm8001_dbg(pm8001_ha, IO, "get_fatal_spcv: return4 0x%x\n", offset); > - return (char *)pm8001_ha->forensic_info.data_buf.direct_data - > - (char *)buf; > + return ((char *)pm8001_ha->forensic_info.data_buf.direct_data - > + (char *)buf); > } > > /* pm80xx_get_non_fatal_dump - dump the nonfatal data from the dma > -- > 2.16.3 >
On Wed, Dec 30, 2020 at 5:48 AM Viswas G <Viswas.G@microchip.com.com> wrote: > > From: Vishakha Channapattan <vishakhavc@google.com> > > A new sysfs variable 'health' is being introduced that tells if the > controller is alive by indicating controller ticks. If on subsequent > run we see the ticks changing that indicates that controller is not > dead. > > Tested: Using 'health' sysfs variable we can see ticks incrementing > mvae14:~# cat /sys/class/scsi_host/host*/health > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x00000169 IOPTCNT=0x0000016a IOP1TCNT=0x0000016a > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x0000014d IOPTCNT=0x0000014d IOP1TCNT=0x0000014d > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x00000149 IOPTCNT=0x00000149 IOP1TCNT=0x00000149 > mvae14:~# > mvae14:~# > mvae14:~# > mvae14:~# cat /sys/class/scsi_host/host*/health > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x0000016c IOPTCNT=0x0000016c IOP1TCNT=0x0000016c > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x0000014f IOPTCNT=0x0000014f IOP1TCNT=0x0000014f > MPI-S= MPI is successfully initialized HMI_ERR=0 > MSGUTCNT = 0x0000014b IOPTCNT=0x0000014b IOP1TCNT=0x0000014b > > Signed-off-by: Vishakha Channapattan <vishakhavc@google.com> > Signed-off-by: Viswas G <Viswas.G@microchip.com> > Signed-off-by: Ruksar Devadi <Ruksar.devadi@microchip.com> > Signed-off-by: Ashokkumar N <Ashokkumar.N@microchip.com> > Signed-off-by: Radha Ramachandran <radha@google.com> Acked-by: Jack Wang <jinpu.wang@cloud.ionos.com> Thx > --- > drivers/scsi/pm8001/pm8001_ctl.c | 42 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/drivers/scsi/pm8001/pm8001_ctl.c b/drivers/scsi/pm8001/pm8001_ctl.c > index 12035baf0997..f46f341132fb 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" > +#include "pm8001_chips.h" > > /* scsi host attributes */ > > @@ -886,6 +887,46 @@ static ssize_t pm8001_show_update_fw(struct device *cdev, > > static DEVICE_ATTR(update_fw, S_IRUGO|S_IWUSR|S_IWGRP, > pm8001_show_update_fw, pm8001_store_update_fw); > + > +/** > + * pm8001_ctl_health_show - controller health check > + * @cdev: pointer to embedded class device > + * @buf: the buffer returned > + * > + * A sysfs 'read-only' shost attribute. > + */ > + > +char mpiStateText[][80] = { > + "MPI is not initialized", > + "MPI is successfully initialized", > + "MPI termination is in progress", > + "MPI initialization failed with error in [31:16]" > +}; > + > +static ssize_t ctl_health_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; > + unsigned int mpiDW0 = 0; > + unsigned int raaeCnt = 0; > + unsigned int iop0Cnt = 0; > + unsigned int iop1Cnt = 0; > + int c; > + > + pm8001_dbg(pm8001_ha, IOCTL, "%s\n", __func__); > + mpiDW0 = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 0); > + raaeCnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 12); > + iop0Cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 16); > + iop1Cnt = pm8001_mr32(pm8001_ha->general_stat_tbl_addr, 20); > + c = sprintf(buf, "MPI-S=%s\t HMI_ERR=%x\nMSGUTCNT=0x%08x IOPTCNT=0x%08x IOP1TCNT=0x%08x\n", > + mpiStateText[mpiDW0 & 0x0003], ((mpiDW0 & 0xff00) >> 16), > + raaeCnt, iop0Cnt, iop1Cnt); > + return c; > +} > +static DEVICE_ATTR_RO(ctl_health); > + > struct device_attribute *pm8001_host_attrs[] = { > &dev_attr_interface_rev, > &dev_attr_controller_fatal_error, > @@ -909,6 +950,7 @@ struct device_attribute *pm8001_host_attrs[] = { > &dev_attr_ob_log, > &dev_attr_ila_version, > &dev_attr_inc_fw_ver, > + &dev_attr_ctl_health, > NULL, > }; > > -- > 2.16.3 >
Hi Viswas!
> From: Viswas G <Viswas.G@microchip.com>
This series was submitted as <Viswas.G@microchip.com.com>. I was going
to fix it up but various tooling gets confused and we end up with weird
lore links.
Please fix your email address and resubmit.
Thanks!
--
Martin K. Petersen Oracle Linux Engineering
From: Viswas G <Viswas.G@microchip.com> This patch set include some bug fixes and enhancements for pm80xx driver. Bhavesh Jashnani (1): pm80xx: Simultaneous poll for all FW readiness. Vishakha Channapattan (2): pm80xx: Log SATA IOMB completion status on failure. pm80xx: Add sysfs attribute for ioc health Viswas G (1): pm80xx: fix driver fatal dump failure. akshatzen (4): pm80xx: No busywait in MPI init check pm80xx: check fatal error pm80xx: check main config table address pm80xx: fix missing tag_free in NVMD DATA req drivers/scsi/pm8001/pm8001_ctl.c | 42 ++++++++ drivers/scsi/pm8001/pm8001_hwi.c | 15 ++- drivers/scsi/pm8001/pm8001_init.c | 11 ++- drivers/scsi/pm8001/pm8001_sas.c | 9 ++ drivers/scsi/pm8001/pm8001_sas.h | 2 + drivers/scsi/pm8001/pm80xx_hwi.c | 202 ++++++++++++++++++++++++-------------- drivers/scsi/pm8001/pm80xx_hwi.h | 17 +++- 7 files changed, 216 insertions(+), 82 deletions(-)