* [PATCH V2 00/24] aacraid: Patchset for Smart Family support
@ 2017-01-25 18:00 Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
` (23 more replies)
0 siblings, 24 replies; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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
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 | 329 +++++-----
drivers/scsi/aacraid/commsup.c | 901 +++++++++++++++++++--------
drivers/scsi/aacraid/dpcsup.c | 159 +++--
drivers/scsi/aacraid/linit.c | 554 +++++++++++------
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, 3387 insertions(+), 1210 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 39+ messages in thread
* [PATCH V2 01/24] aacraid: Remove duplicate irq management code
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 8:26 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 02/24] aacraid: Added aacraid.h include guard Raghava Aditya Renukunta
` (22 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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>
---
Changes in V2:
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] 39+ messages in thread
* [PATCH V2 02/24] aacraid: Added aacraid.h include guard
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 8:27 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
` (21 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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>
---
Changes in V2:
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] 39+ messages in thread
* [PATCH V2 03/24] aacraid: added support for init_struct_8
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 01/24] aacraid: Remove duplicate irq management code Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 02/24] aacraid: Added aacraid.h include guard Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 8:37 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
` (20 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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
drivers/scsi/aacraid/aachba.c | 8 +-
drivers/scsi/aacraid/aacraid.h | 100 +++++++++++------
drivers/scsi/aacraid/comminit.c | 238 +++++++++++++++++++++++++---------------
drivers/scsi/aacraid/commsup.c | 12 +-
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, 259 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..32888a4 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 InitStructRevision;
+ __le32 NoOfMSIXVectors;
+ __le32 fsrev;
+ __le32 CommHeaderAddress;
+ __le32 FastIoCommAreaAddress;
+ __le32 AdapterFibsPhysicalAddress;
+ __le32 AdapterFibsVirtualAddress;
+ __le32 AdapterFibsSize;
+ __le32 AdapterFibAlign;
+ __le32 printfbuf;
+ __le32 printfbufsiz;
+ /* number of 4k pages of host phys. mem. */
+ __le32 HostPhysMemPages;
+ /* number of seconds since 1970. */
+ __le32 HostElapsedSeconds;
+ /* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
+ __le32 InitFlags; /* 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 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 */
+ /* Host RRQ (response queue) for SRC */
+ __le32 HostRRQ_AddrLow;
+ __le32 HostRRQ_AddrHigh;
+ } r7;
+ struct _r8 {
+ /* ADAPTER_INIT_STRUCT_REVISION_8 */
+ __le32 InitStructRevision;
+ __le32 RRQueueCount;
+ __le32 HostElapsedSeconds; /* number of seconds since 1970. */
+ __le32 InitFlags;
+ __le32 MaxIoSize; /* largest I/O command */
+ __le32 MaxNumAif; /* max number of aif */
+ __le32 Reserved1;
+ __le32 Reserved2;
+ struct _rrq {
+ __le32 Host_AddrLow;
+ __le32 Host_AddrHigh;
+ __le16 MSIX_Id;
+ __le16 ElementCount;
+ __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..a59e23b 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -68,104 +68,166 @@ 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.InitStructRevision =
+ cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_8);
+ init->r8.InitFlags = cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+ INITFLAGS_DRIVER_USES_UTC_TIME |
+ INITFLAGS_DRIVER_SUPPORTS_PM);
+ init->r8.InitFlags |=
+ cpu_to_le32(INITFLAGS_DRIVER_SUPPORTS_HBA_MODE);
+ init->r8.RRQueueCount = cpu_to_le32(dev->max_msix);
+ init->r8.MaxIoSize =
+ cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
+ init->r8.MaxNumAif = 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_AddrHigh = cpu_to_le32(
+ upper_32_bits(addr));
+ init->r8.rrq[i].Host_AddrLow = cpu_to_le32(
+ lower_32_bits(addr));
+ init->r8.rrq[i].MSIX_Id = i;
+ init->r8.rrq[i].ElementCount = 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.InitStructRevision =
+ cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
+ if (dev->max_fib_size != sizeof(struct hw_fib))
+ init->r7.InitStructRevision =
+ cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
+ init->r7.NoOfMSIXVectors = 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.AdapterFibsVirtualAddress = 0;
+ init->r7.AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
+ init->r7.AdapterFibsSize = cpu_to_le32(fibsize);
+ init->r7.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->r7.HostPhysMemPages =
+ cpu_to_le32(aac_max_hostphysmempages);
+ else
+ init->r7.HostPhysMemPages =
+ cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
+
+ init->r7.InitFlags =
+ cpu_to_le32(INITFLAGS_DRIVER_USES_UTC_TIME |
+ INITFLAGS_DRIVER_SUPPORTS_PM);
+ init->r7.MaxIoCommands =
+ cpu_to_le32(dev->scsi_host_ptr->can_queue +
+ AAC_NUM_MGT_FIB);
+ init->r7.MaxIoSize =
+ cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
+ init->r7.MaxFibSize = cpu_to_le32(dev->max_fib_size);
+ init->r7.MaxNumAif = cpu_to_le32(dev->max_num_aif);
+
+ if (dev->comm_interface == AAC_COMM_MESSAGE) {
+ init->r7.InitFlags |=
+ 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.InitStructRevision =
+ cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_6);
+ init->r7.InitFlags |=
+ cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+ INITFLAGS_NEW_COMM_TYPE1_SUPPORTED |
+ INITFLAGS_FAST_JBOD_SUPPORTED);
+ init->r7.HostRRQ_AddrHigh =
+ cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
+ init->r7.HostRRQ_AddrLow =
+ 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.InitStructRevision =
+ cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_7);
+ init->r7.InitFlags |=
+ cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED |
+ INITFLAGS_NEW_COMM_TYPE2_SUPPORTED |
+ INITFLAGS_FAST_JBOD_SUPPORTED);
+ init->r7.HostRRQ_AddrHigh =
+ cpu_to_le32(upper_32_bits(dev->host_rrq_pa));
+ init->r7.HostRRQ_AddrLow =
+ cpu_to_le32(lower_32_bits(dev->host_rrq_pa));
+ init->r7.NoOfMSIXVectors = 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 +239,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.CommHeaderAddress = cpu_to_le32((u32)phys);
/*
* Increment the base address by the size of the CommArea
*/
@@ -187,12 +250,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 +501,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..e37dfa5 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.MaxIoCommands = 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,7 @@ 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.AdapterFibsSize)
/ 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..625c17f 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.NoOfMSIXVectors = 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..d57ac43 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.MaxIoCommands =
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..9810509 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.HostElapsedSeconds = 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..2c9629d 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.HostElapsedSeconds = 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..92c55e9 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.HostElapsedSeconds = 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.HostElapsedSeconds = 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] 39+ messages in thread
* [PATCH V2 04/24] aacraid: Added sa firmware support
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (2 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 03/24] aacraid: added support for init_struct_8 Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 8:55 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
` (19 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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
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 32888a4..057ff78 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 a59e23b..407ccf0 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;
@@ -465,9 +473,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)
{
@@ -526,6 +538,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);
@@ -562,61 +580,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 625c17f..e2d063d 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] 39+ messages in thread
* [PATCH V2 05/24] aacraid: Retrieve and update the device types
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (3 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 04/24] aacraid: Added sa firmware support Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 8:59 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
` (18 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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>
---
Changes in V2:
Fixed uninitialized return value
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..64cd4cb 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 057ff78..8c6c4ac 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] 39+ messages in thread
* [PATCH V2 06/24] aacraid: Reworked scsi command submission path
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (4 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 05/24] aacraid: Retrieve and update the device types Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 9:05 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 07/24] aacraid: Process Error for response I/O Raghava Aditya Renukunta
` (17 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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
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 64cd4cb..4be245d 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] 39+ messages in thread
* [PATCH V2 07/24] aacraid: Process Error for response I/O
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (5 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 06/24] aacraid: Reworked scsi command submission path Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-26 9:06 ` Johannes Thumshirn
2017-01-25 18:00 ` [PATCH V2 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
` (16 subsequent siblings)
23 siblings, 1 reply; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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>
---
Changes in V2:
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 4be245d..bdc5b7a 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] 39+ messages in thread
* [PATCH V2 08/24] aacraid: Added support for response path
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (6 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 07/24] aacraid: Process Error for response I/O Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 09/24] aacraid: Added support for read medium error Raghava Aditya Renukunta
` (15 subsequent siblings)
23 siblings, 0 replies; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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
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 bdc5b7a..48a4336 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 8c6c4ac..f749215 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 e37dfa5..31c65ca 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 92c55e9..af31c09 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] 39+ messages in thread
* [PATCH V2 09/24] aacraid: Added support for read medium error
2017-01-25 18:00 [PATCH V2 00/24] aacraid: Patchset for Smart Family support Raghava Aditya Renukunta
` (7 preceding siblings ...)
2017-01-25 18:00 ` [PATCH V2 08/24] aacraid: Added support for response path Raghava Aditya Renukunta
@ 2017-01-25 18:00 ` Raghava Aditya Renukunta
2017-01-25 18:00 ` [PATCH V2 10/24] aacraid: Reworked aac_command_thread Raghava Aditya Renukunta
` (14 subsequent siblings)
23 siblings, 0 replies; 39+ messages in thread
From: Raghava Aditya Renukunta @ 2017-01-25 18:00 UTC (permalink / raw)
To: jejb, martin.petersen, linux-scsi
Cc: David.Carroll, Gana.Sridaran, RaghavaAditya.Renukunta,
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