[PATCH] scsi: aacraid: Fix PD performance regression over incorrect qd being set
The driver fails to set the correct queue depth for native devices, due to failing to set the device type prior to calling aac_set_safw_target_qd(). This results in slave configure setting the queue depth to 1. This causes around 30% performance degradation. Fixed by setting the dev type before trying to set queue depth. Reported-by: Steve Best Fixes: 0bcb45fb20c2a ("scsi: aacraid: Add helper function to set queue depth") cc: sta...@vger.kernel.org Signed-off-by: Raghava Aditya Renukunta Reviewed-by: David Carroll --- drivers/scsi/aacraid/aachba.c | 15 +++ 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a9831bd37a73..a57f3a7d4748 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1974,7 +1974,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev) u32 lun_count, nexus; u32 i, bus, target; u8 expose_flag, attribs; - u8 devtype; lun_count = aac_get_safw_phys_lun_count(dev); @@ -1992,23 +1991,23 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev) continue; if (expose_flag != 0) { - devtype = AAC_DEVTYPE_RAID_MEMBER; - goto update_devtype; + dev->hba_map[bus][target].devtype = + AAC_DEVTYPE_RAID_MEMBER; + continue; } if (nexus != 0 && (attribs & 8)) { - devtype = AAC_DEVTYPE_NATIVE_RAW; + dev->hba_map[bus][target].devtype = + AAC_DEVTYPE_NATIVE_RAW; dev->hba_map[bus][target].rmw_nexus = nexus; } else - devtype = AAC_DEVTYPE_ARC_RAW; + dev->hba_map[bus][target].devtype = + AAC_DEVTYPE_ARC_RAW; dev->hba_map[bus][target].scan_counter = dev->scan_counter; aac_set_safw_target_qd(dev, bus, target); - -update_devtype: - dev->hba_map[bus][target].devtype = devtype; } }
RE: [PATCH] aacraid: Insure command thread is not recursively stopped
> -Original Message- > From: Dave Carroll [mailto:david.carr...@microsemi.com] > Sent: Wednesday, April 4, 2018 3:21 AM > To: Martin K . Petersen <martin.peter...@oracle.com>; James Bottomley > <j...@linux.vnet.ibm.com> > Cc: Dave Carroll <david.carr...@microsemi.com>; linux-scsi s...@vger.kernel.org>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Scott Benesh <scott.ben...@microsemi.com> > Subject: [PATCH] aacraid: Insure command thread is not recursively stopped > > If a recursive IOP_RESET is invoked, usually due to the eh_thread handling > errors after the first reset, be sure we flag that the command thread has > been stopped to avoid an Oops of the form; > > [ 336.620256] CPU: 28 PID: 1193 Comm: scsi_eh_0 Kdump: loaded Not > tainted 4.14.0-49.el7a.ppc64le #1 > [ 336.620297] task: c03fd630b800 task.stack: c03fd61a4000 > [ 336.620326] NIP: c0176794 LR: c013038c CTR: > c024bc10 > [ 336.620361] REGS: c03fd61a7720 TRAP: 0300 Not tainted (4.14.0- > 49.el7a.ppc64le) > [ 336.620395] MSR: 90009033 <SF,HV,EE,ME,IR,DR,RI,LE> CR: > 22084022 XER: 2004 > [ 336.620435] CFAR: c0130388 DAR: DSISR: > 4000 SOFTE: 1 > [ 336.620435] GPR00: c013038c c03fd61a79a0 c14c7e00 > > [ 336.620435] GPR04: 000c 000c > 90009033 0477 > [ 336.620435] GPR08: 0477 > c00810f7d940 > [ 336.620435] GPR12: c024bc10 c7a33400 > c01708a8 c03fe3b881d8 > [ 336.620435] GPR16: c03fe3b88060 c03fd61a7d10 f000 > 001e > [ 336.620435] GPR20: 0001 c0ebf1a0 > 0001 c03fe3b88000 > [ 336.620435] GPR24: 0003 0002 > c03fe3b88840 c03fe3b887e8 > [ 336.620435] GPR28: c03fe3b88000 c03fc8181788 > c03fc8181700 > [ 336.620750] NIP [c0176794] exit_creds+0x34/0x160 > [ 336.620775] LR [c013038c] __put_task_struct+0x8c/0x1f0 > [ 336.620804] Call Trace: > [ 336.620817] [c03fd61a79a0] [c03fe3b88000] 0xc03fe3b88000 > (unreliable) > [ 336.620853] [c03fd61a79d0] [c013038c] > __put_task_struct+0x8c/0x1f0 > [ 336.620889] [c03fd61a7a00] [c0171418] > kthread_stop+0x1e8/0x1f0 > [ 336.620922] [c03fd61a7a40] [c00810f7448c] > aac_reset_adapter+0x14c/0x8d0 [aacraid] > [ 336.620959] [c03fd61a7b00] [c00810f60174] > aac_eh_host_reset+0x84/0x100 [aacraid] > [ 336.621010] [c03fd61a7b30] [c0864f24] > scsi_try_host_reset+0x74/0x180 > [ 336.621046] [c03fd61a7bb0] [c0867ac0] > scsi_eh_ready_devs+0xc00/0x14d0 > [ 336.625165] [c03fd61a7ca0] [c08699e0] > scsi_error_handler+0x550/0x730 > [ 336.632101] [c03fd61a7dc0] [c0170a08] kthread+0x168/0x1b0 > [ 336.639031] [c03fd61a7e30] [c000b528] > ret_from_kernel_thread+0x5c/0xb4 > [ 336.645971] Instruction dump: > [ 336.648743] 384216a0 7c0802a6 fbe1fff8 f8010010 f821ffd1 7c7f1b78 > 6000 6000 > [ 336.657056] 3940 e87f0838 f95f0838 7c0004ac <7d401828> 314affff > 7d40192d 40c2fff4 > [ 336.663997] -[ end trace 4640cf8d4945ad95 ]- > > So flag when the thread is stopped by setting the thread pointer to NULL. > > Signed-off-by: Dave Carroll <david.carr...@microsemi.com> Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
[PATCH v2 3/3] scsi: aacraid: Auto detect INTx or MSIx mode during sync cmd processing
During sync command processing if legacy INTx status indicates command is not completed, sample the MSIx register and check if it indicates command completion, set controller MSIx enabled flag. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> Reviewed-by: Dave Carroll <david.carr...@microsemi.com> --- Changes in V2: Re based on Linus Master drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/src.c | 22 -- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c3fdec9..29bf1e6 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1231,6 +1231,7 @@ struct src_registers { #define SRC_ODR_SHIFT 12 #define SRC_IDR_SHIFT 9 +#define SRC_MSI_READ_MASK 0x1000 typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 09b82d3..3122389f 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -1405,13 +1405,23 @@ void aac_src_access_devreg(struct aac_dev *dev, int mode) static int aac_src_get_sync_status(struct aac_dev *dev) { + int msix_val = 0; + int legacy_val = 0; - int val; + msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0; - if (dev->msi_enabled) - val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0; - else - val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; + if (!dev->msi_enabled) { + /* +* if Legacy int status indicates cmd is not complete +* sample MSIx register to see if it indiactes cmd complete, +* if yes set the controller in MSIx mode and consider cmd +* completed +*/ + legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; + if (!(legacy_val & 1) && msix_val) + dev->msi_enabled = 1; + return legacy_val; + } - return val; + return msix_val; } -- 2.9.4
[PATCH v2 1/3] scsi: aacraid: Implement DropIO sync command
IOP_RESET takes longer time to complete, if controller is in a state where we can bring it back with init struct, controller DropIO sync command is implemented. - If controller is faulted perform standard IOP_RESET in aac_srcv_init. - If controller is not faulted get adapter properties and extended properties. - Update the sa_firmware variable and determine if DropIO request is supported. - Issue DropIO request, and get the number of outstanding commands. - If all commands are complete with success (CT_OK), consider IOP_RESET is complete. - If any commands timeout, Perform the IOP_RESET. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> Reviewed-by: Dave Carroll <david.carr...@microsemi.com> --- Changes in V2: Re based on Linus Master drivers/scsi/aacraid/aacraid.h | 4 + drivers/scsi/aacraid/src.c | 161 +++-- 2 files changed, 159 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 0095fcb..c3fdec9 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1528,6 +1528,7 @@ struct aac_bus_info_response { #define AAC_COMM_MESSAGE_TYPE3 5 #define AAC_EXTOPT_SA_FIRMWARE cpu_to_le32(1<<1) +#define AAC_EXTOPT_SOFT_RESET cpu_to_le32(1<<16) /* MSIX context */ struct aac_msix_ctx { @@ -1662,6 +1663,7 @@ struct aac_dev u8 raw_io_64; u8 printf_enabled; u8 in_reset; + u8 in_soft_reset; u8 msi; u8 sa_firmware; int management_fib_count; @@ -2504,6 +2506,7 @@ struct aac_hba_info { #define RCV_TEMP_READINGS 0x0025 #define GET_COMM_PREFERRED_SETTINGS0x0026 #define IOP_RESET_FW_FIB_DUMP 0x0034 +#define DROP_IO0x0035 #define IOP_RESET 0x1000 #define IOP_RESET_ALWAYS 0x1001 #define RE_INIT_ADAPTER0x00ee @@ -2539,6 +2542,7 @@ struct aac_hba_info { #defineFLASH_UPD_PENDING 0x2000 #defineFLASH_UPD_SUCCESS 0x4000 #defineFLASH_UPD_FAILED0x8000 +#defineINVALID_OMR 0x #defineFWUPD_TIMEOUT (5 * 60) /* diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index fde6b6a..de48845 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -255,7 +255,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command, */ src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT); - if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) { + if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) && + !dev->in_soft_reset) { ok = 0; start = jiffies; @@ -992,6 +993,148 @@ int aac_src_init(struct aac_dev *dev) return -1; } +static int aac_src_wait_sync(struct aac_dev *dev, int *status) +{ + unsigned long start = jiffies; + unsigned long usecs = 0; + int delay = 5 * HZ; + int rc = 1; + + while (time_before(jiffies, start+delay)) { + /* +* Delay 5 microseconds to let Mon960 get info. +*/ + udelay(5); + + /* +* Mon960 will set doorbell0 bit when it has completed the +* command. +*/ + if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) { + /* +* Clear: the doorbell. +*/ + if (dev->msi_enabled) + aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT); + else + src_writel(dev, MUnit.ODR_C, + OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); + rc = 0; + + break; + } + + /* +* Yield the processor in case we are slow +*/ + usecs = 1 * USEC_PER_MSEC; + usleep_range(usecs, usecs + 50); + } + /* +* Pull the synch status from Mailbox 0. +*/ + if (status && !rc) { + status[0] = readl(>IndexRegs->Mailbox[0]); + status[1] = readl(>IndexRegs->Mailbox[1]); + status[2] = readl(>IndexRegs->Mailbox[2]); + status[3] = readl(>IndexRegs->Mailbox[3]); + status[4] = readl(>IndexRegs->Mailbox[4]);
[PATCH v2 2/3] scsi: aacraid: Preserve MSIX mode in the OMR register
Preserve the current MSIX mode value in the OMR before rewriting the OMR to initiate the IOP or Soft Reset. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> Reviewed-by: Dave Carroll <david.carr...@microsemi.com> --- Changes in V2: Re based on Linus Master drivers/scsi/aacraid/src.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index de48845..09b82d3 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -680,6 +680,25 @@ void aac_set_intx_mode(struct aac_dev *dev) } } +static void aac_clear_omr(struct aac_dev *dev) +{ + u32 omr_value = 0; + + omr_value = src_readl(dev, MUnit.OMR); + + /* +* Check for PCI Errors or Kernel Panic +*/ + if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC)) + omr_value = 0; + + /* +* Preserve MSIX Value if any +*/ + src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX); + src_readl(dev, MUnit.OMR); +} + static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) { __le32 supported_options3; @@ -740,6 +759,8 @@ static void aac_send_iop_reset(struct aac_dev *dev) aac_set_intx_mode(dev); + aac_clear_omr(dev); + src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); msleep(5000); @@ -749,6 +770,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev) { u_int32_t val; + aac_clear_omr(dev); val = readl(((char *)(dev->base) + IBW_SWR_OFFSET)); val |= 0x01; writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET)); -- 2.9.4
[PATCH v2 0/3] scsi: aacraid: Multi controller Kdump IOP reset handling
During Kdump aacraid controller IOP reset is invoked, IOP reset takes approx 40 seconds to bring the controller back up and running. with timeout of 120 seconds and anything more than 2 controllers will cause kdump to timeout. This patchset implements a new reset mechanism called DropIO, that induces the fw to drop any pending IO in the fw and making the reset process quicker. Changes in v2: Respun patchset against Linus Master Added Dave Carroll's reviewed-by tags Raghava Aditya Renukunta (3): scsi: aacraid: Implement DropIO sync command scsi: aacraid: Preserve MSIX mode in the OMR register scsi: aacraid: Auto detect INTx or MSIx mode during sync cmd processing drivers/scsi/aacraid/aacraid.h | 5 + drivers/scsi/aacraid/src.c | 205 ++--- 2 files changed, 198 insertions(+), 12 deletions(-) -- 2.9.4
RE: [PATCH 0/3] scsi: aacraid: Multi controller Kdump IOP reset handling
> -Original Message- > From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- > ow...@vger.kernel.org] On Behalf Of Martin K. Petersen > Sent: Tuesday, February 6, 2018 4:21 PM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com> > Cc: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; linux- > s...@vger.kernel.org; Scott Benesh <scott.ben...@microsemi.com>; Tom > White <tom.wh...@microsemi.com>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Guilherme G . Piccoli > <gpicc...@linux.vnet.ibm.com>; Bart Van Assche > <bart.vanass...@wdc.com> > Subject: Re: [PATCH 0/3] scsi: aacraid: Multi controller Kdump IOP reset > handling > > EXTERNAL EMAIL > > > Raghava, > > > During Kdump aacraid controller IOP reset is invoked, IOP reset > > takes approx 40 seconds to bring the controller back up and running. > > with timeout of 120 seconds and anything more than 2 controllers > > will cause kdump to timeout. > > > > This patchset implements a new reset mechanism called DropIO, that > > induces the fw to drop any pending IO in the fw and making the reset > > process quicker. > > This series doesn't apply to my impending 4.17/scsi-queue. Since the > latter won't exist until Linus releases rc1, please respin against > current linus/master and resubmit. Will do Martin. Thanks, Raghava Aditya > Thanks! > -- > Martin K. Petersen Oracle Linux Engineering
[PATCH 0/3] scsi: aacraid: Multi controller Kdump IOP reset handling
During Kdump aacraid controller IOP reset is invoked, IOP reset takes approx 40 seconds to bring the controller back up and running. with timeout of 120 seconds and anything more than 2 controllers will cause kdump to timeout. This patchset implements a new reset mechanism called DropIO, that induces the fw to drop any pending IO in the fw and making the reset process quicker. Raghava Aditya Renukunta (3): scsi: aacraid: Implement DropIO sync command scsi: aacraid: Preserve MSIX mode in the OMR register scsi: aacraid: Auto detect INTx or MSIx mode during sync cmd processing drivers/scsi/aacraid/aacraid.h | 5 + drivers/scsi/aacraid/src.c | 211 ++--- 2 files changed, 202 insertions(+), 14 deletions(-) -- 2.9.4
[PATCH 1/3] scsi: aacraid: Implement DropIO sync command
IOP_RESET takes longer time to complete, if controller is in a state where we can bring it back with init struct, controller DropIO sync command is implemented. - If controller is faulted perform standard IOP_RESET in aac_srcv_init. - If controller is not faulted get adapter properties and extended properties. - Update the sa_firmware variable and determine if DropIO request is supported. - Issue DropIO request, and get the number of outstanding commands. - If all commands are complete with success (CT_OK), consider IOP_RESET is complete. - If any commands timeout, Perform the IOP_RESET. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 4 + drivers/scsi/aacraid/src.c | 167 +++-- 2 files changed, 163 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 3e8bfcf..784783b 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1528,6 +1528,7 @@ struct aac_bus_info_response { #define AAC_COMM_MESSAGE_TYPE3 5 #define AAC_EXTOPT_SA_FIRMWARE cpu_to_le32(1<<1) +#define AAC_EXTOPT_SOFT_RESET cpu_to_le32(1<<16) /* MSIX context */ struct aac_msix_ctx { @@ -1662,6 +1663,7 @@ struct aac_dev u8 raw_io_64; u8 printf_enabled; u8 in_reset; + u8 in_soft_reset; u8 msi; u8 sa_firmware; int management_fib_count; @@ -2502,6 +2504,7 @@ struct aac_hba_info { #define RCV_TEMP_READINGS 0x0025 #define GET_COMM_PREFERRED_SETTINGS0x0026 #define IOP_RESET_FW_FIB_DUMP 0x0034 +#define DROP_IO0x0035 #define IOP_RESET 0x1000 #define IOP_RESET_ALWAYS 0x1001 #define RE_INIT_ADAPTER0x00ee @@ -2537,6 +2540,7 @@ struct aac_hba_info { #defineFLASH_UPD_PENDING 0x2000 #defineFLASH_UPD_SUCCESS 0x4000 #defineFLASH_UPD_FAILED0x8000 +#defineINVALID_OMR 0x #defineFWUPD_TIMEOUT (5 * 60) /* diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 0c9361c..df98f37 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -255,7 +255,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command, */ src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT); - if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) { + if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) && + !dev->in_soft_reset) { ok = 0; start = jiffies; @@ -988,6 +989,148 @@ int aac_src_init(struct aac_dev *dev) return -1; } +static int aac_src_wait_sync(struct aac_dev *dev, int *status) +{ + unsigned long start = jiffies; + unsigned long usecs = 0; + int delay = 5 * HZ; + int rc = 1; + + while (time_before(jiffies, start+delay)) { + /* +* Delay 5 microseconds to let Mon960 get info. +*/ + udelay(5); + + /* +* Mon960 will set doorbell0 bit when it has completed the +* command. +*/ + if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) { + /* +* Clear: the doorbell. +*/ + if (dev->msi_enabled) + aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT); + else + src_writel(dev, MUnit.ODR_C, + OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); + rc = 0; + + break; + } + + /* +* Yield the processor in case we are slow +*/ + usecs = 1 * USEC_PER_MSEC; + usleep_range(usecs, usecs + 50); + } + /* +* Pull the synch status from Mailbox 0. +*/ + if (status && !rc) { + status[0] = readl(>IndexRegs->Mailbox[0]); + status[1] = readl(>IndexRegs->Mailbox[1]); + status[2] = readl(>IndexRegs->Mailbox[2]); + status[3] = readl(>IndexRegs->Mailbox[3]); + status[4] = readl(>IndexRegs->Mailbox[4]); + } + + return rc; +} + +/** + * aac_src_soft_reset - perform soft reset to speed up +
[PATCH 3/3] scsi: aacraid: Auto detect INTx or MSIx mode during sync cmd processing
During sync command processing if legacy INTx status indicates command is not completed, sample the MSIx register and check if it indicates command completion, set controller MSIx enabled flag. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/src.c | 22 -- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 784783b..7834d09 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1231,6 +1231,7 @@ struct src_registers { #define SRC_ODR_SHIFT 12 #define SRC_IDR_SHIFT 9 +#define SRC_MSI_READ_MASK 0x1000 typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index b05c3cf..f9600b6 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -1399,13 +1399,23 @@ void aac_src_access_devreg(struct aac_dev *dev, int mode) static int aac_src_get_sync_status(struct aac_dev *dev) { + int msix_val = 0; + int legacy_val = 0; - int val; + msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0; - if (dev->msi_enabled) - val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0; - else - val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; + if (!dev->msi_enabled) { + /* +* if Legacy int status indicates cmd is not complete +* sample MSIx register to see if it indiactes cmd complete, +* if yes set the controller in MSIx mode and consider cmd +* completed +*/ + legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; + if (!(legacy_val & 1) && msix_val) + dev->msi_enabled = 1; + return legacy_val; + } - return val; + return msix_val; } -- 2.9.4
[PATCH 2/3] scsi: aacraid: Preserve MSIX mode in the OMR register
Preserve the current MSIX mode value in the OMR before rewriting the OMR to initiate the IOP or Soft Reset. Signed-off-by: Prasad B Munirathnam <prasad.munirath...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/src.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index df98f37..b05c3cf 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -680,6 +680,25 @@ void aac_set_intx_mode(struct aac_dev *dev) } } +static void aac_clear_omr(struct aac_dev *dev) +{ + u32 omr_value = 0; + + omr_value = src_readl(dev, MUnit.OMR); + + /* +* Check for PCI Errors or Kernel Panic +*/ + if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC)) + omr_value = 0; + + /* +* Preserve MSIX Value if any +*/ + src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX); + src_readl(dev, MUnit.OMR); +} + static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) { __le32 supported_options3; @@ -740,6 +759,8 @@ static void aac_send_iop_reset(struct aac_dev *dev) aac_set_intx_mode(dev); + aac_clear_omr(dev); + src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); msleep(5000); @@ -749,6 +770,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev) { u_int32_t val; + aac_clear_omr(dev); val = readl(((char *)(dev->base) + IBW_SWR_OFFSET)); val |= 0x01; writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET)); -- 2.9.4
[PATCH 2/2] scsi: aacraid: Delay for rescan worker needs to be 10 seconds
The delay for the rescan worker needs to 10 seconds, missed the HZ in there. Fixes: a1367e4adee207fe (scsi: aacraid: Reschedule host scan in case of failure) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 3e8bfcf..3ab3231 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1340,7 +1340,7 @@ struct fib { #define AAC_DEVTYPE_ARC_RAW2 #define AAC_DEVTYPE_NATIVE_RAW 3 -#define AAC_SAFW_RESCAN_DELAY 10 +#define AAC_SAFW_RESCAN_DELAY (10 * HZ) struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ -- 2.9.4
[PATCH 1/2] scsi: aacraid: Get correct lun count
The correct lun count needs to be divided by 24, missed it in the previous patch set. Fixes: 4b00022753550055 (scsi: aacraid: Create helper functions to get lun info) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a2bdd79..4c65991 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1868,7 +1868,7 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev) static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev) { - return get_unaligned_be32(>safw_phys_luns->list_length[0]); + return get_unaligned_be32(>safw_phys_luns->list_length[0])/24; } static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun) -- 2.9.4
RE: [PATCH][scsi-next] scsi: aacraid: remove redundant setting of variable c
> -Original Message- > From: Colin King [mailto:colin.k...@canonical.com] > Sent: Friday, January 5, 2018 7:31 AM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; James E . J . > Bottomley <j...@linux.vnet.ibm.com>; Martin K . Petersen > <martin.peter...@oracle.com>; linux-scsi@vger.kernel.org > Cc: kernel-janit...@vger.kernel.org; linux-ker...@vger.kernel.org > Subject: [PATCH][scsi-next] scsi: aacraid: remove redundant setting of > variable c > > EXTERNAL EMAIL > > > From: Colin Ian King <colin.k...@canonical.com> > > A previous commit no longer stores the contents of c, so we now have > a situation where c is being updated but the value is never read. Clean > up the code by removing the now redundant setting of variable c. > > Cleans up clang warning: > drivers/scsi/aacraid/aachba.c:943:3: warning: Value stored to 'c' is > never read > > Fixes: f4e8708d3104 ("scsi: aacraid: Fix udev inquiry race condition") > Signed-off-by: Colin Ian King <colin.k...@canonical.com> > --- Reviewed-by :Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH] aacraid driver oops with dead battery
> -Original Message- > From: mr...@math.ut.ee [mailto:mr...@math.ut.ee] On Behalf Of Meelis > Roos > Sent: Wednesday, January 3, 2018 1:11 AM > To: linux-scsi@vger.kernel.org; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com> > Subject: [PATCH] aacraid driver oops with dead battery > > EXTERNAL EMAIL > > > The battery in my HP NetRAID-4M died of old age, and the aacraid driver > started oopsing with NULL pointer dereference on startup after that. > > Fix it by reordering the init sequence to fill in function pointers > before ioremapping memory, or dev->a_ops.adapter_ioremap pointer will > be > NULL. > > Other subtypes of aacraid seem to have the order already correct. > > This was the call trace: > > ? aac_probe_one+0x7a5/0xb30 [aacraid] > pci_device_probe+0xc0/0x1a0 > driver_probe_device+0x1df/0x3b0 > __driver_attach+0xa9/0xe0 > ? driver_probe_device+0x3b0/0x3b0 > bus_for_each_dev+0x4c/0x90 > driver_attach+0x1d/0x40 > ? driver_probe_device+0x3b0/0x3b0 > bus_add_driver+0x1a7/0x2a0 > driver_register+0x6e/0x130 > __pci_register_driver+0x54/0x90 > ? 0xf81f4000 > aac_init+0x2b/0x1000 [aacraid] > do_one_initcall+0x45/0x1e0 > ? kfree_skbmem+0x74/0xa0 > ? kfree+0x16d/0x240 > ? kvfree+0x45/0x50 > ? kvfree+0x45/0x50 > ? __vunmap+0x99/0x120 > ? do_init_module+0x1a/0x245 > do_init_module+0x83/0x245 > load_module+0x2764/0x34a0 > ? kernel_read_file+0x150/0x320 > SyS_finit_module+0x82/0xa0 > do_fast_syscall_32+0xba/0x340 > > Signed-off-by: Meelis Roos <mr...@linux.ee> . Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH v2 22/30] scsi: aacraid: Merge adapter setup with resolve luns
Hi Nikola, > -Original Message- > From: Nikola Pajkovsky [mailto:npajkov...@suse.cz] > Sent: Wednesday, January 3, 2018 2:02 AM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com> > Cc: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; linux- > s...@vger.kernel.org; Scott Benesh <scott.ben...@microsemi.com>; Tom > White <tom.wh...@microsemi.com>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Guilherme G . Piccoli > <gpicc...@linux.vnet.ibm.com>; Bart Van Assche > <bart.vanass...@wdc.com> > Subject: Re: [PATCH v2 22/30] scsi: aacraid: Merge adapter setup with resolve > luns > > EXTERNAL EMAIL > > > Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> > writes: > > > The device hotplug events are processed only after retrieving the updated > > lun information from the fw. Does not make sense to keep them separate. > > > > Merge both the hotplug handling and safw adapter setup code into single > > function. > > > > Signed-off-by: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com> > > According to subsequent commit > > [PATCH v2 23/30] scsi: aacraid: Block concurrent hotplug event handling > > this commit is racy, because 23/30 adds ->scan_mutex. Shouldn't be these > commits squashed? I tried to make the patches as logically distinct as possible, maybe I got a bit too ambitious and I expected the patches to go thru as a set so I don’t think it would make any difference. What do you think? Thanks Raghava Aditya > -- > Nikola
[PATCH v2 07/30] scsi: aacraid: Refactor reset_host store function
Refactored the reset_host store function to make consistent across code bases Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/linit.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 5eb0722..b2273e3 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1375,18 +1375,15 @@ static ssize_t aac_store_reset_adapter(struct device *device, const char *buf, size_t count) { int retval = -EACCES; - int bled = 0; - struct aac_dev *aac; - if (!capable(CAP_SYS_ADMIN)) return retval; - aac = (struct aac_dev *)class_to_shost(device)->hostdata; - bled = buf[0] == '!' ? 1:0; - retval = aac_reset_adapter(aac, bled, IOP_HWSOFT_RESET); + retval = aac_reset_adapter(shost_priv(class_to_shost(device)), + buf[0] == '!', IOP_HWSOFT_RESET); if (retval >= 0) retval = count; + return retval; } -- 2.9.4
[PATCH v2 05/30] scsi: aacraid: Fix ioctl reset hang
Driver would hang when attempting to send reset from the ioctl interface, since it would wait to retrieve the ioctl mutex at send shutdown. Set adapter shutdown and unlock mutex before sending down reset request. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/commctrl.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 9ab0fa9..a2b3430 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -1052,9 +1052,13 @@ static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg) if (copy_from_user((void *), arg, sizeof(struct aac_reset_iop))) return -EFAULT; + dev->adapter_shutdown = 1; + + mutex_unlock(>ioctl_mutex); retval = aac_reset_adapter(dev, 0, reset.reset_type); - return retval; + mutex_lock(>ioctl_mutex); + return retval; } int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) -- 2.9.4
[PATCH v2 21/30] scsi: aacraid: Refactor resolve luns code and scsi functions
Resolve luns checks the if a sdev is already present in the os to figure out if it needs to be removed. Internally the driver exposes HBA on bus 2 even though its bus 1 in the fw. Its mildly confusing. Refactor out the sdev lookup into its function to check if sdev has been added to the kernel or not. Add helper functions to add, remove and put devices based on their fw bus and target number. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Removed unnecessary check and assignment for bus number drivers/scsi/aacraid/commsup.c | 71 -- 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 8966371..5b7a4f5 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1874,6 +1874,39 @@ static inline int is_safw_raid_volume(struct aac_dev *aac, int bus, int target) return bus == CONTAINER_CHANNEL && target < aac->maximum_num_containers; } +static struct scsi_device *aac_lookup_safw_scsi_device(struct aac_dev *dev, + int bus, + int target) +{ + if (bus != CONTAINER_CHANNEL) + bus = aac_phys_to_logical(bus); + + return scsi_device_lookup(dev->scsi_host_ptr, bus, target, 0); +} + +static int aac_add_safw_device(struct aac_dev *dev, int bus, int target) +{ + if (bus != CONTAINER_CHANNEL) + bus = aac_phys_to_logical(bus); + + return scsi_add_device(dev->scsi_host_ptr, bus, target, 0); +} + +static void aac_put_safw_scsi_device(struct scsi_device *sdev) +{ + if (sdev) + scsi_device_put(sdev); +} + +static void aac_remove_safw_device(struct aac_dev *dev, int bus, int target) +{ + struct scsi_device *sdev; + + sdev = aac_lookup_safw_scsi_device(dev, bus, target); + scsi_remove_device(sdev); + aac_put_safw_scsi_device(sdev); +} + static inline int aac_is_safw_scan_count_equal(struct aac_dev *dev, int bus, int target) { @@ -1888,33 +1921,37 @@ static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) return aac_is_safw_scan_count_equal(dev, bus, target); } +static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) +{ + int is_exposed = 0; + struct scsi_device *sdev; + + sdev = aac_lookup_safw_scsi_device(dev, bus, target); + if (sdev) + is_exposed = 1; + aac_put_safw_scsi_device(sdev); + + return is_exposed; +} + static void aac_resolve_luns(struct aac_dev *dev) { int i; - int bus, target, channel; - struct scsi_device *sdev; + int bus, target; + int is_exposed = 0; for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { bus = get_bus_number(i); target = get_target_number(i); - if (bus == CONTAINER_CHANNEL) - channel = CONTAINER_CHANNEL; - else - channel = aac_phys_to_logical(bus); - - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, - target, 0); - - if (!sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_add_device(dev->scsi_host_ptr, channel, - target, 0); - else if (sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_remove_device(sdev); + is_exposed = aac_is_safw_device_exposed(dev, bus, target); - if (sdev) - scsi_device_put(sdev); + if (aac_is_safw_target_valid(dev, bus, target) && !is_exposed) + aac_add_safw_device(dev, bus, target); + else if (!aac_is_safw_target_valid(dev, bus, target) && + is_exposed) + aac_remove_safw_device(dev, bus, target); } } -- 2.9.4
[PATCH v2 28/30] scsi: aacraid: Remove unused rescan variable
Remove unused rescan variable. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 19 +-- drivers/scsi/aacraid/aacraid.h | 6 +++--- drivers/scsi/aacraid/commsup.c | 14 +++--- drivers/scsi/aacraid/linit.c | 4 ++-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 426c61a..f498bed 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1821,12 +1821,11 @@ static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) /** * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure - * @rescan:Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +static int aac_get_safw_ciss_luns(struct aac_dev *dev) { int rcode = -ENOMEM; int datasize; @@ -1932,7 +1931,7 @@ static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev, } } -static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) +static int aac_get_safw_attr_all_targets(struct aac_dev *dev) { int i; int rcode = 0; @@ -1972,7 +1971,7 @@ static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) * * Update our hba map with the information gathered from the FW */ -static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) +static void aac_set_safw_attr_all_targets(struct aac_dev *dev) { /* ok and extended reporting */ u32 lun_count, nexus; @@ -2018,7 +2017,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } } -static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) +static int aac_setup_safw_targets(struct aac_dev *dev) { int rcode = 0; @@ -2026,15 +2025,15 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) if (unlikely(rcode < 0)) goto out; - rcode = aac_get_safw_ciss_luns(dev, rescan); + rcode = aac_get_safw_ciss_luns(dev); if (unlikely(rcode < 0)) goto out; - rcode = aac_get_safw_attr_all_targets(dev, rescan); + rcode = aac_get_safw_attr_all_targets(dev); if (unlikely(rcode < 0)) goto free_ciss_luns; - aac_set_safw_attr_all_targets(dev, rescan); + aac_set_safw_attr_all_targets(dev); aac_free_safw_all_identify_resp(dev, -1); free_ciss_luns: @@ -2043,9 +2042,9 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) return rcode; } -int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) +int aac_setup_safw_adapter(struct aac_dev *dev) { - return aac_setup_safw_targets(dev, rescan); + return aac_setup_safw_targets(dev); } int aac_get_adapter_info(struct aac_dev* dev) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 4cefc47..3e8a44c 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2644,7 +2644,7 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) } -int aac_scan_host(struct aac_dev *dev, int rescan); +int aac_scan_host(struct aac_dev *dev); static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev) { @@ -2659,7 +2659,7 @@ static inline void aac_safw_rescan_worker(struct work_struct *work) wait_event(dev->scsi_host_ptr->host_wait, !scsi_host_in_recovery(dev->scsi_host_ptr)); - aac_scan_host(dev, AAC_RESCAN); + aac_scan_host(dev); } static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) @@ -2677,7 +2677,7 @@ static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) void aac_safw_rescan_worker(struct work_struct *work); int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); -int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); +int aac_setup_safw_adapter(struct aac_dev *dev); const char *aac_driverinfo(struct Scsi_Host *); void aac_fib_vector_assign(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index f0c3e7d..fbf8b7e 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1944,7 +1944,7 @@ static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) return is_exposed; } -static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) +static int aac_update_safw_host_devices(struct aac_dev *dev) { int i; int bus; @@ -1952,7 +1952,7 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) int is_exposed =
[PATCH v2 30/30] scsi: aacraid: Update driver version to 50877
Update driver Version to 50877 Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 4d3536d..3e8bfcf 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -98,7 +98,7 @@ enum { #definePMC_GLOBAL_INT_BIT0 0x0001 #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 50834 +# define AAC_DRIVER_BUILD 50877 # define AAC_DRIVER_BRANCH "-custom" #endif #define MAXIMUM_NUM_CONTAINERS 32 -- 2.9.4
[PATCH v2 24/30] scsi: aacraid: Use hotplug handling function in place of scsi_scan_host
Driver uses scsi_scan_host to add new devices in the driver init path, which adds all the fw exposed devices. The drivers resorts to queue command checks to block out commands to _hidden_ devices. Use the hotplug handler code to add new devices during driver init and other areas, this is only for safw. For ARC scsi_scan_host will still apply. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 4 drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commsup.c | 18 +++--- drivers/scsi/aacraid/linit.c | 5 +++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 4ad9d3f..426c61a 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -2150,10 +2150,6 @@ int aac_get_adapter_info(struct aac_dev* dev) dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); } - if (!dev->sync_mode && dev->sa_firmware && - dev->supplement_adapter_info.virt_device_bus != 0x) - rcode = aac_setup_safw_adapter(dev, AAC_INIT); - if (!dev->in_reset) { char buffer[16]; tmp = le32_to_cpu(dev->adapter_info.kernelrev); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c70c998..ba84d99 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2719,6 +2719,7 @@ static inline int aac_supports_2T(struct aac_dev *dev) return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); } +int aac_scan_host(struct aac_dev *dev, int rescan); char * get_container_type(unsigned type); extern int numacb; extern char aac_driver_version[]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 491e633..4e2687c 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1964,6 +1964,19 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) return rcode; } +int aac_scan_host(struct aac_dev *dev, int rescan) +{ + int rcode = 0; + + mutex_lock(>scan_mutex); + if (dev->sa_firmware) + rcode = aac_update_safw_host_devices(dev, rescan); + else + scsi_scan_host(dev->scsi_host_ptr); + mutex_unlock(>scan_mutex); + return rcode; +} + /** * aac_handle_sa_aif Handle a message from the firmware * @dev: Which adapter this fib is from @@ -1997,9 +2010,8 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: - mutex_lock(>scan_mutex); - aac_update_safw_host_devices(dev, AAC_RESCAN); - mutex_unlock(>scan_mutex); + aac_scan_host(dev, AAC_RESCAN); + break; case SA_AIF_BPSTAT_CHANGE: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 2c862cd..7ea7b2c 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1787,7 +1787,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) error = scsi_add_host(shost, >dev); if (error) goto out_deinit; - scsi_scan_host(shost); + + aac_scan_host(aac, AAC_INIT); pci_enable_pcie_error_reporting(pdev); pci_save_state(pdev); @@ -2071,7 +2072,7 @@ static void aac_pci_resume(struct pci_dev *pdev) if (sdev->sdev_state == SDEV_OFFLINE) sdev->sdev_state = SDEV_RUNNING; scsi_unblock_requests(aac->scsi_host_ptr); - scsi_scan_host(aac->scsi_host_ptr); + aac_scan_host(aac, AAC_RESCAN); pci_save_state(pdev); dev_err(>dev, "aacraid: PCI error - resume\n"); -- 2.9.4
[PATCH v2 15/30] scsi: aacraid: Create helper functions to get lun info
Created inline function to retrieve lun info for each device from the phy luns structure. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Use get_unaligned_be32 instead of open ended conversion drivers/scsi/aacraid/aachba.c | 54 +-- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 43a3c11..fa0132b 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -42,6 +42,8 @@ #include /* For flush_kernel_dcache_page */ #include +#include + #include #include #include @@ -1844,7 +1846,41 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) mem_free_all: kfree(phys_luns); goto out; +} + +static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev) +{ + return get_unaligned_be32(>safw_phys_luns->list_length[0]); +} + +static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].level2[1] & 0x3f; +} + +static inline u32 aac_get_safw_phys_target(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].level2[0]; +} +static inline u32 aac_get_safw_phys_expose_flag(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].bus >> 6; +} + +static inline u32 aac_get_safw_phys_attribs(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].node_ident[9]; +} + +static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun) +{ + return *((u32 *)>safw_phys_luns->lun[lun].node_ident[12]); +} + +static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].node_ident[8]; } /** @@ -1862,22 +1898,16 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) u32 i, bus, target; u8 expose_flag, attribs; u8 devtype; - struct aac_ciss_phys_luns_resp *phys_luns; - - phys_luns = dev->safw_phys_luns; - lun_count = ((phys_luns->list_length[0] << 24) - + (phys_luns->list_length[1] << 16) - + (phys_luns->list_length[2] << 8) - + (phys_luns->list_length[3])) / 24; + lun_count = aac_get_safw_phys_lun_count(dev); for (i = 0; i < lun_count; ++i) { - bus = phys_luns->lun[i].level2[1] & 0x3f; - target = phys_luns->lun[i].level2[0]; - expose_flag = phys_luns->lun[i].bus >> 6; - attribs = phys_luns->lun[i].node_ident[9]; - nexus = *((u32 *) _luns->lun[i].node_ident[12]); + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + expose_flag = aac_get_safw_phys_expose_flag(dev, i); + attribs = aac_get_safw_phys_attribs(dev, i); + nexus = aac_get_safw_phys_nexus(dev, i); if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS) continue; -- 2.9.4
[PATCH v2 26/30] scsi: aacraid: Fix hang while scanning in eh recovery
Add back the ability to scan for hotplug changes while eh was in progress. Schedule a rescan for a later time in the eh recovery code and wait for eh to complete in the rescan worker. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aacraid.h | 4 drivers/scsi/aacraid/commsup.c | 9 + 2 files changed, 13 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 54078bf..4cefc47 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -41,6 +41,7 @@ #include #include +#include /*-- * D E F I N E S @@ -2655,6 +2656,9 @@ static inline void aac_safw_rescan_worker(struct work_struct *work) struct aac_dev *dev = container_of(to_delayed_work(work), struct aac_dev, safw_rescan_work); + wait_event(dev->scsi_host_ptr->host_wait, + !scsi_host_in_recovery(dev->scsi_host_ptr)); + aac_scan_host(dev, AAC_RESCAN); } diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index d562053..706aba0 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1671,6 +1671,15 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) aac->in_reset = 0; scsi_unblock_requests(host); + /* +* Issue bus rescan to catch any configuration that might have +* occurred +*/ + if (!retval) { + dev_info(>pdev->dev, "Scheduling bus rescan\n"); + aac_schedule_safw_scan_worker(aac); + } + if (jafo) { spin_lock_irq(host->host_lock); } -- 2.9.4
[PATCH v2 19/30] scsi: aacraid: Process hba and container hot plug events in single function
The hotplug handler code is duplicated for hba handling and container handling. Merged function to handle hba and container hot plug events into the resolve luns functions. Added a bunch of helper functions to check the validity of a given target and to check if bus, target is container device. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 9 --- drivers/scsi/aacraid/aacraid.h | 3 ++- drivers/scsi/aacraid/commsup.c | 59 -- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index c30f7da..4ad9d3f 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1982,6 +1982,8 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) lun_count = aac_get_safw_phys_lun_count(dev); + dev->scan_counter++; + for (i = 0; i < lun_count; ++i) { bus = aac_get_safw_phys_bus(dev, i); @@ -2007,13 +2009,12 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } else devtype = AAC_DEVTYPE_ARC_RAW; + dev->hba_map[bus][target].scan_counter = dev->scan_counter; + aac_set_safw_target_qd(dev, bus, target); update_devtype: - if (rescan == AAC_INIT) - dev->hba_map[bus][target].devtype = devtype; - else - dev->hba_map[bus][target].new_devtype = devtype; + dev->hba_map[bus][target].devtype = devtype; } } diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index b1a6045..17c6cdd 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1340,11 +1340,11 @@ struct fib { struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ u8 devtype;/* device type */ - u8 new_devtype; u8 reset_state;/* 0 - no reset, 1..x - */ /* after xth TM LUN reset */ u16 qd_limit; u8 expose; /*checks if to expose or not*/ + u32 scan_counter; struct aac_ciss_identify_pd *safw_identify_resp; }; @@ -1669,6 +1669,7 @@ struct aac_dev u32 vector_cap; /* MSI-X vector capab.*/ int msi_enabled;/* MSI/MSI-X enabled */ atomic_tmsix_counter; + u32 scan_counter; struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 9625eb0..ed79159 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1869,13 +1869,29 @@ int aac_check_health(struct aac_dev * aac) return BlinkLED; } +static inline int is_safw_raid_volume(struct aac_dev *aac, int bus, int target) +{ + return bus == CONTAINER_CHANNEL && target < aac->maximum_num_containers; +} + +static inline int aac_is_safw_scan_count_equal(struct aac_dev *dev, + int bus, int target) +{ + return dev->hba_map[bus][target].scan_counter == dev->scan_counter; +} + +static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) +{ + if (is_safw_raid_volume(dev, bus, target)) + return dev->fsa_dev[target].valid; + else + return aac_is_safw_scan_count_equal(dev, bus, target); +} static void aac_resolve_luns(struct aac_dev *dev) { int bus, target, channel; struct scsi_device *sdev; - u8 devtype; - u8 new_devtype; for (bus = 0; bus < AAC_MAX_BUSES; bus++) { for (target = 0; target < AAC_MAX_TARGETS; target++) { @@ -1885,24 +1901,19 @@ static void aac_resolve_luns(struct aac_dev *dev) else channel = aac_phys_to_logical(bus); - devtype = dev->hba_map[bus][target].devtype; - new_devtype = dev->hba_map[bus][target].new_devtype; - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, target, 0); - if (!sdev && new_devtype) + if (!sdev && aac_is_safw_target_valid(dev, bus, target)) scsi_add_device(dev->scsi_host_ptr, channel, target, 0); - else if (sdev && n
[PATCH v2 27/30] scsi: aacraid: Skip schedule rescan in case of kdump
There is a chance of the driver to be stuck in kdump if drives start acting up in kdump discovery process and the kernel decides to send eh resets, which would prompt rescan to be scheduled. Do not perform a rescan in kdump context, since we do not expect a hotplug event during kdump and all the devices are going to go away anyway. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/commsup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 706aba0..f0c3e7d 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -1675,7 +1676,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) * Issue bus rescan to catch any configuration that might have * occurred */ - if (!retval) { + if (!retval && !is_kdump_kernel()) { dev_info(>pdev->dev, "Scheduling bus rescan\n"); aac_schedule_safw_scan_worker(aac); } -- 2.9.4
[PATCH v2 18/30] scsi: aacraid: Merge func to get container information
Merge aac_get_containers to setup target function, so that information about all the present devices can be retrieved in one shot. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 4 drivers/scsi/aacraid/commsup.c | 34 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 67ca5af..c30f7da 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -2021,6 +2021,10 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { int rcode = 0; + rcode = aac_get_containers(dev); + if (unlikely(rcode < 0)) + goto out; + rcode = aac_get_safw_ciss_luns(dev, rescan); if (unlikely(rcode < 0)) goto out; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index f3077b3..9625eb0 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1949,26 +1949,22 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) aac_resolve_luns(dev); - if (events == SA_AIF_LDEV_CHANGE || - events == SA_AIF_BPCFG_CHANGE) { - aac_get_containers(dev); - for (container = 0; container < + for (container = 0; container < dev->maximum_num_containers; ++container) { - sdev = scsi_device_lookup(dev->scsi_host_ptr, - CONTAINER_CHANNEL, - container, 0); - if (dev->fsa_dev[container].valid && !sdev) { - scsi_add_device(dev->scsi_host_ptr, - CONTAINER_CHANNEL, - container, 0); - } else if (!dev->fsa_dev[container].valid && - sdev) { - scsi_remove_device(sdev); - scsi_device_put(sdev); - } else if (sdev) { - scsi_rescan_device(>sdev_gendev); - scsi_device_put(sdev); - } + sdev = scsi_device_lookup(dev->scsi_host_ptr, + CONTAINER_CHANNEL, + container, 0); + if (dev->fsa_dev[container].valid && !sdev) { + scsi_add_device(dev->scsi_host_ptr, + CONTAINER_CHANNEL, + container, 0); + } else if (!dev->fsa_dev[container].valid && + sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } else if (sdev) { + scsi_rescan_device(>sdev_gendev); + scsi_device_put(sdev); } } break; -- 2.9.4
[PATCH v2 11/30] scsi: aacraid: Refactor and rename to make mirror existing changes
Rename variables and functions to make bmic identify, report phy luns to make them consistent across code internal existing code bases Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 36 +++- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 1853bd2..801aff0 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1753,17 +1753,18 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, return rcode; } -static int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) +static int aac_issue_safw_bmic_identify(struct aac_dev *dev, + u32 bus, u32 target) { int rcode = -ENOMEM; - u16 datasize; + int datasize; struct aac_srb_unit srbu; struct aac_srb *srbcmd; - struct aac_ciss_identify_pd *identify_resp; + struct aac_ciss_identify_pd *identify_reply; datasize = sizeof(struct aac_ciss_identify_pd); - identify_resp = kmalloc(datasize, GFP_KERNEL); - if (!identify_resp) + identify_reply = kmalloc(datasize, GFP_KERNEL); + if (!identify_reply) goto out; memset(, 0, sizeof(struct aac_srb_unit)); @@ -1774,30 +1775,31 @@ static int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF); srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE; - rcode = aac_send_safw_bmic_cmd(dev, , identify_resp, datasize); + rcode = aac_send_safw_bmic_cmd(dev, , identify_reply, datasize); if (unlikely(rcode < 0)) goto out; - if (identify_resp->current_queue_depth_limit <= 0 || - identify_resp->current_queue_depth_limit > 32) + if (identify_reply->current_queue_depth_limit <= 0 || + identify_reply->current_queue_depth_limit > 32) dev->hba_map[bus][target].qd_limit = 32; else dev->hba_map[bus][target].qd_limit = - identify_resp->current_queue_depth_limit; + identify_reply->current_queue_depth_limit; - kfree(identify_resp); + kfree(identify_reply); out: return rcode; } /** - * aac_update hba_map()- update current hba map with data from FW + * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure * @phys_luns: FW information from report phys luns + * @rescan: Indicates scan type * * Update our hba map with the information gathered from the FW */ -void aac_update_hba_map(struct aac_dev *dev, +static void aac_set_safw_attr_all_targets(struct aac_dev *dev, struct aac_ciss_phys_luns_resp *phys_luns, int rescan) { /* ok and extended reporting */ @@ -1839,7 +1841,7 @@ void aac_update_hba_map(struct aac_dev *dev, if (devtype != AAC_DEVTYPE_NATIVE_RAW) goto update_devtype; - if (aac_issue_bmic_identify(dev, bus, target) < 0) + if (aac_issue_safw_bmic_identify(dev, bus, target) < 0) dev->hba_map[bus][target].qd_limit = 32; update_devtype: @@ -1851,14 +1853,14 @@ void aac_update_hba_map(struct aac_dev *dev, } /** - * aac_report_phys_luns() Process topology change + * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure * @rescan:Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_report_phys_luns(struct aac_dev *dev, int rescan) +int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) { int rcode = -ENOMEM; int datasize; @@ -1888,7 +1890,7 @@ int aac_report_phys_luns(struct aac_dev *dev, int rescan) /* analyse data */ if (rcode >= 0 && phys_luns->resp_flag == 2) { /* ok and extended reporting */ - aac_update_hba_map(dev, phys_luns, rescan); + aac_set_safw_attr_all_targets(dev, phys_luns, rescan); } kfree(phys_luns); @@ -2001,7 +2003,7 @@ int aac_get_adapter_info(struct aac_dev* dev) if (!dev->sync_mode && dev->sa_firmware && dev->supplement_adapter_info.virt_device_bus != 0x) { /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_report_phys_luns(dev, AAC_INIT); + rcode = aac_get_safw_ciss_luns(dev, AAC_INIT); } if (!dev->in_reset) { diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers
[PATCH v2 03/30] scsi: aacraid: Fix hang in kdump
Driver attempts to perform a device scan and device add after coming out of reset. At times when the kdump kernel loads and it tries to perform eh recovery, the device scan hangs since its commands are blocked because of the eh recovery. This should have shown up in normal eh recovery path (Should have been obvious) Remove the code that performs scanning.I can live without the rescanning support in the stable kernels but a hanging kdump/eh recovery needs to be fixed. Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after controller reset) Cc: <sta...@vger.kernel.org> Reported-by: Douglas Miller <dougm...@linux.vnet.ibm.com> Tested-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after controller reset) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Changed reported by from Guilherme G. Piccoli to Douglas Miller drivers/scsi/aacraid/aachba.c | 1 - drivers/scsi/aacraid/commsup.c | 9 + 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 548a3e7..7173ae5 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -918,7 +918,6 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) char *cname = kmemdup(sup_adap_info->adapter_type_text, sizeof(sup_adap_info->adapter_type_text), GFP_ATOMIC); - if (!cname) return; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 525a652..ffbfd04 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1672,14 +1672,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) out: aac->in_reset = 0; scsi_unblock_requests(host); - /* -* Issue bus rescan to catch any configuration that might have -* occurred -*/ - if (!retval) { - dev_info(>pdev->dev, "Issuing bus rescan\n"); - scsi_scan_host(host); - } + if (jafo) { spin_lock_irq(host->host_lock); } -- 2.9.4
[PATCH v2 22/30] scsi: aacraid: Merge adapter setup with resolve luns
The device hotplug events are processed only after retrieving the updated lun information from the fw. Does not make sense to keep them separate. Merge both the hotplug handling and safw adapter setup code into single function. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/commsup.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 5b7a4f5..34155b1 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1934,11 +1934,18 @@ static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) return is_exposed; } -static void aac_resolve_luns(struct aac_dev *dev) +static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) { int i; - int bus, target; + int bus; + int target; int is_exposed = 0; + int rcode = 0; + + rcode = aac_setup_safw_adapter(dev, rescan); + if (unlikely(rcode < 0)) { + goto out; + } for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { @@ -1953,6 +1960,8 @@ static void aac_resolve_luns(struct aac_dev *dev) is_exposed) aac_remove_safw_device(dev, bus, target); } +out: + return rcode; } /** @@ -1988,9 +1997,7 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: - aac_setup_safw_adapter(dev, AAC_RESCAN); - - aac_resolve_luns(dev); + aac_update_safw_host_devices(dev, AAC_RESCAN); break; case SA_AIF_BPSTAT_CHANGE: -- 2.9.4
[PATCH v2 23/30] scsi: aacraid: Block concurrent hotplug event handling
Currently driver will attempt to process hotplug events concurrently based on the FW interrupt. Protect safw update function with a scan mutex. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commsup.c | 2 ++ drivers/scsi/aacraid/linit.c | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a8fe1e1..c70c998 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1565,6 +1565,7 @@ struct aac_dev spinlock_t fib_lock; struct mutexioctl_mutex; + struct mutexscan_mutex; struct aac_queue_block *queues; /* * The user API will use an IOCTL to register itself to receive diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 34155b1..491e633 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1997,7 +1997,9 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: + mutex_lock(>scan_mutex); aac_update_safw_host_devices(dev, AAC_RESCAN); + mutex_unlock(>scan_mutex); break; case SA_AIF_BPSTAT_CHANGE: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index b2273e3..2c862cd 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1683,6 +1683,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(>fib_lock); mutex_init(>ioctl_mutex); + mutex_init(>scan_mutex); /* * Map in the registers from the adapter. */ -- 2.9.4
[PATCH v2 06/30] scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw
It is possible to restart the controller via the use of the reset_host sysfs variable. This does work for controllers that can no longer respond, since driver will attempt to send down a shutdown in this path. Check if the controller is able to receive commands before sending down a shutdown Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/comminit.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 1bc623a..9eff246 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -295,12 +295,10 @@ int aac_send_shutdown(struct aac_dev * dev) { struct fib * fibctx; struct aac_close *cmd; - int status; + int status = 0; - fibctx = aac_fib_alloc(dev); - if (!fibctx) - return -ENOMEM; - aac_fib_init(fibctx); + if (aac_adapter_check_health(dev)) + return status; if (!dev->adapter_shutdown) { mutex_lock(>ioctl_mutex); @@ -308,6 +306,11 @@ int aac_send_shutdown(struct aac_dev * dev) mutex_unlock(>ioctl_mutex); } + fibctx = aac_fib_alloc(dev); + if (!fibctx) + return -ENOMEM; + aac_fib_init(fibctx); + cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xfffe); -- 2.9.4
[PATCH v2 20/30] scsi: aacraid: Added macros to help loop through known buses and targets
Added macros to loop through the MAX SUPPORTED Buses and Targets. This will make the code a bit easier to read. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aacraid.h | 4 drivers/scsi/aacraid/commsup.c | 34 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 17c6cdd..a8fe1e1 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -117,9 +117,13 @@ enum { /* Thor: 5 phys. buses: #0: empty, 1-4: 256 targets each */ #define AAC_MAX_BUSES 5 #define AAC_MAX_TARGETS256 +#define AAC_BUS_TARGET_LOOP(AAC_MAX_BUSES * AAC_MAX_TARGETS) #define AAC_MAX_NATIVE_SIZE2048 #define FW_ERROR_BUFFER_SIZE 512 +#define get_bus_number(x) (x/AAC_MAX_TARGETS) +#define get_target_number(x) (x%AAC_MAX_TARGETS) + /* Thor AIF events */ #define SA_AIF_HOTPLUG (1<<1) #define SA_AIF_HARDWARE(1<<2) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index ed79159..8966371 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1890,31 +1890,31 @@ static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) static void aac_resolve_luns(struct aac_dev *dev) { + int i; int bus, target, channel; struct scsi_device *sdev; - for (bus = 0; bus < AAC_MAX_BUSES; bus++) { - for (target = 0; target < AAC_MAX_TARGETS; target++) { + for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { - if (bus == CONTAINER_CHANNEL) - channel = CONTAINER_CHANNEL; - else - channel = aac_phys_to_logical(bus); + bus = get_bus_number(i); + target = get_target_number(i); - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, - target, 0); + if (bus == CONTAINER_CHANNEL) + channel = CONTAINER_CHANNEL; + else + channel = aac_phys_to_logical(bus); - if (!sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_add_device(dev->scsi_host_ptr, channel, - target, 0); - else if (sdev && aac_is_safw_target_valid(dev, - bus, target)) - scsi_remove_device(sdev); + sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, + target, 0); - if (sdev) - scsi_device_put(sdev); + if (!sdev && aac_is_safw_target_valid(dev, bus, target)) + scsi_add_device(dev->scsi_host_ptr, channel, + target, 0); + else if (sdev && aac_is_safw_target_valid(dev, bus, target)) + scsi_remove_device(sdev); - } + if (sdev) + scsi_device_put(sdev); } } -- 2.9.4
[PATCH v2 01/30] scsi: aacraid: Fix udev inquiry race condition
When udev requests for a devices inquiry string, it might create multiple threads causing a race condition on the shared inquiry resource string. Created a buffer with the string for each thread. Cc: <sta...@vger.kernel.org> Fixes: 3bc8070fb75b3315 ([SCSI] aacraid: SMC vendor identification) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Replaced kmalloc and memcpy adapter_type_text with kmemdup drivers/scsi/aacraid/aachba.c | 16 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index af3e4d3..548a3e7 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -913,8 +913,16 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) memset(str, ' ', sizeof(*str)); if (sup_adap_info->adapter_type_text[0]) { - char *cp = sup_adap_info->adapter_type_text; int c; + char *cp; + char *cname = kmemdup(sup_adap_info->adapter_type_text, + sizeof(sup_adap_info->adapter_type_text), + GFP_ATOMIC); + + if (!cname) + return; + + cp = cname; if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C')) inqstrcpy("SMC", str->vid); else { @@ -923,7 +931,7 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) ++cp; c = *cp; *cp = '\0'; - inqstrcpy(sup_adap_info->adapter_type_text, str->vid); + inqstrcpy(cname, str->vid); *cp = c; while (*cp && *cp != ' ') ++cp; @@ -937,8 +945,8 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) cp[sizeof(str->pid)] = '\0'; } inqstrcpy (cp, str->pid); - if (c) - cp[sizeof(str->pid)] = c; + + kfree(cname); } else { struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); -- 2.9.4
[PATCH v2 17/30] scsi: aacraid: Add helper function to set queue depth
Add helper function to set queue depth from information retrieved from the bmic phy structure. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 37 - 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index baa3de5..67ca5af 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1755,6 +1755,28 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, return rcode; } +static void aac_set_safw_target_qd(struct aac_dev *dev, int bus, int target) +{ + + struct aac_ciss_identify_pd *identify_resp; + + if (dev->hba_map[bus][target].devtype != AAC_DEVTYPE_NATIVE_RAW) + return; + + identify_resp = dev->hba_map[bus][target].safw_identify_resp; + if (identify_resp == NULL) { + dev->hba_map[bus][target].qd_limit = 32; + return; + } + + if (identify_resp->current_queue_depth_limit <= 0 || + identify_resp->current_queue_depth_limit > 255) + dev->hba_map[bus][target].qd_limit = 32; + else + dev->hba_map[bus][target].qd_limit = + identify_resp->current_queue_depth_limit; +} + static int aac_issue_safw_bmic_identify(struct aac_dev *dev, struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target) { @@ -1781,13 +1803,6 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, if (unlikely(rcode < 0)) goto mem_free_all; - if (identify_reply->current_queue_depth_limit <= 0 || - identify_reply->current_queue_depth_limit > 32) - dev->hba_map[bus][target].qd_limit = 32; - else - dev->hba_map[bus][target].qd_limit = - identify_reply->current_queue_depth_limit; - *identify_resp = identify_reply; out: @@ -1936,17 +1951,14 @@ static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) rcode = aac_issue_safw_bmic_identify(dev, _resp, bus, target); - if (unlikely(rcode < 0)) { - dev->hba_map[bus][target].qd_limit = 32; + if (unlikely(rcode < 0)) goto free_identify_resp; - } dev->hba_map[bus][target].safw_identify_resp = identify_resp; } out: return rcode; - free_identify_resp: aac_free_safw_all_identify_resp(dev, i); goto out; @@ -1995,8 +2007,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } else devtype = AAC_DEVTYPE_ARC_RAW; - if (devtype != AAC_DEVTYPE_NATIVE_RAW) - goto update_devtype; + aac_set_safw_target_qd(dev, bus, target); update_devtype: if (rescan == AAC_INIT) -- 2.9.4
[PATCH v2 16/30] scsi: aacraid: Save bmic phy information for each phy
Save the bmic information for each phy, so that it can processed in target setup function. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Removed unused phy_luns variable drivers/scsi/aacraid/aachba.c | 84 +++--- drivers/scsi/aacraid/aacraid.h | 1 + 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index fa0132b..baa3de5 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1756,7 +1756,7 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, } static int aac_issue_safw_bmic_identify(struct aac_dev *dev, - u32 bus, u32 target) + struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target) { int rcode = -ENOMEM; int datasize; @@ -1779,7 +1779,7 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, rcode = aac_send_safw_bmic_cmd(dev, , identify_reply, datasize); if (unlikely(rcode < 0)) - goto out; + goto mem_free_all; if (identify_reply->current_queue_depth_limit <= 0 || identify_reply->current_queue_depth_limit > 32) @@ -1788,9 +1788,13 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, dev->hba_map[bus][target].qd_limit = identify_reply->current_queue_depth_limit; - kfree(identify_reply); + *identify_resp = identify_reply; + out: return rcode; +mem_free_all: + kfree(identify_reply); + goto out; } static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) @@ -1883,6 +1887,71 @@ static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun) return dev->safw_phys_luns->lun[lun].node_ident[8]; } +static inline void aac_free_safw_identify_resp(struct aac_dev *dev, + int bus, int target) +{ + kfree(dev->hba_map[bus][target].safw_identify_resp); + dev->hba_map[bus][target].safw_identify_resp = NULL; +} + +static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev, + int lun_count) +{ + int luns; + int i; + u32 bus; + u32 target; + + luns = aac_get_safw_phys_lun_count(dev); + + if (luns < lun_count) + lun_count = luns; + else if (lun_count < 0) + lun_count = luns; + + for (i = 0; i < lun_count; i++) { + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + + aac_free_safw_identify_resp(dev, bus, target); + } +} + +static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) +{ + int i; + int rcode = 0; + u32 lun_count; + u32 bus; + u32 target; + struct aac_ciss_identify_pd *identify_resp = NULL; + + lun_count = aac_get_safw_phys_lun_count(dev); + + for (i = 0; i < lun_count; ++i) { + + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + + rcode = aac_issue_safw_bmic_identify(dev, + _resp, bus, target); + + if (unlikely(rcode < 0)) { + dev->hba_map[bus][target].qd_limit = 32; + goto free_identify_resp; + } + + dev->hba_map[bus][target].safw_identify_resp = identify_resp; + } + +out: + return rcode; + +free_identify_resp: + aac_free_safw_all_identify_resp(dev, i); + goto out; +} + /** * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure @@ -1929,9 +1998,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) if (devtype != AAC_DEVTYPE_NATIVE_RAW) goto update_devtype; - if (aac_issue_safw_bmic_identify(dev, bus, target) < 0) - dev->hba_map[bus][target].qd_limit = 32; - update_devtype: if (rescan == AAC_INIT) dev->hba_map[bus][target].devtype = devtype; @@ -1948,8 +2014,14 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) if (unlikely(rcode < 0)) goto out; + rcode = aac_get_safw_attr_all_targets(dev, rescan); + if (unlikely(rcode < 0)) + goto free_ciss_luns; + aac_set_safw_attr_all_targets(dev, rescan); + aac_free_safw_all_identify_resp(dev, -1); +free_ciss_luns: aac_free_safw_ciss_luns(dev); out: return rcode; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 19af4d9..b1a6045 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/d
[PATCH v2 29/30] scsi: aacraid: Remove AAC_HIDE_DISK check in queue command
Earlier driver would scan throgh all supported buses and targets and add devices that responded. It would add devices that were _hidden_ by the fw. Driver would invalidate commands sent to _hidden_ devices via the AAC_HIDE_DISK check. Since the driver now adds only the devices that are supposed to be exposed, this code can be removed. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 10 -- drivers/scsi/aacraid/aacraid.h | 3 --- 2 files changed, 13 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index f498bed..a2bdd79 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1994,8 +1994,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev) if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS) continue; - dev->hba_map[bus][target].expose = expose_flag; - if (expose_flag != 0) { devtype = AAC_DEVTYPE_RAID_MEMBER; goto update_devtype; @@ -2913,14 +2911,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) } } else { /* check for physical non-dasd devices */ bus = aac_logical_to_phys(scmd_channel(scsicmd)); - if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && - (dev->hba_map[bus][cid].expose - == AAC_HIDE_DISK)){ - if (scsicmd->cmnd[0] == INQUIRY) { - scsicmd->result = DID_NO_CONNECT << 16; - goto scsi_done_ret; - } - } if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && dev->hba_map[bus][cid].devtype diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 3e8a44c..4d3536d 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1339,8 +1339,6 @@ struct fib { #define AAC_DEVTYPE_RAID_MEMBER1 #define AAC_DEVTYPE_ARC_RAW2 #define AAC_DEVTYPE_NATIVE_RAW 3 -#define AAC_EXPOSE_DISK0 -#define AAC_HIDE_DISK 3 #define AAC_SAFW_RESCAN_DELAY 10 @@ -1350,7 +1348,6 @@ struct aac_hba_map_info { u8 reset_state;/* 0 - no reset, 1..x - */ /* after xth TM LUN reset */ u16 qd_limit; - u8 expose; /*checks if to expose or not*/ u32 scan_counter; struct aac_ciss_identify_pd *safw_identify_resp; }; -- 2.9.4
[PATCH v2 25/30] scsi: aacraid: Reschedule host scan in case of failure
If the driver fails to retrieve information from the fw (could happen when the fw is not fully in its senses), the driver does nothing and change is not processed correctly by the driver Schedule host rescan in case of failure. This is only for SAFW, since the information retrieval failure will happen on SAFW devices. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Rename rescan worker to match kernel coding conventions drivers/scsi/aacraid/aacraid.h | 27 ++- drivers/scsi/aacraid/commsup.c | 14 +- drivers/scsi/aacraid/linit.c | 5 + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index ba84d99..54078bf 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1341,6 +1341,8 @@ struct fib { #define AAC_EXPOSE_DISK0 #define AAC_HIDE_DISK 3 +#define AAC_SAFW_RESCAN_DELAY 10 + struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ u8 devtype;/* device type */ @@ -1611,6 +1613,7 @@ struct aac_dev int maximum_num_channels; struct fsa_dev_info *fsa_dev; struct task_struct *thread; + struct delayed_work safw_rescan_work; int cardtype; /* *This lock will protect the two 32-bit @@ -2639,12 +2642,35 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) return (dev)->a_ops.adapter_check_health(dev); } + +int aac_scan_host(struct aac_dev *dev, int rescan); + +static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev) +{ + schedule_delayed_work(>safw_rescan_work, AAC_SAFW_RESCAN_DELAY); +} + +static inline void aac_safw_rescan_worker(struct work_struct *work) +{ + struct aac_dev *dev = container_of(to_delayed_work(work), + struct aac_dev, safw_rescan_work); + + aac_scan_host(dev, AAC_RESCAN); +} + +static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) +{ + if (dev->sa_firmware) + cancel_delayed_work_sync(>safw_rescan_work); +} + /* SCp.phase values */ #define AAC_OWNER_MIDLEVEL 0x101 #define AAC_OWNER_LOWLEVEL 0x102 #define AAC_OWNER_ERROR_HANDLER0x103 #define AAC_OWNER_FIRMWARE 0x106 +void aac_safw_rescan_worker(struct work_struct *work); int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); @@ -2719,7 +2745,6 @@ static inline int aac_supports_2T(struct aac_dev *dev) return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); } -int aac_scan_host(struct aac_dev *dev, int rescan); char * get_container_type(unsigned type); extern int numacb; extern char aac_driver_version[]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 4e2687c..d562053 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1964,16 +1964,28 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) return rcode; } +static int aac_scan_safw_host(struct aac_dev *dev, int rescan) +{ + int rcode = 0; + + rcode = aac_update_safw_host_devices(dev, rescan); + if (rcode) + aac_schedule_safw_scan_worker(dev); + + return rcode; +} + int aac_scan_host(struct aac_dev *dev, int rescan) { int rcode = 0; mutex_lock(>scan_mutex); if (dev->sa_firmware) - rcode = aac_update_safw_host_devices(dev, rescan); + rcode = aac_scan_safw_host(dev, rescan); else scsi_scan_host(dev->scsi_host_ptr); mutex_unlock(>scan_mutex); + return rcode; } diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7ea7b2c..bf9d2b7 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1684,6 +1684,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(>ioctl_mutex); mutex_init(>scan_mutex); + + INIT_DELAYED_WORK(>safw_rescan_work, aac_safw_rescan_worker); /* * Map in the registers from the adapter. */ @@ -1873,6 +1875,7 @@ static int aac_suspend(struct pci_dev *pdev, pm_message_t state) struct aac_dev *aac = (struct aac_dev *)shost->hostdata; scsi_block_requests(shost); + aac_cancel_safw_rescan_worker(aac); aac_send_shutdown(aac); aac_release_resources(aac); @@ -1931,6 +1934,7 @@ static void aac_remove_one(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct aac_dev *aac = (struct aac_dev *)shost->hostdata; + aac_cancel_saf
[PATCH 00/30] aacraid: Refactor for sas transport and bug fixes
This patchset primarily lays the foundation for adding sas transport support to the aacraid driver. Being said these patches are mainly code refactors, bug fixes and improvements. - Fixed a udev inquiry race condition - Fixed a kdump hang issue which occurs in case of error recovery in kdump - Made improvements to ioctl reset and reset_host sysfs reset paths - Changed the code to retrieve lun information into stand alone functions. - Merged container and hba hotplug event processing (device addition and and removal into single function) - Removed scsi_scan_host for safw devices and now explicitly add devices retrieved from the fw. - Reschedule scan in driver fails to retrieve lun information from fw. (usually works in a few attempts) - Rescan worker waits for any pending EH recovery before rescanning - Do not trigger rescan worker in kdump kernel Changes in V2: - Added kmemdup intead of kmalloc and memcpy - Changed incorrect reported-by credit - Fixed missing colon in function doc - Used get_unaligned_be32 - Removed unused phy_luns variable - Removed unnecessary bus variable check and assignment - Added patch to increment driver version to 50877 (Missed that one) Raghava Aditya Renukunta (30): scsi: aacraid: Fix udev inquiry race condition scsi: aacraid: Do not attempt abort when Fw panicked scsi: aacraid: Fix hang in kdump scsi: aacraid: Do not remove offlined devices scsi: aacraid: Fix ioctl reset hang scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw scsi: aacraid: Refactor reset_host store function scsi: aacraid: Move code to wait for IO completion to shutdown func scsi: aacraid: Create bmic submission function from bmic identify scsi: aacraid: Change phy luns function to use common bmic function scsi: aacraid: Refactor and rename to make mirror existing changes scsi: aacraid: Add target setup helper function scsi: aacraid: Untangle targets setup from report phy luns scsi: aacraid: Move function around to match existing code scsi: aacraid: Create helper functions to get lun info scsi: aacraid: Save bmic phy information for each phy scsi: aacraid: Add helper function to set queue depth scsi: aacraid: Merge func to get container information scsi: aacraid: Process hba and container hot plug events in single function scsi: aacraid: Added macros to help loop through known buses and targets scsi: aacraid: Refactor resolve luns code and scsi functions scsi: aacraid: Merge adapter setup with resolve luns scsi: aacraid: Block concurrent hotplug event handling scsi: aacraid: Use hotplug handling function in place of scsi_scan_host scsi: aacraid: Reschedule host scan in case of failure scsi: aacraid: Fix hang while scanning in eh recovery scsi: aacraid: Skip schedule rescan in case of kdump scsi: aacraid: Remove unused rescan variable scsi: aacraid: Remove AAC_HIDE_DISK check in queue command scsi: aacraid: Update driver version to 50877 drivers/scsi/aacraid/aachba.c | 468 +++- drivers/scsi/aacraid/aacraid.h | 54 - drivers/scsi/aacraid/commctrl.c | 6 +- drivers/scsi/aacraid/comminit.c | 49 - drivers/scsi/aacraid/commsup.c | 220 ++- drivers/scsi/aacraid/linit.c| 23 +- 6 files changed, 547 insertions(+), 273 deletions(-) -- 2.9.4
[PATCH v2 04/30] scsi: aacraid: Do not remove offlined devices
As part of the recovery process, the drivers removes offline devices ( done by the kernel) and then tries to add them back in the rescan code. Removing the device is like taking a sledgehammer to a nail. Set the device as running if it is marked offline. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/commsup.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index ffbfd04..32b8bdb 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1658,14 +1658,12 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) command->scsi_done(command); } /* -* Any Device that was already marked offline needs to be cleaned up +* Any Device that was already marked offline needs to be marked +* running */ __shost_for_each_device(dev, host) { - if (!scsi_device_online(dev)) { - sdev_printk(KERN_INFO, dev, "Removing offline device\n"); - scsi_remove_device(dev); - scsi_device_put(dev); - } + if (!scsi_device_online(dev)) + scsi_device_set_state(dev, SDEV_RUNNING); } retval = 0; -- 2.9.4
[PATCH v2 09/30] scsi: aacraid: Create bmic submission function from bmic identify
safw command submission is duplicated across many functions. Move the safw submission code from bmic identify into its own function for common use Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 147 +++-- drivers/scsi/aacraid/aacraid.h | 7 +- 2 files changed, 105 insertions(+), 49 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7173ae5..e02158d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1667,60 +1667,116 @@ static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd) (void *) cmd); } -int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) +static int aac_send_safw_bmic_cmd(struct aac_dev *dev, + struct aac_srb_unit *srbu, void *xfer_buf, int xfer_len) { - struct fib *fibptr; - struct aac_srb *srbcmd; - struct sgmap64 *sg64; - struct aac_ciss_identify_pd *identify_resp; - dma_addr_t addr; - u32 vbus, vid; - u16 fibsize, datasize; - int rcode = -ENOMEM; - + struct fib *fibptr; + dma_addr_t addr; + int rcode; + int fibsize; + struct aac_srb *srb; + struct aac_srb_reply *srb_reply; + struct sgmap64 *sg64; + u32 vbus; + u32 vid; + + if (!dev->sa_firmware) + return 0; + /* allocate FIB */ fibptr = aac_fib_alloc(dev); if (!fibptr) - goto out; + return -ENOMEM; - fibsize = sizeof(struct aac_srb) - - sizeof(struct sgentry) + sizeof(struct sgentry64); - datasize = sizeof(struct aac_ciss_identify_pd); + aac_fib_init(fibptr); + fibptr->hw_fib_va->header.XferState &= + ~cpu_to_le32(FastResponseCapable); - identify_resp = dma_alloc_coherent(>pdev->dev, datasize, , - GFP_KERNEL); - if (!identify_resp) - goto fib_free_ptr; + fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + + sizeof(struct sgentry64); - vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_bus); - vid = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_target); + /* allocate DMA buffer for response */ + addr = dma_map_single(>pdev->dev, xfer_buf, xfer_len, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(>pdev->dev, addr)) { + rcode = -ENOMEM; + goto fib_error; + } - aac_fib_init(fibptr); + srb = fib_data(fibptr); + memcpy(srb, >srb, sizeof(struct aac_srb)); - srbcmd = (struct aac_srb *) fib_data(fibptr); - srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(vbus); - srbcmd->id = cpu_to_le32(vid); - srbcmd->lun = 0; - srbcmd->flags= cpu_to_le32(SRB_DataIn); - srbcmd->timeout = cpu_to_le32(10); - srbcmd->retry_limit = 0; - srbcmd->cdb_size = cpu_to_le32(12); - srbcmd->count = cpu_to_le32(datasize); + vbus = (u32)le16_to_cpu( + dev->supplement_adapter_info.virt_device_bus); + vid = (u32)le16_to_cpu( + dev->supplement_adapter_info.virt_device_target); - memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); - srbcmd->cdb[0] = 0x26; - srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF); - srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE; + /* set the common request fields */ + srb->channel= cpu_to_le32(vbus); + srb->id = cpu_to_le32(vid); + srb->lun= 0; + srb->function = cpu_to_le32(SRBF_ExecuteScsi); + srb->timeout= 0; + srb->retry_limit= 0; + srb->cdb_size = cpu_to_le32(16); + srb->count = cpu_to_le32(xfer_len); + + sg64 = (struct sgmap64 *)>sg; + sg64->count = cpu_to_le32(1); + sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); + sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); + sg64->sg[0].count = cpu_to_le32(xfer_len); - sg64 = (struct sgmap64 *)>sg; - sg64->count = cpu_to_le32(1); - sg64->sg[0].addr[1] = cpu_to_le32((u32)(((addr) >> 16) >> 16)); - sg64->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0x)); - sg64->sg[0].count = cpu_to_le32(datasize); + /* +* Copy the updated data for other dumping or other usage
[PATCH v2 13/30] scsi: aacraid: Untangle targets setup from report phy luns
Remove function call to process targets from the report phy luns function and make it a function in its own right. This will help understand the flow of the code. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 44 +++--- drivers/scsi/aacraid/aacraid.h | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 5a95883..629a04d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1799,14 +1799,16 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, * * Update our hba map with the information gathered from the FW */ -static void aac_set_safw_attr_all_targets(struct aac_dev *dev, - struct aac_ciss_phys_luns_resp *phys_luns, int rescan) +static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) { /* ok and extended reporting */ u32 lun_count, nexus; u32 i, bus, target; u8 expose_flag, attribs; u8 devtype; + struct aac_ciss_phys_luns_resp *phys_luns; + + phys_luns = dev->safw_phys_luns; lun_count = ((phys_luns->list_length[0] << 24) + (phys_luns->list_length[1] << 16) @@ -1852,6 +1854,12 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, } } +static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) +{ + kfree(dev->safw_phys_luns); + dev->safw_phys_luns = NULL; +} + /** * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure @@ -1872,7 +1880,7 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); phys_luns = kmalloc(datasize, GFP_KERNEL); if (phys_luns == NULL) - goto err_out; + goto out; memset(, 0, sizeof(struct aac_srb_unit)); @@ -1885,22 +1893,36 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); if (unlikely(rcode < 0)) - goto err_out; + goto mem_free_all; - /* analyse data */ - if (rcode >= 0 && phys_luns->resp_flag == 2) { - /* ok and extended reporting */ - aac_set_safw_attr_all_targets(dev, phys_luns, rescan); + if (phys_luns->resp_flag != 2) { + rcode = -ENOMSG; + goto mem_free_all; } - kfree(phys_luns); -err_out: + dev->safw_phys_luns = phys_luns; + +out: return rcode; +mem_free_all: + kfree(phys_luns); + goto out; + } static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { - return aac_get_safw_ciss_luns(dev, rescan); + int rcode = 0; + + rcode = aac_get_safw_ciss_luns(dev, rescan); + if (unlikely(rcode < 0)) + goto out; + + aac_set_safw_attr_all_targets(dev, rescan); + + aac_free_safw_ciss_luns(dev); +out: + return rcode; } int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 5690767..19af4d9 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1671,6 +1671,7 @@ struct aac_dev struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS]; + struct aac_ciss_phys_luns_resp *safw_phys_luns; u8 adapter_shutdown; u32 handle_pci_error; }; -- 2.9.4
[PATCH v2 08/30] scsi: aacraid: Move code to wait for IO completion to shutdown func
Ideally driver needs to wait for IO to be submitted or responded to before shutdown. Move code to wait for IO completion into shutdown path Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/comminit.c | 36 drivers/scsi/aacraid/commsup.c | 25 - 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 9eff246..0dc7b5a 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include "aacraid.h" @@ -284,6 +286,38 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, q->entries = qsize; } +static void aac_wait_for_io_completion(struct aac_dev *aac) +{ + unsigned long flagv = 0; + int i = 0; + + for (i = 60; i; --i) { + struct scsi_device *dev; + struct scsi_cmnd *command; + int active = 0; + + __shost_for_each_device(dev, aac->scsi_host_ptr) { + spin_lock_irqsave(>list_lock, flagv); + list_for_each_entry(command, >cmd_list, list) { + if (command->SCp.phase == AAC_OWNER_FIRMWARE) { + active++; + break; + } + } + spin_unlock_irqrestore(>list_lock, flagv); + if (active) + break; + + } + /* +* We can exit If all the commands are complete +*/ + if (active == 0) + break; + ssleep(1); + } +} + /** * aac_send_shutdown - shutdown an adapter * @dev: Adapter to shutdown @@ -306,6 +340,8 @@ int aac_send_shutdown(struct aac_dev * dev) mutex_unlock(>ioctl_mutex); } + aac_wait_for_io_completion(dev); + fibctx = aac_fib_alloc(dev); if (!fibctx) return -ENOMEM; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 32b8bdb..9840bd3 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1701,31 +1701,6 @@ int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) */ host = aac->scsi_host_ptr; scsi_block_requests(host); - if (forced < 2) for (retval = 60; retval; --retval) { - struct scsi_device * dev; - struct scsi_cmnd * command; - int active = 0; - - __shost_for_each_device(dev, host) { - spin_lock_irqsave(>list_lock, flagv); - list_for_each_entry(command, >cmd_list, list) { - if (command->SCp.phase == AAC_OWNER_FIRMWARE) { - active++; - break; - } - } - spin_unlock_irqrestore(>list_lock, flagv); - if (active) - break; - - } - /* -* We can exit If all the commands are complete -*/ - if (active == 0) - break; - ssleep(1); - } /* Quiesce build, flush cache, write through mode */ if (forced < 2) -- 2.9.4
[PATCH v2 14/30] scsi: aacraid: Move function around to match existing code
Move the function to get phy luns information to the top of function to set target information Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 112 +- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 629a04d..43a3c11 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1791,6 +1791,62 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, return rcode; } +static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) +{ + kfree(dev->safw_phys_luns); + dev->safw_phys_luns = NULL; +} + +/** + * aac_get_safw_ciss_luns()Process topology change + * @dev: aac_dev structure + * @rescan:Indicates rescan + * + * Execute a CISS REPORT PHYS LUNS and process the results into + * the current hba_map. + */ +static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +{ + int rcode = -ENOMEM; + int datasize; + struct aac_srb *srbcmd; + struct aac_srb_unit srbu; + struct aac_ciss_phys_luns_resp *phys_luns; + + datasize = sizeof(struct aac_ciss_phys_luns_resp) + + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); + phys_luns = kmalloc(datasize, GFP_KERNEL); + if (phys_luns == NULL) + goto out; + + memset(, 0, sizeof(struct aac_srb_unit)); + + srbcmd = + srbcmd->flags = cpu_to_le32(SRB_DataIn); + srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; + srbcmd->cdb[1] = 2; /* extended reporting */ + srbcmd->cdb[8] = (u8)(datasize >> 8); + srbcmd->cdb[9] = (u8)(datasize); + + rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); + if (unlikely(rcode < 0)) + goto mem_free_all; + + if (phys_luns->resp_flag != 2) { + rcode = -ENOMSG; + goto mem_free_all; + } + + dev->safw_phys_luns = phys_luns; + +out: + return rcode; +mem_free_all: + kfree(phys_luns); + goto out; + +} + /** * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure @@ -1854,62 +1910,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } } -static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) -{ - kfree(dev->safw_phys_luns); - dev->safw_phys_luns = NULL; -} - -/** - * aac_get_safw_ciss_luns()Process topology change - * @dev: aac_dev structure - * @rescan:Indicates rescan - * - * Execute a CISS REPORT PHYS LUNS and process the results into - * the current hba_map. - */ -static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) -{ - int rcode = -ENOMEM; - int datasize; - struct aac_srb *srbcmd; - struct aac_srb_unit srbu; - struct aac_ciss_phys_luns_resp *phys_luns; - - datasize = sizeof(struct aac_ciss_phys_luns_resp) + - (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); - phys_luns = kmalloc(datasize, GFP_KERNEL); - if (phys_luns == NULL) - goto out; - - memset(, 0, sizeof(struct aac_srb_unit)); - - srbcmd = - srbcmd->flags = cpu_to_le32(SRB_DataIn); - srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; - srbcmd->cdb[1] = 2; /* extended reporting */ - srbcmd->cdb[8] = (u8)(datasize >> 8); - srbcmd->cdb[9] = (u8)(datasize); - - rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); - if (unlikely(rcode < 0)) - goto mem_free_all; - - if (phys_luns->resp_flag != 2) { - rcode = -ENOMSG; - goto mem_free_all; - } - - dev->safw_phys_luns = phys_luns; - -out: - return rcode; -mem_free_all: - kfree(phys_luns); - goto out; - -} - static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { int rcode = 0; -- 2.9.4
[PATCH v2 12/30] scsi: aacraid: Add target setup helper function
Add helper function to setup targets devices and create the base for the upcoming patches Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/aachba.c | 18 +- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 801aff0..5a95883 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1860,7 +1860,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) { int rcode = -ENOMEM; int datasize; @@ -1898,6 +1898,16 @@ int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) return rcode; } +static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) +{ + return aac_get_safw_ciss_luns(dev, rescan); +} + +int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) +{ + return aac_setup_safw_targets(dev, rescan); +} + int aac_get_adapter_info(struct aac_dev* dev) { struct fib* fibptr; @@ -2001,10 +2011,8 @@ int aac_get_adapter_info(struct aac_dev* dev) } if (!dev->sync_mode && dev->sa_firmware && - dev->supplement_adapter_info.virt_device_bus != 0x) { - /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_get_safw_ciss_luns(dev, AAC_INIT); - } + dev->supplement_adapter_info.virt_device_bus != 0x) + rcode = aac_setup_safw_adapter(dev, AAC_INIT); if (!dev->in_reset) { char buffer[16]; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index d81d0aa..5690767 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2639,7 +2639,7 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); -int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan); +int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); const char *aac_driverinfo(struct Scsi_Host *); void aac_fib_vector_assign(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 82ddc74..f3077b3 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1945,7 +1945,7 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) for (target = 0; target < AAC_MAX_TARGETS; target++) dev->hba_map[bus][target].new_devtype = 0; - rcode = aac_get_safw_ciss_luns(dev, AAC_RESCAN); + rcode = aac_setup_safw_adapter(dev, AAC_RESCAN); aac_resolve_luns(dev); -- 2.9.4
[PATCH v2 02/30] scsi: aacraid: Do not attempt abort when Fw panicked
Check if the adapter can receive abort requests, before sending aborts Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: None drivers/scsi/aacraid/linit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3677bef..5eb0722 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -683,6 +683,9 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) u32 bus, cid; int ret = FAILED; + if (aac_adapter_check_health(aac)) + return ret; + bus = aac_logical_to_phys(scmd_channel(cmd)); cid = scmd_id(cmd); if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { -- 2.9.4
[PATCH v2 10/30] scsi: aacraid: Change phy luns function to use common bmic function
Edit function that retrieves phy lun information to use common bmic function Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- Changes in V2: Added missing colon to match kernel coding style drivers/scsi/aacraid/aachba.c | 75 +- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 11 +-- 3 files changed, 25 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index e02158d..1853bd2 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1853,66 +1853,37 @@ void aac_update_hba_map(struct aac_dev *dev, /** * aac_report_phys_luns() Process topology change * @dev: aac_dev structure - * @fibptr:fib pointer + * @rescan:Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan) +int aac_report_phys_luns(struct aac_dev *dev, int rescan) { - int fibsize, datasize; - struct aac_ciss_phys_luns_resp *phys_luns; + int rcode = -ENOMEM; + int datasize; struct aac_srb *srbcmd; - struct sgmap64 *sg64; - dma_addr_t addr; - u32 vbus, vid; - int rcode = 0; - - /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) - + sizeof(struct sgentry64); - datasize = sizeof(struct aac_ciss_phys_luns_resp) - + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); - - phys_luns = dma_alloc_coherent(>pdev->dev, datasize, , - GFP_KERNEL); - if (phys_luns == NULL) { - rcode = -ENOMEM; - goto err_out; - } - - vbus = (u32) le16_to_cpu( - dev->supplement_adapter_info.virt_device_bus); - vid = (u32) le16_to_cpu( - dev->supplement_adapter_info.virt_device_target); - - aac_fib_init(fibptr); + struct aac_srb_unit srbu; + struct aac_ciss_phys_luns_resp *phys_luns; - srbcmd = (struct aac_srb *) fib_data(fibptr); - srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(vbus); - srbcmd->id = cpu_to_le32(vid); - srbcmd->lun = 0; - srbcmd->flags = cpu_to_le32(SRB_DataIn); - srbcmd->timeout = cpu_to_le32(10); - srbcmd->retry_limit = 0; - srbcmd->cdb_size = cpu_to_le32(12); - srbcmd->count = cpu_to_le32(datasize); + datasize = sizeof(struct aac_ciss_phys_luns_resp) + + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); + phys_luns = kmalloc(datasize, GFP_KERNEL); + if (phys_luns == NULL) + goto err_out; - memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); - srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; - srbcmd->cdb[1] = 2; /* extended reporting */ - srbcmd->cdb[8] = (u8)(datasize >> 8); - srbcmd->cdb[9] = (u8)(datasize); + memset(, 0, sizeof(struct aac_srb_unit)); - sg64 = (struct sgmap64 *) >sg; - sg64->count = cpu_to_le32(1); - sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); - sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); - sg64->sg[0].count = cpu_to_le32(datasize); + srbcmd = + srbcmd->flags = cpu_to_le32(SRB_DataIn); + srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; + srbcmd->cdb[1] = 2; /* extended reporting */ + srbcmd->cdb[8] = (u8)(datasize >> 8); + srbcmd->cdb[9] = (u8)(datasize); - rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, - FsaNormal, 1, 1, NULL, NULL); + rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); + if (unlikely(rcode < 0)) + goto err_out; /* analyse data */ if (rcode >= 0 && phys_luns->resp_flag == 2) { @@ -1920,7 +1891,7 @@ int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan) aac_update_hba_map(dev, phys_luns, rescan); } - dma_free_coherent(>pdev->dev, datasize, phys_luns, addr); + kfree(phys_luns); err_out: return rcode; } @@ -2030,7 +2001,7 @@ int aac_get_adapter_info(struct aac_dev* dev) if (!dev->sync_mode && dev->sa_firmware && dev->supplement_adapter_info.virt_device_bus != 0x) { /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT); + rcode = aac_report_phys_luns(dev, AAC_INIT); } if (!dev->in_reset) { diff --g
RE: [PATCH 08/29] scsi: aacraid: Move code to wait for IO completion to shutdown func
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Friday, December 22, 2017 8:27 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 08/29] scsi: aacraid: Move code to wait for IO completion > to shutdown func > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 17:59 +0000, Bart Van Assche wrote: > > On Thu, 2017-12-21 at 09:33 -0800, Raghava Aditya Renukunta wrote: > > > +static void aac_wait_for_io_completion(struct aac_dev *aac) > > > +{ > > > + unsigned long flagv = 0; > > > + int i = 0; > > > + > > > + for (i = 60; i; --i) { > > > + struct scsi_device *dev; > > > + struct scsi_cmnd *command; > > > + int active = 0; > > > + > > > + __shost_for_each_device(dev, aac->scsi_host_ptr) { > > > + spin_lock_irqsave(>list_lock, flagv); > > > + list_for_each_entry(command, >cmd_list, list) { > > > + if (command->SCp.phase == AAC_OWNER_FIRMWARE) > > > { > > > + active++; > > > + break; > > > + } > > > + } > > > + spin_unlock_irqrestore(>list_lock, flagv); > > > + if (active) > > > + break; > > > + > > > + } > > > + /* > > > +* We can exit If all the commands are complete > > > +*/ > > > + if (active == 0) > > > + break; > > > + ssleep(1); > > > + } > > > +} > > > > Have you considered to call scsi_target_block() and scsi_target_unblock() > instead > > of implementing functionality like the above in a SCSI LLD? > > (replying to my own e-mail) > > It seems like I misread your code - calling scsi_target_block() and > scsi_target_unblock() would not be sufficient. But calling > blk_mq_freeze_queue() > and blk_mq_unfreeze_queue() should be sufficient. The following commit > made these > functions work not only for scsi-mq but also for legacy scsi queues: commit > 055f6e18e08f ("block: Make q_usage_counter also track legacy requests"). Hi Bart, That piece of code is very much legacy that I removed and placed in a function that would benefit all code paths that shutdown the controller. The 2 functions you mentioned are a god send but I think I will hold off on this patchset and do a full refactor with them in the next patchset. ( I suspect that I will have to touch a bunch of different code paths and perform extensive testing to be fully confident) Regards, Raghava Aditya > Bart.
RE: [PATCH 03/29] scsi: aacraid: Fix hang in kdump
> -Original Message- > From: Guilherme G. Piccoli [mailto:gpicc...@linux.vnet.ibm.com] > Sent: Friday, December 22, 2017 7:14 AM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; j...@linux.vnet.ibm.com; > martin.peter...@oracle.com; linux-scsi@vger.kernel.org > Cc: Scott Benesh <scott.ben...@microsemi.com>; dl-esc-Aacraid Linux > Driver <aacr...@microsemi.com>; Tom White > <tom.wh...@microsemi.com>; dougm...@linux.vnet.ibm.com > Subject: Re: [PATCH 03/29] scsi: aacraid: Fix hang in kdump > > EXTERNAL EMAIL > > > On 12/21/2017 03:33 PM, Raghava Aditya Renukunta wrote: > > Driver attempts to perform a device scan and device add after coming out > > of reset. At times when the kdump kernel loads and it tries to perform > > eh recovery, the device scan hangs since its commands are blocked > because > > of the eh recovery. This should have shown up in normal eh recovery path > > (Should have been obvious) > > > > Remove the code that performs scanning.I can live without the rescanning > > support in the stable kernels but a hanging kdump/eh recovery needs to > be > > fixed. > > > > Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after > controller reset) > > Cc: <sta...@vger.kernel.org> > > Reported-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> > > (Sorry in advance for flooding the thread heheh) > I guess it'd be more appropriate to: > > Reported-by: Douglas Miller <dougm...@linux.vnet.ibm.com> > > Although I've tested it, Doug isolated the race condition based on code > analysis... Thank you pointing that out, I will fix it in the next iteration. Regards, Raghava Aditya > Thanks, > > > Guilherme > > > Tested-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> > > Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after > controller reset) > > Signed-off-by: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com> > > --- > > drivers/scsi/aacraid/commsup.c | 9 + > > 1 file changed, 1 insertion(+), 8 deletions(-) > > > > diff --git a/drivers/scsi/aacraid/commsup.c > b/drivers/scsi/aacraid/commsup.c > > index 525a652..ffbfd04 100644 > > --- a/drivers/scsi/aacraid/commsup.c > > +++ b/drivers/scsi/aacraid/commsup.c > > @@ -1672,14 +1672,7 @@ static int _aac_reset_adapter(struct aac_dev > *aac, int forced, u8 reset_type) > > out: > > aac->in_reset = 0; > > scsi_unblock_requests(host); > > - /* > > - * Issue bus rescan to catch any configuration that might have > > - * occurred > > - */ > > - if (!retval) { > > - dev_info(>pdev->dev, "Issuing bus rescan\n"); > > - scsi_scan_host(host); > > - } > > + > > if (jafo) { > > spin_lock_irq(host->host_lock); > > } > >
RE: [PATCH 00/28] aacraid: Refactor for sas transport and bug fixes
> -Original Message- > From: Guilherme G. Piccoli [mailto:gpicc...@linux.vnet.ibm.com] > Sent: Friday, December 22, 2017 7:07 AM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org > Cc: j...@linux.vnet.ibm.com; martin.peter...@oracle.com; Scott Benesh > <scott.ben...@microsemi.com>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Tom White <tom.wh...@microsemi.com> > Subject: Re: [PATCH 00/28] aacraid: Refactor for sas transport and bug fixes > > EXTERNAL EMAIL > > > On 12/21/2017 03:33 PM, Raghava Aditya Renukunta wrote: > > This patchset primarily lays the foundation for adding sas transport > > support to the aacraid driver. Being said these patches are mainly code > > refactors, bug fixes and improvements. > > I was thinking...if possible, and just in case you plan to send a V2 > after Bart's comments (or any other future reviews this patchset gets), > how about splitting in 2 patchsets, one for bug fixes and the other for > improvements/foundation of sas support? > > It could help to speed-up the merge of bug fixes. Hi Guilherme, It did cross my mind, but I wanted to get the sas transport and bug fixes in by 4.16. I thought that breaking the patches into 3 patch sets might not help with it. Regards, Raghava Aditya > Thanks, > > > Guilherme > > > > - Fixed a udev inquiry race condition > > - Fixed a kdump hang issue which occurs in case of error recovery in kdump > > - Made improvements to ioctl reset and reset_host sysfs reset paths > > - Changed the code to retrieve lun information into stand alone functions. > > - Merged container and hba hotplug event processing (device addition and > >and removal into single function) > > - Removed scsi_scan_host for safw devices and now explicitly add devices > >retrieved from the fw. > > - Reschedule scan in driver fails to retrieve lun information from fw. > > (usually works in a few attempts) > > - Rescan worker waits for any pending EH recovery before rescanning > > - Do not trigger rescan worker in kdump kernel > > > > Raghava Aditya Renukunta (29): > > scsi: aacraid: Fix udev inquiry race condition > > scsi: aacraid: Do not attempt abort when Fw panicked > > scsi: aacraid: Fix hang in kdump > > scsi: aacraid: Do not remove offlined devices > > scsi: aacraid: Fix ioctl reset hang > > scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw > > scsi: aacraid: Refactor reset_host store function > > scsi: aacraid: Move code to wait for IO completion to shutdown func > > scsi: aacraid: Create bmic submission function from bmic identify > > scsi: aacraid: Change phy luns function to use common bmic function > > scsi: aacraid: Refactor and rename to make mirror existing changes > > scsi: aacraid: Add target setup helper function > > scsi: aacraid: Untangle targets setup from report phy luns > > scsi: aacraid: Move function around to match existing code > > scsi: aacraid: Create helper functions to get lun info > > scsi: aacraid: Save bmic phy information for each phy > > scsi: aacraid: Add helper function to set queue depth > > scsi: aacraid: Merge func to get container information > > scsi: aacraid: Process hba and container hot plug events in single > > function > > scsi: aacraid: Added macros to help loop through known buses and targets > > scsi: aacraid: Refactor resolve luns code and scsi functions > > scsi: aacraid: Merge adapter setup with resolve luns > > scsi: aacraid: Block concurrent hotplug event handling > > scsi: aacraid: Use hotplug handling function in place of scsi_scan_host > > scsi: aacraid: Reschedule host scan in case of failure > > scsi: aacraid: Fix hang while scanning in eh recovery > > scsi: aacraid: Skip schedule rescan in case of kdump > > scsi: aacraid: Remove unused rescan variable > > scsi: aacraid: Remove AAC_HIDE_DISK check in queue command > > > > drivers/scsi/aacraid/aachba.c | 479 +++ > - > > drivers/scsi/aacraid/aacraid.h | 52 - > > drivers/scsi/aacraid/commctrl.c | 6 +- > > drivers/scsi/aacraid/comminit.c | 49 +++- > > drivers/scsi/aacraid/commsup.c | 224 ++- > > drivers/scsi/aacraid/linit.c| 23 +- > > 6 files changed, 561 insertions(+), 272 deletions(-) > >
RE: [PATCH 25/29] scsi: aacraid: Reschedule host scan in case of failure
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Thursday, December 21, 2017 10:45 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 25/29] scsi: aacraid: Reschedule host scan in case of > failure > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 09:34 -0800, Raghava Aditya Renukunta wrote: > > + struct delayed_work safw_rescan_worker; > > Please make the name of this member variable consistent with other kernel > code. That > means either using e.g. the name "safw_rescan_work" or "safw_rescan". Yes, Will Do, Regards, Raghava Aditya > Thanks, > > Bart.
RE: [PATCH 21/29] scsi: aacraid: Refactor resolve luns code and scsi functions
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Thursday, December 21, 2017 10:43 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 21/29] scsi: aacraid: Refactor resolve luns code and scsi > functions > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 09:34 -0800, Raghava Aditya Renukunta wrote: > > + if (bus == CONTAINER_CHANNEL) > > + bus = CONTAINER_CHANNEL; > > Sorry but I don't see how the above code can be useful? I agree, I did not want to change legacy code a bit too much. I will refactor this in the next iteration. > Thanks, > > Bart.
RE: [PATCH 14/29] scsi: aacraid: Move function around to match existing code
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Thursday, December 21, 2017 10:40 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 14/29] scsi: aacraid: Move function around to match > existing code > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 09:34 -0800, Raghava Aditya Renukunta wrote: > > +/** > > + * aac_get_safw_ciss_luns()Process topology change > > + * @dev: aac_dev structure > > + * @rescan Indicates rescan > > + * > > + * Execute a CISS REPORT PHYS LUNS and process the results into > > + * the current hba_map. > > + */ > > The above function header is not following the kernel-doc syntax: a colon is > missing. Have you tried to build your driver with W=1? That should be > sufficient > with kernel version v4.15-rc1 or later to report kernel-doc header issues. > > Bart. I was not aware of that option I will fix it in the my next version. Regards, Raghava Aditya
RE: [PATCH 15/29] scsi: aacraid: Create helper functions to get lun info
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Thursday, December 21, 2017 10:41 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 15/29] scsi: aacraid: Create helper functions to get lun > info > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 09:34 -0800, Raghava Aditya Renukunta wrote: > > + return ((phys_luns->list_length[0]<<24) + > > + (phys_luns->list_length[1]<<16) + > > + (phys_luns->list_length[2]<<8) + > > + (phys_luns->list_length[3])) / 24; > > Please use get_unaligned_be32() instead of open-coding it. Yes Will do Bart. Thank you Raghava Aditya > Thanks, > > Bart.
RE: [PATCH 01/29] scsi: aacraid: Fix udev inquiry race condition
> -Original Message- > From: Bart Van Assche [mailto:bart.vanass...@wdc.com] > Sent: Thursday, December 21, 2017 9:54 AM > To: j...@linux.vnet.ibm.com; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; linux-scsi@vger.kernel.org; > martin.peter...@oracle.com > Cc: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; > gpicc...@linux.vnet.ibm.com; Tom White <tom.wh...@microsemi.com>; > Scott Benesh <scott.ben...@microsemi.com> > Subject: Re: [PATCH 01/29] scsi: aacraid: Fix udev inquiry race condition > > EXTERNAL EMAIL > > > On Thu, 2017-12-21 at 09:33 -0800, Raghava Aditya Renukunta wrote: > > + char *cp; > > + char *cname = kmalloc(sizeof(sup_adap_info- > >adapter_type_text), > > + GFP_ATOMIC); > > Why did you choose to use GFP_ATOMIC instead of GFP_KERNEL in the > above > kmalloc() call? It was mainly because of a trace call that cut thru the kmalloc call. > > + > > + if (!cname) > > + return; > > + > > + cp = cname; > > + memcpy(cname, sup_adap_info->adapter_type_text, > > + sizeof(sup_adap_info->adapter_type_text)); > > Is the sup_adap_info->adapter_type_text a string that is \0-terminated? If > so, > have you considered to use kmemdup() instead of kmalloc() + memcpy()? I will take that into consideration Bart. Thank you Raghava Aditya > Thanks, > > Bart.
[PATCH 25/29] scsi: aacraid: Reschedule host scan in case of failure
If the driver fails to retrieve information from the fw (could happen when the fw is not fully in its senses), the driver does nothing and change is not processed correctly by the driver Schedule host rescan in case of failure. This is only for SAFW, since the information retrieval failure will happen on SAFW devices. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 27 ++- drivers/scsi/aacraid/commsup.c | 14 +- drivers/scsi/aacraid/linit.c | 5 + 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index ba84d99..70e03ed 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1341,6 +1341,8 @@ struct fib { #define AAC_EXPOSE_DISK0 #define AAC_HIDE_DISK 3 +#define AAC_SAFW_RESCAN_DELAY 10 + struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ u8 devtype;/* device type */ @@ -1611,6 +1613,7 @@ struct aac_dev int maximum_num_channels; struct fsa_dev_info *fsa_dev; struct task_struct *thread; + struct delayed_work safw_rescan_worker; int cardtype; /* *This lock will protect the two 32-bit @@ -2639,12 +2642,35 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) return (dev)->a_ops.adapter_check_health(dev); } + +int aac_scan_host(struct aac_dev *dev, int rescan); + +static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev) +{ + schedule_delayed_work(>safw_rescan_worker, AAC_SAFW_RESCAN_DELAY); +} + +static inline void aac_safw_rescan_worker(struct work_struct *work) +{ + struct aac_dev *dev = container_of(to_delayed_work(work), + struct aac_dev, safw_rescan_worker); + + aac_scan_host(dev, AAC_RESCAN); +} + +static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) +{ + if (dev->sa_firmware) + cancel_delayed_work_sync(>safw_rescan_worker); +} + /* SCp.phase values */ #define AAC_OWNER_MIDLEVEL 0x101 #define AAC_OWNER_LOWLEVEL 0x102 #define AAC_OWNER_ERROR_HANDLER0x103 #define AAC_OWNER_FIRMWARE 0x106 +void aac_safw_rescan_worker(struct work_struct *work); int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); @@ -2719,7 +2745,6 @@ static inline int aac_supports_2T(struct aac_dev *dev) return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); } -int aac_scan_host(struct aac_dev *dev, int rescan); char * get_container_type(unsigned type); extern int numacb; extern char aac_driver_version[]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 46ee7ba..48b5234 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1968,16 +1968,28 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) return rcode; } +static int aac_scan_safw_host(struct aac_dev *dev, int rescan) +{ + int rcode = 0; + + rcode = aac_update_safw_host_devices(dev, rescan); + if (rcode) + aac_schedule_safw_scan_worker(dev); + + return rcode; +} + int aac_scan_host(struct aac_dev *dev, int rescan) { int rcode = 0; mutex_lock(>scan_mutex); if (dev->sa_firmware) - rcode = aac_update_safw_host_devices(dev, rescan); + rcode = aac_scan_safw_host(dev, rescan); else scsi_scan_host(dev->scsi_host_ptr); mutex_unlock(>scan_mutex); + return rcode; } diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 7ea7b2c..d39dc5e 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1684,6 +1684,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) mutex_init(>ioctl_mutex); mutex_init(>scan_mutex); + + INIT_DELAYED_WORK(>safw_rescan_worker, aac_safw_rescan_worker); /* * Map in the registers from the adapter. */ @@ -1873,6 +1875,7 @@ static int aac_suspend(struct pci_dev *pdev, pm_message_t state) struct aac_dev *aac = (struct aac_dev *)shost->hostdata; scsi_block_requests(shost); + aac_cancel_safw_rescan_worker(aac); aac_send_shutdown(aac); aac_release_resources(aac); @@ -1931,6 +1934,7 @@ static void aac_remove_one(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct aac_dev *aac = (struct aac_dev *)shost->hostdata; + aac_cancel_safw_rescan_worker(aac); scsi_remove_host(shost);
[PATCH 29/29] scsi: aacraid: Remove AAC_HIDE_DISK check in queue command
Earlier driver would scan throgh all supported buses and targets and add devices that responded. It would add devices that were _hidden_ by the fw. Driver would invalidate commands sent to _hidden_ devices via the AAC_HIDE_DISK check. Since the driver now adds only the devices that are supposed to be exposed, this code can be removed. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 10 -- drivers/scsi/aacraid/aacraid.h | 3 --- 2 files changed, 13 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index aabbefd..43f9813 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -2005,8 +2005,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev) if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS) continue; - dev->hba_map[bus][target].expose = expose_flag; - if (expose_flag != 0) { devtype = AAC_DEVTYPE_RAID_MEMBER; goto update_devtype; @@ -2924,14 +2922,6 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) } } else { /* check for physical non-dasd devices */ bus = aac_logical_to_phys(scmd_channel(scsicmd)); - if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && - (dev->hba_map[bus][cid].expose - == AAC_HIDE_DISK)){ - if (scsicmd->cmnd[0] == INQUIRY) { - scsicmd->result = DID_NO_CONNECT << 16; - goto scsi_done_ret; - } - } if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS && dev->hba_map[bus][cid].devtype diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 9804d3c..ff1f55f 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1339,8 +1339,6 @@ struct fib { #define AAC_DEVTYPE_RAID_MEMBER1 #define AAC_DEVTYPE_ARC_RAW2 #define AAC_DEVTYPE_NATIVE_RAW 3 -#define AAC_EXPOSE_DISK0 -#define AAC_HIDE_DISK 3 #define AAC_SAFW_RESCAN_DELAY 10 @@ -1350,7 +1348,6 @@ struct aac_hba_map_info { u8 reset_state;/* 0 - no reset, 1..x - */ /* after xth TM LUN reset */ u16 qd_limit; - u8 expose; /*checks if to expose or not*/ u32 scan_counter; struct aac_ciss_identify_pd *safw_identify_resp; }; -- 2.9.4
[PATCH 23/29] scsi: aacraid: Block concurrent hotplug event handling
Currently driver will attempt to process hotplug events concurrently based on the FW interrupt. Protect safw update function with a scan mutex. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commsup.c | 2 ++ drivers/scsi/aacraid/linit.c | 1 + 3 files changed, 4 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a8fe1e1..c70c998 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1565,6 +1565,7 @@ struct aac_dev spinlock_t fib_lock; struct mutexioctl_mutex; + struct mutexscan_mutex; struct aac_queue_block *queues; /* * The user API will use an IOCTL to register itself to receive diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index f781076..698c049 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -2001,7 +2001,9 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: + mutex_lock(>scan_mutex); aac_update_safw_host_devices(dev, AAC_RESCAN); + mutex_unlock(>scan_mutex); break; case SA_AIF_BPSTAT_CHANGE: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index b2273e3..2c862cd 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1683,6 +1683,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) spin_lock_init(>fib_lock); mutex_init(>ioctl_mutex); + mutex_init(>scan_mutex); /* * Map in the registers from the adapter. */ -- 2.9.4
[PATCH 28/29] scsi: aacraid: Remove unused rescan variable
Remove unused rescan variable. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 19 +-- drivers/scsi/aacraid/aacraid.h | 6 +++--- drivers/scsi/aacraid/commsup.c | 14 +++--- drivers/scsi/aacraid/linit.c | 4 ++-- 4 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index eef7322..aabbefd 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1822,12 +1822,11 @@ static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) /** * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure - * @rescan Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +static int aac_get_safw_ciss_luns(struct aac_dev *dev) { int rcode = -ENOMEM; int datasize; @@ -1940,7 +1939,7 @@ static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev, } } -static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) +static int aac_get_safw_attr_all_targets(struct aac_dev *dev) { int i; int rcode = 0; @@ -1983,7 +1982,7 @@ static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) * * Update our hba map with the information gathered from the FW */ -static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) +static void aac_set_safw_attr_all_targets(struct aac_dev *dev) { /* ok and extended reporting */ u32 lun_count, nexus; @@ -2029,7 +2028,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } } -static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) +static int aac_setup_safw_targets(struct aac_dev *dev) { int rcode = 0; @@ -2037,15 +2036,15 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) if (unlikely(rcode < 0)) goto out; - rcode = aac_get_safw_ciss_luns(dev, rescan); + rcode = aac_get_safw_ciss_luns(dev); if (unlikely(rcode < 0)) goto out; - rcode = aac_get_safw_attr_all_targets(dev, rescan); + rcode = aac_get_safw_attr_all_targets(dev); if (unlikely(rcode < 0)) goto free_ciss_luns; - aac_set_safw_attr_all_targets(dev, rescan); + aac_set_safw_attr_all_targets(dev); aac_free_safw_all_identify_resp(dev, -1); free_ciss_luns: @@ -2054,9 +2053,9 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) return rcode; } -int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) +int aac_setup_safw_adapter(struct aac_dev *dev) { - return aac_setup_safw_targets(dev, rescan); + return aac_setup_safw_targets(dev); } int aac_get_adapter_info(struct aac_dev* dev) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 9b678f7..9804d3c 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2644,7 +2644,7 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) } -int aac_scan_host(struct aac_dev *dev, int rescan); +int aac_scan_host(struct aac_dev *dev); static inline void aac_schedule_safw_scan_worker(struct aac_dev *dev) { @@ -2659,7 +2659,7 @@ static inline void aac_safw_rescan_worker(struct work_struct *work) wait_event(dev->scsi_host_ptr->host_wait, !scsi_host_in_recovery(dev->scsi_host_ptr)); - aac_scan_host(dev, AAC_RESCAN); + aac_scan_host(dev); } static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) @@ -2677,7 +2677,7 @@ static inline void aac_cancel_safw_rescan_worker(struct aac_dev *dev) void aac_safw_rescan_worker(struct work_struct *work); int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); -int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); +int aac_setup_safw_adapter(struct aac_dev *dev); const char *aac_driverinfo(struct Scsi_Host *); void aac_fib_vector_assign(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 6f5dfc9..019558f 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1948,7 +1948,7 @@ static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) return is_exposed; } -static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) +static int aac_update_safw_host_devices(struct aac_dev *dev) { int i; int bus; @@ -1956,7 +1956,7 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) int is_exposed = 0; int rc
[PATCH 27/29] scsi: aacraid: Skip schedule rescan in case of kdump
There is a chance of the driver being stuck in kdump if drives start acting up in kdump discovery process and the kernel decides to send eh resets, which would prompt rescan to be scheduled. Do not perform a rescan in kdump context, since we do not expect a hotplug event during kdump and all the devices are going to go away anyway. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commsup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index adebf2e..6f5dfc9 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -1675,7 +1676,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) * Issue bus rescan to catch any configuration that might have * occurred */ - if (!retval) { + if (!retval && !is_kdump_kernel()) { dev_info(>pdev->dev, "Scheduling bus rescan\n"); aac_schedule_safw_scan_worker(aac); } -- 2.9.4
[PATCH 24/29] scsi: aacraid: Use hotplug handling function in place of scsi_scan_host
Driver uses scsi_scan_host to add new devices in the driver init path, which adds all the fw exposed devices. The drivers resorts to queue command checks to block out commands to _hidden_ devices. Use the hotplug handler code to add new devices during driver init and other areas, this is only for safw. For ARC scsi_scan_host will still apply. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 4 drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commsup.c | 18 +++--- drivers/scsi/aacraid/linit.c | 5 +++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 74f1dd2..eef7322 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -2161,10 +2161,6 @@ int aac_get_adapter_info(struct aac_dev* dev) dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount); } - if (!dev->sync_mode && dev->sa_firmware && - dev->supplement_adapter_info.virt_device_bus != 0x) - rcode = aac_setup_safw_adapter(dev, AAC_INIT); - if (!dev->in_reset) { char buffer[16]; tmp = le32_to_cpu(dev->adapter_info.kernelrev); diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index c70c998..ba84d99 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2719,6 +2719,7 @@ static inline int aac_supports_2T(struct aac_dev *dev) return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); } +int aac_scan_host(struct aac_dev *dev, int rescan); char * get_container_type(unsigned type); extern int numacb; extern char aac_driver_version[]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 698c049..46ee7ba 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1968,6 +1968,19 @@ static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) return rcode; } +int aac_scan_host(struct aac_dev *dev, int rescan) +{ + int rcode = 0; + + mutex_lock(>scan_mutex); + if (dev->sa_firmware) + rcode = aac_update_safw_host_devices(dev, rescan); + else + scsi_scan_host(dev->scsi_host_ptr); + mutex_unlock(>scan_mutex); + return rcode; +} + /** * aac_handle_sa_aif Handle a message from the firmware * @dev: Which adapter this fib is from @@ -2001,9 +2014,8 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: - mutex_lock(>scan_mutex); - aac_update_safw_host_devices(dev, AAC_RESCAN); - mutex_unlock(>scan_mutex); + aac_scan_host(dev, AAC_RESCAN); + break; case SA_AIF_BPSTAT_CHANGE: diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 2c862cd..7ea7b2c 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1787,7 +1787,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) error = scsi_add_host(shost, >dev); if (error) goto out_deinit; - scsi_scan_host(shost); + + aac_scan_host(aac, AAC_INIT); pci_enable_pcie_error_reporting(pdev); pci_save_state(pdev); @@ -2071,7 +2072,7 @@ static void aac_pci_resume(struct pci_dev *pdev) if (sdev->sdev_state == SDEV_OFFLINE) sdev->sdev_state = SDEV_RUNNING; scsi_unblock_requests(aac->scsi_host_ptr); - scsi_scan_host(aac->scsi_host_ptr); + aac_scan_host(aac, AAC_RESCAN); pci_save_state(pdev); dev_err(>dev, "aacraid: PCI error - resume\n"); -- 2.9.4
[PATCH 26/29] scsi: aacraid: Fix hang while scanning in eh recovery
Add back the ability to scan for hotplug changes while eh was in progress. Schedule a rescan for a later time in the eh recovery code and wait for eh to complete in the rescan worker. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 4 drivers/scsi/aacraid/commsup.c | 9 + 2 files changed, 13 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 70e03ed..9b678f7 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -41,6 +41,7 @@ #include #include +#include /*-- * D E F I N E S @@ -2655,6 +2656,9 @@ static inline void aac_safw_rescan_worker(struct work_struct *work) struct aac_dev *dev = container_of(to_delayed_work(work), struct aac_dev, safw_rescan_worker); + wait_event(dev->scsi_host_ptr->host_wait, + !scsi_host_in_recovery(dev->scsi_host_ptr)); + aac_scan_host(dev, AAC_RESCAN); } diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 48b5234..adebf2e 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1671,6 +1671,15 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) aac->in_reset = 0; scsi_unblock_requests(host); + /* +* Issue bus rescan to catch any configuration that might have +* occurred +*/ + if (!retval) { + dev_info(>pdev->dev, "Scheduling bus rescan\n"); + aac_schedule_safw_scan_worker(aac); + } + if (jafo) { spin_lock_irq(host->host_lock); } -- 2.9.4
[PATCH 20/29] scsi: aacraid: Added macros to help loop through known buses and targets
Added macros to loop through the MAX SUPPORTED Buses and Targets. This will make the code a bit easier to read. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aacraid.h | 4 drivers/scsi/aacraid/commsup.c | 34 +- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 17c6cdd..a8fe1e1 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -117,9 +117,13 @@ enum { /* Thor: 5 phys. buses: #0: empty, 1-4: 256 targets each */ #define AAC_MAX_BUSES 5 #define AAC_MAX_TARGETS256 +#define AAC_BUS_TARGET_LOOP(AAC_MAX_BUSES * AAC_MAX_TARGETS) #define AAC_MAX_NATIVE_SIZE2048 #define FW_ERROR_BUFFER_SIZE 512 +#define get_bus_number(x) (x/AAC_MAX_TARGETS) +#define get_target_number(x) (x%AAC_MAX_TARGETS) + /* Thor AIF events */ #define SA_AIF_HOTPLUG (1<<1) #define SA_AIF_HARDWARE(1<<2) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index ed79159..8966371 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1890,31 +1890,31 @@ static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) static void aac_resolve_luns(struct aac_dev *dev) { + int i; int bus, target, channel; struct scsi_device *sdev; - for (bus = 0; bus < AAC_MAX_BUSES; bus++) { - for (target = 0; target < AAC_MAX_TARGETS; target++) { + for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { - if (bus == CONTAINER_CHANNEL) - channel = CONTAINER_CHANNEL; - else - channel = aac_phys_to_logical(bus); + bus = get_bus_number(i); + target = get_target_number(i); - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, - target, 0); + if (bus == CONTAINER_CHANNEL) + channel = CONTAINER_CHANNEL; + else + channel = aac_phys_to_logical(bus); - if (!sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_add_device(dev->scsi_host_ptr, channel, - target, 0); - else if (sdev && aac_is_safw_target_valid(dev, - bus, target)) - scsi_remove_device(sdev); + sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, + target, 0); - if (sdev) - scsi_device_put(sdev); + if (!sdev && aac_is_safw_target_valid(dev, bus, target)) + scsi_add_device(dev->scsi_host_ptr, channel, + target, 0); + else if (sdev && aac_is_safw_target_valid(dev, bus, target)) + scsi_remove_device(sdev); - } + if (sdev) + scsi_device_put(sdev); } } -- 2.9.4
[PATCH 22/29] scsi: aacraid: Merge adapter setup with resolve luns
The device hotplug events are processed only after retrieving the updated lun information from the fw. Does not make sense to keep them separate. Merge both the hotplug handling and safw adapter setup code into single function. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commsup.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 2cd880f..f781076 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1938,11 +1938,18 @@ static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) return is_exposed; } -static void aac_resolve_luns(struct aac_dev *dev) +static int aac_update_safw_host_devices(struct aac_dev *dev, int rescan) { int i; - int bus, target; + int bus; + int target; int is_exposed = 0; + int rcode = 0; + + rcode = aac_setup_safw_adapter(dev, rescan); + if (unlikely(rcode < 0)) { + goto out; + } for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { @@ -1957,6 +1964,8 @@ static void aac_resolve_luns(struct aac_dev *dev) is_exposed) aac_remove_safw_device(dev, bus, target); } +out: + return rcode; } /** @@ -1992,9 +2001,7 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) case SA_AIF_LDEV_CHANGE: case SA_AIF_BPCFG_CHANGE: - aac_setup_safw_adapter(dev, AAC_RESCAN); - - aac_resolve_luns(dev); + aac_update_safw_host_devices(dev, AAC_RESCAN); break; case SA_AIF_BPSTAT_CHANGE: -- 2.9.4
[PATCH 21/29] scsi: aacraid: Refactor resolve luns code and scsi functions
Resolve luns checks the if a sdev is already present in the os to figure out if it needs to be removed. Internally the driver exposes HBA on bus 2 even though its bus 1 in the fw. Its mildly confusing. Refactor out the sdev lookup into its function to check if sdev has been added to the kernel or not. Add helper functions to add, remove and put devices based on their fw bus and target number. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commsup.c | 75 -- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 8966371..2cd880f 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1874,6 +1874,43 @@ static inline int is_safw_raid_volume(struct aac_dev *aac, int bus, int target) return bus == CONTAINER_CHANNEL && target < aac->maximum_num_containers; } +static struct scsi_device *aac_lookup_safw_scsi_device(struct aac_dev *dev, + int bus, + int target) +{ + if (bus == CONTAINER_CHANNEL) + bus = CONTAINER_CHANNEL; + else + bus = aac_phys_to_logical(bus); + + return scsi_device_lookup(dev->scsi_host_ptr, bus, target, 0); +} + +static int aac_add_safw_device(struct aac_dev *dev, int bus, int target) +{ + if (bus == CONTAINER_CHANNEL) + bus = CONTAINER_CHANNEL; + else + bus = aac_phys_to_logical(bus); + + return scsi_add_device(dev->scsi_host_ptr, bus, target, 0); +} + +static void aac_put_safw_scsi_device(struct scsi_device *sdev) +{ + if (sdev) + scsi_device_put(sdev); +} + +static void aac_remove_safw_device(struct aac_dev *dev, int bus, int target) +{ + struct scsi_device *sdev; + + sdev = aac_lookup_safw_scsi_device(dev, bus, target); + scsi_remove_device(sdev); + aac_put_safw_scsi_device(sdev); +} + static inline int aac_is_safw_scan_count_equal(struct aac_dev *dev, int bus, int target) { @@ -1888,33 +1925,37 @@ static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) return aac_is_safw_scan_count_equal(dev, bus, target); } +static int aac_is_safw_device_exposed(struct aac_dev *dev, int bus, int target) +{ + int is_exposed = 0; + struct scsi_device *sdev; + + sdev = aac_lookup_safw_scsi_device(dev, bus, target); + if (sdev) + is_exposed = 1; + aac_put_safw_scsi_device(sdev); + + return is_exposed; +} + static void aac_resolve_luns(struct aac_dev *dev) { int i; - int bus, target, channel; - struct scsi_device *sdev; + int bus, target; + int is_exposed = 0; for (i = 0; i < AAC_BUS_TARGET_LOOP; i++) { bus = get_bus_number(i); target = get_target_number(i); - if (bus == CONTAINER_CHANNEL) - channel = CONTAINER_CHANNEL; - else - channel = aac_phys_to_logical(bus); - - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, - target, 0); - - if (!sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_add_device(dev->scsi_host_ptr, channel, - target, 0); - else if (sdev && aac_is_safw_target_valid(dev, bus, target)) - scsi_remove_device(sdev); + is_exposed = aac_is_safw_device_exposed(dev, bus, target); - if (sdev) - scsi_device_put(sdev); + if (aac_is_safw_target_valid(dev, bus, target) && !is_exposed) + aac_add_safw_device(dev, bus, target); + else if (!aac_is_safw_target_valid(dev, bus, target) && + is_exposed) + aac_remove_safw_device(dev, bus, target); } } -- 2.9.4
[PATCH 18/29] scsi: aacraid: Merge func to get container information
Merge aac_get_containers to setup target function, so that information about all the present devices can be retrieved in one shot. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 4 drivers/scsi/aacraid/commsup.c | 34 +++--- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 01cb825..7f6036c 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -2032,6 +2032,10 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { int rcode = 0; + rcode = aac_get_containers(dev); + if (unlikely(rcode < 0)) + goto out; + rcode = aac_get_safw_ciss_luns(dev, rescan); if (unlikely(rcode < 0)) goto out; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index f3077b3..9625eb0 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1949,26 +1949,22 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) aac_resolve_luns(dev); - if (events == SA_AIF_LDEV_CHANGE || - events == SA_AIF_BPCFG_CHANGE) { - aac_get_containers(dev); - for (container = 0; container < + for (container = 0; container < dev->maximum_num_containers; ++container) { - sdev = scsi_device_lookup(dev->scsi_host_ptr, - CONTAINER_CHANNEL, - container, 0); - if (dev->fsa_dev[container].valid && !sdev) { - scsi_add_device(dev->scsi_host_ptr, - CONTAINER_CHANNEL, - container, 0); - } else if (!dev->fsa_dev[container].valid && - sdev) { - scsi_remove_device(sdev); - scsi_device_put(sdev); - } else if (sdev) { - scsi_rescan_device(>sdev_gendev); - scsi_device_put(sdev); - } + sdev = scsi_device_lookup(dev->scsi_host_ptr, + CONTAINER_CHANNEL, + container, 0); + if (dev->fsa_dev[container].valid && !sdev) { + scsi_add_device(dev->scsi_host_ptr, + CONTAINER_CHANNEL, + container, 0); + } else if (!dev->fsa_dev[container].valid && + sdev) { + scsi_remove_device(sdev); + scsi_device_put(sdev); + } else if (sdev) { + scsi_rescan_device(>sdev_gendev); + scsi_device_put(sdev); } } break; -- 2.9.4
[PATCH 12/29] scsi: aacraid: Add target setup helper function
Add helper function to setup targets devices and create the base for the upcoming patches Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 18 +- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index d6b626d..90377b1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1863,7 +1863,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) { int rcode = -ENOMEM; int datasize; @@ -1901,6 +1901,16 @@ int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) return rcode; } +static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) +{ + return aac_get_safw_ciss_luns(dev, rescan); +} + +int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) +{ + return aac_setup_safw_targets(dev, rescan); +} + int aac_get_adapter_info(struct aac_dev* dev) { struct fib* fibptr; @@ -2004,10 +2014,8 @@ int aac_get_adapter_info(struct aac_dev* dev) } if (!dev->sync_mode && dev->sa_firmware && - dev->supplement_adapter_info.virt_device_bus != 0x) { - /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_get_safw_ciss_luns(dev, AAC_INIT); - } + dev->supplement_adapter_info.virt_device_bus != 0x) + rcode = aac_setup_safw_adapter(dev, AAC_INIT); if (!dev->in_reset) { char buffer[16]; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index d81d0aa..5690767 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2639,7 +2639,7 @@ static inline int aac_adapter_check_health(struct aac_dev *dev) int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); -int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan); +int aac_setup_safw_adapter(struct aac_dev *dev, int rescan); const char *aac_driverinfo(struct Scsi_Host *); void aac_fib_vector_assign(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 82ddc74..f3077b3 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1945,7 +1945,7 @@ static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr) for (target = 0; target < AAC_MAX_TARGETS; target++) dev->hba_map[bus][target].new_devtype = 0; - rcode = aac_get_safw_ciss_luns(dev, AAC_RESCAN); + rcode = aac_setup_safw_adapter(dev, AAC_RESCAN); aac_resolve_luns(dev); -- 2.9.4
[PATCH 15/29] scsi: aacraid: Create helper functions to get lun info
Created inline function to retrieve lun info for each device from the phy luns structure. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 59 ++- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index affa2f1..83d2576 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1847,7 +1847,48 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) mem_free_all: kfree(phys_luns); goto out; +} + +static inline u32 aac_get_safw_phys_lun_count(struct aac_dev *dev) +{ + struct aac_ciss_phys_luns_resp *phys_luns; + + phys_luns = dev->safw_phys_luns; + + return ((phys_luns->list_length[0]<<24) + + (phys_luns->list_length[1]<<16) + + (phys_luns->list_length[2]<<8) + + (phys_luns->list_length[3])) / 24; +} +static inline u32 aac_get_safw_phys_bus(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].level2[1] & 0x3f; +} + +static inline u32 aac_get_safw_phys_target(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].level2[0]; +} + +static inline u32 aac_get_safw_phys_expose_flag(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].bus >> 6; +} + +static inline u32 aac_get_safw_phys_attribs(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].node_ident[9]; +} + +static inline u32 aac_get_safw_phys_nexus(struct aac_dev *dev, int lun) +{ + return *((u32 *)>safw_phys_luns->lun[lun].node_ident[12]); +} + +static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun) +{ + return dev->safw_phys_luns->lun[lun].node_ident[8]; } /** @@ -1865,22 +1906,16 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) u32 i, bus, target; u8 expose_flag, attribs; u8 devtype; - struct aac_ciss_phys_luns_resp *phys_luns; - - phys_luns = dev->safw_phys_luns; - lun_count = ((phys_luns->list_length[0] << 24) - + (phys_luns->list_length[1] << 16) - + (phys_luns->list_length[2] << 8) - + (phys_luns->list_length[3])) / 24; + lun_count = aac_get_safw_phys_lun_count(dev); for (i = 0; i < lun_count; ++i) { - bus = phys_luns->lun[i].level2[1] & 0x3f; - target = phys_luns->lun[i].level2[0]; - expose_flag = phys_luns->lun[i].bus >> 6; - attribs = phys_luns->lun[i].node_ident[9]; - nexus = *((u32 *) _luns->lun[i].node_ident[12]); + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + expose_flag = aac_get_safw_phys_expose_flag(dev, i); + attribs = aac_get_safw_phys_attribs(dev, i); + nexus = aac_get_safw_phys_nexus(dev, i); if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS) continue; -- 2.9.4
[PATCH 17/29] scsi: aacraid: Add helper function to set queue depth
Add helper function to set queue depth from information retrieved from the bmic phy structure. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 37 - 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index a29c8fb..01cb825 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1756,6 +1756,28 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, return rcode; } +static void aac_set_safw_target_qd(struct aac_dev *dev, int bus, int target) +{ + + struct aac_ciss_identify_pd *identify_resp; + + if (dev->hba_map[bus][target].devtype != AAC_DEVTYPE_NATIVE_RAW) + return; + + identify_resp = dev->hba_map[bus][target].safw_identify_resp; + if (identify_resp == NULL) { + dev->hba_map[bus][target].qd_limit = 32; + return; + } + + if (identify_resp->current_queue_depth_limit <= 0 || + identify_resp->current_queue_depth_limit > 255) + dev->hba_map[bus][target].qd_limit = 32; + else + dev->hba_map[bus][target].qd_limit = + identify_resp->current_queue_depth_limit; +} + static int aac_issue_safw_bmic_identify(struct aac_dev *dev, struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target) { @@ -1782,13 +1804,6 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, if (unlikely(rcode < 0)) goto mem_free_all; - if (identify_reply->current_queue_depth_limit <= 0 || - identify_reply->current_queue_depth_limit > 32) - dev->hba_map[bus][target].qd_limit = 32; - else - dev->hba_map[bus][target].qd_limit = - identify_reply->current_queue_depth_limit; - *identify_resp = identify_reply; out: @@ -1947,17 +1962,14 @@ static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) rcode = aac_issue_safw_bmic_identify(dev, _resp, bus, target); - if (unlikely(rcode < 0)) { - dev->hba_map[bus][target].qd_limit = 32; + if (unlikely(rcode < 0)) goto free_identify_resp; - } dev->hba_map[bus][target].safw_identify_resp = identify_resp; } out: return rcode; - free_identify_resp: aac_free_safw_all_identify_resp(dev, i); goto out; @@ -2006,8 +2018,7 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } else devtype = AAC_DEVTYPE_ARC_RAW; - if (devtype != AAC_DEVTYPE_NATIVE_RAW) - goto update_devtype; + aac_set_safw_target_qd(dev, bus, target); update_devtype: if (rescan == AAC_INIT) -- 2.9.4
[PATCH 19/29] scsi: aacraid: Process hba and container hot plug events in single function
The hotplug handler code is duplicated for hba handling and container handling. Merged function to handle hba and container hot plug events into the resolve luns functions. Added a bunch of helper functions to check the validity of a given target and to check if bus, target is container device. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 9 --- drivers/scsi/aacraid/aacraid.h | 3 ++- drivers/scsi/aacraid/commsup.c | 59 -- 3 files changed, 30 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7f6036c..74f1dd2 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1993,6 +1993,8 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) lun_count = aac_get_safw_phys_lun_count(dev); + dev->scan_counter++; + for (i = 0; i < lun_count; ++i) { bus = aac_get_safw_phys_bus(dev, i); @@ -2018,13 +2020,12 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } else devtype = AAC_DEVTYPE_ARC_RAW; + dev->hba_map[bus][target].scan_counter = dev->scan_counter; + aac_set_safw_target_qd(dev, bus, target); update_devtype: - if (rescan == AAC_INIT) - dev->hba_map[bus][target].devtype = devtype; - else - dev->hba_map[bus][target].new_devtype = devtype; + dev->hba_map[bus][target].devtype = devtype; } } diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index b1a6045..17c6cdd 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1340,11 +1340,11 @@ struct fib { struct aac_hba_map_info { __le32 rmw_nexus; /* nexus for native HBA devices */ u8 devtype;/* device type */ - u8 new_devtype; u8 reset_state;/* 0 - no reset, 1..x - */ /* after xth TM LUN reset */ u16 qd_limit; u8 expose; /*checks if to expose or not*/ + u32 scan_counter; struct aac_ciss_identify_pd *safw_identify_resp; }; @@ -1669,6 +1669,7 @@ struct aac_dev u32 vector_cap; /* MSI-X vector capab.*/ int msi_enabled;/* MSI/MSI-X enabled */ atomic_tmsix_counter; + u32 scan_counter; struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS]; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 9625eb0..ed79159 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1869,13 +1869,29 @@ int aac_check_health(struct aac_dev * aac) return BlinkLED; } +static inline int is_safw_raid_volume(struct aac_dev *aac, int bus, int target) +{ + return bus == CONTAINER_CHANNEL && target < aac->maximum_num_containers; +} + +static inline int aac_is_safw_scan_count_equal(struct aac_dev *dev, + int bus, int target) +{ + return dev->hba_map[bus][target].scan_counter == dev->scan_counter; +} + +static int aac_is_safw_target_valid(struct aac_dev *dev, int bus, int target) +{ + if (is_safw_raid_volume(dev, bus, target)) + return dev->fsa_dev[target].valid; + else + return aac_is_safw_scan_count_equal(dev, bus, target); +} static void aac_resolve_luns(struct aac_dev *dev) { int bus, target, channel; struct scsi_device *sdev; - u8 devtype; - u8 new_devtype; for (bus = 0; bus < AAC_MAX_BUSES; bus++) { for (target = 0; target < AAC_MAX_TARGETS; target++) { @@ -1885,24 +1901,19 @@ static void aac_resolve_luns(struct aac_dev *dev) else channel = aac_phys_to_logical(bus); - devtype = dev->hba_map[bus][target].devtype; - new_devtype = dev->hba_map[bus][target].new_devtype; - sdev = scsi_device_lookup(dev->scsi_host_ptr, channel, target, 0); - if (!sdev && new_devtype) + if (!sdev && aac_is_safw_target_valid(dev, bus, target)) scsi_add_device(dev->scsi_host_ptr, channel, target, 0); - else if (sdev && n
[PATCH 02/29] scsi: aacraid: Do not attempt abort when Fw panicked
Check if the adapter can receive abort requests, before sending aborts Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/linit.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 3677bef..5eb0722 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -683,6 +683,9 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) u32 bus, cid; int ret = FAILED; + if (aac_adapter_check_health(aac)) + return ret; + bus = aac_logical_to_phys(scmd_channel(cmd)); cid = scmd_id(cmd); if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) { -- 2.9.4
[PATCH 16/29] scsi: aacraid: Save bmic phy information for each phy
Save the bmic information for each phy, so that it can processed in target setup function. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 87 +++--- drivers/scsi/aacraid/aacraid.h | 1 + 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 83d2576..a29c8fb 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1757,7 +1757,7 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, } static int aac_issue_safw_bmic_identify(struct aac_dev *dev, - u32 bus, u32 target) + struct aac_ciss_identify_pd **identify_resp, u32 bus, u32 target) { int rcode = -ENOMEM; int datasize; @@ -1780,7 +1780,7 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, rcode = aac_send_safw_bmic_cmd(dev, , identify_reply, datasize); if (unlikely(rcode < 0)) - goto out; + goto mem_free_all; if (identify_reply->current_queue_depth_limit <= 0 || identify_reply->current_queue_depth_limit > 32) @@ -1789,9 +1789,13 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, dev->hba_map[bus][target].qd_limit = identify_reply->current_queue_depth_limit; - kfree(identify_reply); + *identify_resp = identify_reply; + out: return rcode; +mem_free_all: + kfree(identify_reply); + goto out; } static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) @@ -1891,6 +1895,74 @@ static inline u32 aac_get_safw_phys_device_type(struct aac_dev *dev, int lun) return dev->safw_phys_luns->lun[lun].node_ident[8]; } +static inline void aac_free_safw_identify_resp(struct aac_dev *dev, + int bus, int target) +{ + kfree(dev->hba_map[bus][target].safw_identify_resp); + dev->hba_map[bus][target].safw_identify_resp = NULL; +} + +static inline void aac_free_safw_all_identify_resp(struct aac_dev *dev, + int lun_count) +{ + int luns; + int i; + u32 bus; + u32 target; + + luns = aac_get_safw_phys_lun_count(dev); + + if (luns < lun_count) + lun_count = luns; + else if (lun_count < 0) + lun_count = luns; + + for (i = 0; i < lun_count; i++) { + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + + aac_free_safw_identify_resp(dev, bus, target); + } +} + +static int aac_get_safw_attr_all_targets(struct aac_dev *dev, int rescan) +{ + int i; + int rcode = 0; + u32 lun_count; + u32 bus; + u32 target; + struct aac_ciss_phys_luns_resp *phys_luns; + struct aac_ciss_identify_pd *identify_resp = NULL; + + phys_luns = dev->safw_phys_luns; + + lun_count = aac_get_safw_phys_lun_count(dev); + + for (i = 0; i < lun_count; ++i) { + + bus = aac_get_safw_phys_bus(dev, i); + target = aac_get_safw_phys_target(dev, i); + + rcode = aac_issue_safw_bmic_identify(dev, + _resp, bus, target); + + if (unlikely(rcode < 0)) { + dev->hba_map[bus][target].qd_limit = 32; + goto free_identify_resp; + } + + dev->hba_map[bus][target].safw_identify_resp = identify_resp; + } + +out: + return rcode; + +free_identify_resp: + aac_free_safw_all_identify_resp(dev, i); + goto out; +} + /** * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure @@ -1937,9 +2009,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) if (devtype != AAC_DEVTYPE_NATIVE_RAW) goto update_devtype; - if (aac_issue_safw_bmic_identify(dev, bus, target) < 0) - dev->hba_map[bus][target].qd_limit = 32; - update_devtype: if (rescan == AAC_INIT) dev->hba_map[bus][target].devtype = devtype; @@ -1956,8 +2025,14 @@ static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) if (unlikely(rcode < 0)) goto out; + rcode = aac_get_safw_attr_all_targets(dev, rescan); + if (unlikely(rcode < 0)) + goto free_ciss_luns; + aac_set_safw_attr_all_targets(dev, rescan); + aac_free_safw_all_identify_resp(dev, -1); +free_ciss_luns: aac_free_safw_ciss_luns(dev); out: return rcode; diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 19af4d9..b1a6045 100644 --- a/drivers/
[PATCH 10/29] scsi: aacraid: Change phy luns function to use common bmic function
Edit function that retrieves phy lun information to use common bmic function Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 75 +- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 11 +-- 3 files changed, 25 insertions(+), 63 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 8d119e1..8fb0da7 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1856,66 +1856,37 @@ void aac_update_hba_map(struct aac_dev *dev, /** * aac_report_phys_luns() Process topology change * @dev: aac_dev structure - * @fibptr:fib pointer + * @rescan Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan) +int aac_report_phys_luns(struct aac_dev *dev, int rescan) { - int fibsize, datasize; - struct aac_ciss_phys_luns_resp *phys_luns; + int rcode = -ENOMEM; + int datasize; struct aac_srb *srbcmd; - struct sgmap64 *sg64; - dma_addr_t addr; - u32 vbus, vid; - int rcode = 0; - - /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) - + sizeof(struct sgentry64); - datasize = sizeof(struct aac_ciss_phys_luns_resp) - + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); - - phys_luns = dma_alloc_coherent(>pdev->dev, datasize, , - GFP_KERNEL); - if (phys_luns == NULL) { - rcode = -ENOMEM; - goto err_out; - } - - vbus = (u32) le16_to_cpu( - dev->supplement_adapter_info.virt_device_bus); - vid = (u32) le16_to_cpu( - dev->supplement_adapter_info.virt_device_target); - - aac_fib_init(fibptr); + struct aac_srb_unit srbu; + struct aac_ciss_phys_luns_resp *phys_luns; - srbcmd = (struct aac_srb *) fib_data(fibptr); - srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(vbus); - srbcmd->id = cpu_to_le32(vid); - srbcmd->lun = 0; - srbcmd->flags = cpu_to_le32(SRB_DataIn); - srbcmd->timeout = cpu_to_le32(10); - srbcmd->retry_limit = 0; - srbcmd->cdb_size = cpu_to_le32(12); - srbcmd->count = cpu_to_le32(datasize); + datasize = sizeof(struct aac_ciss_phys_luns_resp) + + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); + phys_luns = kmalloc(datasize, GFP_KERNEL); + if (phys_luns == NULL) + goto err_out; - memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); - srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; - srbcmd->cdb[1] = 2; /* extended reporting */ - srbcmd->cdb[8] = (u8)(datasize >> 8); - srbcmd->cdb[9] = (u8)(datasize); + memset(, 0, sizeof(struct aac_srb_unit)); - sg64 = (struct sgmap64 *) >sg; - sg64->count = cpu_to_le32(1); - sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); - sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); - sg64->sg[0].count = cpu_to_le32(datasize); + srbcmd = + srbcmd->flags = cpu_to_le32(SRB_DataIn); + srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; + srbcmd->cdb[1] = 2; /* extended reporting */ + srbcmd->cdb[8] = (u8)(datasize >> 8); + srbcmd->cdb[9] = (u8)(datasize); - rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize, - FsaNormal, 1, 1, NULL, NULL); + rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); + if (unlikely(rcode < 0)) + goto err_out; /* analyse data */ if (rcode >= 0 && phys_luns->resp_flag == 2) { @@ -1923,7 +1894,7 @@ int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan) aac_update_hba_map(dev, phys_luns, rescan); } - dma_free_coherent(>pdev->dev, datasize, phys_luns, addr); + kfree(phys_luns); err_out: return rcode; } @@ -2033,7 +2004,7 @@ int aac_get_adapter_info(struct aac_dev* dev) if (!dev->sync_mode && dev->sa_firmware && dev->supplement_adapter_info.virt_device_bus != 0x) { /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT); + rcode = aac_report_phys_luns(dev, AAC_INIT); } if (!dev->in_reset) { diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi
[PATCH 13/29] scsi: aacraid: Untangle targets setup from report phy luns
Remove function call to process targets from the report phy luns function and make it a function in its own right. This will help understand the flow of the code. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 44 +++--- drivers/scsi/aacraid/aacraid.h | 1 + 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 90377b1..cf02910 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1802,14 +1802,16 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, * * Update our hba map with the information gathered from the FW */ -static void aac_set_safw_attr_all_targets(struct aac_dev *dev, - struct aac_ciss_phys_luns_resp *phys_luns, int rescan) +static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) { /* ok and extended reporting */ u32 lun_count, nexus; u32 i, bus, target; u8 expose_flag, attribs; u8 devtype; + struct aac_ciss_phys_luns_resp *phys_luns; + + phys_luns = dev->safw_phys_luns; lun_count = ((phys_luns->list_length[0] << 24) + (phys_luns->list_length[1] << 16) @@ -1855,6 +1857,12 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, } } +static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) +{ + kfree(dev->safw_phys_luns); + dev->safw_phys_luns = NULL; +} + /** * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure @@ -1875,7 +1883,7 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); phys_luns = kmalloc(datasize, GFP_KERNEL); if (phys_luns == NULL) - goto err_out; + goto out; memset(, 0, sizeof(struct aac_srb_unit)); @@ -1888,22 +1896,36 @@ static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); if (unlikely(rcode < 0)) - goto err_out; + goto mem_free_all; - /* analyse data */ - if (rcode >= 0 && phys_luns->resp_flag == 2) { - /* ok and extended reporting */ - aac_set_safw_attr_all_targets(dev, phys_luns, rescan); + if (phys_luns->resp_flag != 2) { + rcode = -ENOMSG; + goto mem_free_all; } - kfree(phys_luns); -err_out: + dev->safw_phys_luns = phys_luns; + +out: return rcode; +mem_free_all: + kfree(phys_luns); + goto out; + } static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { - return aac_get_safw_ciss_luns(dev, rescan); + int rcode = 0; + + rcode = aac_get_safw_ciss_luns(dev, rescan); + if (unlikely(rcode < 0)) + goto out; + + aac_set_safw_attr_all_targets(dev, rescan); + + aac_free_safw_ciss_luns(dev); +out: + return rcode; } int aac_setup_safw_adapter(struct aac_dev *dev, int rescan) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 5690767..19af4d9 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1671,6 +1671,7 @@ struct aac_dev struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ struct aac_hba_map_info hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS]; + struct aac_ciss_phys_luns_resp *safw_phys_luns; u8 adapter_shutdown; u32 handle_pci_error; }; -- 2.9.4
[PATCH 08/29] scsi: aacraid: Move code to wait for IO completion to shutdown func
Ideally driver needs to wait for IO to be submitted or responded to before shutdown. Move code to wait for IO completion into shutdown path Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/comminit.c | 36 drivers/scsi/aacraid/commsup.c | 25 - 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 9eff246..0dc7b5a 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -42,6 +42,8 @@ #include #include #include +#include +#include #include "aacraid.h" @@ -284,6 +286,38 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, q->entries = qsize; } +static void aac_wait_for_io_completion(struct aac_dev *aac) +{ + unsigned long flagv = 0; + int i = 0; + + for (i = 60; i; --i) { + struct scsi_device *dev; + struct scsi_cmnd *command; + int active = 0; + + __shost_for_each_device(dev, aac->scsi_host_ptr) { + spin_lock_irqsave(>list_lock, flagv); + list_for_each_entry(command, >cmd_list, list) { + if (command->SCp.phase == AAC_OWNER_FIRMWARE) { + active++; + break; + } + } + spin_unlock_irqrestore(>list_lock, flagv); + if (active) + break; + + } + /* +* We can exit If all the commands are complete +*/ + if (active == 0) + break; + ssleep(1); + } +} + /** * aac_send_shutdown - shutdown an adapter * @dev: Adapter to shutdown @@ -306,6 +340,8 @@ int aac_send_shutdown(struct aac_dev * dev) mutex_unlock(>ioctl_mutex); } + aac_wait_for_io_completion(dev); + fibctx = aac_fib_alloc(dev); if (!fibctx) return -ENOMEM; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 32b8bdb..9840bd3 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1701,31 +1701,6 @@ int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) */ host = aac->scsi_host_ptr; scsi_block_requests(host); - if (forced < 2) for (retval = 60; retval; --retval) { - struct scsi_device * dev; - struct scsi_cmnd * command; - int active = 0; - - __shost_for_each_device(dev, host) { - spin_lock_irqsave(>list_lock, flagv); - list_for_each_entry(command, >cmd_list, list) { - if (command->SCp.phase == AAC_OWNER_FIRMWARE) { - active++; - break; - } - } - spin_unlock_irqrestore(>list_lock, flagv); - if (active) - break; - - } - /* -* We can exit If all the commands are complete -*/ - if (active == 0) - break; - ssleep(1); - } /* Quiesce build, flush cache, write through mode */ if (forced < 2) -- 2.9.4
[PATCH 14/29] scsi: aacraid: Move function around to match existing code
Move the function to get phy luns information to the top of function to set target information Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 112 +- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index cf02910..affa2f1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1794,6 +1794,62 @@ static int aac_issue_safw_bmic_identify(struct aac_dev *dev, return rcode; } +static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) +{ + kfree(dev->safw_phys_luns); + dev->safw_phys_luns = NULL; +} + +/** + * aac_get_safw_ciss_luns()Process topology change + * @dev: aac_dev structure + * @rescan Indicates rescan + * + * Execute a CISS REPORT PHYS LUNS and process the results into + * the current hba_map. + */ +static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) +{ + int rcode = -ENOMEM; + int datasize; + struct aac_srb *srbcmd; + struct aac_srb_unit srbu; + struct aac_ciss_phys_luns_resp *phys_luns; + + datasize = sizeof(struct aac_ciss_phys_luns_resp) + + (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); + phys_luns = kmalloc(datasize, GFP_KERNEL); + if (phys_luns == NULL) + goto out; + + memset(, 0, sizeof(struct aac_srb_unit)); + + srbcmd = + srbcmd->flags = cpu_to_le32(SRB_DataIn); + srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; + srbcmd->cdb[1] = 2; /* extended reporting */ + srbcmd->cdb[8] = (u8)(datasize >> 8); + srbcmd->cdb[9] = (u8)(datasize); + + rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); + if (unlikely(rcode < 0)) + goto mem_free_all; + + if (phys_luns->resp_flag != 2) { + rcode = -ENOMSG; + goto mem_free_all; + } + + dev->safw_phys_luns = phys_luns; + +out: + return rcode; +mem_free_all: + kfree(phys_luns); + goto out; + +} + /** * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure @@ -1857,62 +1913,6 @@ static void aac_set_safw_attr_all_targets(struct aac_dev *dev, int rescan) } } -static inline void aac_free_safw_ciss_luns(struct aac_dev *dev) -{ - kfree(dev->safw_phys_luns); - dev->safw_phys_luns = NULL; -} - -/** - * aac_get_safw_ciss_luns()Process topology change - * @dev: aac_dev structure - * @rescan Indicates rescan - * - * Execute a CISS REPORT PHYS LUNS and process the results into - * the current hba_map. - */ -static int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) -{ - int rcode = -ENOMEM; - int datasize; - struct aac_srb *srbcmd; - struct aac_srb_unit srbu; - struct aac_ciss_phys_luns_resp *phys_luns; - - datasize = sizeof(struct aac_ciss_phys_luns_resp) + - (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun); - phys_luns = kmalloc(datasize, GFP_KERNEL); - if (phys_luns == NULL) - goto out; - - memset(, 0, sizeof(struct aac_srb_unit)); - - srbcmd = - srbcmd->flags = cpu_to_le32(SRB_DataIn); - srbcmd->cdb[0] = CISS_REPORT_PHYSICAL_LUNS; - srbcmd->cdb[1] = 2; /* extended reporting */ - srbcmd->cdb[8] = (u8)(datasize >> 8); - srbcmd->cdb[9] = (u8)(datasize); - - rcode = aac_send_safw_bmic_cmd(dev, , phys_luns, datasize); - if (unlikely(rcode < 0)) - goto mem_free_all; - - if (phys_luns->resp_flag != 2) { - rcode = -ENOMSG; - goto mem_free_all; - } - - dev->safw_phys_luns = phys_luns; - -out: - return rcode; -mem_free_all: - kfree(phys_luns); - goto out; - -} - static int aac_setup_safw_targets(struct aac_dev *dev, int rescan) { int rcode = 0; -- 2.9.4
[PATCH 11/29] scsi: aacraid: Refactor and rename to make mirror existing changes
Rename variables and functions to make bmic identify, report phy luns to make them consistent across code internal existing code bases Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 36 +++- drivers/scsi/aacraid/aacraid.h | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 8fb0da7..d6b626d 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1756,17 +1756,18 @@ static int aac_send_safw_bmic_cmd(struct aac_dev *dev, return rcode; } -static int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) +static int aac_issue_safw_bmic_identify(struct aac_dev *dev, + u32 bus, u32 target) { int rcode = -ENOMEM; - u16 datasize; + int datasize; struct aac_srb_unit srbu; struct aac_srb *srbcmd; - struct aac_ciss_identify_pd *identify_resp; + struct aac_ciss_identify_pd *identify_reply; datasize = sizeof(struct aac_ciss_identify_pd); - identify_resp = kmalloc(datasize, GFP_KERNEL); - if (!identify_resp) + identify_reply = kmalloc(datasize, GFP_KERNEL); + if (!identify_reply) goto out; memset(, 0, sizeof(struct aac_srb_unit)); @@ -1777,30 +1778,31 @@ static int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF); srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE; - rcode = aac_send_safw_bmic_cmd(dev, , identify_resp, datasize); + rcode = aac_send_safw_bmic_cmd(dev, , identify_reply, datasize); if (unlikely(rcode < 0)) goto out; - if (identify_resp->current_queue_depth_limit <= 0 || - identify_resp->current_queue_depth_limit > 32) + if (identify_reply->current_queue_depth_limit <= 0 || + identify_reply->current_queue_depth_limit > 32) dev->hba_map[bus][target].qd_limit = 32; else dev->hba_map[bus][target].qd_limit = - identify_resp->current_queue_depth_limit; + identify_reply->current_queue_depth_limit; - kfree(identify_resp); + kfree(identify_reply); out: return rcode; } /** - * aac_update hba_map()- update current hba map with data from FW + * aac_set_safw_attr_all_targets- update current hba map with data from FW * @dev: aac_dev structure * @phys_luns: FW information from report phys luns + * @rescan: Indicates scan type * * Update our hba map with the information gathered from the FW */ -void aac_update_hba_map(struct aac_dev *dev, +static void aac_set_safw_attr_all_targets(struct aac_dev *dev, struct aac_ciss_phys_luns_resp *phys_luns, int rescan) { /* ok and extended reporting */ @@ -1842,7 +1844,7 @@ void aac_update_hba_map(struct aac_dev *dev, if (devtype != AAC_DEVTYPE_NATIVE_RAW) goto update_devtype; - if (aac_issue_bmic_identify(dev, bus, target) < 0) + if (aac_issue_safw_bmic_identify(dev, bus, target) < 0) dev->hba_map[bus][target].qd_limit = 32; update_devtype: @@ -1854,14 +1856,14 @@ void aac_update_hba_map(struct aac_dev *dev, } /** - * aac_report_phys_luns() Process topology change + * aac_get_safw_ciss_luns()Process topology change * @dev: aac_dev structure * @rescan Indicates rescan * * Execute a CISS REPORT PHYS LUNS and process the results into * the current hba_map. */ -int aac_report_phys_luns(struct aac_dev *dev, int rescan) +int aac_get_safw_ciss_luns(struct aac_dev *dev, int rescan) { int rcode = -ENOMEM; int datasize; @@ -1891,7 +1893,7 @@ int aac_report_phys_luns(struct aac_dev *dev, int rescan) /* analyse data */ if (rcode >= 0 && phys_luns->resp_flag == 2) { /* ok and extended reporting */ - aac_update_hba_map(dev, phys_luns, rescan); + aac_set_safw_attr_all_targets(dev, phys_luns, rescan); } kfree(phys_luns); @@ -2004,7 +2006,7 @@ int aac_get_adapter_info(struct aac_dev* dev) if (!dev->sync_mode && dev->sa_firmware && dev->supplement_adapter_info.virt_device_bus != 0x) { /* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */ - rcode = aac_report_phys_luns(dev, AAC_INIT); + rcode = aac_get_safw_ciss_luns(dev, AAC_INIT); } if (!dev->in_reset) { diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacr
[PATCH 09/29] scsi: aacraid: Create bmic submission function from bmic identify
safw command submission is duplicated across many functions. Move the safw submission code from bmic identify into its own function for common use Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 147 +++-- drivers/scsi/aacraid/aacraid.h | 7 +- 2 files changed, 105 insertions(+), 49 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index f264515..8d119e1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1670,60 +1670,116 @@ static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd) (void *) cmd); } -int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target) +static int aac_send_safw_bmic_cmd(struct aac_dev *dev, + struct aac_srb_unit *srbu, void *xfer_buf, int xfer_len) { - struct fib *fibptr; - struct aac_srb *srbcmd; - struct sgmap64 *sg64; - struct aac_ciss_identify_pd *identify_resp; - dma_addr_t addr; - u32 vbus, vid; - u16 fibsize, datasize; - int rcode = -ENOMEM; - + struct fib *fibptr; + dma_addr_t addr; + int rcode; + int fibsize; + struct aac_srb *srb; + struct aac_srb_reply *srb_reply; + struct sgmap64 *sg64; + u32 vbus; + u32 vid; + + if (!dev->sa_firmware) + return 0; + /* allocate FIB */ fibptr = aac_fib_alloc(dev); if (!fibptr) - goto out; + return -ENOMEM; - fibsize = sizeof(struct aac_srb) - - sizeof(struct sgentry) + sizeof(struct sgentry64); - datasize = sizeof(struct aac_ciss_identify_pd); + aac_fib_init(fibptr); + fibptr->hw_fib_va->header.XferState &= + ~cpu_to_le32(FastResponseCapable); - identify_resp = dma_alloc_coherent(>pdev->dev, datasize, , - GFP_KERNEL); - if (!identify_resp) - goto fib_free_ptr; + fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry) + + sizeof(struct sgentry64); - vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_bus); - vid = (u32)le16_to_cpu(dev->supplement_adapter_info.virt_device_target); + /* allocate DMA buffer for response */ + addr = dma_map_single(>pdev->dev, xfer_buf, xfer_len, + DMA_BIDIRECTIONAL); + if (dma_mapping_error(>pdev->dev, addr)) { + rcode = -ENOMEM; + goto fib_error; + } - aac_fib_init(fibptr); + srb = fib_data(fibptr); + memcpy(srb, >srb, sizeof(struct aac_srb)); - srbcmd = (struct aac_srb *) fib_data(fibptr); - srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); - srbcmd->channel = cpu_to_le32(vbus); - srbcmd->id = cpu_to_le32(vid); - srbcmd->lun = 0; - srbcmd->flags= cpu_to_le32(SRB_DataIn); - srbcmd->timeout = cpu_to_le32(10); - srbcmd->retry_limit = 0; - srbcmd->cdb_size = cpu_to_le32(12); - srbcmd->count = cpu_to_le32(datasize); + vbus = (u32)le16_to_cpu( + dev->supplement_adapter_info.virt_device_bus); + vid = (u32)le16_to_cpu( + dev->supplement_adapter_info.virt_device_target); - memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb)); - srbcmd->cdb[0] = 0x26; - srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF); - srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE; + /* set the common request fields */ + srb->channel= cpu_to_le32(vbus); + srb->id = cpu_to_le32(vid); + srb->lun= 0; + srb->function = cpu_to_le32(SRBF_ExecuteScsi); + srb->timeout= 0; + srb->retry_limit= 0; + srb->cdb_size = cpu_to_le32(16); + srb->count = cpu_to_le32(xfer_len); + + sg64 = (struct sgmap64 *)>sg; + sg64->count = cpu_to_le32(1); + sg64->sg[0].addr[1] = cpu_to_le32(upper_32_bits(addr)); + sg64->sg[0].addr[0] = cpu_to_le32(lower_32_bits(addr)); + sg64->sg[0].count = cpu_to_le32(xfer_len); - sg64 = (struct sgmap64 *)>sg; - sg64->count = cpu_to_le32(1); - sg64->sg[0].addr[1] = cpu_to_le32((u32)(((addr) >> 16) >> 16)); - sg64->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0x)); - sg64->sg[0].count = cpu_to_le32(datasize); + /* +* Copy the updated data for other dumping or other usage if needed +
[PATCH 07/29] scsi: aacraid: Refactor reset_host store function
Refactored the reset_host store function to make consistent across code bases. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/linit.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 5eb0722..b2273e3 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1375,18 +1375,15 @@ static ssize_t aac_store_reset_adapter(struct device *device, const char *buf, size_t count) { int retval = -EACCES; - int bled = 0; - struct aac_dev *aac; - if (!capable(CAP_SYS_ADMIN)) return retval; - aac = (struct aac_dev *)class_to_shost(device)->hostdata; - bled = buf[0] == '!' ? 1:0; - retval = aac_reset_adapter(aac, bled, IOP_HWSOFT_RESET); + retval = aac_reset_adapter(shost_priv(class_to_shost(device)), + buf[0] == '!', IOP_HWSOFT_RESET); if (retval >= 0) retval = count; + return retval; } -- 2.9.4
[PATCH 03/29] scsi: aacraid: Fix hang in kdump
Driver attempts to perform a device scan and device add after coming out of reset. At times when the kdump kernel loads and it tries to perform eh recovery, the device scan hangs since its commands are blocked because of the eh recovery. This should have shown up in normal eh recovery path (Should have been obvious) Remove the code that performs scanning.I can live without the rescanning support in the stable kernels but a hanging kdump/eh recovery needs to be fixed. Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after controller reset) Cc: <sta...@vger.kernel.org> Reported-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> Tested-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> Fixes: a2d0321dd532901e (scsi: aacraid: Reload offlined drives after controller reset) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commsup.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 525a652..ffbfd04 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1672,14 +1672,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) out: aac->in_reset = 0; scsi_unblock_requests(host); - /* -* Issue bus rescan to catch any configuration that might have -* occurred -*/ - if (!retval) { - dev_info(>pdev->dev, "Issuing bus rescan\n"); - scsi_scan_host(host); - } + if (jafo) { spin_lock_irq(host->host_lock); } -- 2.9.4
[PATCH 06/29] scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw
It is possible to restart the controller via the use of the reset_host sysfs variable. This does work for controllers that can no longer respond, since driver will attempt to send down a shutdown in this path. Check if the controller is able to receive commands before sending down a shutdown Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/comminit.c | 13 - 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 1bc623a..9eff246 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -295,12 +295,10 @@ int aac_send_shutdown(struct aac_dev * dev) { struct fib * fibctx; struct aac_close *cmd; - int status; + int status = 0; - fibctx = aac_fib_alloc(dev); - if (!fibctx) - return -ENOMEM; - aac_fib_init(fibctx); + if (aac_adapter_check_health(dev)) + return status; if (!dev->adapter_shutdown) { mutex_lock(>ioctl_mutex); @@ -308,6 +306,11 @@ int aac_send_shutdown(struct aac_dev * dev) mutex_unlock(>ioctl_mutex); } + fibctx = aac_fib_alloc(dev); + if (!fibctx) + return -ENOMEM; + aac_fib_init(fibctx); + cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xfffe); -- 2.9.4
[PATCH 05/29] scsi: aacraid: Fix ioctl reset hang
Driver would hang when attempting to send reset from the ioctl interface, since it would wait to retrieve the ioctl mutex at send shutdown. Set adapter shutdown and unlock mutex before sending down reset request. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commctrl.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 9ab0fa9..a2b3430 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -1052,9 +1052,13 @@ static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg) if (copy_from_user((void *), arg, sizeof(struct aac_reset_iop))) return -EFAULT; + dev->adapter_shutdown = 1; + + mutex_unlock(>ioctl_mutex); retval = aac_reset_adapter(dev, 0, reset.reset_type); - return retval; + mutex_lock(>ioctl_mutex); + return retval; } int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) -- 2.9.4
[PATCH 04/29] scsi: aacraid: Do not remove offlined devices
As part of the recovery process, the drivers removes offline devices ( done by the kernel) and then tries to add them back in the rescan code. Removing the device is like taking a sledgehammer to a nail. Set the device as running if it is marked offline. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/commsup.c | 10 -- 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index ffbfd04..32b8bdb 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1658,14 +1658,12 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) command->scsi_done(command); } /* -* Any Device that was already marked offline needs to be cleaned up +* Any Device that was already marked offline needs to be marked +* running */ __shost_for_each_device(dev, host) { - if (!scsi_device_online(dev)) { - sdev_printk(KERN_INFO, dev, "Removing offline device\n"); - scsi_remove_device(dev); - scsi_device_put(dev); - } + if (!scsi_device_online(dev)) + scsi_device_set_state(dev, SDEV_RUNNING); } retval = 0; -- 2.9.4
[PATCH 01/29] scsi: aacraid: Fix udev inquiry race condition
When udev requests for a devices inquiry string, it might create multiple threads causing a race condition on the shared inquiry resource string. Created a buffer with the string for each thread. Cc: <sta...@vger.kernel.org> Fixes: 3bc8070fb75b3315 ([SCSI] aacraid: SMC vendor identification) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c | 18 ++ 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index af3e4d3..f264515 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -913,8 +913,18 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) memset(str, ' ', sizeof(*str)); if (sup_adap_info->adapter_type_text[0]) { - char *cp = sup_adap_info->adapter_type_text; int c; + char *cp; + char *cname = kmalloc(sizeof(sup_adap_info->adapter_type_text), + GFP_ATOMIC); + + if (!cname) + return; + + cp = cname; + memcpy(cname, sup_adap_info->adapter_type_text, + sizeof(sup_adap_info->adapter_type_text)); + if ((cp[0] == 'A') && (cp[1] == 'O') && (cp[2] == 'C')) inqstrcpy("SMC", str->vid); else { @@ -923,7 +933,7 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) ++cp; c = *cp; *cp = '\0'; - inqstrcpy(sup_adap_info->adapter_type_text, str->vid); + inqstrcpy(cname, str->vid); *cp = c; while (*cp && *cp != ' ') ++cp; @@ -937,8 +947,8 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex) cp[sizeof(str->pid)] = '\0'; } inqstrcpy (cp, str->pid); - if (c) - cp[sizeof(str->pid)] = c; + + kfree(cname); } else { struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype); -- 2.9.4
[PATCH 00/28] aacraid: Refactor for sas transport and bug fixes
This patchset primarily lays the foundation for adding sas transport support to the aacraid driver. Being said these patches are mainly code refactors, bug fixes and improvements. - Fixed a udev inquiry race condition - Fixed a kdump hang issue which occurs in case of error recovery in kdump - Made improvements to ioctl reset and reset_host sysfs reset paths - Changed the code to retrieve lun information into stand alone functions. - Merged container and hba hotplug event processing (device addition and and removal into single function) - Removed scsi_scan_host for safw devices and now explicitly add devices retrieved from the fw. - Reschedule scan in driver fails to retrieve lun information from fw. (usually works in a few attempts) - Rescan worker waits for any pending EH recovery before rescanning - Do not trigger rescan worker in kdump kernel Raghava Aditya Renukunta (29): scsi: aacraid: Fix udev inquiry race condition scsi: aacraid: Do not attempt abort when Fw panicked scsi: aacraid: Fix hang in kdump scsi: aacraid: Do not remove offlined devices scsi: aacraid: Fix ioctl reset hang scsi: aacraid: Allow reset_host sysfs var to recover Panicked Fw scsi: aacraid: Refactor reset_host store function scsi: aacraid: Move code to wait for IO completion to shutdown func scsi: aacraid: Create bmic submission function from bmic identify scsi: aacraid: Change phy luns function to use common bmic function scsi: aacraid: Refactor and rename to make mirror existing changes scsi: aacraid: Add target setup helper function scsi: aacraid: Untangle targets setup from report phy luns scsi: aacraid: Move function around to match existing code scsi: aacraid: Create helper functions to get lun info scsi: aacraid: Save bmic phy information for each phy scsi: aacraid: Add helper function to set queue depth scsi: aacraid: Merge func to get container information scsi: aacraid: Process hba and container hot plug events in single function scsi: aacraid: Added macros to help loop through known buses and targets scsi: aacraid: Refactor resolve luns code and scsi functions scsi: aacraid: Merge adapter setup with resolve luns scsi: aacraid: Block concurrent hotplug event handling scsi: aacraid: Use hotplug handling function in place of scsi_scan_host scsi: aacraid: Reschedule host scan in case of failure scsi: aacraid: Fix hang while scanning in eh recovery scsi: aacraid: Skip schedule rescan in case of kdump scsi: aacraid: Remove unused rescan variable scsi: aacraid: Remove AAC_HIDE_DISK check in queue command drivers/scsi/aacraid/aachba.c | 479 +++- drivers/scsi/aacraid/aacraid.h | 52 - drivers/scsi/aacraid/commctrl.c | 6 +- drivers/scsi/aacraid/comminit.c | 49 +++- drivers/scsi/aacraid/commsup.c | 224 ++- drivers/scsi/aacraid/linit.c| 23 +- 6 files changed, 561 insertions(+), 272 deletions(-) -- 2.9.4
RE: Driver version for PMC Adaptec HBA in Linux and from vendor
Hi Paul, > -Original Message- > From: Paul Menzel [mailto:pmen...@molgen.mpg.de] > Sent: Tuesday, December 19, 2017 3:12 PM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com> > Cc: linux-scsi@vger.kernel.org; it+linux-s...@molgen.mpg.de > Subject: Re: Driver version for PMC Adaptec HBA in Linux and from vendor > > EXTERNAL EMAIL > > > Dear Raghava Aditya, > > > Thank you for your answer. > > Am 18.12.2017 um 19:09 schrieb Raghava Aditya Renukunta: > > >> -Original Message- > >> From: Paul Menzel [mailto:pmen...@molgen.mpg.de] > >> Sent: Saturday, December 16, 2017 1:39 AM > >> To: Raghava Aditya Renukunta > >> <raghavaaditya.renuku...@microsemi.com>; dl-esc-Aacraid Linux Driver > >> <aacr...@microsemi.com> > >> Cc: linux-scsi@vger.kernel.org; it+linux-s...@vger.kernel.org > >> Subject: Re: Driver version for PMC Adaptec HBA in Linux and from > vendor > > >> Am 17.02.2017 um 20:29 schrieb Raghava Aditya Renukunta: > >> > >>>> Using a PMC Adaptec HBA 1000-8e with latest Linux, it only initializes > >>>> in sync mode, instead of async mode. > >>> > >>> The patches that enable async mode in HBA 1000-8e, have been > included in > >> the James Bottomley's linux-scsi Branch and are on track be > >>> Included into Linux 4.11. > >>> > >>> https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/ > >>> > >>>> ``` > >>>> $ git describe --tag > >>>> v4.10-rc8-47-g0722f57bf > >>>> $ dmesg > >>>> [ 21.359635] Adaptec aacraid driver 1.2-1[41066]-ms > >>>> [ 21.360017] aacraid :04:00.0: can't disable ASPM; OS doesn't have > >>>> ASPM control > >>>> [ 21.363987] AAC0: Async. mode not supported by current driver, sync. > >>>> mode enforced. > >>>> [ 21.363987] Please update driver to get full performance. > >>>> [ 21.364949] AAC0: kernel 1.2-0[0] Nov 5 2015 > >>>> [ 21.365275] AAC0: monitor 0.0-0[0] > >>>> [ 21.371382] AAC0: bios 0.13-209[32000] > >>>> [ 21.371711] AAC0: serial 10F447 > >>>> [ 21.372035] AAC0: Non-DASD support enabled. > >>>> [ 21.372360] AAC0: 64bit support enabled. > >>>> [ 21.372688] AAC0: 64 Bit DAC enabled > >>>> […] > >>>> $ git grep 'AAC_DRIVER_BUILD 41066' > >>>> drivers/scsi/aacraid/aacraid.h:# define AAC_DRIVER_BUILD 41066 > >>>> ``` > >>>> > >>>> Searching the vendor Web site, there is *Linux Driver Source > >>>> 1.2.1-53005* available for download [1]. > >>> > >>> The latest upstream driver version is 50740. We will be reaching version > 53005 in couple of patch sets ( ~ 3). > >>> > >> > http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/commit/?id=96f6a613 > >> 4766de0d42a98c7758736dde16e0add5 > >> > >> Thank you for the details. At our infrastructure we only want to use LTS > >> Linux kernels, and the latest in 4.14. So right now, Linux 4.14.6 > >> includes version 50834 [1], which is the same version currently in Linus > >> master branch (4.15-rc3). Is that save to use with async mode, or are > >> you aware of problems and we should always use the latest out of tree > >> driver, which is at version 55022 and can be download from the Microsemi > >> server [3]. > > > > Well at this point I am in the process of creating a patch set that solves a > kdump regression issue(Should be out before the new year), other than that > the upstream driver is pretty much up to date. If kdump support is a must > for you I would recommend that 55022 be used. > > From your answer the state of async support is unclear to me. Could you > please clarify, if that’s support in 4.14.x? (What source line do I need > to check?) It is supported in 4.14, there is no single line specifically, but if the variable sa_firmware is set then async mode is enabled. > >>>> How does the upstream process work? Is there a git repository > somewhere > >>>> from Microsemi? Are the patches already up for review? (I didn’t find > them.) > >>> > >>> We try to push out patch sets to kernel.org for every major driver > release we make. Usually they go into the > >>> sub component maintainers branch (linux-scsi ) , w
RE: Driver version for PMC Adaptec HBA in Linux and from vendor
Hi Paul, > -Original Message- > From: Paul Menzel [mailto:pmen...@molgen.mpg.de] > Sent: Saturday, December 16, 2017 1:39 AM > To: Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com> > Cc: linux-scsi@vger.kernel.org; it+linux-s...@vger.kernel.org > Subject: Re: Driver version for PMC Adaptec HBA in Linux and from vendor > > EXTERNAL EMAIL > > > Dear Aditya, > > > Am 17.02.2017 um 20:29 schrieb Raghava Aditya Renukunta: > > >> Using a PMC Adaptec HBA 1000-8e with latest Linux, it only initializes > >> in sync mode, instead of async mode. > > > > The patches that enable async mode in HBA 1000-8e, have been included in > the James Bottomley's linux-scsi Branch and are on track be > > Included into Linux 4.11. > > > > https://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/ > > > >> ``` > >> $ git describe --tag > >> v4.10-rc8-47-g0722f57bf > >> $ dmesg > >> [ 21.359635] Adaptec aacraid driver 1.2-1[41066]-ms > >> [ 21.360017] aacraid :04:00.0: can't disable ASPM; OS doesn't have > >> ASPM control > >> [ 21.363987] AAC0: Async. mode not supported by current driver, sync. > >> mode enforced. > >> [ 21.363987] Please update driver to get full performance. > >> [ 21.364949] AAC0: kernel 1.2-0[0] Nov 5 2015 > >> [ 21.365275] AAC0: monitor 0.0-0[0] > >> [ 21.371382] AAC0: bios 0.13-209[32000] > >> [ 21.371711] AAC0: serial 10F447 > >> [ 21.372035] AAC0: Non-DASD support enabled. > >> [ 21.372360] AAC0: 64bit support enabled. > >> [ 21.372688] AAC0: 64 Bit DAC enabled > >> […] > >> $ git grep 'AAC_DRIVER_BUILD 41066' > >> drivers/scsi/aacraid/aacraid.h:# define AAC_DRIVER_BUILD 41066 > >> ``` > >> > >> Searching the vendor Web site, there is *Linux Driver Source > >> 1.2.1-53005* available for download [1]. > > > > The latest upstream driver version is 50740. We will be reaching version > 53005 in couple of patch sets ( ~ 3). > > > > > http://git.kernel.org/cgit/linux/kernel/git/jejb/scsi.git/commit/?id=96f6a613 > 4766de0d42a98c7758736dde16e0add5 > > Thank you for the details. At our infrastructure we only want to use LTS > Linux kernels, and the latest in 4.14. So right now, Linux 4.14.6 > includes version 50834 [1], which is the same version currently in Linus > master branch (4.15-rc3). Is that save to use with async mode, or are > you aware of problems and we should always use the latest out of tree > driver, which is at version 55022 and can be download from the Microsemi > server [3]. Well at this point I am in the process of creating a patch set that solves a kdump regression issue(Should be out before the new year), other than that the upstream driver is pretty much up to date. If kdump support is a must for you I would recommend that 55022 be used. > >> How does the upstream process work? Is there a git repository > somewhere > >> from Microsemi? Are the patches already up for review? (I didn’t find > them.) > > > > We try to push out patch sets to kernel.org for every major driver release > we make. Usually they go into the > > sub component maintainers branch (linux-scsi ) , which is then pushed out > to Linus when the merge > > window for opens (currently the merge window for 4.10 is closed , barring > fixes). So Linux version 4.11 should have > > full async support and more for HBA1000-8e. > > > > We do not maintain a git repository unfortunately, but we do release the > source code for every release as you > > indicated. > > > > For further reference the patches are sent out in the scsi mailing list > > linux- > s...@vger.kernel.org , > > the archive is here http://marc.info/?l=linux-scsi=1=2 . > > > > Hope I cleared up your doubts. Please do reach out if you have other > concerns or questions. > > Yes, thank you for your elaborate answer, which cleared up a lot of my > doubts. We would be even more satisfied if you moved your development > fully to the Linux kernel tree, so that it always carries the latest > driver. If we can help with that by contacting certain people, please > tell us. We would love to, but we have lots of customers who are on the older kernel versions 2.6.32, 3.10.0 etc and It becomes almost impossible for us to fully move our development to the Linux kernel tree and support our customers at the same time. Hopefully we will start being up to date with the upstream kernel in the coming months. Hope that answered your questions. Thanks and Happy Holidays! Raghava Aditya > Kind regards, > > Paul > > > >> [1] https://storage.microsemi.com/en-us/speed/raid/aac/linux/aacraid- > linux-src-1_2_1-53005_tgz.php > [2] > https://elixir.free- > electrons.com/linux/v4.14.6/source/drivers/scsi/aacraid/aacraid.h#L100 > [3] > https://storage.microsemi.com/en- > us/downloads/linux_source/linux_source_code/productid=aha-1000- > 8e=microsemi+adaptec+hba+1000-8e.php
RE: [PATCH] scsi: aacraid: fix io drop during the reset
> -Original Message- > From: Prasad B Munirathnam [mailto:prasad.munirath...@microsemi.com] > Sent: Tuesday, December 12, 2017 11:40 AM > To: Prasad Munirathnam <prasad.munirath...@microsemi.com>; Dave > Carroll <david.carr...@microsemi.com>; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; > martin.peter...@oracle.com; james.bottom...@hansenpartnership.com > Cc: linux-scsi@vger.kernel.org > Subject: [PATCH] scsi: aacraid: fix io drop during the reset > > "FIB_CONTEXT_FLAG_TIMEDOUT" flag is set in aac_eh_abort to > indicate command timeout, using the same flag in reset handler > causes the command to timeout and the IO's were droped. > > defined a new flag "FIB_CONTEXT_FLAG_EH_RESET" to make sure IO > is properly handled in eh_reset handler. > > Signed-off-by: Prasad B Munirathnam > <prasad.munirath...@microsemi.com> > --- Reviewed-by :Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH 2/3] scsi: aacraid: Perform initialization reset only once
> -Original Message- > From: Guilherme G. Piccoli [mailto:gpicc...@linux.vnet.ibm.com] > Sent: Friday, November 17, 2017 1:15 PM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; linux- > s...@vger.kernel.org > Cc: gpicc...@linux.vnet.ibm.com; Dave Carroll > <david.carr...@microsemi.com>; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; gpicc...@protonmail.ch > Subject: [PATCH 2/3] scsi: aacraid: Perform initialization reset only once > > EXTERNAL EMAIL > > > Currently the driver accepts two ways of requesting an initialization > reset on the adapter: by passing aac_reset_devices module parameter, > or the generic kernel parameter reset_devices. > > It's working as intended...but if we end up reaching a scsi hang and > the scsi EH mechanism takes place, aacraid performs resets as part of > the scsi error recovery procedure. These EH routines might reinitialize > the device, and if we have provided some of the reset parameters in the > kernel command-line, we again perform an "initialization" reset. > > So, to avoid this duplication of resets in case of scsi EH path, this > patch adds a field to aac_dev struct to keep per-adapter track of the > init reset request - once it's done, we set it to false and don't > proactively reset anymore in case of reinitializations. > > Signed-off-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> > --- Reviewed-by :Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH 3/3] scsi: aacraid: Prevent crash in case of free interrupt during scsi EH path
> -Original Message- > From: Guilherme G. Piccoli [mailto:gpicc...@linux.vnet.ibm.com] > Sent: Friday, November 17, 2017 1:15 PM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com>; linux- > s...@vger.kernel.org > Cc: gpicc...@linux.vnet.ibm.com; Dave Carroll > <david.carr...@microsemi.com>; Raghava Aditya Renukunta > <raghavaaditya.renuku...@microsemi.com>; gpicc...@protonmail.ch > Subject: [PATCH 3/3] scsi: aacraid: Prevent crash in case of free interrupt > during scsi EH path > > EXTERNAL EMAIL > > > As part of the scsi EH path, aacraid performs a reinitialization of > the adapter, which encompass freeing resources and IRQs, NULLifying > lots of pointers, and then initialize it all over again. > We've identified a problem during the free IRQ portion of this path > if CONFIG_DEBUG_SHIRQ is enabled on kernel config file. > > Happens that, in case this flag was set, right after free_irq() > effectively clears the interrupt, it checks if it was requested > as IRQF_SHARED. In positive case, it performs another call to the > IRQ handler on driver. Problem is: since aacraid currently free > some resources *before* freeing the IRQ, once free_irq() path > calls the handler again (due to CONFIG_DEBUG_SHIRQ), aacraid > crashes due to NULL pointer dereference with the following trace: > > aac_src_intr_message+0xf8/0x740 [aacraid] > __free_irq+0x33c/0x4a0 > free_irq+0x78/0xb0 > aac_free_irq+0x13c/0x150 [aacraid] > aac_reset_adapter+0x2e8/0x970 [aacraid] > aac_eh_reset+0x3a8/0x5d0 [aacraid] > scsi_try_host_reset+0x74/0x180 > scsi_eh_ready_devs+0xc70/0x1510 > scsi_error_handler+0x624/0xa20 > > This patch prevents the crash by changing the order of the > deinitialization in this path of aacraid: first we clear the IRQ, > then we free other resources. No functional change intended. > > Signed-off-by: Guilherme G. Piccoli <gpicc...@linux.vnet.ibm.com> > --- Thank you for the fix. Much appreciated. Reviewed-by :Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
[PATCH] aacraid: Fix controller initialization failure
This is a fix to an issue where the driver sends its periodic WELLNESS command to the controller after the driver shut it down.This causes the controller to crash. The window where this can happen is small, but it can be hit at around 4 hours of constant resets. Cc: <sta...@vger.kernel.org> Fixes: fbd185986eba (aacraid: Fix AIF triggered IOP_RESET) Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> Reviewed-by: Dave Carroll <david.carr...@microsemi.com> --- drivers/scsi/aacraid/comminit.c |8 +--- drivers/scsi/aacraid/linit.c|7 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 97d269f..1bc623a 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -302,9 +302,11 @@ int aac_send_shutdown(struct aac_dev * dev) return -ENOMEM; aac_fib_init(fibctx); - mutex_lock(>ioctl_mutex); - dev->adapter_shutdown = 1; - mutex_unlock(>ioctl_mutex); + if (!dev->adapter_shutdown) { + mutex_lock(>ioctl_mutex); + dev->adapter_shutdown = 1; + mutex_unlock(>ioctl_mutex); + } cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 87cc4a9..710ace6 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1547,8 +1547,9 @@ static void __aac_shutdown(struct aac_dev * aac) { int i; + mutex_lock(>ioctl_mutex); aac->adapter_shutdown = 1; - aac_send_shutdown(aac); + mutex_unlock(>ioctl_mutex); if (aac->aif_thread) { int i; @@ -1561,7 +1562,11 @@ static void __aac_shutdown(struct aac_dev * aac) } kthread_stop(aac->thread); } + + aac_send_shutdown(aac); + aac_adapter_disable_int(aac); + if (aac_is_src(aac)) { if (aac->max_msix > 1) { for (i = 0; i < aac->max_msix; i++) {
RE: [PATCH RESEND] aacraid: Fix 2T+ drives on SmartIOC-2000
> -Original Message- > From: Dave Carroll [mailto:david.carr...@microsemi.com] > Sent: Friday, September 15, 2017 10:04 AM > To: Martin K . Petersen <martin.peter...@oracle.com>; James Bottomley > <j...@linux.vnet.ibm.com> > Cc: Dave Carroll <david.carr...@microsemi.com>; linux-scsi s...@vger.kernel.org>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Scott Benesh <scott.ben...@microsemi.com>; > Brian King <brk...@linux.vnet.ibm.com>; sta...@vger.kernel.org > Subject: [PATCH RESEND] aacraid: Fix 2T+ drives on SmartIOC-2000 > > The logic for supporting large drives was previously tied to 4Kn support > for SmartIOC-2000. As SmartIOC-2000 does not support volumes using 4Kn > drives, use the intended option flag AAC_OPT_NEW_COMM_64 to > determine > support for volumes greater than 2T. > > cc: sta...@vger.kernel.org > Signed-off-by: Dave Carroll <david.carr...@microsemi.com> > > --- > drivers/scsi/aacraid/aachba.c | 12 ++-- > drivers/scsi/aacraid/aacraid.h | 5 + > 2 files changed, 11 insertions(+), 6 deletions(-) > > diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c > index 4591113..18a1a1f 100644 > --- a/drivers/scsi/aacraid/aachba.c > +++ b/drivers/scsi/aacraid/aachba.c > @@ -695,13 +695,13 @@ static void _aac_probe_container1(void * context, > struct fib * fibptr) > int status; > > dresp = (struct aac_mount *) fib_data(fibptr); > - if (!(fibptr->dev->supplement_adapter_info.supported_options2 & > - AAC_OPTION_VARIABLE_BLOCK_SIZE)) > + if (!aac_supports_2T(fibptr->dev)) { > dresp->mnt[0].capacityhigh = 0; > - if ((le32_to_cpu(dresp->status) != ST_OK) || > - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { > - _aac_probe_container2(context, fibptr); > - return; > + if ((le32_to_cpu(dresp->status) == ST_OK) && > + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { > + _aac_probe_container2(context, fibptr); > + return; > + } > } > scsicmd = (struct scsi_cmnd *) context; > > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h > index 6981299..998fbad 100644 > --- a/drivers/scsi/aacraid/aacraid.h > +++ b/drivers/scsi/aacraid/aacraid.h > @@ -2701,6 +2701,11 @@ static inline int aac_is_src(struct aac_dev *dev) > return 0; > } > > +static inline int aac_supports_2T(struct aac_dev *dev) > +{ > + return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); > +} > + > char * get_container_type(unsigned type); > extern int numacb; > extern char aac_driver_version[]; > -- > 2.8.4 Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH] aacraid: Fix 2T+ drives on SmartIOC-2000
> -Original Message- > From: Dave Carroll [mailto:david.carr...@microsemi.com] > Sent: Wednesday, August 30, 2017 3:23 PM > To: Martin K . Petersen <martin.peter...@oracle.com>; James Bottomley > <j...@linux.vnet.ibm.com> > Cc: Dave Carroll <david.carr...@microsemi.com>; linux-scsi s...@vger.kernel.org>; dl-esc-Aacraid Linux Driver > <aacr...@microsemi.com>; Scott Benesh <scott.ben...@microsemi.com>; > Brian King <brk...@linux.vnet.ibm.com>; sta...@vger.kernel.org > Subject: [PATCH] aacraid: Fix 2T+ drives on SmartIOC-2000 > > The logic for supporting large drives was previously tied to 4Kn support > for SmartIOC-2000. As SmartIOC-2000 does not support volumes using 4Kn > drives, use the intended option flag AAC_OPT_NEW_COMM_64 to > determine > support for volumes greater than 2T. > > cc: sta...@vger.kernel.org > Signed-off-by: Dave Carroll <david.carr...@microsemi.com> > > --- > drivers/scsi/aacraid/aachba.c | 12 ++-- > drivers/scsi/aacraid/aacraid.h | 5 + > 2 files changed, 11 insertions(+), 6 deletions(-) > > diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c > index 4591113..18a1a1f 100644 > --- a/drivers/scsi/aacraid/aachba.c > +++ b/drivers/scsi/aacraid/aachba.c > @@ -695,13 +695,13 @@ static void _aac_probe_container1(void * context, > struct fib * fibptr) > int status; > > dresp = (struct aac_mount *) fib_data(fibptr); > - if (!(fibptr->dev->supplement_adapter_info.supported_options2 & > - AAC_OPTION_VARIABLE_BLOCK_SIZE)) > + if (!aac_supports_2T(fibptr->dev)) { > dresp->mnt[0].capacityhigh = 0; > - if ((le32_to_cpu(dresp->status) != ST_OK) || > - (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { > - _aac_probe_container2(context, fibptr); > - return; > + if ((le32_to_cpu(dresp->status) == ST_OK) && > + (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE)) { > + _aac_probe_container2(context, fibptr); > + return; > + } > } > scsicmd = (struct scsi_cmnd *) context; > > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h > index 6981299..998fbad 100644 > --- a/drivers/scsi/aacraid/aacraid.h > +++ b/drivers/scsi/aacraid/aacraid.h > @@ -2701,6 +2701,11 @@ static inline int aac_is_src(struct aac_dev *dev) > return 0; > } > > +static inline int aac_supports_2T(struct aac_dev *dev) > +{ > + return (dev->adapter_info.options & AAC_OPT_NEW_COMM_64); > +} > + > char * get_container_type(unsigned type); > extern int numacb; > extern char aac_driver_version[]; > -- > 2.8.4 Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH 2/3] scsi: aacraid: get rid of one level of indentation
> -Original Message- > From: Nikola Pajkovsky [mailto:npajkov...@suse.cz] > Sent: Tuesday, August 29, 2017 4:59 AM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com> > Cc: Nikola Pajkovsky <npajkov...@suse.cz>; James E.J. Bottomley > <j...@linux.vnet.ibm.com>; Martin K. Petersen > <martin.peter...@oracle.com>; linux-scsi@vger.kernel.org; linux- > ker...@vger.kernel.org > Subject: [PATCH 2/3] scsi: aacraid: get rid of one level of indentation > > EXTERNAL EMAIL > > > unsigned long byte_count = 0; > nseg = scsi_dma_map(scsicmd); > if (nseg < 0) > return nseg; > if (nseg) { > ... > } > return byte_count; > > is equal to > > unsigned long byte_count = 0; > nseg = scsi_dma_map(scsicmd); > if (nseg <= 0) > return nseg; > ... > return byte_count; > > No other code has changed. > > Signed-off-by: Nikola Pajkovsky <npajkov...@suse.cz> > --- [.] Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH 3/3] scsi: aacraid: report -ENOMEM to upper layer from aac_convert_sgraw2()
> -Original Message- > From: Nikola Pajkovsky [mailto:npajkov...@suse.cz] > Sent: Tuesday, August 29, 2017 4:59 AM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com> > Cc: Nikola Pajkovsky <npajkov...@suse.cz>; James E.J. Bottomley > <j...@linux.vnet.ibm.com>; Martin K. Petersen > <martin.peter...@oracle.com>; linux-scsi@vger.kernel.org; linux- > ker...@vger.kernel.org > Subject: [PATCH 3/3] scsi: aacraid: report -ENOMEM to upper layer from > aac_convert_sgraw2() > > EXTERNAL EMAIL > > > aac_convert_sgraw2() kmalloc memory and return -1 on error, which > should be -ENOMEM. However, nobody is checking return value, so with > this change, -ENOMEM is propagated to upper layer. > > Signed-off-by: Nikola Pajkovsky <npajkov...@suse.cz> > --- [.] Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
RE: [PATCH 1/3] scsi: aacraid: fix indentation errors
> -Original Message- > From: Nikola Pajkovsky [mailto:npajkov...@suse.cz] > Sent: Tuesday, August 29, 2017 4:59 AM > To: dl-esc-Aacraid Linux Driver <aacr...@microsemi.com> > Cc: Nikola Pajkovsky <npajkov...@suse.cz>; James E.J. Bottomley > <j...@linux.vnet.ibm.com>; Martin K. Petersen > <martin.peter...@oracle.com>; linux-scsi@vger.kernel.org; linux- > ker...@vger.kernel.org > Subject: [PATCH 1/3] scsi: aacraid: fix indentation errors > > EXTERNAL EMAIL > > > fix stupid indent error, no rocket science here. > > Signed-off-by: Nikola Pajkovsky <npajkov...@suse.cz> > --- [.] Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>
[PATCH] aacraid: Fix out of bounds in aac_get_name_resp
We terminate the aac_get_name_resp on a byte that is outside the bounds of the structure. Extend the return response by one byte to remove the appearance of out of bounds reference. Thank you Dan for reporting the issue. Thank you Bart Van Assche <bart.vanass...@wdc.com> for suggesting the FIELD_SIZEOF macro. Fixes: b836439faf04 ("aacraid: 4KB sector support") Reported-by: Dan Carpenter <dan.carpen...@oracle.com> Signed-off-by: David Carroll <david.carr...@microsemi.com> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- drivers/scsi/aacraid/aachba.c |9 +++-- drivers/scsi/aacraid/aacraid.h |2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 707ee2f5954d..a875175d58d1 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -549,7 +549,9 @@ static void get_container_name_callback(void *context, struct fib * fibptr) if ((le32_to_cpu(get_name_reply->status) == CT_OK) && (get_name_reply->data[0] != '\0')) { char *sp = get_name_reply->data; - sp[sizeof(((struct aac_get_name_resp *)NULL)->data)] = '\0'; + int data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); + + sp[data_size - 1] = '\0'; while (*sp == ' ') ++sp; if (*sp) { @@ -579,12 +581,15 @@ static void get_container_name_callback(void *context, struct fib * fibptr) static int aac_get_container_name(struct scsi_cmnd * scsicmd) { int status; + int data_size; struct aac_get_name *dinfo; struct fib * cmd_fibcontext; struct aac_dev * dev; dev = (struct aac_dev *)scsicmd->device->host->hostdata; + data_size = FIELD_SIZEOF(struct aac_get_name_resp, data); + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); aac_fib_init(cmd_fibcontext); @@ -593,7 +598,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->type = cpu_to_le32(CT_READ_NAME); dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); - dinfo->count = cpu_to_le32(sizeof(((struct aac_get_name_resp *)NULL)->data)); + dinfo->count = cpu_to_le32(data_size - 1); status = aac_fib_send(ContainerCommand, cmd_fibcontext, diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 69812994b81e..92fabf2b0c24 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -2275,7 +2275,7 @@ struct aac_get_name_resp { __le32 parm3; __le32 parm4; __le32 parm5; - u8 data[16]; + u8 data[17]; }; #define CT_CID_TO_32BITS_UID 165
[PATCH] scsi: Add helper functions to set target ID
This patch adds 3 helper functions to set the initial target id, expander id and port id numbers. The ARC/HBA1000 product line exposes RAID drives on bus number 0 and sas transport HBA drives use bus 0 as well. We wanted to differentiate between the RAID and HBA targets when the adapter in mixed mode (both RAID and HBA are exposed). Since the number of RAID drives we support is limited to 64 we wanted to block the first 64 targets and then add the sas enabled HBA drives from target id 64. Unfortunately the current sas transport implementation does not allow changing of the next_target_id value (used by rphy to add drives), since it is not exposed directly to the driver. One way around this is to add helper functions to explicitly set the next_target_id and others. I still have to submit the sas transport aacraid support patches, but I wanted to send this out to get comments and any other changes if required. Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com> --- 0 files changed diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index 5006a656e16a..a6ef5520cb66 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -294,6 +294,31 @@ static void sas_bsg_remove(struct Scsi_Host *shost, struct sas_rphy *rphy) bsg_unregister_queue(q); } +void sas_set_initial_target_id(struct Scsi_Host *shost, u32 target_id) +{ + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + + sas_host->next_target_id = target_id; +} +EXPORT_SYMBOL(sas_set_initial_target_id); + +void sas_set_initial_expander_id(struct Scsi_Host *shost, u32 expander_id) +{ + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + + sas_host->next_expander_id = expander_id; +} +EXPORT_SYMBOL(sas_set_initial_expander_id); + +void sas_set_initial_port_id(struct Scsi_Host *shost, u32 port_id) +{ + struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); + + sas_host->next_port_id = port_id; +} +EXPORT_SYMBOL(sas_set_initial_port_id); + + /* * SAS host attributes */ diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 73d870918939..6917eee7bc24 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -179,6 +179,9 @@ struct sas_function_template { int (*smp_handler)(struct Scsi_Host *, struct sas_rphy *, struct request *); }; +void sas_set_initial_target_id(struct Scsi_Host *shost, u32 target_id); +void sas_set_initial_expander_id(struct Scsi_Host *shost, u32 expander_id); +void sas_set_initial_port_id(struct Scsi_Host *shost, u32 port_id); void sas_remove_children(struct device *); extern void sas_remove_host(struct Scsi_Host *);
RE: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib
> -Original Message- > From: Hannes Reinecke [mailto:h...@suse.de] > Sent: Friday, June 30, 2017 10:18 AM > To: Martin K. Petersen <martin.peter...@oracle.com> > Cc: Christoph Hellwig <h...@lst.de>; James Bottomley > <james.bottom...@hansenpartnership.com>; linux-scsi@vger.kernel.org; > Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>; > Hannes Reinecke <h...@suse.de>; Hannes Reinecke <h...@suse.com> > Subject: [PATCH 4/7] aacraid: use aac_tmf_callback for reset fib > > EXTERNAL EMAIL > > > When sending a reset fib we shouldn't rely on the scsi command, > but rather set the TMF status in the map_info->reset_state variable. > That allows us to send a TMF independent on a scsi command. > > Signed-off-by: Hannes Reinecke <h...@suse.com> > --- > drivers/scsi/aacraid/linit.c | 99 +--- > > 1 file changed, 74 insertions(+), 25 deletions(-) > > diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c > index 57b2077..e5d2d91 100644 > --- a/drivers/scsi/aacraid/linit.c > +++ b/drivers/scsi/aacraid/linit.c > @@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd) > return ret; > } > > -static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib, > - int bus, int cid, u64 tmf_lun) > +static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info, > + struct fib *fib, u64 tmf_lun) > { > struct aac_hba_tm_req *tmf; > u64 address; > @@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev > *aac, struct fib *fib, > tmf = (struct aac_hba_tm_req *)fib->hw_fib_va; > memset(tmf, 0, sizeof(*tmf)); > tmf->tmf = HBA_TMF_LUN_RESET; > - tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus; > + tmf->it_nexus = info->rmw_nexus; > int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun); > > address = (u64)fib->hw_error_pa; > @@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev > *aac, struct fib *fib, > return HBA_IU_TYPE_SCSI_TM_REQ; > } > > -static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib, > - int bus, int cid) > +static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info, > + struct fib *fib) > { > struct aac_hba_reset_req *rst; > u64 address; > @@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev > *aac, struct fib *fib, > /* already tried, start a hard reset now */ > rst = (struct aac_hba_reset_req *)fib->hw_fib_va; > memset(rst, 0, sizeof(*rst)); > - /* reset_type is already zero... */ > - rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus; > + rst->it_nexus = info->rmw_nexus; > > address = (u64)fib->hw_error_pa; > rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32)); > @@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev > *aac, struct fib *fib, > return HBA_IU_TYPE_SATA_REQ; > } > > +void aac_tmf_callback(void *context, struct fib *fibptr) > +{ > + struct aac_hba_resp *err = > + &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err; > + struct aac_hba_map_info *info = context; > + int res; > + > + switch (err->service_response) { > + case HBA_RESP_SVCRES_TMF_REJECTED: > + res = -1; > + break; > + case HBA_RESP_SVCRES_TMF_LUN_INVALID: > + res = 0; > + break; > + case HBA_RESP_SVCRES_TMF_COMPLETE: > + case HBA_RESP_SVCRES_TMF_SUCCEEDED: > + res = 0; > + break; > + default: > + res = -2; > + break; > + } > + aac_fib_complete(fibptr); > + > + info->reset_state = res; > +} > + > /* > * aac_eh_dev_reset- Device reset command handling > * @scsi_cmd: SCSI command block causing the reset > @@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd) > struct scsi_device * dev = cmd->device; > struct Scsi_Host * host = dev->host; > struct aac_dev * aac = (struct aac_dev *)host->hostdata; > + struct aac_hba_map_info *info; > int count; > u32 bus, cid; > struct fib *fib; > @@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd) > > bus = aac_logical_to
RE: [PATCH 07/47] aacraid: complete all commands during bus reset
> -Original Message- > From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- > ow...@vger.kernel.org] On Behalf Of Hannes Reinecke > Sent: Wednesday, June 28, 2017 1:33 AM > To: Christoph Hellwig <h...@lst.de> > Cc: Martin K. Petersen <martin.peter...@oracle.com>; James Bottomley > <james.bottom...@hansenpartnership.com>; linux-scsi@vger.kernel.org; > Hannes Reinecke <h...@suse.de>; Hannes Reinecke <h...@suse.com> > Subject: [PATCH 07/47] aacraid: complete all commands during bus reset > > EXTERNAL EMAIL > > > When issuing a bus reset we should complete all commands, not > just the command triggering the reset. > > Signed-off-by: Hannes Reinecke <h...@suse.com> > --- > drivers/scsi/aacraid/linit.c | 34 -- > 1 file changed, 20 insertions(+), 14 deletions(-) > > diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c > index 9b284a0..c26130e 100644 > --- a/drivers/scsi/aacraid/linit.c > +++ b/drivers/scsi/aacraid/linit.c > @@ -1007,23 +1007,29 @@ static int aac_eh_bus_reset(struct scsi_cmnd* > cmd) > struct Scsi_Host * host = dev->host; > struct aac_dev * aac = (struct aac_dev *)host->hostdata; > int count; > - u32 bus, cid; > + u32 cmd_bus; > int status = 0; > > > - bus = aac_logical_to_phys(scmd_channel(cmd)); > - cid = scmd_id(cmd); > - if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || > - aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) { > - /* Mark the assoc. FIB to not complete, eh handler does this > */ > - for (count = 0; > - count < (host->can_queue + AAC_NUM_MGT_FIB); > - ++count) { > - struct fib *fib = >fibs[count]; > - > - if (fib->hw_fib_va->header.XferState && > - (fib->flags & FIB_CONTEXT_FLAG) && > - (fib->callback_data == cmd)) { > + cmd_bus = aac_logical_to_phys(scmd_channel(cmd)); > + /* Mark the assoc. FIB to not complete, eh handler does this */ > + for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); > ++count) { > + struct fib *fib = >fibs[count]; > + > + if (fib->hw_fib_va->header.XferState && > + (fib->flags & FIB_CONTEXT_FLAG) && > + (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) { > + struct aac_hba_map_info *info; > + u32 bus, cid; > + > + cmd = (struct scsi_cmnd *)fib->callback_data; > + bus = aac_logical_to_phys(scmd_channel(cmd)); > + if (bus != cmd_bus) > + continue; > + cid = scmd_id(cmd); > + info = >hba_map[bus][cid]; > + if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || > + info->devtype != AAC_DEVTYPE_NATIVE_RAW) { > fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT; > cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; > } > -- > 1.8.5.6 Reviewed-by: Raghava Aditya Renukunta <raghavaaditya.renuku...@microsemi.com>