You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley: "This update includes the usual round of major driver updates (ncr5380, ufs, lpfc, be2iscsi, hisi_sas, storvsc, cxlflash, aacraid, megaraid_sas, ...). There's also an assortment of minor fixes and the major update of switching a bunch of drivers to pci_alloc_irq_vectors from Christoph" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (188 commits) scsi: megaraid_sas: handle dma_addr_t right on 32-bit scsi: megaraid_sas: array overflow in megasas_dump_frame() scsi: snic: switch to pci_irq_alloc_vectors scsi: megaraid_sas: driver version upgrade scsi: megaraid_sas: Change RAID_1_10_RMW_CMDS to RAID_1_PEER_CMDS and set value to 2 scsi: megaraid_sas: Indentation and smatch warning fixes scsi: megaraid_sas: Cleanup VD_EXT_DEBUG and SPAN_DEBUG related debug prints scsi: megaraid_sas: Increase internal command pool scsi: megaraid_sas: Use synchronize_irq to wait for IRQs to complete scsi: megaraid_sas: Bail out the driver load if ld_list_query fails scsi: megaraid_sas: Change build_mpt_mfi_pass_thru to return void scsi: megaraid_sas: During OCR, if get_ctrl_info fails do not continue with OCR scsi: megaraid_sas: Do not set fp_possible if TM capable for non-RW syspdIO, change fp_possible to bool scsi: megaraid_sas: Remove unused pd_index from megasas_build_ld_nonrw_fusion scsi: megaraid_sas: megasas_return_cmd does not memset IO frame to zero scsi: megaraid_sas: max_fw_cmds are decremented twice, remove duplicate scsi: megaraid_sas: update can_queue only if the new value is less scsi: megaraid_sas: Change max_cmd from u32 to u16 in all functions scsi: megaraid_sas: set pd_after_lb from MR_BuildRaidContext and initialize pDevHandle to MR_DEVHANDLE_INVALID scsi: megaraid_sas: latest controller OCR capability from FW before sending shutdown DCMD ...
This commit is contained in:
@@ -549,6 +549,7 @@ enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd)
|
||||
DPRINTK("EXIT, ret=%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ata_scsi_timed_out);
|
||||
|
||||
static void ata_eh_unload(struct ata_port *ap)
|
||||
{
|
||||
|
||||
@@ -716,7 +716,6 @@ struct scsi_transport_template *ata_attach_transport(void)
|
||||
return NULL;
|
||||
|
||||
i->t.eh_strategy_handler = ata_scsi_error;
|
||||
i->t.eh_timed_out = ata_scsi_timed_out;
|
||||
i->t.user_scan = ata_scsi_user_scan;
|
||||
|
||||
i->t.host_attrs.ac.attrs = &i->port_attrs[0];
|
||||
|
||||
@@ -159,7 +159,6 @@ extern unsigned long ata_internal_cmd_timeout(struct ata_device *dev, u8 cmd);
|
||||
extern void ata_internal_cmd_timed_out(struct ata_device *dev, u8 cmd);
|
||||
extern void ata_eh_acquire(struct ata_port *ap);
|
||||
extern void ata_eh_release(struct ata_port *ap);
|
||||
extern enum blk_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
|
||||
extern void ata_scsi_error(struct Scsi_Host *host);
|
||||
extern void ata_eh_fastdrain_timerfn(unsigned long arg);
|
||||
extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
|
||||
|
||||
+15
-15
@@ -400,27 +400,27 @@ static bool SA5_performant_intr_pending(ctlr_info_t *h)
|
||||
}
|
||||
|
||||
static struct access_method SA5_access = {
|
||||
SA5_submit_command,
|
||||
SA5_intr_mask,
|
||||
SA5_fifo_full,
|
||||
SA5_intr_pending,
|
||||
SA5_completed,
|
||||
.submit_command = SA5_submit_command,
|
||||
.set_intr_mask = SA5_intr_mask,
|
||||
.fifo_full = SA5_fifo_full,
|
||||
.intr_pending = SA5_intr_pending,
|
||||
.command_completed = SA5_completed,
|
||||
};
|
||||
|
||||
static struct access_method SA5B_access = {
|
||||
SA5_submit_command,
|
||||
SA5B_intr_mask,
|
||||
SA5_fifo_full,
|
||||
SA5B_intr_pending,
|
||||
SA5_completed,
|
||||
.submit_command = SA5_submit_command,
|
||||
.set_intr_mask = SA5B_intr_mask,
|
||||
.fifo_full = SA5_fifo_full,
|
||||
.intr_pending = SA5B_intr_pending,
|
||||
.command_completed = SA5_completed,
|
||||
};
|
||||
|
||||
static struct access_method SA5_performant_access = {
|
||||
SA5_submit_command,
|
||||
SA5_performant_intr_mask,
|
||||
SA5_fifo_full,
|
||||
SA5_performant_intr_pending,
|
||||
SA5_performant_completed,
|
||||
.submit_command = SA5_submit_command,
|
||||
.set_intr_mask = SA5_performant_intr_mask,
|
||||
.fifo_full = SA5_fifo_full,
|
||||
.intr_pending = SA5_performant_intr_pending,
|
||||
.command_completed = SA5_performant_completed,
|
||||
};
|
||||
|
||||
struct board_type {
|
||||
|
||||
@@ -994,6 +994,7 @@ static struct scsi_host_template iscsi_iser_sht = {
|
||||
.change_queue_depth = scsi_change_queue_depth,
|
||||
.sg_tablesize = ISCSI_ISER_DEF_SG_TABLESIZE,
|
||||
.cmd_per_lun = ISER_DEF_CMD_PER_LUN,
|
||||
.eh_timed_out = iscsi_eh_cmd_timed_out,
|
||||
.eh_abort_handler = iscsi_eh_abort,
|
||||
.eh_device_reset_handler= iscsi_eh_device_reset,
|
||||
.eh_target_reset_handler = iscsi_eh_recover_target,
|
||||
|
||||
@@ -2869,6 +2869,7 @@ static struct scsi_host_template srp_template = {
|
||||
.info = srp_target_info,
|
||||
.queuecommand = srp_queuecommand,
|
||||
.change_queue_depth = srp_change_queue_depth,
|
||||
.eh_timed_out = srp_timed_out,
|
||||
.eh_abort_handler = srp_abort,
|
||||
.eh_device_reset_handler = srp_reset_device,
|
||||
.eh_host_reset_handler = srp_reset_host,
|
||||
|
||||
@@ -119,6 +119,7 @@ static struct scsi_host_template mptfc_driver_template = {
|
||||
.target_destroy = mptfc_target_destroy,
|
||||
.slave_destroy = mptscsih_slave_destroy,
|
||||
.change_queue_depth = mptscsih_change_queue_depth,
|
||||
.eh_timed_out = fc_eh_timed_out,
|
||||
.eh_abort_handler = mptfc_abort,
|
||||
.eh_device_reset_handler = mptfc_dev_reset,
|
||||
.eh_bus_reset_handler = mptfc_bus_reset,
|
||||
|
||||
@@ -65,7 +65,6 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
@@ -1983,6 +1983,7 @@ static struct scsi_host_template mptsas_driver_template = {
|
||||
.target_destroy = mptsas_target_destroy,
|
||||
.slave_destroy = mptscsih_slave_destroy,
|
||||
.change_queue_depth = mptscsih_change_queue_depth,
|
||||
.eh_timed_out = mptsas_eh_timed_out,
|
||||
.eh_abort_handler = mptscsih_abort,
|
||||
.eh_device_reset_handler = mptscsih_dev_reset,
|
||||
.eh_host_reset_handler = mptscsih_host_reset,
|
||||
@@ -5398,7 +5399,6 @@ mptsas_init(void)
|
||||
sas_attach_transport(&mptsas_transport_functions);
|
||||
if (!mptsas_transport_template)
|
||||
return -ENODEV;
|
||||
mptsas_transport_template->eh_timed_out = mptsas_eh_timed_out;
|
||||
|
||||
mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER,
|
||||
"mptscsih_io_done");
|
||||
|
||||
@@ -330,6 +330,7 @@ static struct scsi_host_template zfcp_scsi_host_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "zfcp",
|
||||
.queuecommand = zfcp_scsi_queuecommand,
|
||||
.eh_timed_out = fc_eh_timed_out,
|
||||
.eh_abort_handler = zfcp_scsi_eh_abort_handler,
|
||||
.eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
|
||||
.eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler,
|
||||
|
||||
+22
-42
@@ -96,17 +96,6 @@
|
||||
* of chips. To use it, you write an architecture specific functions
|
||||
* and macros and include this file in your driver.
|
||||
*
|
||||
* These macros control options :
|
||||
* AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
|
||||
* for commands that return with a CHECK CONDITION status.
|
||||
*
|
||||
* DIFFERENTIAL - if defined, NCR53c81 chips will use external differential
|
||||
* transceivers.
|
||||
*
|
||||
* PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases.
|
||||
*
|
||||
* REAL_DMA - if defined, REAL DMA is used during the data transfer phases.
|
||||
*
|
||||
* These macros MUST be defined :
|
||||
*
|
||||
* NCR5380_read(register) - read from the specified register
|
||||
@@ -347,7 +336,7 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* NCR58380_info - report driver and host information
|
||||
* NCR5380_info - report driver and host information
|
||||
* @instance: relevant scsi host instance
|
||||
*
|
||||
* For use as the host template info() handler.
|
||||
@@ -360,33 +349,6 @@ static const char *NCR5380_info(struct Scsi_Host *instance)
|
||||
return hostdata->info;
|
||||
}
|
||||
|
||||
static void prepare_info(struct Scsi_Host *instance)
|
||||
{
|
||||
struct NCR5380_hostdata *hostdata = shost_priv(instance);
|
||||
|
||||
snprintf(hostdata->info, sizeof(hostdata->info),
|
||||
"%s, irq %d, "
|
||||
"io_port 0x%lx, base 0x%lx, "
|
||||
"can_queue %d, cmd_per_lun %d, "
|
||||
"sg_tablesize %d, this_id %d, "
|
||||
"flags { %s%s%s}, "
|
||||
"options { %s} ",
|
||||
instance->hostt->name, instance->irq,
|
||||
hostdata->io_port, hostdata->base,
|
||||
instance->can_queue, instance->cmd_per_lun,
|
||||
instance->sg_tablesize, instance->this_id,
|
||||
hostdata->flags & FLAG_DMA_FIXUP ? "DMA_FIXUP " : "",
|
||||
hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
|
||||
hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "",
|
||||
#ifdef DIFFERENTIAL
|
||||
"DIFFERENTIAL "
|
||||
#endif
|
||||
#ifdef PARITY
|
||||
"PARITY "
|
||||
#endif
|
||||
"");
|
||||
}
|
||||
|
||||
/**
|
||||
* NCR5380_init - initialise an NCR5380
|
||||
* @instance: adapter to configure
|
||||
@@ -436,7 +398,14 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
|
||||
if (!hostdata->work_q)
|
||||
return -ENOMEM;
|
||||
|
||||
prepare_info(instance);
|
||||
snprintf(hostdata->info, sizeof(hostdata->info),
|
||||
"%s, irq %d, io_port 0x%lx, base 0x%lx, can_queue %d, cmd_per_lun %d, sg_tablesize %d, this_id %d, flags { %s%s%s}",
|
||||
instance->hostt->name, instance->irq, hostdata->io_port,
|
||||
hostdata->base, instance->can_queue, instance->cmd_per_lun,
|
||||
instance->sg_tablesize, instance->this_id,
|
||||
hostdata->flags & FLAG_DMA_FIXUP ? "DMA_FIXUP " : "",
|
||||
hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
|
||||
hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "");
|
||||
|
||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||
NCR5380_write(MODE_REG, MR_BASE);
|
||||
@@ -622,8 +591,9 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance)
|
||||
list_empty(&hostdata->unissued) &&
|
||||
list_empty(&hostdata->autosense) &&
|
||||
!hostdata->connected &&
|
||||
!hostdata->selecting)
|
||||
!hostdata->selecting) {
|
||||
NCR5380_release_dma_irq(instance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -962,6 +932,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
|
||||
|
||||
static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
|
||||
struct scsi_cmnd *cmd)
|
||||
__releases(&hostdata->lock) __acquires(&hostdata->lock)
|
||||
{
|
||||
struct NCR5380_hostdata *hostdata = shost_priv(instance);
|
||||
unsigned char tmp[3], phase;
|
||||
@@ -1194,8 +1165,16 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
|
||||
data = tmp;
|
||||
phase = PHASE_MSGOUT;
|
||||
NCR5380_transfer_pio(instance, &phase, &len, &data);
|
||||
if (len) {
|
||||
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
|
||||
cmd->result = DID_ERROR << 16;
|
||||
complete_cmd(instance, cmd);
|
||||
dsprintk(NDEBUG_SELECTION, instance, "IDENTIFY message transfer failed\n");
|
||||
cmd = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
|
||||
/* XXX need to handle errors here */
|
||||
|
||||
hostdata->connected = cmd;
|
||||
hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
|
||||
@@ -1654,6 +1633,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
|
||||
*/
|
||||
|
||||
static void NCR5380_information_transfer(struct Scsi_Host *instance)
|
||||
__releases(&hostdata->lock) __acquires(&hostdata->lock)
|
||||
{
|
||||
struct NCR5380_hostdata *hostdata = shost_priv(instance);
|
||||
unsigned char msgout = NOP;
|
||||
|
||||
+1
-16
@@ -81,11 +81,7 @@
|
||||
#define ICR_ASSERT_ATN 0x02 /* rw Set to assert ATN */
|
||||
#define ICR_ASSERT_DATA 0x01 /* rw SCSI_DATA_REG is asserted */
|
||||
|
||||
#ifdef DIFFERENTIAL
|
||||
#define ICR_BASE ICR_DIFF_ENABLE
|
||||
#else
|
||||
#define ICR_BASE 0
|
||||
#endif
|
||||
|
||||
#define MODE_REG 2
|
||||
/*
|
||||
@@ -102,11 +98,7 @@
|
||||
#define MR_DMA_MODE 0x02 /* rw DMA / pseudo DMA mode */
|
||||
#define MR_ARBITRATE 0x01 /* rw start arbitration */
|
||||
|
||||
#ifdef PARITY
|
||||
#define MR_BASE MR_ENABLE_PAR_CHECK
|
||||
#else
|
||||
#define MR_BASE 0
|
||||
#endif
|
||||
|
||||
#define TARGET_COMMAND_REG 3
|
||||
#define TCR_LAST_BYTE_SENT 0x80 /* ro DMA done */
|
||||
@@ -174,11 +166,7 @@
|
||||
#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer read */
|
||||
#define CSR_GATED_53C80_IRQ 0x01 /* ro Last block xferred */
|
||||
|
||||
#if 0
|
||||
#define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
|
||||
#else
|
||||
#define CSR_BASE CSR_53C80_INTR
|
||||
#endif
|
||||
|
||||
/* Note : PHASE_* macros are based on the values of the STATUS register */
|
||||
#define PHASE_MASK (SR_MSG | SR_CD | SR_IO)
|
||||
@@ -234,11 +222,9 @@ struct NCR5380_hostdata {
|
||||
unsigned char id_higher_mask; /* All bits above id_mask */
|
||||
unsigned char last_message; /* Last Message Out */
|
||||
unsigned long region_size; /* Size of address/port range */
|
||||
char info[256];
|
||||
char info[168]; /* Host banner message */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct NCR5380_cmd {
|
||||
struct list_head list;
|
||||
};
|
||||
@@ -331,5 +317,4 @@ static inline int NCR5380_dma_residual_none(struct NCR5380_hostdata *hostdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* NCR5380_H */
|
||||
|
||||
+965
-329
File diff suppressed because it is too large
Load Diff
+568
-76
File diff suppressed because it is too large
Load Diff
+271
-71
File diff suppressed because it is too large
Load Diff
+188
-138
@@ -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
|
||||
@@ -72,104 +73,175 @@ 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)
|
||||
if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) ||
|
||||
(dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) ||
|
||||
(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_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);
|
||||
size = fibsize + sizeof(struct aac_init) + commsize +
|
||||
commalign + printfbufsiz + host_rrq_size;
|
||||
|
||||
+ 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);
|
||||
}
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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->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;
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -181,7 +253,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
|
||||
*/
|
||||
@@ -191,12 +264,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);
|
||||
@@ -404,9 +479,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)
|
||||
{
|
||||
@@ -440,30 +519,37 @@ 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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
@@ -500,61 +586,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 ||
|
||||
|
||||
+702
-256
File diff suppressed because it is too large
Load Diff
+104
-57
@@ -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
|
||||
@@ -122,7 +123,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 +251,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 +283,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 +306,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;
|
||||
@@ -344,7 +347,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
|
||||
(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.
|
||||
@@ -362,60 +365,104 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
|
||||
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 (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 {
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
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.NormalRecved);
|
||||
if (complete)
|
||||
aac_fib_complete(fib);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
|
||||
if (start_callback) {
|
||||
/*
|
||||
* NOTE: we cannot touch the fib after this
|
||||
* call, because it may have been deallocated.
|
||||
* 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);
|
||||
} 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);
|
||||
}
|
||||
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 (fib->done == 2) {
|
||||
spin_lock_irqsave(&fib->event_lock, flagv);
|
||||
fib->done = 0;
|
||||
spin_unlock_irqrestore(&fib->event_lock, flagv);
|
||||
} else {
|
||||
aac_fib_complete(fib);
|
||||
aac_fib_free(fib);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+391
-179
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user