All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V3 00/24] aacraid: Patchset for Smart Family Support
@ 2017-01-27 19:28 Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
                   ` (23 more replies)
  0 siblings, 24 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patchset adds support to the HBA1000 and SMARTIOC2000
family of cards. The driver version is now updated to 50740

Changes in V2:
Fixed kbuild test robot warnings

Changes in V3:
Removed Camel case definitions
Misc fixes

Raghava Aditya Renukunta (24):
 [SCSI] aacraid: Remove duplicate irq management code
 [SCSI] aacraid: Added aacraid.h include guard
 [SCSI] aacraid: added support for init_struct_8
 [SCSI] aacraid: Added sa firmware support
 [SCSI] aacraid: Retrieve and update the device types
 [SCSI] aacraid: Reworked scsi command submission path
 [SCSI] aacraid: Process Error for response I/O
 [SCSI] aacraid: Added support for response path
 [SCSI] aacraid: Added support for read medium error
 [SCSI] aacraid: Reworked aac_command_thread
 [SCSI] aacraid: Added support for periodic wellness sync
 [SCSI] aacraid: Retrieve Queue Depth from Adapter FW
 [SCSI] aacraid: Added support to set QD of attached drives
 [SCSI] aacraid: Added support for hotplug
 [SCSI] aacraid: Include HBA direct interface
 [SCSI] aacraid: Add task management functionality
 [SCSI] aacraid: Added support to abort cmd and reset lun
 [SCSI] aacraid: VPD 83 type3 support
 [SCSI] aacraid: Added new IWBR reset
 [SCSI] aacraid: Added ioctl to trigger IOP/IWBR reset
 [SCSI] aacraid: Retrieve HBA host information ioctl
 [SCSI] aacraid: Update copyrights
 [SCSI] aacraid: Change Driver Version Prefix
 [SCSI] aacraid: update version

 drivers/scsi/aacraid/aachba.c   | 1294 +++++++++++++++++++++++++++++----------
 drivers/scsi/aacraid/aacraid.h  |  648 +++++++++++++++++---
 drivers/scsi/aacraid/commctrl.c |  342 ++++++++---
 drivers/scsi/aacraid/comminit.c |  330 +++++-----
 drivers/scsi/aacraid/commsup.c  |  901 +++++++++++++++++++--------
 drivers/scsi/aacraid/dpcsup.c   |  159 +++--
 drivers/scsi/aacraid/linit.c    |  556 +++++++++++------
 drivers/scsi/aacraid/nark.c     |    3 +-
 drivers/scsi/aacraid/rkt.c      |    5 +-
 drivers/scsi/aacraid/rx.c       |   17 +-
 drivers/scsi/aacraid/sa.c       |    9 +-
 drivers/scsi/aacraid/src.c      |  336 +++++++---
 12 files changed, 3390 insertions(+), 1210 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 55+ messages in thread

* [PATCH V3 01/24] aacraid: Remove duplicate irq management code
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 02/24] aacraid: Added aacraid.h include guard Raghava Aditya Renukunta
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Removed duplicate code that for acquiring and releasing irqs

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

---
Changes in V2:
None

Changes in V3:
None

 drivers/scsi/aacraid/linit.c | 58 +++-----------------------------------------
 1 file changed, 3 insertions(+), 55 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 3ecbf20..fd26a2d 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1327,35 +1327,12 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 
 static void aac_release_resources(struct aac_dev *aac)
 {
-	int i;
-
 	aac_adapter_disable_int(aac);
-	if (aac->pdev->device == PMC_DEVICE_S6 ||
-	    aac->pdev->device == PMC_DEVICE_S7 ||
-	    aac->pdev->device == PMC_DEVICE_S8 ||
-	    aac->pdev->device == PMC_DEVICE_S9) {
-		if (aac->max_msix > 1) {
-			for (i = 0; i < aac->max_msix; i++)
-				free_irq(pci_irq_vector(aac->pdev, i),
-					&(aac->aac_msix[i]));
-		} else {
-			free_irq(aac->pdev->irq, &(aac->aac_msix[0]));
-		}
-	} else {
-		free_irq(aac->pdev->irq, aac);
-	}
-	if (aac->msi)
-		pci_disable_msi(aac->pdev);
-	else if (aac->max_msix > 1)
-		pci_disable_msix(aac->pdev);
-
+	aac_free_irq(aac);
 }
 
 static int aac_acquire_resources(struct aac_dev *dev)
 {
-	int i, j;
-	int instance = dev->id;
-	const char *name = dev->name;
 	unsigned long status;
 	/*
 	 *	First clear out all interrupts.  Then enable the one's that we
@@ -1377,37 +1354,8 @@ static int aac_acquire_resources(struct aac_dev *dev)
 	if (dev->msi_enabled)
 		aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
 
-	if (!dev->sync_mode && dev->msi_enabled && dev->max_msix > 1) {
-		for (i = 0; i < dev->max_msix; i++) {
-			dev->aac_msix[i].vector_no = i;
-			dev->aac_msix[i].dev = dev;
-
-			if (request_irq(pci_irq_vector(dev->pdev, i),
-					dev->a_ops.adapter_intr,
-					0, "aacraid", &(dev->aac_msix[i]))) {
-				printk(KERN_ERR "%s%d: Failed to register IRQ for vector %d.\n",
-						name, instance, i);
-				for (j = 0 ; j < i ; j++)
-					free_irq(pci_irq_vector(dev->pdev, j),
-						 &(dev->aac_msix[j]));
-				pci_disable_msix(dev->pdev);
-				goto error_iounmap;
-			}
-		}
-	} else {
-		dev->aac_msix[0].vector_no = 0;
-		dev->aac_msix[0].dev = dev;
-
-		if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr,
-			IRQF_SHARED, "aacraid",
-			&(dev->aac_msix[0])) < 0) {
-			if (dev->msi)
-				pci_disable_msi(dev->pdev);
-			printk(KERN_ERR "%s%d: Interrupt unavailable.\n",
-					name, instance);
-			goto error_iounmap;
-		}
-	}
+	if (aac_acquire_irq(dev))
+		goto error_iounmap;
 
 	aac_adapter_enable_int(dev);
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 02/24] aacraid: Added aacraid.h include guard
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added aacraid.h include guard

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index f059c14..01b457b 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1,3 +1,5 @@
+#ifndef _AACRAID_H_
+#define _AACRAID_H_
 #ifndef dprintk
 # define dprintk(x)
 #endif
@@ -2194,3 +2196,4 @@ extern int aac_commit;
 extern int update_interval;
 extern int check_interval;
 extern int aac_check_reset;
+#endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 03/24] aacraid: added support for init_struct_8
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 02/24] aacraid: Added aacraid.h include guard Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:15   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This  patch lays the groundwork for supporting the new HBA-1000 controller
family.A new INIT structure INIT_STRUCT_8 has been added which allows for a
variable size for MSI-x vectors among other things,  and is used for both
Series-8, HBA-1000 and SmartIOC-2000.

Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in V3:
Removed Camel Case header variable definitions

 drivers/scsi/aacraid/aachba.c   |   8 +-
 drivers/scsi/aacraid/aacraid.h  | 100 +++++++++++------
 drivers/scsi/aacraid/comminit.c | 239 +++++++++++++++++++++++++---------------
 drivers/scsi/aacraid/commsup.c  |  13 ++-
 drivers/scsi/aacraid/linit.c    |   2 +-
 drivers/scsi/aacraid/rkt.c      |   2 +-
 drivers/scsi/aacraid/rx.c       |   4 +-
 drivers/scsi/aacraid/sa.c       |   4 +-
 drivers/scsi/aacraid/src.c      |  27 +++--
 9 files changed, 261 insertions(+), 138 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 6678d1f..8a58b96 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1144,7 +1144,9 @@ static int aac_read_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u3
 	long ret;
 
 	aac_fib_init(fib);
-	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
+	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
+		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
+		!dev->sync_mode) {
 		struct aac_raw_io2 *readcmd2;
 		readcmd2 = (struct aac_raw_io2 *) fib_data(fib);
 		memset(readcmd2, 0, sizeof(struct aac_raw_io2));
@@ -1270,7 +1272,9 @@ static int aac_write_raw_io(struct fib * fib, struct scsi_cmnd * cmd, u64 lba, u
 	long ret;
 
 	aac_fib_init(fib);
-	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 && !dev->sync_mode) {
+	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
+		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) &&
+		!dev->sync_mode) {
 		struct aac_raw_io2 *writecmd2;
 		writecmd2 = (struct aac_raw_io2 *) fib_data(fib);
 		memset(writecmd2, 0, sizeof(struct aac_raw_io2));
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 01b457b..f712d8d 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -82,6 +82,11 @@ enum {
 #define AAC_DEBUG_INSTRUMENT_AIF_DELETE
 
 /*
+ * Interrupts
+ */
+#define AAC_MAX_HRRQ		64
+
+/*
  * These macros convert from physical channels to virtual channels
  */
 #define CONTAINER_CHANNEL		(0)
@@ -491,41 +496,64 @@ enum fib_xfer_state {
 #define ADAPTER_INIT_STRUCT_REVISION_4		4 // rocket science
 #define ADAPTER_INIT_STRUCT_REVISION_6		6 /* PMC src */
 #define ADAPTER_INIT_STRUCT_REVISION_7		7 /* Denali */
+#define ADAPTER_INIT_STRUCT_REVISION_8		8 // Thor
 
-struct aac_init
+union aac_init
 {
-	__le32	InitStructRevision;
-	__le32	Sa_MSIXVectors;
-	__le32	fsrev;
-	__le32	CommHeaderAddress;
-	__le32	FastIoCommAreaAddress;
-	__le32	AdapterFibsPhysicalAddress;
-	__le32	AdapterFibsVirtualAddress;
-	__le32	AdapterFibsSize;
-	__le32	AdapterFibAlign;
-	__le32	printfbuf;
-	__le32	printfbufsiz;
-	__le32	HostPhysMemPages;   /* number of 4k pages of host
-				       physical memory */
-	__le32	HostElapsedSeconds; /* number of seconds since 1970. */
-	/*
-	 * ADAPTER_INIT_STRUCT_REVISION_4 begins here
-	 */
-	__le32	InitFlags;	/* flags for supported features */
+	struct _r7 {
+		__le32	init_struct_revision;
+		__le32	no_of_msix_vectors;
+		__le32	fsrev;
+		__le32	comm_header_address;
+		__le32	fast_io_comm_area_address;
+		__le32	adapter_fibs_physical_address;
+		__le32	adapter_fibs_virtual_address;
+		__le32	adapter_fibs_size;
+		__le32	adapter_fib_align;
+		__le32	printfbuf;
+		__le32	printfbufsiz;
+		/* number of 4k pages of host phys. mem. */
+		__le32	host_phys_mem_pages;
+		/* number of seconds since 1970. */
+		__le32	host_elapsed_seconds;
+		/* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
+		__le32	init_flags;	/* flags for supported features */
 #define INITFLAGS_NEW_COMM_SUPPORTED	0x00000001
 #define INITFLAGS_DRIVER_USES_UTC_TIME	0x00000010
 #define INITFLAGS_DRIVER_SUPPORTS_PM	0x00000020
 #define INITFLAGS_NEW_COMM_TYPE1_SUPPORTED	0x00000040
 #define INITFLAGS_FAST_JBOD_SUPPORTED	0x00000080
 #define INITFLAGS_NEW_COMM_TYPE2_SUPPORTED	0x00000100
-	__le32	MaxIoCommands;	/* max outstanding commands */
-	__le32	MaxIoSize;	/* largest I/O command */
-	__le32	MaxFibSize;	/* largest FIB to adapter */
-	/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
-	__le32	MaxNumAif;	/* max number of aif */
-	/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
-	__le32	HostRRQ_AddrLow;
-	__le32	HostRRQ_AddrHigh;	/* Host RRQ (response queue) for SRC */
+#define INITFLAGS_DRIVER_SUPPORTS_HBA_MODE  0x00000400
+		__le32	max_io_commands;	/* max outstanding commands */
+		__le32	max_io_size;	/* largest I/O command */
+		__le32	max_fib_size;	/* largest FIB to adapter */
+		/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
+		__le32	max_num_aif;	/* max number of aif */
+		/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
+		/* Host RRQ (response queue) for SRC */
+		__le32	host_rrq_addr_low;
+		__le32	host_rrq_addr_high;
+	} r7;
+	struct _r8 {
+		/* ADAPTER_INIT_STRUCT_REVISION_8 */
+		__le32	init_struct_revision;
+		__le32	rr_queue_count;
+		__le32	host_elapsed_seconds; /* number of secs since 1970. */
+		__le32	init_flags;
+		__le32	max_io_size;	/* largest I/O command */
+		__le32	max_num_aif;	/* max number of aif */
+		__le32	reserved1;
+		__le32	reserved2;
+		struct _rrq {
+			__le32	host_addr_low;
+			__le32	host_addr_high;
+			__le16	msix_id;
+			__le16	element_count;
+			__le16	comp_thresh;
+			__le16	unused;
+		} rrq[1];		/* up to 64 RRQ addresses */
+	} r8;
 };
 
 enum aac_log_level {
@@ -729,6 +757,7 @@ struct sa_registers {
 
 
 #define SA_INIT_NUM_MSIXVECTORS		1
+#define SA_MINIPORT_REVISION		SA_INIT_NUM_MSIXVECTORS
 
 #define sa_readw(AEP, CSR)		readl(&((AEP)->regs.sa->CSR))
 #define sa_readl(AEP, CSR)		readl(&((AEP)->regs.sa->CSR))
@@ -1106,6 +1135,12 @@ struct aac_bus_info_response {
 #define AAC_OPT_NEW_COMM_TYPE3		cpu_to_le32(1<<30)
 #define AAC_OPT_NEW_COMM_TYPE4		cpu_to_le32(1<<31)
 
+#define AAC_COMM_PRODUCER		0
+#define AAC_COMM_MESSAGE		1
+#define AAC_COMM_MESSAGE_TYPE1		3
+#define AAC_COMM_MESSAGE_TYPE2		4
+#define AAC_COMM_MESSAGE_TYPE3		5
+
 /* MSIX context */
 struct aac_msix_ctx {
 	int		vector_no;
@@ -1159,8 +1194,11 @@ struct aac_dev
 
 	resource_size_t		base_size, dbg_size;	/* Size of
 							 *  mapped in region */
-
-	struct aac_init		*init;		/* Holds initialization info to communicate with adapter */
+	/*
+	 * Holds initialization info
+	 * to communicate with adapter
+	 */
+	union aac_init		*init;
 	dma_addr_t		init_pa;	/* Holds physical address of the init struct */
 
 	u32			*host_rrq;	/* response queue
@@ -1229,10 +1267,6 @@ struct aac_dev
 	u8			needs_dac;
 	u8			raid_scsi_mode;
 	u8			comm_interface;
-#	define AAC_COMM_PRODUCER 0
-#	define AAC_COMM_MESSAGE  1
-#	define AAC_COMM_MESSAGE_TYPE1	3
-#	define AAC_COMM_MESSAGE_TYPE2	4
 	u8			raw_io_interface;
 	u8			raw_io_64;
 	u8			printf_enabled;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 4f56b10..480ff01 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -68,104 +68,167 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 	unsigned long size, align;
 	const unsigned long fibsize = dev->max_fib_size;
 	const unsigned long printfbufsiz = 256;
-	unsigned long host_rrq_size = 0;
-	struct aac_init *init;
+	unsigned long host_rrq_size, aac_init_size;
+	union aac_init *init;
 	dma_addr_t phys;
 	unsigned long aac_max_hostphysmempages;
 
-	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
-	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2)
-		host_rrq_size = (dev->scsi_host_ptr->can_queue
-			+ AAC_NUM_MGT_FIB) * sizeof(u32);
-	size = fibsize + sizeof(struct aac_init) + commsize +
-			commalign + printfbufsiz + host_rrq_size;
- 
+	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
+		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
+		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3))
+		host_rrq_size =
+			(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)
+				* sizeof(u32);
+	else
+		host_rrq_size = 0;
+
+	aac_init_size = sizeof(union aac_init);
+	size = fibsize + aac_init_size + commsize + commalign +
+			printfbufsiz + host_rrq_size;
+
 	base = pci_alloc_consistent(dev->pdev, size, &phys);
 
-	if(base == NULL)
-	{
+	if (base == NULL) {
 		printk(KERN_ERR "aacraid: unable to create mapping.\n");
 		return 0;
 	}
+
 	dev->comm_addr = (void *)base;
 	dev->comm_phys = phys;
 	dev->comm_size = size;
-	
-	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
-	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
+
+	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
+	    (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
+	    (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) {
 		dev->host_rrq = (u32 *)(base + fibsize);
 		dev->host_rrq_pa = phys + fibsize;
 		memset(dev->host_rrq, 0, host_rrq_size);
 	}
 
-	dev->init = (struct aac_init *)(base + fibsize + host_rrq_size);
+	dev->init = (union aac_init *)(base + fibsize + host_rrq_size);
 	dev->init_pa = phys + fibsize + host_rrq_size;
 
 	init = dev->init;
 
-	init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
-	if (dev->max_fib_size != sizeof(struct hw_fib))
-		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
-	init->Sa_MSIXVectors = cpu_to_le32(SA_INIT_NUM_MSIXVECTORS);
-	init->fsrev = cpu_to_le32(dev->fsrev);
+	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
+		int i;
+		u64 addr;
+
+		init->r8.init_struct_revision =
+			cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_8);
+		init->r8.init_flags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+					INITFLAGS_DRIVER_USES_UTC_TIME |
+					INITFLAGS_DRIVER_SUPPORTS_PM);
+		init->r8.init_flags |=
+				cpu_to_le32(INITFLAGS_DRIVER_SUPPORTS_HBA_MODE);
+		init->r8.rr_queue_count = cpu_to_le32(dev->max_msix);
+		init->r8.max_io_size =
+			cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
+		init->r8.max_num_aif = init->r8.reserved1 =
+			init->r8.reserved2 = 0;
+
+		for (i = 0; i < dev->max_msix; i++) {
+			addr = (u64)dev->host_rrq_pa + dev->vector_cap * i *
+					sizeof(u32);
+			init->r8.rrq[i].host_addr_high = cpu_to_le32(
+						upper_32_bits(addr));
+			init->r8.rrq[i].host_addr_low = cpu_to_le32(
+						lower_32_bits(addr));
+			init->r8.rrq[i].msix_id = i;
+			init->r8.rrq[i].element_count = cpu_to_le16(
+					(u16)dev->vector_cap);
+			init->r8.rrq[i].comp_thresh =
+					init->r8.rrq[i].unused = 0;
+		}
 
-	/*
-	 *	Adapter Fibs are the first thing allocated so that they
-	 *	start page aligned
-	 */
-	dev->aif_base_va = (struct hw_fib *)base;
-	
-	init->AdapterFibsVirtualAddress = 0;
-	init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
-	init->AdapterFibsSize = cpu_to_le32(fibsize);
-	init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
-	/*
-	 * number of 4k pages of host physical memory. The aacraid fw needs
-	 * this number to be less than 4gb worth of pages. New firmware doesn't
-	 * have any issues with the mapping system, but older Firmware did, and
-	 * had *troubles* dealing with the math overloading past 32 bits, thus
-	 * we must limit this field.
-	 */
-	aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
-	if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
-		init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
-	else
-		init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
-
-	init->InitFlags = cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
-		INITFLAGS_DRIVER_SUPPORTS_PM);
-	init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
-	init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
-	init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
-	init->MaxNumAif = cpu_to_le32(dev->max_num_aif);
-
-	if (dev->comm_interface == AAC_COMM_MESSAGE) {
-		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
-		dprintk((KERN_WARNING"aacraid: New Comm Interface enabled\n"));
-	} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
-		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
-		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
-			INITFLAGS_NEW_COMM_TYPE1_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
-		init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
-		init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
-		dprintk((KERN_WARNING"aacraid: New Comm Interface type1 enabled\n"));
-	} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
-		init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
-		init->InitFlags |= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
-			INITFLAGS_NEW_COMM_TYPE2_SUPPORTED | INITFLAGS_FAST_JBOD_SUPPORTED);
-		init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
-		init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));
-		/* number of MSI-X */
-		init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
-		dprintk((KERN_WARNING"aacraid: New Comm Interface type2 enabled\n"));
+		pr_warn("aacraid: Comm Interface type3 enabled\n");
+	} else {
+		init->r7.init_struct_revision =
+			cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
+		if (dev->max_fib_size != sizeof(struct hw_fib))
+			init->r7.init_struct_revision =
+				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
+		init->r7.no_of_msix_vectors = cpu_to_le32(SA_MINIPORT_REVISION);
+		init->r7.fsrev = cpu_to_le32(dev->fsrev);
+
+		/*
+		 *	Adapter Fibs are the first thing allocated so that they
+		 *	start page aligned
+		 */
+		dev->aif_base_va = (struct hw_fib *)base;
+
+		init->r7.adapter_fibs_virtual_address = 0;
+		init->r7.adapter_fibs_physical_address = cpu_to_le32((u32)phys);
+		init->r7.adapter_fibs_size = cpu_to_le32(fibsize);
+		init->r7.adapter_fib_align = cpu_to_le32(sizeof(struct hw_fib));
+
+		/*
+		 * number of 4k pages of host physical memory. The aacraid fw
+		 * needs this number to be less than 4gb worth of pages. New
+		 * firmware doesn't have any issues with the mapping system, but
+		 * older Firmware did, and had *troubles* dealing with the math
+		 * overloading past 32 bits, thus we must limit this field.
+		 */
+		aac_max_hostphysmempages =
+				dma_get_required_mask(&dev->pdev->dev) >> 12;
+		if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
+			init->r7.host_phys_mem_pages =
+					cpu_to_le32(aac_max_hostphysmempages);
+		else
+			init->r7.host_phys_mem_pages =
+					cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
+
+		init->r7.init_flags =
+			cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
+			INITFLAGS_DRIVER_SUPPORTS_PM);
+		init->r7.max_io_commands =
+			cpu_to_le32(dev->scsi_host_ptr->can_queue +
+					AAC_NUM_MGT_FIB);
+		init->r7.max_io_size =
+			cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
+		init->r7.max_fib_size = cpu_to_le32(dev->max_fib_size);
+		init->r7.max_num_aif = cpu_to_le32(dev->max_num_aif);
+
+		if (dev->comm_interface == AAC_COMM_MESSAGE) {
+			init->r7.init_flags |=
+				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED);
+			pr_warn("aacraid: Comm Interface enabled\n");
+		} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) {
+			init->r7.init_struct_revision =
+				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
+			init->r7.init_flags |=
+				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+				INITFLAGS_NEW_COMM_TYPE1_SUPPORTED |
+				INITFLAGS_FAST_JBOD_SUPPORTED);
+			init->r7.host_rrq_addr_high =
+				cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
+			init->r7.host_rrq_addr_low =
+				cpu_to_le32(lower_32_bits(dev->host_rrq_pa));
+			pr_warn("aacraid: Comm Interface type1 enabled\n");
+		} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
+			init->r7.init_struct_revision =
+				cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
+			init->r7.init_flags |=
+				cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+				INITFLAGS_NEW_COMM_TYPE2_SUPPORTED |
+				INITFLAGS_FAST_JBOD_SUPPORTED);
+			init->r7.host_rrq_addr_high =
+				cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
+			init->r7.host_rrq_addr_low =
+				cpu_to_le32(lower_32_bits(dev->host_rrq_pa));
+			init->r7.no_of_msix_vectors =
+				cpu_to_le32(dev->max_msix);
+			/* must be the COMM_PREFERRED_SETTINGS values */
+			pr_warn("aacraid: Comm Interface type2 enabled\n");
+		}
 	}
 
 	/*
 	 * Increment the base address by the amount already used
 	 */
-	base = base + fibsize + host_rrq_size + sizeof(struct aac_init);
+	base = base + fibsize + host_rrq_size + aac_init_size;
 	phys = (dma_addr_t)((ulong)phys + fibsize + host_rrq_size +
-		sizeof(struct aac_init));
+			aac_init_size);
 
 	/*
 	 *	Align the beginning of Headers to commalign
@@ -177,7 +240,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 	 *	Fill in addresses of the Comm Area Headers and Queues
 	 */
 	*commaddr = base;
-	init->CommHeaderAddress = cpu_to_le32((u32)phys);
+	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3)
+		init->r7.comm_header_address = cpu_to_le32((u32)phys);
 	/*
 	 *	Increment the base address by the size of the CommArea
 	 */
@@ -187,12 +251,14 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 	 *	 Place the Printf buffer area after the Fast I/O comm area.
 	 */
 	dev->printfbuf = (void *)base;
-	init->printfbuf = cpu_to_le32(phys);
-	init->printfbufsiz = cpu_to_le32(printfbufsiz);
+	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3) {
+		init->r7.printfbuf = cpu_to_le32(phys);
+		init->r7.printfbufsiz = cpu_to_le32(printfbufsiz);
+	}
 	memset(base, 0, printfbufsiz);
 	return 1;
 }
-    
+
 static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem, int qsize)
 {
 	atomic_set(&q->numpending, 0);
@@ -436,26 +502,27 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 
 	if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
 		0, 0, 0, 0, 0, 0,
-		status+0, status+1, status+2, status+3, NULL)) &&
-	 		(status[0] == 0x00000001)) {
+		status+0, status+1, status+2, status+3, status+4)) &&
+		(status[0] == 0x00000001)) {
 		dev->doorbell_mask = status[3];
-		if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
+		if (status[1] & AAC_OPT_NEW_COMM_64)
 			dev->raw_io_64 = 1;
 		dev->sync_mode = aac_sync_mode;
 		if (dev->a_ops.adapter_comm &&
-			(status[1] & le32_to_cpu(AAC_OPT_NEW_COMM))) {
+			(status[1] & AAC_OPT_NEW_COMM)) {
 				dev->comm_interface = AAC_COMM_MESSAGE;
 				dev->raw_io_interface = 1;
-			if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE1))) {
+			if ((status[1] & AAC_OPT_NEW_COMM_TYPE1)) {
 				/* driver supports TYPE1 (Tupelo) */
 				dev->comm_interface = AAC_COMM_MESSAGE_TYPE1;
-			} else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE2))) {
-				/* driver supports TYPE2 (Denali) */
+			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE2) {
+				/* driver supports TYPE2 (Denali, Yosemite) */
 				dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
-			} else if ((status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE4)) ||
-				  (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_TYPE3))) {
-				/* driver doesn't TYPE3 and TYPE4 */
-				/* switch to sync. mode */
+			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE3) {
+				/* driver supports TYPE3 (Yosemite, Thor) */
+				dev->comm_interface = AAC_COMM_MESSAGE_TYPE3;
+			} else if (status[1] & AAC_OPT_NEW_COMM_TYPE4) {
+				/* not supported TYPE - switch to sync. mode */
 				dev->comm_interface = AAC_COMM_MESSAGE_TYPE2;
 				dev->sync_mode = 1;
 			}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 9e7551f..d18ed9a 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -129,11 +129,14 @@ int aac_fib_setup(struct aac_dev * dev)
 	struct hw_fib *hw_fib;
 	dma_addr_t hw_fib_pa;
 	int i;
+	u32 max_cmds;
 
 	while (((i = fib_map_alloc(dev)) == -ENOMEM)
 	 && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
-		dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1);
-		dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB;
+		max_cmds = (dev->scsi_host_ptr->can_queue+AAC_NUM_MGT_FIB) >> 1;
+		dev->scsi_host_ptr->can_queue = max_cmds - AAC_NUM_MGT_FIB;
+		if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE3)
+			dev->init->r7.max_io_commands = cpu_to_le32(max_cmds);
 	}
 	if (i<0)
 		return -ENOMEM;
@@ -761,7 +764,8 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
 	unsigned long qflags;
 
 	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1 ||
-	    dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
+		dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
+		dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
 		kfree(hw_fib);
 		return 0;
 	}
@@ -1817,7 +1821,8 @@ int aac_command_thread(void *data)
 				 * and pre-allocate a set of fibs outside the
 				 * lock.
 				 */
-				num = le32_to_cpu(dev->init->AdapterFibsSize)
+				num = le32_to_cpu(dev->init->
+							r7.adapter_fibs_size)
 				    / sizeof(struct hw_fib); /* some extra */
 				spin_lock_irqsave(&dev->fib_lock, flagv);
 				entry = dev->fib_list.next;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index fd26a2d..0f3de1e 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1368,7 +1368,7 @@ static int aac_acquire_resources(struct aac_dev *dev)
 		/* After EEH recovery or suspend resume, max_msix count
 		 * may change, therfore updating in init as well.
 		 */
-		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
+		dev->init->r7.no_of_msix_vectors = cpu_to_le32(dev->max_msix);
 		aac_adapter_start(dev);
 	}
 	return 0;
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 7d8013f..6dff8ad 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -60,7 +60,7 @@ static int aac_rkt_select_comm(struct aac_dev *dev, int comm)
 		 * case warrants this half baked, but convenient, check here.
 		 */
 		if (dev->scsi_host_ptr->can_queue > AAC_NUM_IO_FIB_RKT) {
-			dev->init->MaxIoCommands =
+			dev->init->r7.max_io_commands =
 				cpu_to_le32(AAC_NUM_IO_FIB_RKT + AAC_NUM_MGT_FIB);
 			dev->scsi_host_ptr->can_queue = AAC_NUM_IO_FIB_RKT;
 		}
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index ac16380..67213b9 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -315,10 +315,10 @@ static void aac_rx_notify_adapter(struct aac_dev *dev, u32 event)
 
 static void aac_rx_start_adapter(struct aac_dev *dev)
 {
-	struct aac_init *init;
+	union aac_init *init;
 
 	init = dev->init;
-	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
+	init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 	// We can only use a 32 bit address here
 	rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
 	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 869aea2..b8538e0 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -245,12 +245,12 @@ static void aac_sa_interrupt_adapter (struct aac_dev *dev)
 
 static void aac_sa_start_adapter(struct aac_dev *dev)
 {
-	struct aac_init *init;
+	union aac_init *init;
 	/*
 	 * Fill in the remaining pieces of the init.
 	 */
 	init = dev->init;
-	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
+	init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
 	/* We can only use a 32 bit address here */
 	sa_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, 
 			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 0c45388..a5f7a6f 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -384,7 +384,7 @@ static void aac_src_notify_adapter(struct aac_dev *dev, u32 event)
 
 static void aac_src_start_adapter(struct aac_dev *dev)
 {
-	struct aac_init *init;
+	union aac_init *init;
 	int i;
 
 	 /* reset host_rrq_idx first */
@@ -395,11 +395,22 @@ static void aac_src_start_adapter(struct aac_dev *dev)
 	dev->fibs_pushed_no = 0;
 
 	init = dev->init;
-	init->HostElapsedSeconds = cpu_to_le32(get_seconds());
+	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
+		init->r8.host_elapsed_seconds = cpu_to_le32(get_seconds());
+		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
+			(u32)(ulong)dev->init_pa,
+			(u32)((ulong)dev->init_pa>>32),
+			sizeof(struct _r8) +
+			(AAC_MAX_HRRQ - 1) * sizeof(struct _rrq),
+			0, 0, 0, NULL, NULL, NULL, NULL, NULL);
+	} else {
+		init->r7.host_elapsed_seconds = cpu_to_le32(get_seconds());
+		// We can only use a 32 bit address here
+		src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS,
+			(u32)(ulong)dev->init_pa, 0, 0, 0, 0, 0,
+			NULL, NULL, NULL, NULL, NULL);
+	}
 
-	/* We can only use a 32 bit address here */
-	src_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa,
-	  0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -467,7 +478,8 @@ static int aac_src_deliver_message(struct fib *fib)
 
 	atomic_inc(&dev->rrq_outstanding[vector_no]);
 
-	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) {
+	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
+		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) {
 		/* Calculate the amount to the fibsize bits */
 		fibsize = (hdr_size + 127) / 128 - 1;
 		if (fibsize > (ALIGN32 - 1))
@@ -897,7 +909,8 @@ int aac_srcv_init(struct aac_dev *dev)
 
 	if (aac_init_adapter(dev) == NULL)
 		goto error_iounmap;
-	if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2)
+	if ((dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) &&
+		(dev->comm_interface != AAC_COMM_MESSAGE_TYPE3))
 		goto error_iounmap;
 	if (dev->msi_enabled)
 		aac_src_access_devreg(dev, AAC_ENABLE_MSIX);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 04/24] aacraid: Added sa firmware support
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (2 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:23   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

sa_firmware adds the capability to differentiate the new SmartIOC family
of adapters from the series 8 and below.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in V3:
Removed unnecessary brackets

 drivers/scsi/aacraid/aacraid.h  |  4 ++
 drivers/scsi/aacraid/comminit.c | 98 +++++++++++++++++------------------------
 drivers/scsi/aacraid/linit.c    |  2 +-
 3 files changed, 45 insertions(+), 59 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index f712d8d..1069c01 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1130,6 +1130,7 @@ struct aac_bus_info_response {
 #define AAC_OPT_SUPPLEMENT_ADAPTER_INFO	cpu_to_le32(1<<16)
 #define AAC_OPT_NEW_COMM		cpu_to_le32(1<<17)
 #define AAC_OPT_NEW_COMM_64		cpu_to_le32(1<<18)
+#define AAC_OPT_EXTENDED		cpu_to_le32(1<<23)
 #define AAC_OPT_NEW_COMM_TYPE1		cpu_to_le32(1<<28)
 #define AAC_OPT_NEW_COMM_TYPE2		cpu_to_le32(1<<29)
 #define AAC_OPT_NEW_COMM_TYPE3		cpu_to_le32(1<<30)
@@ -1141,6 +1142,8 @@ struct aac_bus_info_response {
 #define AAC_COMM_MESSAGE_TYPE2		4
 #define AAC_COMM_MESSAGE_TYPE3		5
 
+#define AAC_EXTOPT_SA_FIRMWARE		cpu_to_le32(1<<1)
+
 /* MSIX context */
 struct aac_msix_ctx {
 	int		vector_no;
@@ -1272,6 +1275,7 @@ struct aac_dev
 	u8			printf_enabled;
 	u8			in_reset;
 	u8			msi;
+	u8			sa_firmware;
 	int			management_fib_count;
 	spinlock_t		manage_lock;
 	spinlock_t		sync_lock;
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 480ff01..5aad018 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -75,14 +75,22 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
 
 	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
 		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
-		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3))
+		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 &&
+		!dev->sa_firmware)) {
 		host_rrq_size =
 			(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)
 				* sizeof(u32);
-	else
+		aac_init_size = sizeof(union aac_init);
+	} else if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 &&
+		dev->sa_firmware) {
+		host_rrq_size = (dev->scsi_host_ptr->can_queue
+			+ AAC_NUM_MGT_FIB) * sizeof(u32)  * AAC_MAX_MSIX;
+		aac_init_size = sizeof(union aac_init) +
+			(AAC_MAX_HRRQ - 1) * sizeof(struct _rrq);
+	} else {
 		host_rrq_size = 0;
-
-	aac_init_size = sizeof(union aac_init);
+		aac_init_size = sizeof(union aac_init);
+	}
 	size = fibsize + aac_init_size + commsize + commalign +
 			printfbufsiz + host_rrq_size;
 
@@ -466,9 +474,13 @@ void aac_define_int_mode(struct aac_dev *dev)
 		if (dev->max_msix > msi_count)
 			dev->max_msix = msi_count;
 	}
-	dev->vector_cap =
-		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) /
-		msi_count;
+	if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE3 && dev->sa_firmware)
+		dev->vector_cap = dev->scsi_host_ptr->can_queue +
+				AAC_NUM_MGT_FIB;
+	else
+		dev->vector_cap = (dev->scsi_host_ptr->can_queue +
+				AAC_NUM_MGT_FIB) / msi_count;
+
 }
 struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 {
@@ -527,6 +539,12 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 				dev->sync_mode = 1;
 			}
 		}
+		if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) &&
+			(status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE)))
+			dev->sa_firmware = 1;
+		else
+			dev->sa_firmware = 0;
+
 		if ((dev->comm_interface == AAC_COMM_MESSAGE) &&
 		    (status[2] > dev->base_size)) {
 			aac_adapter_ioremap(dev, 0);
@@ -563,61 +581,25 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
 		dev->sg_tablesize = status[2] & 0xFFFF;
 		if (dev->pdev->device == PMC_DEVICE_S7 ||
 		    dev->pdev->device == PMC_DEVICE_S8 ||
-		    dev->pdev->device == PMC_DEVICE_S9)
-			host->can_queue = ((status[3] >> 16) ? (status[3] >> 16) :
-				(status[3] & 0xFFFF)) - AAC_NUM_MGT_FIB;
-		else
-			host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
+		    dev->pdev->device == PMC_DEVICE_S9) {
+			if (host->can_queue > (status[3] >> 16) -
+					AAC_NUM_MGT_FIB)
+				host->can_queue = (status[3] >> 16) -
+					AAC_NUM_MGT_FIB;
+		} else if (host->can_queue > (status[3] & 0xFFFF) -
+				AAC_NUM_MGT_FIB)
+			host->can_queue = (status[3] & 0xFFFF) -
+				AAC_NUM_MGT_FIB;
+
 		dev->max_num_aif = status[4] & 0xFFFF;
-		/*
-		 *	NOTE:
-		 *	All these overrides are based on a fixed internal
-		 *	knowledge and understanding of existing adapters,
-		 *	acbsize should be set with caution.
-		 */
-		if (acbsize == 512) {
-			host->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
-			dev->max_fib_size = 512;
-			dev->sg_tablesize = host->sg_tablesize
-			  = (512 - sizeof(struct aac_fibhdr)
-			    - sizeof(struct aac_write) + sizeof(struct sgentry))
-			     / sizeof(struct sgentry);
-			host->can_queue = AAC_NUM_IO_FIB;
-		} else if (acbsize == 2048) {
-			host->max_sectors = 512;
-			dev->max_fib_size = 2048;
-			host->sg_tablesize = 65;
-			dev->sg_tablesize = 81;
-			host->can_queue = 512 - AAC_NUM_MGT_FIB;
-		} else if (acbsize == 4096) {
-			host->max_sectors = 1024;
-			dev->max_fib_size = 4096;
-			host->sg_tablesize = 129;
-			dev->sg_tablesize = 166;
-			host->can_queue = 256 - AAC_NUM_MGT_FIB;
-		} else if (acbsize == 8192) {
-			host->max_sectors = 2048;
-			dev->max_fib_size = 8192;
-			host->sg_tablesize = 257;
-			dev->sg_tablesize = 337;
-			host->can_queue = 128 - AAC_NUM_MGT_FIB;
-		} else if (acbsize > 0) {
-			printk("Illegal acbsize=%d ignored\n", acbsize);
-		}
 	}
-	{
-
-		if (numacb > 0) {
-			if (numacb < host->can_queue)
-				host->can_queue = numacb;
-			else
-				printk("numacb=%d ignored\n", numacb);
-		}
+	if (numacb > 0) {
+		if (numacb < host->can_queue)
+			host->can_queue = numacb;
+		else
+			pr_warn("numacb=%d ignored\n", numacb);
 	}
 
-	if (host->can_queue > AAC_NUM_IO_FIB)
-		host->can_queue = AAC_NUM_IO_FIB;
-
 	if (dev->pdev->device == PMC_DEVICE_S6 ||
 	    dev->pdev->device == PMC_DEVICE_S7 ||
 	    dev->pdev->device == PMC_DEVICE_S8 ||
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 0f3de1e..1912e7b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1285,7 +1285,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	else
 		shost->this_id = shost->max_id;
 
-	if (aac_drivers[index].quirks & AAC_QUIRK_SRC)
+	if (!aac->sa_firmware && aac_drivers[index].quirks & AAC_QUIRK_SRC)
 		aac_intr_normal(aac, 0, 2, 0, NULL);
 
 	/*
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 05/24] aacraid: Retrieve and update the device types
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (3 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:35   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
                   ` (18 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patch adds support to retrieve the type of each adapter connected
device. Applicable to HBA1000 and SmartIOC2000 products

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

---
Changes in  V2:
Fixed uninitialized return value

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c  | 144 ++++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/aacraid/aacraid.h |  60 ++++++++++++++++-
 2 files changed, 202 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 8a58b96..f2ec795 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1509,11 +1509,141 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
 	return aac_scsi_32(fib, cmd);
 }
 
+/**
+ *	aac_update hba_map()-	update current hba map with data from FW
+ *	@dev:	aac_dev structure
+ *	@phys_luns: FW information from report phys luns
+ *
+ *	Update our hba map with the information gathered from the FW
+ */
+void aac_update_hba_map(struct aac_dev *dev,
+		struct aac_ciss_phys_luns_resp *phys_luns)
+{
+	/* ok and extended reporting */
+	u32 lun_count, nexus;
+	u32 i, bus, target;
+	u8 expose_flag, attribs;
+	u8 devtype;
+
+	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;
+
+	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 *) &phys_luns->lun[i].node_ident[12]);
+
+		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;
+		}
+
+		if (nexus != 0 && (attribs & 8)) {
+			devtype = AAC_DEVTYPE_NATIVE_RAW;
+			dev->hba_map[bus][target].rmw_nexus =
+					nexus;
+		} else
+			devtype = AAC_DEVTYPE_ARC_RAW;
+
+		if (devtype != AAC_DEVTYPE_NATIVE_RAW)
+			goto update_devtype;
+
+update_devtype:
+		dev->hba_map[bus][target].devtype = devtype;
+	}
+}
+
+/**
+ *	aac_report_phys_luns()	Process topology change
+ *	@dev:		aac_dev structure
+ *	@fibptr:	fib pointer
+ *
+ *	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 fibsize, datasize;
+	struct aac_ciss_phys_luns_resp *phys_luns;
+	struct aac_srb *srbcmd;
+	struct sgmap64 *sg64;
+	dma_addr_t addr;
+	u32 vbus, vid;
+	u32 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 = (struct aac_ciss_phys_luns_resp *) pci_alloc_consistent(
+			dev->pdev, datasize, &addr);
+
+	if (phys_luns == NULL) {
+		rcode = -ENOMEM;
+		goto err_out;
+	}
+
+	vbus = (u32) le16_to_cpu(
+			dev->supplement_adapter_info.VirtDeviceBus);
+	vid = (u32) le16_to_cpu(
+			dev->supplement_adapter_info.VirtDeviceTarget);
+
+	aac_fib_init(fibptr);
+
+	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);
+
+	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);
+
+	sg64 = (struct sgmap64 *) &srbcmd->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);
+
+	rcode = aac_fib_send(ScsiPortCommand64, fibptr, fibsize,
+			FsaNormal, 1, 1, NULL, NULL);
+
+	/* analyse data */
+	if (rcode >= 0 && phys_luns->resp_flag == 2) {
+		/* ok and extended reporting */
+		aac_update_hba_map(dev, phys_luns);
+	}
+
+	pci_free_consistent(dev->pdev, datasize, (void *) phys_luns, addr);
+err_out:
+	return rcode;
+}
+
 int aac_get_adapter_info(struct aac_dev* dev)
 {
 	struct fib* fibptr;
 	int rcode;
-	u32 tmp;
+	u32 tmp, bus, target;
 	struct aac_adapter_info *info;
 	struct aac_bus_info *command;
 	struct aac_bus_info_response *bus_info;
@@ -1544,6 +1674,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
 	}
 	memcpy(&dev->adapter_info, info, sizeof(*info));
 
+	dev->supplement_adapter_info.VirtDeviceBus = 0xffff;
 	if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
 		struct aac_supplement_adapter_info * sinfo;
 
@@ -1571,6 +1702,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
 
 	}
 
+	/* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
+	for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
+		for (target = 0; target < AAC_MAX_TARGETS; target++)
+			dev->hba_map[bus][target].devtype = 0;
+	}
 
 	/*
 	 * GetBusInfo
@@ -1603,6 +1739,12 @@ 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.VirtDeviceBus != 0xffff) {
+		/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
+		rcode = aac_report_phys_luns(dev, fibptr);
+	}
+
 	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 1069c01..00df610 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -81,6 +81,27 @@ enum {
 
 #define AAC_DEBUG_INSTRUMENT_AIF_DELETE
 
+#define AAC_MAX_NATIVE_TARGETS		1024
+/* Thor: 5 phys. buses: #0: empty, 1-4: 256 targets each */
+#define AAC_MAX_BUSES			5
+#define AAC_MAX_TARGETS		256
+#define AAC_MAX_NATIVE_SIZE		2048
+
+#define CISS_REPORT_PHYSICAL_LUNS	0xc3
+
+struct aac_ciss_phys_luns_resp {
+	u8	list_length[4];		/* LUN list length (N-7, big endian) */
+	u8	resp_flag;		/* extended response_flag */
+	u8	reserved[3];
+	struct _ciss_lun {
+		u8	tid[3];		/* Target ID */
+		u8	bus;		/* Bus, flag (bits 6,7) */
+		u8	level3[2];
+		u8	level2[2];
+		u8	node_ident[16];	/* phys. node identifier */
+	} lun[1];			/* List of phys. devices */
+};
+
 /*
  * Interrupts
  */
@@ -993,6 +1014,20 @@ struct fib {
 	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
 };
 
+#define AAC_DEVTYPE_RAID_MEMBER	1
+#define AAC_DEVTYPE_ARC_RAW		2
+#define AAC_DEVTYPE_NATIVE_RAW		3
+#define AAC_EXPOSE_DISK		0
+#define AAC_HIDE_DISK			3
+
+struct aac_hba_map_info {
+	__le32	rmw_nexus;		/* nexus for native HBA devices */
+	u8		devtype;	/* device type */
+	u8		reset_state;	/* 0 - no reset, 1..x - */
+					/* after xth TM LUN reset */
+	u8		expose;		/*checks if to expose or not*/
+};
+
 /*
  *	Adapter Information Block
  *
@@ -1056,7 +1091,28 @@ struct aac_supplement_adapter_info
 	/* StructExpansion == 1 */
 	__le32	FeatureBits3;
 	__le32	SupportedPerformanceModes;
-	__le32	ReservedForFutureGrowth[80];
+	u8	HostBusType;		/* uses HOST_BUS_TYPE_xxx defines */
+	u8	HostBusWidth;		/* actual width in bits or links */
+	u16	HostBusSpeed;		/* actual bus speed/link rate in MHz */
+	u8	MaxRRCDrives;		/* max. number of ITP-RRC drives/pool */
+	u8	MaxDiskXtasks;		/* max. possible num of DiskX Tasks */
+
+	u8	CpldVerLoaded;
+	u8	CpldVerInFlash;
+
+	__le64	MaxRRCCapacity;
+	__le32	CompiledMaxHistLogLevel;
+	u8	CustomBoardName[12];
+	u16	SupportedCntlrMode;	/* identify supported controller mode */
+	u16	ReservedForFuture16;
+	__le32	SupportedOptions3;	/* reserved for future options */
+
+	__le16	VirtDeviceBus;		/* virt. SCSI device for Thor */
+	__le16	VirtDeviceTarget;
+	__le16	VirtDeviceLUN;
+	__le16	Unused;
+	__le32	ReservedForFutureGrowth[68];
+
 };
 #define AAC_FEATURE_FALCON	cpu_to_le32(0x00000010)
 #define AAC_FEATURE_JBOD	cpu_to_le32(0x08000000)
@@ -1287,6 +1343,7 @@ struct aac_dev
 	u32			vector_cap;	/* MSI-X vector capab.*/
 	int			msi_enabled;	/* MSI/MSI-X enabled */
 	struct aac_msix_ctx	aac_msix[AAC_MAX_MSIX]; /* context */
+	struct aac_hba_map_info	hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
 	u8			adapter_shutdown;
 	u32			handle_pci_error;
 };
@@ -2171,6 +2228,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
 
 int aac_acquire_irq(struct aac_dev *dev);
 void aac_free_irq(struct aac_dev *dev);
+int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr);
 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);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 06/24] aacraid: Reworked scsi command submission path
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (4 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:38   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 07/24] aacraid: Process Error for response I/O Raghava Aditya Renukunta
                   ` (17 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Moved the READ and WRITE switch cases to the top. Added a  default
case to the switch case and replaced duplicate scsi result value with a
macro.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c | 172 +++++++++++++++++-------------------------
 1 file changed, 70 insertions(+), 102 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index f2ec795..e7456a0 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -106,6 +106,8 @@
 #define ASENCODE_LUN_FAILED_SELF_CONFIG		0x00
 #define ASENCODE_OVERLAPPED_COMMAND		0x00
 
+#define AAC_STAT_GOOD (DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD)
+
 #define BYTE0(x) (unsigned char)(x)
 #define BYTE1(x) (unsigned char)((x) >> 8)
 #define BYTE2(x) (unsigned char)((x) >> 16)
@@ -2476,8 +2478,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			if((cid >= dev->maximum_num_containers) ||
 					(scsicmd->device->lun != 0)) {
 				scsicmd->result = DID_NO_CONNECT << 16;
-				scsicmd->scsi_done(scsicmd);
-				return 0;
+				goto scsi_done_ret;
 			}
 
 			/*
@@ -2512,8 +2513,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				return aac_send_srb_fib(scsicmd);
 			} else {
 				scsicmd->result = DID_NO_CONNECT << 16;
-				scsicmd->scsi_done(scsicmd);
-				return 0;
+				goto scsi_done_ret;
 			}
 		}
 	}
@@ -2531,13 +2531,34 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
 		       min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
 			     SCSI_SENSE_BUFFERSIZE));
-		scsicmd->scsi_done(scsicmd);
-		return 0;
+		goto scsi_done_ret;
 	}
 
-
-	/* Handle commands here that don't really require going out to the adapter */
 	switch (scsicmd->cmnd[0]) {
+	case READ_6:
+	case READ_10:
+	case READ_12:
+	case READ_16:
+		if (dev->in_reset)
+			return -1;
+		return aac_read(scsicmd);
+
+	case WRITE_6:
+	case WRITE_10:
+	case WRITE_12:
+	case WRITE_16:
+		if (dev->in_reset)
+			return -1;
+		return aac_write(scsicmd);
+
+	case SYNCHRONIZE_CACHE:
+		if (((aac_cache & 6) == 6) && dev->cache_protected) {
+			scsicmd->result = AAC_STAT_GOOD;
+			break;
+		}
+		/* Issue FIB to tell Firmware to flush it's cache */
+		if ((aac_cache & 6) != 2)
+			return aac_synchronize(scsicmd);
 	case INQUIRY:
 	{
 		struct inquiry_data inq_data;
@@ -2560,8 +2581,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				arr[1] = scsicmd->cmnd[2];
 				scsi_sg_copy_from_buffer(scsicmd, &inq_data,
 							 sizeof(inq_data));
-				scsicmd->result = DID_OK << 16 |
-				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+				scsicmd->result = AAC_STAT_GOOD;
 			} else if (scsicmd->cmnd[2] == 0x80) {
 				/* unit serial number page */
 				arr[3] = setinqserial(dev, &arr[4],
@@ -2572,8 +2592,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				if (aac_wwn != 2)
 					return aac_get_container_serial(
 						scsicmd);
-				scsicmd->result = DID_OK << 16 |
-				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+				scsicmd->result = AAC_STAT_GOOD;
 			} else if (scsicmd->cmnd[2] == 0x83) {
 				/* vpd page 0x83 - Device Identification Page */
 				char *sno = (char *)&inq_data;
@@ -2582,8 +2601,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				if (aac_wwn != 2)
 					return aac_get_container_serial(
 						scsicmd);
-				scsicmd->result = DID_OK << 16 |
-				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+				scsicmd->result = AAC_STAT_GOOD;
 			} else {
 				/* vpd page not implemented */
 				scsicmd->result = DID_OK << 16 |
@@ -2598,8 +2616,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 					sizeof(dev->fsa_dev[cid].sense_data),
 					SCSI_SENSE_BUFFERSIZE));
 			}
-			scsicmd->scsi_done(scsicmd);
-			return 0;
+			break;
 		}
 		inq_data.inqd_ver = 2;	/* claim compliance to SCSI-2 */
 		inq_data.inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
@@ -2615,9 +2632,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			inq_data.inqd_pdt = INQD_PDT_PROC;	/* Processor device */
 			scsi_sg_copy_from_buffer(scsicmd, &inq_data,
 						 sizeof(inq_data));
-			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-			scsicmd->scsi_done(scsicmd);
-			return 0;
+			scsicmd->result = AAC_STAT_GOOD;
+			break;
 		}
 		if (dev->in_reset)
 			return -1;
@@ -2665,10 +2681,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		/* Do not cache partition table for arrays */
 		scsicmd->device->removable = 1;
 
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 	}
 
 	case READ_CAPACITY:
@@ -2693,11 +2707,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
 		/* Do not cache partition table for arrays */
 		scsicmd->device->removable = 1;
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
-		  SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 	}
 
 	case MODE_SENSE:
@@ -2775,10 +2786,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		scsi_sg_copy_from_buffer(scsicmd,
 					 (char *)&mpd,
 					 mode_buf_length);
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 	}
 	case MODE_SENSE_10:
 	{
@@ -2854,18 +2863,17 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 					 (char *)&mpd10,
 					 mode_buf_length);
 
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 	}
 	case REQUEST_SENSE:
 		dprintk((KERN_DEBUG "REQUEST SENSE command.\n"));
-		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, sizeof (struct sense_data));
-		memset(&dev->fsa_dev[cid].sense_data, 0, sizeof (struct sense_data));
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-		return 0;
+		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+				sizeof(struct sense_data));
+		memset(&dev->fsa_dev[cid].sense_data, 0,
+				sizeof(struct sense_data));
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 
 	case ALLOW_MEDIUM_REMOVAL:
 		dprintk((KERN_DEBUG "LOCK command.\n"));
@@ -2874,9 +2882,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		else
 			fsa_dev_ptr[cid].locked = 0;
 
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 	/*
 	 *	These commands are all No-Ops
 	 */
@@ -2892,80 +2899,41 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			       min_t(size_t,
 				     sizeof(dev->fsa_dev[cid].sense_data),
 				     SCSI_SENSE_BUFFERSIZE));
-			scsicmd->scsi_done(scsicmd);
-			return 0;
+		break;
 		}
-		/* FALLTHRU */
 	case RESERVE:
 	case RELEASE:
 	case REZERO_UNIT:
 	case REASSIGN_BLOCKS:
 	case SEEK_10:
-		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-		scsicmd->scsi_done(scsicmd);
-		return 0;
+		scsicmd->result = AAC_STAT_GOOD;
+		break;
 
 	case START_STOP:
 		return aac_start_stop(scsicmd);
-	}
 
-	switch (scsicmd->cmnd[0])
-	{
-		case READ_6:
-		case READ_10:
-		case READ_12:
-		case READ_16:
-			if (dev->in_reset)
-				return -1;
-			/*
-			 *	Hack to keep track of ordinal number of the device that
-			 *	corresponds to a container. Needed to convert
-			 *	containers to /dev/sd device names
-			 */
-
-			if (scsicmd->request->rq_disk)
-				strlcpy(fsa_dev_ptr[cid].devname,
-				scsicmd->request->rq_disk->disk_name,
-				min(sizeof(fsa_dev_ptr[cid].devname),
-				sizeof(scsicmd->request->rq_disk->disk_name) + 1));
-
-			return aac_read(scsicmd);
-
-		case WRITE_6:
-		case WRITE_10:
-		case WRITE_12:
-		case WRITE_16:
-			if (dev->in_reset)
-				return -1;
-			return aac_write(scsicmd);
-
-		case SYNCHRONIZE_CACHE:
-			if (((aac_cache & 6) == 6) && dev->cache_protected) {
-				scsicmd->result = DID_OK << 16 |
-					COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
-				scsicmd->scsi_done(scsicmd);
-				return 0;
-			}
-			/* Issue FIB to tell Firmware to flush it's cache */
-			if ((aac_cache & 6) != 2)
-				return aac_synchronize(scsicmd);
-			/* FALLTHRU */
-		default:
-			/*
-			 *	Unhandled commands
-			 */
-			dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]));
-			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
-			set_sense(&dev->fsa_dev[cid].sense_data,
+	/* FALLTHRU */
+	default:
+	/*
+	 *	Unhandled commands
+	 */
+		dprintk((KERN_WARNING "Unhandled SCSI Command: 0x%x.\n",
+				scsicmd->cmnd[0]));
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+				SAM_STAT_CHECK_CONDITION;
+		set_sense(&dev->fsa_dev[cid].sense_data,
 			  ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND,
 			  ASENCODE_INVALID_COMMAND, 0, 0);
-			memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
 				min_t(size_t,
 				      sizeof(dev->fsa_dev[cid].sense_data),
 				      SCSI_SENSE_BUFFERSIZE));
-			scsicmd->scsi_done(scsicmd);
-			return 0;
 	}
+
+scsi_done_ret:
+
+	scsicmd->scsi_done(scsicmd);
+	return 0;
 }
 
 static int query_disk(struct aac_dev *dev, void __user *arg)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 07/24] aacraid: Process Error for response I/O
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (5 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Make sure that the driver processes error conditions even in the fast
response path for response from the adapter.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c | 289 ++++++++++++++++++++++--------------------
 1 file changed, 151 insertions(+), 138 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index e7456a0..d848335 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -3068,16 +3068,11 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
 		return;
 
 	BUG_ON(fibptr == NULL);
-	dev = fibptr->dev;
-
-	scsi_dma_unmap(scsicmd);
 
-	/* expose physical device if expose_physicald flag is on */
-	if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)
-	  && expose_physicals > 0)
-		aac_expose_phy_device(scsicmd);
+	dev = fibptr->dev;
 
 	srbreply = (struct aac_srb_reply *) fib_data(fibptr);
+
 	scsicmd->sense_buffer[0] = '\0';  /* Initialize sense valid flag to false */
 
 	if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
@@ -3090,158 +3085,176 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
 		 */
 		scsi_set_resid(scsicmd, scsi_bufflen(scsicmd)
 				   - le32_to_cpu(srbreply->data_xfer_length));
-		/*
-		 * First check the fib status
-		 */
+	}
 
-		if (le32_to_cpu(srbreply->status) != ST_OK) {
-			int len;
 
-			printk(KERN_WARNING "aac_srb_callback: srb failed, status = %d\n", le32_to_cpu(srbreply->status));
-			len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
-				    SCSI_SENSE_BUFFERSIZE);
-			scsicmd->result = DID_ERROR << 16
-						| COMMAND_COMPLETE << 8
-						| SAM_STAT_CHECK_CONDITION;
-			memcpy(scsicmd->sense_buffer,
-					srbreply->sense_data, len);
-		}
+	scsi_dma_unmap(scsicmd);
 
-		/*
-		 * Next check the srb status
-		 */
-		switch ((le32_to_cpu(srbreply->srb_status))&0x3f) {
-		case SRB_STATUS_ERROR_RECOVERY:
-		case SRB_STATUS_PENDING:
-		case SRB_STATUS_SUCCESS:
-			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-			break;
-		case SRB_STATUS_DATA_OVERRUN:
-			switch (scsicmd->cmnd[0]) {
-			case  READ_6:
-			case  WRITE_6:
-			case  READ_10:
-			case  WRITE_10:
-			case  READ_12:
-			case  WRITE_12:
-			case  READ_16:
-			case  WRITE_16:
-				if (le32_to_cpu(srbreply->data_xfer_length)
-							< scsicmd->underflow)
-					printk(KERN_WARNING"aacraid: SCSI CMD underflow\n");
-				else
-					printk(KERN_WARNING"aacraid: SCSI CMD Data Overrun\n");
-				scsicmd->result = DID_ERROR << 16
-							| COMMAND_COMPLETE << 8;
-				break;
-			case INQUIRY: {
-				scsicmd->result = DID_OK << 16
-							| COMMAND_COMPLETE << 8;
-				break;
-			}
-			default:
-				scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
-				break;
-			}
-			break;
-		case SRB_STATUS_ABORTED:
-			scsicmd->result = DID_ABORT << 16 | ABORT << 8;
-			break;
-		case SRB_STATUS_ABORT_FAILED:
-			/*
-			 * Not sure about this one - but assuming the
-			 * hba was trying to abort for some reason
-			 */
-			scsicmd->result = DID_ERROR << 16 | ABORT << 8;
-			break;
-		case SRB_STATUS_PARITY_ERROR:
-			scsicmd->result = DID_PARITY << 16
-						| MSG_PARITY_ERROR << 8;
-			break;
-		case SRB_STATUS_NO_DEVICE:
-		case SRB_STATUS_INVALID_PATH_ID:
-		case SRB_STATUS_INVALID_TARGET_ID:
-		case SRB_STATUS_INVALID_LUN:
-		case SRB_STATUS_SELECTION_TIMEOUT:
-			scsicmd->result = DID_NO_CONNECT << 16
-						| COMMAND_COMPLETE << 8;
-			break;
+	/* expose physical device if expose_physicald flag is on */
+	if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01)
+	  && expose_physicals > 0)
+		aac_expose_phy_device(scsicmd);
 
-		case SRB_STATUS_COMMAND_TIMEOUT:
-		case SRB_STATUS_TIMEOUT:
-			scsicmd->result = DID_TIME_OUT << 16
-						| COMMAND_COMPLETE << 8;
-			break;
+	/*
+	 * First check the fib status
+	 */
 
-		case SRB_STATUS_BUSY:
-			scsicmd->result = DID_BUS_BUSY << 16
-						| COMMAND_COMPLETE << 8;
-			break;
+	if (le32_to_cpu(srbreply->status) != ST_OK) {
+		int len;
 
-		case SRB_STATUS_BUS_RESET:
-			scsicmd->result = DID_RESET << 16
-						| COMMAND_COMPLETE << 8;
-			break;
+		pr_warn("aac_srb_callback: srb failed, status = %d\n",
+				le32_to_cpu(srbreply->status));
+		len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+			    SCSI_SENSE_BUFFERSIZE);
+		scsicmd->result = DID_ERROR << 16
+				| COMMAND_COMPLETE << 8
+				| SAM_STAT_CHECK_CONDITION;
+		memcpy(scsicmd->sense_buffer,
+				srbreply->sense_data, len);
+	}
 
-		case SRB_STATUS_MESSAGE_REJECTED:
+	/*
+	 * Next check the srb status
+	 */
+	switch ((le32_to_cpu(srbreply->srb_status))&0x3f) {
+	case SRB_STATUS_ERROR_RECOVERY:
+	case SRB_STATUS_PENDING:
+	case SRB_STATUS_SUCCESS:
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+		break;
+	case SRB_STATUS_DATA_OVERRUN:
+		switch (scsicmd->cmnd[0]) {
+		case  READ_6:
+		case  WRITE_6:
+		case  READ_10:
+		case  WRITE_10:
+		case  READ_12:
+		case  WRITE_12:
+		case  READ_16:
+		case  WRITE_16:
+			if (le32_to_cpu(srbreply->data_xfer_length)
+						< scsicmd->underflow)
+				pr_warn("aacraid: SCSI CMD underflow\n");
+			else
+				pr_warn("aacraid: SCSI CMD Data Overrun\n");
 			scsicmd->result = DID_ERROR << 16
-						| MESSAGE_REJECT << 8;
+					| COMMAND_COMPLETE << 8;
+			break;
+		case INQUIRY:
+			scsicmd->result = DID_OK << 16
+					| COMMAND_COMPLETE << 8;
 			break;
-		case SRB_STATUS_REQUEST_FLUSHED:
-		case SRB_STATUS_ERROR:
-		case SRB_STATUS_INVALID_REQUEST:
-		case SRB_STATUS_REQUEST_SENSE_FAILED:
-		case SRB_STATUS_NO_HBA:
-		case SRB_STATUS_UNEXPECTED_BUS_FREE:
-		case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
-		case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
-		case SRB_STATUS_DELAYED_RETRY:
-		case SRB_STATUS_BAD_FUNCTION:
-		case SRB_STATUS_NOT_STARTED:
-		case SRB_STATUS_NOT_IN_USE:
-		case SRB_STATUS_FORCE_ABORT:
-		case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
 		default:
+			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+			break;
+		}
+		break;
+	case SRB_STATUS_ABORTED:
+		scsicmd->result = DID_ABORT << 16 | ABORT << 8;
+		break;
+	case SRB_STATUS_ABORT_FAILED:
+		/*
+		 * Not sure about this one - but assuming the
+		 * hba was trying to abort for some reason
+		 */
+		scsicmd->result = DID_ERROR << 16 | ABORT << 8;
+		break;
+	case SRB_STATUS_PARITY_ERROR:
+		scsicmd->result = DID_PARITY << 16
+				| MSG_PARITY_ERROR << 8;
+		break;
+	case SRB_STATUS_NO_DEVICE:
+	case SRB_STATUS_INVALID_PATH_ID:
+	case SRB_STATUS_INVALID_TARGET_ID:
+	case SRB_STATUS_INVALID_LUN:
+	case SRB_STATUS_SELECTION_TIMEOUT:
+		scsicmd->result = DID_NO_CONNECT << 16
+				| COMMAND_COMPLETE << 8;
+		break;
+
+	case SRB_STATUS_COMMAND_TIMEOUT:
+	case SRB_STATUS_TIMEOUT:
+		scsicmd->result = DID_TIME_OUT << 16
+				| COMMAND_COMPLETE << 8;
+		break;
+
+	case SRB_STATUS_BUSY:
+		scsicmd->result = DID_BUS_BUSY << 16
+				| COMMAND_COMPLETE << 8;
+		break;
+
+	case SRB_STATUS_BUS_RESET:
+		scsicmd->result = DID_RESET << 16
+				| COMMAND_COMPLETE << 8;
+		break;
+
+	case SRB_STATUS_MESSAGE_REJECTED:
+		scsicmd->result = DID_ERROR << 16
+				| MESSAGE_REJECT << 8;
+		break;
+	case SRB_STATUS_REQUEST_FLUSHED:
+	case SRB_STATUS_ERROR:
+	case SRB_STATUS_INVALID_REQUEST:
+	case SRB_STATUS_REQUEST_SENSE_FAILED:
+	case SRB_STATUS_NO_HBA:
+	case SRB_STATUS_UNEXPECTED_BUS_FREE:
+	case SRB_STATUS_PHASE_SEQUENCE_FAILURE:
+	case SRB_STATUS_BAD_SRB_BLOCK_LENGTH:
+	case SRB_STATUS_DELAYED_RETRY:
+	case SRB_STATUS_BAD_FUNCTION:
+	case SRB_STATUS_NOT_STARTED:
+	case SRB_STATUS_NOT_IN_USE:
+	case SRB_STATUS_FORCE_ABORT:
+	case SRB_STATUS_DOMAIN_VALIDATION_FAIL:
+	default:
 #ifdef AAC_DETAILED_STATUS_INFO
-			printk(KERN_INFO "aacraid: SRB ERROR(%u) %s scsi cmd 0x%x - scsi status 0x%x\n",
-				le32_to_cpu(srbreply->srb_status) & 0x3F,
-				aac_get_status_string(
-					le32_to_cpu(srbreply->srb_status) & 0x3F),
-				scsicmd->cmnd[0],
-				le32_to_cpu(srbreply->scsi_status));
+		pr_info("aacraid: SRB ERROR(%u) %s scsi cmd 0x%x -scsi status 0x%x\n",
+			le32_to_cpu(srbreply->srb_status) & 0x3F,
+			aac_get_status_string(
+				le32_to_cpu(srbreply->srb_status) & 0x3F),
+			scsicmd->cmnd[0],
+			le32_to_cpu(srbreply->scsi_status));
 #endif
-			if ((scsicmd->cmnd[0] == ATA_12)
-				|| (scsicmd->cmnd[0] == ATA_16)) {
-					if (scsicmd->cmnd[2] & (0x01 << 5)) {
-						scsicmd->result = DID_OK << 16
-							| COMMAND_COMPLETE << 8;
-				break;
-				} else {
-					scsicmd->result = DID_ERROR << 16
-						| COMMAND_COMPLETE << 8;
-					break;
-				}
+		/*
+		 * When the CC bit is SET by the host in ATA pass thru CDB,
+		 *  driver is supposed to return DID_OK
+		 *
+		 * When the CC bit is RESET by the host, driver should
+		 *  return DID_ERROR
+		 */
+		if ((scsicmd->cmnd[0] == ATA_12)
+			|| (scsicmd->cmnd[0] == ATA_16)) {
+
+			if (scsicmd->cmnd[2] & (0x01 << 5)) {
+				scsicmd->result = DID_OK << 16
+					| COMMAND_COMPLETE << 8;
+			break;
 			} else {
 				scsicmd->result = DID_ERROR << 16
 					| COMMAND_COMPLETE << 8;
-				break;
+			break;
 			}
+		} else {
+			scsicmd->result = DID_ERROR << 16
+				| COMMAND_COMPLETE << 8;
+			break;
 		}
-		if (le32_to_cpu(srbreply->scsi_status)
-				== SAM_STAT_CHECK_CONDITION) {
-			int len;
+	}
+	if (le32_to_cpu(srbreply->scsi_status)
+			== SAM_STAT_CHECK_CONDITION) {
+		int len;
 
-			scsicmd->result |= SAM_STAT_CHECK_CONDITION;
-			len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
-				    SCSI_SENSE_BUFFERSIZE);
+		scsicmd->result |= SAM_STAT_CHECK_CONDITION;
+		len = min_t(u32, le32_to_cpu(srbreply->sense_data_size),
+			    SCSI_SENSE_BUFFERSIZE);
 #ifdef AAC_DETAILED_STATUS_INFO
-			printk(KERN_WARNING "aac_srb_callback: check condition, status = %d len=%d\n",
-						le32_to_cpu(srbreply->status), len);
+		pr_warn("aac_srb_callback: check condition, status = %d len=%d\n",
+					le32_to_cpu(srbreply->status), len);
 #endif
-			memcpy(scsicmd->sense_buffer,
-					srbreply->sense_data, len);
-		}
+		memcpy(scsicmd->sense_buffer,
+				srbreply->sense_data, len);
 	}
+
 	/*
 	 * OR in the scsi status (already shifted up a bit)
 	 */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 08/24] aacraid: Added support for response path
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (6 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 07/24] aacraid: Process Error for response I/O Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:50   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 09/24] aacraid: Added support for read medium error Raghava Aditya Renukunta
                   ` (15 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patch enables the driver to actually process the I/O, or srb replies
from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events.

Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c  | 34 +++++++++++++++------------
 drivers/scsi/aacraid/aacraid.h | 52 +++++++++++++++++++++++-------------------
 drivers/scsi/aacraid/commsup.c | 17 +++++++++-----
 drivers/scsi/aacraid/dpcsup.c  | 20 ++++++++--------
 drivers/scsi/aacraid/src.c     | 38 ++++++++++++++++++++++--------
 5 files changed, 99 insertions(+), 62 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index d848335..4bb94a2 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -329,7 +329,7 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
 	}
 	scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
 	device = scsicmd->device;
-	if (unlikely(!device || !scsi_device_online(device))) {
+	if (unlikely(!device)) {
 		dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
 		aac_fib_complete(fibptr);
 		return 0;
@@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev)
 
 	if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
 		maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
-	fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers,
-			GFP_KERNEL);
-	if (!fsa_dev_ptr)
-		return -ENOMEM;
+	if ((dev->fsa_dev == NULL) ||
+		(dev->maximum_num_containers != maximum_num_containers)) {
+
+		fsa_dev_ptr = dev->fsa_dev;
 
-	dev->fsa_dev = fsa_dev_ptr;
-	dev->maximum_num_containers = maximum_num_containers;
+		dev->fsa_dev = kzalloc(sizeof(*fsa_dev_ptr) *
+				maximum_num_containers,	GFP_KERNEL);
 
-	for (index = 0; index < dev->maximum_num_containers; ) {
-		fsa_dev_ptr[index].devname[0] = '\0';
+		kfree(fsa_dev_ptr);
+		fsa_dev_ptr = NULL;
+
+
+		if (!dev->fsa_dev)
+			return -ENOMEM;
+
+		dev->maximum_num_containers = maximum_num_containers;
+	}
+	for (index = 0; index < dev->maximum_num_containers; index++) {
+		dev->fsa_dev[index].devname[0] = '\0';
+		dev->fsa_dev[index].valid = 0;
 
 		status = aac_probe_container(dev, index);
 
@@ -492,12 +502,6 @@ int aac_get_containers(struct aac_dev *dev)
 			printk(KERN_WARNING "aac_get_containers: SendFIB failed.\n");
 			break;
 		}
-
-		/*
-		 *	If there are no more containers, then stop asking.
-		 */
-		if (++index >= status)
-			break;
 	}
 	return status;
 }
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 00df610..d1f5a66 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -407,7 +407,7 @@ struct aac_fibhdr {
 		__le32 SenderFibAddressHigh;/* upper 32bit of phys. FIB address */
 		__le32 TimeStamp;	/* otherwise timestamp for FW internal use */
 	} u;
-	u32 Handle;		/* FIB handle used for MSGU commnunication */
+	__le32 Handle;		/* FIB handle used for MSGU commnunication */
 	u32 Previous;		/* FW internal use */
 	u32 Next;		/* FW internal use */
 };
@@ -872,18 +872,20 @@ struct rkt_registers {
 #define src_inbound rx_inbound
 
 struct src_mu_registers {
-				/*	PCI*| Name */
-	__le32	reserved0[6];	/*	00h | Reserved */
-	__le32	IOAR[2];	/*	18h | IOA->host interrupt register */
-	__le32	IDR;		/*	20h | Inbound Doorbell Register */
-	__le32	IISR;		/*	24h | Inbound Int. Status Register */
-	__le32	reserved1[3];	/*	28h | Reserved */
-	__le32	OIMR;		/*	34h | Outbound Int. Mask Register */
-	__le32	reserved2[25];	/*	38h | Reserved */
-	__le32	ODR_R;		/*	9ch | Outbound Doorbell Read */
-	__le32	ODR_C;		/*	a0h | Outbound Doorbell Clear */
-	__le32	reserved3[6];	/*	a4h | Reserved */
-	__le32	OMR;		/*	bch | Outbound Message Register */
+				/*  PCI*| Name */
+	__le32	reserved0[6];	/*  00h | Reserved */
+	__le32	IOAR[2];	/*  18h | IOA->host interrupt register */
+	__le32	IDR;		/*  20h | Inbound Doorbell Register */
+	__le32	IISR;		/*  24h | Inbound Int. Status Register */
+	__le32	reserved1[3];	/*  28h | Reserved */
+	__le32	OIMR;		/*  34h | Outbound Int. Mask Register */
+	__le32	reserved2[25];  /*  38h | Reserved */
+	__le32	ODR_R;		/*  9ch | Outbound Doorbell Read */
+	__le32	ODR_C;		/*  a0h | Outbound Doorbell Clear */
+	__le32	reserved3[3];	/*  a4h | Reserved */
+	__le32	SCR0;		/*  b0h | Scratchpad 0 */
+	__le32	reserved4[2];	/*  b4h | Reserved */
+	__le32	OMR;		/*  bch | Outbound Message Register */
 	__le32	IQ_L;		/*  c0h | Inbound Queue (Low address) */
 	__le32	IQ_H;		/*  c4h | Inbound Queue (High address) */
 	__le32	ODR_MSI;	/*  c8h | MSI register for sync./AIF */
@@ -982,6 +984,7 @@ struct fsa_dev_info {
 	char		devname[8];
 	struct sense_data sense_data;
 	u32		block_size;
+	u8		identifier[16];
 };
 
 struct fib {
@@ -1012,6 +1015,7 @@ struct fib {
 	u32			vector_no;
 	struct hw_fib		*hw_fib_va;		/* Actual shared object */
 	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
+	u32			hbacmd_size;	/* cmd size for native */
 };
 
 #define AAC_DEVTYPE_RAID_MEMBER	1
@@ -1215,9 +1219,11 @@ struct aac_dev
 	/*
 	 *	negotiated FIB settings
 	 */
-	unsigned		max_fib_size;
-	unsigned		sg_tablesize;
-	unsigned		max_num_aif;
+	unsigned int		max_fib_size;
+	unsigned int		sg_tablesize;
+	unsigned int		max_num_aif;
+
+	unsigned int		max_cmd_size;	/* max_fib_size or MAX_NATIVE */
 
 	/*
 	 *	Map for 128 fib objects (64k)
@@ -1259,18 +1265,17 @@ struct aac_dev
 	 */
 	union aac_init		*init;
 	dma_addr_t		init_pa;	/* Holds physical address of the init struct */
-
-	u32			*host_rrq;	/* response queue
-						 * if AAC_COMM_MESSAGE_TYPE1 */
-
+	/* response queue (if AAC_COMM_MESSAGE_TYPE1) */
+	__le32			*host_rrq;
 	dma_addr_t		host_rrq_pa;	/* phys. address */
 	/* index into rrq buffer */
 	u32			host_rrq_idx[AAC_MAX_MSIX];
 	atomic_t		rrq_outstanding[AAC_MAX_MSIX];
 	u32			fibs_pushed_no;
 	struct pci_dev		*pdev;		/* Our PCI interface */
-	void *			printfbuf;	/* pointer to buffer used for printf's from the adapter */
-	void *			comm_addr;	/* Base address of Comm area */
+	/* pointer to buffer used for printf's from the adapter */
+	void			*printfbuf;
+	void			*comm_addr;	/* Base address of Comm area */
 	dma_addr_t		comm_phys;	/* Physical Address of Comm area */
 	size_t			comm_size;
 
@@ -1342,6 +1347,8 @@ struct aac_dev
 	u32			max_msix;	/* max. MSI-X vectors */
 	u32			vector_cap;	/* MSI-X vector capab.*/
 	int			msi_enabled;	/* MSI/MSI-X enabled */
+	atomic_t		msix_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];
 	u8			adapter_shutdown;
@@ -2281,7 +2288,6 @@ int aac_rx_select_comm(struct aac_dev *dev, int comm);
 int aac_rx_deliver_producer(struct fib * fib);
 char * get_container_type(unsigned type);
 extern int numacb;
-extern int acbsize;
 extern char aac_driver_version[];
 extern int startup_timeout;
 extern int aif_timeout;
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index d18ed9a..4b1177a 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -60,12 +60,17 @@
 
 static int fib_map_alloc(struct aac_dev *dev)
 {
+	if (dev->max_fib_size > AAC_MAX_NATIVE_SIZE)
+		dev->max_cmd_size = AAC_MAX_NATIVE_SIZE;
+	else
+		dev->max_cmd_size = dev->max_fib_size;
+
 	dprintk((KERN_INFO
 	  "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
-	  dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue,
+	  dev->pdev, dev->max_cmd_size, dev->scsi_host_ptr->can_queue,
 	  AAC_NUM_MGT_FIB, &dev->hw_fib_pa));
 	dev->hw_fib_va = pci_alloc_consistent(dev->pdev,
-		(dev->max_fib_size + sizeof(struct aac_fib_xporthdr))
+		(dev->max_cmd_size + sizeof(struct aac_fib_xporthdr))
 		* (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) + (ALIGN32 - 1),
 		&dev->hw_fib_pa);
 	if (dev->hw_fib_va == NULL)
@@ -83,9 +88,9 @@ static int fib_map_alloc(struct aac_dev *dev)
 
 void aac_fib_map_free(struct aac_dev *dev)
 {
-	if (dev->hw_fib_va && dev->max_fib_size) {
+	if (dev->hw_fib_va && dev->max_cmd_size) {
 		pci_free_consistent(dev->pdev,
-		(dev->max_fib_size *
+		(dev->max_cmd_size *
 		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)),
 		dev->hw_fib_va, dev->hw_fib_pa);
 	}
@@ -176,9 +181,9 @@ int aac_fib_setup(struct aac_dev * dev)
 		hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size);
 		fibptr->hw_fib_pa = hw_fib_pa;
 		hw_fib = (struct hw_fib *)((unsigned char *)hw_fib +
-			dev->max_fib_size + sizeof(struct aac_fib_xporthdr));
+			dev->max_cmd_size + sizeof(struct aac_fib_xporthdr));
 		hw_fib_pa = hw_fib_pa +
-			dev->max_fib_size + sizeof(struct aac_fib_xporthdr);
+			dev->max_cmd_size + sizeof(struct aac_fib_xporthdr);
 	}
 
 	/*
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 7e83620..8077dba 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -122,7 +122,6 @@ unsigned int aac_response_normal(struct aac_queue * q)
 			 *	NOTE:  we cannot touch the fib after this
 			 *	    call, because it may have been deallocated.
 			 */
-			fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
 			fib->callback(fib->callback_data, fib);
 		} else {
 			unsigned long flagv;
@@ -251,8 +250,9 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
 	BUG_ON(fibptr == NULL);
 	dev = fibptr->dev;
 
-	if (fibptr->hw_fib_va->header.XferState &
-	    cpu_to_le32(NoMoreAifDataAvailable)) {
+	if ((fibptr->hw_fib_va->header.XferState &
+	    cpu_to_le32(NoMoreAifDataAvailable)) ||
+		dev->sa_firmware) {
 		aac_fib_complete(fibptr);
 		aac_fib_free(fibptr);
 		return;
@@ -282,8 +282,8 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
  *	know there is a response on our normal priority queue. We will pull off
  *	all QE there are and wake up all the waiters before exiting.
  */
-unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
-			int isAif, int isFastResponse, struct hw_fib *aif_fib)
+unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
+	int isFastResponse, struct hw_fib *aif_fib)
 {
 	unsigned long mflags;
 	dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
@@ -305,12 +305,14 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
 			kfree (fib);
 			return 1;
 		}
-		if (aif_fib != NULL) {
+		if (dev->sa_firmware) {
+			fib->hbacmd_size = index;	/* store event type */
+		} else if (aif_fib != NULL) {
 			memcpy(hw_fib, aif_fib, sizeof(struct hw_fib));
 		} else {
-			memcpy(hw_fib,
-				(struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
-				index), sizeof(struct hw_fib));
+			memcpy(hw_fib, (struct hw_fib *)
+				(((uintptr_t)(dev->regs.sa)) + index),
+				sizeof(struct hw_fib));
 		}
 		INIT_LIST_HEAD(&fib->fiblink);
 		fib->type = FSAFS_NTC_FIB_CONTEXT;
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index a5f7a6f..5508893 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -135,8 +135,16 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
 
 	if (mode & AAC_INT_MODE_AIF) {
 		/* handle AIF */
-		if (dev->aif_thread && dev->fsa_dev)
-			aac_intr_normal(dev, 0, 2, 0, NULL);
+		if (dev->sa_firmware) {
+			u32 events = src_readl(dev, MUnit.SCR0);
+
+			aac_intr_normal(dev, events, 1, 0, NULL);
+			writel(events, &dev->IndexRegs->Mailbox[0]);
+			src_writel(dev, MUnit.IDR, 1 << 23);
+		} else {
+			if (dev->aif_thread && dev->fsa_dev)
+				aac_intr_normal(dev, 0, 2, 0, NULL);
+		}
 		if (dev->msi_enabled)
 			aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
 		mode = 0;
@@ -148,17 +156,19 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
 		for (;;) {
 			isFastResponse = 0;
 			/* remove toggle bit (31) */
-			handle = (dev->host_rrq[index] & 0x7fffffff);
-			/* check fast response bit (30) */
+			handle = le32_to_cpu((dev->host_rrq[index])
+				& 0x7fffffff);
+			/* check fast response bits (30, 1) */
 			if (handle & 0x40000000)
 				isFastResponse = 1;
 			handle &= 0x0000ffff;
 			if (handle == 0)
 				break;
+			handle >>= 2;
 			if (dev->msi_enabled && dev->max_msix > 1)
 				atomic_dec(&dev->rrq_outstanding[vector_no]);
+			aac_intr_normal(dev, handle, 0, isFastResponse, NULL);
 			dev->host_rrq[index++] = 0;
-			aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL);
 			if (index == (vector_no + 1) * dev->vector_cap)
 				index = vector_no * dev->vector_cap;
 			dev->host_rrq_idx[vector_no] = index;
@@ -392,6 +402,7 @@ static void aac_src_start_adapter(struct aac_dev *dev)
 		dev->host_rrq_idx[i] = i * dev->vector_cap;
 		atomic_set(&dev->rrq_outstanding[i], 0);
 	}
+	atomic_set(&dev->msix_counter, 0);
 	dev->fibs_pushed_no = 0;
 
 	init = dev->init;
@@ -565,9 +576,18 @@ static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
 		dev->base = dev->regs.src.bar0 = NULL;
 		return 0;
 	}
+
+	dev->regs.src.bar1 =
+	ioremap(pci_resource_start(dev->pdev, 2), AAC_MIN_SRCV_BAR1_SIZE);
+	dev->base = NULL;
+	if (dev->regs.src.bar1 == NULL)
+		return -1;
 	dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size);
-	if (dev->base == NULL)
+	if (dev->base == NULL) {
+		iounmap(dev->regs.src.bar1);
+		dev->regs.src.bar1 = NULL;
 		return -1;
+	}
 	dev->IndexRegs = &((struct src_registers __iomem *)
 		dev->base)->u.denali.IndexRegs;
 	return 0;
@@ -918,9 +938,9 @@ int aac_srcv_init(struct aac_dev *dev)
 	if (aac_acquire_irq(dev))
 		goto error_iounmap;
 
-	dev->dbg_base = dev->base_start;
-	dev->dbg_base_mapped = dev->base;
-	dev->dbg_size = dev->base_size;
+	dev->dbg_base = pci_resource_start(dev->pdev, 2);
+	dev->dbg_base_mapped = dev->regs.src.bar1;
+	dev->dbg_size = AAC_MIN_SRCV_BAR1_SIZE;
 	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
 
 	aac_adapter_enable_int(dev);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 09/24] aacraid: Added support for read medium error
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (7 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30  9:55   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 10/24] aacraid: Reworked aac_command_thread Raghava Aditya Renukunta
                   ` (14 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patch processes Raw IO read medium errors.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c  | 10 ++++++++++
 drivers/scsi/aacraid/aacraid.h |  1 +
 2 files changed, 11 insertions(+)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 4bb94a2..e441a54 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -62,6 +62,7 @@
 #define SENCODE_END_OF_DATA			0x00
 #define SENCODE_BECOMING_READY			0x04
 #define SENCODE_INIT_CMD_REQUIRED		0x04
+#define SENCODE_UNRECOVERED_READ_ERROR		0x11
 #define SENCODE_PARAM_LIST_LENGTH_ERROR		0x1A
 #define SENCODE_INVALID_COMMAND			0x20
 #define SENCODE_LBA_OUT_OF_RANGE		0x21
@@ -1997,6 +1998,15 @@ static void io_callback(void *context, struct fib * fibptr)
 		       min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
 			     SCSI_SENSE_BUFFERSIZE));
 		break;
+	case ST_MEDERR:
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 |
+			SAM_STAT_CHECK_CONDITION;
+		set_sense(&dev->fsa_dev[cid].sense_data, MEDIUM_ERROR,
+		  SENCODE_UNRECOVERED_READ_ERROR, ASENCODE_NO_SENSE, 0, 0);
+		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+		       min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data),
+			     SCSI_SENSE_BUFFERSIZE));
+		break;
 	default:
 #ifdef AAC_DETAILED_STATUS_INFO
 		printk(KERN_WARNING "io_callback: io failed, status = %d\n",
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d1f5a66..b54c1bf 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1462,6 +1462,7 @@ struct aac_dev
 #define		ST_IO		5
 #define		ST_NXIO		6
 #define		ST_E2BIG	7
+#define		ST_MEDERR	8
 #define		ST_ACCES	13
 #define		ST_EXIST	17
 #define		ST_XDEV		18
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 10/24] aacraid: Reworked aac_command_thread
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (8 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 09/24] aacraid: Added support for read medium error Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 10:11   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 11/24] aacraid: Added support for periodic wellness sync Raghava Aditya Renukunta
                   ` (13 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Reworked aac_command_thread into aac_process_events

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/commsup.c | 411 ++++++++++++++++++++++-------------------
 1 file changed, 217 insertions(+), 194 deletions(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 4b1177a..346c1c0 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1729,6 +1729,222 @@ int aac_check_health(struct aac_dev * aac)
 	return BlinkLED;
 }
 
+static void aac_process_events(struct aac_dev *dev)
+{
+	struct hw_fib *hw_fib, *hw_newfib;
+	struct fib *fib, *newfib;
+	struct aac_fib_context *fibctx;
+	unsigned long flags;
+	spinlock_t *t_lock;
+
+	spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
+	while (!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
+		struct list_head *entry;
+		struct aac_aifcmd *aifcmd;
+		u32 time_now, time_last;
+		unsigned long flagv;
+		unsigned int  num;
+		struct hw_fib **hw_fib_pool, **hw_fib_p;
+		struct fib **fib_pool, **fib_p;
+
+		set_current_state(TASK_RUNNING);
+
+		entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
+		list_del(entry);
+
+
+		t_lock = dev->queues->queue[HostNormCmdQueue].lock;
+		spin_unlock_irqrestore(t_lock, flags);
+
+		fib = list_entry(entry, struct fib, fiblink);
+		hw_fib = fib->hw_fib_va;
+		/*
+		 *	We will process the FIB here or pass it to a
+		 *	worker thread that is TBD. We Really can't
+		 *	do anything at this point since we don't have
+		 *	anything defined for this thread to do.
+		 */
+		memset(fib, 0, sizeof(struct fib));
+		fib->type = FSAFS_NTC_FIB_CONTEXT;
+		fib->size = sizeof(struct fib);
+		fib->hw_fib_va = hw_fib;
+		fib->data = hw_fib->data;
+		fib->dev = dev;
+		/*
+		 *	We only handle AifRequest fibs from the adapter.
+		 */
+
+		aifcmd = (struct aac_aifcmd *) hw_fib->data;
+		if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
+			/* Handle Driver Notify Events */
+			aac_handle_aif(dev, fib);
+			*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
+			aac_fib_adapter_complete(fib, (u16)sizeof(u32));
+			continue;
+		}
+		/*
+		 * The u32 here is important and intended. We are using
+		 * 32bit wrapping time to fit the adapter field
+		 */
+
+
+		/* Sniff events */
+		if ((aifcmd->command ==	cpu_to_le32(AifCmdEventNotify)) ||
+				(aifcmd->command ==
+				cpu_to_le32(AifCmdJobProgress))) {
+			aac_handle_aif(dev, fib);
+		}
+
+		time_now = jiffies/HZ;
+
+		/*
+		 * Warning: no sleep allowed while
+		 * holding spinlock. We take the estimate
+		 * and pre-allocate a set of fibs outside the
+		 * lock.
+		 */
+		num = le32_to_cpu(dev->init->r7.adapter_fibs_size)
+				/ sizeof(struct hw_fib); /* some extra */
+		spin_lock_irqsave(&dev->fib_lock, flagv);
+		entry = dev->fib_list.next;
+		while (entry != &dev->fib_list) {
+			entry = entry->next;
+			++num;
+		}
+		spin_unlock_irqrestore(&dev->fib_lock, flagv);
+		hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *),
+						GFP_KERNEL);
+		fib_pool = kmalloc_array(num, sizeof(struct fib *),
+						GFP_KERNEL);
+		if (num	&& fib_pool && hw_fib_pool) {
+			hw_fib_p = hw_fib_pool;
+			fib_p = fib_pool;
+			while (hw_fib_p < &hw_fib_pool[num]) {
+				*(hw_fib_p) = kmalloc(sizeof(struct hw_fib),
+						GFP_KERNEL);
+				if (!(*(hw_fib_p++))) {
+					--hw_fib_p;
+					break;
+				}
+				*(fib_p) = kmalloc(sizeof(struct fib),
+						GFP_KERNEL);
+				if (!(*(fib_p++))) {
+					kfree(*(--hw_fib_p));
+					break;
+				}
+			}
+			num = hw_fib_p - hw_fib_pool;
+			if (!num) {
+				kfree(fib_pool);
+				fib_pool = NULL;
+				kfree(hw_fib_pool);
+				hw_fib_pool = NULL;
+				continue;
+			}
+		} else {
+			kfree(hw_fib_pool);
+			hw_fib_pool = NULL;
+			kfree(fib_pool);
+			fib_pool = NULL;
+		}
+		spin_lock_irqsave(&dev->fib_lock, flagv);
+		entry = dev->fib_list.next;
+		/*
+		 * For each Context that is on the
+		 * fibctxList, make a copy of the
+		 * fib, and then set the event to wake up the
+		 * thread that is waiting for it.
+		 */
+		hw_fib_p = hw_fib_pool;
+		fib_p = fib_pool;
+		while (entry != &dev->fib_list) {
+			/*
+			 * Extract the fibctx
+			 */
+			fibctx = list_entry(entry, struct aac_fib_context,
+					next);
+			/*
+			 * Check if the queue is getting
+			 * backlogged
+			 */
+			if (fibctx->count > 20) {
+				/*
+				 * It's *not* jiffies folks,
+				 * but jiffies / HZ so do not
+				 * panic ...
+				 */
+				time_last = fibctx->jiffies;
+				/*
+				 * Has it been > 2 minutes
+				 * since the last read off
+				 * the queue?
+				 */
+				if ((time_now - time_last) > aif_timeout) {
+					entry = entry->next;
+					aac_close_fib_context(dev, fibctx);
+					continue;
+				}
+			}
+			/*
+			 * Warning: no sleep allowed while
+			 * holding spinlock
+			 */
+			if (hw_fib_p < &hw_fib_pool[num]) {
+				hw_newfib = *hw_fib_p;
+				*(hw_fib_p++) = NULL;
+				newfib = *fib_p;
+				*(fib_p++) = NULL;
+				/*
+				 * Make the copy of the FIB
+				 */
+				memcpy(hw_newfib, hw_fib,
+					sizeof(struct hw_fib));
+				memcpy(newfib, fib, sizeof(struct fib));
+				newfib->hw_fib_va = hw_newfib;
+				/*
+				 * Put the FIB onto the
+				 * fibctx's fibs
+				 */
+				list_add_tail(&newfib->fiblink,
+					&fibctx->fib_list);
+				fibctx->count++;
+				/*
+				 * Set the event to wake up the
+				 * thread that is waiting.
+				 */
+				up(&fibctx->wait_sem);
+			} else {
+				pr_warn("aifd: didn't allocate NewFib.\n");
+			}
+			entry = entry->next;
+		}
+		/*
+		 *	Set the status of this FIB
+		 */
+		*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
+		aac_fib_adapter_complete(fib, sizeof(u32));
+		spin_unlock_irqrestore(&dev->fib_lock, flagv);
+		/* Free up the remaining resources */
+		hw_fib_p = hw_fib_pool;
+		fib_p = fib_pool;
+		while (hw_fib_p < &hw_fib_pool[num]) {
+			kfree(*hw_fib_p);
+			kfree(*fib_p);
+			++fib_p;
+			++hw_fib_p;
+		}
+		kfree(hw_fib_pool);
+		kfree(fib_pool);
+		kfree(fib);
+		spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock,
+				flags);
+	}
+	/*
+	 *	There are no more AIF's
+	 */
+	spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock,
+			flags);
+}
 
 /**
  *	aac_command_thread	-	command processing thread
@@ -1743,10 +1959,6 @@ int aac_check_health(struct aac_dev * aac)
 int aac_command_thread(void *data)
 {
 	struct aac_dev *dev = data;
-	struct hw_fib *hw_fib, *hw_newfib;
-	struct fib *fib, *newfib;
-	struct aac_fib_context *fibctx;
-	unsigned long flags;
 	DECLARE_WAITQUEUE(wait, current);
 	unsigned long next_jiffies = jiffies + HZ;
 	unsigned long next_check_jiffies = next_jiffies;
@@ -1766,197 +1978,8 @@ int aac_command_thread(void *data)
 	set_current_state(TASK_INTERRUPTIBLE);
 	dprintk ((KERN_INFO "aac_command_thread start\n"));
 	while (1) {
-		spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
-		while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
-			struct list_head *entry;
-			struct aac_aifcmd * aifcmd;
 
-			set_current_state(TASK_RUNNING);
-
-			entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
-			list_del(entry);
-
-			spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
-			fib = list_entry(entry, struct fib, fiblink);
-			/*
-			 *	We will process the FIB here or pass it to a
-			 *	worker thread that is TBD. We Really can't
-			 *	do anything at this point since we don't have
-			 *	anything defined for this thread to do.
-			 */
-			hw_fib = fib->hw_fib_va;
-			memset(fib, 0, sizeof(struct fib));
-			fib->type = FSAFS_NTC_FIB_CONTEXT;
-			fib->size = sizeof(struct fib);
-			fib->hw_fib_va = hw_fib;
-			fib->data = hw_fib->data;
-			fib->dev = dev;
-			/*
-			 *	We only handle AifRequest fibs from the adapter.
-			 */
-			aifcmd = (struct aac_aifcmd *) hw_fib->data;
-			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
-				/* Handle Driver Notify Events */
-				aac_handle_aif(dev, fib);
-				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-				aac_fib_adapter_complete(fib, (u16)sizeof(u32));
-			} else {
-				/* The u32 here is important and intended. We are using
-				   32bit wrapping time to fit the adapter field */
-
-				u32 time_now, time_last;
-				unsigned long flagv;
-				unsigned num;
-				struct hw_fib ** hw_fib_pool, ** hw_fib_p;
-				struct fib ** fib_pool, ** fib_p;
-
-				/* Sniff events */
-				if ((aifcmd->command ==
-				     cpu_to_le32(AifCmdEventNotify)) ||
-				    (aifcmd->command ==
-				     cpu_to_le32(AifCmdJobProgress))) {
-					aac_handle_aif(dev, fib);
-				}
-
-				time_now = jiffies/HZ;
-
-				/*
-				 * Warning: no sleep allowed while
-				 * holding spinlock. We take the estimate
-				 * and pre-allocate a set of fibs outside the
-				 * lock.
-				 */
-				num = le32_to_cpu(dev->init->
-							r7.adapter_fibs_size)
-				    / sizeof(struct hw_fib); /* some extra */
-				spin_lock_irqsave(&dev->fib_lock, flagv);
-				entry = dev->fib_list.next;
-				while (entry != &dev->fib_list) {
-					entry = entry->next;
-					++num;
-				}
-				spin_unlock_irqrestore(&dev->fib_lock, flagv);
-				hw_fib_pool = NULL;
-				fib_pool = NULL;
-				if (num
-				 && ((hw_fib_pool = kmalloc(sizeof(struct hw_fib *) * num, GFP_KERNEL)))
-				 && ((fib_pool = kmalloc(sizeof(struct fib *) * num, GFP_KERNEL)))) {
-					hw_fib_p = hw_fib_pool;
-					fib_p = fib_pool;
-					while (hw_fib_p < &hw_fib_pool[num]) {
-						if (!(*(hw_fib_p++) = kmalloc(sizeof(struct hw_fib), GFP_KERNEL))) {
-							--hw_fib_p;
-							break;
-						}
-						if (!(*(fib_p++) = kmalloc(sizeof(struct fib), GFP_KERNEL))) {
-							kfree(*(--hw_fib_p));
-							break;
-						}
-					}
-					if ((num = hw_fib_p - hw_fib_pool) == 0) {
-						kfree(fib_pool);
-						fib_pool = NULL;
-						kfree(hw_fib_pool);
-						hw_fib_pool = NULL;
-					}
-				} else {
-					kfree(hw_fib_pool);
-					hw_fib_pool = NULL;
-				}
-				spin_lock_irqsave(&dev->fib_lock, flagv);
-				entry = dev->fib_list.next;
-				/*
-				 * For each Context that is on the
-				 * fibctxList, make a copy of the
-				 * fib, and then set the event to wake up the
-				 * thread that is waiting for it.
-				 */
-				hw_fib_p = hw_fib_pool;
-				fib_p = fib_pool;
-				while (entry != &dev->fib_list) {
-					/*
-					 * Extract the fibctx
-					 */
-					fibctx = list_entry(entry, struct aac_fib_context, next);
-					/*
-					 * Check if the queue is getting
-					 * backlogged
-					 */
-					if (fibctx->count > 20)
-					{
-						/*
-						 * It's *not* jiffies folks,
-						 * but jiffies / HZ so do not
-						 * panic ...
-						 */
-						time_last = fibctx->jiffies;
-						/*
-						 * Has it been > 2 minutes
-						 * since the last read off
-						 * the queue?
-						 */
-						if ((time_now - time_last) > aif_timeout) {
-							entry = entry->next;
-							aac_close_fib_context(dev, fibctx);
-							continue;
-						}
-					}
-					/*
-					 * Warning: no sleep allowed while
-					 * holding spinlock
-					 */
-					if (hw_fib_p < &hw_fib_pool[num]) {
-						hw_newfib = *hw_fib_p;
-						*(hw_fib_p++) = NULL;
-						newfib = *fib_p;
-						*(fib_p++) = NULL;
-						/*
-						 * Make the copy of the FIB
-						 */
-						memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib));
-						memcpy(newfib, fib, sizeof(struct fib));
-						newfib->hw_fib_va = hw_newfib;
-						/*
-						 * Put the FIB onto the
-						 * fibctx's fibs
-						 */
-						list_add_tail(&newfib->fiblink, &fibctx->fib_list);
-						fibctx->count++;
-						/*
-						 * Set the event to wake up the
-						 * thread that is waiting.
-						 */
-						up(&fibctx->wait_sem);
-					} else {
-						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
-					}
-					entry = entry->next;
-				}
-				/*
-				 *	Set the status of this FIB
-				 */
-				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-				aac_fib_adapter_complete(fib, sizeof(u32));
-				spin_unlock_irqrestore(&dev->fib_lock, flagv);
-				/* Free up the remaining resources */
-				hw_fib_p = hw_fib_pool;
-				fib_p = fib_pool;
-				while (hw_fib_p < &hw_fib_pool[num]) {
-					kfree(*hw_fib_p);
-					kfree(*fib_p);
-					++fib_p;
-					++hw_fib_p;
-				}
-				kfree(hw_fib_pool);
-				kfree(fib_pool);
-			}
-			kfree(fib);
-			spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
-		}
-		/*
-		 *	There are no more AIF's
-		 */
-		spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
+		aac_process_events(dev);
 
 		/*
 		 *	Background activity
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 11/24] aacraid: Added support for periodic wellness sync
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (9 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 10/24] aacraid: Reworked aac_command_thread Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 10:27   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW Raghava Aditya Renukunta
                   ` (12 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patch adds a new functions that periodically sync the time of host
to the adapter. In addition also informs the adapter that the driver is
alive and kicking. Only applicable to the HBA1000 and SMARTIOC2000.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h |   3 +
 drivers/scsi/aacraid/commsup.c | 176 +++++++++++++++++++++++++++++++++--------
 2 files changed, 148 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index b54c1bf..05884e6 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -88,6 +88,9 @@ enum {
 #define AAC_MAX_NATIVE_SIZE		2048
 
 #define CISS_REPORT_PHYSICAL_LUNS	0xc3
+#define WRITE_HOST_WELLNESS		0xa5
+#define BMIC_IN			0x26
+#define BMIC_OUT			0x27
 
 struct aac_ciss_phys_luns_resp {
 	u8	list_length[4];		/* LUN list length (N-7, big endian) */
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 346c1c0..0c009f1 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -43,6 +43,7 @@
 #include <linux/kthread.h>
 #include <linux/interrupt.h>
 #include <linux/semaphore.h>
+#include <linux/bcd.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
@@ -1946,6 +1947,143 @@ static void aac_process_events(struct aac_dev *dev)
 			flags);
 }
 
+static int aac_send_wellness_command(struct aac_dev *dev, char *wellness_str,
+							u32 datasize)
+{
+	struct aac_srb *srbcmd;
+	struct sgmap64 *sg64;
+	dma_addr_t addr;
+	char *dma_buf;
+	struct fib *fibptr;
+	int ret = -ENOMEM;
+
+	fibptr = aac_fib_alloc(dev);
+	if (fibptr) {
+		aac_fib_init(fibptr);
+
+		dma_buf = pci_alloc_consistent(dev->pdev, datasize, &addr);
+		if (dma_buf != NULL) {
+			u32 vbus, vid;
+
+			vbus = (u32)le16_to_cpu(
+				dev->supplement_adapter_info.VirtDeviceBus);
+			vid = (u32)le16_to_cpu(
+				dev->supplement_adapter_info.VirtDeviceTarget);
+
+			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_DataOut);
+			srbcmd->timeout = cpu_to_le32(10);
+			srbcmd->retry_limit = 0;
+			srbcmd->cdb_size = cpu_to_le32(12);
+			srbcmd->count = cpu_to_le32(datasize);
+
+			memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+			srbcmd->cdb[0] = BMIC_OUT;
+			srbcmd->cdb[6] = WRITE_HOST_WELLNESS;
+			memcpy(dma_buf, (char *)wellness_str, datasize);
+
+			sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
+			sg64->sg[0].count = cpu_to_le32(datasize);
+
+			ret = aac_fib_send(ScsiPortCommand64, fibptr,
+				sizeof(struct aac_srb), FsaNormal,
+				1, 1, NULL, NULL);
+
+			pci_free_consistent(dev->pdev, datasize,
+						(void *)dma_buf, addr);
+	}
+
+		/*
+		 * Do not set XferState to zero unless
+		 * receives a response from F/W
+		 */
+		if (ret >= 0)
+			aac_fib_complete(fibptr);
+
+		/*
+		 * FIB should be freed only after
+		 * getting the response from the F/W
+		 */
+		if (ret != -ERESTARTSYS)
+			aac_fib_free(fibptr);
+	}
+
+	return ret;
+}
+
+int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)
+{
+	int ret = -ENOMEM;
+	struct fib *fibptr;
+
+	/*
+	 *  This whole block needs to be rewritten with helpers
+	 *  Changing tabs to a single space should not be allowed!!
+	 */
+
+	if (dev->sa_firmware) {
+		struct tm cur_tm;
+		char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ";
+		u32 datasize = sizeof(wellness_str);
+		unsigned long local_time;
+
+		local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60));
+		time_to_tm(local_time, 0, &cur_tm);
+		cur_tm.tm_mon += 1;
+		cur_tm.tm_year += 1900;
+		wellness_str[8] = bin2bcd(cur_tm.tm_hour);
+		wellness_str[9] = bin2bcd(cur_tm.tm_min);
+		wellness_str[10] = bin2bcd(cur_tm.tm_sec);
+		wellness_str[12] = bin2bcd(cur_tm.tm_mon);
+		wellness_str[13] = bin2bcd(cur_tm.tm_mday);
+		wellness_str[14] = bin2bcd(cur_tm.tm_year / 100);
+		wellness_str[15] = bin2bcd(cur_tm.tm_year % 100);
+
+		ret = aac_send_wellness_command(dev, wellness_str, datasize);
+
+		return ret;
+	}
+
+	fibptr = aac_fib_alloc(dev);
+	if (fibptr) {
+		__le32 *info;
+
+		aac_fib_init(fibptr);
+		info = (__le32 *)fib_data(fibptr);
+		*info = cpu_to_le32(now->tv_sec);
+		ret = aac_fib_send(
+			SendHostTime, fibptr,
+			sizeof(*info), FsaNormal,
+			1, 1, NULL, NULL);
+
+		/*
+		 * Do not set XferState to zero unless
+		 * receives a response from F/W
+		 */
+		if (ret >= 0)
+			aac_fib_complete(fibptr);
+
+		/*
+		 * FIB should be freed only after
+		 * getting the response from the F/W
+		 */
+		if (ret != -ERESTARTSYS)
+			aac_fib_free(fibptr);
+	}
+
+	return ret;
+}
+
 /**
  *	aac_command_thread	-	command processing thread
  *	@dev: Adapter to monitor
@@ -2001,7 +2139,7 @@ int aac_command_thread(void *data)
 
 			/* Don't even try to talk to adapter if its sick */
 			ret = aac_check_health(dev);
-			if (!ret && !dev->queues)
+			if (!dev->queues)
 				break;
 			next_check_jiffies = jiffies
 					   + ((long)(unsigned)check_interval)
@@ -2014,36 +2152,12 @@ int aac_command_thread(void *data)
 				difference = (((1000000 - now.tv_usec) * HZ)
 				  + 500000) / 1000000;
 			else if (ret == 0) {
-				struct fib *fibptr;
-
-				if ((fibptr = aac_fib_alloc(dev))) {
-					int status;
-					__le32 *info;
-
-					aac_fib_init(fibptr);
-
-					info = (__le32 *) fib_data(fibptr);
-					if (now.tv_usec > 500000)
-						++now.tv_sec;
-
-					*info = cpu_to_le32(now.tv_sec);
-
-					status = aac_fib_send(SendHostTime,
-						fibptr,
-						sizeof(*info),
-						FsaNormal,
-						1, 1,
-						NULL,
-						NULL);
-					/* Do not set XferState to zero unless
-					 * receives a response from F/W */
-					if (status >= 0)
-						aac_fib_complete(fibptr);
-					/* FIB should be freed only after
-					 * getting the response from the F/W */
-					if (status != -ERESTARTSYS)
-						aac_fib_free(fibptr);
-				}
+
+				if (now.tv_usec > 500000)
+					++now.tv_sec;
+
+				ret = aac_send_hosttime(dev, &now);
+
 				difference = (long)(unsigned)update_interval*HZ;
 			} else {
 				/* retry shortly */
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (10 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 11/24] aacraid: Added support for periodic wellness sync Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 10:31   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 13/24] aacraid: Added support to set QD of attached drives Raghava Aditya Renukunta
                   ` (11 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Retrieved queue depth from fw and saved it for future use.
Only applicable for HBA1000 drives.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c  | 84 ++++++++++++++++++++++++++++++++++++++++-
 drivers/scsi/aacraid/aacraid.h | 85 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 167 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index e441a54..c34686f 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1516,6 +1516,83 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
 	return aac_scsi_32(fib, cmd);
 }
 
+int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
+{
+	struct fib *fibptr;
+	int rcode = -1;
+	u16 fibsize, datasize;
+	struct aac_srb *srbcmd;
+	struct sgmap64 *sg64;
+	struct aac_ciss_identify_pd *identify_resp;
+	dma_addr_t addr;
+	u32 vbus, vid;
+	u16 temp;
+
+	fibptr = aac_fib_alloc(dev);
+	if (!fibptr)
+		return -ENOMEM;
+
+	temp = AAC_MAX_LUN + target;
+
+	fibsize = sizeof(struct aac_srb) -
+		sizeof(struct sgentry) + sizeof(struct sgentry64);
+	datasize = sizeof(struct aac_ciss_identify_pd);
+
+	identify_resp = (struct aac_ciss_identify_pd *)
+		pci_alloc_consistent(dev->pdev, datasize, &addr);
+
+	if (identify_resp != NULL) {
+		vbus = (u32)le16_to_cpu(
+			dev->supplement_adapter_info.VirtDeviceBus);
+		vid = (u32)le16_to_cpu(
+			dev->supplement_adapter_info.VirtDeviceTarget);
+
+		aac_fib_init(fibptr);
+		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);
+
+		memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
+		srbcmd->cdb[0] = 0x26;
+		srbcmd->cdb[2] = (u8)(temp & 0x00FF);
+
+		srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
+
+		sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
+		sg64->sg[0].count = cpu_to_le32(datasize);
+
+		rcode = aac_fib_send(ScsiPortCommand64,
+			fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL);
+
+		if (identify_resp->current_queue_depth_limit <= 0 ||
+			identify_resp->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;
+
+		pci_free_consistent(dev->pdev, datasize,
+					(void *)identify_resp, addr);
+
+		aac_fib_complete(fibptr);
+	}
+
+	aac_fib_free(fibptr);
+
+	return rcode;
+}
+
 /**
  *	aac_update hba_map()-	update current hba map with data from FW
  *	@dev:	aac_dev structure
@@ -1565,6 +1642,9 @@ 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)
+			dev->hba_map[bus][target].qd_limit = 32;
+
 update_devtype:
 		dev->hba_map[bus][target].devtype = devtype;
 	}
@@ -1711,8 +1791,10 @@ int aac_get_adapter_info(struct aac_dev* dev)
 
 	/* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
 	for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
-		for (target = 0; target < AAC_MAX_TARGETS; target++)
+		for (target = 0; target < AAC_MAX_TARGETS; target++) {
 			dev->hba_map[bus][target].devtype = 0;
+			dev->hba_map[bus][target].qd_limit = 0;
+		}
 	}
 
 	/*
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 05884e6..e541394 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -74,7 +74,7 @@ enum {
 #define AAC_NUM_IO_FIB		(1024 - AAC_NUM_MGT_FIB)
 #define AAC_NUM_FIB		(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
 
-#define AAC_MAX_LUN		(8)
+#define AAC_MAX_LUN		(256)
 
 #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
 #define AAC_MAX_32BIT_SGBCOUNT	((unsigned short)256)
@@ -89,6 +89,7 @@ enum {
 
 #define CISS_REPORT_PHYSICAL_LUNS	0xc3
 #define WRITE_HOST_WELLNESS		0xa5
+#define CISS_IDENTIFY_PHYSICAL_DEVICE	0x15
 #define BMIC_IN			0x26
 #define BMIC_OUT			0x27
 
@@ -110,6 +111,86 @@ struct aac_ciss_phys_luns_resp {
  */
 #define AAC_MAX_HRRQ		64
 
+#pragma pack(1)
+
+struct aac_ciss_identify_pd {
+	u8 scsi_bus;			/* SCSI Bus number on controller */
+	u8 scsi_id;			/* SCSI ID on this bus */
+	u16 block_size;			/* sector size in bytes */
+	u32 total_blocks;		/* number for sectors on drive */
+	u32 reserved_blocks;		/* controller reserved (RIS) */
+	u8 model[40];			/* Physical Drive Model */
+	u8 serial_number[40];		/* Drive Serial Number */
+	u8 firmware_revision[8];	/* drive firmware revision */
+	u8 scsi_inquiry_bits;		/* inquiry byte 7 bits */
+	u8 compaq_drive_stamp;		/* 0 means drive not stamped */
+	u8 last_failure_reason;
+
+	u8  flags;
+	u8  more_flags;
+	u8  scsi_lun;			/* SCSI LUN for phys drive */
+	u8  yet_more_flags;
+	u8  even_more_flags;
+	u32 spi_speed_rules;		/* SPI Speed :Ultra disable diagnose */
+	u8  phys_connector[2];		/* connector number on controller */
+	u8  phys_box_on_bus;		/* phys enclosure this drive resides */
+	u8  phys_bay_in_box;		/* phys drv bay this drive resides */
+	u32 rpm;			/* Drive rotational speed in rpm */
+	u8  device_type;		/* type of drive */
+	u8  sata_version;		/* only valid when drive_type is SATA */
+	u64 big_total_block_count;
+	u64 ris_starting_lba;
+	u32 ris_size;
+	u8  wwid[20];
+	u8  controller_phy_map[32];
+	u16 phy_count;
+	u8  phy_connected_dev_type[256];
+	u8  phy_to_drive_bay_num[256];
+	u16 phy_to_attached_dev_index[256];
+	u8  box_index;
+	u8  spitfire_support;
+	u16 extra_physical_drive_flags;
+	u8  negotiated_link_rate[256];
+	u8  phy_to_phy_map[256];
+	u8  redundant_path_present_map;
+	u8  redundant_path_failure_map;
+	u8  active_path_number;
+	u16 alternate_paths_phys_connector[8];
+	u8  alternate_paths_phys_box_on_port[8];
+	u8  multi_lun_device_lun_count;
+	u8  minimum_good_fw_revision[8];
+	u8  unique_inquiry_bytes[20];
+	u8  current_temperature_degreesC;
+	u8  temperature_threshold_degreesC;
+	u8  max_temperature_degreesC;
+	u8  logical_blocks_per_phys_block_exp;	/* phyblocksize = 512 * 2^exp */
+	u16 current_queue_depth_limit;
+	u8  switch_name[10];
+	u16 switch_port;
+	u8  alternate_paths_switch_name[40];
+	u8  alternate_paths_switch_port[8];
+	u16 power_on_hours;		/* valid only if gas gauge supported */
+	u16 percent_endurance_used;	/* valid only if gas gauge supported. */
+	u8  drive_authentication;
+	u8  smart_carrier_authentication;
+	u8  smart_carrier_app_fw_version;
+	u8  smart_carrier_bootloader_fw_version;
+	u8  SanitizeSecureEraseSupport;
+	u8  DriveKeyFlags;
+	u8  encryption_key_name[64];
+	u32 misc_drive_flags;
+	u16 dek_index;
+	u16 drive_encryption_flags;
+	u8  sanitize_maximum_time[6];
+	u8  connector_info_mode;
+	u8  connector_info_number[4];
+	u8  long_connector_name[64];
+	u8  device_unique_identifier[16];
+	u8  padto_2K[17];
+};
+
+#pragma pack()
+
 /*
  * These macros convert from physical channels to virtual channels
  */
@@ -1032,6 +1113,7 @@ struct aac_hba_map_info {
 	u8		devtype;	/* device type */
 	u8		reset_state;	/* 0 - no reset, 1..x - */
 					/* after xth TM LUN reset */
+	u16		qd_limit;
 	u8		expose;		/*checks if to expose or not*/
 };
 
@@ -2240,6 +2322,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
 int aac_acquire_irq(struct aac_dev *dev);
 void aac_free_irq(struct aac_dev *dev);
 int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr);
+int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target);
 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);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 13/24] aacraid: Added support to set QD of attached drives
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (11 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 10:39   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 14/24] aacraid: Added support for hotplug Raghava Aditya Renukunta
                   ` (10 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added support to set qd of drives in slave_configure.This only works for
HBA1000 attached drives.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/linit.c | 100 ++++++++++++++++++++++++++++---------------
 1 file changed, 66 insertions(+), 34 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 1912e7b..77d07b7 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -401,20 +401,33 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev,
 static int aac_slave_configure(struct scsi_device *sdev)
 {
 	struct aac_dev *aac = (struct aac_dev *)sdev->host->hostdata;
-	if (aac->jbod && (sdev->type == TYPE_DISK))
-		sdev->removable = 1;
-	if ((sdev->type == TYPE_DISK) &&
+	int chn, tid, is_native_device = 0;
+
+	chn = aac_logical_to_phys(sdev_channel(sdev));
+	tid = sdev_id(sdev);
+	if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
+		aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW)
+		is_native_device = 1;
+
+
+	if (!is_native_device) {
+		if (aac->jbod && (sdev->type == TYPE_DISK))
+			sdev->removable = 1;
+		if ((sdev->type == TYPE_DISK) &&
 			(sdev_channel(sdev) != CONTAINER_CHANNEL) &&
 			(!aac->jbod || sdev->inq_periph_qual) &&
 			(!aac->raid_scsi_mode || (sdev_channel(sdev) != 2))) {
-		if (expose_physicals == 0)
-			return -ENXIO;
-		if (expose_physicals < 0)
-			sdev->no_uld_attach = 1;
+			if (expose_physicals == 0)
+				return -ENXIO;
+			if (expose_physicals < 0)
+				sdev->no_uld_attach = 1;
+		}
 	}
-	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
+
+	if (is_native_device ||
+		(sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 			(!aac->raid_scsi_mode || (sdev_channel(sdev) != 2)) &&
-			!sdev->no_uld_attach) {
+			!sdev->no_uld_attach)) {
 		struct scsi_device * dev;
 		struct Scsi_Host *host = sdev->host;
 		unsigned num_lsu = 0;
@@ -428,34 +441,41 @@ static int aac_slave_configure(struct scsi_device *sdev)
 		 */
 		if (sdev->request_queue->rq_timeout < (45 * HZ))
 			blk_queue_rq_timeout(sdev->request_queue, 45*HZ);
-		for (cid = 0; cid < aac->maximum_num_containers; ++cid)
-			if (aac->fsa_dev[cid].valid)
-				++num_lsu;
-		__shost_for_each_device(dev, host) {
-			if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
+		if (!is_native_device) {
+			for (cid = 0; cid < aac->maximum_num_containers; ++cid)
+				if (aac->fsa_dev[cid].valid)
+					++num_lsu;
+			__shost_for_each_device(dev, host) {
+				if (dev->tagged_supported &&
+					(dev->type == TYPE_DISK) &&
 					(!aac->raid_scsi_mode ||
-						(sdev_channel(sdev) != 2)) &&
+					(sdev_channel(sdev) != 2)) &&
 					!dev->no_uld_attach) {
-				if ((sdev_channel(dev) != CONTAINER_CHANNEL)
-				 || !aac->fsa_dev[sdev_id(dev)].valid)
-					++num_lsu;
-			} else
-				++num_one;
+					if ((sdev_channel(dev)
+						!= CONTAINER_CHANNEL)
+					 || !aac->fsa_dev[sdev_id(dev)].valid) {
+						++num_lsu;
+					}
+				} else {
+					++num_one;
+				}
+			}
+			if (num_lsu == 0)
+				++num_lsu;
+			depth = (host->can_queue - num_one) / num_lsu;
+			if (depth > 256)
+				depth = 256;
+			else if (depth < 2)
+				depth = 2;
+			scsi_change_queue_depth(sdev, depth);
+		} else {
+			scsi_change_queue_depth(sdev,
+				aac->hba_map[chn][tid].qd_limit);
 		}
-		if (num_lsu == 0)
-			++num_lsu;
-		depth = (host->can_queue - num_one) / num_lsu;
-		if (depth > 256)
-			depth = 256;
-		else if (depth < 2)
-			depth = 2;
-		scsi_change_queue_depth(sdev, depth);
-	} else {
-		scsi_change_queue_depth(sdev, 1);
-
-		sdev->tagged_supported = 1;
 	}
 
+	sdev->tagged_supported = 1;
+
 	return 0;
 }
 
@@ -470,6 +490,15 @@ static int aac_slave_configure(struct scsi_device *sdev)
 
 static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
 {
+	struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
+	int chn, tid, is_native_device = 0;
+
+	chn = aac_logical_to_phys(sdev_channel(sdev));
+	tid = sdev_id(sdev);
+	if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS &&
+		aac->hba_map[chn][tid].devtype == AAC_DEVTYPE_NATIVE_RAW)
+		is_native_device = 1;
+
 	if (sdev->tagged_supported && (sdev->type == TYPE_DISK) &&
 	    (sdev_channel(sdev) == CONTAINER_CHANNEL)) {
 		struct scsi_device * dev;
@@ -491,9 +520,12 @@ static int aac_change_queue_depth(struct scsi_device *sdev, int depth)
 		else if (depth < 2)
 			depth = 2;
 		return scsi_change_queue_depth(sdev, depth);
+	} else if (is_native_device) {
+		scsi_change_queue_depth(sdev, aac->hba_map[chn][tid].qd_limit);
+	} else {
+		scsi_change_queue_depth(sdev, 1);
 	}
-
-	return scsi_change_queue_depth(sdev, 1);
+	return sdev->queue_depth;
 }
 
 static ssize_t aac_show_raid_level(struct device *dev, struct device_attribute *attr, char *buf)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 14/24] aacraid: Added support for hotplug
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (12 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 13/24] aacraid: Added support to set QD of attached drives Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 15/24] aacraid: Include HBA direct interface Raghava Aditya Renukunta
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added support for drive hotplug add and removal

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V2:
None

 drivers/scsi/aacraid/aachba.c  |  13 ++--
 drivers/scsi/aacraid/aacraid.h |  17 +++++-
 drivers/scsi/aacraid/commsup.c | 136 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 159 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index c34686f..cc003d1 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -1601,7 +1601,7 @@ int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
  *	Update our hba map with the information gathered from the FW
  */
 void aac_update_hba_map(struct aac_dev *dev,
-		struct aac_ciss_phys_luns_resp *phys_luns)
+		struct aac_ciss_phys_luns_resp *phys_luns, int rescan)
 {
 	/* ok and extended reporting */
 	u32 lun_count, nexus;
@@ -1646,7 +1646,10 @@ void aac_update_hba_map(struct aac_dev *dev,
 			dev->hba_map[bus][target].qd_limit = 32;
 
 update_devtype:
-		dev->hba_map[bus][target].devtype = devtype;
+		if (rescan == AAC_INIT)
+			dev->hba_map[bus][target].devtype = devtype;
+		else
+			dev->hba_map[bus][target].new_devtype = devtype;
 	}
 }
 
@@ -1658,7 +1661,7 @@ void aac_update_hba_map(struct aac_dev *dev,
  *	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 aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan)
 {
 	int fibsize, datasize;
 	struct aac_ciss_phys_luns_resp *phys_luns;
@@ -1718,7 +1721,7 @@ int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr)
 	/* analyse data */
 	if (rcode >= 0 && phys_luns->resp_flag == 2) {
 		/* ok and extended reporting */
-		aac_update_hba_map(dev, phys_luns);
+		aac_update_hba_map(dev, phys_luns, rescan);
 	}
 
 	pci_free_consistent(dev->pdev, datasize, (void *) phys_luns, addr);
@@ -1831,7 +1834,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
 	if (!dev->sync_mode && dev->sa_firmware &&
 			dev->supplement_adapter_info.VirtDeviceBus != 0xffff) {
 		/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
-		rcode = aac_report_phys_luns(dev, fibptr);
+		rcode = aac_report_phys_luns(dev, fibptr, AAC_INIT);
 	}
 
 	if (!dev->in_reset) {
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index e541394..d7d1585 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -74,7 +74,7 @@ enum {
 #define AAC_NUM_IO_FIB		(1024 - AAC_NUM_MGT_FIB)
 #define AAC_NUM_FIB		(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
 
-#define AAC_MAX_LUN		(256)
+#define AAC_MAX_LUN		256
 
 #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
 #define AAC_MAX_32BIT_SGBCOUNT	((unsigned short)256)
@@ -87,6 +87,14 @@ enum {
 #define AAC_MAX_TARGETS		256
 #define AAC_MAX_NATIVE_SIZE		2048
 
+/* Thor AIF events */
+#define SA_AIF_HOTPLUG			(1<<1)
+#define SA_AIF_HARDWARE		(1<<2)
+#define SA_AIF_PDEV_CHANGE		(1<<4)
+#define SA_AIF_LDEV_CHANGE		(1<<5)
+#define SA_AIF_BPSTAT_CHANGE		(1<<30)
+#define SA_AIF_BPCFG_CHANGE		(1<<31)
+
 #define CISS_REPORT_PHYSICAL_LUNS	0xc3
 #define WRITE_HOST_WELLNESS		0xa5
 #define CISS_IDENTIFY_PHYSICAL_DEVICE	0x15
@@ -198,6 +206,7 @@ struct aac_ciss_identify_pd {
 #define CONTAINER_TO_CHANNEL(cont)	(CONTAINER_CHANNEL)
 #define CONTAINER_TO_ID(cont)		(cont)
 #define CONTAINER_TO_LUN(cont)		(0)
+#define ENCLOSURE_CHANNEL		(3)
 
 #define PMC_DEVICE_S6	0x28b
 #define PMC_DEVICE_S7	0x28c
@@ -1102,6 +1111,9 @@ struct fib {
 	u32			hbacmd_size;	/* cmd size for native */
 };
 
+#define AAC_INIT			0
+#define AAC_RESCAN			1
+
 #define AAC_DEVTYPE_RAID_MEMBER	1
 #define AAC_DEVTYPE_ARC_RAW		2
 #define AAC_DEVTYPE_NATIVE_RAW		3
@@ -1111,6 +1123,7 @@ 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;
@@ -2321,7 +2334,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
 
 int aac_acquire_irq(struct aac_dev *dev);
 void aac_free_irq(struct aac_dev *dev);
-int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr);
+int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr, int rescan);
 int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target);
 const char *aac_driverinfo(struct Scsi_Host *);
 void aac_fib_vector_assign(struct aac_dev *dev);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 0c009f1..9e51508 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1730,6 +1730,136 @@ int aac_check_health(struct aac_dev * aac)
 	return BlinkLED;
 }
 
+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++) {
+
+			if (aac_phys_to_logical(bus) == ENCLOSURE_CHANNEL)
+				continue;
+
+			if (bus == CONTAINER_CHANNEL)
+				channel = CONTAINER_CHANNEL;
+			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 && devtype)
+				scsi_add_device(dev->scsi_host_ptr, channel,
+						target, 0);
+			else if (sdev && new_devtype != devtype)
+				scsi_remove_device(sdev);
+			else if (sdev && new_devtype == devtype)
+				scsi_rescan_device(&sdev->sdev_gendev);
+
+			if (sdev)
+				scsi_device_put(sdev);
+
+			dev->hba_map[bus][target].devtype = new_devtype;
+		}
+	}
+}
+
+/**
+ *	aac_handle_sa_aif	Handle a message from the firmware
+ *	@dev: Which adapter this fib is from
+ *	@fibptr: Pointer to fibptr from adapter
+ *
+ *	This routine handles a driver notify fib from the adapter and
+ *	dispatches it to the appropriate routine for handling.
+ */
+static void aac_handle_sa_aif(struct aac_dev *dev, struct fib *fibptr)
+{
+	int i, bus, target, container, rcode = 0;
+	u32 events = 0;
+	struct fib *fib;
+	struct scsi_device *sdev;
+
+	if (fibptr->hbacmd_size & SA_AIF_HOTPLUG)
+		events = SA_AIF_HOTPLUG;
+	else if (fibptr->hbacmd_size & SA_AIF_HARDWARE)
+		events = SA_AIF_HARDWARE;
+	else if (fibptr->hbacmd_size & SA_AIF_PDEV_CHANGE)
+		events = SA_AIF_PDEV_CHANGE;
+	else if (fibptr->hbacmd_size & SA_AIF_LDEV_CHANGE)
+		events = SA_AIF_LDEV_CHANGE;
+	else if (fibptr->hbacmd_size & SA_AIF_BPSTAT_CHANGE)
+		events = SA_AIF_BPSTAT_CHANGE;
+	else if (fibptr->hbacmd_size & SA_AIF_BPCFG_CHANGE)
+		events = SA_AIF_BPCFG_CHANGE;
+
+	switch (events) {
+	case SA_AIF_HOTPLUG:
+	case SA_AIF_HARDWARE:
+	case SA_AIF_PDEV_CHANGE:
+	case SA_AIF_LDEV_CHANGE:
+	case SA_AIF_BPCFG_CHANGE:
+
+		fib = aac_fib_alloc(dev);
+		if (!fib) {
+			pr_err("aac_handle_sa_aif: out of memory\n");
+			return;
+		}
+		for (bus = 0; bus < AAC_MAX_BUSES; bus++)
+			for (target = 0; target < AAC_MAX_TARGETS; target++)
+				dev->hba_map[bus][target].new_devtype = 0;
+
+		rcode = aac_report_phys_luns(dev, fib, AAC_RESCAN);
+
+		if (rcode != -ERESTARTSYS)
+			aac_fib_free(fib);
+
+		aac_resolve_luns(dev);
+
+		if (events == SA_AIF_LDEV_CHANGE ||
+		    events == SA_AIF_BPCFG_CHANGE) {
+			aac_get_containers(dev);
+			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->sdev_gendev);
+					scsi_device_put(sdev);
+				}
+			}
+		}
+		break;
+
+	case SA_AIF_BPSTAT_CHANGE:
+		/* currently do nothing */
+		break;
+	}
+
+	for (i = 1; i <= 10; ++i) {
+		events = src_readl(dev, MUnit.IDR);
+		if (events & (1<<23)) {
+			pr_warn(" AIF not cleared by firmware - %d/%d)\n",
+				i, 10);
+			ssleep(1);
+		}
+	}
+}
+
 static void aac_process_events(struct aac_dev *dev)
 {
 	struct hw_fib *hw_fib, *hw_newfib;
@@ -1759,6 +1889,12 @@ static void aac_process_events(struct aac_dev *dev)
 
 		fib = list_entry(entry, struct fib, fiblink);
 		hw_fib = fib->hw_fib_va;
+		if (dev->sa_firmware) {
+			/* Thor AIF */
+			aac_handle_sa_aif(dev, fib);
+			aac_fib_adapter_complete(fib, (u16)sizeof(u32));
+			continue;
+		}
 		/*
 		 *	We will process the FIB here or pass it to a
 		 *	worker thread that is TBD. We Really can't
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 15/24] aacraid: Include HBA direct interface
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (13 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 14/24] aacraid: Added support for hotplug Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:02   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 16/24] aacraid: Add task management functionality Raghava Aditya Renukunta
                   ` (8 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added support to send direct pasthru srb commands from management utilty
to the  controller.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h  | 175 ++++++++++++++++++++++--
 drivers/scsi/aacraid/commctrl.c | 294 ++++++++++++++++++++++++++++++----------
 drivers/scsi/aacraid/commsup.c  | 134 +++++++++++++++---
 drivers/scsi/aacraid/dpcsup.c   | 136 ++++++++++++-------
 drivers/scsi/aacraid/linit.c    |   1 +
 drivers/scsi/aacraid/src.c      | 118 ++++++++++------
 6 files changed, 669 insertions(+), 189 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d7d1585..77c4749 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -86,6 +86,7 @@ enum {
 #define AAC_MAX_BUSES			5
 #define AAC_MAX_TARGETS		256
 #define AAC_MAX_NATIVE_SIZE		2048
+#define FW_ERROR_BUFFER_SIZE		512
 
 /* Thor AIF events */
 #define SA_AIF_HOTPLUG			(1<<1)
@@ -95,6 +96,141 @@ enum {
 #define SA_AIF_BPSTAT_CHANGE		(1<<30)
 #define SA_AIF_BPCFG_CHANGE		(1<<31)
 
+#define HBA_MAX_SG_EMBEDDED		28
+#define HBA_MAX_SG_SEPARATE		90
+#define HBA_SENSE_DATA_LEN_MAX		32
+#define HBA_REQUEST_TAG_ERROR_FLAG	0x00000002
+#define HBA_SGL_FLAGS_EXT		0x80000000UL
+
+struct aac_hba_sgl {
+	u32		addr_lo; /* Lower 32-bits of SGL element address */
+	u32		addr_hi; /* Upper 32-bits of SGL element address */
+	u32		len;	/* Length of SGL element in bytes */
+	u32		flags;	/* SGL element flags */
+};
+
+enum {
+	HBA_IU_TYPE_SCSI_CMD_REQ		= 0x40,
+	HBA_IU_TYPE_SCSI_TM_REQ			= 0x41,
+	HBA_IU_TYPE_SATA_REQ			= 0x42,
+	HBA_IU_TYPE_RESP			= 0x60,
+	HBA_IU_TYPE_COALESCED_RESP		= 0x61,
+	HBA_IU_TYPE_INT_COALESCING_CFG_REQ	= 0x70
+};
+
+enum {
+	HBA_CMD_BYTE1_DATA_DIR_IN		= 0x1,
+	HBA_CMD_BYTE1_DATA_DIR_OUT		= 0x2,
+	HBA_CMD_BYTE1_DATA_TYPE_DDR		= 0x4,
+	HBA_CMD_BYTE1_CRYPTO_ENABLE		= 0x8
+};
+
+enum {
+	HBA_CMD_BYTE1_BITOFF_DATA_DIR_IN	= 0x0,
+	HBA_CMD_BYTE1_BITOFF_DATA_DIR_OUT,
+	HBA_CMD_BYTE1_BITOFF_DATA_TYPE_DDR,
+	HBA_CMD_BYTE1_BITOFF_CRYPTO_ENABLE
+};
+
+enum {
+	HBA_RESP_DATAPRES_NO_DATA		= 0x0,
+	HBA_RESP_DATAPRES_RESPONSE_DATA,
+	HBA_RESP_DATAPRES_SENSE_DATA
+};
+
+enum {
+	HBA_RESP_SVCRES_TASK_COMPLETE		= 0x0,
+	HBA_RESP_SVCRES_FAILURE,
+	HBA_RESP_SVCRES_TMF_COMPLETE,
+	HBA_RESP_SVCRES_TMF_SUCCEEDED,
+	HBA_RESP_SVCRES_TMF_REJECTED,
+	HBA_RESP_SVCRES_TMF_LUN_INVALID
+};
+
+enum {
+	HBA_RESP_STAT_IO_ERROR			= 0x1,
+	HBA_RESP_STAT_IO_ABORTED,
+	HBA_RESP_STAT_NO_PATH_TO_DEVICE,
+	HBA_RESP_STAT_INVALID_DEVICE,
+	HBA_RESP_STAT_HBAMODE_DISABLED		= 0xE,
+	HBA_RESP_STAT_UNDERRUN			= 0x51,
+	HBA_RESP_STAT_OVERRUN			= 0x75
+};
+
+struct aac_hba_cmd_req {
+	u8	iu_type;	/* HBA information unit type */
+	/*
+	 * byte1:
+	 * [1:0] DIR - 0=No data, 0x1 = IN, 0x2 = OUT
+	 * [2]   TYPE - 0=PCI, 1=DDR
+	 * [3]   CRYPTO_ENABLE - 0=Crypto disabled, 1=Crypto enabled
+	 */
+	u8	byte1;
+	u8	reply_qid;	/* Host reply queue to post response to */
+	u8	reserved1;
+	__le32	it_nexus;	/* Device handle for the request */
+	__le32	request_id;	/* Sender context */
+	/* Lower 32-bits of tweak value for crypto enabled IOs */
+	__le32	tweak_value_lo;
+	u8	cdb[16];	/* SCSI CDB of the command */
+	u8	lun[8];		/* SCSI LUN of the command */
+
+	/* Total data length in bytes to be read/written (if any) */
+	__le32	data_length;
+
+	/* [2:0] Task Attribute, [6:3] Command Priority */
+	u8	attr_prio;
+
+	/* Number of SGL elements embedded in the HBA req */
+	u8	emb_data_desc_count;
+
+	__le16	dek_index;	/* DEK index for crypto enabled IOs */
+
+	/* Lower 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_lo;
+
+	/* Upper 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_hi;
+
+	/* Length of reserved error data area on the host in bytes */
+	__le32	error_length;
+
+	/* Upper 32-bits of tweak value for crypto enabled IOs */
+	__le32	tweak_value_hi;
+
+	struct aac_hba_sgl sge[HBA_MAX_SG_SEPARATE+2]; /* SG list space */
+
+	/*
+	 * structure must not exceed
+	 * AAC_MAX_NATIVE_SIZE-FW_ERROR_BUFFER_SIZE
+	 */
+};
+
+struct aac_hba_resp {
+	u8	iu_type;		/* HBA information unit type */
+	u8	reserved1[3];
+	__le32	request_identifier;	/* sender context */
+	__le32	reserved2;
+	u8	service_response;	/* SCSI service response */
+	u8	status;			/* SCSI status */
+	u8	datapres;	/* [1:0] - data present, [7:2] - reserved */
+	u8	sense_response_data_len;	/* Sense/response data length */
+	__le32	residual_count;		/* Residual data length in bytes */
+	/* Sense/response data */
+	u8	sense_response_buf[HBA_SENSE_DATA_LEN_MAX];
+};
+
+struct aac_native_hba {
+	union {
+		struct aac_hba_cmd_req cmd;
+		u8 cmd_bytes[AAC_MAX_NATIVE_SIZE-FW_ERROR_BUFFER_SIZE];
+	} cmd;
+	union {
+		struct aac_hba_resp err;
+		u8 resp_bytes[FW_ERROR_BUFFER_SIZE];
+	} resp;
+};
+
 #define CISS_REPORT_PHYSICAL_LUNS	0xc3
 #define WRITE_HOST_WELLNESS		0xa5
 #define CISS_IDENTIFY_PHYSICAL_DEVICE	0x15
@@ -472,10 +608,10 @@ enum aac_queue_types {
 
 /* transport FIB header (PMC) */
 struct aac_fib_xporthdr {
-	u64	HostAddress;	/* FIB host address w/o xport header */
-	u32	Size;		/* FIB size excluding xport header */
-	u32	Handle;		/* driver handle to reference the FIB */
-	u64	Reserved[2];
+	__le64	HostAddress;	/* FIB host address w/o xport header */
+	__le32	Size;		/* FIB size excluding xport header */
+	__le32	Handle;		/* driver handle to reference the FIB */
+	__le64	Reserved[2];
 };
 
 #define		ALIGN32		32
@@ -982,17 +1118,20 @@ struct src_mu_registers {
 	__le32	IQ_L;		/*  c0h | Inbound Queue (Low address) */
 	__le32	IQ_H;		/*  c4h | Inbound Queue (High address) */
 	__le32	ODR_MSI;	/*  c8h | MSI register for sync./AIF */
+	__le32  reserved5;	/*  cch | Reserved */
+	__le32	IQN_L;		/*  d0h | Inbound (native cmd) low  */
+	__le32	IQN_H;		/*  d4h | Inbound (native cmd) high */
 };
 
 struct src_registers {
 	struct src_mu_registers MUnit;	/* 00h - cbh */
 	union {
 		struct {
-			__le32 reserved1[130789];	/* cch - 7fc5fh */
+			__le32 reserved1[130786];	/* d8h - 7fc5fh */
 			struct src_inbound IndexRegs;	/* 7fc60h */
 		} tupelo;
 		struct {
-			__le32 reserved1[973];		/* cch - fffh */
+			__le32 reserved1[970];		/* d8h - fffh */
 			struct src_inbound IndexRegs;	/* 1000h */
 		} denali;
 	} u;
@@ -1106,8 +1245,10 @@ struct fib {
 	struct list_head	fiblink;
 	void			*data;
 	u32			vector_no;
-	struct hw_fib		*hw_fib_va;		/* Actual shared object */
-	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
+	struct hw_fib		*hw_fib_va;	/* also used for native */
+	dma_addr_t		hw_fib_pa;	/* physical address of hw_fib*/
+	dma_addr_t		hw_sgl_pa;	/* extra sgl for native */
+	dma_addr_t		hw_error_pa;	/* error buffer for native */
 	u32			hbacmd_size;	/* cmd size for native */
 };
 
@@ -1289,6 +1430,7 @@ struct aac_bus_info_response {
 #define AAC_OPT_NEW_COMM		cpu_to_le32(1<<17)
 #define AAC_OPT_NEW_COMM_64		cpu_to_le32(1<<18)
 #define AAC_OPT_EXTENDED		cpu_to_le32(1<<23)
+#define AAC_OPT_NATIVE_HBA		cpu_to_le32(1<<25)
 #define AAC_OPT_NEW_COMM_TYPE1		cpu_to_le32(1<<28)
 #define AAC_OPT_NEW_COMM_TYPE2		cpu_to_le32(1<<29)
 #define AAC_OPT_NEW_COMM_TYPE3		cpu_to_le32(1<<30)
@@ -1326,8 +1468,8 @@ struct aac_dev
 	/*
 	 *	Map for 128 fib objects (64k)
 	 */
-	dma_addr_t		hw_fib_pa;
-	struct hw_fib		*hw_fib_va;
+	dma_addr_t		hw_fib_pa;	/* also used for native cmd */
+	struct hw_fib		*hw_fib_va;	/* also used for native cmd */
 	struct hw_fib		*aif_base_va;
 	/*
 	 *	Fib Headers
@@ -1502,6 +1644,8 @@ struct aac_dev
 #define FIB_CONTEXT_FLAG			(0x00000002)
 #define FIB_CONTEXT_FLAG_WAIT			(0x00000004)
 #define FIB_CONTEXT_FLAG_FASTRESP		(0x00000008)
+#define FIB_CONTEXT_FLAG_NATIVE_HBA		(0x00000010)
+#define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF	(0x00000020)
 
 /*
  *	Define the command values
@@ -2161,6 +2305,8 @@ struct aac_common
 #ifdef DBG
 	u32 FibsSent;
 	u32 FibRecved;
+	u32 NativeSent;
+	u32 NativeRecved;
 	u32 NoResponseSent;
 	u32 NoResponseRecved;
 	u32 AsyncSent;
@@ -2172,7 +2318,6 @@ struct aac_common
 
 extern struct aac_common aac_config;
 
-
 /*
  *	The following macro is used when sending and receiving FIBs. It is
  *	only used for debugging.
@@ -2299,9 +2444,10 @@ extern struct aac_common aac_config;
 
 /* PMC NEW COMM: Request the event data */
 #define		AifReqEvent		200
+#define		AifRawDeviceRemove	203	/* RAW device deleted */
+#define		AifNativeDeviceAdd	204	/* native HBA device added */
+#define		AifNativeDeviceRemove	205	/* native HBA device removed */
 
-/* RAW device deleted */
-#define		AifRawDeviceRemove	203
 
 /*
  *	Adapter Initiated FIB command structures. Start with the adapter
@@ -2346,9 +2492,12 @@ void aac_fib_free(struct fib * context);
 void aac_fib_init(struct fib * context);
 void aac_printf(struct aac_dev *dev, u32 val);
 int aac_fib_send(u16 command, struct fib * context, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *ctxt);
+int aac_hba_send(u8 command, struct fib *context,
+		fib_callback callback, void *ctxt);
 int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry);
 void aac_consumer_free(struct aac_dev * dev, struct aac_queue * q, u32 qnum);
 int aac_fib_complete(struct fib * context);
+void aac_hba_callback(void *context, struct fib *fibptr);
 #define fib_data(fibctx) ((void *)(fibctx)->hw_fib_va->data)
 struct aac_dev *aac_init_adapter(struct aac_dev *dev);
 void aac_src_access_devreg(struct aac_dev *dev, int mode);
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 5648b71..b2af77f 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -477,20 +477,24 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 	struct fib* srbfib;
 	int status;
 	struct aac_srb *srbcmd = NULL;
+	struct aac_hba_cmd_req *hbacmd = NULL;
 	struct user_aac_srb *user_srbcmd = NULL;
 	struct user_aac_srb __user *user_srb = arg;
 	struct aac_srb_reply __user *user_reply;
-	struct aac_srb_reply* reply;
+	u32 chn;
 	u32 fibsize = 0;
 	u32 flags = 0;
 	s32 rcode = 0;
 	u32 data_dir;
-	void __user *sg_user[32];
-	void *sg_list[32];
+	void __user *sg_user[HBA_MAX_SG_EMBEDDED];
+	void *sg_list[HBA_MAX_SG_EMBEDDED];
+	u32 sg_count[HBA_MAX_SG_EMBEDDED];
 	u32 sg_indx = 0;
 	u32 byte_count = 0;
 	u32 actual_fibsize64, actual_fibsize = 0;
 	int i;
+	int is_native_device;
+	u64 address;
 
 
 	if (dev->in_reset) {
@@ -507,11 +511,6 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 	if (!(srbfib = aac_fib_alloc(dev))) {
 		return -ENOMEM;
 	}
-	aac_fib_init(srbfib);
-	/* raw_srb FIB is not FastResponseCapable */
-	srbfib->hw_fib_va->header.XferState &= ~cpu_to_le32(FastResponseCapable);
-
-	srbcmd = (struct aac_srb*) fib_data(srbfib);
 
 	memset(sg_list, 0, sizeof(sg_list)); /* cleanup may take issue */
 	if(copy_from_user(&fibsize, &user_srb->count,sizeof(u32))){
@@ -538,21 +537,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 		goto cleanup;
 	}
 
-	user_reply = arg+fibsize;
-
 	flags = user_srbcmd->flags; /* from user in cpu order */
-	// Fix up srb for endian and force some values
-
-	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);	// Force this
-	srbcmd->channel	 = cpu_to_le32(user_srbcmd->channel);
-	srbcmd->id	 = cpu_to_le32(user_srbcmd->id);
-	srbcmd->lun	 = cpu_to_le32(user_srbcmd->lun);
-	srbcmd->timeout	 = cpu_to_le32(user_srbcmd->timeout);
-	srbcmd->flags	 = cpu_to_le32(flags);
-	srbcmd->retry_limit = 0; // Obsolete parameter
-	srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
-	memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
-
 	switch (flags & (SRB_DataIn | SRB_DataOut)) {
 	case SRB_DataOut:
 		data_dir = DMA_TO_DEVICE;
@@ -568,7 +553,12 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 	}
 	if (user_srbcmd->sg.count > ARRAY_SIZE(sg_list)) {
 		dprintk((KERN_DEBUG"aacraid: too many sg entries %d\n",
-		  le32_to_cpu(srbcmd->sg.count)));
+			user_srbcmd->sg.count));
+		rcode = -EINVAL;
+		goto cleanup;
+	}
+	if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) {
+		dprintk((KERN_DEBUG"aacraid:SG with no direction specified\n"));
 		rcode = -EINVAL;
 		goto cleanup;
 	}
@@ -588,13 +578,136 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 		rcode = -EINVAL;
 		goto cleanup;
 	}
-	if ((data_dir == DMA_NONE) && user_srbcmd->sg.count) {
-		dprintk((KERN_DEBUG"aacraid: SG with no direction specified in Raw SRB command\n"));
-		rcode = -EINVAL;
-		goto cleanup;
+
+	chn = aac_logical_to_phys(user_srbcmd->channel);
+	if (chn < AAC_MAX_BUSES && user_srbcmd->id < AAC_MAX_TARGETS &&
+		dev->hba_map[chn][user_srbcmd->id].devtype ==
+		AAC_DEVTYPE_NATIVE_RAW) {
+		is_native_device = 1;
+		hbacmd = (struct aac_hba_cmd_req *)srbfib->hw_fib_va;
+		memset(hbacmd, 0, 96);	/* sizeof(*hbacmd) is not necessary */
+
+		/* iu_type is a parameter of aac_hba_send */
+		switch (data_dir) {
+		case DMA_TO_DEVICE:
+			hbacmd->byte1 = 2;
+			break;
+		case DMA_FROM_DEVICE:
+		case DMA_BIDIRECTIONAL:
+			hbacmd->byte1 = 1;
+			break;
+		case DMA_NONE:
+		default:
+			break;
+		}
+		hbacmd->lun[1] = cpu_to_le32(user_srbcmd->lun);
+		hbacmd->it_nexus = dev->hba_map[chn][user_srbcmd->id].rmw_nexus;
+
+		/*
+		 * we fill in reply_qid later in aac_src_deliver_message
+		 * we fill in iu_type, request_id later in aac_hba_send
+		 * we fill in emb_data_desc_count, data_length later
+		 * in sg list build
+		 */
+
+		memcpy(hbacmd->cdb, user_srbcmd->cdb, sizeof(hbacmd->cdb));
+
+		address = (u64)srbfib->hw_error_pa;
+		hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+		hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
+		hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+		hbacmd->emb_data_desc_count =
+					cpu_to_le32(user_srbcmd->sg.count);
+		srbfib->hbacmd_size = 64 +
+			user_srbcmd->sg.count * sizeof(struct aac_hba_sgl);
+
+	} else {
+		is_native_device = 0;
+		aac_fib_init(srbfib);
+
+		/* raw_srb FIB is not FastResponseCapable */
+		srbfib->hw_fib_va->header.XferState &=
+			~cpu_to_le32(FastResponseCapable);
+
+		srbcmd = (struct aac_srb *) fib_data(srbfib);
+
+		// Fix up srb for endian and force some values
+
+		srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi); // Force this
+		srbcmd->channel	 = cpu_to_le32(user_srbcmd->channel);
+		srbcmd->id	 = cpu_to_le32(user_srbcmd->id);
+		srbcmd->lun	 = cpu_to_le32(user_srbcmd->lun);
+		srbcmd->timeout	 = cpu_to_le32(user_srbcmd->timeout);
+		srbcmd->flags	 = cpu_to_le32(flags);
+		srbcmd->retry_limit = 0; // Obsolete parameter
+		srbcmd->cdb_size = cpu_to_le32(user_srbcmd->cdb_size);
+		memcpy(srbcmd->cdb, user_srbcmd->cdb, sizeof(srbcmd->cdb));
 	}
+
 	byte_count = 0;
-	if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
+	if (is_native_device) {
+		struct user_sgmap *usg32 = &user_srbcmd->sg;
+		struct user_sgmap64 *usg64 =
+			(struct user_sgmap64 *)&user_srbcmd->sg;
+
+		for (i = 0; i < usg32->count; i++) {
+			void *p;
+			u64 addr;
+
+			sg_count[i] = (actual_fibsize64 == fibsize) ?
+				usg64->sg[i].count : usg32->sg[i].count;
+			if (sg_count[i] >
+				(dev->scsi_host_ptr->max_sectors << 9)) {
+				pr_err("aacraid: upsg->sg[%d].count=%u>%u\n",
+					i, sg_count[i],
+					dev->scsi_host_ptr->max_sectors << 9);
+				rcode = -EINVAL;
+				goto cleanup;
+			}
+
+			p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+			if (!p) {
+				rcode = -ENOMEM;
+				goto cleanup;
+			}
+
+			if (actual_fibsize64 == fibsize) {
+				addr = (u64)usg64->sg[i].addr[0];
+				addr += ((u64)usg64->sg[i].addr[1]) << 32;
+			} else {
+				addr = (u64)usg32->sg[i].addr;
+			}
+
+			sg_user[i] = (void __user *)(uintptr_t)addr;
+			sg_list[i] = p; // save so we can clean up later
+			sg_indx = i;
+
+			if (flags & SRB_DataOut) {
+				if (copy_from_user(p, sg_user[i],
+					sg_count[i])) {
+					rcode = -EFAULT;
+					goto cleanup;
+				}
+			}
+			addr = pci_map_single(dev->pdev, p, sg_count[i],
+						data_dir);
+			hbacmd->sge[i].addr_hi = cpu_to_le32((u32)(addr>>32));
+			hbacmd->sge[i].addr_lo = cpu_to_le32(
+						(u32)(addr & 0xffffffff));
+			hbacmd->sge[i].len = cpu_to_le32(sg_count[i]);
+			hbacmd->sge[i].flags = 0;
+			byte_count += sg_count[i];
+		}
+
+		if (usg32->count > 0)	/* embedded sglist */
+			hbacmd->sge[usg32->count-1].flags =
+				cpu_to_le32(0x40000000);
+		hbacmd->data_length = cpu_to_le32(byte_count);
+
+		status = aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, srbfib,
+					NULL, NULL);
+
+	} else if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
 		struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg;
 		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
 
@@ -606,7 +719,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 			for (i = 0; i < upsg->count; i++) {
 				u64 addr;
 				void* p;
-				if (upsg->sg[i].count >
+
+				sg_count[i] = upsg->sg[i].count;
+				if (sg_count[i] >
 				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
@@ -615,10 +730,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 					goto cleanup;
 				}
 				/* Does this really need to be GFP_DMA? */
-				p = kmalloc(upsg->sg[i].count,GFP_KERNEL|__GFP_DMA);
+				p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
 				if(!p) {
 					dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-					  upsg->sg[i].count,i,upsg->count));
+					  sg_count[i], i, upsg->count));
 					rcode = -ENOMEM;
 					goto cleanup;
 				}
@@ -629,18 +744,20 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 				sg_indx = i;
 
 				if (flags & SRB_DataOut) {
-					if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
+					if (copy_from_user(p, sg_user[i],
+						sg_count[i])){
 						dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
 						rcode = -EFAULT;
 						goto cleanup;
 					}
 				}
-				addr = pci_map_single(dev->pdev, p, upsg->sg[i].count, data_dir);
+				addr = pci_map_single(dev->pdev, p,
+							sg_count[i], data_dir);
 
 				psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
 				psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
-				byte_count += upsg->sg[i].count;
-				psg->sg[i].count = cpu_to_le32(upsg->sg[i].count);
+				byte_count += sg_count[i];
+				psg->sg[i].count = cpu_to_le32(sg_count[i]);
 			}
 		} else {
 			struct user_sgmap* usg;
@@ -657,7 +774,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 			for (i = 0; i < usg->count; i++) {
 				u64 addr;
 				void* p;
-				if (usg->sg[i].count >
+
+				sg_count[i] = usg->sg[i].count;
+				if (sg_count[i] >
 				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
@@ -667,10 +786,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 					goto cleanup;
 				}
 				/* Does this really need to be GFP_DMA? */
-				p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
+				p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
 				if(!p) {
 					dprintk((KERN_DEBUG "aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-					  usg->sg[i].count,i,usg->count));
+						sg_count[i], i, usg->count));
 					kfree(usg);
 					rcode = -ENOMEM;
 					goto cleanup;
@@ -680,19 +799,21 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 				sg_indx = i;
 
 				if (flags & SRB_DataOut) {
-					if(copy_from_user(p,sg_user[i],upsg->sg[i].count)){
+					if (copy_from_user(p, sg_user[i],
+						sg_count[i])) {
 						kfree (usg);
 						dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
 						rcode = -EFAULT;
 						goto cleanup;
 					}
 				}
-				addr = pci_map_single(dev->pdev, p, usg->sg[i].count, data_dir);
+				addr = pci_map_single(dev->pdev, p,
+							sg_count[i], data_dir);
 
 				psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
 				psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
-				byte_count += usg->sg[i].count;
-				psg->sg[i].count = cpu_to_le32(usg->sg[i].count);
+				byte_count += sg_count[i];
+				psg->sg[i].count = cpu_to_le32(sg_count[i]);
 			}
 			kfree (usg);
 		}
@@ -711,7 +832,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 			for (i = 0; i < upsg->count; i++) {
 				uintptr_t addr;
 				void* p;
-				if (usg->sg[i].count >
+
+				sg_count[i] = usg->sg[i].count;
+				if (sg_count[i] >
 				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
@@ -720,10 +843,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 					goto cleanup;
 				}
 				/* Does this really need to be GFP_DMA? */
-				p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
-				if(!p) {
+				p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
+				if (!p) {
 					dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-					  usg->sg[i].count,i,usg->count));
+						sg_count[i], i, usg->count));
 					rcode = -ENOMEM;
 					goto cleanup;
 				}
@@ -734,7 +857,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 				sg_indx = i;
 
 				if (flags & SRB_DataOut) {
-					if(copy_from_user(p,sg_user[i],usg->sg[i].count)){
+					if (copy_from_user(p, sg_user[i],
+						sg_count[i])){
 						dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
 						rcode = -EFAULT;
 						goto cleanup;
@@ -744,13 +868,15 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 
 				psg->sg[i].addr = cpu_to_le32(addr & 0xffffffff);
 				byte_count += usg->sg[i].count;
-				psg->sg[i].count = cpu_to_le32(usg->sg[i].count);
+				psg->sg[i].count = cpu_to_le32(sg_count[i]);
 			}
 		} else {
 			for (i = 0; i < upsg->count; i++) {
 				dma_addr_t addr;
 				void* p;
-				if (upsg->sg[i].count >
+
+				sg_count[i] = upsg->sg[i].count;
+				if (sg_count[i] >
 				    ((dev->adapter_info.options &
 				     AAC_OPT_NEW_COMM) ?
 				      (dev->scsi_host_ptr->max_sectors << 9) :
@@ -758,10 +884,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 					rcode = -EINVAL;
 					goto cleanup;
 				}
-				p = kmalloc(upsg->sg[i].count, GFP_KERNEL);
+				p = kmalloc(sg_count[i], GFP_KERNEL);
 				if (!p) {
 					dprintk((KERN_DEBUG"aacraid: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
-					  upsg->sg[i].count, i, upsg->count));
+					  sg_count[i], i, upsg->count));
 					rcode = -ENOMEM;
 					goto cleanup;
 				}
@@ -770,19 +896,19 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 				sg_indx = i;
 
 				if (flags & SRB_DataOut) {
-					if(copy_from_user(p, sg_user[i],
-							upsg->sg[i].count)) {
+					if (copy_from_user(p, sg_user[i],
+						sg_count[i])) {
 						dprintk((KERN_DEBUG"aacraid: Could not copy sg data from user\n"));
 						rcode = -EFAULT;
 						goto cleanup;
 					}
 				}
 				addr = pci_map_single(dev->pdev, p,
-					upsg->sg[i].count, data_dir);
+					sg_count[i], data_dir);
 
 				psg->sg[i].addr = cpu_to_le32(addr);
-				byte_count += upsg->sg[i].count;
-				psg->sg[i].count = cpu_to_le32(upsg->sg[i].count);
+				byte_count += sg_count[i];
+				psg->sg[i].count = cpu_to_le32(sg_count[i]);
 			}
 		}
 		srbcmd->count = cpu_to_le32(byte_count);
@@ -792,12 +918,13 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 			psg->count = 0;
 		status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
 	}
+
 	if (status == -ERESTARTSYS) {
 		rcode = -ERESTARTSYS;
 		goto cleanup;
 	}
 
-	if (status != 0){
+	if (status != 0) {
 		dprintk((KERN_DEBUG"aacraid: Could not send raw srb fib to hba\n"));
 		rcode = -ENXIO;
 		goto cleanup;
@@ -805,11 +932,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 
 	if (flags & SRB_DataIn) {
 		for(i = 0 ; i <= sg_indx; i++){
-			byte_count = le32_to_cpu(
-			  (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)
-			      ? ((struct sgmap64*)&srbcmd->sg)->sg[i].count
-			      : srbcmd->sg.sg[i].count);
-			if(copy_to_user(sg_user[i], sg_list[i], byte_count)){
+			if (copy_to_user(sg_user[i], sg_list[i], sg_count[i])) {
 				dprintk((KERN_DEBUG"aacraid: Could not copy sg data to user\n"));
 				rcode = -EFAULT;
 				goto cleanup;
@@ -818,19 +941,50 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
 		}
 	}
 
-	reply = (struct aac_srb_reply *) fib_data(srbfib);
-	if(copy_to_user(user_reply,reply,sizeof(struct aac_srb_reply))){
-		dprintk((KERN_DEBUG"aacraid: Could not copy reply to user\n"));
-		rcode = -EFAULT;
-		goto cleanup;
+	user_reply = arg + fibsize;
+	if (is_native_device) {
+		struct aac_hba_resp *err =
+			&((struct aac_native_hba *)srbfib->hw_fib_va)->resp.err;
+		struct aac_srb_reply reply;
+
+		reply.status = ST_OK;
+		if (srbfib->flags & FIB_CONTEXT_FLAG_FASTRESP) {
+			/* fast response */
+			reply.srb_status = SRB_STATUS_SUCCESS;
+			reply.scsi_status = 0;
+			reply.data_xfer_length = byte_count;
+		} else {
+			reply.srb_status = err->service_response;
+			reply.scsi_status = err->status;
+			reply.data_xfer_length = byte_count -
+				le32_to_cpu(err->residual_count);
+			reply.sense_data_size = err->sense_response_data_len;
+			memcpy(reply.sense_data, err->sense_response_buf,
+				AAC_SENSE_BUFFERSIZE);
+		}
+		if (copy_to_user(user_reply, &reply,
+			sizeof(struct aac_srb_reply))) {
+			dprintk((KERN_DEBUG"aacraid: Copy to user failed\n"));
+			rcode = -EFAULT;
+			goto cleanup;
+		}
+	} else {
+		struct aac_srb_reply *reply;
+
+		reply = (struct aac_srb_reply *) fib_data(srbfib);
+		if (copy_to_user(user_reply, reply,
+			sizeof(struct aac_srb_reply))) {
+			dprintk((KERN_DEBUG"aacraid: Copy to user failed\n"));
+			rcode = -EFAULT;
+			goto cleanup;
+		}
 	}
 
 cleanup:
 	kfree(user_srbcmd);
-	for(i=0; i <= sg_indx; i++){
-		kfree(sg_list[i]);
-	}
 	if (rcode != -ERESTARTSYS) {
+		for (i = 0; i <= sg_indx; i++)
+			kfree(sg_list[i]);
 		aac_fib_complete(srbfib);
 		aac_fib_free(srbfib);
 	}
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 9e51508..3aac5b1 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -65,6 +65,11 @@ static int fib_map_alloc(struct aac_dev *dev)
 		dev->max_cmd_size = AAC_MAX_NATIVE_SIZE;
 	else
 		dev->max_cmd_size = dev->max_fib_size;
+	if (dev->max_fib_size < AAC_MAX_NATIVE_SIZE) {
+		dev->max_cmd_size = AAC_MAX_NATIVE_SIZE;
+	} else {
+		dev->max_cmd_size = dev->max_fib_size;
+	}
 
 	dprintk((KERN_INFO
 	  "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
@@ -153,7 +158,7 @@ int aac_fib_setup(struct aac_dev * dev)
 		(hw_fib_pa - dev->hw_fib_pa));
 	dev->hw_fib_pa = hw_fib_pa;
 	memset(dev->hw_fib_va, 0,
-		(dev->max_fib_size + sizeof(struct aac_fib_xporthdr)) *
+		(dev->max_cmd_size + sizeof(struct aac_fib_xporthdr)) *
 		(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
 
 	/* add Xport header */
@@ -179,8 +184,18 @@ int aac_fib_setup(struct aac_dev * dev)
 		sema_init(&fibptr->event_wait, 0);
 		spin_lock_init(&fibptr->event_lock);
 		hw_fib->header.XferState = cpu_to_le32(0xffffffff);
-		hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size);
+		hw_fib->header.SenderSize =
+			cpu_to_le16(dev->max_fib_size);	/* ?? max_cmd_size */
 		fibptr->hw_fib_pa = hw_fib_pa;
+		fibptr->hw_sgl_pa = hw_fib_pa +
+			offsetof(struct aac_hba_cmd_req, sge[2]);
+		/*
+		 * one element is for the ptr to the separate sg list,
+		 * second element for 32 byte alignment
+		 */
+		fibptr->hw_error_pa = hw_fib_pa +
+			offsetof(struct aac_native_hba, resp.resp_bytes[0]);
+
 		hw_fib = (struct hw_fib *)((unsigned char *)hw_fib +
 			dev->max_cmd_size + sizeof(struct aac_fib_xporthdr));
 		hw_fib_pa = hw_fib_pa +
@@ -282,7 +297,8 @@ void aac_fib_free(struct fib *fibptr)
 	spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
 	if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
 		aac_config.fib_timeouts++;
-	if (fibptr->hw_fib_va->header.XferState != 0) {
+	if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) &&
+		fibptr->hw_fib_va->header.XferState != 0) {
 		printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n",
 			 (void*)fibptr,
 			 le32_to_cpu(fibptr->hw_fib_va->header.XferState));
@@ -510,8 +526,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 	 *	Map the fib into 32bits by using the fib number
 	 */
 
-	hw_fib->header.SenderFibAddress = cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
-	hw_fib->header.Handle = (u32)(fibptr - dev->fibs) + 1;
+	hw_fib->header.SenderFibAddress =
+		cpu_to_le32(((u32)(fibptr - dev->fibs)) << 2);
+
+	/* use the same shifted value for handle to be compatible
+	 * with the new native hba command handle
+	 */
+	hw_fib->header.Handle =
+		cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
+
 	/*
 	 *	Set FIB state to indicate where it came from and if we want a
 	 *	response from the adapter. Also load the command from the
@@ -679,6 +702,82 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 		return 0;
 }
 
+int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
+		void *callback_data)
+{
+	struct aac_dev *dev = fibptr->dev;
+	int wait;
+	unsigned long flags = 0;
+	unsigned long mflags = 0;
+
+	fibptr->flags = (FIB_CONTEXT_FLAG | FIB_CONTEXT_FLAG_NATIVE_HBA);
+	if (callback) {
+		wait = 0;
+		fibptr->callback = callback;
+		fibptr->callback_data = callback_data;
+	} else
+		wait = 1;
+
+
+	if (command == HBA_IU_TYPE_SCSI_CMD_REQ) {
+		struct aac_hba_cmd_req *hbacmd =
+			(struct aac_hba_cmd_req *)fibptr->hw_fib_va;
+
+		hbacmd->iu_type = command;
+		/* bit1 of request_id must be 0 */
+		hbacmd->request_id =
+			cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
+	} else
+		return -EINVAL;
+
+
+	if (wait) {
+		spin_lock_irqsave(&dev->manage_lock, mflags);
+		if (dev->management_fib_count >= AAC_NUM_MGT_FIB) {
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+			return -EBUSY;
+		}
+		dev->management_fib_count++;
+		spin_unlock_irqrestore(&dev->manage_lock, mflags);
+		spin_lock_irqsave(&fibptr->event_lock, flags);
+	}
+
+	if (aac_adapter_deliver(fibptr) != 0) {
+		if (wait) {
+			spin_unlock_irqrestore(&fibptr->event_lock, flags);
+			spin_lock_irqsave(&dev->manage_lock, mflags);
+			dev->management_fib_count--;
+			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+		}
+		return -EBUSY;
+	}
+	FIB_COUNTER_INCREMENT(aac_config.NativeSent);
+
+	if (wait) {
+		spin_unlock_irqrestore(&fibptr->event_lock, flags);
+		/* Only set for first known interruptable command */
+		if (down_interruptible(&fibptr->event_wait)) {
+			fibptr->done = 2;
+			up(&fibptr->event_wait);
+		}
+		spin_lock_irqsave(&fibptr->event_lock, flags);
+		if ((fibptr->done == 0) || (fibptr->done == 2)) {
+			fibptr->done = 2; /* Tell interrupt we aborted */
+			spin_unlock_irqrestore(&fibptr->event_lock, flags);
+			return -ERESTARTSYS;
+		}
+		spin_unlock_irqrestore(&fibptr->event_lock, flags);
+		WARN_ON(fibptr->done == 0);
+
+		if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
+			return -ETIMEDOUT;
+
+		return 0;
+	}
+
+	return -EINPROGRESS;
+}
+
 /**
  *	aac_consumer_get	-	get the top of the queue
  *	@dev: Adapter
@@ -837,11 +936,17 @@ int aac_fib_complete(struct fib *fibptr)
 {
 	struct hw_fib * hw_fib = fibptr->hw_fib_va;
 
+	if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) {
+		fib_dealloc(fibptr);
+		return 0;
+	}
+
 	/*
-	 *	Check for a fib which has already been completed
+	 *	Check for a fib which has already been completed or with a
+	 *	status wait timeout
 	 */
 
-	if (hw_fib->header.XferState == 0)
+	if (hw_fib->header.XferState == 0 || fibptr->done == 2)
 		return 0;
 	/*
 	 *	If we plan to do anything check the structure type first.
@@ -994,20 +1099,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 			lun = (container >> 16) & 0xFF;
 			container = (u32)-1;
 			channel = aac_phys_to_logical(channel);
-			device_config_needed =
-			  (((__le32 *)aifcmd->data)[0] ==
-			    cpu_to_le32(AifRawDeviceRemove)) ? DELETE : ADD;
-
-			if (device_config_needed == ADD) {
-				device = scsi_device_lookup(
-					dev->scsi_host_ptr,
-					channel, id, lun);
-				if (device) {
-					scsi_remove_device(device);
-					scsi_device_put(device);
-				}
-			}
+			device_config_needed = DELETE;
 			break;
+
 		/*
 		 *	Morph or Expand complete
 		 */
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index 8077dba..c426ea2 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -346,7 +346,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
 			(fib_callback)aac_aif_callback, fibctx);
 	} else {
 		struct fib *fib = &dev->fibs[index];
-		struct hw_fib * hwfib = fib->hw_fib_va;
+		int start_callback = 0;
 
 		/*
 		 *	Remove this fib from the Outstanding I/O queue.
@@ -364,60 +364,104 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
 			return 0;
 		}
 
-		if (isFastResponse) {
-			/*
-			 *	Doctor the fib
-			 */
-			*(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
-			hwfib->header.XferState |= cpu_to_le32(AdapterProcessed);
-			fib->flags |= FIB_CONTEXT_FLAG_FASTRESP;
-		}
-
 		FIB_COUNTER_INCREMENT(aac_config.FibRecved);
 
-		if (hwfib->header.Command == cpu_to_le16(NuFileSystem))
-		{
-			__le32 *pstatus = (__le32 *)hwfib->data;
-			if (*pstatus & cpu_to_le32(0xffff0000))
-				*pstatus = cpu_to_le32(ST_OK);
-		}
-		if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) 
-		{
-	        	if (hwfib->header.XferState & cpu_to_le32(NoResponseExpected))
-				FIB_COUNTER_INCREMENT(aac_config.NoResponseRecved);
-			else 
-				FIB_COUNTER_INCREMENT(aac_config.AsyncRecved);
-			/*
-			 *	NOTE:  we cannot touch the fib after this
-			 *	    call, because it may have been deallocated.
-			 */
-			if (likely(fib->callback && fib->callback_data)) {
-				fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
-				fib->callback(fib->callback_data, fib);
-			} else
-				dev_info(&dev->pdev->dev,
-				"Invalid callback_fib[%d] (*%p)(%p)\n",
-				index, fib->callback, fib->callback_data);
+		if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) {
+
+			if (isFastResponse)
+				fib->flags |= FIB_CONTEXT_FLAG_FASTRESP;
+
+			if (fib->callback) {
+				start_callback = 1;
+			} else {
+				unsigned long flagv;
+				int complete = 0;
+
+				dprintk((KERN_INFO "event_wait up\n"));
+				spin_lock_irqsave(&fib->event_lock, flagv);
+				if (fib->done == 2) {
+					fib->done = 1;
+					complete = 1;
+				} else {
+					fib->done = 1;
+					up(&fib->event_wait);
+				}
+				spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+				spin_lock_irqsave(&dev->manage_lock, mflags);
+				dev->management_fib_count--;
+				spin_unlock_irqrestore(&dev->manage_lock,
+					mflags);
+
+				FIB_COUNTER_INCREMENT(aac_config.NativeRecved);
+				if (complete)
+					aac_fib_complete(fib);
+			}
 		} else {
-			unsigned long flagv;
-	  		dprintk((KERN_INFO "event_wait up\n"));
-			spin_lock_irqsave(&fib->event_lock, flagv);
-			if (!fib->done) {
-				fib->done = 1;
-				up(&fib->event_wait);
+			struct hw_fib *hwfib = fib->hw_fib_va;
+
+			if (isFastResponse) {
+				/* Doctor the fib */
+				*(__le32 *)hwfib->data = cpu_to_le32(ST_OK);
+				hwfib->header.XferState |=
+					cpu_to_le32(AdapterProcessed);
+				fib->flags |= FIB_CONTEXT_FLAG_FASTRESP;
 			}
-			spin_unlock_irqrestore(&fib->event_lock, flagv);
 
-			spin_lock_irqsave(&dev->manage_lock, mflags);
-			dev->management_fib_count--;
-			spin_unlock_irqrestore(&dev->manage_lock, mflags);
+			if (hwfib->header.Command ==
+				cpu_to_le16(NuFileSystem)) {
+				__le32 *pstatus = (__le32 *)hwfib->data;
 
-			FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
-			if (fib->done == 2) {
+				if (*pstatus & cpu_to_le32(0xffff0000))
+					*pstatus = cpu_to_le32(ST_OK);
+			}
+			if (hwfib->header.XferState &
+				cpu_to_le32(NoResponseExpected | Async)) {
+				if (hwfib->header.XferState & cpu_to_le32(
+					NoResponseExpected))
+					FIB_COUNTER_INCREMENT(
+						aac_config.NoResponseRecved);
+				else
+					FIB_COUNTER_INCREMENT(
+						aac_config.AsyncRecved);
+				start_callback = 1;
+			} else {
+				unsigned long flagv;
+				int complete = 0;
+
+				dprintk((KERN_INFO "event_wait up\n"));
 				spin_lock_irqsave(&fib->event_lock, flagv);
-				fib->done = 0;
+				if (fib->done == 2) {
+					fib->done = 1;
+					complete = 1;
+				} else {
+					fib->done = 1;
+					up(&fib->event_wait);
+				}
 				spin_unlock_irqrestore(&fib->event_lock, flagv);
+
+				spin_lock_irqsave(&dev->manage_lock, mflags);
+				dev->management_fib_count--;
+				spin_unlock_irqrestore(&dev->manage_lock,
+					mflags);
+
+				FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
+				if (complete)
+					aac_fib_complete(fib);
+			}
+		}
+
+
+		if (start_callback) {
+			/*
+			 * NOTE:  we cannot touch the fib after this
+			 *  call, because it may have been deallocated.
+			 */
+			if (likely(fib->callback && fib->callback_data)) {
+				fib->callback(fib->callback_data, fib);
+			} else {
 				aac_fib_complete(fib);
+				aac_fib_free(fib);
 			}
 
 		}
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 77d07b7..202ed34 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1102,6 +1102,7 @@ static void __aac_shutdown(struct aac_dev * aac)
 {
 	int i;
 
+	aac->adapter_shutdown = 1;
 	aac_send_shutdown(aac);
 
 	if (aac->aif_thread) {
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 5508893..946a010 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -457,6 +457,11 @@ static int aac_src_check_health(struct aac_dev *dev)
 	return 0;
 }
 
+static inline u32 aac_get_vector(struct aac_dev *dev)
+{
+	return atomic_inc_return(&dev->msix_counter)%dev->max_msix;
+}
+
 /**
  *	aac_src_deliver_message
  *	@fib: fib to issue
@@ -470,67 +475,100 @@ static int aac_src_deliver_message(struct fib *fib)
 	u32 fibsize;
 	dma_addr_t address;
 	struct aac_fib_xporthdr *pFibX;
+	int native_hba;
 #if !defined(writeq)
 	unsigned long flags;
 #endif
 
-	u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);
 	u16 vector_no;
 
 	atomic_inc(&q->numpending);
 
-	if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest &&
-	    dev->max_msix > 1) {
-		vector_no = fib->vector_no;
-		fib->hw_fib_va->header.Handle += (vector_no << 16);
+	native_hba = (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) ? 1 : 0;
+
+
+	if (dev->msi_enabled && dev->max_msix > 1 &&
+		(native_hba || fib->hw_fib_va->header.Command != AifRequest)) {
+
+		if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)
+			&& dev->sa_firmware)
+			vector_no = aac_get_vector(dev);
+		else
+			vector_no = fib->vector_no;
+
+		if (native_hba) {
+			((struct aac_hba_cmd_req *)fib->hw_fib_va)->reply_qid
+				= vector_no;
+			((struct aac_hba_cmd_req *)fib->hw_fib_va)->request_id
+				+= (vector_no << 16);
+		} else {
+			fib->hw_fib_va->header.Handle += (vector_no << 16);
+		}
 	} else {
 		vector_no = 0;
 	}
 
 	atomic_inc(&dev->rrq_outstanding[vector_no]);
 
-	if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
-		(dev->comm_interface == AAC_COMM_MESSAGE_TYPE3)) {
-		/* Calculate the amount to the fibsize bits */
-		fibsize = (hdr_size + 127) / 128 - 1;
-		if (fibsize > (ALIGN32 - 1))
-			return -EMSGSIZE;
-		/* New FIB header, 32-bit */
+	if (native_hba) {
 		address = fib->hw_fib_pa;
-		fib->hw_fib_va->header.StructType = FIB_MAGIC2;
-		fib->hw_fib_va->header.SenderFibAddress = (u32)address;
-		fib->hw_fib_va->header.u.TimeStamp = 0;
-		BUG_ON(upper_32_bits(address) != 0L);
+		fibsize = (fib->hbacmd_size + 127) / 128 - 1;
+		if (fibsize > 31)
+			fibsize = 31;
 		address |= fibsize;
+#if defined(writeq)
+		src_writeq(dev, MUnit.IQN_L, (u64)address);
+#else
+		spin_lock_irqsave(&fib->dev->iq_lock, flags);
+		src_writel(dev, MUnit.IQN_H,
+			upper_32_bits(address) & 0xffffffff);
+		src_writel(dev, MUnit.IQN_L, address & 0xffffffff);
+		spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
+#endif
 	} else {
-		/* Calculate the amount to the fibsize bits */
-		fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1;
-		if (fibsize > (ALIGN32 - 1))
-			return -EMSGSIZE;
-
-		/* Fill XPORT header */
-		pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr);
-		pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.Handle);
-		pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa);
-		pFibX->Size = cpu_to_le32(hdr_size);
-
-		/*
-		 * The xport header has been 32-byte aligned for us so that fibsize
-		 * can be masked out of this address by hardware. -- BenC
-		 */
-		address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr);
-		if (address & (ALIGN32 - 1))
-			return -EINVAL;
+		if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2 ||
+			dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) {
+			/* Calculate the amount to the fibsize bits */
+			fibsize = (le16_to_cpu(fib->hw_fib_va->header.Size)
+				+ 127) / 128 - 1;
+			/* New FIB header, 32-bit */
+			address = fib->hw_fib_pa;
+			fib->hw_fib_va->header.StructType = FIB_MAGIC2;
+			fib->hw_fib_va->header.SenderFibAddress =
+				cpu_to_le32((u32)address);
+			fib->hw_fib_va->header.u.TimeStamp = 0;
+			WARN_ON(((u32)(((address) >> 16) >> 16)) != 0L);
+		} else {
+			/* Calculate the amount to the fibsize bits */
+			fibsize = (sizeof(struct aac_fib_xporthdr) +
+				le16_to_cpu(fib->hw_fib_va->header.Size)
+				+ 127) / 128 - 1;
+			/* Fill XPORT header */
+			pFibX = (struct aac_fib_xporthdr *)
+				((unsigned char *)fib->hw_fib_va -
+				sizeof(struct aac_fib_xporthdr));
+			pFibX->Handle = fib->hw_fib_va->header.Handle;
+			pFibX->HostAddress =
+				cpu_to_le64((u64)fib->hw_fib_pa);
+			pFibX->Size = cpu_to_le32(
+				le16_to_cpu(fib->hw_fib_va->header.Size));
+			address = fib->hw_fib_pa -
+				(u64)sizeof(struct aac_fib_xporthdr);
+		}
+		if (fibsize > 31)
+			fibsize = 31;
 		address |= fibsize;
-	}
+
 #if defined(writeq)
-	src_writeq(dev, MUnit.IQ_L, (u64)address);
+		src_writeq(dev, MUnit.IQ_L, (u64)address);
 #else
-	spin_lock_irqsave(&fib->dev->iq_lock, flags);
-	src_writel(dev, MUnit.IQ_H, upper_32_bits(address) & 0xffffffff);
-	src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
-	spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
+		spin_lock_irqsave(&fib->dev->iq_lock, flags);
+		src_writel(dev, MUnit.IQ_H,
+			upper_32_bits(address) & 0xffffffff);
+		src_writel(dev, MUnit.IQ_L, address & 0xffffffff);
+		spin_unlock_irqrestore(&fib->dev->iq_lock, flags);
 #endif
+	}
 	return 0;
 }
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 16/24] aacraid: Add task management functionality
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (14 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 15/24] aacraid: Include HBA direct interface Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:19   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun Raghava Aditya Renukunta
                   ` (7 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added support to send out task management commands.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
Fixed overflow warning

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c | 364 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 360 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index cc003d1..c76db95 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -217,9 +217,13 @@ static long aac_build_sg64(struct scsi_cmnd *scsicmd, struct sgmap64 *psg);
 static long aac_build_sgraw(struct scsi_cmnd *scsicmd, struct sgmapraw *psg);
 static long aac_build_sgraw2(struct scsi_cmnd *scsicmd,
 				struct aac_raw_io2 *rio2, int sg_max);
+static long aac_build_sghba(struct scsi_cmnd *scsicmd,
+				struct aac_hba_cmd_req *hbacmd,
+				int sg_max, u64 sg_address);
 static int aac_convert_sgraw2(struct aac_raw_io2 *rio2,
 				int pages, int nseg, int nseg_new);
 static int aac_send_srb_fib(struct scsi_cmnd* scsicmd);
+static int aac_send_hba_fib(struct scsi_cmnd *scsicmd);
 #ifdef AAC_DETAILED_STATUS_INFO
 static char *aac_get_status_string(u32 status);
 #endif
@@ -1446,6 +1450,52 @@ static struct aac_srb * aac_scsi_common(struct fib * fib, struct scsi_cmnd * cmd
 	return srbcmd;
 }
 
+static struct aac_hba_cmd_req *aac_construct_hbacmd(struct fib *fib,
+							struct scsi_cmnd *cmd)
+{
+	struct aac_hba_cmd_req *hbacmd;
+	struct aac_dev *dev;
+	int bus, target;
+	u64 address;
+
+	dev = (struct aac_dev *)cmd->device->host->hostdata;
+
+	hbacmd = (struct aac_hba_cmd_req *)fib->hw_fib_va;
+	memset(hbacmd, 0, 96);	/* sizeof(*hbacmd) is not necessary */
+	/* iu_type is a parameter of aac_hba_send */
+	switch (cmd->sc_data_direction) {
+	case DMA_TO_DEVICE:
+		hbacmd->byte1 = 2;
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		hbacmd->byte1 = 1;
+		break;
+	case DMA_NONE:
+	default:
+		break;
+	}
+	hbacmd->lun[1] = cpu_to_le32(cmd->device->lun);
+
+	bus = aac_logical_to_phys(scmd_channel(cmd));
+	target = scmd_id(cmd);
+	hbacmd->it_nexus = dev->hba_map[bus][target].rmw_nexus;
+
+	/* we fill in reply_qid later in aac_src_deliver_message */
+	/* we fill in iu_type, request_id later in aac_hba_send */
+	/* we fill in emb_data_desc_count later in aac_build_sghba */
+
+	memcpy(hbacmd->cdb, cmd->cmnd, cmd->cmd_len);
+	hbacmd->data_length = cpu_to_le32(scsi_bufflen(cmd));
+
+	address = (u64)fib->hw_error_pa;
+	hbacmd->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+	hbacmd->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
+	hbacmd->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+
+	return hbacmd;
+}
+
 static void aac_srb_callback(void *context, struct fib * fibptr);
 
 static int aac_scsi_64(struct fib * fib, struct scsi_cmnd * cmd)
@@ -1516,6 +1566,31 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
 	return aac_scsi_32(fib, cmd);
 }
 
+static int aac_adapter_hba(struct fib *fib, struct scsi_cmnd *cmd)
+{
+	struct aac_hba_cmd_req *hbacmd = aac_construct_hbacmd(fib, cmd);
+	struct aac_dev *dev;
+	// u16 fibsize;
+	long ret;
+
+	dev = (struct aac_dev *)cmd->device->host->hostdata;
+
+	ret = aac_build_sghba(cmd, hbacmd,
+		dev->scsi_host_ptr->sg_tablesize, (u64)fib->hw_sgl_pa);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 *	Now send the HBA command to the adapter
+	 */
+	fib->hbacmd_size = 64 + le32_to_cpu(hbacmd->emb_data_desc_count) *
+		sizeof(struct aac_hba_sgl);
+
+	return aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, fib,
+				  (fib_callback) aac_hba_callback,
+				  (void *) cmd);
+}
+
 int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
 {
 	struct fib *fibptr;
@@ -1528,6 +1603,7 @@ int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
 	u32 vbus, vid;
 	u16 temp;
 
+
 	fibptr = aac_fib_alloc(dev);
 	if (!fibptr)
 		return -ENOMEM;
@@ -2003,6 +2079,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
 			  (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
 		}
 	}
+	if (!dev->sync_mode && dev->sa_firmware &&
+		dev->scsi_host_ptr->sg_tablesize > HBA_MAX_SG_SEPARATE)
+		dev->scsi_host_ptr->sg_tablesize = dev->sg_tablesize =
+			HBA_MAX_SG_SEPARATE;
+
 	/* FIB should be freed only after getting the response from the F/W */
 	if (rcode != -ERESTARTSYS) {
 		aac_fib_complete(fibptr);
@@ -2559,7 +2640,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
 
 int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 {
-	u32 cid;
+	u32 cid, bus;
 	struct Scsi_Host *host = scsicmd->device->host;
 	struct aac_dev *dev = (struct aac_dev *)host->hostdata;
 	struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
@@ -2605,8 +2686,24 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				}
 			}
 		} else {  /* check for physical non-dasd devices */
-			if (dev->nondasd_support || expose_physicals ||
-					dev->jbod) {
+			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
+					== AAC_DEVTYPE_NATIVE_RAW) {
+				if (dev->in_reset)
+					return -1;
+				return aac_send_hba_fib(scsicmd);
+			} else if (dev->nondasd_support || expose_physicals ||
+				dev->jbod) {
 				if (dev->in_reset)
 					return -1;
 				return aac_send_srb_fib(scsicmd);
@@ -3365,7 +3462,151 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
 
 /**
  *
- * aac_send_scb_fib
+ * aac_hba_callback
+ * @context: the context set in the fib - here it is scsi cmd
+ * @fibptr: pointer to the fib
+ *
+ * Handles the completion of a native HBA scsi command
+ *
+ */
+void aac_hba_callback(void *context, struct fib *fibptr)
+{
+	struct aac_dev *dev;
+	struct scsi_cmnd *scsicmd;
+
+	scsicmd = (struct scsi_cmnd *) context;
+
+	if (!aac_valid_context(scsicmd, fibptr))
+		return;
+
+	WARN_ON(fibptr == NULL);
+	dev = fibptr->dev;
+
+	if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))
+		scsi_dma_unmap(scsicmd);
+
+	if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
+		/* fast response */
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
+	} else {
+		struct aac_hba_resp *err =
+			&((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
+
+		// BUG_ON(err->iu_type != HBA_IU_TYPE_RESP);
+		if (err->service_response == HBA_RESP_SVCRES_TASK_COMPLETE) {
+			scsicmd->result = err->status;
+			/* set residual count */
+			scsi_set_resid(scsicmd,
+				le32_to_cpu(err->residual_count));
+
+			switch (err->status) {
+			case SAM_STAT_GOOD:
+				scsicmd->result |= DID_OK << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			case SAM_STAT_CHECK_CONDITION:
+			{
+				int len;
+
+				len = min_t(u8, err->sense_response_data_len,
+					SCSI_SENSE_BUFFERSIZE);
+				if (len)
+					memcpy(scsicmd->sense_buffer,
+						err->sense_response_buf, len);
+				scsicmd->result |= DID_OK << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			}
+			case SAM_STAT_BUSY:
+				scsicmd->result |= DID_BUS_BUSY << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			case SAM_STAT_TASK_ABORTED:
+				scsicmd->result |= DID_ABORT << 16 |
+					ABORT << 8;
+				break;
+			case SAM_STAT_RESERVATION_CONFLICT:
+			case SAM_STAT_TASK_SET_FULL:
+			default:
+				scsicmd->result |= DID_ERROR << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			}
+		} else if (err->service_response == HBA_RESP_SVCRES_FAILURE) {
+			switch (err->status) {
+			case HBA_RESP_STAT_HBAMODE_DISABLED:
+			{
+				u32 bus, cid;
+
+				bus = aac_logical_to_phys(
+						scmd_channel(scsicmd));
+				cid = scmd_id(scsicmd);
+				if (dev->hba_map[bus][cid].devtype ==
+					AAC_DEVTYPE_NATIVE_RAW) {
+					dev->hba_map[bus][cid].devtype =
+						AAC_DEVTYPE_ARC_RAW;
+					dev->hba_map[bus][cid].rmw_nexus =
+						0xffffffff;
+				}
+				scsicmd->result = DID_NO_CONNECT << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			}
+			case HBA_RESP_STAT_IO_ERROR:
+			case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
+				scsicmd->result = DID_OK << 16 |
+					COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
+				break;
+			case HBA_RESP_STAT_IO_ABORTED:
+				scsicmd->result = DID_ABORT << 16 |
+					ABORT << 8;
+				break;
+			case HBA_RESP_STAT_INVALID_DEVICE:
+				scsicmd->result = DID_NO_CONNECT << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			case HBA_RESP_STAT_UNDERRUN:
+				/* UNDERRUN is OK */
+				scsicmd->result = DID_OK << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			case HBA_RESP_STAT_OVERRUN:
+			default:
+				scsicmd->result = DID_ERROR << 16 |
+					COMMAND_COMPLETE << 8;
+				break;
+			}
+		} else if (err->service_response ==
+			HBA_RESP_SVCRES_TMF_REJECTED) {
+			scsicmd->result =
+				DID_ERROR << 16 | MESSAGE_REJECT << 8;
+		} else if (err->service_response ==
+			HBA_RESP_SVCRES_TMF_LUN_INVALID) {
+			scsicmd->result =
+				DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
+		} else if ((err->service_response ==
+			HBA_RESP_SVCRES_TMF_COMPLETE) ||
+			(err->service_response ==
+			HBA_RESP_SVCRES_TMF_SUCCEEDED)) {
+			scsicmd->result =
+				DID_OK << 16 | COMMAND_COMPLETE << 8;
+		} else {
+			scsicmd->result =
+				DID_ERROR << 16 | COMMAND_COMPLETE << 8;
+		}
+	}
+
+	aac_fib_complete(fibptr);
+
+	if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
+		scsicmd->SCp.sent_command = 1;
+	else
+		scsicmd->scsi_done(scsicmd);
+}
+
+/**
+ *
+ * aac_send_srb_fib
  * @scsicmd: the scsi command block
  *
  * This routine will form a FIB and fill in the aac_srb from the
@@ -3408,6 +3649,54 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
 	return -1;
 }
 
+/**
+ *
+ * aac_send_hba_fib
+ * @scsicmd: the scsi command block
+ *
+ * This routine will form a FIB and fill in the aac_hba_cmd_req from the
+ * scsicmd passed in.
+ */
+static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
+{
+	struct fib *cmd_fibcontext;
+	struct aac_dev *dev;
+	int status;
+
+	dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+	if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
+			scsicmd->device->lun > AAC_MAX_LUN - 1) {
+		scsicmd->result = DID_NO_CONNECT << 16;
+		scsicmd->scsi_done(scsicmd);
+		return 0;
+	}
+
+	/*
+	 *	Allocate and initialize a Fib then setup a BlockWrite command
+	 */
+	cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
+	if (!cmd_fibcontext)
+		return -1;
+
+	status = aac_adapter_hba(cmd_fibcontext, scsicmd);
+
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS) {
+		scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+		return 0;
+	}
+
+	pr_warn("aac_hba_cmd_req: aac_fib_send failed with status: %d\n",
+		status);
+	aac_fib_complete(cmd_fibcontext);
+	aac_fib_free(cmd_fibcontext);
+
+	return -1;
+}
+
+
 static long aac_build_sg(struct scsi_cmnd *scsicmd, struct sgmap *psg)
 {
 	struct aac_dev *dev;
@@ -3660,6 +3949,73 @@ static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int
 	return 0;
 }
 
+static long aac_build_sghba(struct scsi_cmnd *scsicmd,
+			struct aac_hba_cmd_req *hbacmd,
+			int sg_max,
+			u64 sg_address)
+{
+	unsigned long byte_count = 0;
+	int nseg;
+
+	nseg = scsi_dma_map(scsicmd);
+	if (nseg < 0)
+		return nseg;
+	if (nseg) {
+		struct scatterlist *sg;
+		int i;
+		u32 cur_size;
+		struct aac_hba_sgl *sge;
+
+		if (nseg > HBA_MAX_SG_EMBEDDED)
+			sge = &hbacmd->sge[2];
+		else
+			sge = &hbacmd->sge[0];
+
+		scsi_for_each_sg(scsicmd, sg, nseg, i) {
+			int count = sg_dma_len(sg);
+			u64 addr = sg_dma_address(sg);
+
+			WARN_ON(i >= sg_max);
+			sge->addr_hi = cpu_to_le32((u32)(addr>>32));
+			sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));
+			cur_size = cpu_to_le32(count);
+			sge->len = cur_size;
+			sge->flags = 0;
+			byte_count += count;
+			sge++;
+		}
+
+		sge--;
+		/* hba wants the size to be exact */
+		if (byte_count > scsi_bufflen(scsicmd)) {
+			u32 temp = le32_to_cpu(sge->len) -
+				(byte_count - scsi_bufflen(scsicmd));
+			sge->len = cpu_to_le32(temp);
+			byte_count = scsi_bufflen(scsicmd);
+		}
+
+		if (nseg <= HBA_MAX_SG_EMBEDDED) {
+			hbacmd->emb_data_desc_count = cpu_to_le32(nseg);
+			sge->flags = cpu_to_le32(0x40000000);
+		} else {
+			/* not embedded */
+			hbacmd->sge[0].flags = cpu_to_le32(0x80000000);
+			hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);
+			hbacmd->sge[0].addr_hi =
+				(u32)cpu_to_le32(sg_address >> 32);
+			hbacmd->sge[0].addr_lo =
+				cpu_to_le32((u32)(sg_address & 0xffffffff));
+		}
+
+		/* Check for command underflow */
+		if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
+			pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",
+					byte_count, scsicmd->underflow);
+		}
+	}
+	return byte_count;
+}
+
 #ifdef AAC_DETAILED_STATUS_INFO
 
 struct aac_srb_status_info {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (15 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 16/24] aacraid: Add task management functionality Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:24   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 18/24] aacraid: VPD 83 type3 support Raghava Aditya Renukunta
                   ` (6 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added task management command support to abort any timed out commands
in case of a eh_abort call and to reset lun's in case of eh_reset call.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
Fixed  freeing of initialized address

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h |  48 ++++++
 drivers/scsi/aacraid/linit.c   | 351 +++++++++++++++++++++++++++++++----------
 drivers/scsi/aacraid/src.c     |  33 +++-
 3 files changed, 345 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 77c4749..4b32ff1 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -206,6 +206,53 @@ struct aac_hba_cmd_req {
 	 */
 };
 
+/* Task Management Functions (TMF) */
+#define HBA_TMF_ABORT_TASK	0x01
+#define HBA_TMF_LUN_RESET	0x08
+
+struct aac_hba_tm_req {
+	u8	iu_type;	/* HBA information unit type */
+	u8	reply_qid;	/* Host reply queue to post response to */
+	u8	tmf;		/* Task management function */
+	u8	reserved1;
+
+	__le32	it_nexus;	/* Device handle for the command */
+
+	u8	lun[8];		/* SCSI LUN */
+
+	/* Used to hold sender context. */
+	__le32	request_id;	/* Sender context */
+	__le32	reserved2;
+
+	/* Request identifier of managed task */
+	__le32	managed_request_id;	/* Sender context being managed */
+	__le32	reserved3;
+
+	/* Lower 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_lo;
+	/* Upper 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_hi;
+	/* Length of reserved error data area on the host in bytes */
+	__le32	error_length;
+};
+
+struct aac_hba_reset_req {
+	u8	iu_type;	/* HBA information unit type */
+	/* 0 - reset specified device, 1 - reset all devices */
+	u8	reset_type;
+	u8	reply_qid;	/* Host reply queue to post response to */
+	u8	reserved1;
+
+	__le32	it_nexus;	/* Device handle for the command */
+	__le32	request_id;	/* Sender context */
+	/* Lower 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_lo;
+	/* Upper 32-bits of reserved error data target location on the host */
+	__le32	error_ptr_hi;
+	/* Length of reserved error data area on the host in bytes */
+	__le32	error_length;
+};
+
 struct aac_hba_resp {
 	u8	iu_type;		/* HBA information unit type */
 	u8	reserved1[3];
@@ -223,6 +270,7 @@ struct aac_hba_resp {
 struct aac_native_hba {
 	union {
 		struct aac_hba_cmd_req cmd;
+		struct aac_hba_tm_req tmr;
 		u8 cmd_bytes[AAC_MAX_NATIVE_SIZE-FW_ERROR_BUFFER_SIZE];
 	} cmd;
 	union {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 202ed34..9740a05 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -566,46 +566,136 @@ static int aac_eh_abort(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;
-	int count;
+	int count, found;
+	u32 bus, cid;
 	int ret = FAILED;
 
-	printk(KERN_ERR "%s: Host adapter abort request (%d,%d,%d,%llu)\n",
-		AAC_DRIVERNAME,
-		host->host_no, sdev_channel(dev), sdev_id(dev), dev->lun);
-	switch (cmd->cmnd[0]) {
-	case SERVICE_ACTION_IN_16:
-		if (!(aac->raw_io_interface) ||
-		    !(aac->raw_io_64) ||
-		    ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
-			break;
-	case INQUIRY:
-	case READ_CAPACITY:
-		/* Mark associated FIB to not complete, eh handler does this */
+	bus = aac_logical_to_phys(scmd_channel(cmd));
+	cid = scmd_id(cmd);
+	if (aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
+		struct fib *fib;
+		struct aac_hba_tm_req *tmf;
+		int status;
+		u64 address;
+		__le32 managed_request_id;
+
+		pr_err("%s: Host adapter abort request (%d,%d,%d,%d)\n",
+		 AAC_DRIVERNAME,
+		 host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun);
+
+		found = 0;
 		for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
-			struct fib * fib = &aac->fibs[count];
-			if (fib->hw_fib_va->header.XferState &&
-			  (fib->flags & FIB_CONTEXT_FLAG) &&
-			  (fib->callback_data == cmd)) {
-				fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
-				cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+			fib = &aac->fibs[count];
+			if (*(u8 *)fib->hw_fib_va != 0 &&
+				(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) &&
+				(fib->callback_data == cmd)) {
+				found = 1;
+				managed_request_id = ((struct aac_hba_cmd_req *)
+					fib->hw_fib_va)->request_id;
+				break;
+			}
+		}
+		if (!found)
+			return ret;
+
+		/* start a HBA_TMF_ABORT_TASK TMF request */
+		fib = aac_fib_alloc(aac);
+		if (!fib)
+			return ret;
+
+		tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
+		memset(tmf, 0, sizeof(*tmf));
+		tmf->tmf = HBA_TMF_ABORT_TASK;
+		tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+		tmf->lun[1] = cmd->device->lun;
+
+		address = (u64)fib->hw_error_pa;
+		tmf->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+		tmf->error_ptr_lo = cpu_to_le32((u32)(address & 0xffffffff));
+		tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+
+		fib->hbacmd_size = sizeof(*tmf);
+		cmd->SCp.sent_command = 0;
+
+		status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib,
+				  (fib_callback) aac_hba_callback,
+				  (void *) cmd);
+
+		/* Wait up to 2 minutes for completion */
+		for (count = 0; count < 120; ++count) {
+			if (cmd->SCp.sent_command) {
 				ret = SUCCESS;
+				break;
 			}
+			msleep(1000);
 		}
-		break;
-	case TEST_UNIT_READY:
-		/* Mark associated FIB to not complete, eh handler does this */
-		for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
-			struct scsi_cmnd * command;
-			struct fib * fib = &aac->fibs[count];
-			if ((fib->hw_fib_va->header.XferState & cpu_to_le32(Async | NoResponseExpected)) &&
-			  (fib->flags & FIB_CONTEXT_FLAG) &&
-			  ((command = fib->callback_data)) &&
-			  (command->device == cmd->device)) {
-				fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
-				command->SCp.phase = AAC_OWNER_ERROR_HANDLER;
-				if (command == cmd)
+
+		if (ret != SUCCESS)
+			pr_err("%s: Host adapter abort request timed out\n",
+			AAC_DRIVERNAME);
+	} else {
+		pr_err(
+			"%s: Host adapter abort request.\n"
+			"%s: Outstanding commands on (%d,%d,%d,%d):\n",
+			AAC_DRIVERNAME, AAC_DRIVERNAME,
+			host->host_no, sdev_channel(dev), sdev_id(dev),
+			(int)dev->lun);
+		switch (cmd->cmnd[0]) {
+		case SERVICE_ACTION_IN_16:
+			if (!(aac->raw_io_interface) ||
+			    !(aac->raw_io_64) ||
+			    ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
+				break;
+		case INQUIRY:
+		case READ_CAPACITY:
+			/*
+			 * Mark associated FIB to not complete,
+			 * eh handler does this
+			 */
+			for (count = 0;
+				count < (host->can_queue + AAC_NUM_MGT_FIB);
+				++count) {
+				struct fib *fib = &aac->fibs[count];
+
+				if (fib->hw_fib_va->header.XferState &&
+				(fib->flags & FIB_CONTEXT_FLAG) &&
+				(fib->callback_data == cmd)) {
+					fib->flags |=
+						FIB_CONTEXT_FLAG_TIMED_OUT;
+					cmd->SCp.phase =
+						AAC_OWNER_ERROR_HANDLER;
 					ret = SUCCESS;
+				}
 			}
+			break;
+		case TEST_UNIT_READY:
+			/*
+			 * Mark associated FIB to not complete,
+			 * eh handler does this
+			 */
+			for (count = 0;
+				count < (host->can_queue + AAC_NUM_MGT_FIB);
+				++count) {
+				struct scsi_cmnd *command;
+				struct fib *fib = &aac->fibs[count];
+
+				command = fib->callback_data;
+
+				if ((fib->hw_fib_va->header.XferState &
+					cpu_to_le32
+					(Async | NoResponseExpected)) &&
+					(fib->flags & FIB_CONTEXT_FLAG) &&
+					((command)) &&
+					(command->device == cmd->device)) {
+					fib->flags |=
+						FIB_CONTEXT_FLAG_TIMED_OUT;
+					command->SCp.phase =
+						AAC_OWNER_ERROR_HANDLER;
+					if (command == cmd)
+						ret = SUCCESS;
+				}
+			}
+			break;
 		}
 	}
 	return ret;
@@ -620,70 +710,165 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 {
 	struct scsi_device * dev = cmd->device;
 	struct Scsi_Host * host = dev->host;
-	struct scsi_cmnd * command;
-	int count;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
-	unsigned long flags;
-
-	/* Mark the associated FIB to not complete, eh handler does this */
-	for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
-		struct fib * fib = &aac->fibs[count];
-		if (fib->hw_fib_va->header.XferState &&
-		  (fib->flags & FIB_CONTEXT_FLAG) &&
-		  (fib->callback_data == cmd)) {
-			fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
-			cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+	int count;
+	u32 bus, cid;
+	int ret = FAILED;
+
+	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) {
+		struct fib *fib;
+		int status;
+		u64 address;
+		u8 command;
+
+		pr_err("%s: Host adapter reset request. SCSI hang ?\n",
+			AAC_DRIVERNAME);
+
+		fib = aac_fib_alloc(aac);
+		if (!fib)
+			return ret;
+
+
+		if (aac->hba_map[bus][cid].reset_state == 0) {
+			struct aac_hba_tm_req *tmf;
+
+			/* start a HBA_TMF_LUN_RESET TMF request */
+			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->lun[1] = cmd->device->lun;
+
+			address = (u64)fib->hw_error_pa;
+			tmf->error_ptr_hi = cpu_to_le32
+					((u32)(address >> 32));
+			tmf->error_ptr_lo = cpu_to_le32
+					((u32)(address & 0xffffffff));
+			tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+			fib->hbacmd_size = sizeof(*tmf);
+
+			command = HBA_IU_TYPE_SCSI_TM_REQ;
+			aac->hba_map[bus][cid].reset_state++;
+		} else if (aac->hba_map[bus][cid].reset_state >= 1) {
+			struct aac_hba_reset_req *rst;
+
+			/* 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;
+
+			address = (u64)fib->hw_error_pa;
+			rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+			rst->error_ptr_lo = cpu_to_le32
+				((u32)(address & 0xffffffff));
+			rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+			fib->hbacmd_size = sizeof(*rst);
+
+			command = HBA_IU_TYPE_SATA_REQ;
+			aac->hba_map[bus][cid].reset_state = 0;
 		}
-	}
-	printk(KERN_ERR "%s: Host adapter reset request. SCSI hang ?\n",
+		cmd->SCp.sent_command = 0;
+
+		status = aac_hba_send(command, fib,
+				  (fib_callback) aac_hba_callback,
+				  (void *) cmd);
+
+		/* Wait up to 2 minutes for completion */
+		for (count = 0; count < 120; ++count) {
+			if (cmd->SCp.sent_command) {
+				ret = SUCCESS;
+				break;
+			}
+			msleep(1000);
+		}
+
+		if (ret != SUCCESS)
+			pr_err("%s: Host adapter reset request timed out\n",
+			AAC_DRIVERNAME);
+	} else {
+		struct scsi_cmnd *command;
+		unsigned long flags;
+
+		/* 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 = &aac->fibs[count];
+
+			if (fib->hw_fib_va->header.XferState &&
+				(fib->flags & FIB_CONTEXT_FLAG) &&
+				(fib->callback_data == cmd)) {
+				fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
+				cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+			}
+		}
+
+		pr_err("%s: Host adapter reset request. SCSI hang ?\n",
 					AAC_DRIVERNAME);
 
-	if ((count = aac_check_health(aac)))
-		return count;
-	/*
-	 * Wait for all commands to complete to this specific
-	 * target (block maximum 60 seconds).
-	 */
-	for (count = 60; count; --count) {
-		int active = aac->in_reset;
+		count = aac_check_health(aac);
+		if (count)
+			return count;
+		/*
+		 * Wait for all commands to complete to this specific
+		 * target (block maximum 60 seconds).
+		 */
+		for (count = 60; count; --count) {
+			int active = aac->in_reset;
 
-		if (active == 0)
-		__shost_for_each_device(dev, host) {
-			spin_lock_irqsave(&dev->list_lock, flags);
-			list_for_each_entry(command, &dev->cmd_list, list) {
-				if ((command != cmd) &&
-				    (command->SCp.phase == AAC_OWNER_FIRMWARE)) {
-					active++;
-					break;
+			if (active == 0)
+			__shost_for_each_device(dev, host) {
+				spin_lock_irqsave(&dev->list_lock, flags);
+				list_for_each_entry(command, &dev->cmd_list,
+					list) {
+					if ((command != cmd) &&
+					(command->SCp.phase ==
+					AAC_OWNER_FIRMWARE)) {
+						active++;
+						break;
+					}
 				}
-			}
-			spin_unlock_irqrestore(&dev->list_lock, flags);
-			if (active)
-				break;
+				spin_unlock_irqrestore(&dev->list_lock, flags);
+				if (active)
+					break;
 
+			}
+			/*
+			 * We can exit If all the commands are complete
+			 */
+			if (active == 0)
+				return SUCCESS;
+			ssleep(1);
 		}
+		pr_err("%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
+
 		/*
-		 * We can exit If all the commands are complete
+		 * This adapter needs a blind reset, only do so for
+		 * Adapters that support a register, instead of a commanded,
+		 * reset.
 		 */
-		if (active == 0)
-			return SUCCESS;
-		ssleep(1);
+		if (((aac->supplement_adapter_info.SupportedOptions2 &
+			  AAC_OPTION_MU_RESET) ||
+			  (aac->supplement_adapter_info.SupportedOptions2 &
+			  AAC_OPTION_DOORBELL_RESET)) &&
+			  aac_check_reset &&
+			  ((aac_check_reset != 1) ||
+			   !(aac->supplement_adapter_info.SupportedOptions2 &
+			    AAC_OPTION_IGNORE_RESET))) {
+			/* Bypass wait for command quiesce */
+			aac_reset_adapter(aac, 2);
+		}
+		ret = SUCCESS;
 	}
-	printk(KERN_ERR "%s: SCSI bus appears hung\n", AAC_DRIVERNAME);
 	/*
-	 * This adapter needs a blind reset, only do so for Adapters that
-	 * support a register, instead of a commanded, reset.
+	 * Cause an immediate retry of the command with a ten second delay
+	 * after successful tur
 	 */
-	if (((aac->supplement_adapter_info.SupportedOptions2 &
-	  AAC_OPTION_MU_RESET) ||
-	  (aac->supplement_adapter_info.SupportedOptions2 &
-	  AAC_OPTION_DOORBELL_RESET)) &&
-	  aac_check_reset &&
-	  ((aac_check_reset != 1) ||
-	   !(aac->supplement_adapter_info.SupportedOptions2 &
-	    AAC_OPTION_IGNORE_RESET)))
-		aac_reset_adapter(aac, 2); /* Bypass wait for command quiesce */
-	return SUCCESS; /* Cause an immediate retry of the command with a ten second delay after successful tur */
+	return ret;
 }
 
 /**
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 946a010..1dd62a4 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -497,10 +497,35 @@ static int aac_src_deliver_message(struct fib *fib)
 			vector_no = fib->vector_no;
 
 		if (native_hba) {
-			((struct aac_hba_cmd_req *)fib->hw_fib_va)->reply_qid
-				= vector_no;
-			((struct aac_hba_cmd_req *)fib->hw_fib_va)->request_id
-				+= (vector_no << 16);
+			if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) {
+				struct aac_hba_tm_req *tm_req;
+
+				tm_req = (struct aac_hba_tm_req *)
+						fib->hw_fib_va;
+				if (tm_req->iu_type ==
+					HBA_IU_TYPE_SCSI_TM_REQ) {
+					((struct aac_hba_tm_req *)
+						fib->hw_fib_va)->reply_qid
+							= vector_no;
+					((struct aac_hba_tm_req *)
+						fib->hw_fib_va)->request_id
+							+= (vector_no << 16);
+				} else {
+					((struct aac_hba_reset_req *)
+						fib->hw_fib_va)->reply_qid
+							= vector_no;
+					((struct aac_hba_reset_req *)
+						fib->hw_fib_va)->request_id
+							+= (vector_no << 16);
+				}
+			} else {
+				((struct aac_hba_cmd_req *)
+					fib->hw_fib_va)->reply_qid
+						= vector_no;
+				((struct aac_hba_cmd_req *)
+					fib->hw_fib_va)->request_id
+						+= (vector_no << 16);
+			}
 		} else {
 			fib->hw_fib_va->header.Handle += (vector_no << 16);
 		}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 18/24] aacraid: VPD 83 type3 support
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (16 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 19/24] aacraid: Added new IWBR reset Raghava Aditya Renukunta
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

This patch adds support to retrieve the unique identifier data (VPD page
83 type3) for Logical drives created on SmartIOC 2000 products. In
addition  added a sysfs device structure to expose the id information.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c  | 180 ++++++++++++++++++++++++++---------------
 drivers/scsi/aacraid/aacraid.h |   2 +
 drivers/scsi/aacraid/linit.c   |  31 +++++++
 3 files changed, 150 insertions(+), 63 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index c76db95..74b9bb1 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -167,46 +167,56 @@ struct inquiry_data {
 };
 
 /* Added for VPD 0x83 */
-typedef struct {
-	u8 CodeSet:4;	/* VPD_CODE_SET */
-	u8 Reserved:4;
-	u8 IdentifierType:4;	/* VPD_IDENTIFIER_TYPE */
-	u8 Reserved2:4;
-	u8 Reserved3;
-	u8 IdentifierLength;
-	u8 VendId[8];
-	u8 ProductId[16];
-	u8 SerialNumber[8];	/* SN in ASCII */
-
-} TVPD_ID_Descriptor_Type_1;
+struct  tvpd_id_descriptor_type_1 {
+	u8 codeset:4;		/* VPD_CODE_SET */
+	u8 reserved:4;
+	u8 identifiertype:4;	/* VPD_IDENTIFIER_TYPE */
+	u8 reserved2:4;
+	u8 reserved3;
+	u8 identifierlength;
+	u8 venid[8];
+	u8 productid[16];
+	u8 serialnumber[8];	/* SN in ASCII */
 
-typedef struct {
-	u8 CodeSet:4;	/* VPD_CODE_SET */
-	u8 Reserved:4;
-	u8 IdentifierType:4;	/* VPD_IDENTIFIER_TYPE */
-	u8 Reserved2:4;
-	u8 Reserved3;
-	u8 IdentifierLength;
-	struct TEU64Id {
+};
+
+struct tvpd_id_descriptor_type_2 {
+	u8 codeset:4;		/* VPD_CODE_SET */
+	u8 reserved:4;
+	u8 identifiertype:4;	/* VPD_IDENTIFIER_TYPE */
+	u8 reserved2:4;
+	u8 reserved3;
+	u8 identifierlength;
+	struct teu64id {
 		u32 Serial;
 		 /* The serial number supposed to be 40 bits,
 		  * bit we only support 32, so make the last byte zero. */
-		u8 Reserved;
-		u8 VendId[3];
-	} EU64Id;
+		u8 reserved;
+		u8 venid[3];
+	} eu64id;
 
-} TVPD_ID_Descriptor_Type_2;
+};
 
-typedef struct {
+struct tvpd_id_descriptor_type_3 {
+	u8 codeset : 4;          /* VPD_CODE_SET */
+	u8 reserved : 4;
+	u8 identifiertype : 4;   /* VPD_IDENTIFIER_TYPE */
+	u8 reserved2 : 4;
+	u8 reserved3;
+	u8 identifierlength;
+	u8 Identifier[16];
+};
+
+struct tvpd_page83 {
 	u8 DeviceType:5;
 	u8 DeviceTypeQualifier:3;
 	u8 PageCode;
-	u8 Reserved;
+	u8 reserved;
 	u8 PageLength;
-	TVPD_ID_Descriptor_Type_1 IdDescriptorType1;
-	TVPD_ID_Descriptor_Type_2 IdDescriptorType2;
-
-} TVPD_Page83;
+	struct tvpd_id_descriptor_type_1 type1;
+	struct tvpd_id_descriptor_type_2 type2;
+	struct tvpd_id_descriptor_type_3 type3;
+};
 
 /*
  *              M O D U L E   G L O B A L S
@@ -613,6 +623,7 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
 	struct fsa_dev_info *fsa_dev_ptr;
 	int (*callback)(struct scsi_cmnd *);
 	struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context;
+	int i;
 
 
 	if (!aac_valid_context(scsicmd, fibptr))
@@ -635,6 +646,10 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
 				fsa_dev_ptr->block_size =
 					le32_to_cpu(dresp->mnt[0].fileinfo.bdevinfo.block_size);
 			}
+			for (i = 0; i < 16; i++)
+				fsa_dev_ptr->identifier[i] =
+					dresp->mnt[0].fileinfo.bdevinfo
+								.identifier[i];
 			fsa_dev_ptr->valid = 1;
 			/* sense_key holds the current state of the spin-up */
 			if (dresp->mnt[0].state & cpu_to_le32(FSCS_NOT_READY))
@@ -929,6 +944,28 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
 	inqstrcpy ("V1.0", str->prl);
 }
 
+static void build_vpd83_type3(struct tvpd_page83 *vpdpage83data,
+		struct aac_dev *dev, struct scsi_cmnd *scsicmd)
+{
+	int container;
+
+	vpdpage83data->type3.codeset = 1;
+	vpdpage83data->type3.identifiertype = 3;
+	vpdpage83data->type3.identifierlength = sizeof(vpdpage83data->type3)
+			- 4;
+
+	for (container = 0; container < dev->maximum_num_containers;
+			container++) {
+
+		if (scmd_id(scsicmd) == container) {
+			memcpy(vpdpage83data->type3.Identifier,
+					dev->fsa_dev[container].identifier,
+					16);
+			break;
+		}
+	}
+}
+
 static void get_container_serial_callback(void *context, struct fib * fibptr)
 {
 	struct aac_get_serial_resp * get_serial_reply;
@@ -946,39 +983,47 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
 		/*Check to see if it's for VPD 0x83 or 0x80 */
 		if (scsicmd->cmnd[2] == 0x83) {
 			/* vpd page 0x83 - Device Identification Page */
+			struct aac_dev *dev;
 			int i;
-			TVPD_Page83 VPDPage83Data;
+			struct tvpd_page83 vpdpage83data;
 
-			memset(((u8 *)&VPDPage83Data), 0,
-			       sizeof(VPDPage83Data));
+			dev = (struct aac_dev *)scsicmd->device->host->hostdata;
+
+			memset(((u8 *)&vpdpage83data), 0,
+			       sizeof(vpdpage83data));
 
 			/* DIRECT_ACCESS_DEVIC */
-			VPDPage83Data.DeviceType = 0;
+			vpdpage83data.DeviceType = 0;
 			/* DEVICE_CONNECTED */
-			VPDPage83Data.DeviceTypeQualifier = 0;
+			vpdpage83data.DeviceTypeQualifier = 0;
 			/* VPD_DEVICE_IDENTIFIERS */
-			VPDPage83Data.PageCode = 0x83;
-			VPDPage83Data.Reserved = 0;
-			VPDPage83Data.PageLength =
-				sizeof(VPDPage83Data.IdDescriptorType1) +
-				sizeof(VPDPage83Data.IdDescriptorType2);
+			vpdpage83data.PageCode = 0x83;
+			vpdpage83data.reserved = 0;
+			vpdpage83data.PageLength =
+				sizeof(vpdpage83data.type1) +
+				sizeof(vpdpage83data.type2);
+
+			/* VPD 83 Type 3 is not supported for ARC */
+			if (dev->sa_firmware)
+				vpdpage83data.PageLength +=
+				sizeof(vpdpage83data.type3);
 
 			/* T10 Vendor Identifier Field Format */
-			/* VpdCodeSetAscii */
-			VPDPage83Data.IdDescriptorType1.CodeSet = 2;
+			/* VpdcodesetAscii */
+			vpdpage83data.type1.codeset = 2;
 			/* VpdIdentifierTypeVendorId */
-			VPDPage83Data.IdDescriptorType1.IdentifierType = 1;
-			VPDPage83Data.IdDescriptorType1.IdentifierLength =
-				sizeof(VPDPage83Data.IdDescriptorType1) - 4;
+			vpdpage83data.type1.identifiertype = 1;
+			vpdpage83data.type1.identifierlength =
+				sizeof(vpdpage83data.type1) - 4;
 
 			/* "ADAPTEC " for adaptec */
-			memcpy(VPDPage83Data.IdDescriptorType1.VendId,
+			memcpy(vpdpage83data.type1.venid,
 				"ADAPTEC ",
-				sizeof(VPDPage83Data.IdDescriptorType1.VendId));
-			memcpy(VPDPage83Data.IdDescriptorType1.ProductId,
+				sizeof(vpdpage83data.type1.venid));
+			memcpy(vpdpage83data.type1.productid,
 				"ARRAY           ",
 				sizeof(
-				VPDPage83Data.IdDescriptorType1.ProductId));
+				vpdpage83data.type1.productid));
 
 			/* Convert to ascii based serial number.
 			 * The LSB is the the end.
@@ -987,32 +1032,41 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
 				u8 temp =
 					(u8)((get_serial_reply->uid >> ((7 - i) * 4)) & 0xF);
 				if (temp  > 0x9) {
-					VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
+					vpdpage83data.type1.serialnumber[i] =
 							'A' + (temp - 0xA);
 				} else {
-					VPDPage83Data.IdDescriptorType1.SerialNumber[i] =
+					vpdpage83data.type1.serialnumber[i] =
 							'0' + temp;
 				}
 			}
 
 			/* VpdCodeSetBinary */
-			VPDPage83Data.IdDescriptorType2.CodeSet = 1;
-			/* VpdIdentifierTypeEUI64 */
-			VPDPage83Data.IdDescriptorType2.IdentifierType = 2;
-			VPDPage83Data.IdDescriptorType2.IdentifierLength =
-				sizeof(VPDPage83Data.IdDescriptorType2) - 4;
+			vpdpage83data.type2.codeset = 1;
+			/* VpdidentifiertypeEUI64 */
+			vpdpage83data.type2.identifiertype = 2;
+			vpdpage83data.type2.identifierlength =
+				sizeof(vpdpage83data.type2) - 4;
 
-			VPDPage83Data.IdDescriptorType2.EU64Id.VendId[0] = 0xD0;
-			VPDPage83Data.IdDescriptorType2.EU64Id.VendId[1] = 0;
-			VPDPage83Data.IdDescriptorType2.EU64Id.VendId[2] = 0;
+			vpdpage83data.type2.eu64id.venid[0] = 0xD0;
+			vpdpage83data.type2.eu64id.venid[1] = 0;
+			vpdpage83data.type2.eu64id.venid[2] = 0;
 
-			VPDPage83Data.IdDescriptorType2.EU64Id.Serial =
+			vpdpage83data.type2.eu64id.Serial =
 							get_serial_reply->uid;
-			VPDPage83Data.IdDescriptorType2.EU64Id.Reserved = 0;
+			vpdpage83data.type2.eu64id.reserved = 0;
+
+			/*
+			 * VpdIdentifierTypeFCPHName
+			 * VPD 0x83 Type 3 not supported for ARC
+			 */
+			if (dev->sa_firmware) {
+				build_vpd83_type3(&vpdpage83data,
+						dev, scsicmd);
+			}
 
 			/* Move the inquiry data to the response buffer. */
-			scsi_sg_copy_from_buffer(scsicmd, &VPDPage83Data,
-						 sizeof(VPDPage83Data));
+			scsi_sg_copy_from_buffer(scsicmd, &vpdpage83data,
+						 sizeof(vpdpage83data));
 		} else {
 			/* It must be for VPD 0x80 */
 			char sp[13];
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 4b32ff1..07a60a3 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2110,6 +2110,8 @@ struct aac_fsinfo {
 
 struct  aac_blockdevinfo {
 	__le32	block_size;
+	__le32  logical_phys_map;
+	u8	identifier[16];
 };
 
 union aac_contentinfo {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9740a05..2ead5c7 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -548,8 +548,39 @@ static struct device_attribute aac_raid_level_attr = {
 	.show = aac_show_raid_level
 };
 
+static ssize_t aac_show_unique_id(struct device *dev,
+	     struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct aac_dev *aac = (struct aac_dev *)(sdev->host->hostdata);
+	unsigned char sn[16];
+
+	memset(sn, 0, sizeof(sn));
+
+	if (sdev_channel(sdev) == CONTAINER_CHANNEL)
+		memcpy(sn, aac->fsa_dev[sdev_id(sdev)].identifier, sizeof(sn));
+
+	return snprintf(buf, 16 * 2 + 2,
+		"%02X%02X%02X%02X%02X%02X%02X%02X %02X%02X%02X%02X%02X%02X%02X%02X\n",
+		sn[0], sn[1], sn[2], sn[3],
+		sn[4], sn[5], sn[6], sn[7],
+		sn[8], sn[9], sn[10], sn[11],
+		sn[12], sn[13], sn[14], sn[15]);
+}
+
+static struct device_attribute aac_unique_id_attr = {
+	.attr = {
+		.name = "unique_id",
+		.mode = 0444,
+	},
+	.show = aac_show_unique_id
+};
+
+
+
 static struct device_attribute *aac_dev_attrs[] = {
 	&aac_raid_level_attr,
+	&aac_unique_id_attr,
 	NULL,
 };
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 19/24] aacraid: Added new IWBR reset
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (17 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 18/24] aacraid: VPD 83 type3 support Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:39   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset Raghava Aditya Renukunta
                   ` (4 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added a new IWBR soft reset type, reworked the IOP reset interface for
a bit.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h |  15 +++--
 drivers/scsi/aacraid/commsup.c |  15 +++--
 drivers/scsi/aacraid/linit.c   |   8 ++-
 drivers/scsi/aacraid/rx.c      |  10 ++--
 drivers/scsi/aacraid/sa.c      |   2 +-
 drivers/scsi/aacraid/src.c     | 129 ++++++++++++++++++++++++++++++-----------
 6 files changed, 127 insertions(+), 52 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 07a60a3..e2df7a5 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -882,7 +882,7 @@ struct adapter_ops
 	void (*adapter_enable_int)(struct aac_dev *dev);
 	int  (*adapter_sync_cmd)(struct aac_dev *dev, u32 command, u32 p1, u32 p2, u32 p3, u32 p4, u32 p5, u32 p6, u32 *status, u32 *r1, u32 *r2, u32 *r3, u32 *r4);
 	int  (*adapter_check_health)(struct aac_dev *dev);
-	int  (*adapter_restart)(struct aac_dev *dev, int bled);
+	int  (*adapter_restart)(struct aac_dev *dev, int bled, u8 reset_type);
 	void (*adapter_start)(struct aac_dev *dev);
 	/* Transport operations */
 	int  (*adapter_ioremap)(struct aac_dev * dev, u32 size);
@@ -1661,8 +1661,8 @@ struct aac_dev
 #define aac_adapter_check_health(dev) \
 	(dev)->a_ops.adapter_check_health(dev)
 
-#define aac_adapter_restart(dev,bled) \
-	(dev)->a_ops.adapter_restart(dev,bled)
+#define aac_adapter_restart(dev, bled, reset_type) \
+	((dev)->a_ops.adapter_restart(dev, bled, reset_type))
 
 #define aac_adapter_start(dev) \
 	((dev)->a_ops.adapter_start(dev))
@@ -2337,6 +2337,13 @@ struct revision
 #define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
 #define FSACTL_GET_CONTAINERS			2131
 #define FSACTL_SEND_LARGE_FIB			CTL_CODE(2138, METHOD_BUFFERED)
+/* flags defined for IOP & HW SOFT RESET */
+#define HW_IOP_RESET				0x01
+#define HW_SOFT_RESET				0x02
+#define IOP_HWSOFT_RESET			(HW_IOP_RESET | HW_SOFT_RESET)
+/* HW Soft Reset register offset */
+#define IBW_SWR_OFFSET				0x4000
+#define SOFT_RESET_TIME			60
 
 
 struct aac_common
@@ -2573,7 +2580,7 @@ unsigned int aac_command_normal(struct aac_queue * q);
 unsigned int aac_intr_normal(struct aac_dev *dev, u32 Index,
 			int isAif, int isFastResponse,
 			struct hw_fib *aif_fib);
-int aac_reset_adapter(struct aac_dev * dev, int forced);
+int aac_reset_adapter(struct aac_dev *dev, int forced, u8 reset_type);
 int aac_check_health(struct aac_dev * dev);
 int aac_command_thread(void *data);
 int aac_close_fib_context(struct aac_dev * dev, struct aac_fib_context *fibctx);
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3aac5b1..3a98b1f 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -1455,7 +1455,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 	}
 }
 
-static int _aac_reset_adapter(struct aac_dev *aac, int forced)
+static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
 {
 	int index, quirks;
 	int retval;
@@ -1464,6 +1464,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
 	struct scsi_cmnd *command;
 	struct scsi_cmnd *command_list;
 	int jafo = 0;
+	int bled;
 
 	/*
 	 * Assumptions:
@@ -1488,7 +1489,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
 	 *	If a positive health, means in a known DEAD PANIC
 	 * state and the adapter could be reset to `try again'.
 	 */
-	retval = aac_adapter_restart(aac, forced ? 0 : aac_adapter_check_health(aac));
+	bled = forced ? 0 : aac_adapter_check_health(aac);
+	retval = aac_adapter_restart(aac, bled, reset_type);
 
 	if (retval)
 		goto out;
@@ -1598,7 +1600,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
 	return retval;
 }
 
-int aac_reset_adapter(struct aac_dev * aac, int forced)
+int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
 {
 	unsigned long flagv = 0;
 	int retval;
@@ -1651,7 +1653,9 @@ int aac_reset_adapter(struct aac_dev * aac, int forced)
 	if (forced < 2)
 		aac_send_shutdown(aac);
 	spin_lock_irqsave(host->host_lock, flagv);
-	retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset != 0) && (aac_check_reset != 1)));
+	retval = _aac_reset_adapter(aac,
+		forced ? forced : ((aac_check_reset != 0) &&
+		(aac_check_reset != 1)), reset_type);
 	spin_unlock_irqrestore(host->host_lock, flagv);
 
 	if ((forced < 2) && (retval == -ENODEV)) {
@@ -1814,7 +1818,8 @@ int aac_check_health(struct aac_dev * aac)
 	host = aac->scsi_host_ptr;
 	if (aac->thread->pid != current->pid)
 		spin_lock_irqsave(host->host_lock, flagv);
-	BlinkLED = _aac_reset_adapter(aac, aac_check_reset != 1);
+	BlinkLED = _aac_reset_adapter(aac,
+		aac_check_reset != 1, IOP_HWSOFT_RESET);
 	if (aac->thread->pid != current->pid)
 		spin_unlock_irqrestore(host->host_lock, flagv);
 	return BlinkLED;
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 2ead5c7..a0f26f6 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -561,7 +561,7 @@ static ssize_t aac_show_unique_id(struct device *dev,
 		memcpy(sn, aac->fsa_dev[sdev_id(sdev)].identifier, sizeof(sn));
 
 	return snprintf(buf, 16 * 2 + 2,
-		"%02X%02X%02X%02X%02X%02X%02X%02X %02X%02X%02X%02X%02X%02X%02X%02X\n",
+		"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
 		sn[0], sn[1], sn[2], sn[3],
 		sn[4], sn[5], sn[6], sn[7],
 		sn[8], sn[9], sn[10], sn[11],
@@ -891,7 +891,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 			   !(aac->supplement_adapter_info.SupportedOptions2 &
 			    AAC_OPTION_IGNORE_RESET))) {
 			/* Bypass wait for command quiesce */
-			aac_reset_adapter(aac, 2);
+			aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
 		}
 		ret = SUCCESS;
 	}
@@ -1162,7 +1162,9 @@ static ssize_t aac_store_reset_adapter(struct device *device,
 
 	if (!capable(CAP_SYS_ADMIN))
 		return retval;
-	retval = aac_reset_adapter((struct aac_dev*)class_to_shost(device)->hostdata, buf[0] == '!');
+	retval = aac_reset_adapter((struct aac_dev *)
+		class_to_shost(device)->hostdata,
+		buf[0] == '!', IOP_HWSOFT_RESET);
 	if (retval >= 0)
 		retval = count;
 	return retval;
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 67213b9..8287e09 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -470,7 +470,7 @@ static int aac_rx_ioremap(struct aac_dev * dev, u32 size)
 	return 0;
 }
 
-static int aac_rx_restart_adapter(struct aac_dev *dev, int bled)
+static int aac_rx_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
 {
 	u32 var = 0;
 
@@ -559,7 +559,7 @@ int _aac_rx_init(struct aac_dev *dev)
 	dev->a_ops.adapter_enable_int = aac_rx_disable_interrupt;
 	dev->OIMR = status = rx_readb (dev, MUnit.OIMR);
 	if ((((status & 0x0c) != 0x0c) || aac_reset_devices || reset_devices) &&
-	  !aac_rx_restart_adapter(dev, 0))
+	  !aac_rx_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
 		/* Make sure the Hardware FIFO is empty */
 		while ((++restart < 512) &&
 		  (rx_readl(dev, MUnit.OutboundQueue) != 0xFFFFFFFFL));
@@ -568,7 +568,8 @@ int _aac_rx_init(struct aac_dev *dev)
 	 */
 	status = rx_readl(dev, MUnit.OMRx[0]);
 	if (status & KERNEL_PANIC) {
-		if (aac_rx_restart_adapter(dev, aac_rx_check_health(dev)))
+		if (aac_rx_restart_adapter(dev,
+			aac_rx_check_health(dev), IOP_HWSOFT_RESET))
 			goto error_iounmap;
 		++restart;
 	}
@@ -606,7 +607,8 @@ int _aac_rx_init(struct aac_dev *dev)
 		  ((startup_timeout > 60)
 		    ? (startup_timeout - 60)
 		    : (startup_timeout / 2))))) {
-			if (likely(!aac_rx_restart_adapter(dev, aac_rx_check_health(dev))))
+			if (likely(!aac_rx_restart_adapter(dev,
+				aac_rx_check_health(dev), IOP_HWSOFT_RESET)))
 				start = jiffies;
 			++restart;
 		}
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index b8538e0..6124f1b 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -257,7 +257,7 @@ static void aac_sa_start_adapter(struct aac_dev *dev)
 			NULL, NULL, NULL, NULL, NULL);
 }
 
-static int aac_sa_restart_adapter(struct aac_dev *dev, int bled)
+static int aac_sa_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
 {
 	return -EINVAL;
 }
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 1dd62a4..874096e 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -656,44 +656,100 @@ static int aac_srcv_ioremap(struct aac_dev *dev, u32 size)
 	return 0;
 }
 
-static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
+static void aac_set_intx_mode(struct aac_dev *dev)
+{
+	if (dev->msi_enabled) {
+		aac_src_access_devreg(dev, AAC_ENABLE_INTX);
+		dev->msi_enabled = 0;
+		msleep(5000); /* Delay 5 seconds */
+	}
+}
+
+static void aac_send_iop_reset(struct aac_dev *dev, int bled)
 {
 	u32 var, reset_mask;
 
-	if (bled >= 0) {
-		if (bled)
-			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
+	bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
+				    0, 0, 0, 0, 0, 0, &var,
+				    &reset_mask, NULL, NULL, NULL);
+
+	if ((bled || var != 0x00000001) && !dev->doorbell_mask)
+		bled = -EINVAL;
+	else if (dev->doorbell_mask) {
+		reset_mask = dev->doorbell_mask;
+		bled = 0;
+		var = 0x00000001;
+	}
+
+	aac_set_intx_mode(dev);
+
+	if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
+	    AAC_OPTION_DOORBELL_RESET)) {
+		src_writel(dev, MUnit.IDR, reset_mask);
+	} else {
+		src_writel(dev, MUnit.IDR, 0x100);
+	}
+	msleep(30000);
+}
+
+static void aac_send_hardware_soft_reset(struct aac_dev *dev)
+{
+	u_int32_t val;
+
+	val = readl(((char *)(dev->base) + IBW_SWR_OFFSET));
+	val |= 0x01;
+	writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET));
+	msleep_interruptible(20000);
+}
+
+static int aac_src_restart_adapter(struct aac_dev *dev, int bled, u8 reset_type)
+{
+	unsigned long status, start;
+
+	if (bled < 0)
+		goto invalid_out;
+
+	if (bled)
+		pr_err("%s%d: adapter kernel panic'd %x.\n",
 				dev->name, dev->id, bled);
-		dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
-		bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
-			0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
-		if ((bled || (var != 0x00000001)) &&
-		    !dev->doorbell_mask)
-			return -EINVAL;
-		else if (dev->doorbell_mask) {
-			reset_mask = dev->doorbell_mask;
-			bled = 0;
-			var = 0x00000001;
-		}
 
-		if ((dev->pdev->device == PMC_DEVICE_S7 ||
-		    dev->pdev->device == PMC_DEVICE_S8 ||
-		    dev->pdev->device == PMC_DEVICE_S9) && dev->msi_enabled) {
-			aac_src_access_devreg(dev, AAC_ENABLE_INTX);
-			dev->msi_enabled = 0;
-			msleep(5000); /* Delay 5 seconds */
-		}
+	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 
-		if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
-		    AAC_OPTION_DOORBELL_RESET)) {
-			src_writel(dev, MUnit.IDR, reset_mask);
-			ssleep(45);
-		} else {
-			src_writel(dev, MUnit.IDR, 0x100);
-			ssleep(45);
+	switch (reset_type) {
+	case IOP_HWSOFT_RESET:
+		aac_send_iop_reset(dev, bled);
+		/*
+		 * Check to see if KERNEL_UP_AND_RUNNING
+		 * Wait for the adapter to be up and running.
+		 * If !KERNEL_UP_AND_RUNNING issue HW Soft Reset
+		 */
+		status = src_readl(dev, MUnit.OMR);
+		if (dev->sa_firmware
+		 && !(status & KERNEL_UP_AND_RUNNING)) {
+			start = jiffies;
+			do {
+				status = src_readl(dev, MUnit.OMR);
+				if (time_after(jiffies,
+				 start+HZ*SOFT_RESET_TIME)) {
+					aac_send_hardware_soft_reset(dev);
+					start = jiffies;
+				}
+			} while (!(status & KERNEL_UP_AND_RUNNING));
 		}
+		break;
+	case HW_SOFT_RESET:
+		if (dev->sa_firmware) {
+			aac_send_hardware_soft_reset(dev);
+			aac_set_intx_mode(dev);
+		}
+		break;
+	default:
+		aac_send_iop_reset(dev, bled);
+		break;
 	}
 
+invalid_out:
+
 	if (src_readl(dev, MUnit.OMR) & KERNEL_PANIC)
 		return -ENODEV;
 
@@ -748,14 +804,15 @@ int aac_src_init(struct aac_dev *dev)
 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 	if ((aac_reset_devices || reset_devices) &&
-		!aac_src_restart_adapter(dev, 0))
+		!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
 		++restart;
 	/*
 	 *	Check to see if the board panic'd while booting.
 	 */
 	status = src_readl(dev, MUnit.OMR);
 	if (status & KERNEL_PANIC) {
-		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
+		if (aac_src_restart_adapter(dev,
+			aac_src_check_health(dev), IOP_HWSOFT_RESET))
 			goto error_iounmap;
 		++restart;
 	}
@@ -796,7 +853,7 @@ int aac_src_init(struct aac_dev *dev)
 		    ? (startup_timeout - 60)
 		    : (startup_timeout / 2))))) {
 			if (likely(!aac_src_restart_adapter(dev,
-			    aac_src_check_health(dev))))
+				aac_src_check_health(dev), IOP_HWSOFT_RESET)))
 				start = jiffies;
 			++restart;
 		}
@@ -893,7 +950,7 @@ int aac_srcv_init(struct aac_dev *dev)
 	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
 	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
 	if ((aac_reset_devices || reset_devices) &&
-		!aac_src_restart_adapter(dev, 0))
+		!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET))
 		++restart;
 	/*
 	 *	Check to see if flash update is running.
@@ -922,7 +979,8 @@ int aac_srcv_init(struct aac_dev *dev)
 	 */
 	status = src_readl(dev, MUnit.OMR);
 	if (status & KERNEL_PANIC) {
-		if (aac_src_restart_adapter(dev, aac_src_check_health(dev)))
+		if (aac_src_restart_adapter(dev,
+			aac_src_check_health(dev), IOP_HWSOFT_RESET))
 			goto error_iounmap;
 		++restart;
 	}
@@ -961,7 +1019,8 @@ int aac_srcv_init(struct aac_dev *dev)
 		  ((startup_timeout > 60)
 		    ? (startup_timeout - 60)
 		    : (startup_timeout / 2))))) {
-			if (likely(!aac_src_restart_adapter(dev, aac_src_check_health(dev))))
+			if (likely(!aac_src_restart_adapter(dev,
+				aac_src_check_health(dev), IOP_HWSOFT_RESET)))
 				start = jiffies;
 			++restart;
 		}
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (18 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 19/24] aacraid: Added new IWBR reset Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:41   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl Raghava Aditya Renukunta
                   ` (3 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added a new ioctl interface to trigger an IOP or IWBR reset from ioctl.
Primary used by management utility to trigger resets.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h  |  1 +
 drivers/scsi/aacraid/commctrl.c | 19 +++++++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index e2df7a5..6b80a63 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2337,6 +2337,7 @@ struct revision
 #define FSACTL_FORCE_DELETE_DISK		CTL_CODE(2120, METHOD_NEITHER)
 #define FSACTL_GET_CONTAINERS			2131
 #define FSACTL_SEND_LARGE_FIB			CTL_CODE(2138, METHOD_BUFFERED)
+#define FSACTL_RESET_IOP			CTL_CODE(2140, METHOD_BUFFERED)
 /* flags defined for IOP & HW SOFT RESET */
 #define HW_IOP_RESET				0x01
 #define HW_SOFT_RESET				0x02
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index b2af77f..4b65b91 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -1011,7 +1011,22 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
 	}
 	return 0;
 }
+struct aac_reset_iop {
+	u8	reset_type;
+};
+
+static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg)
+{
+	struct aac_reset_iop reset;
+	int retval;
 
+	if (copy_from_user((void *)&reset, arg, sizeof(struct aac_reset_iop)))
+		return -EFAULT;
+
+	retval = aac_reset_adapter(dev, 0, reset.reset_type);
+	return retval;
+
+}
 
 int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
 {
@@ -1055,6 +1070,10 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
 	case FSACTL_GET_PCI_INFO:
 		status = aac_get_pci_info(dev,arg);
 		break;
+	case FSACTL_RESET_IOP:
+		status = aac_send_reset_adapter(dev, arg);
+		break;
+
 	default:
 		status = -ENOTTY;
 		break;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (19 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:43   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 22/24] aacraid: Update copyrights Raghava Aditya Renukunta
                   ` (2 subsequent siblings)
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added a new ioctl interface to retrieve the host device information.

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h  | 52 +++++++++++++++++++++++++++++++++++++++++
 drivers/scsi/aacraid/commctrl.c | 26 +++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 6b80a63..e14916e 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -2338,6 +2338,7 @@ struct revision
 #define FSACTL_GET_CONTAINERS			2131
 #define FSACTL_SEND_LARGE_FIB			CTL_CODE(2138, METHOD_BUFFERED)
 #define FSACTL_RESET_IOP			CTL_CODE(2140, METHOD_BUFFERED)
+#define FSACTL_GET_HBA_INFO			CTL_CODE(2150, METHOD_BUFFERED)
 /* flags defined for IOP & HW SOFT RESET */
 #define HW_IOP_RESET				0x01
 #define HW_SOFT_RESET				0x02
@@ -2377,6 +2378,57 @@ struct aac_common
 extern struct aac_common aac_config;
 
 /*
+ * This is for management ioctl purpose only.
+ */
+struct aac_hba_info {
+
+	u8	DriverName[50];
+	u8	AdapterNumber;
+	u8	SystemIoBusNumber;
+	u8	DeviceNumber;
+	u32	FunctionNumber;
+	u32	VendorID;
+	u32	DeviceID;
+	u32	SubVendorID;
+	u32	SubSystemID;
+	u32	MappedBaseAddressSize;
+	u32	BasePhysicalAddress_HighPart;
+	u32	BasePhysicalAddress_LowPart;
+
+	u32	MaxCommandSize;
+	u32	MaxFibSize;
+	u32	MaxScatterGatherFromOs;
+	u32	MaxScatterGatherToFw;
+	u32	MaxOutstandingFibs;
+
+	u32	QueueStartThreshold;
+	u32	QueueDumpThreshold;
+	u32	MaxIoSizeQueued;
+	u32	OutstandingIO;
+
+	u32	FirmwareBuildNumber;
+	u32	BIOSBuildNumber;
+	u32	DriverBuildNumber;
+	u32	SerialNumber_HighPart;
+	u32	SerialNumber_LowPart;
+	u32	SupportedOptions;
+	u32	FeatureBits;
+	u32	currentnumberPorts;
+
+	u8	NewCommInterface:1;
+	u8	NewCommandsSupported:1;
+	u8	DisablePassthrough:1;
+	u8	ExposeNonDasd:1;
+	u8	QueueAllowed:1;
+	u8	BLEDCheckEnabled:1;
+	u8	reserved1:1;
+	u8	reserted2:1;
+
+	u32	reserved3[10];
+
+};
+
+/*
  *	The following macro is used when sending and receiving FIBs. It is
  *	only used for debugging.
  */
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 4b65b91..9ade2b4 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -1011,6 +1011,29 @@ static int aac_get_pci_info(struct aac_dev* dev, void __user *arg)
 	}
 	return 0;
 }
+
+static int aac_get_hba_info(struct aac_dev *dev, void __user *arg)
+{
+	struct aac_hba_info hbainfo;
+
+	hbainfo.AdapterNumber		= (u8) dev->id;
+	hbainfo.SystemIoBusNumber	= dev->pdev->bus->number;
+	hbainfo.DeviceNumber		= (dev->pdev->devfn >> 3);
+	hbainfo.FunctionNumber		= (dev->pdev->devfn & 0x0007);
+
+	hbainfo.VendorID		= dev->pdev->vendor;
+	hbainfo.DeviceID		= dev->pdev->device;
+	hbainfo.SubVendorID		= dev->pdev->subsystem_vendor;
+	hbainfo.SubSystemID		= dev->pdev->subsystem_device;
+
+	if (copy_to_user(arg, &hbainfo, sizeof(struct aac_hba_info))) {
+		dprintk((KERN_DEBUG "aacraid: Could not copy hba info\n"));
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
 struct aac_reset_iop {
 	u8	reset_type;
 };
@@ -1070,6 +1093,9 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
 	case FSACTL_GET_PCI_INFO:
 		status = aac_get_pci_info(dev,arg);
 		break;
+	case FSACTL_GET_HBA_INFO:
+		status = aac_get_hba_info(dev, arg);
+		break;
 	case FSACTL_RESET_IOP:
 		status = aac_send_reset_adapter(dev, arg);
 		break;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 22/24] aacraid: Update copyrights
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (20 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:43   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 23/24] aacraid: Change Driver Version Prefix Raghava Aditya Renukunta
  2017-01-27 19:28 ` [PATCH V3 24/24] aacraid: update version Raghava Aditya Renukunta
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Added new copyright messages

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aachba.c   |  8 +++++++-
 drivers/scsi/aacraid/aacraid.h  | 32 ++++++++++++++++++++++++++++++++
 drivers/scsi/aacraid/commctrl.c |  3 ++-
 drivers/scsi/aacraid/comminit.c |  3 ++-
 drivers/scsi/aacraid/commsup.c  |  3 ++-
 drivers/scsi/aacraid/dpcsup.c   |  3 ++-
 drivers/scsi/aacraid/linit.c    |  3 ++-
 drivers/scsi/aacraid/nark.c     |  3 ++-
 drivers/scsi/aacraid/rkt.c      |  3 ++-
 drivers/scsi/aacraid/rx.c       |  3 ++-
 drivers/scsi/aacraid/sa.c       |  3 ++-
 drivers/scsi/aacraid/src.c      |  3 ++-
 12 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 74b9bb1..4205d93 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +23,11 @@
  * along with this program; see the file COPYING.  If not, write to
  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
+ * Module Name:
+ *  aachba.c
+ *
+ * Abstract: Contains Interfaces to manage IOs.
+ *
  */
 
 #include <linux/kernel.h>
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index e14916e..3835375 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1,3 +1,35 @@
+/*
+ *	Adaptec AAC series RAID controller driver
+ *	(c) Copyright 2001 Red Hat Inc.	<alan@redhat.com>
+ *
+ * based on the old aacraid driver that is..
+ * Adaptec aacraid device driver for Linux.
+ *
+ * Copyright (c) 2000-2010 Adaptec, Inc.
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Module Name:
+ *  aacraid.h
+ *
+ * Abstract: Contains all routines for control of the aacraid driver
+ *
+ */
+
 #ifndef _AACRAID_H_
 #define _AACRAID_H_
 #ifndef dprintk
diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c
index 9ade2b4..a704e8d 100644
--- a/drivers/scsi/aacraid/commctrl.c
+++ b/drivers/scsi/aacraid/commctrl.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 5aad018..d0c7724 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 3a98b1f..69d98b7 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c
index c426ea2..417ba34 100644
--- a/drivers/scsi/aacraid/dpcsup.c
+++ b/drivers/scsi/aacraid/dpcsup.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index a0f26f6..786776d 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/nark.c b/drivers/scsi/aacraid/nark.c
index 6c53b1d..c59074e 100644
--- a/drivers/scsi/aacraid/nark.c
+++ b/drivers/scsi/aacraid/nark.c
@@ -5,7 +5,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c
index 6dff8ad..a1bc5bb 100644
--- a/drivers/scsi/aacraid/rkt.c
+++ b/drivers/scsi/aacraid/rkt.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c
index 8287e09..0e69a80 100644
--- a/drivers/scsi/aacraid/rx.c
+++ b/drivers/scsi/aacraid/rx.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c
index 6124f1b..553922f 100644
--- a/drivers/scsi/aacraid/sa.c
+++ b/drivers/scsi/aacraid/sa.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c
index 874096e..46976a3 100644
--- a/drivers/scsi/aacraid/src.c
+++ b/drivers/scsi/aacraid/src.c
@@ -6,7 +6,8 @@
  * Adaptec aacraid device driver for Linux.
  *
  * Copyright (c) 2000-2010 Adaptec, Inc.
- *               2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *               2010-2015 PMC-Sierra, Inc. (aacraid@pmc-sierra.com)
+ *		 2016-2017 Microsemi Corp. (aacraid@microsemi.com)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 23/24] aacraid: Change Driver Version Prefix
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (21 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 22/24] aacraid: Update copyrights Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:44   ` Johannes Thumshirn
  2017-01-27 19:28 ` [PATCH V3 24/24] aacraid: update version Raghava Aditya Renukunta
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Change the aacraid driver prefix from 1.2-1 to 1.2.1

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/linit.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 786776d..5efdd18 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -58,7 +58,7 @@
 
 #include "aacraid.h"
 
-#define AAC_DRIVER_VERSION		"1.2-1"
+#define AAC_DRIVER_VERSION		"1.2.1"
 #ifndef AAC_DRIVER_BRANCH
 #define AAC_DRIVER_BRANCH		""
 #endif
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* [PATCH V3 24/24] aacraid: update version
  2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
                   ` (22 preceding siblings ...)
  2017-01-27 19:28 ` [PATCH V3 23/24] aacraid: Change Driver Version Prefix Raghava Aditya Renukunta
@ 2017-01-27 19:28 ` Raghava Aditya Renukunta
  2017-01-30 11:44   ` Johannes Thumshirn
  23 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-27 19:28 UTC (permalink / raw)
  To: jejb, martin.petersen, linux-scsi
  Cc: David.Carroll, Gana.Sridaran, Scott.Benesh

Update the driver version to 50740

Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>

---
Changes in  V2:
None

Changes in  V3:
None

 drivers/scsi/aacraid/aacraid.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 3835375..9a3b510 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -97,8 +97,8 @@ enum {
 #define	PMC_GLOBAL_INT_BIT0		0x00000001
 
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 41066
-# define AAC_DRIVER_BRANCH "-ms"
+# define AAC_DRIVER_BUILD 50740
+# define AAC_DRIVER_BRANCH "-custom"
 #endif
 #define MAXIMUM_NUM_CONTAINERS	32
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 03/24] aacraid: added support for init_struct_8
  2017-01-27 19:28 ` [PATCH V3 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
@ 2017-01-30  9:15   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:15 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:32AM -0800, Raghava Aditya Renukunta wrote:
> This  patch lays the groundwork for supporting the new HBA-1000 controller
> family.A new INIT structure INIT_STRUCT_8 has been added which allows for a
> variable size for MSI-x vectors among other things,  and is used for both
> Series-8, HBA-1000 and SmartIOC-2000.
> 
> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 04/24] aacraid: Added sa firmware support
  2017-01-27 19:28 ` [PATCH V3 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
@ 2017-01-30  9:23   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:23 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:33AM -0800, Raghava Aditya Renukunta wrote:
> sa_firmware adds the capability to differentiate the new SmartIOC family
> of adapters from the series 8 and below.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 05/24] aacraid: Retrieve and update the device types
  2017-01-27 19:28 ` [PATCH V3 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
@ 2017-01-30  9:35   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:35 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:34AM -0800, Raghava Aditya Renukunta wrote:
> This patch adds support to retrieve the type of each adapter connected
> device. Applicable to HBA1000 and SmartIOC2000 products
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 06/24] aacraid: Reworked scsi command submission path
  2017-01-27 19:28 ` [PATCH V3 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
@ 2017-01-30  9:38   ` Johannes Thumshirn
  2017-01-30 20:17     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:38 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:35AM -0800, Raghava Aditya Renukunta wrote:
> Moved the READ and WRITE switch cases to the top. Added a  default
> case to the switch case and replaced duplicate scsi result value with a
> macro.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

I really whished this one had a better commit message (not only explaining
what you've changes but also why you did it).

But if this is the only issue there's hardly a reason to repost.

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 08/24] aacraid: Added support for response path
  2017-01-27 19:28 ` [PATCH V3 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
@ 2017-01-30  9:50   ` Johannes Thumshirn
  2017-01-30 20:16     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:50 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:37AM -0800, Raghava Aditya Renukunta wrote:
> This patch enables the driver to actually process the I/O, or srb replies
> from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events.
> 
> Signed-off-by: Raghava Aditya Renukunta <raghavaaditya.renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Sorry for not completely reviewing the patchset before you reposted.

> @@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev)
>  
>  	if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
>  		maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
> -	fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) * maximum_num_containers,
> -			GFP_KERNEL);
> -	if (!fsa_dev_ptr)
> -		return -ENOMEM;
> +	if ((dev->fsa_dev == NULL) ||
> +		(dev->maximum_num_containers != maximum_num_containers)) {
> +
> +		fsa_dev_ptr = dev->fsa_dev;

Comparison has precedence over logical OR. See
http://en.cppreference.com/w/c/language/operator_precedence


>  
> -	dev->fsa_dev = fsa_dev_ptr;
> -	dev->maximum_num_containers = maximum_num_containers;
> +		dev->fsa_dev = kzalloc(sizeof(*fsa_dev_ptr) *
> +				maximum_num_containers,	GFP_KERNEL);

kcalloc()?

[...]


> @@ -251,8 +250,9 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
>  	BUG_ON(fibptr == NULL);
>  	dev = fibptr->dev;
>  
> -	if (fibptr->hw_fib_va->header.XferState &
> -	    cpu_to_le32(NoMoreAifDataAvailable)) {
> +	if ((fibptr->hw_fib_va->header.XferState &
> +	    cpu_to_le32(NoMoreAifDataAvailable)) ||
> +		dev->sa_firmware) {

Again unnecessary parenthesis.

>  		aac_fib_complete(fibptr);
>  		aac_fib_free(fibptr);
>  		return;
> @@ -282,8 +282,8 @@ static void aac_aif_callback(void *context, struct fib * fibptr)
>   *	know there is a response on our normal priority queue. We will pull off
>   *	all QE there are and wake up all the waiters before exiting.
>   */
> -unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
> -			int isAif, int isFastResponse, struct hw_fib *aif_fib)
> +unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
> +	int isFastResponse, struct hw_fib *aif_fib)

Isn't this exactly the same but now with broken indent?

[...]

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 09/24] aacraid: Added support for read medium error
  2017-01-27 19:28 ` [PATCH V3 09/24] aacraid: Added support for read medium error Raghava Aditya Renukunta
@ 2017-01-30  9:55   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30  9:55 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:38AM -0800, Raghava Aditya Renukunta wrote:
> This patch processes Raw IO read medium errors.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 10/24] aacraid: Reworked aac_command_thread
  2017-01-27 19:28 ` [PATCH V3 10/24] aacraid: Reworked aac_command_thread Raghava Aditya Renukunta
@ 2017-01-30 10:11   ` Johannes Thumshirn
  2017-01-30 20:11     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 10:11 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:39AM -0800, Raghava Aditya Renukunta wrote:
> Reworked aac_command_thread into aac_process_events
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Wow, thanks for factoring this out.

> +static void aac_process_events(struct aac_dev *dev)
> +{
> +	struct hw_fib *hw_fib, *hw_newfib;
> +	struct fib *fib, *newfib;
> +	struct aac_fib_context *fibctx;
> +	unsigned long flags;
> +	spinlock_t *t_lock;
> +

	t_lock = dev->queues->queue[HostNormCmdQueue].lock;
	spin_lock_irqsave(t_lock, flags);

> +	spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);
> +	while (!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {
> +		struct list_head *entry;
> +		struct aac_aifcmd *aifcmd;
> +		u32 time_now, time_last;
> +		unsigned long flagv;
> +		unsigned int  num;
> +		struct hw_fib **hw_fib_pool, **hw_fib_p;
> +		struct fib **fib_pool, **fib_p;
> +
> +		set_current_state(TASK_RUNNING);
> +
> +		entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
> +		list_del(entry);
> +
> +
> +		t_lock = dev->queues->queue[HostNormCmdQueue].lock;
> +		spin_unlock_irqrestore(t_lock, flags);
> +
> +		fib = list_entry(entry, struct fib, fiblink);
> +		hw_fib = fib->hw_fib_va;
> +		/*
> +		 *	We will process the FIB here or pass it to a
> +		 *	worker thread that is TBD. We Really can't
> +		 *	do anything at this point since we don't have
> +		 *	anything defined for this thread to do.
> +		 */
> +		memset(fib, 0, sizeof(struct fib));
> +		fib->type = FSAFS_NTC_FIB_CONTEXT;
> +		fib->size = sizeof(struct fib);
> +		fib->hw_fib_va = hw_fib;
> +		fib->data = hw_fib->data;
> +		fib->dev = dev;
> +		/*
> +		 *	We only handle AifRequest fibs from the adapter.
> +		 */
> +
> +		aifcmd = (struct aac_aifcmd *) hw_fib->data;
> +		if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
> +			/* Handle Driver Notify Events */
> +			aac_handle_aif(dev, fib);
> +			*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> +			aac_fib_adapter_complete(fib, (u16)sizeof(u32));
> +			continue;
> +		}
> +		/*
> +		 * The u32 here is important and intended. We are using
> +		 * 32bit wrapping time to fit the adapter field
> +		 */
> +
> +
> +		/* Sniff events */
> +		if ((aifcmd->command ==	cpu_to_le32(AifCmdEventNotify)) ||
> +				(aifcmd->command ==
> +				cpu_to_le32(AifCmdJobProgress))) {

Parenthesis and indentation.

> +			aac_handle_aif(dev, fib);
> +		}
> +
> +		time_now = jiffies/HZ;
> +
> +		/*
> +		 * Warning: no sleep allowed while
> +		 * holding spinlock. We take the estimate
> +		 * and pre-allocate a set of fibs outside the
> +		 * lock.
> +		 */
> +		num = le32_to_cpu(dev->init->r7.adapter_fibs_size)
> +				/ sizeof(struct hw_fib); /* some extra */
> +		spin_lock_irqsave(&dev->fib_lock, flagv);
> +		entry = dev->fib_list.next;
> +		while (entry != &dev->fib_list) {
> +			entry = entry->next;
> +			++num;
> +		}
> +		spin_unlock_irqrestore(&dev->fib_lock, flagv);

Bonus points for getting the estimation of the fibs into an own function. From
the start of the comment till the spin_unlock().

> +		hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *),
> +						GFP_KERNEL);
> +		fib_pool = kmalloc_array(num, sizeof(struct fib *),
> +						GFP_KERNEL);
> +		if (num	&& fib_pool && hw_fib_pool) {

Ditto for the following block (this would have the benefit of describing what
the block does).

> +			hw_fib_p = hw_fib_pool;
> +			fib_p = fib_pool;
> +			while (hw_fib_p < &hw_fib_pool[num]) {
> +				*(hw_fib_p) = kmalloc(sizeof(struct hw_fib),
> +						GFP_KERNEL);
> +				if (!(*(hw_fib_p++))) {
> +					--hw_fib_p;
> +					break;
> +				}
> +				*(fib_p) = kmalloc(sizeof(struct fib),
> +						GFP_KERNEL);
> +				if (!(*(fib_p++))) {
> +					kfree(*(--hw_fib_p));
> +					break;
> +				}
> +			}
> +			num = hw_fib_p - hw_fib_pool;
> +			if (!num) {
> +				kfree(fib_pool);
> +				fib_pool = NULL;
> +				kfree(hw_fib_pool);
> +				hw_fib_pool = NULL;
> +				continue;
> +			}
> +		} else {
> +			kfree(hw_fib_pool);
> +			hw_fib_pool = NULL;
> +			kfree(fib_pool);
> +			fib_pool = NULL;
> +		}

And for either everything under the fib_lock or the while loop. 

> +		spin_lock_irqsave(&dev->fib_lock, flagv);
> +		entry = dev->fib_list.next;
> +		/*
> +		 * For each Context that is on the
> +		 * fibctxList, make a copy of the
> +		 * fib, and then set the event to wake up the
> +		 * thread that is waiting for it.
> +		 */
> +		hw_fib_p = hw_fib_pool;
> +		fib_p = fib_pool;
> +		while (entry != &dev->fib_list) {
> +			/*
> +			 * Extract the fibctx
> +			 */
> +			fibctx = list_entry(entry, struct aac_fib_context,
> +					next);
> +			/*
> +			 * Check if the queue is getting
> +			 * backlogged
> +			 */
> +			if (fibctx->count > 20) {
> +				/*
> +				 * It's *not* jiffies folks,
> +				 * but jiffies / HZ so do not
> +				 * panic ...
> +				 */
> +				time_last = fibctx->jiffies;
> +				/*
> +				 * Has it been > 2 minutes
> +				 * since the last read off
> +				 * the queue?
> +				 */
> +				if ((time_now - time_last) > aif_timeout) {
> +					entry = entry->next;
> +					aac_close_fib_context(dev, fibctx);
> +					continue;
> +				}
> +			}
> +			/*
> +			 * Warning: no sleep allowed while
> +			 * holding spinlock
> +			 */
> +			if (hw_fib_p < &hw_fib_pool[num]) {
> +				hw_newfib = *hw_fib_p;
> +				*(hw_fib_p++) = NULL;
> +				newfib = *fib_p;
> +				*(fib_p++) = NULL;
> +				/*
> +				 * Make the copy of the FIB
> +				 */
> +				memcpy(hw_newfib, hw_fib,
> +					sizeof(struct hw_fib));
> +				memcpy(newfib, fib, sizeof(struct fib));
> +				newfib->hw_fib_va = hw_newfib;
> +				/*
> +				 * Put the FIB onto the
> +				 * fibctx's fibs
> +				 */
> +				list_add_tail(&newfib->fiblink,
> +					&fibctx->fib_list);
> +				fibctx->count++;
> +				/*
> +				 * Set the event to wake up the
> +				 * thread that is waiting.
> +				 */
> +				up(&fibctx->wait_sem);
> +			} else {
> +				pr_warn("aifd: didn't allocate NewFib.\n");
> +			}
> +			entry = entry->next;
> +		}
> +		/*
> +		 *	Set the status of this FIB
> +		 */
> +		*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> +		aac_fib_adapter_complete(fib, sizeof(u32));
> +		spin_unlock_irqrestore(&dev->fib_lock, flagv);
> +		/* Free up the remaining resources */
> +		hw_fib_p = hw_fib_pool;
> +		fib_p = fib_pool;
> +		while (hw_fib_p < &hw_fib_pool[num]) {
> +			kfree(*hw_fib_p);
> +			kfree(*fib_p);
> +			++fib_p;
> +			++hw_fib_p;
> +		}
> +		kfree(hw_fib_pool);
> +		kfree(fib_pool);
> +		kfree(fib);
> +		spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock,
> +				flags);
> +	}
> +	/*
> +	 *	There are no more AIF's
> +	 */
> +	spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock,
> +			flags);
> +}

[...]

Thanks, 
this change is highly appreciated by me

	Johannes

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 11/24] aacraid: Added support for periodic wellness sync
  2017-01-27 19:28 ` [PATCH V3 11/24] aacraid: Added support for periodic wellness sync Raghava Aditya Renukunta
@ 2017-01-30 10:27   ` Johannes Thumshirn
  2017-01-30 20:07     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 10:27 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:40AM -0800, Raghava Aditya Renukunta wrote:
> This patch adds a new functions that periodically sync the time of host
> to the adapter. In addition also informs the adapter that the driver is
> alive and kicking. Only applicable to the HBA1000 and SMARTIOC2000.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---
> Changes in  V2:
> None
> 
> Changes in  V3:
> None
> 
>  drivers/scsi/aacraid/aacraid.h |   3 +
>  drivers/scsi/aacraid/commsup.c | 176 +++++++++++++++++++++++++++++++++--------
>  2 files changed, 148 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> index b54c1bf..05884e6 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -88,6 +88,9 @@ enum {
>  #define AAC_MAX_NATIVE_SIZE		2048
>  
>  #define CISS_REPORT_PHYSICAL_LUNS	0xc3
> +#define WRITE_HOST_WELLNESS		0xa5
> +#define BMIC_IN			0x26
> +#define BMIC_OUT			0x27
>  
>  struct aac_ciss_phys_luns_resp {
>  	u8	list_length[4];		/* LUN list length (N-7, big endian) */
> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index 346c1c0..0c009f1 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -43,6 +43,7 @@
>  #include <linux/kthread.h>
>  #include <linux/interrupt.h>
>  #include <linux/semaphore.h>
> +#include <linux/bcd.h>
>  #include <scsi/scsi.h>
>  #include <scsi/scsi_host.h>
>  #include <scsi/scsi_device.h>
> @@ -1946,6 +1947,143 @@ static void aac_process_events(struct aac_dev *dev)
>  			flags);
>  }
>  
> +static int aac_send_wellness_command(struct aac_dev *dev, char *wellness_str,
> +							u32 datasize)
> +{
> +	struct aac_srb *srbcmd;
> +	struct sgmap64 *sg64;
> +	dma_addr_t addr;
> +	char *dma_buf;
> +	struct fib *fibptr;
> +	int ret = -ENOMEM;
> +
> +	fibptr = aac_fib_alloc(dev);
> +	if (fibptr) {
> +		aac_fib_init(fibptr);
> +
> +		dma_buf = pci_alloc_consistent(dev->pdev, datasize, &addr);
> +		if (dma_buf != NULL) {

if (!dma_buf)
	return -ENOMEM;

It makes the code flow more obvious and saves you a level of indent.

> +			u32 vbus, vid;
> +
> +			vbus = (u32)le16_to_cpu(
> +				dev->supplement_adapter_info.VirtDeviceBus);
> +			vid = (u32)le16_to_cpu(
> +				dev->supplement_adapter_info.VirtDeviceTarget);
> +
> +			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_DataOut);
> +			srbcmd->timeout = cpu_to_le32(10);
> +			srbcmd->retry_limit = 0;
> +			srbcmd->cdb_size = cpu_to_le32(12);
> +			srbcmd->count = cpu_to_le32(datasize);
> +
> +			memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
> +			srbcmd->cdb[0] = BMIC_OUT;
> +			srbcmd->cdb[6] = WRITE_HOST_WELLNESS;
> +			memcpy(dma_buf, (char *)wellness_str, datasize);
> +
> +			sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
> +			sg64->sg[0].count = cpu_to_le32(datasize);
> +
> +			ret = aac_fib_send(ScsiPortCommand64, fibptr,
> +				sizeof(struct aac_srb), FsaNormal,
> +				1, 1, NULL, NULL);
> +
> +			pci_free_consistent(dev->pdev, datasize,
> +						(void *)dma_buf, addr);
> +	}
> +
> +		/*
> +		 * Do not set XferState to zero unless
> +		 * receives a response from F/W
> +		 */
> +		if (ret >= 0)
> +			aac_fib_complete(fibptr);
> +
> +		/*
> +		 * FIB should be freed only after
> +		 * getting the response from the F/W
> +		 */
> +		if (ret != -ERESTARTSYS)
> +			aac_fib_free(fibptr);
> +	}

Not sure if it's my mailclient, but indentation looks a bit odd here.

> +
> +	return ret;
> +}
> +
> +int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)
> +{
> +	int ret = -ENOMEM;
> +	struct fib *fibptr;
> +
> +	/*
> +	 *  This whole block needs to be rewritten with helpers
> +	 *  Changing tabs to a single space should not be allowed!!
> +	 */
> +
> +	if (dev->sa_firmware) {
> +		struct tm cur_tm;
> +		char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ";
> +		u32 datasize = sizeof(wellness_str);
> +		unsigned long local_time;
> +
> +		local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60));
> +		time_to_tm(local_time, 0, &cur_tm);
> +		cur_tm.tm_mon += 1;
> +		cur_tm.tm_year += 1900;
> +		wellness_str[8] = bin2bcd(cur_tm.tm_hour);
> +		wellness_str[9] = bin2bcd(cur_tm.tm_min);
> +		wellness_str[10] = bin2bcd(cur_tm.tm_sec);
> +		wellness_str[12] = bin2bcd(cur_tm.tm_mon);
> +		wellness_str[13] = bin2bcd(cur_tm.tm_mday);
> +		wellness_str[14] = bin2bcd(cur_tm.tm_year / 100);
> +		wellness_str[15] = bin2bcd(cur_tm.tm_year % 100);
> +
> +		ret = aac_send_wellness_command(dev, wellness_str, datasize);
> +
> +		return ret;
> +	}
> +
> +	fibptr = aac_fib_alloc(dev);
> +	if (fibptr) {

Same here.

> +		__le32 *info;
> +
> +		aac_fib_init(fibptr);
> +		info = (__le32 *)fib_data(fibptr);
> +		*info = cpu_to_le32(now->tv_sec);
> +		ret = aac_fib_send(
> +			SendHostTime, fibptr,
> +			sizeof(*info), FsaNormal,
> +			1, 1, NULL, NULL);
> +
> +		/*
> +		 * Do not set XferState to zero unless
> +		 * receives a response from F/W
> +		 */
> +		if (ret >= 0)
> +			aac_fib_complete(fibptr);
> +
> +		/*
> +		 * FIB should be freed only after
> +		 * getting the response from the F/W
> +		 */
> +		if (ret != -ERESTARTSYS)
> +			aac_fib_free(fibptr);
> +	}
> +
> +	return ret;
> +}
> +
>  /**
>   *	aac_command_thread	-	command processing thread
>   *	@dev: Adapter to monitor
> @@ -2001,7 +2139,7 @@ int aac_command_thread(void *data)
>  
>  			/* Don't even try to talk to adapter if its sick */
>  			ret = aac_check_health(dev);
> -			if (!ret && !dev->queues)
> +			if (!dev->queues)
>  				break;
>  			next_check_jiffies = jiffies
>  					   + ((long)(unsigned)check_interval)
> @@ -2014,36 +2152,12 @@ int aac_command_thread(void *data)
>  				difference = (((1000000 - now.tv_usec) * HZ)
>  				  + 500000) / 1000000;
>  			else if (ret == 0) {
> -				struct fib *fibptr;
> -
> -				if ((fibptr = aac_fib_alloc(dev))) {
> -					int status;
> -					__le32 *info;
> -
> -					aac_fib_init(fibptr);
> -
> -					info = (__le32 *) fib_data(fibptr);
> -					if (now.tv_usec > 500000)
> -						++now.tv_sec;
> -
> -					*info = cpu_to_le32(now.tv_sec);
> -
> -					status = aac_fib_send(SendHostTime,
> -						fibptr,
> -						sizeof(*info),
> -						FsaNormal,
> -						1, 1,
> -						NULL,
> -						NULL);
> -					/* Do not set XferState to zero unless
> -					 * receives a response from F/W */
> -					if (status >= 0)
> -						aac_fib_complete(fibptr);
> -					/* FIB should be freed only after
> -					 * getting the response from the F/W */
> -					if (status != -ERESTARTSYS)
> -						aac_fib_free(fibptr);
> -				}
> +
> +				if (now.tv_usec > 500000)
> +					++now.tv_sec;
> +
> +				ret = aac_send_hosttime(dev, &now);
> +
>  				difference = (long)(unsigned)update_interval*HZ;
>  			} else {
>  				/* retry shortly */
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW
  2017-01-27 19:28 ` [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW Raghava Aditya Renukunta
@ 2017-01-30 10:31   ` Johannes Thumshirn
  2017-01-30 20:05     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 10:31 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:41AM -0800, Raghava Aditya Renukunta wrote:
> Retrieved queue depth from fw and saved it for future use.
> Only applicable for HBA1000 drives.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---
> Changes in  V2:
> None
> 
> Changes in  V3:
> None
> 
>  drivers/scsi/aacraid/aachba.c  | 84 ++++++++++++++++++++++++++++++++++++++++-
>  drivers/scsi/aacraid/aacraid.h | 85 +++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 167 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
> index e441a54..c34686f 100644
> --- a/drivers/scsi/aacraid/aachba.c
> +++ b/drivers/scsi/aacraid/aachba.c
> @@ -1516,6 +1516,83 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
>  	return aac_scsi_32(fib, cmd);
>  }
>  
> +int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
> +{
> +	struct fib *fibptr;
> +	int rcode = -1;
> +	u16 fibsize, datasize;
> +	struct aac_srb *srbcmd;
> +	struct sgmap64 *sg64;
> +	struct aac_ciss_identify_pd *identify_resp;
> +	dma_addr_t addr;
> +	u32 vbus, vid;
> +	u16 temp;
> +
> +	fibptr = aac_fib_alloc(dev);
> +	if (!fibptr)
> +		return -ENOMEM;
> +
> +	temp = AAC_MAX_LUN + target;
> +
> +	fibsize = sizeof(struct aac_srb) -
> +		sizeof(struct sgentry) + sizeof(struct sgentry64);
> +	datasize = sizeof(struct aac_ciss_identify_pd);
> +
> +	identify_resp = (struct aac_ciss_identify_pd *)
> +		pci_alloc_consistent(dev->pdev, datasize, &addr);

Please don't cast void pointers.

> +
> +	if (identify_resp != NULL) {

if (!identify_resp)
	goto free_fib_ptr;

> +		vbus = (u32)le16_to_cpu(
> +			dev->supplement_adapter_info.VirtDeviceBus);
> +		vid = (u32)le16_to_cpu(
> +			dev->supplement_adapter_info.VirtDeviceTarget);
> +
> +		aac_fib_init(fibptr);
> +		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);
> +
> +		memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
> +		srbcmd->cdb[0] = 0x26;
> +		srbcmd->cdb[2] = (u8)(temp & 0x00FF);
> +
> +		srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
> +
> +		sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
> +		sg64->sg[0].count = cpu_to_le32(datasize);
> +
> +		rcode = aac_fib_send(ScsiPortCommand64,
> +			fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL);
> +
> +		if (identify_resp->current_queue_depth_limit <= 0 ||
> +			identify_resp->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;
> +
> +		pci_free_consistent(dev->pdev, datasize,
> +					(void *)identify_resp, addr);
> +
> +		aac_fib_complete(fibptr);
> +	}

free_fib_ptr:

> +
> +	aac_fib_free(fibptr);
> +
> +	return rcode;
> +}
> +
>  /**
>   *	aac_update hba_map()-	update current hba map with data from FW
>   *	@dev:	aac_dev structure
> @@ -1565,6 +1642,9 @@ 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)
> +			dev->hba_map[bus][target].qd_limit = 32;
> +
>  update_devtype:
>  		dev->hba_map[bus][target].devtype = devtype;
>  	}
> @@ -1711,8 +1791,10 @@ int aac_get_adapter_info(struct aac_dev* dev)
>  
>  	/* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
>  	for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
> -		for (target = 0; target < AAC_MAX_TARGETS; target++)
> +		for (target = 0; target < AAC_MAX_TARGETS; target++) {
>  			dev->hba_map[bus][target].devtype = 0;
> +			dev->hba_map[bus][target].qd_limit = 0;
> +		}
>  	}
>  
>  	/*
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> index 05884e6..e541394 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -74,7 +74,7 @@ enum {
>  #define AAC_NUM_IO_FIB		(1024 - AAC_NUM_MGT_FIB)
>  #define AAC_NUM_FIB		(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
>  
> -#define AAC_MAX_LUN		(8)
> +#define AAC_MAX_LUN		(256)
>  
>  #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
>  #define AAC_MAX_32BIT_SGBCOUNT	((unsigned short)256)
> @@ -89,6 +89,7 @@ enum {
>  
>  #define CISS_REPORT_PHYSICAL_LUNS	0xc3
>  #define WRITE_HOST_WELLNESS		0xa5
> +#define CISS_IDENTIFY_PHYSICAL_DEVICE	0x15
>  #define BMIC_IN			0x26
>  #define BMIC_OUT			0x27
>  
> @@ -110,6 +111,86 @@ struct aac_ciss_phys_luns_resp {
>   */
>  #define AAC_MAX_HRRQ		64
>  
> +#pragma pack(1)
> +
> +struct aac_ciss_identify_pd {

[...]

> +};
> +
> +#pragma pack()

I'd prefer '}; __packed' over #pragma pack(1) .. #pragma pack()

[...]


-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 13/24] aacraid: Added support to set QD of attached drives
  2017-01-27 19:28 ` [PATCH V3 13/24] aacraid: Added support to set QD of attached drives Raghava Aditya Renukunta
@ 2017-01-30 10:39   ` Johannes Thumshirn
  2017-01-30 20:01     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 10:39 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:42AM -0800, Raghava Aditya Renukunta wrote:
> Added support to set qd of drives in slave_configure.This only works for
> HBA1000 attached drives.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

[...]

> @@ -428,34 +441,41 @@ static int aac_slave_configure(struct scsi_device *sdev)
>  		 */
>  		if (sdev->request_queue->rq_timeout < (45 * HZ))
>  			blk_queue_rq_timeout(sdev->request_queue, 45*HZ);
> -		for (cid = 0; cid < aac->maximum_num_containers; ++cid)
> -			if (aac->fsa_dev[cid].valid)
> -				++num_lsu;
> -		__shost_for_each_device(dev, host) {
> -			if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
> +		if (!is_native_device) {
> +			for (cid = 0; cid < aac->maximum_num_containers; ++cid)
> +				if (aac->fsa_dev[cid].valid)
> +					++num_lsu;
> +			__shost_for_each_device(dev, host) {
> +				if (dev->tagged_supported &&
> +					(dev->type == TYPE_DISK) &&
>  					(!aac->raid_scsi_mode ||
> -						(sdev_channel(sdev) != 2)) &&
> +					(sdev_channel(sdev) != 2)) &&
>  					!dev->no_uld_attach) {
> -				if ((sdev_channel(dev) != CONTAINER_CHANNEL)
> -				 || !aac->fsa_dev[sdev_id(dev)].valid)
> -					++num_lsu;
> -			} else
> -				++num_one;
> +					if ((sdev_channel(dev)
> +						!= CONTAINER_CHANNEL)
> +					 || !aac->fsa_dev[sdev_id(dev)].valid) {
> +						++num_lsu;
> +					}
> +				} else {
> +					++num_one;
> +				}
> +			}
> +			if (num_lsu == 0)
> +				++num_lsu;
> +			depth = (host->can_queue - num_one) / num_lsu;
> +			if (depth > 256)
> +				depth = 256;
> +			else if (depth < 2)
> +				depth = 2;
> +			scsi_change_queue_depth(sdev, depth);
> +		} else {
> +			scsi_change_queue_depth(sdev,
> +				aac->hba_map[chn][tid].qd_limit);

At least in diff form, the above is quite hard to read. Can you make the code
flow a bit more obvious? The extra level of indentation and thus newly
introduced linebreaks didn't make it easier.


>  		}
> -		if (num_lsu == 0)
> -			++num_lsu;
> -		depth = (host->can_queue - num_one) / num_lsu;
> -		if (depth > 256)
> -			depth = 256;
> -		else if (depth < 2)
> -			depth = 2;
> -		scsi_change_queue_depth(sdev, depth);
> -	} else {
> -		scsi_change_queue_depth(sdev, 1);
> -
> -		sdev->tagged_supported = 1;
>  	}


[...]

Thanks,
	Johannes
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 15/24] aacraid: Include HBA direct interface
  2017-01-27 19:28 ` [PATCH V3 15/24] aacraid: Include HBA direct interface Raghava Aditya Renukunta
@ 2017-01-30 11:02   ` Johannes Thumshirn
  2017-01-30 20:00     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:02 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:44AM -0800, Raghava Aditya Renukunta wrote:
> Added support to send direct pasthru srb commands from management utilty
> to the  controller.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

[...]

Bonus points if you tidy up the following:

>  	byte_count = 0;
> -	if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
> +	if (is_native_device) {
> +		struct user_sgmap *usg32 = &user_srbcmd->sg;
> +		struct user_sgmap64 *usg64 =
> +			(struct user_sgmap64 *)&user_srbcmd->sg;
> +
> +		for (i = 0; i < usg32->count; i++) {
> +			void *p;
> +			u64 addr;
> +
> +			sg_count[i] = (actual_fibsize64 == fibsize) ?
> +				usg64->sg[i].count : usg32->sg[i].count;
> +			if (sg_count[i] >
> +				(dev->scsi_host_ptr->max_sectors << 9)) {
> +				pr_err("aacraid: upsg->sg[%d].count=%u>%u\n",
> +					i, sg_count[i],
> +					dev->scsi_host_ptr->max_sectors << 9);
> +				rcode = -EINVAL;
> +				goto cleanup;
> +			}
> +
> +			p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
> +			if (!p) {
> +				rcode = -ENOMEM;
> +				goto cleanup;
> +			}
> +
> +			if (actual_fibsize64 == fibsize) {
> +				addr = (u64)usg64->sg[i].addr[0];
> +				addr += ((u64)usg64->sg[i].addr[1]) << 32;
> +			} else {
> +				addr = (u64)usg32->sg[i].addr;
> +			}
> +
> +			sg_user[i] = (void __user *)(uintptr_t)addr;
> +			sg_list[i] = p; // save so we can clean up later
> +			sg_indx = i;
> +
> +			if (flags & SRB_DataOut) {
> +				if (copy_from_user(p, sg_user[i],
> +					sg_count[i])) {
> +					rcode = -EFAULT;
> +					goto cleanup;
> +				}
> +			}
> +			addr = pci_map_single(dev->pdev, p, sg_count[i],
> +						data_dir);
> +			hbacmd->sge[i].addr_hi = cpu_to_le32((u32)(addr>>32));
> +			hbacmd->sge[i].addr_lo = cpu_to_le32(
> +						(u32)(addr & 0xffffffff));
> +			hbacmd->sge[i].len = cpu_to_le32(sg_count[i]);
> +			hbacmd->sge[i].flags = 0;
> +			byte_count += sg_count[i];
> +		}
> +
> +		if (usg32->count > 0)	/* embedded sglist */
> +			hbacmd->sge[usg32->count-1].flags =
> +				cpu_to_le32(0x40000000);
> +		hbacmd->data_length = cpu_to_le32(byte_count);
> +
> +		status = aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, srbfib,
> +					NULL, NULL);
> +
> +	} else if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
>  		struct user_sgmap64* upsg = (struct user_sgmap64*)&user_srbcmd->sg;
>  		struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
>  
> @@ -606,7 +719,9 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)

[...]

Anyways,
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 16/24] aacraid: Add task management functionality
  2017-01-27 19:28 ` [PATCH V3 16/24] aacraid: Add task management functionality Raghava Aditya Renukunta
@ 2017-01-30 11:19   ` Johannes Thumshirn
  2017-01-30 19:59     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:19 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:45AM -0800, Raghava Aditya Renukunta wrote:
> Added support to send out task management commands.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

[...]

> @@ -3365,7 +3462,151 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
>  
>  /**
>   *
> - * aac_send_scb_fib
> + * aac_hba_callback
> + * @context: the context set in the fib - here it is scsi cmd
> + * @fibptr: pointer to the fib
> + *
> + * Handles the completion of a native HBA scsi command
> + *
> + */
> +void aac_hba_callback(void *context, struct fib *fibptr)
> +{
> +	struct aac_dev *dev;
> +	struct scsi_cmnd *scsicmd;
> +
> +	scsicmd = (struct scsi_cmnd *) context;
> +
> +	if (!aac_valid_context(scsicmd, fibptr))
> +		return;
> +
> +	WARN_ON(fibptr == NULL);
> +	dev = fibptr->dev;
> +
> +	if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))
> +		scsi_dma_unmap(scsicmd);
> +
> +	if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
> +		/* fast response */
> +		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
> +	} else {
> +		struct aac_hba_resp *err =
> +			&((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
> +
> +		// BUG_ON(err->iu_type != HBA_IU_TYPE_RESP);

Please zap that C++ comment and see if you can tidy up the remaining code a
bit (e.g a new function for the else block, switch statement iterating over
err->serivce_response, etc...)

> +		if (err->service_response == HBA_RESP_SVCRES_TASK_COMPLETE) {
> +			scsicmd->result = err->status;
> +			/* set residual count */
> +			scsi_set_resid(scsicmd,
> +				le32_to_cpu(err->residual_count));
> +
> +			switch (err->status) {
> +			case SAM_STAT_GOOD:
> +				scsicmd->result |= DID_OK << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			case SAM_STAT_CHECK_CONDITION:
> +			{
> +				int len;
> +
> +				len = min_t(u8, err->sense_response_data_len,
> +					SCSI_SENSE_BUFFERSIZE);
> +				if (len)
> +					memcpy(scsicmd->sense_buffer,
> +						err->sense_response_buf, len);
> +				scsicmd->result |= DID_OK << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			}
> +			case SAM_STAT_BUSY:
> +				scsicmd->result |= DID_BUS_BUSY << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			case SAM_STAT_TASK_ABORTED:
> +				scsicmd->result |= DID_ABORT << 16 |
> +					ABORT << 8;
> +				break;
> +			case SAM_STAT_RESERVATION_CONFLICT:
> +			case SAM_STAT_TASK_SET_FULL:
> +			default:
> +				scsicmd->result |= DID_ERROR << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			}
> +		} else if (err->service_response == HBA_RESP_SVCRES_FAILURE) {
> +			switch (err->status) {
> +			case HBA_RESP_STAT_HBAMODE_DISABLED:
> +			{
> +				u32 bus, cid;
> +
> +				bus = aac_logical_to_phys(
> +						scmd_channel(scsicmd));
> +				cid = scmd_id(scsicmd);
> +				if (dev->hba_map[bus][cid].devtype ==
> +					AAC_DEVTYPE_NATIVE_RAW) {
> +					dev->hba_map[bus][cid].devtype =
> +						AAC_DEVTYPE_ARC_RAW;
> +					dev->hba_map[bus][cid].rmw_nexus =
> +						0xffffffff;
> +				}
> +				scsicmd->result = DID_NO_CONNECT << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			}
> +			case HBA_RESP_STAT_IO_ERROR:
> +			case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
> +				scsicmd->result = DID_OK << 16 |
> +					COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
> +				break;
> +			case HBA_RESP_STAT_IO_ABORTED:
> +				scsicmd->result = DID_ABORT << 16 |
> +					ABORT << 8;
> +				break;
> +			case HBA_RESP_STAT_INVALID_DEVICE:
> +				scsicmd->result = DID_NO_CONNECT << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			case HBA_RESP_STAT_UNDERRUN:
> +				/* UNDERRUN is OK */
> +				scsicmd->result = DID_OK << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			case HBA_RESP_STAT_OVERRUN:
> +			default:
> +				scsicmd->result = DID_ERROR << 16 |
> +					COMMAND_COMPLETE << 8;
> +				break;
> +			}
> +		} else if (err->service_response ==
> +			HBA_RESP_SVCRES_TMF_REJECTED) {
> +			scsicmd->result =
> +				DID_ERROR << 16 | MESSAGE_REJECT << 8;
> +		} else if (err->service_response ==
> +			HBA_RESP_SVCRES_TMF_LUN_INVALID) {
> +			scsicmd->result =
> +				DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
> +		} else if ((err->service_response ==
> +			HBA_RESP_SVCRES_TMF_COMPLETE) ||
> +			(err->service_response ==
> +			HBA_RESP_SVCRES_TMF_SUCCEEDED)) {
> +			scsicmd->result =
> +				DID_OK << 16 | COMMAND_COMPLETE << 8;
> +		} else {
> +			scsicmd->result =
> +				DID_ERROR << 16 | COMMAND_COMPLETE << 8;
> +		}
> +	}
> +
> +	aac_fib_complete(fibptr);
> +
> +	if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
> +		scsicmd->SCp.sent_command = 1;
> +	else
> +		scsicmd->scsi_done(scsicmd);
> +}

[...]

> @@ -3408,6 +3649,54 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
>  	return -1;
>  }
>  
> +/**
> + *
> + * aac_send_hba_fib
> + * @scsicmd: the scsi command block
> + *
> + * This routine will form a FIB and fill in the aac_hba_cmd_req from the
> + * scsicmd passed in.
> + */
> +static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
> +{
> +	struct fib *cmd_fibcontext;
> +	struct aac_dev *dev;
> +	int status;
> +
> +	dev = (struct aac_dev *)scsicmd->device->host->hostdata;

dev = shost_priv(scsicmd->device->host);

[...]

> @@ -3660,6 +3949,73 @@ static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int
>  	return 0;
>  }
>  
> +static long aac_build_sghba(struct scsi_cmnd *scsicmd,
> +			struct aac_hba_cmd_req *hbacmd,
> +			int sg_max,
> +			u64 sg_address)
> +{
> +	unsigned long byte_count = 0;
> +	int nseg;
> +
> +	nseg = scsi_dma_map(scsicmd);
> +	if (nseg < 0)
> +		return nseg;

if (nseg <= 0)
	return nseg;

> +	if (nseg) {
> +		struct scatterlist *sg;
> +		int i;
> +		u32 cur_size;
> +		struct aac_hba_sgl *sge;
> +
> +		if (nseg > HBA_MAX_SG_EMBEDDED)
> +			sge = &hbacmd->sge[2];
> +		else
> +			sge = &hbacmd->sge[0];
> +
> +		scsi_for_each_sg(scsicmd, sg, nseg, i) {
> +			int count = sg_dma_len(sg);
> +			u64 addr = sg_dma_address(sg);
> +
> +			WARN_ON(i >= sg_max);
> +			sge->addr_hi = cpu_to_le32((u32)(addr>>32));
> +			sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));
> +			cur_size = cpu_to_le32(count);
> +			sge->len = cur_size;
> +			sge->flags = 0;
> +			byte_count += count;
> +			sge++;
> +		}
> +
> +		sge--;
> +		/* hba wants the size to be exact */
> +		if (byte_count > scsi_bufflen(scsicmd)) {
> +			u32 temp = le32_to_cpu(sge->len) -
> +				(byte_count - scsi_bufflen(scsicmd));
> +			sge->len = cpu_to_le32(temp);
> +			byte_count = scsi_bufflen(scsicmd);
> +		}
> +
> +		if (nseg <= HBA_MAX_SG_EMBEDDED) {
> +			hbacmd->emb_data_desc_count = cpu_to_le32(nseg);
> +			sge->flags = cpu_to_le32(0x40000000);
> +		} else {
> +			/* not embedded */
> +			hbacmd->sge[0].flags = cpu_to_le32(0x80000000);
> +			hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);
> +			hbacmd->sge[0].addr_hi =
> +				(u32)cpu_to_le32(sg_address >> 32);
> +			hbacmd->sge[0].addr_lo =
> +				cpu_to_le32((u32)(sg_address & 0xffffffff));
> +		}
> +
> +		/* Check for command underflow */
> +		if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
> +			pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",
> +					byte_count, scsicmd->underflow);
> +		}
> +	}
> +	return byte_count;
> +}
> +
>  #ifdef AAC_DETAILED_STATUS_INFO
>  
>  struct aac_srb_status_info {
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun
  2017-01-27 19:28 ` [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun Raghava Aditya Renukunta
@ 2017-01-30 11:24   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:24 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:46AM -0800, Raghava Aditya Renukunta wrote:
> Added task management command support to abort any timed out commands
> in case of a eh_abort call and to reset lun's in case of eh_reset call.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 19/24] aacraid: Added new IWBR reset
  2017-01-27 19:28 ` [PATCH V3 19/24] aacraid: Added new IWBR reset Raghava Aditya Renukunta
@ 2017-01-30 11:39   ` Johannes Thumshirn
  2017-01-30 19:56     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:39 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:48AM -0800, Raghava Aditya Renukunta wrote:
> Added a new IWBR soft reset type, reworked the IOP reset interface for
> a bit.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

[...]

> @@ -1488,7 +1489,8 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
>  	 *	If a positive health, means in a known DEAD PANIC
>  	 * state and the adapter could be reset to `try again'.
>  	 */
> -	retval = aac_adapter_restart(aac, forced ? 0 : aac_adapter_check_health(aac));
> +	bled = forced ? 0 : aac_adapter_check_health(aac);
> +	retval = aac_adapter_restart(aac, bled, reset_type);
>  
>  	if (retval)
>  		goto out;
> @@ -1598,7 +1600,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced)
>  	return retval;
>  }
>  
> -int aac_reset_adapter(struct aac_dev * aac, int forced)
> +int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
>  {
>  	unsigned long flagv = 0;
>  	int retval;
> @@ -1651,7 +1653,9 @@ int aac_reset_adapter(struct aac_dev * aac, int forced)
>  	if (forced < 2)
>  		aac_send_shutdown(aac);
>  	spin_lock_irqsave(host->host_lock, flagv);
> -	retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset != 0) && (aac_check_reset != 1)));
> +	retval = _aac_reset_adapter(aac,
> +		forced ? forced : ((aac_check_reset != 0) &&
> +		(aac_check_reset != 1)), reset_type);
>  	spin_unlock_irqrestore(host->host_lock, flagv);

Can you please add a local bled here as well, like you did in
_aac_reset_adapter() instead of doing the 'forced ? forced : ((aac_check_reset
!= 0) && aac_check_reset != 1))' dance in the function call.

>  
>  	if ((forced < 2) && (retval == -ENODEV)) {
> @@ -1814,7 +1818,8 @@ int aac_check_health(struct aac_dev * aac)
>  	host = aac->scsi_host_ptr;
>  	if (aac->thread->pid != current->pid)
>  		spin_lock_irqsave(host->host_lock, flagv);
> -	BlinkLED = _aac_reset_adapter(aac, aac_check_reset != 1);
> +	BlinkLED = _aac_reset_adapter(aac,
> +		aac_check_reset != 1, IOP_HWSOFT_RESET);

Arguably here as well.

>  	if (aac->thread->pid != current->pid)
>  		spin_unlock_irqrestore(host->host_lock, flagv);
>  	return BlinkLED;
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 2ead5c7..a0f26f6 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c

[...]

> @@ -1162,7 +1162,9 @@ static ssize_t aac_store_reset_adapter(struct device *device,
>  
>  	if (!capable(CAP_SYS_ADMIN))
>  		return retval;

struct aac_dev *adap = shost_priv(class_to_shost(device));
int bled = buf[0] == "!";

retval = aac_reset_adapter(adap, bled, IOP_HWSOFT_RESET);

> -	retval = aac_reset_adapter((struct aac_dev*)class_to_shost(device)->hostdata, buf[0] == '!');
> +	retval = aac_reset_adapter((struct aac_dev *)
> +		class_to_shost(device)->hostdata,
> +		buf[0] == '!', IOP_HWSOFT_RESET);
>  	if (retval >= 0)
>  		retval = count;
>  	return retval;

[...]

Thanks,
	Johannes
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset
  2017-01-27 19:28 ` [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset Raghava Aditya Renukunta
@ 2017-01-30 11:41   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:41 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:49AM -0800, Raghava Aditya Renukunta wrote:
> Added a new ioctl interface to trigger an IOP or IWBR reset from ioctl.
> Primary used by management utility to trigger resets.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl
  2017-01-27 19:28 ` [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl Raghava Aditya Renukunta
@ 2017-01-30 11:43   ` Johannes Thumshirn
  2017-01-30 19:53     ` Raghava Aditya Renukunta
  0 siblings, 1 reply; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:43 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:50AM -0800, Raghava Aditya Renukunta wrote:
> Added a new ioctl interface to retrieve the host device information.
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

[...]

> + * This is for management ioctl purpose only.
> + */
> +struct aac_hba_info {
> +
> +	u8	DriverName[50];
> +	u8	AdapterNumber;
> +	u8	SystemIoBusNumber;
> +	u8	DeviceNumber;
> +	u32	FunctionNumber;
> +	u32	VendorID;
> +	u32	DeviceID;
> +	u32	SubVendorID;
> +	u32	SubSystemID;
> +	u32	MappedBaseAddressSize;
> +	u32	BasePhysicalAddress_HighPart;
> +	u32	BasePhysicalAddress_LowPart;
> +
> +	u32	MaxCommandSize;
> +	u32	MaxFibSize;
> +	u32	MaxScatterGatherFromOs;
> +	u32	MaxScatterGatherToFw;
> +	u32	MaxOutstandingFibs;
> +
> +	u32	QueueStartThreshold;
> +	u32	QueueDumpThreshold;
> +	u32	MaxIoSizeQueued;
> +	u32	OutstandingIO;
> +
> +	u32	FirmwareBuildNumber;
> +	u32	BIOSBuildNumber;
> +	u32	DriverBuildNumber;
> +	u32	SerialNumber_HighPart;
> +	u32	SerialNumber_LowPart;
> +	u32	SupportedOptions;
> +	u32	FeatureBits;
> +	u32	currentnumberPorts;
> +
> +	u8	NewCommInterface:1;
> +	u8	NewCommandsSupported:1;
> +	u8	DisablePassthrough:1;
> +	u8	ExposeNonDasd:1;
> +	u8	QueueAllowed:1;
> +	u8	BLEDCheckEnabled:1;
> +	u8	reserved1:1;
> +	u8	reserted2:1;
> +
> +	u32	reserved3[10];
> +
> +};

Again, is it possible to get this without CamelCase?

Anyways,
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 22/24] aacraid: Update copyrights
  2017-01-27 19:28 ` [PATCH V3 22/24] aacraid: Update copyrights Raghava Aditya Renukunta
@ 2017-01-30 11:43   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:43 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:51AM -0800, Raghava Aditya Renukunta wrote:
> Added new copyright messages
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 23/24] aacraid: Change Driver Version Prefix
  2017-01-27 19:28 ` [PATCH V3 23/24] aacraid: Change Driver Version Prefix Raghava Aditya Renukunta
@ 2017-01-30 11:44   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:44 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:52AM -0800, Raghava Aditya Renukunta wrote:
> Change the aacraid driver prefix from 1.2-1 to 1.2.1
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 24/24] aacraid: update version
  2017-01-27 19:28 ` [PATCH V3 24/24] aacraid: update version Raghava Aditya Renukunta
@ 2017-01-30 11:44   ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-30 11:44 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, David.Carroll, Gana.Sridaran,
	Scott.Benesh

On Fri, Jan 27, 2017 at 11:28:53AM -0800, Raghava Aditya Renukunta wrote:
> Update the driver version to 50740
> 
> Signed-off-by: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
> Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> 
> ---

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl
  2017-01-30 11:43   ` Johannes Thumshirn
@ 2017-01-30 19:53     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 19:53 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 3:43 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:50AM -0800, Raghava Aditya Renukunta wrote:
> > Added a new ioctl interface to retrieve the host device information.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> [...]
> 
> > + * This is for management ioctl purpose only.
> > + */
> > +struct aac_hba_info {
> > +
> > +     u8      DriverName[50];
> > +     u8      AdapterNumber;
> > +     u8      SystemIoBusNumber;
> > +     u8      DeviceNumber;
> > +     u32     FunctionNumber;
> > +     u32     VendorID;
> > +     u32     DeviceID;
> > +     u32     SubVendorID;
> > +     u32     SubSystemID;
> > +     u32     MappedBaseAddressSize;
> > +     u32     BasePhysicalAddress_HighPart;
> > +     u32     BasePhysicalAddress_LowPart;
> > +
> > +     u32     MaxCommandSize;
> > +     u32     MaxFibSize;
> > +     u32     MaxScatterGatherFromOs;
> > +     u32     MaxScatterGatherToFw;
> > +     u32     MaxOutstandingFibs;
> > +
> > +     u32     QueueStartThreshold;
> > +     u32     QueueDumpThreshold;
> > +     u32     MaxIoSizeQueued;
> > +     u32     OutstandingIO;
> > +
> > +     u32     FirmwareBuildNumber;
> > +     u32     BIOSBuildNumber;
> > +     u32     DriverBuildNumber;
> > +     u32     SerialNumber_HighPart;
> > +     u32     SerialNumber_LowPart;
> > +     u32     SupportedOptions;
> > +     u32     FeatureBits;
> > +     u32     currentnumberPorts;
> > +
> > +     u8      NewCommInterface:1;
> > +     u8      NewCommandsSupported:1;
> > +     u8      DisablePassthrough:1;
> > +     u8      ExposeNonDasd:1;
> > +     u8      QueueAllowed:1;
> > +     u8      BLEDCheckEnabled:1;
> > +     u8      reserved1:1;
> > +     u8      reserted2:1;
> > +
> > +     u32     reserved3[10];
> > +
> > +};
> 
> Again, is it possible to get this without CamelCase?

Next patch version submission I will fix this.

> Anyways,
> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 19/24] aacraid: Added new IWBR reset
  2017-01-30 11:39   ` Johannes Thumshirn
@ 2017-01-30 19:56     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 19:56 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Johannes Thumshirn
> Sent: Monday, January 30, 2017 3:40 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 19/24] aacraid: Added new IWBR reset
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:48AM -0800, Raghava Aditya Renukunta wrote:
> > Added a new IWBR soft reset type, reworked the IOP reset interface for
> > a bit.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> [...]
> 
> > @@ -1488,7 +1489,8 @@ static int _aac_reset_adapter(struct aac_dev
> *aac, int forced)
> >        *      If a positive health, means in a known DEAD PANIC
> >        * state and the adapter could be reset to `try again'.
> >        */
> > -     retval = aac_adapter_restart(aac, forced ? 0 :
> aac_adapter_check_health(aac));
> > +     bled = forced ? 0 : aac_adapter_check_health(aac);
> > +     retval = aac_adapter_restart(aac, bled, reset_type);
> >
> >       if (retval)
> >               goto out;
> > @@ -1598,7 +1600,7 @@ static int _aac_reset_adapter(struct aac_dev
> *aac, int forced)
> >       return retval;
> >  }
> >
> > -int aac_reset_adapter(struct aac_dev * aac, int forced)
> > +int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
> >  {
> >       unsigned long flagv = 0;
> >       int retval;
> > @@ -1651,7 +1653,9 @@ int aac_reset_adapter(struct aac_dev * aac, int
> forced)
> >       if (forced < 2)
> >               aac_send_shutdown(aac);
> >       spin_lock_irqsave(host->host_lock, flagv);
> > -     retval = _aac_reset_adapter(aac, forced ? forced : ((aac_check_reset !=
> 0) && (aac_check_reset != 1)));
> > +     retval = _aac_reset_adapter(aac,
> > +             forced ? forced : ((aac_check_reset != 0) &&
> > +             (aac_check_reset != 1)), reset_type);
> >       spin_unlock_irqrestore(host->host_lock, flagv);
> 
> Can you please add a local bled here as well, like you did in
> _aac_reset_adapter() instead of doing the 'forced ? forced :
> ((aac_check_reset
> != 0) && aac_check_reset != 1))' dance in the function call.

Yup, I will do that. 

> >
> >       if ((forced < 2) && (retval == -ENODEV)) {
> > @@ -1814,7 +1818,8 @@ int aac_check_health(struct aac_dev * aac)
> >       host = aac->scsi_host_ptr;
> >       if (aac->thread->pid != current->pid)
> >               spin_lock_irqsave(host->host_lock, flagv);
> > -     BlinkLED = _aac_reset_adapter(aac, aac_check_reset != 1);
> > +     BlinkLED = _aac_reset_adapter(aac,
> > +             aac_check_reset != 1, IOP_HWSOFT_RESET);
> 
> Arguably here as well.


Ditto here.

> 
> >       if (aac->thread->pid != current->pid)
> >               spin_unlock_irqrestore(host->host_lock, flagv);
> >       return BlinkLED;
> > diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> > index 2ead5c7..a0f26f6 100644
> > --- a/drivers/scsi/aacraid/linit.c
> > +++ b/drivers/scsi/aacraid/linit.c
> 
> [...]
> 
> > @@ -1162,7 +1162,9 @@ static ssize_t aac_store_reset_adapter(struct
> device *device,
> >
> >       if (!capable(CAP_SYS_ADMIN))
> >               return retval;
> 
> struct aac_dev *adap = shost_priv(class_to_shost(device));
> int bled = buf[0] == "!";
> 
> retval = aac_reset_adapter(adap, bled, IOP_HWSOFT_RESET);

Here as well. I will make the necessary changes

> > -     retval = aac_reset_adapter((struct aac_dev*)class_to_shost(device)-
> >hostdata, buf[0] == '!');
> > +     retval = aac_reset_adapter((struct aac_dev *)
> > +             class_to_shost(device)->hostdata,
> > +             buf[0] == '!', IOP_HWSOFT_RESET);
> >       if (retval >= 0)
> >               retval = count;
> >       return retval;
> 
> [...]

Thank you,
Regards,
Raghava Aditya

> Thanks,
>         Johannes
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 16/24] aacraid: Add task management functionality
  2017-01-30 11:19   ` Johannes Thumshirn
@ 2017-01-30 19:59     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 19:59 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 3:20 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 16/24] aacraid: Add task management functionality
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:45AM -0800, Raghava Aditya Renukunta wrote:
> > Added support to send out task management commands.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> [...]
> 
> > @@ -3365,7 +3462,151 @@ static void aac_srb_callback(void *context,
> struct fib * fibptr)
> >
> >  /**
> >   *
> > - * aac_send_scb_fib
> > + * aac_hba_callback
> > + * @context: the context set in the fib - here it is scsi cmd
> > + * @fibptr: pointer to the fib
> > + *
> > + * Handles the completion of a native HBA scsi command
> > + *
> > + */
> > +void aac_hba_callback(void *context, struct fib *fibptr)
> > +{
> > +     struct aac_dev *dev;
> > +     struct scsi_cmnd *scsicmd;
> > +
> > +     scsicmd = (struct scsi_cmnd *) context;
> > +
> > +     if (!aac_valid_context(scsicmd, fibptr))
> > +             return;
> > +
> > +     WARN_ON(fibptr == NULL);
> > +     dev = fibptr->dev;
> > +
> > +     if (!(fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF))
> > +             scsi_dma_unmap(scsicmd);
> > +
> > +     if (fibptr->flags & FIB_CONTEXT_FLAG_FASTRESP) {
> > +             /* fast response */
> > +             scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
> > +     } else {
> > +             struct aac_hba_resp *err =
> > +                     &((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
> > +
> > +             // BUG_ON(err->iu_type != HBA_IU_TYPE_RESP);
> 
> Please zap that C++ comment and see if you can tidy up the remaining code a
> bit (e.g a new function for the else block, switch statement iterating over
> err->serivce_response, etc...)

Yes Johannes,
I have some ideas to rewrite this bit of code, let me go ahead and do it then.


> > +             if (err->service_response ==
> HBA_RESP_SVCRES_TASK_COMPLETE) {
> > +                     scsicmd->result = err->status;
> > +                     /* set residual count */
> > +                     scsi_set_resid(scsicmd,
> > +                             le32_to_cpu(err->residual_count));
> > +
> > +                     switch (err->status) {
> > +                     case SAM_STAT_GOOD:
> > +                             scsicmd->result |= DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case SAM_STAT_CHECK_CONDITION:
> > +                     {
> > +                             int len;
> > +
> > +                             len = min_t(u8, err->sense_response_data_len,
> > +                                     SCSI_SENSE_BUFFERSIZE);
> > +                             if (len)
> > +                                     memcpy(scsicmd->sense_buffer,
> > +                                             err->sense_response_buf, len);
> > +                             scsicmd->result |= DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +                     case SAM_STAT_BUSY:
> > +                             scsicmd->result |= DID_BUS_BUSY << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case SAM_STAT_TASK_ABORTED:
> > +                             scsicmd->result |= DID_ABORT << 16 |
> > +                                     ABORT << 8;
> > +                             break;
> > +                     case SAM_STAT_RESERVATION_CONFLICT:
> > +                     case SAM_STAT_TASK_SET_FULL:
> > +                     default:
> > +                             scsicmd->result |= DID_ERROR << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +             } else if (err->service_response == HBA_RESP_SVCRES_FAILURE) {
> > +                     switch (err->status) {
> > +                     case HBA_RESP_STAT_HBAMODE_DISABLED:
> > +                     {
> > +                             u32 bus, cid;
> > +
> > +                             bus = aac_logical_to_phys(
> > +                                             scmd_channel(scsicmd));
> > +                             cid = scmd_id(scsicmd);
> > +                             if (dev->hba_map[bus][cid].devtype ==
> > +                                     AAC_DEVTYPE_NATIVE_RAW) {
> > +                                     dev->hba_map[bus][cid].devtype =
> > +                                             AAC_DEVTYPE_ARC_RAW;
> > +                                     dev->hba_map[bus][cid].rmw_nexus =
> > +                                             0xffffffff;
> > +                             }
> > +                             scsicmd->result = DID_NO_CONNECT << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +                     case HBA_RESP_STAT_IO_ERROR:
> > +                     case HBA_RESP_STAT_NO_PATH_TO_DEVICE:
> > +                             scsicmd->result = DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8 | SAM_STAT_BUSY;
> > +                             break;
> > +                     case HBA_RESP_STAT_IO_ABORTED:
> > +                             scsicmd->result = DID_ABORT << 16 |
> > +                                     ABORT << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_INVALID_DEVICE:
> > +                             scsicmd->result = DID_NO_CONNECT << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_UNDERRUN:
> > +                             /* UNDERRUN is OK */
> > +                             scsicmd->result = DID_OK << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     case HBA_RESP_STAT_OVERRUN:
> > +                     default:
> > +                             scsicmd->result = DID_ERROR << 16 |
> > +                                     COMMAND_COMPLETE << 8;
> > +                             break;
> > +                     }
> > +             } else if (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_REJECTED) {
> > +                     scsicmd->result =
> > +                             DID_ERROR << 16 | MESSAGE_REJECT << 8;
> > +             } else if (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_LUN_INVALID) {
> > +                     scsicmd->result =
> > +                             DID_NO_CONNECT << 16 | COMMAND_COMPLETE << 8;
> > +             } else if ((err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_COMPLETE) ||
> > +                     (err->service_response ==
> > +                     HBA_RESP_SVCRES_TMF_SUCCEEDED)) {
> > +                     scsicmd->result =
> > +                             DID_OK << 16 | COMMAND_COMPLETE << 8;
> > +             } else {
> > +                     scsicmd->result =
> > +                             DID_ERROR << 16 | COMMAND_COMPLETE << 8;
> > +             }
> > +     }
> > +
> > +     aac_fib_complete(fibptr);
> > +
> > +     if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
> > +             scsicmd->SCp.sent_command = 1;
> > +     else
> > +             scsicmd->scsi_done(scsicmd);
> > +}
> 
> [...]
> 
> > @@ -3408,6 +3649,54 @@ static int aac_send_srb_fib(struct scsi_cmnd*
> scsicmd)
> >       return -1;
> >  }
> >
> > +/**
> > + *
> > + * aac_send_hba_fib
> > + * @scsicmd: the scsi command block
> > + *
> > + * This routine will form a FIB and fill in the aac_hba_cmd_req from the
> > + * scsicmd passed in.
> > + */
> > +static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
> > +{
> > +     struct fib *cmd_fibcontext;
> > +     struct aac_dev *dev;
> > +     int status;
> > +
> > +     dev = (struct aac_dev *)scsicmd->device->host->hostdata;
> 
> dev = shost_priv(scsicmd->device->host);

Yes, 

> [...]
> 
> > @@ -3660,6 +3949,73 @@ static int aac_convert_sgraw2(struct
> aac_raw_io2 *rio2, int pages, int nseg, int
> >       return 0;
> >  }
> >
> > +static long aac_build_sghba(struct scsi_cmnd *scsicmd,
> > +                     struct aac_hba_cmd_req *hbacmd,
> > +                     int sg_max,
> > +                     u64 sg_address)
> > +{
> > +     unsigned long byte_count = 0;
> > +     int nseg;
> > +
> > +     nseg = scsi_dma_map(scsicmd);
> > +     if (nseg < 0)
> > +             return nseg;
> 
> if (nseg <= 0)
>         return nseg;

Yes
 
> > +     if (nseg) {
> > +             struct scatterlist *sg;
> > +             int i;
> > +             u32 cur_size;
> > +             struct aac_hba_sgl *sge;
> > +
> > +             if (nseg > HBA_MAX_SG_EMBEDDED)
> > +                     sge = &hbacmd->sge[2];
> > +             else
> > +                     sge = &hbacmd->sge[0];
> > +
> > +             scsi_for_each_sg(scsicmd, sg, nseg, i) {
> > +                     int count = sg_dma_len(sg);
> > +                     u64 addr = sg_dma_address(sg);
> > +
> > +                     WARN_ON(i >= sg_max);
> > +                     sge->addr_hi = cpu_to_le32((u32)(addr>>32));
> > +                     sge->addr_lo = cpu_to_le32((u32)(addr & 0xffffffff));
> > +                     cur_size = cpu_to_le32(count);
> > +                     sge->len = cur_size;
> > +                     sge->flags = 0;
> > +                     byte_count += count;
> > +                     sge++;
> > +             }
> > +
> > +             sge--;
> > +             /* hba wants the size to be exact */
> > +             if (byte_count > scsi_bufflen(scsicmd)) {
> > +                     u32 temp = le32_to_cpu(sge->len) -
> > +                             (byte_count - scsi_bufflen(scsicmd));
> > +                     sge->len = cpu_to_le32(temp);
> > +                     byte_count = scsi_bufflen(scsicmd);
> > +             }
> > +
> > +             if (nseg <= HBA_MAX_SG_EMBEDDED) {
> > +                     hbacmd->emb_data_desc_count = cpu_to_le32(nseg);
> > +                     sge->flags = cpu_to_le32(0x40000000);
> > +             } else {
> > +                     /* not embedded */
> > +                     hbacmd->sge[0].flags = cpu_to_le32(0x80000000);
> > +                     hbacmd->emb_data_desc_count = (u8)cpu_to_le32(1);
> > +                     hbacmd->sge[0].addr_hi =
> > +                             (u32)cpu_to_le32(sg_address >> 32);
> > +                     hbacmd->sge[0].addr_lo =
> > +                             cpu_to_le32((u32)(sg_address & 0xffffffff));
> > +             }
> > +
> > +             /* Check for command underflow */
> > +             if (scsicmd->underflow && (byte_count < scsicmd->underflow)) {
> > +                     pr_warn("aacraid: cmd len %08lX cmd underflow %08X\n",
> > +                                     byte_count, scsicmd->underflow);
> > +             }
> > +     }
> > +     return byte_count;
> > +}
> > +
> >  #ifdef AAC_DETAILED_STATUS_INFO

Regards,
Raghava Aditya

> >  struct aac_srb_status_info {
> > --
> > 2.7.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 15/24] aacraid: Include HBA direct interface
  2017-01-30 11:02   ` Johannes Thumshirn
@ 2017-01-30 20:00     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:00 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Johannes Thumshirn
> Sent: Monday, January 30, 2017 3:02 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 15/24] aacraid: Include HBA direct interface
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:44AM -0800, Raghava Aditya Renukunta wrote:
> > Added support to send direct pasthru srb commands from management
> utilty
> > to the  controller.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> [...]
> 
> Bonus points if you tidy up the following:

Let me try for those points then :). 

> 
> >       byte_count = 0;
> > -     if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
> > +     if (is_native_device) {
> > +             struct user_sgmap *usg32 = &user_srbcmd->sg;
> > +             struct user_sgmap64 *usg64 =
> > +                     (struct user_sgmap64 *)&user_srbcmd->sg;
> > +
> > +             for (i = 0; i < usg32->count; i++) {
> > +                     void *p;
> > +                     u64 addr;
> > +
> > +                     sg_count[i] = (actual_fibsize64 == fibsize) ?
> > +                             usg64->sg[i].count : usg32->sg[i].count;
> > +                     if (sg_count[i] >
> > +                             (dev->scsi_host_ptr->max_sectors << 9)) {
> > +                             pr_err("aacraid: upsg->sg[%d].count=%u>%u\n",
> > +                                     i, sg_count[i],
> > +                                     dev->scsi_host_ptr->max_sectors << 9);
> > +                             rcode = -EINVAL;
> > +                             goto cleanup;
> > +                     }
> > +
> > +                     p = kmalloc(sg_count[i], GFP_KERNEL|__GFP_DMA);
> > +                     if (!p) {
> > +                             rcode = -ENOMEM;
> > +                             goto cleanup;
> > +                     }
> > +
> > +                     if (actual_fibsize64 == fibsize) {
> > +                             addr = (u64)usg64->sg[i].addr[0];
> > +                             addr += ((u64)usg64->sg[i].addr[1]) << 32;
> > +                     } else {
> > +                             addr = (u64)usg32->sg[i].addr;
> > +                     }
> > +
> > +                     sg_user[i] = (void __user *)(uintptr_t)addr;
> > +                     sg_list[i] = p; // save so we can clean up later
> > +                     sg_indx = i;
> > +
> > +                     if (flags & SRB_DataOut) {
> > +                             if (copy_from_user(p, sg_user[i],
> > +                                     sg_count[i])) {
> > +                                     rcode = -EFAULT;
> > +                                     goto cleanup;
> > +                             }
> > +                     }
> > +                     addr = pci_map_single(dev->pdev, p, sg_count[i],
> > +                                             data_dir);
> > +                     hbacmd->sge[i].addr_hi = cpu_to_le32((u32)(addr>>32));
> > +                     hbacmd->sge[i].addr_lo = cpu_to_le32(
> > +                                             (u32)(addr & 0xffffffff));
> > +                     hbacmd->sge[i].len = cpu_to_le32(sg_count[i]);
> > +                     hbacmd->sge[i].flags = 0;
> > +                     byte_count += sg_count[i];
> > +             }
> > +
> > +             if (usg32->count > 0)   /* embedded sglist */
> > +                     hbacmd->sge[usg32->count-1].flags =
> > +                             cpu_to_le32(0x40000000);
> > +             hbacmd->data_length = cpu_to_le32(byte_count);
> > +
> > +             status = aac_hba_send(HBA_IU_TYPE_SCSI_CMD_REQ, srbfib,
> > +                                     NULL, NULL);
> > +
> > +     } else if (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64) {
> >               struct user_sgmap64* upsg = (struct
> user_sgmap64*)&user_srbcmd->sg;
> >               struct sgmap64* psg = (struct sgmap64*)&srbcmd->sg;
> >
> > @@ -606,7 +719,9 @@ static int aac_send_raw_srb(struct aac_dev* dev,
> void __user * arg)
> 
> [...]
> 
> Anyways,
> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 13/24] aacraid: Added support to set QD of attached drives
  2017-01-30 10:39   ` Johannes Thumshirn
@ 2017-01-30 20:01     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:01 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 2:40 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 13/24] aacraid: Added support to set QD of attached
> drives
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:42AM -0800, Raghava Aditya Renukunta wrote:
> > Added support to set qd of drives in slave_configure.This only works for
> > HBA1000 attached drives.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> [...]
> 
> > @@ -428,34 +441,41 @@ static int aac_slave_configure(struct scsi_device
> *sdev)
> >                */
> >               if (sdev->request_queue->rq_timeout < (45 * HZ))
> >                       blk_queue_rq_timeout(sdev->request_queue, 45*HZ);
> > -             for (cid = 0; cid < aac->maximum_num_containers; ++cid)
> > -                     if (aac->fsa_dev[cid].valid)
> > -                             ++num_lsu;
> > -             __shost_for_each_device(dev, host) {
> > -                     if (dev->tagged_supported && (dev->type == TYPE_DISK) &&
> > +             if (!is_native_device) {
> > +                     for (cid = 0; cid < aac->maximum_num_containers; ++cid)
> > +                             if (aac->fsa_dev[cid].valid)
> > +                                     ++num_lsu;
> > +                     __shost_for_each_device(dev, host) {
> > +                             if (dev->tagged_supported &&
> > +                                     (dev->type == TYPE_DISK) &&
> >                                       (!aac->raid_scsi_mode ||
> > -                                             (sdev_channel(sdev) != 2)) &&
> > +                                     (sdev_channel(sdev) != 2)) &&
> >                                       !dev->no_uld_attach) {
> > -                             if ((sdev_channel(dev) != CONTAINER_CHANNEL)
> > -                              || !aac->fsa_dev[sdev_id(dev)].valid)
> > -                                     ++num_lsu;
> > -                     } else
> > -                             ++num_one;
> > +                                     if ((sdev_channel(dev)
> > +                                             != CONTAINER_CHANNEL)
> > +                                      || !aac->fsa_dev[sdev_id(dev)].valid) {
> > +                                             ++num_lsu;
> > +                                     }
> > +                             } else {
> > +                                     ++num_one;
> > +                             }
> > +                     }
> > +                     if (num_lsu == 0)
> > +                             ++num_lsu;
> > +                     depth = (host->can_queue - num_one) / num_lsu;
> > +                     if (depth > 256)
> > +                             depth = 256;
> > +                     else if (depth < 2)
> > +                             depth = 2;
> > +                     scsi_change_queue_depth(sdev, depth);
> > +             } else {
> > +                     scsi_change_queue_depth(sdev,
> > +                             aac->hba_map[chn][tid].qd_limit);
> 
> At least in diff form, the above is quite hard to read. Can you make the code
> flow a bit more obvious? The extra level of indentation and thus newly
> introduced linebreaks didn't make it easier.

Yes let me rewrite the code to make it a bit more palatable. 

> 
> >               }
> > -             if (num_lsu == 0)
> > -                     ++num_lsu;
> > -             depth = (host->can_queue - num_one) / num_lsu;
> > -             if (depth > 256)
> > -                     depth = 256;
> > -             else if (depth < 2)
> > -                     depth = 2;
> > -             scsi_change_queue_depth(sdev, depth);
> > -     } else {
> > -             scsi_change_queue_depth(sdev, 1);
> > -
> > -             sdev->tagged_supported = 1;
> >       }
> 
> 
> [...]
> 
> Thanks,
>         Johannes
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW
  2017-01-30 10:31   ` Johannes Thumshirn
@ 2017-01-30 20:05     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:05 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 2:31 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter
> FW
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:41AM -0800, Raghava Aditya Renukunta wrote:
> > Retrieved queue depth from fw and saved it for future use.
> > Only applicable for HBA1000 drives.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> > Changes in  V2:
> > None
> >
> > Changes in  V3:
> > None
> >
> >  drivers/scsi/aacraid/aachba.c  | 84
> ++++++++++++++++++++++++++++++++++++++++-
> >  drivers/scsi/aacraid/aacraid.h | 85
> +++++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 167 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
> > index e441a54..c34686f 100644
> > --- a/drivers/scsi/aacraid/aachba.c
> > +++ b/drivers/scsi/aacraid/aachba.c
> > @@ -1516,6 +1516,83 @@ static int aac_scsi_32_64(struct fib * fib, struct
> scsi_cmnd * cmd)
> >       return aac_scsi_32(fib, cmd);
> >  }
> >
> > +int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
> > +{
> > +     struct fib *fibptr;
> > +     int rcode = -1;
> > +     u16 fibsize, datasize;
> > +     struct aac_srb *srbcmd;
> > +     struct sgmap64 *sg64;
> > +     struct aac_ciss_identify_pd *identify_resp;
> > +     dma_addr_t addr;
> > +     u32 vbus, vid;
> > +     u16 temp;
> > +
> > +     fibptr = aac_fib_alloc(dev);
> > +     if (!fibptr)
> > +             return -ENOMEM;
> > +
> > +     temp = AAC_MAX_LUN + target;
> > +
> > +     fibsize = sizeof(struct aac_srb) -
> > +             sizeof(struct sgentry) + sizeof(struct sgentry64);
> > +     datasize = sizeof(struct aac_ciss_identify_pd);
> > +
> > +     identify_resp = (struct aac_ciss_identify_pd *)
> > +             pci_alloc_consistent(dev->pdev, datasize, &addr);
> 
> Please don't cast void pointers.
I apologize, yes I will remove this.
> 
> > +
> > +     if (identify_resp != NULL) {
> 
> if (!identify_resp)
>         goto free_fib_ptr;
> 
> > +             vbus = (u32)le16_to_cpu(
> > +                     dev->supplement_adapter_info.VirtDeviceBus);
> > +             vid = (u32)le16_to_cpu(
> > +                     dev->supplement_adapter_info.VirtDeviceTarget);
> > +
> > +             aac_fib_init(fibptr);
> > +             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);
> > +
> > +             memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
> > +             srbcmd->cdb[0] = 0x26;
> > +             srbcmd->cdb[2] = (u8)(temp & 0x00FF);
> > +
> > +             srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;
> > +
> > +             sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
> > +             sg64->sg[0].count = cpu_to_le32(datasize);
> > +
> > +             rcode = aac_fib_send(ScsiPortCommand64,
> > +                     fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL);
> > +
> > +             if (identify_resp->current_queue_depth_limit <= 0 ||
> > +                     identify_resp->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;
> > +
> > +             pci_free_consistent(dev->pdev, datasize,
> > +                                     (void *)identify_resp, addr);
> > +
> > +             aac_fib_complete(fibptr);
> > +     }
> 
> free_fib_ptr:
Yes let me do that.

> > +
> > +     aac_fib_free(fibptr);
> > +
> > +     return rcode;
> > +}
> > +
> >  /**
> >   *   aac_update hba_map()-   update current hba map with data from FW
> >   *   @dev:   aac_dev structure
> > @@ -1565,6 +1642,9 @@ 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)
> > +                     dev->hba_map[bus][target].qd_limit = 32;
> > +
> >  update_devtype:
> >               dev->hba_map[bus][target].devtype = devtype;
> >       }
> > @@ -1711,8 +1791,10 @@ int aac_get_adapter_info(struct aac_dev* dev)
> >
> >       /* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
> >       for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
> > -             for (target = 0; target < AAC_MAX_TARGETS; target++)
> > +             for (target = 0; target < AAC_MAX_TARGETS; target++) {
> >                       dev->hba_map[bus][target].devtype = 0;
> > +                     dev->hba_map[bus][target].qd_limit = 0;
> > +             }
> >       }
> >
> >       /*
> > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> > index 05884e6..e541394 100644
> > --- a/drivers/scsi/aacraid/aacraid.h
> > +++ b/drivers/scsi/aacraid/aacraid.h
> > @@ -74,7 +74,7 @@ enum {
> >  #define AAC_NUM_IO_FIB               (1024 - AAC_NUM_MGT_FIB)
> >  #define AAC_NUM_FIB          (AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)
> >
> > -#define AAC_MAX_LUN          (8)
> > +#define AAC_MAX_LUN          (256)
> >
> >  #define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
> >  #define AAC_MAX_32BIT_SGBCOUNT       ((unsigned short)256)
> > @@ -89,6 +89,7 @@ enum {
> >
> >  #define CISS_REPORT_PHYSICAL_LUNS    0xc3
> >  #define WRITE_HOST_WELLNESS          0xa5
> > +#define CISS_IDENTIFY_PHYSICAL_DEVICE        0x15
> >  #define BMIC_IN                      0x26
> >  #define BMIC_OUT                     0x27
> >
> > @@ -110,6 +111,86 @@ struct aac_ciss_phys_luns_resp {
> >   */
> >  #define AAC_MAX_HRRQ         64
> >
> > +#pragma pack(1)
> > +
> > +struct aac_ciss_identify_pd {
> 
> [...]
> 
> > +};
> > +
> > +#pragma pack()
> 
> I'd prefer '}; __packed' over #pragma pack(1) .. #pragma pack()

Yes, let me make that change. 

Regards,
Raghava Aditya

> [...]
> 
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 11/24] aacraid: Added support for periodic wellness sync
  2017-01-30 10:27   ` Johannes Thumshirn
@ 2017-01-30 20:07     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:07 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 2:27 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 11/24] aacraid: Added support for periodic wellness
> sync
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:40AM -0800, Raghava Aditya Renukunta wrote:
> > This patch adds a new functions that periodically sync the time of host
> > to the adapter. In addition also informs the adapter that the driver is
> > alive and kicking. Only applicable to the HBA1000 and SMARTIOC2000.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> > Changes in  V2:
> > None
> >
> > Changes in  V3:
> > None
> >
> >  drivers/scsi/aacraid/aacraid.h |   3 +
> >  drivers/scsi/aacraid/commsup.c | 176
> +++++++++++++++++++++++++++++++++--------
> >  2 files changed, 148 insertions(+), 31 deletions(-)
> >
> > diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> > index b54c1bf..05884e6 100644
> > --- a/drivers/scsi/aacraid/aacraid.h
> > +++ b/drivers/scsi/aacraid/aacraid.h
> > @@ -88,6 +88,9 @@ enum {
> >  #define AAC_MAX_NATIVE_SIZE          2048
> >
> >  #define CISS_REPORT_PHYSICAL_LUNS    0xc3
> > +#define WRITE_HOST_WELLNESS          0xa5
> > +#define BMIC_IN                      0x26
> > +#define BMIC_OUT                     0x27
> >
> >  struct aac_ciss_phys_luns_resp {
> >       u8      list_length[4];         /* LUN list length (N-7, big endian) */
> > diff --git a/drivers/scsi/aacraid/commsup.c
> b/drivers/scsi/aacraid/commsup.c
> > index 346c1c0..0c009f1 100644
> > --- a/drivers/scsi/aacraid/commsup.c
> > +++ b/drivers/scsi/aacraid/commsup.c
> > @@ -43,6 +43,7 @@
> >  #include <linux/kthread.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/semaphore.h>
> > +#include <linux/bcd.h>
> >  #include <scsi/scsi.h>
> >  #include <scsi/scsi_host.h>
> >  #include <scsi/scsi_device.h>
> > @@ -1946,6 +1947,143 @@ static void aac_process_events(struct aac_dev
> *dev)
> >                       flags);
> >  }
> >
> > +static int aac_send_wellness_command(struct aac_dev *dev, char
> *wellness_str,
> > +                                                     u32 datasize)
> > +{
> > +     struct aac_srb *srbcmd;
> > +     struct sgmap64 *sg64;
> > +     dma_addr_t addr;
> > +     char *dma_buf;
> > +     struct fib *fibptr;
> > +     int ret = -ENOMEM;
> > +
> > +     fibptr = aac_fib_alloc(dev);
> > +     if (fibptr) {
> > +             aac_fib_init(fibptr);
> > +
> > +             dma_buf = pci_alloc_consistent(dev->pdev, datasize, &addr);
> > +             if (dma_buf != NULL) {
> 
> if (!dma_buf)
>         return -ENOMEM;
Yes , let me make the changes.
> 
> It makes the code flow more obvious and saves you a level of indent.
> 
> > +                     u32 vbus, vid;
> > +
> > +                     vbus = (u32)le16_to_cpu(
> > +                             dev->supplement_adapter_info.VirtDeviceBus);
> > +                     vid = (u32)le16_to_cpu(
> > +                             dev->supplement_adapter_info.VirtDeviceTarget);
> > +
> > +                     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_DataOut);
> > +                     srbcmd->timeout = cpu_to_le32(10);
> > +                     srbcmd->retry_limit = 0;
> > +                     srbcmd->cdb_size = cpu_to_le32(12);
> > +                     srbcmd->count = cpu_to_le32(datasize);
> > +
> > +                     memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
> > +                     srbcmd->cdb[0] = BMIC_OUT;
> > +                     srbcmd->cdb[6] = WRITE_HOST_WELLNESS;
> > +                     memcpy(dma_buf, (char *)wellness_str, datasize);
> > +
> > +                     sg64 = (struct sgmap64 *)&srbcmd->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 & 0xffffffff));
> > +                     sg64->sg[0].count = cpu_to_le32(datasize);
> > +
> > +                     ret = aac_fib_send(ScsiPortCommand64, fibptr,
> > +                             sizeof(struct aac_srb), FsaNormal,
> > +                             1, 1, NULL, NULL);
> > +
> > +                     pci_free_consistent(dev->pdev, datasize,
> > +                                             (void *)dma_buf, addr);
> > +     }
> > +
> > +             /*
> > +              * Do not set XferState to zero unless
> > +              * receives a response from F/W
> > +              */
> > +             if (ret >= 0)
> > +                     aac_fib_complete(fibptr);
> > +
> > +             /*
> > +              * FIB should be freed only after
> > +              * getting the response from the F/W
> > +              */
> > +             if (ret != -ERESTARTSYS)
> > +                     aac_fib_free(fibptr);
> > +     }
> 
> Not sure if it's my mailclient, but indentation looks a bit odd here.
I agree  I will check out  what's going on here.
> > +
> > +     return ret;
> > +}
> > +
> > +int aac_send_hosttime(struct aac_dev *dev, struct timeval *now)
> > +{
> > +     int ret = -ENOMEM;
> > +     struct fib *fibptr;
> > +
> > +     /*
> > +      *  This whole block needs to be rewritten with helpers
> > +      *  Changing tabs to a single space should not be allowed!!
> > +      */
> > +
> > +     if (dev->sa_firmware) {
> > +             struct tm cur_tm;
> > +             char wellness_str[] = "<HW>TD\010\0\0\0\0\0\0\0\0\0DW\0\0ZZ";
> > +             u32 datasize = sizeof(wellness_str);
> > +             unsigned long local_time;
> > +
> > +             local_time = (u32)(now->tv_sec - (sys_tz.tz_minuteswest * 60));
> > +             time_to_tm(local_time, 0, &cur_tm);
> > +             cur_tm.tm_mon += 1;
> > +             cur_tm.tm_year += 1900;
> > +             wellness_str[8] = bin2bcd(cur_tm.tm_hour);
> > +             wellness_str[9] = bin2bcd(cur_tm.tm_min);
> > +             wellness_str[10] = bin2bcd(cur_tm.tm_sec);
> > +             wellness_str[12] = bin2bcd(cur_tm.tm_mon);
> > +             wellness_str[13] = bin2bcd(cur_tm.tm_mday);
> > +             wellness_str[14] = bin2bcd(cur_tm.tm_year / 100);
> > +             wellness_str[15] = bin2bcd(cur_tm.tm_year % 100);
> > +
> > +             ret = aac_send_wellness_command(dev, wellness_str, datasize);
> > +
> > +             return ret;
> > +     }
> > +
> > +     fibptr = aac_fib_alloc(dev);
> > +     if (fibptr) {
> 
> Same here.
Here as well. 

> > +             __le32 *info;
> > +
> > +             aac_fib_init(fibptr);
> > +             info = (__le32 *)fib_data(fibptr);
> > +             *info = cpu_to_le32(now->tv_sec);
> > +             ret = aac_fib_send(
> > +                     SendHostTime, fibptr,
> > +                     sizeof(*info), FsaNormal,
> > +                     1, 1, NULL, NULL);
> > +
> > +             /*
> > +              * Do not set XferState to zero unless
> > +              * receives a response from F/W
> > +              */
> > +             if (ret >= 0)
> > +                     aac_fib_complete(fibptr);
> > +
> > +             /*
> > +              * FIB should be freed only after
> > +              * getting the response from the F/W
> > +              */
> > +             if (ret != -ERESTARTSYS)
> > +                     aac_fib_free(fibptr);
> > +     }
> > +
> > +     return ret;
> > +}
> > +
> >  /**
> >   *   aac_command_thread      -       command processing thread
> >   *   @dev: Adapter to monitor
> > @@ -2001,7 +2139,7 @@ int aac_command_thread(void *data)
> >
> >                       /* Don't even try to talk to adapter if its sick */
> >                       ret = aac_check_health(dev);
> > -                     if (!ret && !dev->queues)
> > +                     if (!dev->queues)
> >                               break;
> >                       next_check_jiffies = jiffies
> >                                          + ((long)(unsigned)check_interval)
> > @@ -2014,36 +2152,12 @@ int aac_command_thread(void *data)
> >                               difference = (((1000000 - now.tv_usec) * HZ)
> >                                 + 500000) / 1000000;
> >                       else if (ret == 0) {
> > -                             struct fib *fibptr;
> > -
> > -                             if ((fibptr = aac_fib_alloc(dev))) {
> > -                                     int status;
> > -                                     __le32 *info;
> > -
> > -                                     aac_fib_init(fibptr);
> > -
> > -                                     info = (__le32 *) fib_data(fibptr);
> > -                                     if (now.tv_usec > 500000)
> > -                                             ++now.tv_sec;
> > -
> > -                                     *info = cpu_to_le32(now.tv_sec);
> > -
> > -                                     status = aac_fib_send(SendHostTime,
> > -                                             fibptr,
> > -                                             sizeof(*info),
> > -                                             FsaNormal,
> > -                                             1, 1,
> > -                                             NULL,
> > -                                             NULL);
> > -                                     /* Do not set XferState to zero unless
> > -                                      * receives a response from F/W */
> > -                                     if (status >= 0)
> > -                                             aac_fib_complete(fibptr);
> > -                                     /* FIB should be freed only after
> > -                                      * getting the response from the F/W */
> > -                                     if (status != -ERESTARTSYS)
> > -                                             aac_fib_free(fibptr);
> > -                             }
> > +
> > +                             if (now.tv_usec > 500000)
> > +                                     ++now.tv_sec;
> > +
> > +                             ret = aac_send_hosttime(dev, &now);
> > +
> >                               difference = (long)(unsigned)update_interval*HZ;
> >                       } else {
> >                               /* retry shortly */

Thank you,
Raghava Aditya

> > --
> > 2.7.4
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 10/24] aacraid: Reworked aac_command_thread
  2017-01-30 10:11   ` Johannes Thumshirn
@ 2017-01-30 20:11     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:11 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 2:11 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 10/24] aacraid: Reworked aac_command_thread
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:39AM -0800, Raghava Aditya Renukunta wrote:
> > Reworked aac_command_thread into aac_process_events
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> Wow, thanks for factoring this out.
> 
> > +static void aac_process_events(struct aac_dev *dev)
> > +{
> > +     struct hw_fib *hw_fib, *hw_newfib;
> > +     struct fib *fib, *newfib;
> > +     struct aac_fib_context *fibctx;
> > +     unsigned long flags;
> > +     spinlock_t *t_lock;
> > +
> 
>         t_lock = dev->queues->queue[HostNormCmdQueue].lock;
>         spin_lock_irqsave(t_lock, flags);

Yes, let me change this peace of code.

> > +     spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock,
> flags);
> > +     while (!list_empty(&(dev->queues-
> >queue[HostNormCmdQueue].cmdq))) {
> > +             struct list_head *entry;
> > +             struct aac_aifcmd *aifcmd;
> > +             u32 time_now, time_last;
> > +             unsigned long flagv;
> > +             unsigned int  num;
> > +             struct hw_fib **hw_fib_pool, **hw_fib_p;
> > +             struct fib **fib_pool, **fib_p;
> > +
> > +             set_current_state(TASK_RUNNING);
> > +
> > +             entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;
> > +             list_del(entry);
> > +
> > +
> > +             t_lock = dev->queues->queue[HostNormCmdQueue].lock;
> > +             spin_unlock_irqrestore(t_lock, flags);
> > +
> > +             fib = list_entry(entry, struct fib, fiblink);
> > +             hw_fib = fib->hw_fib_va;
> > +             /*
> > +              *      We will process the FIB here or pass it to a
> > +              *      worker thread that is TBD. We Really can't
> > +              *      do anything at this point since we don't have
> > +              *      anything defined for this thread to do.
> > +              */
> > +             memset(fib, 0, sizeof(struct fib));
> > +             fib->type = FSAFS_NTC_FIB_CONTEXT;
> > +             fib->size = sizeof(struct fib);
> > +             fib->hw_fib_va = hw_fib;
> > +             fib->data = hw_fib->data;
> > +             fib->dev = dev;
> > +             /*
> > +              *      We only handle AifRequest fibs from the adapter.
> > +              */
> > +
> > +             aifcmd = (struct aac_aifcmd *) hw_fib->data;
> > +             if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {
> > +                     /* Handle Driver Notify Events */
> > +                     aac_handle_aif(dev, fib);
> > +                     *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> > +                     aac_fib_adapter_complete(fib, (u16)sizeof(u32));
> > +                     continue;
> > +             }
> > +             /*
> > +              * The u32 here is important and intended. We are using
> > +              * 32bit wrapping time to fit the adapter field
> > +              */
> > +
> > +
> > +             /* Sniff events */
> > +             if ((aifcmd->command == cpu_to_le32(AifCmdEventNotify)) ||
> > +                             (aifcmd->command ==
> > +                             cpu_to_le32(AifCmdJobProgress))) {
> 
> Parenthesis and indentation.

Yes I will make the  changes.

> 
> > +                     aac_handle_aif(dev, fib);
> > +             }
> > +
> > +             time_now = jiffies/HZ;
> > +
> > +             /*
> > +              * Warning: no sleep allowed while
> > +              * holding spinlock. We take the estimate
> > +              * and pre-allocate a set of fibs outside the
> > +              * lock.
> > +              */
> > +             num = le32_to_cpu(dev->init->r7.adapter_fibs_size)
> > +                             / sizeof(struct hw_fib); /* some extra */
> > +             spin_lock_irqsave(&dev->fib_lock, flagv);
> > +             entry = dev->fib_list.next;
> > +             while (entry != &dev->fib_list) {
> > +                     entry = entry->next;
> > +                     ++num;
> > +             }
> > +             spin_unlock_irqrestore(&dev->fib_lock, flagv);
> 
> Bonus points for getting the estimation of the fibs into an own function.
> From
> the start of the comment till the spin_unlock().
Ok , let me do that.
> 
> > +             hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *),
> > +                                             GFP_KERNEL);
> > +             fib_pool = kmalloc_array(num, sizeof(struct fib *),
> > +                                             GFP_KERNEL);
> > +             if (num && fib_pool && hw_fib_pool) {
> 
> Ditto for the following block (this would have the benefit of describing what
> the block does).
Acknowledged 
> 
> > +                     hw_fib_p = hw_fib_pool;
> > +                     fib_p = fib_pool;
> > +                     while (hw_fib_p < &hw_fib_pool[num]) {
> > +                             *(hw_fib_p) = kmalloc(sizeof(struct hw_fib),
> > +                                             GFP_KERNEL);
> > +                             if (!(*(hw_fib_p++))) {
> > +                                     --hw_fib_p;
> > +                                     break;
> > +                             }
> > +                             *(fib_p) = kmalloc(sizeof(struct fib),
> > +                                             GFP_KERNEL);
> > +                             if (!(*(fib_p++))) {
> > +                                     kfree(*(--hw_fib_p));
> > +                                     break;
> > +                             }
> > +                     }
> > +                     num = hw_fib_p - hw_fib_pool;
> > +                     if (!num) {
> > +                             kfree(fib_pool);
> > +                             fib_pool = NULL;
> > +                             kfree(hw_fib_pool);
> > +                             hw_fib_pool = NULL;
> > +                             continue;
> > +                     }
> > +             } else {
> > +                     kfree(hw_fib_pool);
> > +                     hw_fib_pool = NULL;
> > +                     kfree(fib_pool);
> > +                     fib_pool = NULL;
> > +             }
> 
> And for either everything under the fib_lock or the while loop.

Acknowledged. 

> > +             spin_lock_irqsave(&dev->fib_lock, flagv);
> > +             entry = dev->fib_list.next;
> > +             /*
> > +              * For each Context that is on the
> > +              * fibctxList, make a copy of the
> > +              * fib, and then set the event to wake up the
> > +              * thread that is waiting for it.
> > +              */
> > +             hw_fib_p = hw_fib_pool;
> > +             fib_p = fib_pool;
> > +             while (entry != &dev->fib_list) {
> > +                     /*
> > +                      * Extract the fibctx
> > +                      */
> > +                     fibctx = list_entry(entry, struct aac_fib_context,
> > +                                     next);
> > +                     /*
> > +                      * Check if the queue is getting
> > +                      * backlogged
> > +                      */
> > +                     if (fibctx->count > 20) {
> > +                             /*
> > +                              * It's *not* jiffies folks,
> > +                              * but jiffies / HZ so do not
> > +                              * panic ...
> > +                              */
> > +                             time_last = fibctx->jiffies;
> > +                             /*
> > +                              * Has it been > 2 minutes
> > +                              * since the last read off
> > +                              * the queue?
> > +                              */
> > +                             if ((time_now - time_last) > aif_timeout) {
> > +                                     entry = entry->next;
> > +                                     aac_close_fib_context(dev, fibctx);
> > +                                     continue;
> > +                             }
> > +                     }
> > +                     /*
> > +                      * Warning: no sleep allowed while
> > +                      * holding spinlock
> > +                      */
> > +                     if (hw_fib_p < &hw_fib_pool[num]) {
> > +                             hw_newfib = *hw_fib_p;
> > +                             *(hw_fib_p++) = NULL;
> > +                             newfib = *fib_p;
> > +                             *(fib_p++) = NULL;
> > +                             /*
> > +                              * Make the copy of the FIB
> > +                              */
> > +                             memcpy(hw_newfib, hw_fib,
> > +                                     sizeof(struct hw_fib));
> > +                             memcpy(newfib, fib, sizeof(struct fib));
> > +                             newfib->hw_fib_va = hw_newfib;
> > +                             /*
> > +                              * Put the FIB onto the
> > +                              * fibctx's fibs
> > +                              */
> > +                             list_add_tail(&newfib->fiblink,
> > +                                     &fibctx->fib_list);
> > +                             fibctx->count++;
> > +                             /*
> > +                              * Set the event to wake up the
> > +                              * thread that is waiting.
> > +                              */
> > +                             up(&fibctx->wait_sem);
> > +                     } else {
> > +                             pr_warn("aifd: didn't allocate NewFib.\n");
> > +                     }
> > +                     entry = entry->next;
> > +             }
> > +             /*
> > +              *      Set the status of this FIB
> > +              */
> > +             *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
> > +             aac_fib_adapter_complete(fib, sizeof(u32));
> > +             spin_unlock_irqrestore(&dev->fib_lock, flagv);
> > +             /* Free up the remaining resources */
> > +             hw_fib_p = hw_fib_pool;
> > +             fib_p = fib_pool;
> > +             while (hw_fib_p < &hw_fib_pool[num]) {
> > +                     kfree(*hw_fib_p);
> > +                     kfree(*fib_p);
> > +                     ++fib_p;
> > +                     ++hw_fib_p;
> > +             }
> > +             kfree(hw_fib_pool);
> > +             kfree(fib_pool);
> > +             kfree(fib);
> > +             spin_lock_irqsave(dev->queues-
> >queue[HostNormCmdQueue].lock,
> > +                             flags);
> > +     }
> > +     /*
> > +      *      There are no more AIF's
> > +      */
> > +     spin_unlock_irqrestore(dev->queues-
> >queue[HostNormCmdQueue].lock,
> > +                     flags);
> > +}
> 
> [...]
> 
> Thanks,
> this change is highly appreciated by me
> 
>         Johannes
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 08/24] aacraid: Added support for response path
  2017-01-30  9:50   ` Johannes Thumshirn
@ 2017-01-30 20:16     ` Raghava Aditya Renukunta
  2017-01-31  8:02       ` Johannes Thumshirn
  0 siblings, 1 reply; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:16 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 1:50 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 08/24] aacraid: Added support for response path
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:37AM -0800, Raghava Aditya Renukunta wrote:
> > This patch enables the driver to actually process the I/O, or srb replies
> > from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <raghavaaditya.renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> Sorry for not completely reviewing the patchset before you reposted.
> 
> > @@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev)
> >
> >       if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
> >               maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
> > -     fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) *
> maximum_num_containers,
> > -                     GFP_KERNEL);
> > -     if (!fsa_dev_ptr)
> > -             return -ENOMEM;
> > +     if ((dev->fsa_dev == NULL) ||
> > +             (dev->maximum_num_containers != maximum_num_containers))
> {
> > +
> > +             fsa_dev_ptr = dev->fsa_dev;
> 
> Comparison has precedence over logical OR. See
> http://en.cppreference.com/w/c/language/operator_precedence

Acknowledged.  , I will remove the parentheses.
The idea was to make it easier to read the code , if there were enclosed in 
Parenthesis  (I dabbled a bit in lisp , and for me brackets makes it easier to read).

> 
> >
> > -     dev->fsa_dev = fsa_dev_ptr;
> > -     dev->maximum_num_containers = maximum_num_containers;
> > +             dev->fsa_dev = kzalloc(sizeof(*fsa_dev_ptr) *
> > +                             maximum_num_containers, GFP_KERNEL);
> 
> kcalloc()?

Yes kcalloc makes sense, but then an additional mem set would be required.
Unless there is a kzcalloc or kczalloc?


> [...]
> 
> 
> > @@ -251,8 +250,9 @@ static void aac_aif_callback(void *context, struct fib
> * fibptr)
> >       BUG_ON(fibptr == NULL);
> >       dev = fibptr->dev;
> >
> > -     if (fibptr->hw_fib_va->header.XferState &
> > -         cpu_to_le32(NoMoreAifDataAvailable)) {
> > +     if ((fibptr->hw_fib_va->header.XferState &
> > +         cpu_to_le32(NoMoreAifDataAvailable)) ||
> > +             dev->sa_firmware) {
> 
> Again unnecessary parenthesis.

> >               aac_fib_complete(fibptr);
> >               aac_fib_free(fibptr);
> >               return;
> > @@ -282,8 +282,8 @@ static void aac_aif_callback(void *context, struct fib
> * fibptr)
> >   *   know there is a response on our normal priority queue. We will pull off
> >   *   all QE there are and wake up all the waiters before exiting.
> >   */
> > -unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
> > -                     int isAif, int isFastResponse, struct hw_fib *aif_fib)
> > +unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
> > +     int isFastResponse, struct hw_fib *aif_fib)
> 
> Isn't this exactly the same but now with broken indent?

It is, I tried removing stuff like this before sending the patches, must have
snuck in. I will remove it. 

Regards,
Raghava Aditya

> [...]
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* RE: [PATCH V3 06/24] aacraid: Reworked scsi command submission path
  2017-01-30  9:38   ` Johannes Thumshirn
@ 2017-01-30 20:17     ` Raghava Aditya Renukunta
  0 siblings, 0 replies; 55+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-30 20:17 UTC (permalink / raw)
  To: Johannes Thumshirn
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh



> -----Original Message-----
> From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> Sent: Monday, January 30, 2017 1:38 AM
> To: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> <scott.benesh@microsemi.com>
> Subject: Re: [PATCH V3 06/24] aacraid: Reworked scsi command submission
> path
> 
> EXTERNAL EMAIL
> 
> 
> On Fri, Jan 27, 2017 at 11:28:35AM -0800, Raghava Aditya Renukunta wrote:
> > Moved the READ and WRITE switch cases to the top. Added a  default
> > case to the switch case and replaced duplicate scsi result value with a
> > macro.
> >
> > Signed-off-by: Raghava Aditya Renukunta
> <RaghavaAditya.Renukunta@microsemi.com>
> > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> >
> > ---
> 
> I really whished this one had a better commit message (not only explaining
> what you've changes but also why you did it).
> 
> But if this is the only issue there's hardly a reason to repost.

Oh let me rewrite the description to include the reasoning as well.
Regards,
Raghava Aditya

> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
> 
> --
> Johannes Thumshirn                                          Storage
> jthumshirn@suse.de                                +49 911 74053 689
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: Felix Imendörffer, Jane Smithard, Graham Norton
> HRB 21284 (AG Nürnberg)
> Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

* Re: [PATCH V3 08/24] aacraid: Added support for response path
  2017-01-30 20:16     ` Raghava Aditya Renukunta
@ 2017-01-31  8:02       ` Johannes Thumshirn
  0 siblings, 0 replies; 55+ messages in thread
From: Johannes Thumshirn @ 2017-01-31  8:02 UTC (permalink / raw)
  To: Raghava Aditya Renukunta
  Cc: jejb, martin.petersen, linux-scsi, Dave Carroll, Gana Sridaran,
	Scott Benesh

On Mon, Jan 30, 2017 at 08:16:48PM +0000, Raghava Aditya Renukunta wrote:
> 
> 
> > -----Original Message-----
> > From: Johannes Thumshirn [mailto:jthumshirn@suse.de]
> > Sent: Monday, January 30, 2017 1:50 AM
> > To: Raghava Aditya Renukunta
> > <RaghavaAditya.Renukunta@microsemi.com>
> > Cc: jejb@linux.vnet.ibm.com; martin.petersen@oracle.com; linux-
> > scsi@vger.kernel.org; Dave Carroll <david.carroll@microsemi.com>; Gana
> > Sridaran <gana.sridaran@microsemi.com>; Scott Benesh
> > <scott.benesh@microsemi.com>
> > Subject: Re: [PATCH V3 08/24] aacraid: Added support for response path
> > 
> > EXTERNAL EMAIL
> > 
> > 
> > On Fri, Jan 27, 2017 at 11:28:37AM -0800, Raghava Aditya Renukunta wrote:
> > > This patch enables the driver to actually process the I/O, or srb replies
> > > from adapter. In addition to any HBA1000 or SmartIOC2000 adapter events.
> > >
> > > Signed-off-by: Raghava Aditya Renukunta
> > <raghavaaditya.renukunta@microsemi.com>
> > > Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
> > >
> > > ---
> > 
> > Sorry for not completely reviewing the patchset before you reposted.
> > 
> > > @@ -475,16 +475,26 @@ int aac_get_containers(struct aac_dev *dev)
> > >
> > >       if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
> > >               maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
> > > -     fsa_dev_ptr = kzalloc(sizeof(*fsa_dev_ptr) *
> > maximum_num_containers,
> > > -                     GFP_KERNEL);
> > > -     if (!fsa_dev_ptr)
> > > -             return -ENOMEM;
> > > +     if ((dev->fsa_dev == NULL) ||
> > > +             (dev->maximum_num_containers != maximum_num_containers))
> > {
> > > +
> > > +             fsa_dev_ptr = dev->fsa_dev;
> > 
> > Comparison has precedence over logical OR. See
> > http://en.cppreference.com/w/c/language/operator_precedence
> 
> Acknowledged.  , I will remove the parentheses.
> The idea was to make it easier to read the code , if there were enclosed in 
> Parenthesis  (I dabbled a bit in lisp , and for me brackets makes it easier to read).

I think it makes it a bit less obvious and yes it kinda looks like LISP,
you're right.

> 
> > 
> > >
> > > -     dev->fsa_dev = fsa_dev_ptr;
> > > -     dev->maximum_num_containers = maximum_num_containers;
> > > +             dev->fsa_dev = kzalloc(sizeof(*fsa_dev_ptr) *
> > > +                             maximum_num_containers, GFP_KERNEL);
> > 
> > kcalloc()?
> 
> Yes kcalloc makes sense, but then an additional mem set would be required.
> Unless there is a kzcalloc or kczalloc?

No kcalloc() (and it's user-space counterpart calloc() give you zeroed out
memory). If you don't want a zero-fill kmalloc_array() would be the way to go.

Thanks for taking care of that,
	Johannes

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 55+ messages in thread

end of thread, other threads:[~2017-01-31  8:03 UTC | newest]

Thread overview: 55+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-27 19:28 [PATCH V3 00/24] aacraid: Patchset for Smart Family Support Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 02/24] aacraid: Added aacraid.h include guard Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
2017-01-30  9:15   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
2017-01-30  9:23   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
2017-01-30  9:35   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
2017-01-30  9:38   ` Johannes Thumshirn
2017-01-30 20:17     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 07/24] aacraid: Process Error for response I/O Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
2017-01-30  9:50   ` Johannes Thumshirn
2017-01-30 20:16     ` Raghava Aditya Renukunta
2017-01-31  8:02       ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 09/24] aacraid: Added support for read medium error Raghava Aditya Renukunta
2017-01-30  9:55   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 10/24] aacraid: Reworked aac_command_thread Raghava Aditya Renukunta
2017-01-30 10:11   ` Johannes Thumshirn
2017-01-30 20:11     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 11/24] aacraid: Added support for periodic wellness sync Raghava Aditya Renukunta
2017-01-30 10:27   ` Johannes Thumshirn
2017-01-30 20:07     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 12/24] aacraid: Retrieve Queue Depth from Adapter FW Raghava Aditya Renukunta
2017-01-30 10:31   ` Johannes Thumshirn
2017-01-30 20:05     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 13/24] aacraid: Added support to set QD of attached drives Raghava Aditya Renukunta
2017-01-30 10:39   ` Johannes Thumshirn
2017-01-30 20:01     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 14/24] aacraid: Added support for hotplug Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 15/24] aacraid: Include HBA direct interface Raghava Aditya Renukunta
2017-01-30 11:02   ` Johannes Thumshirn
2017-01-30 20:00     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 16/24] aacraid: Add task management functionality Raghava Aditya Renukunta
2017-01-30 11:19   ` Johannes Thumshirn
2017-01-30 19:59     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 17/24] aacraid: Added support to abort cmd and reset lun Raghava Aditya Renukunta
2017-01-30 11:24   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 18/24] aacraid: VPD 83 type3 support Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 19/24] aacraid: Added new IWBR reset Raghava Aditya Renukunta
2017-01-30 11:39   ` Johannes Thumshirn
2017-01-30 19:56     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 20/24] aacraid: Added ioctl to trigger IOP/IWBR reset Raghava Aditya Renukunta
2017-01-30 11:41   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 21/24] aacraid: Retrieve HBA host information ioctl Raghava Aditya Renukunta
2017-01-30 11:43   ` Johannes Thumshirn
2017-01-30 19:53     ` Raghava Aditya Renukunta
2017-01-27 19:28 ` [PATCH V3 22/24] aacraid: Update copyrights Raghava Aditya Renukunta
2017-01-30 11:43   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 23/24] aacraid: Change Driver Version Prefix Raghava Aditya Renukunta
2017-01-30 11:44   ` Johannes Thumshirn
2017-01-27 19:28 ` [PATCH V3 24/24] aacraid: update version Raghava Aditya Renukunta
2017-01-30 11:44   ` Johannes Thumshirn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.