SCSI misc on 20160517

This patch includes the usual quota of driver updates (bnx2fc, mp3sas,
 hpsa, ncr5380, lpfc, hisi_sas, snic, aacraid, megaraid_sas) there's
 also a multiqueue update for scsi_debug, assorted bug fixes and a few
 other minor updates (refactor of scsi_sg_pools into generic code, alua
 and VPD updates, and struct timeval conversions).
 
 Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQEcBAABAgAGBQJXO8W0AAoJEDeqqVYsXL0MW24H/jGWwfjsDUiSsLwbLca6DWu8
 ZCWZ7rSZ27CApwGPgZGpLvUg+vpW8Ykm2zdeBnlZ6ScXS+dT3uo/PHsnemsTextj
 6glQNIOFY0Ja2GwkkN00M6IZQhTJ628cqJKIEJxC68lIw16wiOwjZaK68GMrusDO
 Sl062rkuLR6Jb2T+YoT/sD8jQfWlSj2V9e9rqJoS/rIbS6B+hUipuybz2yQ2yK2u
 XFc30yal9oVz1fHEoh2O8aqckW3/iskukVXVuZ0MQzT/lV/bm9I6AnWVHw7d0Yhp
 ZELjXpjx5M2Z/d8k0Wvx1e25oL/ERwa96yLnTvRcqyF5Yt1EgAhT+jKvo4pnGr8=
 =L6y/
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
 "First round of SCSI updates for the 4.6+ merge window.

  This batch includes the usual quota of driver updates (bnx2fc, mp3sas,
  hpsa, ncr5380, lpfc, hisi_sas, snic, aacraid, megaraid_sas).  There's
  also a multiqueue update for scsi_debug, assorted bug fixes and a few
  other minor updates (refactor of scsi_sg_pools into generic code, alua
  and VPD updates, and struct timeval conversions)"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (138 commits)
  mpt3sas: Used "synchronize_irq()"API to synchronize timed-out IO & TMs
  mpt3sas: Set maximum transfer length per IO to 4MB for VDs
  mpt3sas: Updating mpt3sas driver version to 13.100.00.00
  mpt3sas: Fix initial Reference tag field for 4K PI drives.
  mpt3sas: Handle active cable exception event
  mpt3sas: Update MPI header to 2.00.42
  Revert "lpfc: Delete unnecessary checks before the function call mempool_destroy"
  eata_pio: missing break statement
  hpsa: Fix type ZBC conditional checks
  scsi_lib: Decode T10 vendor IDs
  scsi_dh_alua: do not fail for unknown VPD identification
  scsi_debug: use locally assigned naa
  scsi_debug: uuid for lu name
  scsi_debug: vpd and mode page work
  scsi_debug: add multiple queue support
  bfa: fix bfa_fcb_itnim_alloc() error handling
  megaraid_sas: Downgrade two success messages to info
  cxlflash: Fix to resolve dead-lock during EEH recovery
  scsi_debug: rework resp_report_luns
  scsi_debug: use pdt constants
  ...
This commit is contained in:
Linus Torvalds 2016-05-18 16:38:59 -07:00
commit 675e0655c1
117 changed files with 4828 additions and 6470 deletions

View file

@ -23,11 +23,10 @@ supported by the driver.
If the default configuration does not work for you, you can use the kernel
command lines (eg using the lilo append command):
ncr5380=port,irq,dma
ncr53c400=port,irq
or
ncr5380=base,irq,dma
ncr53c400=base,irq
ncr5380=addr,irq
ncr53c400=addr,irq
ncr53c400a=addr,irq
dtc3181e=addr,irq
The driver does not probe for any addresses or ports other than those in
the OVERRIDE or given to the kernel as above.
@ -36,19 +35,17 @@ This driver provides some information on what it has detected in
/proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
time. More info to come in the future.
When NCR53c400 support is compiled in, BIOS parameters will be returned by
the driver (the raw 5380 driver does not and I don't plan to fiddle with
it!).
This driver works as a module.
When included as a module, parameters can be passed on the insmod/modprobe
command line:
ncr_irq=xx the interrupt
ncr_addr=xx the port or base address (for port or memory
mapped, resp.)
ncr_dma=xx the DMA
ncr_5380=1 to set up for a NCR5380 board
ncr_53c400=1 to set up for a NCR53C400 board
ncr_53c400a=1 to set up for a NCR53C400A board
dtc_3181e=1 to set up for a Domex Technology Corp 3181E board
hp_c2502=1 to set up for a Hewlett Packard C2502 board
e.g.
modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
for a port mapped NCR5380 board or

View file

@ -27,13 +27,15 @@ parameters may be changed at runtime by the command
aic79xx= [HW,SCSI]
See Documentation/scsi/aic79xx.txt.
atascsi= [HW,SCSI] Atari SCSI
atascsi= [HW,SCSI]
See drivers/scsi/atari_scsi.c.
BusLogic= [HW,SCSI]
See drivers/scsi/BusLogic.c, comment before function
BusLogic_ParseDriverOptions().
dtc3181e= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
eata= [HW,SCSI]
@ -51,8 +53,8 @@ parameters may be changed at runtime by the command
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
See header of drivers/scsi/ips.c.
mac5380= [HW,SCSI] Format:
<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
mac5380= [HW,SCSI]
See drivers/scsi/mac_scsi.c.
max_luns= [SCSI] Maximum number of LUNs to probe.
Should be between 1 and 2^32-1.
@ -65,10 +67,13 @@ parameters may be changed at runtime by the command
See header of drivers/scsi/NCR_D700.c.
ncr5380= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c400= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c400a= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c406a= [HW,SCSI]

View file

@ -7593,10 +7593,10 @@ M: Michael Schmitz <schmitzmic@gmail.com>
L: linux-scsi@vger.kernel.org
S: Maintained
F: Documentation/scsi/g_NCR5380.txt
F: Documentation/scsi/dtc3x80.txt
F: drivers/scsi/NCR5380.*
F: drivers/scsi/arm/cumana_1.c
F: drivers/scsi/arm/oak.c
F: drivers/scsi/atari_NCR5380.c
F: drivers/scsi/atari_scsi.*
F: drivers/scsi/dmx3191d.c
F: drivers/scsi/dtc.*

View file

@ -294,7 +294,7 @@ static int icside_dma_init(struct pata_icside_info *info)
static struct scsi_host_template pata_icside_sht = {
ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
};

View file

@ -81,7 +81,7 @@ MODULE_PARM_DESC(cmd_sg_entries,
module_param(indirect_sg_entries, uint, 0444);
MODULE_PARM_DESC(indirect_sg_entries,
"Default max number of gather/scatter entries (default is 12, max is " __stringify(SCSI_MAX_SG_CHAIN_SEGMENTS) ")");
"Default max number of gather/scatter entries (default is 12, max is " __stringify(SG_MAX_SEGMENTS) ")");
module_param(allow_ext_sg, bool, 0444);
MODULE_PARM_DESC(allow_ext_sg,
@ -2819,7 +2819,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
spin_unlock(&host->target_lock);
scsi_scan_target(&target->scsi_host->shost_gendev,
0, target->scsi_id, SCAN_WILD_CARD, 0);
0, target->scsi_id, SCAN_WILD_CARD, SCSI_SCAN_INITIAL);
if (srp_connected_ch(target) < target->ch_count ||
target->qp_in_error) {
@ -3097,7 +3097,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
case SRP_OPT_SG_TABLESIZE:
if (match_int(args, &token) || token < 1 ||
token > SCSI_MAX_SG_CHAIN_SEGMENTS) {
token > SG_MAX_SEGMENTS) {
pr_warn("bad max sg_tablesize parameter '%s'\n",
p);
goto out;

View file

@ -2281,7 +2281,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_out)
if (pci_dma_mapping_error(ioc->pcidev, dma_addr_out))
goto put_mf;
ioc->add_sge(psge, flagsLength, dma_addr_out);
psge += ioc->SGE_size;
@ -2296,7 +2296,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
flagsLength |= blk_rq_bytes(rsp) + 4;
dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_in)
if (pci_dma_mapping_error(ioc->pcidev, dma_addr_in))
goto unmap;
ioc->add_sge(psge, flagsLength, dma_addr_in);

View file

@ -1150,7 +1150,7 @@ static void mpt_work_wrapper(struct work_struct *work)
}
shost_printk(KERN_INFO, shost, MYIOC_s_FMT
"Integrated RAID detects new device %d\n", ioc->name, disk);
scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, 1);
scsi_scan_target(&ioc->sh->shost_gendev, 1, disk, 0, SCSI_SCAN_RESCAN);
}

View file

@ -26,7 +26,8 @@ void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
if (rport && rport->port_state == FC_PORTSTATE_ONLINE)
scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun, 1);
scsi_scan_target(&rport->dev, 0, rport->scsi_target_id, lun,
SCSI_SCAN_MANUAL);
}
static void zfcp_unit_scsi_scan_work(struct work_struct *work)

View file

@ -17,6 +17,7 @@ config SCSI
tristate "SCSI device support"
depends on BLOCK
select SCSI_DMA if HAS_DMA
select SG_POOL
---help---
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or
any other SCSI device under Linux, say Y and make sure that you know
@ -202,12 +203,12 @@ config SCSI_ENCLOSURE
certain enclosure conditions to be reported and is not required.
config SCSI_CONSTANTS
bool "Verbose SCSI error reporting (kernel size +=75K)"
bool "Verbose SCSI error reporting (kernel size += 36K)"
depends on SCSI
help
The error messages regarding your SCSI hardware will be easier to
understand if you say Y here; it will enlarge your kernel by about
75 KB. If in doubt, say Y.
36 KB. If in doubt, say Y.
config SCSI_LOGGING
bool "SCSI logging facility"
@ -813,17 +814,6 @@ config SCSI_GENERIC_NCR5380_MMIO
To compile this driver as a module, choose M here: the
module will be called g_NCR5380_mmio.
config SCSI_GENERIC_NCR53C400
bool "Enable NCR53c400 extensions"
depends on SCSI_GENERIC_NCR5380
help
This enables certain optimizations for the NCR53c400 SCSI cards.
You might as well try it out. Note that this driver will only probe
for the Trantor T130B in its default configuration; you might have
to pass a command line option to the kernel at boot time if it does
not detect your card. See the file
<file:Documentation/scsi/g_NCR5380.txt> for details.
config SCSI_IPS
tristate "IBM ServeRAID support"
depends on PCI && SCSI

File diff suppressed because it is too large Load diff

View file

@ -199,13 +199,6 @@
#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
/*
* "Special" value for the (unsigned char) command tag, to indicate
* I_T_L nexus instead of I_T_L_Q.
*/
#define TAG_NONE 0xff
/*
* These are "special" values for the irq and dma_channel fields of the
* Scsi_Host structure
@ -220,28 +213,17 @@
#define NO_IRQ 0
#endif
#define FLAG_NO_DMA_FIXUP 1 /* No DMA errata workarounds */
#define FLAG_DMA_FIXUP 1 /* Use DMA errata workarounds */
#define FLAG_NO_PSEUDO_DMA 8 /* Inhibit DMA */
#define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */
#define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */
#define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */
#ifdef SUPPORT_TAGS
struct tag_alloc {
DECLARE_BITMAP(allocated, MAX_TAGS);
int nr_allocated;
int queue_size;
};
#endif
struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char busy[8]; /* index = target, bit = lun */
#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
int dma_len; /* requested length of DMA */
#endif
unsigned char last_message; /* last message OUT */
struct scsi_cmnd *connected; /* currently connected cmnd */
struct scsi_cmnd *selecting; /* cmnd to be connected */
@ -256,13 +238,6 @@ struct NCR5380_hostdata {
int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */
struct work_struct main_task;
#ifdef SUPPORT_TAGS
struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */
#endif
#ifdef PSEUDO_DMA
unsigned spin_max_r;
unsigned spin_max_w;
#endif
struct workqueue_struct *work_q;
unsigned long accesses_per_ms; /* chip register accesses per ms */
};
@ -305,132 +280,20 @@ static void NCR5380_print(struct Scsi_Host *instance);
#define NCR5380_dprint_phase(flg, arg) do {} while (0)
#endif
#if defined(AUTOPROBE_IRQ)
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif
static int NCR5380_init(struct Scsi_Host *instance, int flags);
static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
static irqreturn_t NCR5380_intr(int irq, void *dev_id);
#endif
static void NCR5380_main(struct work_struct *work);
static const char *NCR5380_info(struct Scsi_Host *instance);
static void NCR5380_reselect(struct Scsi_Host *instance);
static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
#endif
static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
static int NCR5380_poll_politely(struct Scsi_Host *, int, int, int, int);
static int NCR5380_poll_politely2(struct Scsi_Host *, int, int, int, int, int, int, int);
#if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
#if defined(i386) || defined(__alpha__)
/**
* NCR5380_pc_dma_setup - setup ISA DMA
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
* @mode: DMA controller mode to use
*
* Program the DMA controller ready to perform an ISA DMA transfer
* on this chip.
*
* Locks: takes and releases the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_setup(struct Scsi_Host *instance, unsigned char *ptr, unsigned int count, unsigned char mode)
{
unsigned limit;
unsigned long bus_addr = virt_to_bus(ptr);
unsigned long flags;
if (instance->dma_channel <= 3) {
if (count > 65536)
count = 65536;
limit = 65536 - (bus_addr & 0xFFFF);
} else {
if (count > 65536 * 2)
count = 65536 * 2;
limit = 65536 * 2 - (bus_addr & 0x1FFFF);
}
if (count > limit)
count = limit;
if ((count & 1) || (bus_addr & 1))
panic("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
flags=claim_dma_lock();
disable_dma(instance->dma_channel);
clear_dma_ff(instance->dma_channel);
set_dma_addr(instance->dma_channel, bus_addr);
set_dma_count(instance->dma_channel, count);
set_dma_mode(instance->dma_channel, mode);
enable_dma(instance->dma_channel);
release_dma_lock(flags);
return count;
}
/**
* NCR5380_pc_dma_write_setup - setup ISA DMA write
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
*
* Program the DMA controller ready to perform an ISA DMA write to the
* SCSI controller.
*
* Locks: called routines take and release the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_write_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
{
return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_WRITE);
}
/**
* NCR5380_pc_dma_read_setup - setup ISA DMA read
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
*
* Program the DMA controller ready to perform an ISA DMA read from the
* SCSI controller.
*
* Locks: called routines take and release the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_read_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
{
return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_READ);
}
/**
* NCR5380_pc_dma_residual - return bytes left
* @instance: adapter
*
* Reports the number of bytes left over after the DMA was terminated.
*
* Locks: takes and releases the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
{
unsigned long flags;
int tmp;
flags = claim_dma_lock();
clear_dma_ff(instance->dma_channel);
tmp = get_dma_residue(instance->dma_channel);
release_dma_lock(flags);
return tmp;
}
#endif /* defined(i386) || defined(__alpha__) */
#endif /* defined(REAL_DMA) */
#endif /* __KERNEL__ */
#endif /* NCR5380_H */

View file

@ -555,8 +555,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
@ -1037,8 +1035,6 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);
@ -1950,10 +1946,6 @@ static int aac_read(struct scsi_cmnd * scsicmd)
* Alocate and initialize a Fib
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext) {
printk(KERN_WARNING "aac_read: fib allocation failed\n");
return -1;
}
status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
@ -2048,16 +2040,6 @@ static int aac_write(struct scsi_cmnd * scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext) {
/* FIB temporarily unavailable,not catastrophic failure */
/* scsicmd->result = DID_ERROR << 16;
* scsicmd->scsi_done(scsicmd);
* return 0;
*/
printk(KERN_WARNING "aac_write: fib allocation failed\n");
return -1;
}
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
@ -2283,8 +2265,6 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
* Allocate and initialize a Fib
*/
cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
if (!cmd_fibcontext)
return SCSI_MLQUEUE_HOST_BUSY;
aac_fib_init(cmd_fibcontext);
@ -3184,8 +3164,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command
*/
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -1;
status = aac_adapter_scsi(cmd_fibcontext, scsicmd);

View file

@ -29,6 +29,7 @@ enum {
#define AAC_INT_MODE_MSI (1<<1)
#define AAC_INT_MODE_AIF (1<<2)
#define AAC_INT_MODE_SYNC (1<<3)
#define AAC_INT_MODE_MSIX (1<<16)
#define AAC_INT_ENABLE_TYPE1_INTX 0xfffffffb
#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
@ -62,7 +63,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 41052
# define AAC_DRIVER_BUILD 41066
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@ -720,7 +721,7 @@ struct sa_registers {
};
#define Sa_MINIPORT_REVISION 1
#define SA_INIT_NUM_MSIXVECTORS 1
#define sa_readw(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
#define sa_readl(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
@ -2065,6 +2066,10 @@ extern struct aac_common aac_config;
#define AifEnAddJBOD 30 /* JBOD created */
#define AifEnDeleteJBOD 31 /* JBOD deleted */
#define AifBuManagerEvent 42 /* Bu management*/
#define AifBuCacheDataLoss 10
#define AifBuCacheDataRecover 11
#define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */
#define AifJobStsSuccess 1 /* Job completes */

View file

@ -37,6 +37,7 @@
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h>
#include <linux/mm.h>
#include <scsi/scsi_host.h>
@ -47,6 +48,20 @@ struct aac_common aac_config = {
.irq_mod = 1
};
static inline int aac_is_msix_mode(struct aac_dev *dev)
{
u32 status;
status = src_readl(dev, MUnit.OMR);
return (status & AAC_INT_MODE_MSIX);
}
static inline void aac_change_to_intx(struct aac_dev *dev)
{
aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
aac_src_access_devreg(dev, AAC_ENABLE_INTX);
}
static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
{
unsigned char *base;
@ -91,7 +106,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
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_MINIPORT_REVISION);
init->Sa_MSIXVectors = cpu_to_le32(SA_INIT_NUM_MSIXVECTORS);
init->fsrev = cpu_to_le32(dev->fsrev);
/*
@ -378,21 +393,8 @@ void aac_define_int_mode(struct aac_dev *dev)
msi_count = i;
} else {
dev->msi_enabled = 0;
printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n",
dev->name, dev->id, i);
}
}
if (!dev->msi_enabled) {
msi_count = 1;
i = pci_enable_msi(dev->pdev);
if (!i) {
dev->msi_enabled = 1;
dev->msi = 1;
} else {
printk(KERN_ERR "%s%d: MSI not supported!! Will try INTx 0x%x.\n",
dev->name, dev->id, i);
dev_err(&dev->pdev->dev,
"MSIX not supported!! Will try INTX 0x%x.\n", i);
}
}
@ -427,6 +429,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->comm_interface = AAC_COMM_PRODUCER;
dev->raw_io_interface = dev->raw_io_64 = 0;
/*
* Enable INTX mode, if not done already Enabled
*/
if (aac_is_msix_mode(dev)) {
aac_change_to_intx(dev);
dev_info(&dev->pdev->dev, "Changed firmware to INTX mode");
}
if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, NULL)) &&

View file

@ -637,10 +637,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
}
return -EFAULT;
}
/* We used to udelay() here but that absorbed
* a CPU when a timeout occured. Not very
* useful. */
cpu_relax();
/*
* Allow other processes / CPUS to use core
*/
schedule();
}
} else if (down_interruptible(&fibptr->event_wait)) {
/* Do nothing ... satisfy
@ -901,6 +901,31 @@ void aac_printf(struct aac_dev *dev, u32 val)
memset(cp, 0, 256);
}
static inline int aac_aif_data(struct aac_aifcmd *aifcmd, uint32_t index)
{
return le32_to_cpu(((__le32 *)aifcmd->data)[index]);
}
static void aac_handle_aif_bu(struct aac_dev *dev, struct aac_aifcmd *aifcmd)
{
switch (aac_aif_data(aifcmd, 1)) {
case AifBuCacheDataLoss:
if (aac_aif_data(aifcmd, 2))
dev_info(&dev->pdev->dev, "Backup unit had cache data loss - [%d]\n",
aac_aif_data(aifcmd, 2));
else
dev_info(&dev->pdev->dev, "Backup Unit had cache data loss\n");
break;
case AifBuCacheDataRecover:
if (aac_aif_data(aifcmd, 2))
dev_info(&dev->pdev->dev, "DDR cache data recovered successfully - [%d]\n",
aac_aif_data(aifcmd, 2));
else
dev_info(&dev->pdev->dev, "DDR cache data recovered successfully\n");
break;
}
}
/**
* aac_handle_aif - Handle a message from the firmware
@ -1154,6 +1179,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
ADD : DELETE;
break;
}
case AifBuManagerEvent:
aac_handle_aif_bu(dev, aifcmd);
break;
}
@ -1996,6 +2023,10 @@ int aac_command_thread(void *data)
if (difference <= 0)
difference = 1;
set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop())
break;
schedule_timeout(difference);
if (kthread_should_stop())

View file

@ -392,9 +392,10 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
if (likely(fib->callback && fib->callback_data)) {
fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
fib->callback(fib->callback_data, fib);
} else {
aac_fib_complete(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"));

View file

@ -1299,6 +1299,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
else
shost->this_id = shost->max_id;
aac_intr_normal(aac, 0, 2, 0, NULL);
/*
* dmb - we may need to move the setting of these parms somewhere else once
* we get a fib that can report the actual numbers
@ -1431,8 +1433,8 @@ 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.
*/
aac_adapter_start(dev);
dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
aac_adapter_start(dev);
}
return 0;

View file

@ -135,7 +135,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
if (mode & AAC_INT_MODE_AIF) {
/* handle AIF */
aac_intr_normal(dev, 0, 2, 0, NULL);
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;

View file

@ -13,13 +13,14 @@
#include <scsi/scsi_host.h>
#define PSEUDO_DMA
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_read(reg) cumanascsi_read(instance, reg)
#define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value)
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_dma_recv_setup cumanascsi_pread
#define NCR5380_dma_send_setup cumanascsi_pwrite
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_intr cumanascsi_intr
#define NCR5380_queue_command cumanascsi_queue_command
@ -41,8 +42,8 @@ void cumanascsi_setup(char *str, int *ints)
#define L(v) (((v)<<16)|((v) & 0x0000ffff))
#define H(v) (((v)>>16)|((v) & 0xffff0000))
static inline int
NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
static inline int cumanascsi_pwrite(struct Scsi_Host *host,
unsigned char *addr, int len)
{
unsigned long *laddr;
void __iomem *dma = priv(host)->dma + 0x2000;
@ -101,11 +102,14 @@ NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
}
end:
writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
return len;
if (len)
return -1;
return 0;
}
static inline int
NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
static inline int cumanascsi_pread(struct Scsi_Host *host,
unsigned char *addr, int len)
{
unsigned long *laddr;
void __iomem *dma = priv(host)->dma + 0x2000;
@ -163,7 +167,10 @@ NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
}
end:
writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
return len;
if (len)
return -1;
return 0;
}
static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
@ -239,7 +246,7 @@ static int cumanascsi1_probe(struct expansion_card *ec,
host->irq = ec->irq;
ret = NCR5380_init(host, 0);
ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
if (ret)
goto out_unmap;

View file

@ -365,7 +365,7 @@ static struct scsi_host_template cumanascsi2_template = {
.eh_abort_handler = fas216_eh_abort,
.can_queue = 1,
.this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "cumanascsi2",

View file

@ -484,7 +484,7 @@ static struct scsi_host_template eesox_template = {
.eh_abort_handler = fas216_eh_abort,
.can_queue = 1,
.this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "eesox",

View file

@ -14,9 +14,6 @@
#include <scsi/scsi_host.h>
/*#define PSEUDO_DMA*/
#define DONT_USE_INTR
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_read(reg) \
@ -24,7 +21,10 @@
#define NCR5380_write(reg, value) \
writeb(value, priv(instance)->base + ((reg) << 2))
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_dma_xfer_len(instance, cmd, phase) (0)
#define NCR5380_dma_recv_setup oakscsi_pread
#define NCR5380_dma_send_setup oakscsi_pwrite
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_queue_command oakscsi_queue_command
#define NCR5380_info oakscsi_info
@ -40,23 +40,23 @@
#define STAT ((128 + 16) << 2)
#define DATA ((128 + 8) << 2)
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
int len)
static inline int oakscsi_pwrite(struct Scsi_Host *instance,
unsigned char *addr, int len)
{
void __iomem *base = priv(instance)->base;
printk("writing %p len %d\n",addr, len);
if(!len) return -1;
while(1)
{
int status;
while (((status = readw(base + STAT)) & 0x100)==0);
}
return 0;
}
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
int len)
static inline int oakscsi_pread(struct Scsi_Host *instance,
unsigned char *addr, int len)
{
void __iomem *base = priv(instance)->base;
printk("reading %p len %d\n", addr, len);
@ -73,7 +73,7 @@ printk("reading %p len %d\n", addr, len);
if(status & 0x200 || !timeout)
{
printk("status = %08X\n", status);
return 1;
return -1;
}
}
@ -143,7 +143,7 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
host->irq = NO_IRQ;
host->n_io_port = 255;
ret = NCR5380_init(host, 0);
ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
if (ret)
goto out_unmap;

View file

@ -291,7 +291,7 @@ static struct scsi_host_template powertecscsi_template = {
.can_queue = 8,
.this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS,
.sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,

File diff suppressed because it is too large Load diff

View file

@ -14,55 +14,23 @@
*
*/
/**************************************************************************/
/* */
/* Notes for Falcon SCSI: */
/* ---------------------- */
/* */
/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among */
/* several device drivers, locking and unlocking the access to this */
/* chip is required. But locking is not possible from an interrupt, */
/* since it puts the process to sleep if the lock is not available. */
/* This prevents "late" locking of the DMA chip, i.e. locking it just */
/* before using it, since in case of disconnection-reconnection */
/* commands, the DMA is started from the reselection interrupt. */
/* */
/* Two possible schemes for ST-DMA-locking would be: */
/* 1) The lock is taken for each command separately and disconnecting */
/* is forbidden (i.e. can_queue = 1). */
/* 2) The DMA chip is locked when the first command comes in and */
/* released when the last command is finished and all queues are */
/* empty. */
/* The first alternative would result in bad performance, since the */
/* interleaving of commands would not be used. The second is unfair to */
/* other drivers using the ST-DMA, because the queues will seldom be */
/* totally empty if there is a lot of disk traffic. */
/* */
/* For this reasons I decided to employ a more elaborate scheme: */
/* - First, we give up the lock every time we can (for fairness), this */
/* means every time a command finishes and there are no other commands */
/* on the disconnected queue. */
/* - If there are others waiting to lock the DMA chip, we stop */
/* issuing commands, i.e. moving them onto the issue queue. */
/* Because of that, the disconnected queue will run empty in a */
/* while. Instead we go to sleep on a 'fairness_queue'. */
/* - If the lock is released, all processes waiting on the fairness */
/* queue will be woken. The first of them tries to re-lock the DMA, */
/* the others wait for the first to finish this task. After that, */
/* they can all run on and do their commands... */
/* This sounds complicated (and it is it :-(), but it seems to be a */
/* good compromise between fairness and performance: As long as no one */
/* else wants to work with the ST-DMA chip, SCSI can go along as */
/* usual. If now someone else comes, this behaviour is changed to a */
/* "fairness mode": just already initiated commands are finished and */
/* then the lock is released. The other one waiting will probably win */
/* the race for locking the DMA, since it was waiting for longer. And */
/* after it has finished, SCSI can go ahead again. Finally: I hope I */
/* have not produced any deadlock possibilities! */
/* */
/**************************************************************************/
/*
* Notes for Falcon SCSI DMA
*
* The 5380 device is one of several that all share the DMA chip. Hence
* "locking" and "unlocking" access to this chip is required.
*
* Two possible schemes for ST DMA acquisition by atari_scsi are:
* 1) The lock is taken for each command separately (i.e. can_queue == 1).
* 2) The lock is taken when the first command arrives and released
* when the last command is finished (i.e. can_queue > 1).
*
* The first alternative limits SCSI bus utilization, since interleaving
* commands is not possible. The second gives better performance but is
* unfair to other drivers needing to use the ST DMA chip. In order to
* allow the IDE and floppy drivers equal access to the ST DMA chip
* the default is can_queue == 1.
*/
#include <linux/module.h>
#include <linux/types.h>
@ -83,13 +51,10 @@
#include <scsi/scsi_host.h>
/* Definitions for the core NCR5380 driver. */
#define REAL_DMA
#define SUPPORT_TAGS
#define MAX_TAGS 32
#define DMA_MIN_SIZE 32
/* Definitions for the core NCR5380 driver. */
#define NCR5380_implementation_fields /* none */
#define NCR5380_read(reg) atari_scsi_reg_read(reg)
@ -99,9 +64,9 @@
#define NCR5380_abort atari_scsi_abort
#define NCR5380_info atari_scsi_info
#define NCR5380_dma_read_setup(instance, data, count) \
#define NCR5380_dma_recv_setup(instance, data, count) \
atari_scsi_dma_setup(instance, data, count, 0)
#define NCR5380_dma_write_setup(instance, data, count) \
#define NCR5380_dma_send_setup(instance, data, count) \
atari_scsi_dma_setup(instance, data, count, 1)
#define NCR5380_dma_residual(instance) \
atari_scsi_dma_residual(instance)
@ -159,14 +124,11 @@ static inline unsigned long SCSI_DMA_GETADR(void)
return adr;
}
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void);
#endif
static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value);
#ifdef REAL_DMA
static unsigned long atari_dma_residual, atari_dma_startaddr;
static short atari_dma_active;
/* pointer to the dribble buffer */
@ -185,7 +147,6 @@ static char *atari_dma_orig_addr;
/* mask for address bits that can't be used with the ST-DMA */
static unsigned long atari_dma_stram_mask;
#define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0)
#endif
static int setup_can_queue = -1;
module_param(setup_can_queue, int, 0);
@ -193,16 +154,12 @@ static int setup_cmd_per_lun = -1;
module_param(setup_cmd_per_lun, int, 0);
static int setup_sg_tablesize = -1;
module_param(setup_sg_tablesize, int, 0);
static int setup_use_tagged_queuing = -1;
module_param(setup_use_tagged_queuing, int, 0);
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
static int setup_toshiba_delay = -1;
module_param(setup_toshiba_delay, int, 0);
#if defined(REAL_DMA)
static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
{
int i;
@ -255,12 +212,9 @@ static void scsi_dma_buserr(int irq, void *dummy)
}
#endif
#endif
static irqreturn_t scsi_tt_intr(int irq, void *dev)
{
#ifdef REAL_DMA
struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
@ -342,8 +296,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev)
tt_scsi_dma.dma_ctrl = 0;
}
#endif /* REAL_DMA */
NCR5380_intr(irq, dev);
return IRQ_HANDLED;
@ -352,7 +304,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev)
static irqreturn_t scsi_falcon_intr(int irq, void *dev)
{
#ifdef REAL_DMA
struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat;
@ -405,15 +356,12 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dev)
atari_dma_orig_addr = NULL;
}
#endif /* REAL_DMA */
NCR5380_intr(irq, dev);
return IRQ_HANDLED;
}
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void)
{
int nr;
@ -436,7 +384,6 @@ static void atari_scsi_fetch_restbytes(void)
*dst++ = *src++;
}
}
#endif /* REAL_DMA */
/* This function releases the lock on the DMA chip if there is no
@ -464,6 +411,10 @@ static int falcon_get_lock(struct Scsi_Host *instance)
if (IS_A_TT())
return 1;
if (stdma_is_locked_by(scsi_falcon_intr) &&
instance->hostt->can_queue > 1)
return 1;
if (in_interrupt())
return stdma_try_lock(scsi_falcon_intr, instance);
@ -495,8 +446,7 @@ static int __init atari_scsi_setup(char *str)
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
/* ints[5] (use_tagged_queuing) is ignored */
/* ints[6] (use_pdma) is ignored */
if (ints[0] >= 7)
setup_toshiba_delay = ints[7];
@ -508,8 +458,6 @@ __setup("atascsi=", atari_scsi_setup);
#endif /* !MODULE */
#if defined(REAL_DMA)
static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
void *data, unsigned long count,
int dir)
@ -545,9 +493,6 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
*/
dma_cache_maintenance(addr, count, dir);
if (count == 0)
printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");
if (IS_A_TT()) {
tt_scsi_dma.dma_ctrl = dir;
SCSI_DMA_WRITE_P(dma_addr, addr);
@ -624,6 +569,9 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
{
unsigned long possible_len, limit;
if (wanted_len < DMA_MIN_SIZE)
return 0;
if (IS_A_TT())
/* TT SCSI DMA can transfer arbitrary #bytes */
return wanted_len;
@ -703,9 +651,6 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
}
#endif /* REAL_DMA */
/* NCR5380 register access functions
*
* There are separate functions for TT and Falcon, because the access
@ -736,7 +681,7 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
}
#include "atari_NCR5380.c"
#include "NCR5380.c"
static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
{
@ -745,7 +690,6 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
local_irq_save(flags);
#ifdef REAL_DMA
/* Abort a maybe active DMA transfer */
if (IS_A_TT()) {
tt_scsi_dma.dma_ctrl = 0;
@ -754,7 +698,6 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
atari_dma_active = 0;
atari_dma_orig_addr = NULL;
}
#endif
rv = NCR5380_bus_reset(cmd);
@ -781,6 +724,7 @@ static struct scsi_host_template atari_scsi_template = {
.eh_abort_handler = atari_scsi_abort,
.eh_bus_reset_handler = atari_scsi_bus_reset,
.this_id = 7,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
};
@ -804,24 +748,11 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
atari_scsi_reg_write = atari_scsi_falcon_reg_write;
}
/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary.
* Higher values should work, too; try it!
* (But cmd_per_lun costs memory!)
*
* But there seems to be a bug somewhere that requires CAN_QUEUE to be
* 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
* changed CMD_PER_LUN...
*
* Note: The Falcon currently uses 8/1 setting due to unsolved problems
* with cmd_per_lun != 1
*/
if (ATARIHW_PRESENT(TT_SCSI)) {
atari_scsi_template.can_queue = 16;
atari_scsi_template.cmd_per_lun = 8;
atari_scsi_template.sg_tablesize = SG_ALL;
} else {
atari_scsi_template.can_queue = 8;
atari_scsi_template.cmd_per_lun = 1;
atari_scsi_template.can_queue = 1;
atari_scsi_template.sg_tablesize = SG_NONE;
}
@ -850,8 +781,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
}
}
#ifdef REAL_DMA
/* If running on a Falcon and if there's TT-Ram (i.e., more than one
* memory block, since there's always ST-Ram in a Falcon), then
* allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
@ -867,7 +796,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
atari_dma_orig_addr = 0;
}
#endif
instance = scsi_host_alloc(&atari_scsi_template,
sizeof(struct NCR5380_hostdata));
@ -879,9 +807,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
instance->irq = irq->start;
host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
error = NCR5380_init(instance, host_flags);
@ -897,7 +822,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
goto fail_irq;
}
tt_mfp.active_edge |= 0x80; /* SCSI int on L->H */
#ifdef REAL_DMA
tt_scsi_dma.dma_ctrl = 0;
atari_dma_residual = 0;
@ -919,17 +844,14 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
hostdata->read_overruns = 4;
}
#endif
} else {
/* Nothing to do for the interrupt: the ST-DMA is initialized
* already.
*/
#ifdef REAL_DMA
atari_dma_residual = 0;
atari_dma_active = 0;
atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
: 0xff000000);
#endif
}
NCR5380_maybe_reset_bus(instance);

View file

@ -874,8 +874,8 @@ bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad,
/*
* itnim callbacks
*/
void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
struct bfad_itnim_s **itnim_drv);
int bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
struct bfad_itnim_s **itnim_drv);
void bfa_fcb_itnim_free(struct bfad_s *bfad,
struct bfad_itnim_s *itnim_drv);
void bfa_fcb_itnim_online(struct bfad_itnim_s *itnim_drv);

View file

@ -588,12 +588,13 @@ bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport)
struct bfa_fcs_lport_s *port = rport->port;
struct bfa_fcs_itnim_s *itnim;
struct bfad_itnim_s *itnim_drv;
int ret;
/*
* call bfad to allocate the itnim
*/
bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
if (itnim == NULL) {
ret = bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
if (ret) {
bfa_trc(port->fcs, rport->pwwn);
return NULL;
}

View file

@ -440,13 +440,13 @@ bfad_im_slave_destroy(struct scsi_device *sdev)
* BFA FCS itnim alloc callback, after successful PRLI
* Context: Interrupt
*/
void
int
bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
struct bfad_itnim_s **itnim_drv)
{
*itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC);
if (*itnim_drv == NULL)
return;
return -ENOMEM;
(*itnim_drv)->im = bfad->im;
*itnim = &(*itnim_drv)->fcs_itnim;
@ -457,6 +457,7 @@ bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
*/
INIT_WORK(&(*itnim_drv)->itnim_work, bfad_im_itnim_work_handler);
bfad->bfad_flags |= BFAD_RPORT_ONLINE;
return 0;
}
/*

View file

@ -65,7 +65,7 @@
#include "bnx2fc_constants.h"
#define BNX2FC_NAME "bnx2fc"
#define BNX2FC_VERSION "2.9.6"
#define BNX2FC_VERSION "2.10.3"
#define PFX "bnx2fc: "
@ -261,6 +261,7 @@ struct bnx2fc_interface {
u8 vlan_enabled;
int vlan_id;
bool enabled;
u8 tm_timeout;
};
#define bnx2fc_from_ctlr(x) \

View file

@ -107,6 +107,26 @@ MODULE_PARM_DESC(debug_logging,
"\t\t0x10 - fcoe L2 fame related logs.\n"
"\t\t0xff - LOG all messages.");
uint bnx2fc_devloss_tmo;
module_param_named(devloss_tmo, bnx2fc_devloss_tmo, uint, S_IRUGO);
MODULE_PARM_DESC(devloss_tmo, " Change devloss_tmo for the remote ports "
"attached via bnx2fc.");
uint bnx2fc_max_luns = BNX2FC_MAX_LUN;
module_param_named(max_luns, bnx2fc_max_luns, uint, S_IRUGO);
MODULE_PARM_DESC(max_luns, " Change the default max_lun per SCSI host. Default "
"0xffff.");
uint bnx2fc_queue_depth;
module_param_named(queue_depth, bnx2fc_queue_depth, uint, S_IRUGO);
MODULE_PARM_DESC(queue_depth, " Change the default queue depth of SCSI devices "
"attached via bnx2fc.");
uint bnx2fc_log_fka;
module_param_named(log_fka, bnx2fc_log_fka, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(log_fka, " Print message to kernel log when fcoe is "
"initiating a FIP keep alive when debug logging is enabled.");
static int bnx2fc_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu);
/* notification function for CPU hotplug events */
@ -692,7 +712,7 @@ static int bnx2fc_shost_config(struct fc_lport *lport, struct device *dev)
int rc = 0;
shost->max_cmd_len = BNX2FC_MAX_CMD_LEN;
shost->max_lun = BNX2FC_MAX_LUN;
shost->max_lun = bnx2fc_max_luns;
shost->max_id = BNX2FC_MAX_FCP_TGT;
shost->max_channel = 0;
if (lport->vport)
@ -1061,6 +1081,20 @@ static u8 *bnx2fc_get_src_mac(struct fc_lport *lport)
*/
static void bnx2fc_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fip_header *fiph;
struct ethhdr *eth_hdr;
u16 op;
u8 sub;
fiph = (struct fip_header *) ((void *)skb->data + 2 * ETH_ALEN + 2);
eth_hdr = (struct ethhdr *)skb_mac_header(skb);
op = ntohs(fiph->fip_op);
sub = fiph->fip_subcode;
if (op == FIP_OP_CTRL && sub == FIP_SC_SOL && bnx2fc_log_fka)
BNX2FC_MISC_DBG("Sending FKA from %pM to %pM.\n",
eth_hdr->h_source, eth_hdr->h_dest);
skb->dev = bnx2fc_from_ctlr(fip)->netdev;
dev_queue_xmit(skb);
}
@ -1102,6 +1136,9 @@ static int bnx2fc_vport_create(struct fc_vport *vport, bool disabled)
return -EIO;
}
if (bnx2fc_devloss_tmo)
fc_host_dev_loss_tmo(vn_port->host) = bnx2fc_devloss_tmo;
if (disabled) {
fc_vport_set_state(vport, FC_VPORT_DISABLED);
} else {
@ -1495,6 +1532,9 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface,
}
fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
if (bnx2fc_devloss_tmo)
fc_host_dev_loss_tmo(shost) = bnx2fc_devloss_tmo;
/* Allocate exchange manager */
if (!npiv)
rc = bnx2fc_em_config(lport, hba);
@ -1999,6 +2039,8 @@ static void bnx2fc_ulp_init(struct cnic_dev *dev)
return;
}
pr_info(PFX "FCoE initialized for %s.\n", dev->netdev->name);
/* Add HBA to the adapter list */
mutex_lock(&bnx2fc_dev_lock);
list_add_tail(&hba->list, &adapter_list);
@ -2293,6 +2335,7 @@ static int _bnx2fc_create(struct net_device *netdev,
ctlr = bnx2fc_to_ctlr(interface);
cdev = fcoe_ctlr_to_ctlr_dev(ctlr);
interface->vlan_id = vlan_id;
interface->tm_timeout = BNX2FC_TM_TIMEOUT;
interface->timer_work_queue =
create_singlethread_workqueue("bnx2fc_timer_wq");
@ -2612,6 +2655,15 @@ static int bnx2fc_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
static int bnx2fc_slave_configure(struct scsi_device *sdev)
{
if (!bnx2fc_queue_depth)
return 0;
scsi_change_queue_depth(sdev, bnx2fc_queue_depth);
return 0;
}
/**
* bnx2fc_mod_init - module init entry point
*
@ -2858,6 +2910,50 @@ static struct fc_function_template bnx2fc_vport_xport_function = {
.bsg_request = fc_lport_bsg_request,
};
/*
* Additional scsi_host attributes.
*/
static ssize_t
bnx2fc_tm_timeout_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct fc_lport *lport = shost_priv(shost);
struct fcoe_port *port = lport_priv(lport);
struct bnx2fc_interface *interface = port->priv;
sprintf(buf, "%u\n", interface->tm_timeout);
return strlen(buf);
}
static ssize_t
bnx2fc_tm_timeout_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct fc_lport *lport = shost_priv(shost);
struct fcoe_port *port = lport_priv(lport);
struct bnx2fc_interface *interface = port->priv;
int rval, val;
rval = kstrtouint(buf, 10, &val);
if (rval)
return rval;
if (val > 255)
return -ERANGE;
interface->tm_timeout = (u8)val;
return strlen(buf);
}
static DEVICE_ATTR(tm_timeout, S_IRUGO|S_IWUSR, bnx2fc_tm_timeout_show,
bnx2fc_tm_timeout_store);
static struct device_attribute *bnx2fc_host_attrs[] = {
&dev_attr_tm_timeout,
NULL,
};
/**
* scsi_host_template structure used while registering with SCSI-ml
*/
@ -2877,6 +2973,8 @@ static struct scsi_host_template bnx2fc_shost_template = {
.sg_tablesize = BNX2FC_MAX_BDS_PER_CMD,
.max_sectors = 1024,
.track_queue_depth = 1,
.slave_configure = bnx2fc_slave_configure,
.shost_attrs = bnx2fc_host_attrs,
};
static struct libfc_function_template bnx2fc_libfc_fcn_templ = {

View file

@ -179,12 +179,24 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
bnx2fc_unmap_sg_list(io_req);
io_req->sc_cmd = NULL;
/* Sanity checks before returning command to mid-layer */
if (!sc_cmd) {
printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. "
"IO(0x%x) already cleaned up\n",
io_req->xid);
return;
}
if (!sc_cmd->device) {
pr_err(PFX "0x%x: sc_cmd->device is NULL.\n", io_req->xid);
return;
}
if (!sc_cmd->device->host) {
pr_err(PFX "0x%x: sc_cmd->device->host is NULL.\n",
io_req->xid);
return;
}
sc_cmd->result = err_code << 16;
BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n",
@ -770,7 +782,7 @@ retry_tmf:
spin_unlock_bh(&tgt->tgt_lock);
rc = wait_for_completion_timeout(&io_req->tm_done,
BNX2FC_TM_TIMEOUT * HZ);
interface->tm_timeout * HZ);
spin_lock_bh(&tgt->tgt_lock);
io_req->wait_for_comp = 0;

View file

@ -675,7 +675,7 @@ bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{
struct list_head *list;
struct list_head *tmp;
struct bnx2i_endpoint *ep;
struct bnx2i_endpoint *ep = NULL;
read_lock_bh(&hba->ep_rdwr_lock);
list_for_each_safe(list, tmp, &hba->ep_ofld_list) {
@ -703,7 +703,7 @@ bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{
struct list_head *list;
struct list_head *tmp;
struct bnx2i_endpoint *ep;
struct bnx2i_endpoint *ep = NULL;
read_lock_bh(&hba->ep_rdwr_lock);
list_for_each_safe(list, tmp, &hba->ep_destroy_list) {

View file

@ -292,850 +292,30 @@ bool scsi_opcode_sa_name(int opcode, int service_action,
struct error_info {
unsigned short code12; /* 0x0302 looks better than 0x03,0x02 */
const char * text;
unsigned short size;
};
/*
* The canonical list of T10 Additional Sense Codes is available at:
* http://www.t10.org/lists/asc-num.txt [most recent: 20141221]
* There are 700+ entries in this table. To save space, we don't store
* (code, pointer) pairs, which would make sizeof(struct
* error_info)==16 on 64 bits. Rather, the second element just stores
* the size (including \0) of the corresponding string, and we use the
* sum of these to get the appropriate offset into additional_text
* defined below. This approach saves 12 bytes per entry.
*/
static const struct error_info additional[] =
{
{0x0000, "No additional sense information"},
{0x0001, "Filemark detected"},
{0x0002, "End-of-partition/medium detected"},
{0x0003, "Setmark detected"},
{0x0004, "Beginning-of-partition/medium detected"},
{0x0005, "End-of-data detected"},
{0x0006, "I/O process terminated"},
{0x0007, "Programmable early warning detected"},
{0x0011, "Audio play operation in progress"},
{0x0012, "Audio play operation paused"},
{0x0013, "Audio play operation successfully completed"},
{0x0014, "Audio play operation stopped due to error"},
{0x0015, "No current audio status to return"},
{0x0016, "Operation in progress"},
{0x0017, "Cleaning requested"},
{0x0018, "Erase operation in progress"},
{0x0019, "Locate operation in progress"},
{0x001A, "Rewind operation in progress"},
{0x001B, "Set capacity operation in progress"},
{0x001C, "Verify operation in progress"},
{0x001D, "ATA pass through information available"},
{0x001E, "Conflicting SA creation request"},
{0x001F, "Logical unit transitioning to another power condition"},
{0x0020, "Extended copy information available"},
{0x0021, "Atomic command aborted due to ACA"},
{0x0100, "No index/sector signal"},
{0x0200, "No seek complete"},
{0x0300, "Peripheral device write fault"},
{0x0301, "No write current"},
{0x0302, "Excessive write errors"},
{0x0400, "Logical unit not ready, cause not reportable"},
{0x0401, "Logical unit is in process of becoming ready"},
{0x0402, "Logical unit not ready, initializing command required"},
{0x0403, "Logical unit not ready, manual intervention required"},
{0x0404, "Logical unit not ready, format in progress"},
{0x0405, "Logical unit not ready, rebuild in progress"},
{0x0406, "Logical unit not ready, recalculation in progress"},
{0x0407, "Logical unit not ready, operation in progress"},
{0x0408, "Logical unit not ready, long write in progress"},
{0x0409, "Logical unit not ready, self-test in progress"},
{0x040A, "Logical unit not accessible, asymmetric access state "
"transition"},
{0x040B, "Logical unit not accessible, target port in standby state"},
{0x040C, "Logical unit not accessible, target port in unavailable "
"state"},
{0x040D, "Logical unit not ready, structure check required"},
{0x040E, "Logical unit not ready, security session in progress"},
{0x0410, "Logical unit not ready, auxiliary memory not accessible"},
{0x0411, "Logical unit not ready, notify (enable spinup) required"},
{0x0412, "Logical unit not ready, offline"},
{0x0413, "Logical unit not ready, SA creation in progress"},
{0x0414, "Logical unit not ready, space allocation in progress"},
{0x0415, "Logical unit not ready, robotics disabled"},
{0x0416, "Logical unit not ready, configuration required"},
{0x0417, "Logical unit not ready, calibration required"},
{0x0418, "Logical unit not ready, a door is open"},
{0x0419, "Logical unit not ready, operating in sequential mode"},
{0x041A, "Logical unit not ready, start stop unit command in "
"progress"},
{0x041B, "Logical unit not ready, sanitize in progress"},
{0x041C, "Logical unit not ready, additional power use not yet "
"granted"},
{0x041D, "Logical unit not ready, configuration in progress"},
{0x041E, "Logical unit not ready, microcode activation required"},
{0x041F, "Logical unit not ready, microcode download required"},
{0x0420, "Logical unit not ready, logical unit reset required"},
{0x0421, "Logical unit not ready, hard reset required"},
{0x0422, "Logical unit not ready, power cycle required"},
{0x0500, "Logical unit does not respond to selection"},
{0x0600, "No reference position found"},
{0x0700, "Multiple peripheral devices selected"},
{0x0800, "Logical unit communication failure"},
{0x0801, "Logical unit communication time-out"},
{0x0802, "Logical unit communication parity error"},
{0x0803, "Logical unit communication CRC error (Ultra-DMA/32)"},
{0x0804, "Unreachable copy target"},
{0x0900, "Track following error"},
{0x0901, "Tracking servo failure"},
{0x0902, "Focus servo failure"},
{0x0903, "Spindle servo failure"},
{0x0904, "Head select fault"},
{0x0905, "Vibration induced tracking error"},
{0x0A00, "Error log overflow"},
{0x0B00, "Warning"},
{0x0B01, "Warning - specified temperature exceeded"},
{0x0B02, "Warning - enclosure degraded"},
{0x0B03, "Warning - background self-test failed"},
{0x0B04, "Warning - background pre-scan detected medium error"},
{0x0B05, "Warning - background medium scan detected medium error"},
{0x0B06, "Warning - non-volatile cache now volatile"},
{0x0B07, "Warning - degraded power to non-volatile cache"},
{0x0B08, "Warning - power loss expected"},
{0x0B09, "Warning - device statistics notification active"},
{0x0C00, "Write error"},
{0x0C01, "Write error - recovered with auto reallocation"},
{0x0C02, "Write error - auto reallocation failed"},
{0x0C03, "Write error - recommend reassignment"},
{0x0C04, "Compression check miscompare error"},
{0x0C05, "Data expansion occurred during compression"},
{0x0C06, "Block not compressible"},
{0x0C07, "Write error - recovery needed"},
{0x0C08, "Write error - recovery failed"},
{0x0C09, "Write error - loss of streaming"},
{0x0C0A, "Write error - padding blocks added"},
{0x0C0B, "Auxiliary memory write error"},
{0x0C0C, "Write error - unexpected unsolicited data"},
{0x0C0D, "Write error - not enough unsolicited data"},
{0x0C0E, "Multiple write errors"},
{0x0C0F, "Defects in error window"},
{0x0C10, "Incomplete multiple atomic write operations"},
{0x0D00, "Error detected by third party temporary initiator"},
{0x0D01, "Third party device failure"},
{0x0D02, "Copy target device not reachable"},
{0x0D03, "Incorrect copy target device type"},
{0x0D04, "Copy target device data underrun"},
{0x0D05, "Copy target device data overrun"},
{0x0E00, "Invalid information unit"},
{0x0E01, "Information unit too short"},
{0x0E02, "Information unit too long"},
{0x0E03, "Invalid field in command information unit"},
{0x1000, "Id CRC or ECC error"},
{0x1001, "Logical block guard check failed"},
{0x1002, "Logical block application tag check failed"},
{0x1003, "Logical block reference tag check failed"},
{0x1004, "Logical block protection error on recover buffered data"},
{0x1005, "Logical block protection method error"},
{0x1100, "Unrecovered read error"},
{0x1101, "Read retries exhausted"},
{0x1102, "Error too long to correct"},
{0x1103, "Multiple read errors"},
{0x1104, "Unrecovered read error - auto reallocate failed"},
{0x1105, "L-EC uncorrectable error"},
{0x1106, "CIRC unrecovered error"},
{0x1107, "Data re-synchronization error"},
{0x1108, "Incomplete block read"},
{0x1109, "No gap found"},
{0x110A, "Miscorrected error"},
{0x110B, "Unrecovered read error - recommend reassignment"},
{0x110C, "Unrecovered read error - recommend rewrite the data"},
{0x110D, "De-compression CRC error"},
{0x110E, "Cannot decompress using declared algorithm"},
{0x110F, "Error reading UPC/EAN number"},
{0x1110, "Error reading ISRC number"},
{0x1111, "Read error - loss of streaming"},
{0x1112, "Auxiliary memory read error"},
{0x1113, "Read error - failed retransmission request"},
{0x1114, "Read error - lba marked bad by application client"},
{0x1115, "Write after sanitize required"},
{0x1200, "Address mark not found for id field"},
{0x1300, "Address mark not found for data field"},
{0x1400, "Recorded entity not found"},
{0x1401, "Record not found"},
{0x1402, "Filemark or setmark not found"},
{0x1403, "End-of-data not found"},
{0x1404, "Block sequence error"},
{0x1405, "Record not found - recommend reassignment"},
{0x1406, "Record not found - data auto-reallocated"},
{0x1407, "Locate operation failure"},
{0x1500, "Random positioning error"},
{0x1501, "Mechanical positioning error"},
{0x1502, "Positioning error detected by read of medium"},
{0x1600, "Data synchronization mark error"},
{0x1601, "Data sync error - data rewritten"},
{0x1602, "Data sync error - recommend rewrite"},
{0x1603, "Data sync error - data auto-reallocated"},
{0x1604, "Data sync error - recommend reassignment"},
{0x1700, "Recovered data with no error correction applied"},
{0x1701, "Recovered data with retries"},
{0x1702, "Recovered data with positive head offset"},
{0x1703, "Recovered data with negative head offset"},
{0x1704, "Recovered data with retries and/or circ applied"},
{0x1705, "Recovered data using previous sector id"},
{0x1706, "Recovered data without ECC - data auto-reallocated"},
{0x1707, "Recovered data without ECC - recommend reassignment"},
{0x1708, "Recovered data without ECC - recommend rewrite"},
{0x1709, "Recovered data without ECC - data rewritten"},
{0x1800, "Recovered data with error correction applied"},
{0x1801, "Recovered data with error corr. & retries applied"},
{0x1802, "Recovered data - data auto-reallocated"},
{0x1803, "Recovered data with CIRC"},
{0x1804, "Recovered data with L-EC"},
{0x1805, "Recovered data - recommend reassignment"},
{0x1806, "Recovered data - recommend rewrite"},
{0x1807, "Recovered data with ECC - data rewritten"},
{0x1808, "Recovered data with linking"},
{0x1900, "Defect list error"},
{0x1901, "Defect list not available"},
{0x1902, "Defect list error in primary list"},
{0x1903, "Defect list error in grown list"},
{0x1A00, "Parameter list length error"},
{0x1B00, "Synchronous data transfer error"},
{0x1C00, "Defect list not found"},
{0x1C01, "Primary defect list not found"},
{0x1C02, "Grown defect list not found"},
{0x1D00, "Miscompare during verify operation"},
{0x1D01, "Miscompare verify of unmapped LBA"},
{0x1E00, "Recovered id with ECC correction"},
{0x1F00, "Partial defect list transfer"},
{0x2000, "Invalid command operation code"},
{0x2001, "Access denied - initiator pending-enrolled"},
{0x2002, "Access denied - no access rights"},
{0x2003, "Access denied - invalid mgmt id key"},
{0x2004, "Illegal command while in write capable state"},
{0x2005, "Obsolete"},
{0x2006, "Illegal command while in explicit address mode"},
{0x2007, "Illegal command while in implicit address mode"},
{0x2008, "Access denied - enrollment conflict"},
{0x2009, "Access denied - invalid LU identifier"},
{0x200A, "Access denied - invalid proxy token"},
{0x200B, "Access denied - ACL LUN conflict"},
{0x200C, "Illegal command when not in append-only mode"},
{0x2100, "Logical block address out of range"},
{0x2101, "Invalid element address"},
{0x2102, "Invalid address for write"},
{0x2103, "Invalid write crossing layer jump"},
{0x2104, "Unaligned write command"},
{0x2105, "Write boundary violation"},
{0x2106, "Attempt to read invalid data"},
{0x2107, "Read boundary violation"},
{0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"},
{0x2300, "Invalid token operation, cause not reportable"},
{0x2301, "Invalid token operation, unsupported token type"},
{0x2302, "Invalid token operation, remote token usage not supported"},
{0x2303, "Invalid token operation, remote rod token creation not "
"supported"},
{0x2304, "Invalid token operation, token unknown"},
{0x2305, "Invalid token operation, token corrupt"},
{0x2306, "Invalid token operation, token revoked"},
{0x2307, "Invalid token operation, token expired"},
{0x2308, "Invalid token operation, token cancelled"},
{0x2309, "Invalid token operation, token deleted"},
{0x230A, "Invalid token operation, invalid token length"},
{0x2400, "Invalid field in cdb"},
{0x2401, "CDB decryption error"},
{0x2402, "Obsolete"},
{0x2403, "Obsolete"},
{0x2404, "Security audit value frozen"},
{0x2405, "Security working key frozen"},
{0x2406, "Nonce not unique"},
{0x2407, "Nonce timestamp out of range"},
{0x2408, "Invalid XCDB"},
{0x2500, "Logical unit not supported"},
{0x2600, "Invalid field in parameter list"},
{0x2601, "Parameter not supported"},
{0x2602, "Parameter value invalid"},
{0x2603, "Threshold parameters not supported"},
{0x2604, "Invalid release of persistent reservation"},
{0x2605, "Data decryption error"},
{0x2606, "Too many target descriptors"},
{0x2607, "Unsupported target descriptor type code"},
{0x2608, "Too many segment descriptors"},
{0x2609, "Unsupported segment descriptor type code"},
{0x260A, "Unexpected inexact segment"},
{0x260B, "Inline data length exceeded"},
{0x260C, "Invalid operation for copy source or destination"},
{0x260D, "Copy segment granularity violation"},
{0x260E, "Invalid parameter while port is enabled"},
{0x260F, "Invalid data-out buffer integrity check value"},
{0x2610, "Data decryption key fail limit reached"},
{0x2611, "Incomplete key-associated data set"},
{0x2612, "Vendor specific key reference not found"},
{0x2700, "Write protected"},
{0x2701, "Hardware write protected"},
{0x2702, "Logical unit software write protected"},
{0x2703, "Associated write protect"},
{0x2704, "Persistent write protect"},
{0x2705, "Permanent write protect"},
{0x2706, "Conditional write protect"},
{0x2707, "Space allocation failed write protect"},
{0x2708, "Zone is read only"},
{0x2800, "Not ready to ready change, medium may have changed"},
{0x2801, "Import or export element accessed"},
{0x2802, "Format-layer may have changed"},
{0x2803, "Import/export element accessed, medium changed"},
{0x2900, "Power on, reset, or bus device reset occurred"},
{0x2901, "Power on occurred"},
{0x2902, "Scsi bus reset occurred"},
{0x2903, "Bus device reset function occurred"},
{0x2904, "Device internal reset"},
{0x2905, "Transceiver mode changed to single-ended"},
{0x2906, "Transceiver mode changed to lvd"},
{0x2907, "I_T nexus loss occurred"},
{0x2A00, "Parameters changed"},
{0x2A01, "Mode parameters changed"},
{0x2A02, "Log parameters changed"},
{0x2A03, "Reservations preempted"},
{0x2A04, "Reservations released"},
{0x2A05, "Registrations preempted"},
{0x2A06, "Asymmetric access state changed"},
{0x2A07, "Implicit asymmetric access state transition failed"},
{0x2A08, "Priority changed"},
{0x2A09, "Capacity data has changed"},
{0x2A0A, "Error history I_T nexus cleared"},
{0x2A0B, "Error history snapshot released"},
{0x2A0C, "Error recovery attributes have changed"},
{0x2A0D, "Data encryption capabilities changed"},
{0x2A10, "Timestamp changed"},
{0x2A11, "Data encryption parameters changed by another i_t nexus"},
{0x2A12, "Data encryption parameters changed by vendor specific "
"event"},
{0x2A13, "Data encryption key instance counter has changed"},
{0x2A14, "SA creation capabilities data has changed"},
{0x2A15, "Medium removal prevention preempted"},
{0x2B00, "Copy cannot execute since host cannot disconnect"},
{0x2C00, "Command sequence error"},
{0x2C01, "Too many windows specified"},
{0x2C02, "Invalid combination of windows specified"},
{0x2C03, "Current program area is not empty"},
{0x2C04, "Current program area is empty"},
{0x2C05, "Illegal power condition request"},
{0x2C06, "Persistent prevent conflict"},
{0x2C07, "Previous busy status"},
{0x2C08, "Previous task set full status"},
{0x2C09, "Previous reservation conflict status"},
{0x2C0A, "Partition or collection contains user objects"},
{0x2C0B, "Not reserved"},
{0x2C0C, "Orwrite generation does not match"},
{0x2C0D, "Reset write pointer not allowed"},
{0x2C0E, "Zone is offline"},
{0x2D00, "Overwrite error on update in place"},
{0x2E00, "Insufficient time for operation"},
{0x2E01, "Command timeout before processing"},
{0x2E02, "Command timeout during processing"},
{0x2E03, "Command timeout during processing due to error recovery"},
{0x2F00, "Commands cleared by another initiator"},
{0x2F01, "Commands cleared by power loss notification"},
{0x2F02, "Commands cleared by device server"},
{0x2F03, "Some commands cleared by queuing layer event"},
{0x3000, "Incompatible medium installed"},
{0x3001, "Cannot read medium - unknown format"},
{0x3002, "Cannot read medium - incompatible format"},
{0x3003, "Cleaning cartridge installed"},
{0x3004, "Cannot write medium - unknown format"},
{0x3005, "Cannot write medium - incompatible format"},
{0x3006, "Cannot format medium - incompatible medium"},
{0x3007, "Cleaning failure"},
{0x3008, "Cannot write - application code mismatch"},
{0x3009, "Current session not fixated for append"},
{0x300A, "Cleaning request rejected"},
{0x300C, "WORM medium - overwrite attempted"},
{0x300D, "WORM medium - integrity check"},
{0x3010, "Medium not formatted"},
{0x3011, "Incompatible volume type"},
{0x3012, "Incompatible volume qualifier"},
{0x3013, "Cleaning volume expired"},
{0x3100, "Medium format corrupted"},
{0x3101, "Format command failed"},
{0x3102, "Zoned formatting failed due to spare linking"},
{0x3103, "Sanitize command failed"},
{0x3200, "No defect spare location available"},
{0x3201, "Defect list update failure"},
{0x3300, "Tape length error"},
{0x3400, "Enclosure failure"},
{0x3500, "Enclosure services failure"},
{0x3501, "Unsupported enclosure function"},
{0x3502, "Enclosure services unavailable"},
{0x3503, "Enclosure services transfer failure"},
{0x3504, "Enclosure services transfer refused"},
{0x3505, "Enclosure services checksum error"},
{0x3600, "Ribbon, ink, or toner failure"},
{0x3700, "Rounded parameter"},
{0x3800, "Event status notification"},
{0x3802, "Esn - power management class event"},
{0x3804, "Esn - media class event"},
{0x3806, "Esn - device busy class event"},
{0x3807, "Thin Provisioning soft threshold reached"},
{0x3900, "Saving parameters not supported"},
{0x3A00, "Medium not present"},
{0x3A01, "Medium not present - tray closed"},
{0x3A02, "Medium not present - tray open"},
{0x3A03, "Medium not present - loadable"},
{0x3A04, "Medium not present - medium auxiliary memory accessible"},
{0x3B00, "Sequential positioning error"},
{0x3B01, "Tape position error at beginning-of-medium"},
{0x3B02, "Tape position error at end-of-medium"},
{0x3B03, "Tape or electronic vertical forms unit not ready"},
{0x3B04, "Slew failure"},
{0x3B05, "Paper jam"},
{0x3B06, "Failed to sense top-of-form"},
{0x3B07, "Failed to sense bottom-of-form"},
{0x3B08, "Reposition error"},
{0x3B09, "Read past end of medium"},
{0x3B0A, "Read past beginning of medium"},
{0x3B0B, "Position past end of medium"},
{0x3B0C, "Position past beginning of medium"},
{0x3B0D, "Medium destination element full"},
{0x3B0E, "Medium source element empty"},
{0x3B0F, "End of medium reached"},
{0x3B11, "Medium magazine not accessible"},
{0x3B12, "Medium magazine removed"},
{0x3B13, "Medium magazine inserted"},
{0x3B14, "Medium magazine locked"},
{0x3B15, "Medium magazine unlocked"},
{0x3B16, "Mechanical positioning or changer error"},
{0x3B17, "Read past end of user object"},
{0x3B18, "Element disabled"},
{0x3B19, "Element enabled"},
{0x3B1A, "Data transfer device removed"},
{0x3B1B, "Data transfer device inserted"},
{0x3B1C, "Too many logical objects on partition to support "
"operation"},
{0x3D00, "Invalid bits in identify message"},
{0x3E00, "Logical unit has not self-configured yet"},
{0x3E01, "Logical unit failure"},
{0x3E02, "Timeout on logical unit"},
{0x3E03, "Logical unit failed self-test"},
{0x3E04, "Logical unit unable to update self-test log"},
{0x3F00, "Target operating conditions have changed"},
{0x3F01, "Microcode has been changed"},
{0x3F02, "Changed operating definition"},
{0x3F03, "Inquiry data has changed"},
{0x3F04, "Component device attached"},
{0x3F05, "Device identifier changed"},
{0x3F06, "Redundancy group created or modified"},
{0x3F07, "Redundancy group deleted"},
{0x3F08, "Spare created or modified"},
{0x3F09, "Spare deleted"},
{0x3F0A, "Volume set created or modified"},
{0x3F0B, "Volume set deleted"},
{0x3F0C, "Volume set deassigned"},
{0x3F0D, "Volume set reassigned"},
{0x3F0E, "Reported luns data has changed"},
{0x3F0F, "Echo buffer overwritten"},
{0x3F10, "Medium loadable"},
{0x3F11, "Medium auxiliary memory accessible"},
{0x3F12, "iSCSI IP address added"},
{0x3F13, "iSCSI IP address removed"},
{0x3F14, "iSCSI IP address changed"},
{0x3F15, "Inspect referrals sense descriptors"},
{0x3F16, "Microcode has been changed without reset"},
/*
* {0x40NN, "Ram failure"},
* {0x40NN, "Diagnostic failure on component nn"},
* {0x41NN, "Data path failure"},
* {0x42NN, "Power-on or self-test failure"},
*/
{0x4300, "Message error"},
{0x4400, "Internal target failure"},
{0x4401, "Persistent reservation information lost"},
{0x4471, "ATA device failed set features"},
{0x4500, "Select or reselect failure"},
{0x4600, "Unsuccessful soft reset"},
{0x4700, "Scsi parity error"},
{0x4701, "Data phase CRC error detected"},
{0x4702, "Scsi parity error detected during st data phase"},
{0x4703, "Information unit iuCRC error detected"},
{0x4704, "Asynchronous information protection error detected"},
{0x4705, "Protocol service CRC error"},
{0x4706, "Phy test function in progress"},
{0x477f, "Some commands cleared by iSCSI Protocol event"},
{0x4800, "Initiator detected error message received"},
{0x4900, "Invalid message error"},
{0x4A00, "Command phase error"},
{0x4B00, "Data phase error"},
{0x4B01, "Invalid target port transfer tag received"},
{0x4B02, "Too much write data"},
{0x4B03, "Ack/nak timeout"},
{0x4B04, "Nak received"},
{0x4B05, "Data offset error"},
{0x4B06, "Initiator response timeout"},
{0x4B07, "Connection lost"},
{0x4B08, "Data-in buffer overflow - data buffer size"},
{0x4B09, "Data-in buffer overflow - data buffer descriptor area"},
{0x4B0A, "Data-in buffer error"},
{0x4B0B, "Data-out buffer overflow - data buffer size"},
{0x4B0C, "Data-out buffer overflow - data buffer descriptor area"},
{0x4B0D, "Data-out buffer error"},
{0x4B0E, "PCIe fabric error"},
{0x4B0F, "PCIe completion timeout"},
{0x4B10, "PCIe completer abort"},
{0x4B11, "PCIe poisoned tlp received"},
{0x4B12, "PCIe eCRC check failed"},
{0x4B13, "PCIe unsupported request"},
{0x4B14, "PCIe acs violation"},
{0x4B15, "PCIe tlp prefix blocked"},
{0x4C00, "Logical unit failed self-configuration"},
/*
* {0x4DNN, "Tagged overlapped commands (nn = queue tag)"},
*/
{0x4E00, "Overlapped commands attempted"},
{0x5000, "Write append error"},
{0x5001, "Write append position error"},
{0x5002, "Position error related to timing"},
{0x5100, "Erase failure"},
{0x5101, "Erase failure - incomplete erase operation detected"},
{0x5200, "Cartridge fault"},
{0x5300, "Media load or eject failed"},
{0x5301, "Unload tape failure"},
{0x5302, "Medium removal prevented"},
{0x5303, "Medium removal prevented by data transfer element"},
{0x5304, "Medium thread or unthread failure"},
{0x5305, "Volume identifier invalid"},
{0x5306, "Volume identifier missing"},
{0x5307, "Duplicate volume identifier"},
{0x5308, "Element status unknown"},
{0x5309, "Data transfer device error - load failed"},
{0x530a, "Data transfer device error - unload failed"},
{0x530b, "Data transfer device error - unload missing"},
{0x530c, "Data transfer device error - eject failed"},
{0x530d, "Data transfer device error - library communication failed"},
{0x5400, "Scsi to host system interface failure"},
{0x5500, "System resource failure"},
{0x5501, "System buffer full"},
{0x5502, "Insufficient reservation resources"},
{0x5503, "Insufficient resources"},
{0x5504, "Insufficient registration resources"},
{0x5505, "Insufficient access control resources"},
{0x5506, "Auxiliary memory out of space"},
{0x5507, "Quota error"},
{0x5508, "Maximum number of supplemental decryption keys exceeded"},
{0x5509, "Medium auxiliary memory not accessible"},
{0x550A, "Data currently unavailable"},
{0x550B, "Insufficient power for operation"},
{0x550C, "Insufficient resources to create rod"},
{0x550D, "Insufficient resources to create rod token"},
{0x550E, "Insufficient zone resources"},
{0x5700, "Unable to recover table-of-contents"},
{0x5800, "Generation does not exist"},
{0x5900, "Updated block read"},
{0x5A00, "Operator request or state change input"},
{0x5A01, "Operator medium removal request"},
{0x5A02, "Operator selected write protect"},
{0x5A03, "Operator selected write permit"},
{0x5B00, "Log exception"},
{0x5B01, "Threshold condition met"},
{0x5B02, "Log counter at maximum"},
{0x5B03, "Log list codes exhausted"},
{0x5C00, "Rpl status change"},
{0x5C01, "Spindles synchronized"},
{0x5C02, "Spindles not synchronized"},
{0x5D00, "Failure prediction threshold exceeded"},
{0x5D01, "Media failure prediction threshold exceeded"},
{0x5D02, "Logical unit failure prediction threshold exceeded"},
{0x5D03, "Spare area exhaustion prediction threshold exceeded"},
{0x5D10, "Hardware impending failure general hard drive failure"},
{0x5D11, "Hardware impending failure drive error rate too high"},
{0x5D12, "Hardware impending failure data error rate too high"},
{0x5D13, "Hardware impending failure seek error rate too high"},
{0x5D14, "Hardware impending failure too many block reassigns"},
{0x5D15, "Hardware impending failure access times too high"},
{0x5D16, "Hardware impending failure start unit times too high"},
{0x5D17, "Hardware impending failure channel parametrics"},
{0x5D18, "Hardware impending failure controller detected"},
{0x5D19, "Hardware impending failure throughput performance"},
{0x5D1A, "Hardware impending failure seek time performance"},
{0x5D1B, "Hardware impending failure spin-up retry count"},
{0x5D1C, "Hardware impending failure drive calibration retry count"},
{0x5D20, "Controller impending failure general hard drive failure"},
{0x5D21, "Controller impending failure drive error rate too high"},
{0x5D22, "Controller impending failure data error rate too high"},
{0x5D23, "Controller impending failure seek error rate too high"},
{0x5D24, "Controller impending failure too many block reassigns"},
{0x5D25, "Controller impending failure access times too high"},
{0x5D26, "Controller impending failure start unit times too high"},
{0x5D27, "Controller impending failure channel parametrics"},
{0x5D28, "Controller impending failure controller detected"},
{0x5D29, "Controller impending failure throughput performance"},
{0x5D2A, "Controller impending failure seek time performance"},
{0x5D2B, "Controller impending failure spin-up retry count"},
{0x5D2C, "Controller impending failure drive calibration retry count"},
{0x5D30, "Data channel impending failure general hard drive failure"},
{0x5D31, "Data channel impending failure drive error rate too high"},
{0x5D32, "Data channel impending failure data error rate too high"},
{0x5D33, "Data channel impending failure seek error rate too high"},
{0x5D34, "Data channel impending failure too many block reassigns"},
{0x5D35, "Data channel impending failure access times too high"},
{0x5D36, "Data channel impending failure start unit times too high"},
{0x5D37, "Data channel impending failure channel parametrics"},
{0x5D38, "Data channel impending failure controller detected"},
{0x5D39, "Data channel impending failure throughput performance"},
{0x5D3A, "Data channel impending failure seek time performance"},
{0x5D3B, "Data channel impending failure spin-up retry count"},
{0x5D3C, "Data channel impending failure drive calibration retry "
"count"},
{0x5D40, "Servo impending failure general hard drive failure"},
{0x5D41, "Servo impending failure drive error rate too high"},
{0x5D42, "Servo impending failure data error rate too high"},
{0x5D43, "Servo impending failure seek error rate too high"},
{0x5D44, "Servo impending failure too many block reassigns"},
{0x5D45, "Servo impending failure access times too high"},
{0x5D46, "Servo impending failure start unit times too high"},
{0x5D47, "Servo impending failure channel parametrics"},
{0x5D48, "Servo impending failure controller detected"},
{0x5D49, "Servo impending failure throughput performance"},
{0x5D4A, "Servo impending failure seek time performance"},
{0x5D4B, "Servo impending failure spin-up retry count"},
{0x5D4C, "Servo impending failure drive calibration retry count"},
{0x5D50, "Spindle impending failure general hard drive failure"},
{0x5D51, "Spindle impending failure drive error rate too high"},
{0x5D52, "Spindle impending failure data error rate too high"},
{0x5D53, "Spindle impending failure seek error rate too high"},
{0x5D54, "Spindle impending failure too many block reassigns"},
{0x5D55, "Spindle impending failure access times too high"},
{0x5D56, "Spindle impending failure start unit times too high"},
{0x5D57, "Spindle impending failure channel parametrics"},
{0x5D58, "Spindle impending failure controller detected"},
{0x5D59, "Spindle impending failure throughput performance"},
{0x5D5A, "Spindle impending failure seek time performance"},
{0x5D5B, "Spindle impending failure spin-up retry count"},
{0x5D5C, "Spindle impending failure drive calibration retry count"},
{0x5D60, "Firmware impending failure general hard drive failure"},
{0x5D61, "Firmware impending failure drive error rate too high"},
{0x5D62, "Firmware impending failure data error rate too high"},
{0x5D63, "Firmware impending failure seek error rate too high"},
{0x5D64, "Firmware impending failure too many block reassigns"},
{0x5D65, "Firmware impending failure access times too high"},
{0x5D66, "Firmware impending failure start unit times too high"},
{0x5D67, "Firmware impending failure channel parametrics"},
{0x5D68, "Firmware impending failure controller detected"},
{0x5D69, "Firmware impending failure throughput performance"},
{0x5D6A, "Firmware impending failure seek time performance"},
{0x5D6B, "Firmware impending failure spin-up retry count"},
{0x5D6C, "Firmware impending failure drive calibration retry count"},
{0x5DFF, "Failure prediction threshold exceeded (false)"},
{0x5E00, "Low power condition on"},
{0x5E01, "Idle condition activated by timer"},
{0x5E02, "Standby condition activated by timer"},
{0x5E03, "Idle condition activated by command"},
{0x5E04, "Standby condition activated by command"},
{0x5E05, "Idle_b condition activated by timer"},
{0x5E06, "Idle_b condition activated by command"},
{0x5E07, "Idle_c condition activated by timer"},
{0x5E08, "Idle_c condition activated by command"},
{0x5E09, "Standby_y condition activated by timer"},
{0x5E0A, "Standby_y condition activated by command"},
{0x5E41, "Power state change to active"},
{0x5E42, "Power state change to idle"},
{0x5E43, "Power state change to standby"},
{0x5E45, "Power state change to sleep"},
{0x5E47, "Power state change to device control"},
{0x6000, "Lamp failure"},
{0x6100, "Video acquisition error"},
{0x6101, "Unable to acquire video"},
{0x6102, "Out of focus"},
{0x6200, "Scan head positioning error"},
{0x6300, "End of user area encountered on this track"},
{0x6301, "Packet does not fit in available space"},
{0x6400, "Illegal mode for this track"},
{0x6401, "Invalid packet size"},
{0x6500, "Voltage fault"},
{0x6600, "Automatic document feeder cover up"},
{0x6601, "Automatic document feeder lift up"},
{0x6602, "Document jam in automatic document feeder"},
{0x6603, "Document miss feed automatic in document feeder"},
{0x6700, "Configuration failure"},
{0x6701, "Configuration of incapable logical units failed"},
{0x6702, "Add logical unit failed"},
{0x6703, "Modification of logical unit failed"},
{0x6704, "Exchange of logical unit failed"},
{0x6705, "Remove of logical unit failed"},
{0x6706, "Attachment of logical unit failed"},
{0x6707, "Creation of logical unit failed"},
{0x6708, "Assign failure occurred"},
{0x6709, "Multiply assigned logical unit"},
{0x670A, "Set target port groups command failed"},
{0x670B, "ATA device feature not enabled"},
{0x6800, "Logical unit not configured"},
{0x6801, "Subsidiary logical unit not configured"},
{0x6900, "Data loss on logical unit"},
{0x6901, "Multiple logical unit failures"},
{0x6902, "Parity/data mismatch"},
{0x6A00, "Informational, refer to log"},
{0x6B00, "State change has occurred"},
{0x6B01, "Redundancy level got better"},
{0x6B02, "Redundancy level got worse"},
{0x6C00, "Rebuild failure occurred"},
{0x6D00, "Recalculate failure occurred"},
{0x6E00, "Command to logical unit failed"},
{0x6F00, "Copy protection key exchange failure - authentication "
"failure"},
{0x6F01, "Copy protection key exchange failure - key not present"},
{0x6F02, "Copy protection key exchange failure - key not established"},
{0x6F03, "Read of scrambled sector without authentication"},
{0x6F04, "Media region code is mismatched to logical unit region"},
{0x6F05, "Drive region must be permanent/region reset count error"},
{0x6F06, "Insufficient block count for binding nonce recording"},
{0x6F07, "Conflict in binding nonce recording"},
/*
* {0x70NN, "Decompression exception short algorithm id of nn"},
*/
{0x7100, "Decompression exception long algorithm id"},
{0x7200, "Session fixation error"},
{0x7201, "Session fixation error writing lead-in"},
{0x7202, "Session fixation error writing lead-out"},
{0x7203, "Session fixation error - incomplete track in session"},
{0x7204, "Empty or partially written reserved track"},
{0x7205, "No more track reservations allowed"},
{0x7206, "RMZ extension is not allowed"},
{0x7207, "No more test zone extensions are allowed"},
{0x7300, "Cd control error"},
{0x7301, "Power calibration area almost full"},
{0x7302, "Power calibration area is full"},
{0x7303, "Power calibration area error"},
{0x7304, "Program memory area update failure"},
{0x7305, "Program memory area is full"},
{0x7306, "RMA/PMA is almost full"},
{0x7310, "Current power calibration area almost full"},
{0x7311, "Current power calibration area is full"},
{0x7317, "RDZ is full"},
{0x7400, "Security error"},
{0x7401, "Unable to decrypt data"},
{0x7402, "Unencrypted data encountered while decrypting"},
{0x7403, "Incorrect data encryption key"},
{0x7404, "Cryptographic integrity validation failed"},
{0x7405, "Error decrypting data"},
{0x7406, "Unknown signature verification key"},
{0x7407, "Encryption parameters not useable"},
{0x7408, "Digital signature validation failure"},
{0x7409, "Encryption mode mismatch on read"},
{0x740A, "Encrypted block not raw read enabled"},
{0x740B, "Incorrect Encryption parameters"},
{0x740C, "Unable to decrypt parameter list"},
{0x740D, "Encryption algorithm disabled"},
{0x7410, "SA creation parameter value invalid"},
{0x7411, "SA creation parameter value rejected"},
{0x7412, "Invalid SA usage"},
{0x7421, "Data Encryption configuration prevented"},
{0x7430, "SA creation parameter not supported"},
{0x7440, "Authentication failed"},
{0x7461, "External data encryption key manager access error"},
{0x7462, "External data encryption key manager error"},
{0x7463, "External data encryption key not found"},
{0x7464, "External data encryption request not authorized"},
{0x746E, "External data encryption control timeout"},
{0x746F, "External data encryption control error"},
{0x7471, "Logical unit access not authorized"},
{0x7479, "Security conflict in translated device"},
{0, NULL}
#define SENSE_CODE(c, s) {c, sizeof(s)},
#include "sense_codes.h"
#undef SENSE_CODE
};
static const char *additional_text =
#define SENSE_CODE(c, s) s "\0"
#include "sense_codes.h"
#undef SENSE_CODE
;
struct error_info2 {
unsigned char code1, code2_min, code2_max;
const char * str;
@ -1197,11 +377,14 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq, const char **fmt)
{
int i;
unsigned short code = ((asc << 8) | ascq);
unsigned offset = 0;
*fmt = NULL;
for (i = 0; additional[i].text; i++)
for (i = 0; i < ARRAY_SIZE(additional); i++) {
if (additional[i].code12 == code)
return additional[i].text;
return additional_text + offset;
offset += additional[i].size;
}
for (i = 0; additional2[i].fmt; i++) {
if (additional2[i].code1 == asc &&
ascq >= additional2[i].code2_min &&

View file

@ -1615,6 +1615,13 @@ err1:
* place at the same time and the failure was due to CXL services being
* unable to keep up.
*
* As this routine is called on ioctl context, it holds the ioctl r/w
* semaphore that is used to drain ioctls in recovery scenarios. The
* implementation to achieve the pacing described above (a local mutex)
* requires that the ioctl r/w semaphore be dropped and reacquired to
* avoid a 3-way deadlock when multiple process recoveries operate in
* parallel.
*
* Because a user can detect an error condition before the kernel, it is
* quite possible for this routine to act as the kernel's EEH detection
* source (MMIO read of mbox_r). Because of this, there is a window of
@ -1642,9 +1649,17 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
int rc = 0;
atomic_inc(&cfg->recovery_threads);
up_read(&cfg->ioctl_rwsem);
rc = mutex_lock_interruptible(mutex);
down_read(&cfg->ioctl_rwsem);
if (rc)
goto out;
rc = check_state(cfg);
if (rc) {
dev_err(dev, "%s: Failed state! rc=%d\n", __func__, rc);
rc = -ENODEV;
goto out;
}
dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n",
__func__, recover->reason, rctxid);

View file

@ -190,15 +190,18 @@ static int submit_stpg(struct scsi_device *sdev, int group_id,
ALUA_FAILOVER_RETRIES, NULL, req_flags);
}
struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
int group_id)
static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
int group_id)
{
struct alua_port_group *pg;
if (!id_str || !id_size || !strlen(id_str))
return NULL;
list_for_each_entry(pg, &port_group_list, node) {
if (pg->group_id != group_id)
continue;
if (pg->device_id_len != id_size)
if (!pg->device_id_len || pg->device_id_len != id_size)
continue;
if (strncmp(pg->device_id_str, id_str, id_size))
continue;
@ -219,8 +222,8 @@ struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size,
* Allocate a new port_group structure for a given
* device.
*/
struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
int group_id, int tpgs)
static struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
int group_id, int tpgs)
{
struct alua_port_group *pg, *tmp_pg;
@ -232,14 +235,14 @@ struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev,
sizeof(pg->device_id_str));
if (pg->device_id_len <= 0) {
/*
* Internal error: TPGS supported but no device
* identifcation found. Disable ALUA support.
* TPGS supported but no device identification found.
* Generate private device identification.
*/
kfree(pg);
sdev_printk(KERN_INFO, sdev,
"%s: No device descriptors found\n",
ALUA_DH_NAME);
return ERR_PTR(-ENXIO);
pg->device_id_str[0] = '\0';
pg->device_id_len = 0;
}
pg->group_id = group_id;
pg->tpgs = tpgs;
@ -354,9 +357,15 @@ static int alua_check_vpd(struct scsi_device *sdev, struct alua_dh_data *h,
return SCSI_DH_NOMEM;
return SCSI_DH_DEV_UNSUPP;
}
sdev_printk(KERN_INFO, sdev,
"%s: device %s port group %x rel port %x\n",
ALUA_DH_NAME, pg->device_id_str, group_id, rel_port);
if (pg->device_id_len)
sdev_printk(KERN_INFO, sdev,
"%s: device %s port group %x rel port %x\n",
ALUA_DH_NAME, pg->device_id_str,
group_id, rel_port);
else
sdev_printk(KERN_INFO, sdev,
"%s: port group %x rel port %x\n",
ALUA_DH_NAME, group_id, rel_port);
/* Check for existing port group references */
spin_lock(&h->pg_lock);

View file

@ -34,11 +34,14 @@
* Definitions for the generic 5380 driver.
*/
#define DONT_USE_INTR
#define NCR5380_read(reg) inb(instance->io_port + reg)
#define NCR5380_write(reg, value) outb(value, instance->io_port + reg)
#define NCR5380_dma_xfer_len(instance, cmd, phase) (0)
#define NCR5380_dma_recv_setup(instance, dst, len) (0)
#define NCR5380_dma_send_setup(instance, src, len) (0)
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_implementation_fields /* none */
#include "NCR5380.h"
@ -62,7 +65,6 @@ static struct scsi_host_template dmx3191d_driver_template = {
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128,
};
static int dmx3191d_probe_one(struct pci_dev *pdev,
@ -93,7 +95,7 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
*/
shost->irq = NO_IRQ;
error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA);
error = NCR5380_init(shost, 0);
if (error)
goto out_host_put;

View file

@ -1,6 +1,3 @@
#define PSEUDO_DMA
#define DONT_USE_INTR
/*
* DTC 3180/3280 driver, by
* Ray Van Tassle rayvt@comm.mot.com
@ -54,7 +51,6 @@
#include <scsi/scsi_host.h>
#include "dtc.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
/*
@ -229,7 +225,7 @@ found:
instance->base = addr;
((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
if (NCR5380_init(instance, FLAG_NO_DMA_FIXUP))
if (NCR5380_init(instance, FLAG_LATE_DMA_SETUP))
goto out_unregister;
NCR5380_maybe_reset_bus(instance);
@ -244,9 +240,10 @@ found:
if (instance->irq == 255)
instance->irq = NO_IRQ;
#ifndef DONT_USE_INTR
/* With interrupts enabled, it will sometimes hang when doing heavy
* reads. So better not enable them until I finger it out. */
instance->irq = NO_IRQ;
if (instance->irq != NO_IRQ)
if (request_irq(instance->irq, dtc_intr, 0,
"dtc", instance)) {
@ -258,11 +255,7 @@ found:
printk(KERN_WARNING "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
printk(KERN_WARNING "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
#else
if (instance->irq != NO_IRQ)
printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
instance->irq = NO_IRQ;
#endif
dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
instance->host_no, instance->irq);
@ -323,7 +316,8 @@ static int dtc_biosparam(struct scsi_device *sdev, struct block_device *dev,
* timeout.
*/
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
static inline int dtc_pread(struct Scsi_Host *instance,
unsigned char *dst, int len)
{
unsigned char *d = dst;
int i; /* For counting time spent in the poll-loop */
@ -352,8 +346,6 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
++i;
rtrc(0);
if (i > hostdata->spin_max_r)
hostdata->spin_max_r = i;
return (0);
}
@ -370,7 +362,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
* timeout.
*/
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
static inline int dtc_pwrite(struct Scsi_Host *instance,
unsigned char *src, int len)
{
int i;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
@ -400,8 +393,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
rtrc(7);
/* Check for parity error here. fixme. */
rtrc(0);
if (i > hostdata->spin_max_w)
hostdata->spin_max_w = i;
return (0);
}
@ -440,8 +431,6 @@ static struct scsi_host_template driver_template = {
.detect = dtc_detect,
.release = dtc_release,
.proc_name = "dtc3x80",
.show_info = dtc_show_info,
.write_info = dtc_write_info,
.info = dtc_info,
.queuecommand = dtc_queue_command,
.eh_abort_handler = dtc_abort,

View file

@ -21,14 +21,17 @@
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
dtc_dma_xfer_len(cmd)
#define NCR5380_dma_recv_setup dtc_pread
#define NCR5380_dma_send_setup dtc_pwrite
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_intr dtc_intr
#define NCR5380_queue_command dtc_queue_command
#define NCR5380_abort dtc_abort
#define NCR5380_bus_reset dtc_bus_reset
#define NCR5380_info dtc_info
#define NCR5380_show_info dtc_show_info
#define NCR5380_write_info dtc_write_info
#define NCR5380_io_delay(x) udelay(x)
/* 15 12 11 10
1001 1100 0000 0000 */

View file

@ -729,6 +729,7 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev
break;
case 0x24:
SD(sh)->EATA_revision = 'z';
break;
default:
SD(sh)->EATA_revision = '?';
}

View file

@ -246,7 +246,7 @@ static struct scsi_host_template driver_template = {
.eh_target_reset_handler = esas2r_target_reset,
.can_queue = 128,
.this_id = -1,
.sg_tablesize = SCSI_MAX_SG_SEGMENTS,
.sg_tablesize = SG_CHUNK_SIZE,
.cmd_per_lun =
ESAS2R_DEFAULT_CMD_PER_LUN,
.present = 0,
@ -271,7 +271,7 @@ module_param(num_sg_lists, int, 0);
MODULE_PARM_DESC(num_sg_lists,
"Number of scatter/gather lists. Default 1024.");
int sg_tablesize = SCSI_MAX_SG_SEGMENTS;
int sg_tablesize = SG_CHUNK_SIZE;
module_param(sg_tablesize, int, 0);
MODULE_PARM_DESC(sg_tablesize,
"Maximum number of entries in a scatter/gather table.");

View file

@ -39,7 +39,7 @@
#define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver"
#define DRV_VERSION "1.6.0.17a"
#define DRV_VERSION "1.6.0.21"
#define PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: "

View file

@ -439,7 +439,6 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
int sg_count = 0;
unsigned long flags = 0;
unsigned long ptr;
struct fc_rport_priv *rdata;
spinlock_t *io_lock = NULL;
int io_lock_acquired = 0;
@ -455,14 +454,17 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
return 0;
}
rdata = lp->tt.rport_lookup(lp, rport->port_id);
if (!rdata || (rdata->rp_state == RPORT_ST_DELETE)) {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"returning IO as rport is removed\n");
atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
sc->result = DID_NO_CONNECT;
done(sc);
return 0;
if (rport) {
struct fc_rport_libfc_priv *rp = rport->dd_data;
if (!rp || rp->rp_state != RPORT_ST_READY) {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"returning DID_NO_CONNECT for IO as rport is removed\n");
atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
sc->result = DID_NO_CONNECT<<16;
done(sc);
return 0;
}
}
if (lp->state != LPORT_ST_READY || !(lp->link_up))
@ -1091,6 +1093,11 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
atomic64_inc(
&term_stats->terminate_fw_timeouts);
break;
case FCPIO_ITMF_REJECTED:
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"abort reject recd. id %d\n",
(int)(id & FNIC_TAG_MASK));
break;
case FCPIO_IO_NOT_FOUND:
if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
atomic64_inc(&abts_stats->abort_io_not_found);
@ -1111,9 +1118,15 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
spin_unlock_irqrestore(io_lock, flags);
return;
}
CMD_ABTS_STATUS(sc) = hdr_status;
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE;
/* If the status is IO not found consider it as success */
if (hdr_status == FCPIO_IO_NOT_FOUND)
CMD_ABTS_STATUS(sc) = FCPIO_SUCCESS;
else
CMD_ABTS_STATUS(sc) = hdr_status;
atomic64_dec(&fnic_stats->io_stats.active_ios);
if (atomic64_read(&fnic->io_cmpl_skip))
atomic64_dec(&fnic->io_cmpl_skip);
@ -1926,21 +1939,31 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
start_time = io_req->start_time;
/*
* firmware completed the abort, check the status,
* free the io_req irrespective of failure or success
* free the io_req if successful. If abort fails,
* Device reset will clean the I/O.
*/
if (CMD_ABTS_STATUS(sc) != FCPIO_SUCCESS)
if (CMD_ABTS_STATUS(sc) == FCPIO_SUCCESS)
CMD_SP(sc) = NULL;
else {
ret = FAILED;
CMD_SP(sc) = NULL;
spin_unlock_irqrestore(io_lock, flags);
goto fnic_abort_cmd_end;
}
spin_unlock_irqrestore(io_lock, flags);
start_time = io_req->start_time;
fnic_release_ioreq_buf(fnic, io_req, sc);
mempool_free(io_req, fnic->io_req_pool);
if (sc->scsi_done) {
/* Call SCSI completion function to complete the IO */
sc->result = (DID_ABORT << 16);
sc->scsi_done(sc);
}
fnic_abort_cmd_end:
FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no,
sc->request->tag, sc,
@ -2018,7 +2041,9 @@ lr_io_req_end:
* successfully aborted, 1 otherwise
*/
static int fnic_clean_pending_aborts(struct fnic *fnic,
struct scsi_cmnd *lr_sc)
struct scsi_cmnd *lr_sc,
bool new_sc)
{
int tag, abt_tag;
struct fnic_io_req *io_req;
@ -2036,10 +2061,10 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, tag);
/*
* ignore this lun reset cmd or cmds that do not belong to
* this lun
* ignore this lun reset cmd if issued using new SC
* or cmds that do not belong to this lun
*/
if (!sc || sc == lr_sc || sc->device != lun_dev) {
if (!sc || ((sc == lr_sc) && new_sc) || sc->device != lun_dev) {
spin_unlock_irqrestore(io_lock, flags);
continue;
}
@ -2145,11 +2170,27 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
goto clean_pending_aborts_end;
}
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
CMD_SP(sc) = NULL;
/* original sc used for lr is handled by dev reset code */
if (sc != lr_sc)
CMD_SP(sc) = NULL;
spin_unlock_irqrestore(io_lock, flags);
fnic_release_ioreq_buf(fnic, io_req, sc);
mempool_free(io_req, fnic->io_req_pool);
/* original sc used for lr is handled by dev reset code */
if (sc != lr_sc) {
fnic_release_ioreq_buf(fnic, io_req, sc);
mempool_free(io_req, fnic->io_req_pool);
}
/*
* Any IO is returned during reset, it needs to call scsi_done
* to return the scsi_cmnd to upper layer.
*/
if (sc->scsi_done) {
/* Set result to let upper SCSI layer retry */
sc->result = DID_RESET << 16;
sc->scsi_done(sc);
}
}
schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov));
@ -2243,6 +2284,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
int tag = 0;
DECLARE_COMPLETION_ONSTACK(tm_done);
int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/
bool new_sc = 0;
/* Wait for rport to unblock */
fc_block_scsi_eh(sc);
@ -2288,13 +2330,12 @@ int fnic_device_reset(struct scsi_cmnd *sc)
* fix the way the EH ioctls work for real, but until
* that happens we fail these explicit requests here.
*/
if (shost_use_blk_mq(sc->device->host))
goto fnic_device_reset_end;
tag = fnic_scsi_host_start_tag(fnic, sc);
if (unlikely(tag == SCSI_NO_TAG))
goto fnic_device_reset_end;
tag_gen_flag = 1;
new_sc = 1;
}
io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags);
@ -2429,7 +2470,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
* the lun reset cmd. If all cmds get cleaned, the lun reset
* succeeds
*/
if (fnic_clean_pending_aborts(fnic, sc)) {
if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,

View file

@ -18,50 +18,10 @@
*
* Added ISAPNP support for DTC436 adapters,
* Thomas Sailer, sailer@ife.ee.ethz.ch
*/
/*
* TODO : flesh out DMA support, find some one actually using this (I have
* a memory mapped Trantor board that works fine)
*/
/*
* The card is detected and initialized in one of several ways :
* 1. With command line overrides - NCR5380=port,irq may be
* used on the LILO command line to override the defaults.
*
* 2. With the GENERIC_NCR5380_OVERRIDE compile time define. This is
* specified as an array of address, irq, dma, board tuples. Ie, for
* one board at 0x350, IRQ5, no dma, I could say
* -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
*
* -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
* IRQ line if overridden on the command line.
*
* 3. When included as a module, with arguments passed on the command line:
* ncr_irq=xx the interrupt
* ncr_addr=xx the port or base address (for port or memory
* mapped, resp.)
* ncr_dma=xx the DMA
* ncr_5380=1 to set up for a NCR5380 board
* ncr_53c400=1 to set up for a NCR53C400 board
* e.g.
* modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
* for a port mapped NCR5380 board or
* modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
* for a memory mapped NCR53C400 board with interrupts disabled.
*
* 255 should be specified for no or DMA interrupt, 254 to autoprobe for an
* IRQ line if overridden on the command line.
*
* See Documentation/scsi/g_NCR5380.txt for more info.
*/
#define AUTOPROBE_IRQ
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define PSEUDO_DMA
#endif
#include <asm/io.h>
#include <linux/blkdev.h>
#include <linux/module.h>
@ -270,7 +230,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
#ifndef SCSI_G_NCR5380_MEM
int i;
int port_idx = -1;
unsigned long region_size = 16;
unsigned long region_size;
#endif
static unsigned int __initdata ncr_53c400a_ports[] = {
0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
@ -290,6 +250,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
#ifdef SCSI_G_NCR5380_MEM
unsigned long base;
void __iomem *iomem;
resource_size_t iomem_size;
#endif
if (ncr_irq)
@ -350,25 +311,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
flags = 0;
switch (overrides[current_override].board) {
case BOARD_NCR5380:
flags = FLAG_NO_PSEUDO_DMA;
break;
case BOARD_NCR53C400:
#ifdef PSEUDO_DMA
flags = FLAG_NO_DMA_FIXUP;
#endif
flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
break;
case BOARD_NCR53C400A:
flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
magic = ncr_53c400a_magic;
break;
case BOARD_HP_C2502:
flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
magic = hp_c2502_magic;
break;
case BOARD_DTC3181E:
flags = FLAG_NO_DMA_FIXUP;
ports = dtc_3181e_ports;
magic = ncr_53c400a_magic;
break;
@ -381,20 +334,22 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
/* Disable the adapter and look for a free io port */
magic_configure(-1, 0, magic);
region_size = 16;
if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
for (i = 0; ports[i]; i++) {
if (!request_region(ports[i], 16, "ncr53c80"))
if (!request_region(ports[i], region_size, "ncr53c80"))
continue;
if (overrides[current_override].NCR5380_map_name == ports[i])
break;
release_region(ports[i], 16);
release_region(ports[i], region_size);
} else
for (i = 0; ports[i]; i++) {
if (!request_region(ports[i], 16, "ncr53c80"))
if (!request_region(ports[i], region_size, "ncr53c80"))
continue;
if (inb(ports[i]) == 0xff)
break;
release_region(ports[i], 16);
release_region(ports[i], region_size);
}
if (ports[i]) {
/* At this point we have our region reserved */
@ -410,17 +365,19 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
else
{
/* Not a 53C400A style setup - just grab */
if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")))
region_size = 8;
if (!request_region(overrides[current_override].NCR5380_map_name,
region_size, "ncr5380"))
continue;
region_size = NCR5380_region_size;
}
#else
base = overrides[current_override].NCR5380_map_name;
if (!request_mem_region(base, NCR5380_region_size, "ncr5380"))
iomem_size = NCR53C400_region_size;
if (!request_mem_region(base, iomem_size, "ncr5380"))
continue;
iomem = ioremap(base, NCR5380_region_size);
iomem = ioremap(base, iomem_size);
if (!iomem) {
release_mem_region(base, NCR5380_region_size);
release_mem_region(base, iomem_size);
continue;
}
#endif
@ -458,6 +415,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
#else
instance->base = overrides[current_override].NCR5380_map_name;
hostdata->iomem = iomem;
hostdata->iomem_size = iomem_size;
switch (overrides[current_override].board) {
case BOARD_NCR53C400:
hostdata->c400_ctl_status = 0x100;
@ -472,7 +430,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
}
#endif
if (NCR5380_init(instance, flags))
if (NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP))
goto out_unregister;
switch (overrides[current_override].board) {
@ -524,7 +482,7 @@ out_release:
release_region(overrides[current_override].NCR5380_map_name, region_size);
#else
iounmap(iomem);
release_mem_region(base, NCR5380_region_size);
release_mem_region(base, iomem_size);
#endif
return count;
}
@ -546,45 +504,18 @@ static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
#ifndef SCSI_G_NCR5380_MEM
release_region(instance->io_port, instance->n_io_port);
#else
iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
release_mem_region(instance->base, NCR5380_region_size);
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
iounmap(hostdata->iomem);
release_mem_region(instance->base, hostdata->iomem_size);
}
#endif
return 0;
}
#ifdef BIOSPARAM
/**
* generic_NCR5380_biosparam
* @disk: disk to compute geometry for
* @dev: device identifier for this disk
* @ip: sizes to fill in
*
* Generates a BIOS / DOS compatible H-C-S mapping for the specified
* device / size.
*
* XXX Most SCSI boards use this mapping, I could be incorrect. Someone
* using hard disks on a trantor should verify that this mapping
* corresponds to that used by the BIOS / ASPI driver by running the linux
* fdisk program and matching the H_C_S coordinates to what DOS uses.
*
* Locks: none
*/
static int
generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
sector_t capacity, int *ip)
{
ip[0] = 64;
ip[1] = 32;
ip[2] = capacity >> 11;
return 0;
}
#endif
#ifdef PSEUDO_DMA
/**
* NCR5380_pread - pseudo DMA read
* generic_NCR5380_pread - pseudo DMA read
* @instance: adapter to read from
* @dst: buffer to read into
* @len: buffer length
@ -593,7 +524,8 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
* controller
*/
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
unsigned char *dst, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
@ -661,7 +593,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
}
/**
* NCR5380_write - pseudo DMA write
* generic_NCR5380_pwrite - pseudo DMA write
* @instance: adapter to read from
* @dst: buffer to read into
* @len: buffer length
@ -670,7 +602,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
* controller
*/
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
unsigned char *src, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
@ -738,10 +671,15 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
return 0;
}
static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int transfersize = cmd->transfersize;
if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
return 0;
/* Limit transfers to 32K, for xx400 & xx406
* pseudoDMA that transfers in 128 bytes blocks.
*/
@ -756,8 +694,6 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
return transfersize;
}
#endif /* PSEUDO_DMA */
/*
* Include the NCR5380 core code that we build our driver around
*/
@ -773,7 +709,6 @@ static struct scsi_host_template driver_template = {
.queuecommand = generic_NCR5380_queue_command,
.eh_abort_handler = generic_NCR5380_abort,
.eh_bus_reset_handler = generic_NCR5380_bus_reset,
.bios_param = NCR5380_BIOSPARAM,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,

View file

@ -14,13 +14,6 @@
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define BIOSPARAM
#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
#else
#define NCR5380_BIOSPARAM NULL
#endif
#define __STRVAL(x) #x
#define STRVAL(x) __STRVAL(x)
@ -30,12 +23,6 @@
#define NCR5380_map_type int
#define NCR5380_map_name port
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR5380_region_size 16
#else
#define NCR5380_region_size 8
#endif
#define NCR5380_read(reg) \
inb(instance->io_port + (reg))
#define NCR5380_write(reg, value) \
@ -55,7 +42,7 @@
#define NCR5380_map_name base
#define NCR53C400_mem_base 0x3880
#define NCR53C400_host_buffer 0x3900
#define NCR5380_region_size 0x3a00
#define NCR53C400_region_size 0x3a00
#define NCR5380_read(reg) \
readb(((struct NCR5380_hostdata *)shost_priv(instance))->iomem + \
@ -66,6 +53,7 @@
#define NCR5380_implementation_fields \
void __iomem *iomem; \
resource_size_t iomem_size; \
int c400_ctl_status; \
int c400_blk_cnt; \
int c400_host_buf;
@ -73,16 +61,18 @@
#endif
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
generic_NCR5380_dma_xfer_len(cmd)
generic_NCR5380_dma_xfer_len(instance, cmd)
#define NCR5380_dma_recv_setup generic_NCR5380_pread
#define NCR5380_dma_send_setup generic_NCR5380_pwrite
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_intr generic_NCR5380_intr
#define NCR5380_queue_command generic_NCR5380_queue_command
#define NCR5380_abort generic_NCR5380_abort
#define NCR5380_bus_reset generic_NCR5380_bus_reset
#define NCR5380_pread generic_NCR5380_pread
#define NCR5380_pwrite generic_NCR5380_pwrite
#define NCR5380_info generic_NCR5380_info
#define NCR5380_show_info generic_NCR5380_show_info
#define NCR5380_io_delay(x) udelay(x)
#define BOARD_NCR5380 0
#define BOARD_NCR53C400 1

View file

@ -23,7 +23,7 @@
#include <scsi/sas_ata.h>
#include <scsi/libsas.h>
#define DRV_VERSION "v1.3"
#define DRV_VERSION "v1.4"
#define HISI_SAS_MAX_PHYS 9
#define HISI_SAS_MAX_QUEUES 32
@ -133,6 +133,9 @@ struct hisi_sas_hw {
int (*hw_init)(struct hisi_hba *hisi_hba);
void (*setup_itct)(struct hisi_hba *hisi_hba,
struct hisi_sas_device *device);
int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx,
struct domain_device *device);
struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
void (*sl_notify)(struct hisi_hba *hisi_hba, int phy_no);
int (*get_free_slot)(struct hisi_hba *hisi_hba, int *q, int *s);
void (*start_delivery)(struct hisi_hba *hisi_hba);
@ -298,7 +301,7 @@ struct hisi_sas_command_table_stp {
u8 atapi_cdb[ATAPI_CDB_LEN];
};
#define HISI_SAS_SGE_PAGE_CNT SCSI_MAX_SG_SEGMENTS
#define HISI_SAS_SGE_PAGE_CNT SG_CHUNK_SIZE
struct hisi_sas_sge_page {
struct hisi_sas_sge sge[HISI_SAS_SGE_PAGE_CNT];
};

View file

@ -227,7 +227,11 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_hba *hisi_hba,
} else
n_elem = task->num_scatter;
rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
if (hisi_hba->hw->slot_index_alloc)
rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx,
device);
else
rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
if (rc)
goto err_out;
rc = hisi_hba->hw->get_free_slot(hisi_hba, &dlvry_queue,
@ -417,7 +421,10 @@ static int hisi_sas_dev_found(struct domain_device *device)
struct hisi_sas_device *sas_dev;
struct device *dev = &hisi_hba->pdev->dev;
sas_dev = hisi_sas_alloc_dev(device);
if (hisi_hba->hw->alloc_dev)
sas_dev = hisi_hba->hw->alloc_dev(device);
else
sas_dev = hisi_sas_alloc_dev(device);
if (!sas_dev) {
dev_err(dev, "fail alloc dev: max support %d devices\n",
HISI_SAS_MAX_DEVICES);

View file

@ -465,6 +465,62 @@ static u32 hisi_sas_phy_read32(struct hisi_hba *hisi_hba,
return readl(regs);
}
/* This function needs to be protected from pre-emption. */
static int
slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, int *slot_idx,
struct domain_device *device)
{
unsigned int index = 0;
void *bitmap = hisi_hba->slot_index_tags;
int sata_dev = dev_is_sata(device);
while (1) {
index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
index);
if (index >= hisi_hba->slot_index_count)
return -SAS_QUEUE_FULL;
/*
* SAS IPTT bit0 should be 1
*/
if (sata_dev || (index & 1))
break;
index++;
}
set_bit(index, bitmap);
*slot_idx = index;
return 0;
}
static struct
hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)
{
struct hisi_hba *hisi_hba = device->port->ha->lldd_ha;
struct hisi_sas_device *sas_dev = NULL;
int i, sata_dev = dev_is_sata(device);
spin_lock(&hisi_hba->lock);
for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
/*
* SATA device id bit0 should be 0
*/
if (sata_dev && (i & 1))
continue;
if (hisi_hba->devices[i].dev_type == SAS_PHY_UNUSED) {
hisi_hba->devices[i].device_id = i;
sas_dev = &hisi_hba->devices[i];
sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
sas_dev->dev_type = device->dev_type;
sas_dev->hisi_hba = hisi_hba;
sas_dev->sas_device = device;
break;
}
}
spin_unlock(&hisi_hba->lock);
return sas_dev;
}
static void config_phy_opt_mode_v2_hw(struct hisi_hba *hisi_hba, int phy_no)
{
u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG);
@ -544,7 +600,7 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
}
qw0 |= ((1 << ITCT_HDR_VALID_OFF) |
(device->max_linkrate << ITCT_HDR_MCR_OFF) |
(device->linkrate << ITCT_HDR_MCR_OFF) |
(1 << ITCT_HDR_VLN_OFF) |
(port->id << ITCT_HDR_PORT_ID_OFF));
itct->qw0 = cpu_to_le64(qw0);
@ -554,10 +610,11 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
itct->sas_addr = __swab64(itct->sas_addr);
/* qw2 */
itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_INLT_OFF) |
(0xff00ULL << ITCT_HDR_BITLT_OFF) |
(0xff00ULL << ITCT_HDR_MCTLT_OFF) |
(0xff00ULL << ITCT_HDR_RTOLT_OFF));
if (!dev_is_sata(device))
itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_INLT_OFF) |
(0x1ULL << ITCT_HDR_BITLT_OFF) |
(0x32ULL << ITCT_HDR_MCTLT_OFF) |
(0x1ULL << ITCT_HDR_RTOLT_OFF));
}
static void free_device_v2_hw(struct hisi_hba *hisi_hba,
@ -715,7 +772,7 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL, 0x7FF);
hisi_sas_write32(hisi_hba, OPENA_WT_CONTI_TIME, 0x1);
hisi_sas_write32(hisi_hba, I_T_NEXUS_LOSS_TIME, 0x1F4);
hisi_sas_write32(hisi_hba, MAX_CON_TIME_LIMIT_TIME, 0x4E20);
hisi_sas_write32(hisi_hba, MAX_CON_TIME_LIMIT_TIME, 0x32);
hisi_sas_write32(hisi_hba, BUS_INACTIVE_LIMIT_TIME, 0x1);
hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
hisi_sas_write32(hisi_hba, HGC_ERR_STAT_EN, 0x1);
@ -1993,22 +2050,23 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
u32 ent_tmp, ent_msk, ent_int, port_id, link_rate, hard_phy_linkrate;
irqreturn_t res = IRQ_HANDLED;
u8 attached_sas_addr[SAS_ADDR_SIZE] = {0};
int phy_no;
int phy_no, offset;
phy_no = sas_phy->id;
initial_fis = &hisi_hba->initial_fis[phy_no];
fis = &initial_fis->fis;
ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK1);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk | 1 << phy_no);
offset = 4 * (phy_no / 4);
ent_msk = hisi_sas_read32(hisi_hba, ENT_INT_SRC_MSK1 + offset);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset,
ent_msk | 1 << ((phy_no % 4) * 8));
ent_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC1);
ent_tmp = ent_int;
ent_int = hisi_sas_read32(hisi_hba, ENT_INT_SRC1 + offset);
ent_tmp = ent_int & (1 << (ENT_INT_SRC1_D2H_FIS_CH1_OFF *
(phy_no % 4)));
ent_int >>= ENT_INT_SRC1_D2H_FIS_CH1_OFF * (phy_no % 4);
if ((ent_int & ENT_INT_SRC1_D2H_FIS_CH0_MSK) == 0) {
dev_warn(dev, "sata int: phy%d did not receive FIS\n", phy_no);
hisi_sas_write32(hisi_hba, ENT_INT_SRC1, ent_tmp);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk);
res = IRQ_NONE;
goto end;
}
@ -2056,8 +2114,8 @@ static irqreturn_t sata_int_v2_hw(int irq_no, void *p)
queue_work(hisi_hba->wq, &phy->phyup_ws);
end:
hisi_sas_write32(hisi_hba, ENT_INT_SRC1, ent_tmp);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, ent_msk);
hisi_sas_write32(hisi_hba, ENT_INT_SRC1 + offset, ent_tmp);
hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1 + offset, ent_msk);
return res;
}
@ -2165,6 +2223,8 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba)
static const struct hisi_sas_hw hisi_sas_v2_hw = {
.hw_init = hisi_sas_v2_init,
.setup_itct = setup_itct_v2_hw,
.slot_index_alloc = slot_index_alloc_quirk_v2_hw,
.alloc_dev = alloc_dev_quirk_v2_hw,
.sl_notify = sl_notify_v2_hw,
.get_wideport_bitmap = get_wideport_bitmap_v2_hw,
.free_device = free_device_v2_hw,

View file

@ -60,7 +60,7 @@
* HPSA_DRIVER_VERSION must be 3 byte values (0-255) separated by '.'
* with an optional trailing '-' followed by a byte value (0-255).
*/
#define HPSA_DRIVER_VERSION "3.4.14-0"
#define HPSA_DRIVER_VERSION "3.4.16-0"
#define DRIVER_NAME "HP HPSA Driver (v " HPSA_DRIVER_VERSION ")"
#define HPSA "hpsa"
@ -294,6 +294,9 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h);
static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h,
struct ReportExtendedLUNdata *buf, int bufsize);
static int hpsa_luns_changed(struct ctlr_info *h);
static bool hpsa_cmd_dev_match(struct ctlr_info *h, struct CommandList *c,
struct hpsa_scsi_dev_t *dev,
unsigned char *scsi3addr);
static inline struct ctlr_info *sdev_to_hba(struct scsi_device *sdev)
{
@ -728,6 +731,29 @@ static ssize_t unique_id_show(struct device *dev,
sn[12], sn[13], sn[14], sn[15]);
}
static ssize_t sas_address_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct ctlr_info *h;
struct scsi_device *sdev;
struct hpsa_scsi_dev_t *hdev;
unsigned long flags;
u64 sas_address;
sdev = to_scsi_device(dev);
h = sdev_to_hba(sdev);
spin_lock_irqsave(&h->lock, flags);
hdev = sdev->hostdata;
if (!hdev || is_logical_device(hdev) || !hdev->expose_device) {
spin_unlock_irqrestore(&h->lock, flags);
return -ENODEV;
}
sas_address = hdev->sas_address;
spin_unlock_irqrestore(&h->lock, flags);
return snprintf(buf, PAGE_SIZE, "0x%016llx\n", sas_address);
}
static ssize_t host_show_hp_ssd_smart_path_enabled(struct device *dev,
struct device_attribute *attr, char *buf)
{
@ -840,6 +866,7 @@ static DEVICE_ATTR(raid_level, S_IRUGO, raid_level_show, NULL);
static DEVICE_ATTR(lunid, S_IRUGO, lunid_show, NULL);
static DEVICE_ATTR(unique_id, S_IRUGO, unique_id_show, NULL);
static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
static DEVICE_ATTR(sas_address, S_IRUGO, sas_address_show, NULL);
static DEVICE_ATTR(hp_ssd_smart_path_enabled, S_IRUGO,
host_show_hp_ssd_smart_path_enabled, NULL);
static DEVICE_ATTR(path_info, S_IRUGO, path_info_show, NULL);
@ -865,6 +892,7 @@ static struct device_attribute *hpsa_sdev_attrs[] = {
&dev_attr_unique_id,
&dev_attr_hp_ssd_smart_path_enabled,
&dev_attr_path_info,
&dev_attr_sas_address,
NULL,
};
@ -1637,9 +1665,8 @@ static void hpsa_figure_phys_disk_ptrs(struct ctlr_info *h,
for (j = 0; j < ndevices; j++) {
if (dev[j] == NULL)
continue;
if (dev[j]->devtype != TYPE_DISK)
continue;
if (dev[j]->devtype != TYPE_ZBC)
if (dev[j]->devtype != TYPE_DISK &&
dev[j]->devtype != TYPE_ZBC)
continue;
if (is_logical_device(dev[j]))
continue;
@ -1684,9 +1711,8 @@ static void hpsa_update_log_drive_phys_drive_ptrs(struct ctlr_info *h,
for (i = 0; i < ndevices; i++) {
if (dev[i] == NULL)
continue;
if (dev[i]->devtype != TYPE_DISK)
continue;
if (dev[i]->devtype != TYPE_ZBC)
if (dev[i]->devtype != TYPE_DISK &&
dev[i]->devtype != TYPE_ZBC)
continue;
if (!is_logical_device(dev[i]))
continue;
@ -1720,6 +1746,51 @@ static int hpsa_add_device(struct ctlr_info *h, struct hpsa_scsi_dev_t *device)
return rc;
}
static int hpsa_find_outstanding_commands_for_dev(struct ctlr_info *h,
struct hpsa_scsi_dev_t *dev)
{
int i;
int count = 0;
for (i = 0; i < h->nr_cmds; i++) {
struct CommandList *c = h->cmd_pool + i;
int refcount = atomic_inc_return(&c->refcount);
if (refcount > 1 && hpsa_cmd_dev_match(h, c, dev,
dev->scsi3addr)) {
unsigned long flags;
spin_lock_irqsave(&h->lock, flags); /* Implied MB */
if (!hpsa_is_cmd_idle(c))
++count;
spin_unlock_irqrestore(&h->lock, flags);
}
cmd_free(h, c);
}
return count;
}
static void hpsa_wait_for_outstanding_commands_for_dev(struct ctlr_info *h,
struct hpsa_scsi_dev_t *device)
{
int cmds = 0;
int waits = 0;
while (1) {
cmds = hpsa_find_outstanding_commands_for_dev(h, device);
if (cmds == 0)
break;
if (++waits > 20)
break;
dev_warn(&h->pdev->dev,
"%s: removing device with %d outstanding commands!\n",
__func__, cmds);
msleep(1000);
}
}
static void hpsa_remove_device(struct ctlr_info *h,
struct hpsa_scsi_dev_t *device)
{
@ -1743,8 +1814,13 @@ static void hpsa_remove_device(struct ctlr_info *h,
hpsa_show_dev_msg(KERN_WARNING, h, device,
"didn't find device for removal.");
}
} else /* HBA */
} else { /* HBA */
device->removed = 1;
hpsa_wait_for_outstanding_commands_for_dev(h, device);
hpsa_remove_sas_device(device);
}
}
static void adjust_hpsa_scsi_table(struct ctlr_info *h,
@ -2146,7 +2222,8 @@ static void hpsa_unmap_sg_chain_block(struct ctlr_info *h,
static int handle_ioaccel_mode2_error(struct ctlr_info *h,
struct CommandList *c,
struct scsi_cmnd *cmd,
struct io_accel2_cmd *c2)
struct io_accel2_cmd *c2,
struct hpsa_scsi_dev_t *dev)
{
int data_len;
int retry = 0;
@ -2210,8 +2287,27 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
case IOACCEL2_STATUS_SR_NO_PATH_TO_DEVICE:
case IOACCEL2_STATUS_SR_INVALID_DEVICE:
case IOACCEL2_STATUS_SR_IOACCEL_DISABLED:
/* We will get an event from ctlr to trigger rescan */
retry = 1;
/*
* Did an HBA disk disappear? We will eventually
* get a state change event from the controller but
* in the meantime, we need to tell the OS that the
* HBA disk is no longer there and stop I/O
* from going down. This allows the potential re-insert
* of the disk to get the same device node.
*/
if (dev->physical_device && dev->expose_device) {
cmd->result = DID_NO_CONNECT << 16;
dev->removed = 1;
h->drv_req_rescan = 1;
dev_warn(&h->pdev->dev,
"%s: device is gone!\n", __func__);
} else
/*
* Retry by sending down the RAID path.
* We will get an event from ctlr to
* trigger rescan regardless.
*/
retry = 1;
break;
default:
retry = 1;
@ -2335,13 +2431,15 @@ static void process_ioaccel2_completion(struct ctlr_info *h,
c2->error_data.serv_response ==
IOACCEL2_SERV_RESPONSE_FAILURE) {
if (c2->error_data.status ==
IOACCEL2_STATUS_SR_IOACCEL_DISABLED)
IOACCEL2_STATUS_SR_IOACCEL_DISABLED) {
dev->offload_enabled = 0;
dev->offload_to_be_enabled = 0;
}
return hpsa_retry_cmd(h, c);
}
if (handle_ioaccel_mode2_error(h, c, cmd, c2))
if (handle_ioaccel_mode2_error(h, c, cmd, c2, dev))
return hpsa_retry_cmd(h, c);
return hpsa_cmd_free_and_done(h, c, cmd);
@ -2806,7 +2904,7 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr,
goto out;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@ -2832,7 +2930,7 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
/* fill_cmd can't fail here, no data buffer to map. */
(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
scsi3addr, TYPE_MSG);
rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
if (rc) {
dev_warn(&h->pdev->dev, "Failed to send reset command\n");
goto out;
@ -3080,7 +3178,7 @@ static int hpsa_get_raid_map(struct ctlr_info *h,
return -1;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@ -3123,7 +3221,7 @@ static int hpsa_bmic_sense_subsystem_information(struct ctlr_info *h,
c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@ -3151,7 +3249,7 @@ static int hpsa_bmic_id_controller(struct ctlr_info *h,
goto out;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@ -3182,7 +3280,7 @@ static int hpsa_bmic_id_physical_device(struct ctlr_info *h,
c->Request.CDB[9] = (bmic_device_index >> 8) & 0xff;
hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
NO_TIMEOUT);
DEFAULT_TIMEOUT);
ei = c->err_info;
if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
hpsa_scsi_interpret_error(h, c);
@ -3250,7 +3348,7 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h,
c->Request.CDB[5] = 0;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
NO_TIMEOUT);
DEFAULT_TIMEOUT);
if (rc)
goto out;
@ -3462,7 +3560,7 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical,
if (extended_response)
c->Request.CDB[1] = extended_response;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
ei = c->err_info;
@ -3569,7 +3667,8 @@ static int hpsa_volume_offline(struct ctlr_info *h,
c = cmd_alloc(h);
(void) fill_cmd(c, TEST_UNIT_READY, h, NULL, 0, 0, scsi3addr, TYPE_CMD);
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
DEFAULT_TIMEOUT);
if (rc) {
cmd_free(h, c);
return 0;
@ -3644,7 +3743,8 @@ static int hpsa_device_supports_aborts(struct ctlr_info *h,
c = cmd_alloc(h);
(void) fill_cmd(c, HPSA_ABORT_MSG, h, &tag, 0, 0, scsi3addr, TYPE_MSG);
(void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
(void) hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
DEFAULT_TIMEOUT);
/* no unmap needed here because no data xfer. */
ei = c->err_info;
switch (ei->CommandStatus) {
@ -5234,6 +5334,12 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
dev = cmd->device->hostdata;
if (!dev) {
cmd->result = NOT_READY << 16; /* host byte */
cmd->scsi_done(cmd);
return 0;
}
if (dev->removed) {
cmd->result = DID_NO_CONNECT << 16;
cmd->scsi_done(cmd);
return 0;
@ -5414,7 +5520,7 @@ static int hpsa_send_test_unit_ready(struct ctlr_info *h,
/* Send the Test Unit Ready, fill_cmd can't fail, no mapping */
(void) fill_cmd(c, TEST_UNIT_READY, h,
NULL, 0, 0, lunaddr, TYPE_CMD);
rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
if (rc)
return rc;
/* no unmap needed here because no data xfer. */
@ -5638,7 +5744,7 @@ static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr,
0, 0, scsi3addr, TYPE_MSG);
if (h->needs_abort_tags_swizzled)
swizzle_abort_tag(&c->Request.CDB[4]);
(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
hpsa_get_tag(h, abort, &taglower, &tagupper);
dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd(abort) completed.\n",
__func__, tagupper, taglower);
@ -5803,7 +5909,7 @@ static int hpsa_send_abort_ioaccel2(struct ctlr_info *h,
c = cmd_alloc(h);
setup_ioaccel2_abort_cmd(c, h, abort, reply_queue);
c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
(void) hpsa_scsi_do_simple_cmd(h, c, reply_queue, DEFAULT_TIMEOUT);
hpsa_get_tag(h, abort, &taglower, &tagupper);
dev_dbg(&h->pdev->dev,
"%s: Tag:0x%08x:%08x: do_simple_cmd(ioaccel2 abort) completed.\n",
@ -6348,7 +6454,8 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
c->SG[0].Len = cpu_to_le32(iocommand.buf_size);
c->SG[0].Ext = cpu_to_le32(HPSA_SG_LAST); /* not chaining */
}
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
DEFAULT_TIMEOUT);
if (iocommand.buf_size > 0)
hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
check_ioctl_unit_attention(h, c);
@ -6480,7 +6587,8 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
}
c->SG[--i].Ext = cpu_to_le32(HPSA_SG_LAST);
}
status = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE, NO_TIMEOUT);
status = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
DEFAULT_TIMEOUT);
if (sg_used)
hpsa_pci_unmap(h->pdev, c, sg_used, PCI_DMA_BIDIRECTIONAL);
check_ioctl_unit_attention(h, c);
@ -8254,8 +8362,10 @@ static void hpsa_ack_ctlr_events(struct ctlr_info *h)
event_type = "configuration change";
/* Stop sending new RAID offload reqs via the IO accelerator */
scsi_block_requests(h->scsi_host);
for (i = 0; i < h->ndevices; i++)
for (i = 0; i < h->ndevices; i++) {
h->dev[i]->offload_enabled = 0;
h->dev[i]->offload_to_be_enabled = 0;
}
hpsa_drain_accel_commands(h);
/* Set 'accelerator path config change' bit */
dev_warn(&h->pdev->dev,
@ -8541,11 +8651,6 @@ reinit_after_soft_reset:
if (rc)
goto clean6; /* sg, cmd, irq, shost, pci, lu, aer/h */
/* hook into SCSI subsystem */
rc = hpsa_scsi_add_host(h);
if (rc)
goto clean7; /* perf, sg, cmd, irq, shost, pci, lu, aer/h */
/* create the resubmit workqueue */
h->rescan_ctlr_wq = hpsa_create_controller_wq(h, "rescan");
if (!h->rescan_ctlr_wq) {
@ -8642,6 +8747,11 @@ reinit_after_soft_reset:
dev_info(&h->pdev->dev,
"Can't track change to report lun data\n");
/* hook into SCSI subsystem */
rc = hpsa_scsi_add_host(h);
if (rc)
goto clean7; /* perf, sg, cmd, irq, shost, pci, lu, aer/h */
/* Monitor the controller for firmware lockups */
h->heartbeat_sample_interval = HEARTBEAT_SAMPLE_INTERVAL;
INIT_DELAYED_WORK(&h->monitor_ctlr_work, hpsa_monitor_ctlr_worker);
@ -8703,7 +8813,7 @@ static void hpsa_flush_cache(struct ctlr_info *h)
goto out;
}
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_TODEVICE, NO_TIMEOUT);
PCI_DMA_TODEVICE, DEFAULT_TIMEOUT);
if (rc)
goto out;
if (c->err_info->CommandStatus != 0)
@ -8742,7 +8852,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if ((rc != 0) || (c->err_info->CommandStatus != 0))
goto errout;
@ -8754,7 +8864,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_TODEVICE, NO_TIMEOUT);
PCI_DMA_TODEVICE, DEFAULT_TIMEOUT);
if ((rc != 0) || (c->err_info->CommandStatus != 0))
goto errout;
@ -8764,7 +8874,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h)
goto errout;
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c,
PCI_DMA_FROMDEVICE, NO_TIMEOUT);
PCI_DMA_FROMDEVICE, DEFAULT_TIMEOUT);
if ((rc != 0) || (c->err_info->CommandStatus != 0))
goto errout;
@ -9602,6 +9712,7 @@ hpsa_sas_get_linkerrors(struct sas_phy *phy)
static int
hpsa_sas_get_enclosure_identifier(struct sas_rphy *rphy, u64 *identifier)
{
*identifier = 0;
return 0;
}

View file

@ -63,6 +63,7 @@ struct hpsa_scsi_dev_t {
unsigned char scsi3addr[8]; /* as presented to the HW */
u8 physical_device : 1;
u8 expose_device;
u8 removed : 1; /* device is marked for death */
#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
unsigned char device_id[16]; /* from inquiry pg. 0x83 */
u64 sas_address;

View file

@ -2127,7 +2127,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
struct iscsi_conn *conn;
struct iscsi_task *task;
struct iscsi_tm *hdr;
int rc, age;
int age;
cls_session = starget_to_session(scsi_target(sc->device));
session = cls_session->dd_data;
@ -2188,10 +2188,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
hdr = &conn->tmhdr;
iscsi_prep_abort_task_pdu(task, hdr);
if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) {
rc = FAILED;
if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout))
goto failed;
}
switch (conn->tmf_state) {
case TMF_SUCCESS:
@ -2423,7 +2421,7 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
*
* This will attempt to send a warm target reset.
*/
int iscsi_eh_target_reset(struct scsi_cmnd *sc)
static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
@ -2495,7 +2493,6 @@ done:
mutex_unlock(&session->eh_mutex);
return rc;
}
EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
/**
* iscsi_eh_recover_target - reset target and possibly the session

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -694,6 +694,7 @@ struct lpfc_hba {
uint8_t wwnn[8];
uint8_t wwpn[8];
uint32_t RandomData[7];
uint32_t fcp_embed_io;
/* HBA Config Parameters */
uint32_t cfg_ack0;
@ -757,7 +758,6 @@ struct lpfc_hba {
uint32_t cfg_fdmi_on;
#define LPFC_FDMI_NO_SUPPORT 0 /* FDMI not supported */
#define LPFC_FDMI_SUPPORT 1 /* FDMI supported? */
#define LPFC_FDMI_SMART_SAN 2 /* SmartSAN supported */
uint32_t cfg_enable_SmartSAN;
lpfc_vpd_t vpd; /* vital product data */

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -4584,15 +4584,14 @@ LPFC_ATTR_R(enable_SmartSAN, 0, 0, 1, "Enable SmartSAN functionality");
# lpfc_fdmi_on: Controls FDMI support.
# 0 No FDMI support (default)
# 1 Traditional FDMI support
# 2 Smart SAN support
# If lpfc_enable_SmartSAN is set 1, the driver sets lpfc_fdmi_on to value 2
# overwriting the current value. If lpfc_enable_SmartSAN is set 0, the
# driver uses the current value of lpfc_fdmi_on provided it has value 0 or 1.
# A value of 2 with lpfc_enable_SmartSAN set to 0 causes the driver to
# set lpfc_fdmi_on back to 1.
# Value range [0,2]. Default value is 0.
# Traditional FDMI support means the driver will assume FDMI-2 support;
# however, if that fails, it will fallback to FDMI-1.
# If lpfc_enable_SmartSAN is set to 1, the driver ignores lpfc_fdmi_on.
# If lpfc_enable_SmartSAN is set 0, the driver uses the current value of
# lpfc_fdmi_on.
# Value range [0,1]. Default value is 0.
*/
LPFC_ATTR_R(fdmi_on, 0, 0, 2, "Enable FDMI support");
LPFC_ATTR_R(fdmi_on, 0, 0, 1, "Enable FDMI support");
/*
# Specifies the maximum number of ELS cmds we can have outstanding (for
@ -5150,7 +5149,6 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport)
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
}
/*
* Dynamic FC Host Attributes Support
*/
@ -5857,14 +5855,6 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
else
phba->cfg_poll = lpfc_poll;
/* Ensure fdmi_on and enable_SmartSAN don't conflict */
if (phba->cfg_enable_SmartSAN) {
phba->cfg_fdmi_on = LPFC_FDMI_SMART_SAN;
} else {
if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
phba->cfg_fdmi_on = LPFC_FDMI_SUPPORT;
}
phba->cfg_soft_wwnn = 0L;
phba->cfg_soft_wwpn = 0L;
lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@ -2322,7 +2322,7 @@ lpfc_fdmi_smart_attr_version(struct lpfc_vport *vport,
ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
memset(ae, 0, 256);
strncpy(ae->un.AttrString, "Smart SAN Version 1.0",
strncpy(ae->un.AttrString, "Smart SAN Version 2.0",
sizeof(ae->un.AttrString));
len = strnlen(ae->un.AttrString,
sizeof(ae->un.AttrString));
@ -2397,7 +2397,7 @@ lpfc_fdmi_smart_attr_security(struct lpfc_vport *vport,
uint32_t size;
ae = (struct lpfc_fdmi_attr_entry *)&ad->AttrValue;
ae->un.AttrInt = cpu_to_be32(0);
ae->un.AttrInt = cpu_to_be32(1);
size = FOURBYTES + sizeof(uint32_t);
ad->AttrLen = cpu_to_be16(size);
ad->AttrType = cpu_to_be16(RPRT_SMART_SECURITY);

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -690,16 +690,17 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
if (fabric_param_changed) {
/* Reset FDMI attribute masks based on config parameter */
if (phba->cfg_fdmi_on == LPFC_FDMI_NO_SUPPORT) {
vport->fdmi_hba_mask = 0;
vport->fdmi_port_mask = 0;
} else {
if (phba->cfg_enable_SmartSAN ||
(phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {
/* Setup appropriate attribute masks */
vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
if (phba->cfg_enable_SmartSAN)
vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
else
vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
} else {
vport->fdmi_hba_mask = 0;
vport->fdmi_port_mask = 0;
}
}
@ -1069,7 +1070,10 @@ stop_rr_fcf_flogi:
lpfc_sli4_unreg_all_rpis(vport);
}
}
lpfc_issue_reg_vfi(vport);
/* Do not register VFI if the driver aborted FLOGI */
if (!lpfc_error_lost_link(irsp))
lpfc_issue_reg_vfi(vport);
lpfc_nlp_put(ndlp);
goto out;
}
@ -4705,6 +4709,144 @@ lpfc_rdp_res_link_error(struct fc_rdp_link_error_status_desc *desc,
desc->length = cpu_to_be32(sizeof(desc->info));
}
void
lpfc_rdp_res_bbc_desc(struct fc_rdp_bbc_desc *desc, READ_LNK_VAR *stat,
struct lpfc_vport *vport)
{
desc->tag = cpu_to_be32(RDP_BBC_DESC_TAG);
desc->bbc_info.port_bbc = cpu_to_be32(
vport->fc_sparam.cmn.bbCreditMsb |
vport->fc_sparam.cmn.bbCreditlsb << 8);
if (vport->phba->fc_topology != LPFC_TOPOLOGY_LOOP)
desc->bbc_info.attached_port_bbc = cpu_to_be32(
vport->phba->fc_fabparam.cmn.bbCreditMsb |
vport->phba->fc_fabparam.cmn.bbCreditlsb << 8);
else
desc->bbc_info.attached_port_bbc = 0;
desc->bbc_info.rtt = 0;
desc->length = cpu_to_be32(sizeof(desc->bbc_info));
}
void
lpfc_rdp_res_oed_temp_desc(struct fc_rdp_oed_sfp_desc *desc, uint8_t *page_a2)
{
uint32_t flags;
desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
desc->oed_info.hi_alarm =
cpu_to_be16(page_a2[SSF_TEMP_HIGH_ALARM]);
desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_TEMP_LOW_ALARM]);
desc->oed_info.hi_warning =
cpu_to_be16(page_a2[SSF_TEMP_HIGH_WARNING]);
desc->oed_info.lo_warning =
cpu_to_be16(page_a2[SSF_TEMP_LOW_WARNING]);
flags = 0xf; /* All four are valid */
flags |= ((0xf & RDP_OED_TEMPERATURE) << RDP_OED_TYPE_SHIFT);
desc->oed_info.function_flags = cpu_to_be32(flags);
desc->length = cpu_to_be32(sizeof(desc->oed_info));
}
void
lpfc_rdp_res_oed_voltage_desc(struct fc_rdp_oed_sfp_desc *desc,
uint8_t *page_a2)
{
uint32_t flags;
desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
desc->oed_info.hi_alarm =
cpu_to_be16(page_a2[SSF_VOLTAGE_HIGH_ALARM]);
desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_VOLTAGE_LOW_ALARM]);
desc->oed_info.hi_warning =
cpu_to_be16(page_a2[SSF_VOLTAGE_HIGH_WARNING]);
desc->oed_info.lo_warning =
cpu_to_be16(page_a2[SSF_VOLTAGE_LOW_WARNING]);
flags = 0xf; /* All four are valid */
flags |= ((0xf & RDP_OED_VOLTAGE) << RDP_OED_TYPE_SHIFT);
desc->oed_info.function_flags = cpu_to_be32(flags);
desc->length = cpu_to_be32(sizeof(desc->oed_info));
}
void
lpfc_rdp_res_oed_txbias_desc(struct fc_rdp_oed_sfp_desc *desc,
uint8_t *page_a2)
{
uint32_t flags;
desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
desc->oed_info.hi_alarm =
cpu_to_be16(page_a2[SSF_BIAS_HIGH_ALARM]);
desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_BIAS_LOW_ALARM]);
desc->oed_info.hi_warning =
cpu_to_be16(page_a2[SSF_BIAS_HIGH_WARNING]);
desc->oed_info.lo_warning =
cpu_to_be16(page_a2[SSF_BIAS_LOW_WARNING]);
flags = 0xf; /* All four are valid */
flags |= ((0xf & RDP_OED_TXBIAS) << RDP_OED_TYPE_SHIFT);
desc->oed_info.function_flags = cpu_to_be32(flags);
desc->length = cpu_to_be32(sizeof(desc->oed_info));
}
void
lpfc_rdp_res_oed_txpower_desc(struct fc_rdp_oed_sfp_desc *desc,
uint8_t *page_a2)
{
uint32_t flags;
desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
desc->oed_info.hi_alarm =
cpu_to_be16(page_a2[SSF_TXPOWER_HIGH_ALARM]);
desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_TXPOWER_LOW_ALARM]);
desc->oed_info.hi_warning =
cpu_to_be16(page_a2[SSF_TXPOWER_HIGH_WARNING]);
desc->oed_info.lo_warning =
cpu_to_be16(page_a2[SSF_TXPOWER_LOW_WARNING]);
flags = 0xf; /* All four are valid */
flags |= ((0xf & RDP_OED_TXPOWER) << RDP_OED_TYPE_SHIFT);
desc->oed_info.function_flags = cpu_to_be32(flags);
desc->length = cpu_to_be32(sizeof(desc->oed_info));
}
void
lpfc_rdp_res_oed_rxpower_desc(struct fc_rdp_oed_sfp_desc *desc,
uint8_t *page_a2)
{
uint32_t flags;
desc->tag = cpu_to_be32(RDP_OED_DESC_TAG);
desc->oed_info.hi_alarm =
cpu_to_be16(page_a2[SSF_RXPOWER_HIGH_ALARM]);
desc->oed_info.lo_alarm = cpu_to_be16(page_a2[SSF_RXPOWER_LOW_ALARM]);
desc->oed_info.hi_warning =
cpu_to_be16(page_a2[SSF_RXPOWER_HIGH_WARNING]);
desc->oed_info.lo_warning =
cpu_to_be16(page_a2[SSF_RXPOWER_LOW_WARNING]);
flags = 0xf; /* All four are valid */
flags |= ((0xf & RDP_OED_RXPOWER) << RDP_OED_TYPE_SHIFT);
desc->oed_info.function_flags = cpu_to_be32(flags);
desc->length = cpu_to_be32(sizeof(desc->oed_info));
}
void
lpfc_rdp_res_opd_desc(struct fc_rdp_opd_sfp_desc *desc,
uint8_t *page_a0, struct lpfc_vport *vport)
{
desc->tag = cpu_to_be32(RDP_OPD_DESC_TAG);
memcpy(desc->opd_info.vendor_name, &page_a0[SSF_VENDOR_NAME], 16);
memcpy(desc->opd_info.model_number, &page_a0[SSF_VENDOR_PN], 16);
memcpy(desc->opd_info.serial_number, &page_a0[SSF_VENDOR_SN], 16);
memcpy(desc->opd_info.revision, &page_a0[SSF_VENDOR_REV], 2);
memcpy(desc->opd_info.date, &page_a0[SSF_DATE_CODE], 8);
desc->length = cpu_to_be32(sizeof(desc->opd_info));
}
int
lpfc_rdp_res_fec_desc(struct fc_fec_rdp_desc *desc, READ_LNK_VAR *stat)
{
@ -4776,6 +4918,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba)
if (rdp_cap == 0)
rdp_cap = RDP_CAP_UNKNOWN;
if (phba->cfg_link_speed != LPFC_USER_LINK_SPEED_AUTO)
rdp_cap |= RDP_CAP_USER_CONFIGURED;
desc->info.port_speed.capabilities = cpu_to_be16(rdp_cap);
desc->length = cpu_to_be32(sizeof(desc->info));
@ -4875,6 +5019,19 @@ lpfc_els_rdp_cmpl(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context,
lpfc_rdp_res_diag_port_names(&rdp_res->diag_port_names_desc, phba);
lpfc_rdp_res_attach_port_names(&rdp_res->attached_port_names_desc,
vport, ndlp);
lpfc_rdp_res_bbc_desc(&rdp_res->bbc_desc, &rdp_context->link_stat,
vport);
lpfc_rdp_res_oed_temp_desc(&rdp_res->oed_temp_desc,
rdp_context->page_a2);
lpfc_rdp_res_oed_voltage_desc(&rdp_res->oed_voltage_desc,
rdp_context->page_a2);
lpfc_rdp_res_oed_txbias_desc(&rdp_res->oed_txbias_desc,
rdp_context->page_a2);
lpfc_rdp_res_oed_txpower_desc(&rdp_res->oed_txpower_desc,
rdp_context->page_a2);
lpfc_rdp_res_oed_rxpower_desc(&rdp_res->oed_rxpower_desc,
rdp_context->page_a2);
lpfc_rdp_res_opd_desc(&rdp_res->opd_desc, rdp_context->page_a0, vport);
fec_size = lpfc_rdp_res_fec_desc(&rdp_res->fec_desc,
&rdp_context->link_stat);
rdp_res->length = cpu_to_be32(fec_size + RDP_DESC_PAYLOAD_SIZE);
@ -7849,8 +8006,9 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
return;
}
if ((phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) &&
(vport->load_flag & FC_ALLOW_FDMI))
if ((phba->cfg_enable_SmartSAN ||
(phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) &&
(vport->load_flag & FC_ALLOW_FDMI))
lpfc_start_fdmi(vport);
}

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -4545,7 +4545,8 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
(!(vport->load_flag & FC_UNLOADING)) &&
(bf_get(lpfc_sli_intf_if_type,
&phba->sli4_hba.sli_intf) ==
LPFC_SLI_INTF_IF_TYPE_2)) {
LPFC_SLI_INTF_IF_TYPE_2) &&
(atomic_read(&ndlp->kref.refcount) > 0)) {
mbox->context1 = lpfc_nlp_get(ndlp);
mbox->mbox_cmpl =
lpfc_sli4_unreg_rpi_cmpl_clr;

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@ -1134,9 +1134,10 @@ struct fc_rdp_link_error_status_desc {
#define RDP_PS_16GB 0x0400
#define RDP_PS_32GB 0x0200
#define RDP_CAP_UNKNOWN 0x0001
#define RDP_PS_UNKNOWN 0x0002
#define RDP_PS_NOT_ESTABLISHED 0x0001
#define RDP_CAP_USER_CONFIGURED 0x0002
#define RDP_CAP_UNKNOWN 0x0001
#define RDP_PS_UNKNOWN 0x0002
#define RDP_PS_NOT_ESTABLISHED 0x0001
struct fc_rdp_port_speed {
uint16_t capabilities;
@ -1192,6 +1193,58 @@ struct fc_rdp_sfp_desc {
struct fc_rdp_sfp_info sfp_info;
};
/* Buffer Credit Descriptor */
struct fc_rdp_bbc_info {
uint32_t port_bbc; /* FC_Port buffer-to-buffer credit */
uint32_t attached_port_bbc;
uint32_t rtt; /* Round trip time */
};
#define RDP_BBC_DESC_TAG 0x00010006
struct fc_rdp_bbc_desc {
uint32_t tag;
uint32_t length;
struct fc_rdp_bbc_info bbc_info;
};
#define RDP_OED_TEMPERATURE 0x1
#define RDP_OED_VOLTAGE 0x2
#define RDP_OED_TXBIAS 0x3
#define RDP_OED_TXPOWER 0x4
#define RDP_OED_RXPOWER 0x5
#define RDP_OED_TYPE_SHIFT 28
/* Optical Element Data descriptor */
struct fc_rdp_oed_info {
uint16_t hi_alarm;
uint16_t lo_alarm;
uint16_t hi_warning;
uint16_t lo_warning;
uint32_t function_flags;
};
#define RDP_OED_DESC_TAG 0x00010007
struct fc_rdp_oed_sfp_desc {
uint32_t tag;
uint32_t length;
struct fc_rdp_oed_info oed_info;
};
/* Optical Product Data descriptor */
struct fc_rdp_opd_sfp_info {
uint8_t vendor_name[16];
uint8_t model_number[16];
uint8_t serial_number[16];
uint8_t reserved[2];
uint8_t revision[2];
uint8_t date[8];
};
#define RDP_OPD_DESC_TAG 0x00010008
struct fc_rdp_opd_sfp_desc {
uint32_t tag;
uint32_t length;
struct fc_rdp_opd_sfp_info opd_info;
};
struct fc_rdp_req_frame {
uint32_t rdp_command; /* ELS command opcode (0x18)*/
uint32_t rdp_des_length; /* RDP Payload Word 1 */
@ -1208,7 +1261,14 @@ struct fc_rdp_res_frame {
struct fc_rdp_link_error_status_desc link_error_desc; /* Word 13-21 */
struct fc_rdp_port_name_desc diag_port_names_desc; /* Word 22-27 */
struct fc_rdp_port_name_desc attached_port_names_desc;/* Word 28-33 */
struct fc_fec_rdp_desc fec_desc; /* FC Word 34 - 37 */
struct fc_rdp_bbc_desc bbc_desc; /* FC Word 34-38*/
struct fc_rdp_oed_sfp_desc oed_temp_desc; /* FC Word 39-43*/
struct fc_rdp_oed_sfp_desc oed_voltage_desc; /* FC word 44-48*/
struct fc_rdp_oed_sfp_desc oed_txbias_desc; /* FC word 49-53*/
struct fc_rdp_oed_sfp_desc oed_txpower_desc; /* FC word 54-58*/
struct fc_rdp_oed_sfp_desc oed_rxpower_desc; /* FC word 59-63*/
struct fc_rdp_opd_sfp_desc opd_desc; /* FC word 64-80*/
struct fc_fec_rdp_desc fec_desc; /* FC word 81-84*/
};
@ -1216,7 +1276,10 @@ struct fc_rdp_res_frame {
+ sizeof(struct fc_rdp_sfp_desc) \
+ sizeof(struct fc_rdp_port_speed_desc) \
+ sizeof(struct fc_rdp_link_error_status_desc) \
+ (sizeof(struct fc_rdp_port_name_desc) * 2))
+ (sizeof(struct fc_rdp_port_name_desc) * 2) \
+ sizeof(struct fc_rdp_bbc_desc) \
+ (sizeof(struct fc_rdp_oed_sfp_desc) * 5) \
+ sizeof(struct fc_rdp_opd_sfp_desc))
/******** FDMI ********/

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2009-2015 Emulex. All rights reserved. *
* Copyright (C) 2009-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@ -2557,7 +2557,26 @@ struct lpfc_mbx_memory_dump_type3 {
/* SFF-8472 Table 3.1a Diagnostics: Data Fields Address/Page A2 */
#define SSF_AW_THRESHOLDS 0
#define SSF_TEMP_HIGH_ALARM 0
#define SSF_TEMP_LOW_ALARM 2
#define SSF_TEMP_HIGH_WARNING 4
#define SSF_TEMP_LOW_WARNING 6
#define SSF_VOLTAGE_HIGH_ALARM 8
#define SSF_VOLTAGE_LOW_ALARM 10
#define SSF_VOLTAGE_HIGH_WARNING 12
#define SSF_VOLTAGE_LOW_WARNING 14
#define SSF_BIAS_HIGH_ALARM 16
#define SSF_BIAS_LOW_ALARM 18
#define SSF_BIAS_HIGH_WARNING 20
#define SSF_BIAS_LOW_WARNING 22
#define SSF_TXPOWER_HIGH_ALARM 24
#define SSF_TXPOWER_LOW_ALARM 26
#define SSF_TXPOWER_HIGH_WARNING 28
#define SSF_TXPOWER_LOW_WARNING 30
#define SSF_RXPOWER_HIGH_ALARM 32
#define SSF_RXPOWER_LOW_ALARM 34
#define SSF_RXPOWER_HIGH_WARNING 36
#define SSF_RXPOWER_LOW_WARNING 38
#define SSF_EXT_CAL_CONSTANTS 56
#define SSF_CC_DMI 95
#define SFF_TEMPERATURE_B1 96
@ -2865,6 +2884,9 @@ struct lpfc_sli4_parameters {
uint32_t word17;
uint32_t word18;
uint32_t word19;
#define cfg_ext_embed_cb_SHIFT 0
#define cfg_ext_embed_cb_MASK 0x00000001
#define cfg_ext_embed_cb_WORD word19
};
struct lpfc_mbx_get_sli4_parameters {
@ -3919,6 +3941,9 @@ union lpfc_wqe {
union lpfc_wqe128 {
uint32_t words[32];
struct lpfc_wqe_generic generic;
struct fcp_icmnd64_wqe fcp_icmd;
struct fcp_iread64_wqe fcp_iread;
struct fcp_iwrite64_wqe fcp_iwrite;
struct xmit_seq64_wqe xmit_sequence;
struct gen_req64_wqe gen_req;
};

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -6158,11 +6158,12 @@ lpfc_create_shost(struct lpfc_hba *phba)
* any initial discovery should be completed.
*/
vport->load_flag |= FC_ALLOW_FDMI;
if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) {
if (phba->cfg_enable_SmartSAN ||
(phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {
/* Setup appropriate attribute masks */
vport->fdmi_hba_mask = LPFC_FDMI2_HBA_ATTR;
if (phba->cfg_fdmi_on == LPFC_FDMI_SMART_SAN)
if (phba->cfg_enable_SmartSAN)
vport->fdmi_port_mask = LPFC_FDMI2_SMART_ATTR;
else
vport->fdmi_port_mask = LPFC_FDMI2_PORT_ATTR;
@ -7264,8 +7265,15 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba)
phba->sli4_hba.fcp_cq[idx] = qdesc;
/* Create Fast Path FCP WQs */
qdesc = lpfc_sli4_queue_alloc(phba, phba->sli4_hba.wq_esize,
phba->sli4_hba.wq_ecount);
if (phba->fcp_embed_io) {
qdesc = lpfc_sli4_queue_alloc(phba,
LPFC_WQE128_SIZE,
LPFC_WQE128_DEF_COUNT);
} else {
qdesc = lpfc_sli4_queue_alloc(phba,
phba->sli4_hba.wq_esize,
phba->sli4_hba.wq_ecount);
}
if (!qdesc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0503 Failed allocate fast-path FCP "
@ -9510,6 +9518,15 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
/*
* Issue IOs with CDB embedded in WQE to minimized the number
* of DMAs the firmware has to do. Setting this to 1 also forces
* the driver to use 128 bytes WQEs for FCP IOs.
*/
if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters))
phba->fcp_embed_io = 1;
else
phba->fcp_embed_io = 0;
return 0;
}

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -2145,10 +2145,12 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
reg_vfi->e_d_tov = phba->fc_edtov;
reg_vfi->r_a_tov = phba->fc_ratov;
reg_vfi->bde.addrHigh = putPaddrHigh(phys);
reg_vfi->bde.addrLow = putPaddrLow(phys);
reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
if (phys) {
reg_vfi->bde.addrHigh = putPaddrHigh(phys);
reg_vfi->bde.addrLow = putPaddrLow(phys);
reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
}
bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);
/* Only FC supports upd bit */

View file

@ -231,13 +231,15 @@ lpfc_mem_free(struct lpfc_hba *phba)
if (phba->lpfc_hbq_pool)
pci_pool_destroy(phba->lpfc_hbq_pool);
phba->lpfc_hbq_pool = NULL;
mempool_destroy(phba->rrq_pool);
if (phba->rrq_pool)
mempool_destroy(phba->rrq_pool);
phba->rrq_pool = NULL;
/* Free NLP memory pool */
mempool_destroy(phba->nlp_mem_pool);
phba->nlp_mem_pool = NULL;
if (phba->sli_rev == LPFC_SLI_REV4) {
if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) {
mempool_destroy(phba->active_rrq_pool);
phba->active_rrq_pool = NULL;
}

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -1512,6 +1512,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
if ((mb = phba->sli.mbox_active)) {
if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
(ndlp == (struct lpfc_nodelist *) mb->context2)) {
ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
lpfc_nlp_put(ndlp);
mb->context2 = NULL;
mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
@ -1527,6 +1528,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
__lpfc_mbuf_free(phba, mp->virt, mp->phys);
kfree(mp);
}
ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
lpfc_nlp_put(ndlp);
list_del(&mb->list);
phba->sli.mboxq_cnt--;

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -2000,10 +2000,9 @@ lpfc_sli_hbqbuf_get(struct list_head *rb_list)
* @phba: Pointer to HBA context object.
* @tag: Tag of the hbq buffer.
*
* This function is called with hbalock held. This function searches
* for the hbq buffer associated with the given tag in the hbq buffer
* list. If it finds the hbq buffer, it returns the hbq_buffer other wise
* it returns NULL.
* This function searches for the hbq buffer associated with the given tag in
* the hbq buffer list. If it finds the hbq buffer, it returns the hbq_buffer
* otherwise it returns NULL.
**/
static struct hbq_dmabuf *
lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag)
@ -2012,8 +2011,6 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag)
struct hbq_dmabuf *hbq_buf;
uint32_t hbqno;
lockdep_assert_held(&phba->hbalock);
hbqno = tag >> 16;
if (hbqno >= LPFC_MAX_HBQS)
return NULL;
@ -2211,6 +2208,7 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
rpi = pmb->u.mb.un.varWords[0];
vpi = pmb->u.mb.un.varRegLogin.vpi;
lpfc_unreg_login(phba, vpi, rpi, pmb);
pmb->vport = vport;
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
if (rc != MBX_NOT_FINISHED)
@ -4688,6 +4686,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
break;
}
phba->fcp_embed_io = 0; /* SLI4 FC support only */
rc = lpfc_sli_config_port(phba, mode);
@ -6320,10 +6319,12 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
mqe = &mboxq->u.mqe;
phba->sli_rev = bf_get(lpfc_mbx_rd_rev_sli_lvl, &mqe->un.read_rev);
if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev))
if (bf_get(lpfc_mbx_rd_rev_fcoe, &mqe->un.read_rev)) {
phba->hba_flag |= HBA_FCOE_MODE;
else
phba->fcp_embed_io = 0; /* SLI4 FC support only */
} else {
phba->hba_flag &= ~HBA_FCOE_MODE;
}
if (bf_get(lpfc_mbx_rd_rev_cee_ver, &mqe->un.read_rev) ==
LPFC_DCBX_CEE_MODE)
@ -8218,12 +8219,15 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
else
command_type = ELS_COMMAND_NON_FIP;
if (phba->fcp_embed_io)
memset(wqe, 0, sizeof(union lpfc_wqe128));
/* Some of the fields are in the right position already */
memcpy(wqe, &iocbq->iocb, sizeof(union lpfc_wqe));
abort_tag = (uint32_t) iocbq->iotag;
xritag = iocbq->sli4_xritag;
wqe->generic.wqe_com.word7 = 0; /* The ct field has moved so reset */
wqe->generic.wqe_com.word10 = 0;
abort_tag = (uint32_t) iocbq->iotag;
xritag = iocbq->sli4_xritag;
/* words0-2 bpl convert bde */
if (iocbq->iocb.un.genreq64.bdl.bdeFlags == BUFF_TYPE_BLP_64) {
numBdes = iocbq->iocb.un.genreq64.bdl.bdeSize /
@ -8372,11 +8376,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
iocbq->iocb.ulpFCP2Rcvy);
bf_set(wqe_lnk, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpXS);
/* Always open the exchange */
bf_set(wqe_xc, &wqe->fcp_iwrite.wqe_com, 0);
bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE);
bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com,
LPFC_WQE_LENLOC_WORD4);
bf_set(wqe_ebde_cnt, &wqe->fcp_iwrite.wqe_com, 0);
bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, iocbq->iocb.ulpPU);
bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 1);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
@ -8387,6 +8389,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
(phba->cfg_XLanePriority << 1));
}
}
/* Note, word 10 is already initialized to 0 */
if (phba->fcp_embed_io) {
struct lpfc_scsi_buf *lpfc_cmd;
struct sli4_sge *sgl;
union lpfc_wqe128 *wqe128;
struct fcp_cmnd *fcp_cmnd;
uint32_t *ptr;
/* 128 byte wqe support here */
wqe128 = (union lpfc_wqe128 *)wqe;
lpfc_cmd = iocbq->context1;
sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
fcp_cmnd = lpfc_cmd->fcp_cmnd;
/* Word 0-2 - FCP_CMND */
wqe128->generic.bde.tus.f.bdeFlags =
BUFF_TYPE_BDE_IMMED;
wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
wqe128->generic.bde.addrHigh = 0;
wqe128->generic.bde.addrLow = 88; /* Word 22 */
bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1);
/* Word 22-29 FCP CMND Payload */
ptr = &wqe128->words[22];
memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
}
break;
case CMD_FCP_IREAD64_CR:
/* word3 iocb=iotag wqe=payload_offset_len */
@ -8401,11 +8432,9 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
iocbq->iocb.ulpFCP2Rcvy);
bf_set(wqe_lnk, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpXS);
/* Always open the exchange */
bf_set(wqe_xc, &wqe->fcp_iread.wqe_com, 0);
bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ);
bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com,
LPFC_WQE_LENLOC_WORD4);
bf_set(wqe_ebde_cnt, &wqe->fcp_iread.wqe_com, 0);
bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, iocbq->iocb.ulpPU);
bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 1);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
@ -8416,6 +8445,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
(phba->cfg_XLanePriority << 1));
}
}
/* Note, word 10 is already initialized to 0 */
if (phba->fcp_embed_io) {
struct lpfc_scsi_buf *lpfc_cmd;
struct sli4_sge *sgl;
union lpfc_wqe128 *wqe128;
struct fcp_cmnd *fcp_cmnd;
uint32_t *ptr;
/* 128 byte wqe support here */
wqe128 = (union lpfc_wqe128 *)wqe;
lpfc_cmd = iocbq->context1;
sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
fcp_cmnd = lpfc_cmd->fcp_cmnd;
/* Word 0-2 - FCP_CMND */
wqe128->generic.bde.tus.f.bdeFlags =
BUFF_TYPE_BDE_IMMED;
wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
wqe128->generic.bde.addrHigh = 0;
wqe128->generic.bde.addrLow = 88; /* Word 22 */
bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1);
/* Word 22-29 FCP CMND Payload */
ptr = &wqe128->words[22];
memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
}
break;
case CMD_FCP_ICMND64_CR:
/* word3 iocb=iotag wqe=payload_offset_len */
@ -8427,13 +8485,11 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
/* word3 iocb=IO_TAG wqe=reserved */
bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0);
/* Always open the exchange */
bf_set(wqe_xc, &wqe->fcp_icmd.wqe_com, 0);
bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 1);
bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE);
bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1);
bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com,
LPFC_WQE_LENLOC_NONE);
bf_set(wqe_ebde_cnt, &wqe->fcp_icmd.wqe_com, 0);
bf_set(wqe_erp, &wqe->fcp_icmd.wqe_com,
iocbq->iocb.ulpFCP2Rcvy);
if (iocbq->iocb_flag & LPFC_IO_OAS) {
@ -8444,6 +8500,35 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq,
(phba->cfg_XLanePriority << 1));
}
}
/* Note, word 10 is already initialized to 0 */
if (phba->fcp_embed_io) {
struct lpfc_scsi_buf *lpfc_cmd;
struct sli4_sge *sgl;
union lpfc_wqe128 *wqe128;
struct fcp_cmnd *fcp_cmnd;
uint32_t *ptr;
/* 128 byte wqe support here */
wqe128 = (union lpfc_wqe128 *)wqe;
lpfc_cmd = iocbq->context1;
sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl;
fcp_cmnd = lpfc_cmd->fcp_cmnd;
/* Word 0-2 - FCP_CMND */
wqe128->generic.bde.tus.f.bdeFlags =
BUFF_TYPE_BDE_IMMED;
wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len;
wqe128->generic.bde.addrHigh = 0;
wqe128->generic.bde.addrLow = 88; /* Word 22 */
bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1);
/* Word 22-29 FCP CMND Payload */
ptr = &wqe128->words[22];
memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd));
}
break;
case CMD_GEN_REQUEST64_CR:
/* For this command calculate the xmit length of the
@ -8675,12 +8760,19 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
struct lpfc_iocbq *piocb, uint32_t flag)
{
struct lpfc_sglq *sglq;
union lpfc_wqe wqe;
union lpfc_wqe *wqe;
union lpfc_wqe128 wqe128;
struct lpfc_queue *wq;
struct lpfc_sli_ring *pring = &phba->sli.ring[ring_number];
lockdep_assert_held(&phba->hbalock);
/*
* The WQE can be either 64 or 128 bytes,
* so allocate space on the stack assuming the largest.
*/
wqe = (union lpfc_wqe *)&wqe128;
if (piocb->sli4_xritag == NO_XRI) {
if (piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
@ -8727,7 +8819,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
return IOCB_ERROR;
}
if (lpfc_sli4_iocb2wqe(phba, piocb, &wqe))
if (lpfc_sli4_iocb2wqe(phba, piocb, wqe))
return IOCB_ERROR;
if ((piocb->iocb_flag & LPFC_IO_FCP) ||
@ -8737,12 +8829,12 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
} else {
wq = phba->sli4_hba.oas_wq;
}
if (lpfc_sli4_wq_put(wq, &wqe))
if (lpfc_sli4_wq_put(wq, wqe))
return IOCB_ERROR;
} else {
if (unlikely(!phba->sli4_hba.els_wq))
return IOCB_ERROR;
if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe))
if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, wqe))
return IOCB_ERROR;
}
lpfc_sli_ringtxcmpl_put(phba, pring, piocb);
@ -8757,9 +8849,9 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number,
* pointer from the lpfc_hba struct.
*
* Return codes:
* IOCB_ERROR - Error
* IOCB_SUCCESS - Success
* IOCB_BUSY - Busy
* IOCB_ERROR - Error
* IOCB_SUCCESS - Success
* IOCB_BUSY - Busy
**/
int
__lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number,

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2015 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
#define LPFC_DRIVER_VERSION "11.0.0.10."
#define LPFC_DRIVER_VERSION "11.1.0.0."
#define LPFC_DRIVER_NAME "lpfc"
/* Used for SLI 2/3 */
@ -30,4 +30,4 @@
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
LPFC_DRIVER_VERSION
#define LPFC_COPYRIGHT "Copyright(c) 2004-2015 Emulex. All rights reserved."
#define LPFC_COPYRIGHT "Copyright(c) 2004-2016 Emulex. All rights reserved."

View file

@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
* Copyright (C) 2004-2013 Emulex. All rights reserved. *
* Copyright (C) 2004-2016 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@ -395,7 +395,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
/* At this point we are fully registered with SCSI Layer. */
vport->load_flag |= FC_ALLOW_FDMI;
if (phba->cfg_fdmi_on > LPFC_FDMI_NO_SUPPORT) {
if (phba->cfg_enable_SmartSAN ||
(phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {
/* Setup appropriate attribute masks */
vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask;
vport->fdmi_port_mask = phba->pport->fdmi_port_mask;

View file

@ -28,24 +28,23 @@
/* Definitions for the core NCR5380 driver. */
#define PSEUDO_DMA
#define NCR5380_implementation_fields unsigned char *pdma_base
#define NCR5380_implementation_fields unsigned char *pdma_base; \
int pdma_residual
#define NCR5380_read(reg) macscsi_read(instance, reg)
#define NCR5380_write(reg, value) macscsi_write(instance, reg, value)
#define NCR5380_pread macscsi_pread
#define NCR5380_pwrite macscsi_pwrite
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_dma_xfer_len(instance, cmd, phase) \
macscsi_dma_xfer_len(instance, cmd)
#define NCR5380_dma_recv_setup macscsi_pread
#define NCR5380_dma_send_setup macscsi_pwrite
#define NCR5380_dma_residual(instance) (hostdata->pdma_residual)
#define NCR5380_intr macscsi_intr
#define NCR5380_queue_command macscsi_queue_command
#define NCR5380_abort macscsi_abort
#define NCR5380_bus_reset macscsi_bus_reset
#define NCR5380_info macscsi_info
#define NCR5380_show_info macscsi_show_info
#define NCR5380_write_info macscsi_write_info
#include "NCR5380.h"
@ -57,8 +56,6 @@ static int setup_sg_tablesize = -1;
module_param(setup_sg_tablesize, int, 0);
static int setup_use_pdma = -1;
module_param(setup_use_pdma, int, 0);
static int setup_use_tagged_queuing = -1;
module_param(setup_use_tagged_queuing, int, 0);
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
static int setup_toshiba_delay = -1;
@ -97,8 +94,7 @@ static int __init mac_scsi_setup(char *str)
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
/* ints[5] (use_tagged_queuing) is ignored */
if (ints[0] >= 6)
setup_use_pdma = ints[6];
if (ints[0] >= 7)
@ -109,19 +105,9 @@ static int __init mac_scsi_setup(char *str)
__setup("mac5380=", mac_scsi_setup);
#endif /* !MODULE */
#ifdef PSEUDO_DMA
/*
Pseudo-DMA: (Ove Edlund)
The code attempts to catch bus errors that occur if one for example
"trips over the cable".
XXX: Since bus errors in the PDMA routines never happen on my
computer, the bus error code is untested.
If the code works as intended, a bus error results in Pseudo-DMA
being disabled, meaning that the driver switches to slow handshake.
If bus errors are NOT extremely rare, this has to be changed.
*/
/* Pseudo DMA asm originally by Ove Edlund */
#define CP_IO_TO_MEM(s,d,len) \
#define CP_IO_TO_MEM(s,d,n) \
__asm__ __volatile__ \
(" cmp.w #4,%2\n" \
" bls 8f\n" \
@ -158,61 +144,73 @@ __asm__ __volatile__ \
" 9: \n" \
".section .fixup,\"ax\"\n" \
" .even\n" \
"90: moveq.l #1, %2\n" \
"91: moveq.l #1, %2\n" \
" jra 9b\n" \
"94: moveq.l #4, %2\n" \
" jra 9b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 4\n" \
" .long 1b,90b\n" \
" .long 3b,90b\n" \
" .long 31b,90b\n" \
" .long 32b,90b\n" \
" .long 33b,90b\n" \
" .long 34b,90b\n" \
" .long 35b,90b\n" \
" .long 36b,90b\n" \
" .long 37b,90b\n" \
" .long 5b,90b\n" \
" .long 7b,90b\n" \
" .long 1b,91b\n" \
" .long 3b,94b\n" \
" .long 31b,94b\n" \
" .long 32b,94b\n" \
" .long 33b,94b\n" \
" .long 34b,94b\n" \
" .long 35b,94b\n" \
" .long 36b,94b\n" \
" .long 37b,94b\n" \
" .long 5b,94b\n" \
" .long 7b,91b\n" \
".previous" \
: "=a"(s), "=a"(d), "=d"(len) \
: "0"(s), "1"(d), "2"(len) \
: "=a"(s), "=a"(d), "=d"(n) \
: "0"(s), "1"(d), "2"(n) \
: "d0")
static int macscsi_pread(struct Scsi_Host *instance,
unsigned char *dst, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char *d;
unsigned char *s;
unsigned char *s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
unsigned char *d = dst;
int n = len;
int transferred;
s = hostdata->pdma_base + (INPUT_DATA_REG << 4);
d = dst;
while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
BASR_DRQ | BASR_PHASE_MATCH,
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
CP_IO_TO_MEM(s, d, n);
/* These conditions are derived from MacOS */
transferred = d - dst - n;
hostdata->pdma_residual = len - transferred;
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
!(NCR5380_read(STATUS_REG) & SR_REQ))
;
/* No bus error. */
if (n == 0)
return 0;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) {
pr_err("Error in macscsi_pread\n");
return -1;
/* Target changed phase early? */
if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected,
"%s: !REQ and !ACK\n", __func__);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
return 0;
dsprintk(NDEBUG_PSEUDO_DMA, instance,
"%s: bus error (%d/%d)\n", __func__, transferred, len);
NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
d = dst + transferred;
n = len - transferred;
}
CP_IO_TO_MEM(s, d, len);
if (len != 0) {
pr_notice("Bus error in macscsi_pread\n");
return -1;
}
return 0;
scmd_printk(KERN_ERR, hostdata->connected,
"%s: phase mismatch or !DRQ\n", __func__);
NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
return -1;
}
#define CP_MEM_TO_IO(s,d,len) \
#define CP_MEM_TO_IO(s,d,n) \
__asm__ __volatile__ \
(" cmp.w #4,%2\n" \
" bls 8f\n" \
@ -249,59 +247,89 @@ __asm__ __volatile__ \
" 9: \n" \
".section .fixup,\"ax\"\n" \
" .even\n" \
"90: moveq.l #1, %2\n" \
"91: moveq.l #1, %2\n" \
" jra 9b\n" \
"94: moveq.l #4, %2\n" \
" jra 9b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 4\n" \
" .long 1b,90b\n" \
" .long 3b,90b\n" \
" .long 31b,90b\n" \
" .long 32b,90b\n" \
" .long 33b,90b\n" \
" .long 34b,90b\n" \
" .long 35b,90b\n" \
" .long 36b,90b\n" \
" .long 37b,90b\n" \
" .long 5b,90b\n" \
" .long 7b,90b\n" \
" .long 1b,91b\n" \
" .long 3b,94b\n" \
" .long 31b,94b\n" \
" .long 32b,94b\n" \
" .long 33b,94b\n" \
" .long 34b,94b\n" \
" .long 35b,94b\n" \
" .long 36b,94b\n" \
" .long 37b,94b\n" \
" .long 5b,94b\n" \
" .long 7b,91b\n" \
".previous" \
: "=a"(s), "=a"(d), "=d"(len) \
: "0"(s), "1"(d), "2"(len) \
: "=a"(s), "=a"(d), "=d"(n) \
: "0"(s), "1"(d), "2"(n) \
: "d0")
static int macscsi_pwrite(struct Scsi_Host *instance,
unsigned char *src, int len)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char *s;
unsigned char *d;
unsigned char *s = src;
unsigned char *d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
int n = len;
int transferred;
s = src;
d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4);
while (!NCR5380_poll_politely(instance, BUS_AND_STATUS_REG,
BASR_DRQ | BASR_PHASE_MATCH,
BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) {
CP_MEM_TO_IO(s, d, n);
/* These conditions are derived from MacOS */
transferred = s - src - n;
hostdata->pdma_residual = len - transferred;
while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) &&
(!(NCR5380_read(STATUS_REG) & SR_REQ) ||
(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)))
;
/* Target changed phase early? */
if (NCR5380_poll_politely2(instance, STATUS_REG, SR_REQ, SR_REQ,
BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected,
"%s: !REQ and !ACK\n", __func__);
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))
return 0;
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) {
pr_err("Error in macscsi_pwrite\n");
return -1;
/* No bus error. */
if (n == 0) {
if (NCR5380_poll_politely(instance, TARGET_COMMAND_REG,
TCR_LAST_BYTE_SENT,
TCR_LAST_BYTE_SENT, HZ / 64) < 0)
scmd_printk(KERN_ERR, hostdata->connected,
"%s: Last Byte Sent timeout\n", __func__);
return 0;
}
dsprintk(NDEBUG_PSEUDO_DMA, instance,
"%s: bus error (%d/%d)\n", __func__, transferred, len);
NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
s = src + transferred;
n = len - transferred;
}
CP_MEM_TO_IO(s, d, len);
scmd_printk(KERN_ERR, hostdata->connected,
"%s: phase mismatch or !DRQ\n", __func__);
NCR5380_dprint(NDEBUG_PSEUDO_DMA, instance);
if (len != 0) {
pr_notice("Bus error in macscsi_pwrite\n");
return -1;
}
return 0;
return -1;
}
static int macscsi_dma_xfer_len(struct Scsi_Host *instance,
struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
if (hostdata->flags & FLAG_NO_PSEUDO_DMA ||
cmd->SCp.this_residual < 16)
return 0;
return cmd->SCp.this_residual;
}
#endif
#include "NCR5380.c"
@ -311,8 +339,6 @@ static int macscsi_pwrite(struct Scsi_Host *instance,
static struct scsi_host_template mac_scsi_template = {
.module = THIS_MODULE,
.proc_name = DRV_MODULE_NAME,
.show_info = macscsi_show_info,
.write_info = macscsi_write_info,
.name = "Macintosh NCR5380 SCSI",
.info = macscsi_info,
.queuecommand = macscsi_queue_command,
@ -320,7 +346,7 @@ static struct scsi_host_template mac_scsi_template = {
.eh_bus_reset_handler = macscsi_bus_reset,
.can_queue = 16,
.this_id = 7,
.sg_tablesize = SG_ALL,
.sg_tablesize = 1,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
@ -338,9 +364,7 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
if (!pio_mem)
return -ENODEV;
#ifdef PSEUDO_DMA
pdma_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
#endif
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@ -358,8 +382,6 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
mac_scsi_template.sg_tablesize = setup_sg_tablesize;
if (setup_hostid >= 0)
mac_scsi_template.this_id = setup_hostid & 7;
if (setup_use_pdma < 0)
setup_use_pdma = 0;
instance = scsi_host_alloc(&mac_scsi_template,
sizeof(struct NCR5380_hostdata));
@ -379,12 +401,9 @@ static int __init mac_scsi_probe(struct platform_device *pdev)
} else
host_flags |= FLAG_NO_PSEUDO_DMA;
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
error = NCR5380_init(instance, host_flags);
error = NCR5380_init(instance, host_flags | FLAG_LATE_DMA_SETUP);
if (error)
goto fail_init;

View file

@ -35,8 +35,8 @@
/*
* MegaRAID SAS Driver meta data
*/
#define MEGASAS_VERSION "06.810.09.00-rc1"
#define MEGASAS_RELDATE "Jan. 28, 2016"
#define MEGASAS_VERSION "06.811.02.00-rc1"
#define MEGASAS_RELDATE "April 12, 2016"
/*
* Device IDs
@ -1344,6 +1344,8 @@ struct megasas_ctrl_info {
#define SCAN_PD_CHANNEL 0x1
#define SCAN_VD_CHANNEL 0x2
#define MEGASAS_KDUMP_QUEUE_DEPTH 100
enum MR_SCSI_CMD_TYPE {
READ_WRITE_LDIO = 0,
NON_READ_WRITE_LDIO = 1,

View file

@ -2669,17 +2669,6 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
return BLK_EH_RESET_TIMER;
}
/**
* megasas_reset_device - Device reset handler entry point
*/
static int megasas_reset_device(struct scsi_cmnd *scmd)
{
/*
* First wait for all commands to complete
*/
return megasas_generic_reset(scmd);
}
/**
* megasas_reset_bus_host - Bus & host reset handler entry point
*/
@ -2701,6 +2690,50 @@ static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
return ret;
}
/**
* megasas_task_abort - Issues task abort request to firmware
* (supported only for fusion adapters)
* @scmd: SCSI command pointer
*/
static int megasas_task_abort(struct scsi_cmnd *scmd)
{
int ret;
struct megasas_instance *instance;
instance = (struct megasas_instance *)scmd->device->host->hostdata;
if (instance->ctrl_context)
ret = megasas_task_abort_fusion(scmd);
else {
sdev_printk(KERN_NOTICE, scmd->device, "TASK ABORT not supported\n");
ret = FAILED;
}
return ret;
}
/**
* megasas_reset_target: Issues target reset request to firmware
* (supported only for fusion adapters)
* @scmd: SCSI command pointer
*/
static int megasas_reset_target(struct scsi_cmnd *scmd)
{
int ret;
struct megasas_instance *instance;
instance = (struct megasas_instance *)scmd->device->host->hostdata;
if (instance->ctrl_context)
ret = megasas_reset_target_fusion(scmd);
else {
sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not supported\n");
ret = FAILED;
}
return ret;
}
/**
* megasas_bios_param - Returns disk geometry for a disk
* @sdev: device handle
@ -2969,8 +3002,8 @@ static struct scsi_host_template megasas_template = {
.slave_alloc = megasas_slave_alloc,
.slave_destroy = megasas_slave_destroy,
.queuecommand = megasas_queue_command,
.eh_device_reset_handler = megasas_reset_device,
.eh_bus_reset_handler = megasas_reset_bus_host,
.eh_target_reset_handler = megasas_reset_target,
.eh_abort_handler = megasas_task_abort,
.eh_host_reset_handler = megasas_reset_bus_host,
.eh_timed_out = megasas_reset_timer,
.shost_attrs = megaraid_host_attrs,
@ -5152,7 +5185,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
instance->instancet->enable_intr(instance);
dev_err(&instance->pdev->dev, "INIT adapter done\n");
dev_info(&instance->pdev->dev, "INIT adapter done\n");
megasas_setup_jbod_map(instance);
@ -5598,14 +5631,6 @@ static int megasas_io_attach(struct megasas_instance *instance)
host->max_lun = MEGASAS_MAX_LUN;
host->max_cmd_len = 16;
/* Fusion only supports host reset */
if (instance->ctrl_context) {
host->hostt->eh_device_reset_handler = NULL;
host->hostt->eh_bus_reset_handler = NULL;
host->hostt->eh_target_reset_handler = megasas_reset_target_fusion;
host->hostt->eh_abort_handler = megasas_task_abort_fusion;
}
/*
* Notify the mid-layer about the new controller
*/
@ -5761,13 +5786,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
break;
}
instance->system_info_buf = pci_zalloc_consistent(pdev,
sizeof(struct MR_DRV_SYSTEM_INFO),
&instance->system_info_h);
if (!instance->system_info_buf)
dev_info(&instance->pdev->dev, "Can't allocate system info buffer\n");
/* Crash dump feature related initialisation*/
instance->drv_buf_index = 0;
instance->drv_buf_alloc = 0;
@ -5777,14 +5795,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
spin_lock_init(&instance->crashdump_lock);
instance->crash_dump_buf = NULL;
if (!reset_devices)
instance->crash_dump_buf = pci_alloc_consistent(pdev,
CRASH_DMA_BUF_SIZE,
&instance->crash_dump_h);
if (!instance->crash_dump_buf)
dev_err(&pdev->dev, "Can't allocate Firmware "
"crash dump DMA buffer\n");
megasas_poll_wait_aen = 0;
instance->flag_ieee = 0;
instance->ev = NULL;
@ -5803,11 +5813,26 @@ static int megasas_probe_one(struct pci_dev *pdev,
goto fail_alloc_dma_buf;
}
instance->pd_info = pci_alloc_consistent(pdev,
sizeof(struct MR_PD_INFO), &instance->pd_info_h);
if (!reset_devices) {
instance->system_info_buf = pci_zalloc_consistent(pdev,
sizeof(struct MR_DRV_SYSTEM_INFO),
&instance->system_info_h);
if (!instance->system_info_buf)
dev_info(&instance->pdev->dev, "Can't allocate system info buffer\n");
if (!instance->pd_info)
dev_err(&instance->pdev->dev, "Failed to alloc mem for pd_info\n");
instance->pd_info = pci_alloc_consistent(pdev,
sizeof(struct MR_PD_INFO), &instance->pd_info_h);
if (!instance->pd_info)
dev_err(&instance->pdev->dev, "Failed to alloc mem for pd_info\n");
instance->crash_dump_buf = pci_alloc_consistent(pdev,
CRASH_DMA_BUF_SIZE,
&instance->crash_dump_h);
if (!instance->crash_dump_buf)
dev_err(&pdev->dev, "Can't allocate Firmware "
"crash dump DMA buffer\n");
}
/*
* Initialize locks and queues
@ -7173,6 +7198,16 @@ static int __init megasas_init(void)
{
int rval;
/*
* Booted in kdump kernel, minimize memory footprints by
* disabling few features
*/
if (reset_devices) {
msix_vectors = 1;
rdpq_enable = 0;
dual_qdepth_disable = 1;
}
/*
* Announce driver version and other information
*/

View file

@ -257,6 +257,9 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c
if (!instance->is_rdpq)
instance->max_fw_cmds = min_t(u16, instance->max_fw_cmds, 1024);
if (reset_devices)
instance->max_fw_cmds = min(instance->max_fw_cmds,
(u16)MEGASAS_KDUMP_QUEUE_DEPTH);
/*
* Reduce the max supported cmds by 1. This is to ensure that the
* reply_q_sz (1 more than the max cmd that driver may send)
@ -851,7 +854,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
ret = 1;
goto fail_fw_init;
}
dev_err(&instance->pdev->dev, "Init cmd success\n");
dev_info(&instance->pdev->dev, "Init cmd success\n");
ret = 0;
@ -2759,6 +2762,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
dev_warn(&instance->pdev->dev, "Found FW in FAULT state,"
" will reset adapter scsi%d.\n",
instance->host->host_no);
megasas_complete_cmd_dpc_fusion((unsigned long)instance);
retval = 1;
goto out;
}
@ -2766,6 +2770,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
if (reason == MFI_IO_TIMEOUT_OCR) {
dev_info(&instance->pdev->dev,
"MFI IO is timed out, initiating OCR\n");
megasas_complete_cmd_dpc_fusion((unsigned long)instance);
retval = 1;
goto out;
}

View file

@ -8,7 +8,7 @@
* scatter/gather formats.
* Creation Date: June 21, 2006
*
* mpi2.h Version: 02.00.39
* mpi2.h Version: 02.00.42
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -100,6 +100,9 @@
* Added MPI2_DIAG_SBR_RELOAD.
* 03-19-15 02.00.38 Bumped MPI2_HEADER_VERSION_UNIT.
* 05-25-15 02.00.39 Bumped MPI2_HEADER_VERSION_UNIT.
* 08-25-15 02.00.40 Bumped MPI2_HEADER_VERSION_UNIT.
* 12-15-15 02.00.41 Bumped MPI_HEADER_VERSION_UNIT
* 01-01-16 02.00.42 Bumped MPI_HEADER_VERSION_UNIT
* --------------------------------------------------------------------------
*/
@ -139,7 +142,7 @@
#define MPI2_VERSION_02_06 (0x0206)
/*Unit and Dev versioning for this MPI header set */
#define MPI2_HEADER_VERSION_UNIT (0x27)
#define MPI2_HEADER_VERSION_UNIT (0x2A)
#define MPI2_HEADER_VERSION_DEV (0x00)
#define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00)
#define MPI2_HEADER_VERSION_UNIT_SHIFT (8)

View file

@ -6,7 +6,7 @@
* Title: MPI Configuration messages and pages
* Creation Date: November 10, 2006
*
* mpi2_cnfg.h Version: 02.00.33
* mpi2_cnfg.h Version: 02.00.35
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -183,9 +183,12 @@
* Added MPI2_BIOSPAGE1_OPTIONS_ADVANCED_CONFIG.
* Added AdapterOrderAux fields to BIOS Page 3.
* 03-16-15 02.00.31 Updated for MPI v2.6.
* Added Flags field to IO Unit Page 7.
* Added new SAS Phy Event codes
* 05-25-15 02.00.33 Added more defines for the BiosOptions field of
* MPI2_CONFIG_PAGE_BIOS_1.
* 08-25-15 02.00.34 Bumped Header Version.
* 12-18-15 02.00.35 Added SATADeviceWaitTime to SAS IO Unit Page 4.
* --------------------------------------------------------------------------
*/
@ -958,13 +961,16 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
U8 Reserved3; /*0x17 */
U32 BoardPowerRequirement; /*0x18 */
U32 PCISlotPowerAllocation; /*0x1C */
U32 Reserved6; /* 0x20 */
U32 Reserved7; /* 0x24 */
/* reserved prior to MPI v2.6 */
U8 Flags; /* 0x20 */
U8 Reserved6; /* 0x21 */
U16 Reserved7; /* 0x22 */
U32 Reserved8; /* 0x24 */
} MPI2_CONFIG_PAGE_IO_UNIT_7,
*PTR_MPI2_CONFIG_PAGE_IO_UNIT_7,
Mpi2IOUnitPage7_t, *pMpi2IOUnitPage7_t;
#define MPI2_IOUNITPAGE7_PAGEVERSION (0x04)
#define MPI2_IOUNITPAGE7_PAGEVERSION (0x05)
/*defines for IO Unit Page 7 CurrentPowerMode and PreviousPowerMode fields */
#define MPI25_IOUNITPAGE7_PM_INIT_MASK (0xC0)
@ -1045,6 +1051,8 @@ typedef struct _MPI2_CONFIG_PAGE_IO_UNIT_7 {
#define MPI2_IOUNITPAGE7_BOARD_TEMP_FAHRENHEIT (0x01)
#define MPI2_IOUNITPAGE7_BOARD_TEMP_CELSIUS (0x02)
/* defines for IO Unit Page 7 Flags field */
#define MPI2_IOUNITPAGE7_FLAG_CABLE_POWER_EXC (0x01)
/*IO Unit Page 8 */
@ -2271,7 +2279,7 @@ typedef struct _MPI2_CONFIG_PAGE_SASIOUNIT_4 {
U8
BootDeviceWaitTime; /*0x24 */
U8
Reserved4; /*0x25 */
SATADeviceWaitTime; /*0x25 */
U16
Reserved5; /*0x26 */
U8

View file

@ -6,7 +6,7 @@
* Title: MPI SCSI initiator mode messages and structures
* Creation Date: June 23, 2006
*
* mpi2_init.h Version: 02.00.17
* mpi2_init.h Version: 02.00.20
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -51,6 +51,9 @@
* Added MPI26_SCSIIO_IOFLAGS_ESCAPE_PASSTHROUGH.
* Added MPI2_SEP_REQ_SLOTSTATUS_DEV_OFF and
* MPI2_SEP_REPLY_SLOTSTATUS_DEV_OFF.
* 08-26-15 02.00.18 Added SCSITASKMGMT_MSGFLAGS for Target Reset.
* 12-18-15 02.00.19 Added EEDPObservedValue added to SCSI IO Reply message.
* 01-04-16 02.00.20 Modified EEDP reported values in SCSI IO Reply message.
* --------------------------------------------------------------------------
*/
@ -359,8 +362,14 @@ typedef struct _MPI2_SCSI_IO_REPLY {
U16 TaskTag; /*0x20 */
U16 SCSIStatusQualifier; /* 0x22 */
U32 BidirectionalTransferCount; /*0x24 */
U32 EEDPErrorOffset; /*0x28 *//*MPI 2.5 only; Reserved in MPI 2.0*/
U32 Reserved6; /*0x2C */
/* MPI 2.5+ only; Reserved in MPI 2.0 */
U32 EEDPErrorOffset; /* 0x28 */
/* MPI 2.5+ only; Reserved in MPI 2.0 */
U16 EEDPObservedAppTag; /* 0x2C */
/* MPI 2.5+ only; Reserved in MPI 2.0 */
U16 EEDPObservedGuard; /* 0x2E */
/* MPI 2.5+ only; Reserved in MPI 2.0 */
U32 EEDPObservedRefTag; /* 0x30 */
} MPI2_SCSI_IO_REPLY, *PTR_MPI2_SCSI_IO_REPLY,
Mpi2SCSIIOReply_t, *pMpi2SCSIIOReply_t;

View file

@ -6,7 +6,7 @@
* Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: October 11, 2006
*
* mpi2_ioc.h Version: 02.00.26
* mpi2_ioc.h Version: 02.00.27
*
* NOTE: Names (typedefs, defines, etc.) beginning with an MPI25 or Mpi25
* prefix are for use only on MPI v2.5 products, and must not be used
@ -134,9 +134,13 @@
* Added Encrypted Hash Extended Image.
* 12-05-13 02.00.24 Added MPI25_HASH_IMAGE_TYPE_BIOS.
* 11-18-14 02.00.25 Updated copyright information.
* 03-16-15 02.00.26 Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
* 03-16-15 02.00.26 Updated for MPI v2.6.
* Added MPI2_EVENT_ACTIVE_CABLE_EXCEPTION and
* MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT.
* Added MPI26_FW_HEADER_PID_FAMILY_3324_SAS and
* MPI26_FW_HEADER_PID_FAMILY_3516_SAS.
* Added MPI26_CTRL_OP_SHUTDOWN.
* 08-25-15 02.00.27 Added IC ARCH Class based signature defines
* --------------------------------------------------------------------------
*/
@ -168,7 +172,7 @@ typedef struct _MPI2_IOC_INIT_REQUEST {
U16 MsgVersion; /*0x0C */
U16 HeaderVersion; /*0x0E */
U32 Reserved5; /*0x10 */
U16 Reserved6; /*0x14 */
U16 ConfigurationFlags; /* 0x14 */
U8 HostPageSize; /*0x16 */
U8 HostMSIxVectors; /*0x17 */
U16 Reserved8; /*0x18 */
@ -516,6 +520,7 @@ typedef struct _MPI2_EVENT_NOTIFICATION_REPLY {
#define MPI2_EVENT_TEMP_THRESHOLD (0x0027)
#define MPI2_EVENT_HOST_MESSAGE (0x0028)
#define MPI2_EVENT_POWER_PERFORMANCE_CHANGE (0x0029)
#define MPI2_EVENT_ACTIVE_CABLE_EXCEPTION (0x0034)
#define MPI2_EVENT_MIN_PRODUCT_SPECIFIC (0x006E)
#define MPI2_EVENT_MAX_PRODUCT_SPECIFIC (0x007F)
@ -580,7 +585,7 @@ typedef struct _MPI2_EVENT_DATA_HOST_MESSAGE {
} MPI2_EVENT_DATA_HOST_MESSAGE, *PTR_MPI2_EVENT_DATA_HOST_MESSAGE,
Mpi2EventDataHostMessage_t, *pMpi2EventDataHostMessage_t;
/*Power Performance Change Event */
/*Power Performance Change Event data */
typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE {
U8 CurrentPowerMode; /*0x00 */
@ -605,6 +610,21 @@ typedef struct _MPI2_EVENT_DATA_POWER_PERF_CHANGE {
#define MPI2_EVENT_PM_MODE_REDUCED_POWER (0x05)
#define MPI2_EVENT_PM_MODE_STANDBY (0x06)
/* Active Cable Exception Event data */
typedef struct _MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT {
U32 ActiveCablePowerRequirement; /* 0x00 */
U8 ReasonCode; /* 0x04 */
U8 ReceptacleID; /* 0x05 */
U16 Reserved1; /* 0x06 */
} MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
*PTR_MPI26_EVENT_DATA_ACTIVE_CABLE_EXCEPT,
Mpi26EventDataActiveCableExcept_t,
*pMpi26EventDataActiveCableExcept_t;
/* defines for ReasonCode field */
#define MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER (0x00)
/*Hard Reset Received Event data */
typedef struct _MPI2_EVENT_DATA_HARD_RESET_RECEIVED {
@ -1366,7 +1386,16 @@ typedef struct _MPI2_FW_IMAGE_HEADER {
/*Signature0 field */
#define MPI2_FW_HEADER_SIGNATURE0_OFFSET (0x04)
#define MPI2_FW_HEADER_SIGNATURE0 (0x5AFAA55A)
#define MPI26_FW_HEADER_SIGNATURE0 (0x5AEAA55A)
/* Last byte is defined by architecture */
#define MPI26_FW_HEADER_SIGNATURE0_BASE (0x5AEAA500)
#define MPI26_FW_HEADER_SIGNATURE0_ARC_0 (0x5A)
#define MPI26_FW_HEADER_SIGNATURE0_ARC_1 (0x00)
#define MPI26_FW_HEADER_SIGNATURE0_ARC_2 (0x01)
/* legacy (0x5AEAA55A) */
#define MPI26_FW_HEADER_SIGNATURE0 \
(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_0)
#define MPI26_FW_HEADER_SIGNATURE0_3516 \
(MPI26_FW_HEADER_SIGNATURE0_BASE+MPI26_FW_HEADER_SIGNATURE0_ARC_1)
/*Signature1 field */
#define MPI2_FW_HEADER_SIGNATURE1_OFFSET (0x08)
@ -1778,6 +1807,7 @@ typedef struct _MPI26_IOUNIT_CONTROL_REQUEST {
#define MPI26_CTRL_OP_SAS_PHY_LINK_RESET (0x06)
#define MPI26_CTRL_OP_SAS_PHY_HARD_RESET (0x07)
#define MPI26_CTRL_OP_PHY_CLEAR_ERROR_LOG (0x08)
#define MPI26_CTRL_OP_LINK_CLEAR_ERROR_LOG (0x09)
#define MPI26_CTRL_OP_SAS_SEND_PRIMITIVE (0x0A)
#define MPI26_CTRL_OP_FORCE_FULL_DISCOVERY (0x0B)
#define MPI26_CTRL_OP_REMOVE_DEVICE (0x0D)

View file

@ -57,6 +57,7 @@
#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/time.h>
#include <linux/ktime.h>
#include <linux/kthread.h>
#include <linux/aer.h>
@ -654,6 +655,9 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_TEMP_THRESHOLD:
desc = "Temperature Threshold";
break;
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Active cable exception";
break;
}
if (!desc)
@ -1100,18 +1104,16 @@ _base_is_controller_msix_enabled(struct MPT3SAS_ADAPTER *ioc)
}
/**
* mpt3sas_base_flush_reply_queues - flushing the MSIX reply queues
* mpt3sas_base_sync_reply_irqs - flush pending MSIX interrupts
* @ioc: per adapter object
* Context: ISR conext
* Context: non ISR conext
*
* Called when a Task Management request has completed. We want
* to flush the other reply queues so all the outstanding IO has been
* completed back to OS before we process the TM completetion.
* Called when a Task Management request has completed.
*
* Return nothing.
*/
void
mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc)
mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc)
{
struct adapter_reply_queue *reply_q;
@ -1122,12 +1124,13 @@ mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc)
return;
list_for_each_entry(reply_q, &ioc->reply_queue_list, list) {
if (ioc->shost_recovery)
if (ioc->shost_recovery || ioc->remove_host ||
ioc->pci_error_recovery)
return;
/* TMs are on msix_index == 0 */
if (reply_q->msix_index == 0)
continue;
_base_interrupt(reply_q->vector, (void *)reply_q);
synchronize_irq(reply_q->vector);
}
}
@ -3207,10 +3210,10 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
sg_tablesize = MPT_MIN_PHYS_SEGMENTS;
else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) {
sg_tablesize = min_t(unsigned short, sg_tablesize,
SCSI_MAX_SG_CHAIN_SEGMENTS);
SG_MAX_SEGMENTS);
pr_warn(MPT3SAS_FMT
"sg_tablesize(%u) is bigger than kernel"
" defined SCSI_MAX_SG_SEGMENTS(%u)\n", ioc->name,
" defined SG_CHUNK_SIZE(%u)\n", ioc->name,
sg_tablesize, MPT_MAX_PHYS_SEGMENTS);
}
ioc->shost->sg_tablesize = sg_tablesize;
@ -4387,7 +4390,7 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
Mpi2IOCInitRequest_t mpi_request;
Mpi2IOCInitReply_t mpi_reply;
int i, r = 0;
struct timeval current_time;
ktime_t current_time;
u16 ioc_status;
u32 reply_post_free_array_sz = 0;
Mpi2IOCInitRDPQArrayEntry *reply_post_free_array = NULL;
@ -4449,9 +4452,8 @@ _base_send_ioc_init(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
/* This time stamp specifies number of milliseconds
* since epoch ~ midnight January 1, 1970.
*/
do_gettimeofday(&current_time);
mpi_request.TimeStamp = cpu_to_le64((u64)current_time.tv_sec * 1000 +
(current_time.tv_usec / 1000));
current_time = ktime_get_real();
mpi_request.TimeStamp = cpu_to_le64(ktime_to_ms(current_time));
if (ioc->logging_level & MPT_DEBUG_INIT) {
__le32 *mfp;
@ -5424,6 +5426,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_IR_OPERATION_STATUS);
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
if (ioc->hba_mpi_version_belonged == MPI26_VERSION)
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
r = _base_make_ioc_operational(ioc, CAN_SLEEP);
if (r)

View file

@ -73,8 +73,8 @@
#define MPT3SAS_DRIVER_NAME "mpt3sas"
#define MPT3SAS_AUTHOR "Avago Technologies <MPT-FusionLinux.pdl@avagotech.com>"
#define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver"
#define MPT3SAS_DRIVER_VERSION "12.100.00.00"
#define MPT3SAS_MAJOR_VERSION 12
#define MPT3SAS_DRIVER_VERSION "13.100.00.00"
#define MPT3SAS_MAJOR_VERSION 13
#define MPT3SAS_MINOR_VERSION 100
#define MPT3SAS_BUILD_VERSION 0
#define MPT3SAS_RELEASE_VERSION 00
@ -90,7 +90,7 @@
/*
* Set MPT3SAS_SG_DEPTH value based on user input.
*/
#define MPT_MAX_PHYS_SEGMENTS SCSI_MAX_SG_SEGMENTS
#define MPT_MAX_PHYS_SEGMENTS SG_CHUNK_SIZE
#define MPT_MIN_PHYS_SEGMENTS 16
#ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE
@ -112,6 +112,8 @@
#define MPT3SAS_SAS_QUEUE_DEPTH 254
#define MPT3SAS_RAID_QUEUE_DEPTH 128
#define MPT3SAS_RAID_MAX_SECTORS 8192
#define MPT_NAME_LENGTH 32 /* generic length of strings */
#define MPT_STRING_LENGTH 64
@ -1234,7 +1236,8 @@ void *mpt3sas_base_get_msg_frame(struct MPT3SAS_ADAPTER *ioc, u16 smid);
void *mpt3sas_base_get_sense_buffer(struct MPT3SAS_ADAPTER *ioc, u16 smid);
__le32 mpt3sas_base_get_sense_buffer_dma(struct MPT3SAS_ADAPTER *ioc,
u16 smid);
void mpt3sas_base_flush_reply_queues(struct MPT3SAS_ADAPTER *ioc);
void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc);
/* hi-priority queue */
u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx);

View file

@ -174,13 +174,13 @@ struct sense_info {
* struct fw_event_work - firmware event struct
* @list: link list framework
* @work: work object (ioc->fault_reset_work_q)
* @cancel_pending_work: flag set during reset handling
* @ioc: per adapter object
* @device_handle: device handle
* @VF_ID: virtual function id
* @VP_ID: virtual port id
* @ignore: flag meaning this event has been marked to ignore
* @event: firmware event MPI2_EVENT_XXX defined in mpt2_ioc.h
* @event: firmware event MPI2_EVENT_XXX defined in mpi2_ioc.h
* @refcount: kref for this event
* @event_data: reply event data payload follows
*
* This object stored on ioc->fw_event_list.
@ -188,8 +188,6 @@ struct sense_info {
struct fw_event_work {
struct list_head list;
struct work_struct work;
u8 cancel_pending_work;
struct delayed_work delayed_work;
struct MPT3SAS_ADAPTER *ioc;
u16 device_handle;
@ -1911,6 +1909,14 @@ scsih_slave_configure(struct scsi_device *sdev)
(unsigned long long)raid_device->wwid,
raid_device->num_pds, ds);
if (shost->max_sectors > MPT3SAS_RAID_MAX_SECTORS) {
blk_queue_max_hw_sectors(sdev->request_queue,
MPT3SAS_RAID_MAX_SECTORS);
sdev_printk(KERN_INFO, sdev,
"Set queue's max_sector to: %u\n",
MPT3SAS_RAID_MAX_SECTORS);
}
scsih_change_queue_depth(sdev, qdepth);
/* raid transport support */
@ -2118,7 +2124,6 @@ _scsih_tm_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
return 1;
if (ioc->tm_cmds.smid != smid)
return 1;
mpt3sas_base_flush_reply_queues(ioc);
ioc->tm_cmds.status |= MPT3_CMD_COMPLETE;
mpi_reply = mpt3sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
@ -2303,6 +2308,9 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel,
}
}
/* sync IRQs in case those were busy during flush. */
mpt3sas_base_sync_reply_irqs(ioc);
if (ioc->tm_cmds.status & MPT3_CMD_REPLY_VALID) {
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_TASK_MANAGMENT);
mpi_reply = ioc->tm_cmds.reply;
@ -2804,12 +2812,12 @@ _scsih_fw_event_cleanup_queue(struct MPT3SAS_ADAPTER *ioc)
/*
* Wait on the fw_event to complete. If this returns 1, then
* the event was never executed, and we need a put for the
* reference the delayed_work had on the fw_event.
* reference the work had on the fw_event.
*
* If it did execute, we wait for it to finish, and the put will
* happen from _firmware_event_work()
*/
if (cancel_delayed_work_sync(&fw_event->delayed_work))
if (cancel_work_sync(&fw_event->work))
fw_event_work_put(fw_event);
fw_event_work_put(fw_event);
@ -3961,7 +3969,7 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
mpi_request->CDB.EEDP32.PrimaryReferenceTag =
cpu_to_be32(scsi_get_lba(scmd));
cpu_to_be32(scsi_prot_ref_tag(scmd));
break;
case SCSI_PROT_DIF_TYPE3:
@ -7850,6 +7858,7 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
Mpi2EventNotificationReply_t *mpi_reply;
u16 event;
u16 sz;
Mpi26EventDataActiveCableExcept_t *ActiveCableEventData;
/* events turned off due to host reset or driver unloading */
if (ioc->remove_host || ioc->pci_error_recovery)
@ -7962,6 +7971,18 @@ mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
(Mpi2EventDataTemperature_t *)
mpi_reply->EventData);
break;
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
ActiveCableEventData =
(Mpi26EventDataActiveCableExcept_t *) mpi_reply->EventData;
if (ActiveCableEventData->ReasonCode ==
MPI26_EVENT_ACTIVE_CABLE_INSUFFICIENT_POWER)
pr_info(MPT3SAS_FMT "Currently an active cable with ReceptacleID %d",
ioc->name, ActiveCableEventData->ReceptacleID);
pr_info("cannot be powered and devices connected to this active cable");
pr_info("will not be seen. This active cable");
pr_info("requires %d mW of power",
ActiveCableEventData->ActiveCablePowerRequirement);
break;
default: /* ignore the rest */
return 1;

View file

@ -704,24 +704,7 @@ static struct pci_device_id mvs_pci_table[] = {
.class_mask = 0,
.driver_data = chip_9445,
},
{
.vendor = PCI_VENDOR_ID_MARVELL_EXT,
.device = 0x9485,
.subvendor = PCI_ANY_ID,
.subdevice = 0x9480,
.class = 0,
.class_mask = 0,
.driver_data = chip_9485,
},
{
.vendor = PCI_VENDOR_ID_MARVELL_EXT,
.device = 0x9485,
.subvendor = PCI_ANY_ID,
.subdevice = 0x9485,
.class = 0,
.class_mask = 0,
.driver_data = chip_9485,
},
{ PCI_VDEVICE(MARVELL_EXT, 0x9485), chip_9485 }, /* Marvell 9480/9485 (any vendor/model) */
{ PCI_VDEVICE(OCZ, 0x1021), chip_9485}, /* OCZ RevoDrive3 */
{ PCI_VDEVICE(OCZ, 0x1022), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */
{ PCI_VDEVICE(OCZ, 0x1040), chip_9485}, /* OCZ RevoDrive3/zDriveR4 (exact model unknown) */

View file

@ -1,5 +1,3 @@
#define PSEUDO_DMA
/*
* This driver adapted from Drew Eckhardt's Trantor T128 driver
*
@ -77,7 +75,6 @@
#include <scsi/scsi_host.h>
#include "pas16.h"
#define AUTOPROBE_IRQ
#include "NCR5380.h"
@ -377,7 +374,7 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
instance->io_port = io_port;
if (NCR5380_init(instance, 0))
if (NCR5380_init(instance, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP))
goto out_unregister;
NCR5380_maybe_reset_bus(instance);
@ -460,7 +457,7 @@ static int pas16_biosparam(struct scsi_device *sdev, struct block_device *dev,
}
/*
* Function : int NCR5380_pread (struct Scsi_Host *instance,
* Function : int pas16_pread (struct Scsi_Host *instance,
* unsigned char *dst, int len)
*
* Purpose : Fast 5380 pseudo-dma read function, transfers len bytes to
@ -472,14 +469,14 @@ static int pas16_biosparam(struct scsi_device *sdev, struct block_device *dev,
* timeout.
*/
static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
int len) {
static inline int pas16_pread(struct Scsi_Host *instance,
unsigned char *dst, int len)
{
register unsigned char *d = dst;
register unsigned short reg = (unsigned short) (instance->io_port +
P_DATA_REG_OFFSET);
register int i = len;
int ii = 0;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
while ( !(inb(instance->io_port + P_STATUS_REG_OFFSET) & P_ST_RDY) )
++ii;
@ -492,13 +489,11 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
instance->host_no);
return -1;
}
if (ii > hostdata->spin_max_r)
hostdata->spin_max_r = ii;
return 0;
}
/*
* Function : int NCR5380_pwrite (struct Scsi_Host *instance,
* Function : int pas16_pwrite (struct Scsi_Host *instance,
* unsigned char *src, int len)
*
* Purpose : Fast 5380 pseudo-dma write function, transfers len bytes from
@ -510,13 +505,13 @@ static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,
* timeout.
*/
static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,
int len) {
static inline int pas16_pwrite(struct Scsi_Host *instance,
unsigned char *src, int len)
{
register unsigned char *s = src;
register unsigned short reg = (instance->io_port + P_DATA_REG_OFFSET);
register int i = len;
int ii = 0;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
while ( !((inb(instance->io_port + P_STATUS_REG_OFFSET)) & P_ST_RDY) )
++ii;
@ -529,8 +524,6 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
instance->host_no);
return -1;
}
if (ii > hostdata->spin_max_w)
hostdata->spin_max_w = ii;
return 0;
}
@ -550,8 +543,6 @@ static struct scsi_host_template driver_template = {
.detect = pas16_detect,
.release = pas16_release,
.proc_name = "pas16",
.show_info = pas16_show_info,
.write_info = pas16_write_info,
.info = pas16_info,
.queuecommand = pas16_queue_command,
.eh_abort_handler = pas16_abort,

View file

@ -103,14 +103,15 @@
#define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize)
#define NCR5380_dma_recv_setup pas16_pread
#define NCR5380_dma_send_setup pas16_pwrite
#define NCR5380_dma_residual(instance) (0)
#define NCR5380_intr pas16_intr
#define NCR5380_queue_command pas16_queue_command
#define NCR5380_abort pas16_abort
#define NCR5380_bus_reset pas16_bus_reset
#define NCR5380_info pas16_info
#define NCR5380_show_info pas16_show_info
#define NCR5380_write_info pas16_write_info
/* 15 14 12 10 7 5 3
1101 0100 1010 1000 */

View file

@ -418,8 +418,6 @@ static int pm8001_ioremap(struct pm8001_hba_info *pm8001_ha)
if (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) {
pm8001_ha->io_mem[logicalBar].membase =
pci_resource_start(pdev, bar);
pm8001_ha->io_mem[logicalBar].membase &=
(u32)PCI_BASE_ADDRESS_MEM_MASK;
pm8001_ha->io_mem[logicalBar].memsize =
pci_resource_len(pdev, bar);
pm8001_ha->io_mem[logicalBar].memvirtaddr =

View file

@ -6,6 +6,7 @@
*/
#include "qla_def.h"
#include <linux/delay.h>
#include <linux/ktime.h>
#include <linux/pci.h>
#include <linux/ratelimit.h>
#include <linux/vmalloc.h>
@ -1812,7 +1813,6 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
struct host_system_info *phost_info;
struct register_host_info *preg_hsi;
struct new_utsname *p_sysid = NULL;
struct timeval tv;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
@ -1886,8 +1886,7 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
p_sysid->domainname, DOMNAME_LENGTH);
strncpy(phost_info->hostdriver,
QLA2XXX_VERSION, VERSION_LENGTH);
do_gettimeofday(&tv);
preg_hsi->utc = (uint64_t)tv.tv_sec;
preg_hsi->utc = (uint64_t)ktime_get_real_seconds();
ql_dbg(ql_dbg_init, vha, 0x0149,
"ISP%04X: Host registration with firmware\n",
ha->pdev->device);

View file

@ -1229,7 +1229,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
if (buf == NULL) {
ql_log(ql_log_fatal, vha, 0x010c,
"Unable to allocate memory.\n");
return -1;
return -ENOMEM;
}
for (i = 0; i < n; i++) {

File diff suppressed because it is too large Load diff

View file

@ -14,8 +14,6 @@
#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/mempool.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
@ -40,39 +38,6 @@
#include "scsi_logging.h"
#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools)
#define SG_MEMPOOL_SIZE 2
struct scsi_host_sg_pool {
size_t size;
char *name;
struct kmem_cache *slab;
mempool_t *pool;
};
#define SP(x) { .size = x, "sgpool-" __stringify(x) }
#if (SCSI_MAX_SG_SEGMENTS < 32)
#error SCSI_MAX_SG_SEGMENTS is too small (must be 32 or greater)
#endif
static struct scsi_host_sg_pool scsi_sg_pools[] = {
SP(8),
SP(16),
#if (SCSI_MAX_SG_SEGMENTS > 32)
SP(32),
#if (SCSI_MAX_SG_SEGMENTS > 64)
SP(64),
#if (SCSI_MAX_SG_SEGMENTS > 128)
SP(128),
#if (SCSI_MAX_SG_SEGMENTS > 256)
#error SCSI_MAX_SG_SEGMENTS is too large (256 MAX)
#endif
#endif
#endif
#endif
SP(SCSI_MAX_SG_SEGMENTS)
};
#undef SP
struct kmem_cache *scsi_sdb_cache;
/*
@ -553,66 +518,6 @@ void scsi_run_host_queues(struct Scsi_Host *shost)
scsi_run_queue(sdev->request_queue);
}
static inline unsigned int scsi_sgtable_index(unsigned short nents)
{
unsigned int index;
BUG_ON(nents > SCSI_MAX_SG_SEGMENTS);
if (nents <= 8)
index = 0;
else
index = get_count_order(nents) - 3;
return index;
}
static void scsi_sg_free(struct scatterlist *sgl, unsigned int nents)
{
struct scsi_host_sg_pool *sgp;
sgp = scsi_sg_pools + scsi_sgtable_index(nents);
mempool_free(sgl, sgp->pool);
}
static struct scatterlist *scsi_sg_alloc(unsigned int nents, gfp_t gfp_mask)
{
struct scsi_host_sg_pool *sgp;
sgp = scsi_sg_pools + scsi_sgtable_index(nents);
return mempool_alloc(sgp->pool, gfp_mask);
}
static void scsi_free_sgtable(struct scsi_data_buffer *sdb, bool mq)
{
if (mq && sdb->table.orig_nents <= SCSI_MAX_SG_SEGMENTS)
return;
__sg_free_table(&sdb->table, SCSI_MAX_SG_SEGMENTS, mq, scsi_sg_free);
}
static int scsi_alloc_sgtable(struct scsi_data_buffer *sdb, int nents, bool mq)
{
struct scatterlist *first_chunk = NULL;
int ret;
BUG_ON(!nents);
if (mq) {
if (nents <= SCSI_MAX_SG_SEGMENTS) {
sdb->table.nents = sdb->table.orig_nents = nents;
sg_init_table(sdb->table.sgl, nents);
return 0;
}
first_chunk = sdb->table.sgl;
}
ret = __sg_alloc_table(&sdb->table, nents, SCSI_MAX_SG_SEGMENTS,
first_chunk, GFP_ATOMIC, scsi_sg_alloc);
if (unlikely(ret))
scsi_free_sgtable(sdb, mq);
return ret;
}
static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
{
if (cmd->request->cmd_type == REQ_TYPE_FS) {
@ -625,12 +530,17 @@ static void scsi_uninit_cmd(struct scsi_cmnd *cmd)
static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
{
struct scsi_data_buffer *sdb;
if (cmd->sdb.table.nents)
scsi_free_sgtable(&cmd->sdb, true);
if (cmd->request->next_rq && cmd->request->next_rq->special)
scsi_free_sgtable(cmd->request->next_rq->special, true);
sg_free_table_chained(&cmd->sdb.table, true);
if (cmd->request->next_rq) {
sdb = cmd->request->next_rq->special;
if (sdb)
sg_free_table_chained(&sdb->table, true);
}
if (scsi_prot_sg_count(cmd))
scsi_free_sgtable(cmd->prot_sdb, true);
sg_free_table_chained(&cmd->prot_sdb->table, true);
}
static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
@ -669,19 +579,19 @@ static void scsi_mq_uninit_cmd(struct scsi_cmnd *cmd)
static void scsi_release_buffers(struct scsi_cmnd *cmd)
{
if (cmd->sdb.table.nents)
scsi_free_sgtable(&cmd->sdb, false);
sg_free_table_chained(&cmd->sdb.table, false);
memset(&cmd->sdb, 0, sizeof(cmd->sdb));
if (scsi_prot_sg_count(cmd))
scsi_free_sgtable(cmd->prot_sdb, false);
sg_free_table_chained(&cmd->prot_sdb->table, false);
}
static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd)
{
struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special;
scsi_free_sgtable(bidi_sdb, false);
sg_free_table_chained(&bidi_sdb->table, false);
kmem_cache_free(scsi_sdb_cache, bidi_sdb);
cmd->request->next_rq->special = NULL;
}
@ -1085,8 +995,8 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb)
/*
* If sg table allocation fails, requeue request later.
*/
if (unlikely(scsi_alloc_sgtable(sdb, req->nr_phys_segments,
req->mq_ctx != NULL)))
if (unlikely(sg_alloc_table_chained(&sdb->table, req->nr_phys_segments,
sdb->table.sgl)))
return BLKPREP_DEFER;
/*
@ -1158,7 +1068,8 @@ int scsi_init_io(struct scsi_cmnd *cmd)
ivecs = blk_rq_count_integrity_sg(rq->q, rq->bio);
if (scsi_alloc_sgtable(prot_sdb, ivecs, is_mq)) {
if (sg_alloc_table_chained(&prot_sdb->table, ivecs,
prot_sdb->table.sgl)) {
error = BLKPREP_DEFER;
goto err_exit;
}
@ -1932,7 +1843,7 @@ static int scsi_mq_prep_fn(struct request *req)
if (scsi_host_get_prot(shost)) {
cmd->prot_sdb = (void *)sg +
min_t(unsigned int,
shost->sg_tablesize, SCSI_MAX_SG_SEGMENTS) *
shost->sg_tablesize, SG_CHUNK_SIZE) *
sizeof(struct scatterlist);
memset(cmd->prot_sdb, 0, sizeof(struct scsi_data_buffer));
@ -2105,7 +2016,7 @@ static void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
* this limit is imposed by hardware restrictions
*/
blk_queue_max_segments(q, min_t(unsigned short, shost->sg_tablesize,
SCSI_MAX_SG_CHAIN_SEGMENTS));
SG_MAX_SEGMENTS));
if (scsi_host_prot_dma(shost)) {
shost->sg_prot_tablesize =
@ -2187,8 +2098,8 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost)
unsigned int cmd_size, sgl_size, tbl_size;
tbl_size = shost->sg_tablesize;
if (tbl_size > SCSI_MAX_SG_SEGMENTS)
tbl_size = SCSI_MAX_SG_SEGMENTS;
if (tbl_size > SG_CHUNK_SIZE)
tbl_size = SG_CHUNK_SIZE;
sgl_size = tbl_size * sizeof(struct scatterlist);
cmd_size = sizeof(struct scsi_cmnd) + shost->hostt->cmd_size + sgl_size;
if (scsi_host_get_prot(shost))
@ -2264,8 +2175,6 @@ EXPORT_SYMBOL(scsi_unblock_requests);
int __init scsi_init_queue(void)
{
int i;
scsi_sdb_cache = kmem_cache_create("scsi_data_buffer",
sizeof(struct scsi_data_buffer),
0, 0, NULL);
@ -2274,53 +2183,12 @@ int __init scsi_init_queue(void)
return -ENOMEM;
}
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
int size = sgp->size * sizeof(struct scatterlist);
sgp->slab = kmem_cache_create(sgp->name, size, 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!sgp->slab) {
printk(KERN_ERR "SCSI: can't init sg slab %s\n",
sgp->name);
goto cleanup_sdb;
}
sgp->pool = mempool_create_slab_pool(SG_MEMPOOL_SIZE,
sgp->slab);
if (!sgp->pool) {
printk(KERN_ERR "SCSI: can't init sg mempool %s\n",
sgp->name);
goto cleanup_sdb;
}
}
return 0;
cleanup_sdb:
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
if (sgp->pool)
mempool_destroy(sgp->pool);
if (sgp->slab)
kmem_cache_destroy(sgp->slab);
}
kmem_cache_destroy(scsi_sdb_cache);
return -ENOMEM;
}
void scsi_exit_queue(void)
{
int i;
kmem_cache_destroy(scsi_sdb_cache);
for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
mempool_destroy(sgp->pool);
kmem_cache_destroy(sgp->slab);
}
}
/**
@ -3196,6 +3064,7 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len)
* - EUI-64 based 12-byte
* - NAA IEEE Registered
* - NAA IEEE Extended
* - T10 Vendor ID
* as longer descriptors reduce the likelyhood
* of identification clashes.
*/
@ -3214,6 +3083,21 @@ int scsi_vpd_lun_id(struct scsi_device *sdev, char *id, size_t id_len)
goto next_desig;
switch (d[1] & 0xf) {
case 0x1:
/* T10 Vendor ID */
if (cur_id_size > d[3])
break;
/* Prefer anything */
if (cur_id_type > 0x01 && cur_id_type != 0xff)
break;
cur_id_size = d[3];
if (cur_id_size + 4 > id_len)
cur_id_size = id_len - 4;
cur_id_str = d + 4;
cur_id_type = d[1] & 0xf;
id_size = snprintf(id, id_len, "t10.%*pE",
cur_id_size, cur_id_str);
break;
case 0x2:
/* EUI-64 */
if (cur_id_size > d[3])

View file

@ -116,7 +116,7 @@ extern void scsi_exit_procfs(void);
extern char scsi_scan_type[];
extern int scsi_complete_async_scans(void);
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
unsigned int, u64, int);
unsigned int, u64, enum scsi_scan_mode);
extern void scsi_forget_host(struct Scsi_Host *);
extern void scsi_rescan_device(struct device *);

View file

@ -251,7 +251,8 @@ static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
if (shost->transportt->user_scan)
error = shost->transportt->user_scan(shost, channel, id, lun);
else
error = scsi_scan_host_selected(shost, channel, id, lun, 1);
error = scsi_scan_host_selected(shost, channel, id, lun,
SCSI_SCAN_MANUAL);
scsi_host_put(shost);
return error;
}

View file

@ -96,10 +96,13 @@ MODULE_PARM_DESC(max_luns,
#define SCSI_SCAN_TYPE_DEFAULT "sync"
#endif
char scsi_scan_type[6] = SCSI_SCAN_TYPE_DEFAULT;
char scsi_scan_type[7] = SCSI_SCAN_TYPE_DEFAULT;
module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
MODULE_PARM_DESC(scan, "sync, async or none");
module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type),
S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(scan, "sync, async, manual, or none. "
"Setting to 'manual' disables automatic scanning, but allows "
"for manual device scan via the 'scan' sysfs attribute.");
static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ + 18;
@ -316,6 +319,7 @@ static void scsi_target_destroy(struct scsi_target *starget)
struct Scsi_Host *shost = dev_to_shost(dev->parent);
unsigned long flags;
BUG_ON(starget->state == STARGET_DEL);
starget->state = STARGET_DEL;
transport_destroy_device(dev);
spin_lock_irqsave(shost->host_lock, flags);
@ -1040,7 +1044,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
* @lun: LUN of target device
* @bflagsp: store bflags here if not NULL
* @sdevp: probe the LUN corresponding to this scsi_device
* @rescan: if nonzero skip some code only needed on first scan
* @rescan: if not equal to SCSI_SCAN_INITIAL skip some code only
* needed on first scan
* @hostdata: passed to scsi_alloc_sdev()
*
* Description:
@ -1055,7 +1060,8 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq,
**/
static int scsi_probe_and_add_lun(struct scsi_target *starget,
u64 lun, int *bflagsp,
struct scsi_device **sdevp, int rescan,
struct scsi_device **sdevp,
enum scsi_scan_mode rescan,
void *hostdata)
{
struct scsi_device *sdev;
@ -1069,7 +1075,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
*/
sdev = scsi_device_lookup_by_target(starget, lun);
if (sdev) {
if (rescan || !scsi_device_created(sdev)) {
if (rescan != SCSI_SCAN_INITIAL || !scsi_device_created(sdev)) {
SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev,
"scsi scan: device exists on %s\n",
dev_name(&sdev->sdev_gendev)));
@ -1205,7 +1211,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
* Modifies sdevscan->lun.
**/
static void scsi_sequential_lun_scan(struct scsi_target *starget,
int bflags, int scsi_level, int rescan)
int bflags, int scsi_level,
enum scsi_scan_mode rescan)
{
uint max_dev_lun;
u64 sparse_lun, lun;
@ -1300,7 +1307,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
* 1: could not scan with REPORT LUN
**/
static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
int rescan)
enum scsi_scan_mode rescan)
{
char devname[64];
unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@ -1546,7 +1553,7 @@ void scsi_rescan_device(struct device *dev)
EXPORT_SYMBOL(scsi_rescan_device);
static void __scsi_scan_target(struct device *parent, unsigned int channel,
unsigned int id, u64 lun, int rescan)
unsigned int id, u64 lun, enum scsi_scan_mode rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
int bflags = 0;
@ -1604,7 +1611,10 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
* @channel: channel to scan
* @id: target id to scan
* @lun: Specific LUN to scan or SCAN_WILD_CARD
* @rescan: passed to LUN scanning routines
* @rescan: passed to LUN scanning routines; SCSI_SCAN_INITIAL for
* no rescan, SCSI_SCAN_RESCAN to rescan existing LUNs,
* and SCSI_SCAN_MANUAL to force scanning even if
* 'scan=manual' is set.
*
* Description:
* Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
@ -1614,13 +1624,17 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
* sequential scan of LUNs on the target id.
**/
void scsi_scan_target(struct device *parent, unsigned int channel,
unsigned int id, u64 lun, int rescan)
unsigned int id, u64 lun, enum scsi_scan_mode rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
if (strncmp(scsi_scan_type, "none", 4) == 0)
return;
if (rescan != SCSI_SCAN_MANUAL &&
strncmp(scsi_scan_type, "manual", 6) == 0)
return;
mutex_lock(&shost->scan_mutex);
if (!shost->async_scan)
scsi_complete_async_scans();
@ -1634,7 +1648,8 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
EXPORT_SYMBOL(scsi_scan_target);
static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, u64 lun, int rescan)
unsigned int id, u64 lun,
enum scsi_scan_mode rescan)
{
uint order_id;
@ -1665,7 +1680,8 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
}
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
unsigned int id, u64 lun, int rescan)
unsigned int id, u64 lun,
enum scsi_scan_mode rescan)
{
SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost,
"%s: <%u:%u:%llu>\n",
@ -1844,7 +1860,8 @@ void scsi_scan_host(struct Scsi_Host *shost)
{
struct async_scan_data *data;
if (strncmp(scsi_scan_type, "none", 4) == 0)
if (strncmp(scsi_scan_type, "none", 4) == 0 ||
strncmp(scsi_scan_type, "manual", 6) == 0)
return;
if (scsi_autopm_get_host(shost) < 0)
return;

View file

@ -145,7 +145,8 @@ static int scsi_scan(struct Scsi_Host *shost, const char *str)
if (shost->transportt->user_scan)
res = shost->transportt->user_scan(shost, channel, id, lun);
else
res = scsi_scan_host_selected(shost, channel, id, lun, 1);
res = scsi_scan_host_selected(shost, channel, id, lun,
SCSI_SCAN_MANUAL);
return res;
}
@ -1366,18 +1367,18 @@ static void __scsi_remove_target(struct scsi_target *starget)
void scsi_remove_target(struct device *dev)
{
struct Scsi_Host *shost = dev_to_shost(dev->parent);
struct scsi_target *starget, *last_target = NULL;
struct scsi_target *starget;
unsigned long flags;
restart:
spin_lock_irqsave(shost->host_lock, flags);
list_for_each_entry(starget, &shost->__targets, siblings) {
if (starget->state == STARGET_DEL ||
starget == last_target)
starget->state == STARGET_REMOVE)
continue;
if (starget->dev.parent == dev || &starget->dev == dev) {
kref_get(&starget->reap_ref);
last_target = starget;
starget->state = STARGET_REMOVE;
spin_unlock_irqrestore(shost->host_lock, flags);
__scsi_remove_target(starget);
scsi_target_reap(starget);

View file

@ -17,6 +17,7 @@
*/
#include <linux/kernel.h>
#include <linux/trace_seq.h>
#include <asm/unaligned.h>
#include <trace/events/scsi.h>
#define SERVICE_ACTION16(cdb) (cdb[1] & 0x1f)
@ -230,6 +231,158 @@ out:
return ret;
}
static const char *
scsi_trace_maintenance_in(struct trace_seq *p, unsigned char *cdb, int len)
{
const char *ret = trace_seq_buffer_ptr(p), *cmd;
u32 alloc_len;
switch (SERVICE_ACTION16(cdb)) {
case MI_REPORT_IDENTIFYING_INFORMATION:
cmd = "REPORT_IDENTIFYING_INFORMATION";
break;
case MI_REPORT_TARGET_PGS:
cmd = "REPORT_TARGET_PORT_GROUPS";
break;
case MI_REPORT_ALIASES:
cmd = "REPORT_ALIASES";
break;
case MI_REPORT_SUPPORTED_OPERATION_CODES:
cmd = "REPORT_SUPPORTED_OPERATION_CODES";
break;
case MI_REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS:
cmd = "REPORT_SUPPORTED_TASK_MANAGEMENT_FUNCTIONS";
break;
case MI_REPORT_PRIORITY:
cmd = "REPORT_PRIORITY";
break;
case MI_REPORT_TIMESTAMP:
cmd = "REPORT_TIMESTAMP";
break;
case MI_MANAGEMENT_PROTOCOL_IN:
cmd = "MANAGEMENT_PROTOCOL_IN";
break;
default:
trace_seq_puts(p, "UNKNOWN");
goto out;
}
alloc_len = get_unaligned_be32(&cdb[6]);
trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
out:
trace_seq_putc(p, 0);
return ret;
}
static const char *
scsi_trace_maintenance_out(struct trace_seq *p, unsigned char *cdb, int len)
{
const char *ret = trace_seq_buffer_ptr(p), *cmd;
u32 alloc_len;
switch (SERVICE_ACTION16(cdb)) {
case MO_SET_IDENTIFYING_INFORMATION:
cmd = "SET_IDENTIFYING_INFORMATION";
break;
case MO_SET_TARGET_PGS:
cmd = "SET_TARGET_PORT_GROUPS";
break;
case MO_CHANGE_ALIASES:
cmd = "CHANGE_ALIASES";
break;
case MO_SET_PRIORITY:
cmd = "SET_PRIORITY";
break;
case MO_SET_TIMESTAMP:
cmd = "SET_TIMESTAMP";
break;
case MO_MANAGEMENT_PROTOCOL_OUT:
cmd = "MANAGEMENT_PROTOCOL_OUT";
break;
default:
trace_seq_puts(p, "UNKNOWN");
goto out;
}
alloc_len = get_unaligned_be32(&cdb[6]);
trace_seq_printf(p, "%s alloc_len=%u", cmd, alloc_len);
out:
trace_seq_putc(p, 0);
return ret;
}
static const char *
scsi_trace_zbc_in(struct trace_seq *p, unsigned char *cdb, int len)
{
const char *ret = trace_seq_buffer_ptr(p), *cmd;
u64 zone_id;
u32 alloc_len;
u8 options;
switch (SERVICE_ACTION16(cdb)) {
case ZI_REPORT_ZONES:
cmd = "REPORT_ZONES";
break;
default:
trace_seq_puts(p, "UNKNOWN");
goto out;
}
zone_id = get_unaligned_be64(&cdb[2]);
alloc_len = get_unaligned_be32(&cdb[10]);
options = cdb[14] & 0x3f;
trace_seq_printf(p, "%s zone=%llu alloc_len=%u options=%u partial=%u",
cmd, (unsigned long long)zone_id, alloc_len,
options, (cdb[14] >> 7) & 1);
out:
trace_seq_putc(p, 0);
return ret;
}
static const char *
scsi_trace_zbc_out(struct trace_seq *p, unsigned char *cdb, int len)
{
const char *ret = trace_seq_buffer_ptr(p), *cmd;
u64 zone_id;
switch (SERVICE_ACTION16(cdb)) {
case ZO_CLOSE_ZONE:
cmd = "CLOSE_ZONE";
break;
case ZO_FINISH_ZONE:
cmd = "FINISH_ZONE";
break;
case ZO_OPEN_ZONE:
cmd = "OPEN_ZONE";
break;
case ZO_RESET_WRITE_POINTER:
cmd = "RESET_WRITE_POINTER";
break;
default:
trace_seq_puts(p, "UNKNOWN");
goto out;
}
zone_id = get_unaligned_be64(&cdb[2]);
trace_seq_printf(p, "%s zone=%llu all=%u", cmd,
(unsigned long long)zone_id, cdb[14] & 1);
out:
trace_seq_putc(p, 0);
return ret;
}
static const char *
scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
{
@ -282,6 +435,14 @@ scsi_trace_parse_cdb(struct trace_seq *p, unsigned char *cdb, int len)
return scsi_trace_service_action_in(p, cdb, len);
case VARIABLE_LENGTH_CMD:
return scsi_trace_varlen(p, cdb, len);
case MAINTENANCE_IN:
return scsi_trace_maintenance_in(p, cdb, len);
case MAINTENANCE_OUT:
return scsi_trace_maintenance_out(p, cdb, len);
case ZBC_IN:
return scsi_trace_zbc_in(p, cdb, len);
case ZBC_OUT:
return scsi_trace_zbc_out(p, cdb, len);
default:
return scsi_trace_misc(p, cdb, len);
}

View file

@ -2027,11 +2027,10 @@ static void fc_vport_dev_release(struct device *dev)
kfree(vport);
}
int scsi_is_fc_vport(const struct device *dev)
static int scsi_is_fc_vport(const struct device *dev)
{
return dev->release == fc_vport_dev_release;
}
EXPORT_SYMBOL(scsi_is_fc_vport);
static int fc_vport_match(struct attribute_container *cont,
struct device *dev)
@ -2110,7 +2109,8 @@ fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
if ((channel == rport->channel) &&
(id == rport->scsi_target_id)) {
spin_unlock_irqrestore(shost->host_lock, flags);
scsi_scan_target(&rport->dev, channel, id, lun, 1);
scsi_scan_target(&rport->dev, channel, id, lun,
SCSI_SCAN_MANUAL);
return;
}
}
@ -3277,7 +3277,8 @@ fc_scsi_scan_rport(struct work_struct *work)
(rport->roles & FC_PORT_ROLE_FCP_TARGET) &&
!(i->f->disable_target_scan)) {
scsi_scan_target(&rport->dev, rport->channel,
rport->scsi_target_id, SCAN_WILD_CARD, 1);
rport->scsi_target_id, SCAN_WILD_CARD,
SCSI_SCAN_RESCAN);
}
spin_lock_irqsave(shost->host_lock, flags);

View file

@ -1009,7 +1009,7 @@ static void iscsi_flashnode_sess_release(struct device *dev)
kfree(fnode_sess);
}
struct device_type iscsi_flashnode_sess_dev_type = {
static struct device_type iscsi_flashnode_sess_dev_type = {
.name = "iscsi_flashnode_sess_dev_type",
.groups = iscsi_flashnode_sess_attr_groups,
.release = iscsi_flashnode_sess_release,
@ -1195,13 +1195,13 @@ static void iscsi_flashnode_conn_release(struct device *dev)
kfree(fnode_conn);
}
struct device_type iscsi_flashnode_conn_dev_type = {
static struct device_type iscsi_flashnode_conn_dev_type = {
.name = "iscsi_flashnode_conn_dev_type",
.groups = iscsi_flashnode_conn_attr_groups,
.release = iscsi_flashnode_conn_release,
};
struct bus_type iscsi_flashnode_bus;
static struct bus_type iscsi_flashnode_bus;
int iscsi_flashnode_bus_match(struct device *dev,
struct device_driver *drv)
@ -1212,7 +1212,7 @@ int iscsi_flashnode_bus_match(struct device *dev,
}
EXPORT_SYMBOL_GPL(iscsi_flashnode_bus_match);
struct bus_type iscsi_flashnode_bus = {
static struct bus_type iscsi_flashnode_bus = {
.name = "iscsi_flashnode",
.match = &iscsi_flashnode_bus_match,
};
@ -1324,11 +1324,10 @@ EXPORT_SYMBOL_GPL(iscsi_create_flashnode_conn);
* 1 on success
* 0 on failure
*/
int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
static int iscsi_is_flashnode_conn_dev(struct device *dev, void *data)
{
return dev->bus == &iscsi_flashnode_bus;
}
EXPORT_SYMBOL_GPL(iscsi_is_flashnode_conn_dev);
static int iscsi_destroy_flashnode_conn(struct iscsi_bus_flash_conn *fnode_conn)
{
@ -1783,6 +1782,7 @@ struct iscsi_scan_data {
unsigned int channel;
unsigned int id;
u64 lun;
enum scsi_scan_mode rescan;
};
static int iscsi_user_scan_session(struct device *dev, void *data)
@ -1819,7 +1819,7 @@ static int iscsi_user_scan_session(struct device *dev, void *data)
(scan_data->id == SCAN_WILD_CARD ||
scan_data->id == id))
scsi_scan_target(&session->dev, 0, id,
scan_data->lun, 1);
scan_data->lun, scan_data->rescan);
}
user_scan_exit:
@ -1836,6 +1836,7 @@ static int iscsi_user_scan(struct Scsi_Host *shost, uint channel,
scan_data.channel = channel;
scan_data.id = id;
scan_data.lun = lun;
scan_data.rescan = SCSI_SCAN_MANUAL;
return device_for_each_child(&shost->shost_gendev, &scan_data,
iscsi_user_scan_session);
@ -1852,6 +1853,7 @@ static void iscsi_scan_session(struct work_struct *work)
scan_data.channel = 0;
scan_data.id = SCAN_WILD_CARD;
scan_data.lun = SCAN_WILD_CARD;
scan_data.rescan = SCSI_SCAN_RESCAN;
iscsi_user_scan_session(&session->dev, &scan_data);
atomic_dec(&ihost->nr_scans);
@ -2067,13 +2069,10 @@ EXPORT_SYMBOL_GPL(iscsi_alloc_session);
int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
{
struct Scsi_Host *shost = iscsi_session_to_shost(session);
struct iscsi_cls_host *ihost;
unsigned long flags;
int id = 0;
int err;
ihost = shost->shost_data;
session->sid = atomic_add_return(1, &iscsi_session_nr);
if (target_id == ISCSI_MAX_TARGET) {

View file

@ -1614,7 +1614,8 @@ int sas_rphy_add(struct sas_rphy *rphy)
else
lun = 0;
scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun, 0);
scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id, lun,
SCSI_SCAN_INITIAL);
}
return 0;
@ -1739,8 +1740,8 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel,
if ((channel == SCAN_WILD_CARD || channel == 0) &&
(id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) {
scsi_scan_target(&rphy->dev, 0,
rphy->scsi_target_id, lun, 1);
scsi_scan_target(&rphy->dev, 0, rphy->scsi_target_id,
lun, SCSI_SCAN_MANUAL);
}
}
mutex_unlock(&sas_host->lock);

826
drivers/scsi/sense_codes.h Normal file
View file

@ -0,0 +1,826 @@
/*
* The canonical list of T10 Additional Sense Codes is available at:
* http://www.t10.org/lists/asc-num.txt [most recent: 20141221]
*/
SENSE_CODE(0x0000, "No additional sense information")
SENSE_CODE(0x0001, "Filemark detected")
SENSE_CODE(0x0002, "End-of-partition/medium detected")
SENSE_CODE(0x0003, "Setmark detected")
SENSE_CODE(0x0004, "Beginning-of-partition/medium detected")
SENSE_CODE(0x0005, "End-of-data detected")
SENSE_CODE(0x0006, "I/O process terminated")
SENSE_CODE(0x0007, "Programmable early warning detected")
SENSE_CODE(0x0011, "Audio play operation in progress")
SENSE_CODE(0x0012, "Audio play operation paused")
SENSE_CODE(0x0013, "Audio play operation successfully completed")
SENSE_CODE(0x0014, "Audio play operation stopped due to error")
SENSE_CODE(0x0015, "No current audio status to return")
SENSE_CODE(0x0016, "Operation in progress")
SENSE_CODE(0x0017, "Cleaning requested")
SENSE_CODE(0x0018, "Erase operation in progress")
SENSE_CODE(0x0019, "Locate operation in progress")
SENSE_CODE(0x001A, "Rewind operation in progress")
SENSE_CODE(0x001B, "Set capacity operation in progress")
SENSE_CODE(0x001C, "Verify operation in progress")
SENSE_CODE(0x001D, "ATA pass through information available")
SENSE_CODE(0x001E, "Conflicting SA creation request")
SENSE_CODE(0x001F, "Logical unit transitioning to another power condition")
SENSE_CODE(0x0020, "Extended copy information available")
SENSE_CODE(0x0021, "Atomic command aborted due to ACA")
SENSE_CODE(0x0100, "No index/sector signal")
SENSE_CODE(0x0200, "No seek complete")
SENSE_CODE(0x0300, "Peripheral device write fault")
SENSE_CODE(0x0301, "No write current")
SENSE_CODE(0x0302, "Excessive write errors")
SENSE_CODE(0x0400, "Logical unit not ready, cause not reportable")
SENSE_CODE(0x0401, "Logical unit is in process of becoming ready")
SENSE_CODE(0x0402, "Logical unit not ready, initializing command required")
SENSE_CODE(0x0403, "Logical unit not ready, manual intervention required")
SENSE_CODE(0x0404, "Logical unit not ready, format in progress")
SENSE_CODE(0x0405, "Logical unit not ready, rebuild in progress")
SENSE_CODE(0x0406, "Logical unit not ready, recalculation in progress")
SENSE_CODE(0x0407, "Logical unit not ready, operation in progress")
SENSE_CODE(0x0408, "Logical unit not ready, long write in progress")
SENSE_CODE(0x0409, "Logical unit not ready, self-test in progress")
SENSE_CODE(0x040A, "Logical unit not accessible, asymmetric access state transition")
SENSE_CODE(0x040B, "Logical unit not accessible, target port in standby state")
SENSE_CODE(0x040C, "Logical unit not accessible, target port in unavailable state")
SENSE_CODE(0x040D, "Logical unit not ready, structure check required")
SENSE_CODE(0x040E, "Logical unit not ready, security session in progress")
SENSE_CODE(0x0410, "Logical unit not ready, auxiliary memory not accessible")
SENSE_CODE(0x0411, "Logical unit not ready, notify (enable spinup) required")
SENSE_CODE(0x0412, "Logical unit not ready, offline")
SENSE_CODE(0x0413, "Logical unit not ready, SA creation in progress")
SENSE_CODE(0x0414, "Logical unit not ready, space allocation in progress")
SENSE_CODE(0x0415, "Logical unit not ready, robotics disabled")
SENSE_CODE(0x0416, "Logical unit not ready, configuration required")
SENSE_CODE(0x0417, "Logical unit not ready, calibration required")
SENSE_CODE(0x0418, "Logical unit not ready, a door is open")
SENSE_CODE(0x0419, "Logical unit not ready, operating in sequential mode")
SENSE_CODE(0x041A, "Logical unit not ready, start stop unit command in progress")
SENSE_CODE(0x041B, "Logical unit not ready, sanitize in progress")
SENSE_CODE(0x041C, "Logical unit not ready, additional power use not yet granted")
SENSE_CODE(0x041D, "Logical unit not ready, configuration in progress")
SENSE_CODE(0x041E, "Logical unit not ready, microcode activation required")
SENSE_CODE(0x041F, "Logical unit not ready, microcode download required")
SENSE_CODE(0x0420, "Logical unit not ready, logical unit reset required")
SENSE_CODE(0x0421, "Logical unit not ready, hard reset required")
SENSE_CODE(0x0422, "Logical unit not ready, power cycle required")
SENSE_CODE(0x0500, "Logical unit does not respond to selection")
SENSE_CODE(0x0600, "No reference position found")
SENSE_CODE(0x0700, "Multiple peripheral devices selected")
SENSE_CODE(0x0800, "Logical unit communication failure")
SENSE_CODE(0x0801, "Logical unit communication time-out")
SENSE_CODE(0x0802, "Logical unit communication parity error")
SENSE_CODE(0x0803, "Logical unit communication CRC error (Ultra-DMA/32)")
SENSE_CODE(0x0804, "Unreachable copy target")
SENSE_CODE(0x0900, "Track following error")
SENSE_CODE(0x0901, "Tracking servo failure")
SENSE_CODE(0x0902, "Focus servo failure")
SENSE_CODE(0x0903, "Spindle servo failure")
SENSE_CODE(0x0904, "Head select fault")
SENSE_CODE(0x0905, "Vibration induced tracking error")
SENSE_CODE(0x0A00, "Error log overflow")
SENSE_CODE(0x0B00, "Warning")
SENSE_CODE(0x0B01, "Warning - specified temperature exceeded")
SENSE_CODE(0x0B02, "Warning - enclosure degraded")
SENSE_CODE(0x0B03, "Warning - background self-test failed")
SENSE_CODE(0x0B04, "Warning - background pre-scan detected medium error")
SENSE_CODE(0x0B05, "Warning - background medium scan detected medium error")
SENSE_CODE(0x0B06, "Warning - non-volatile cache now volatile")
SENSE_CODE(0x0B07, "Warning - degraded power to non-volatile cache")
SENSE_CODE(0x0B08, "Warning - power loss expected")
SENSE_CODE(0x0B09, "Warning - device statistics notification active")
SENSE_CODE(0x0C00, "Write error")
SENSE_CODE(0x0C01, "Write error - recovered with auto reallocation")
SENSE_CODE(0x0C02, "Write error - auto reallocation failed")
SENSE_CODE(0x0C03, "Write error - recommend reassignment")
SENSE_CODE(0x0C04, "Compression check miscompare error")
SENSE_CODE(0x0C05, "Data expansion occurred during compression")
SENSE_CODE(0x0C06, "Block not compressible")
SENSE_CODE(0x0C07, "Write error - recovery needed")
SENSE_CODE(0x0C08, "Write error - recovery failed")
SENSE_CODE(0x0C09, "Write error - loss of streaming")
SENSE_CODE(0x0C0A, "Write error - padding blocks added")
SENSE_CODE(0x0C0B, "Auxiliary memory write error")
SENSE_CODE(0x0C0C, "Write error - unexpected unsolicited data")
SENSE_CODE(0x0C0D, "Write error - not enough unsolicited data")
SENSE_CODE(0x0C0E, "Multiple write errors")
SENSE_CODE(0x0C0F, "Defects in error window")
SENSE_CODE(0x0C10, "Incomplete multiple atomic write operations")
SENSE_CODE(0x0D00, "Error detected by third party temporary initiator")
SENSE_CODE(0x0D01, "Third party device failure")
SENSE_CODE(0x0D02, "Copy target device not reachable")
SENSE_CODE(0x0D03, "Incorrect copy target device type")
SENSE_CODE(0x0D04, "Copy target device data underrun")
SENSE_CODE(0x0D05, "Copy target device data overrun")
SENSE_CODE(0x0E00, "Invalid information unit")
SENSE_CODE(0x0E01, "Information unit too short")
SENSE_CODE(0x0E02, "Information unit too long")
SENSE_CODE(0x0E03, "Invalid field in command information unit")
SENSE_CODE(0x1000, "Id CRC or ECC error")
SENSE_CODE(0x1001, "Logical block guard check failed")
SENSE_CODE(0x1002, "Logical block application tag check failed")
SENSE_CODE(0x1003, "Logical block reference tag check failed")
SENSE_CODE(0x1004, "Logical block protection error on recover buffered data")
SENSE_CODE(0x1005, "Logical block protection method error")
SENSE_CODE(0x1100, "Unrecovered read error")
SENSE_CODE(0x1101, "Read retries exhausted")
SENSE_CODE(0x1102, "Error too long to correct")
SENSE_CODE(0x1103, "Multiple read errors")
SENSE_CODE(0x1104, "Unrecovered read error - auto reallocate failed")
SENSE_CODE(0x1105, "L-EC uncorrectable error")
SENSE_CODE(0x1106, "CIRC unrecovered error")
SENSE_CODE(0x1107, "Data re-synchronization error")
SENSE_CODE(0x1108, "Incomplete block read")
SENSE_CODE(0x1109, "No gap found")
SENSE_CODE(0x110A, "Miscorrected error")
SENSE_CODE(0x110B, "Unrecovered read error - recommend reassignment")
SENSE_CODE(0x110C, "Unrecovered read error - recommend rewrite the data")
SENSE_CODE(0x110D, "De-compression CRC error")
SENSE_CODE(0x110E, "Cannot decompress using declared algorithm")
SENSE_CODE(0x110F, "Error reading UPC/EAN number")
SENSE_CODE(0x1110, "Error reading ISRC number")
SENSE_CODE(0x1111, "Read error - loss of streaming")
SENSE_CODE(0x1112, "Auxiliary memory read error")
SENSE_CODE(0x1113, "Read error - failed retransmission request")
SENSE_CODE(0x1114, "Read error - lba marked bad by application client")
SENSE_CODE(0x1115, "Write after sanitize required")
SENSE_CODE(0x1200, "Address mark not found for id field")
SENSE_CODE(0x1300, "Address mark not found for data field")
SENSE_CODE(0x1400, "Recorded entity not found")
SENSE_CODE(0x1401, "Record not found")
SENSE_CODE(0x1402, "Filemark or setmark not found")
SENSE_CODE(0x1403, "End-of-data not found")
SENSE_CODE(0x1404, "Block sequence error")
SENSE_CODE(0x1405, "Record not found - recommend reassignment")
SENSE_CODE(0x1406, "Record not found - data auto-reallocated")
SENSE_CODE(0x1407, "Locate operation failure")
SENSE_CODE(0x1500, "Random positioning error")
SENSE_CODE(0x1501, "Mechanical positioning error")
SENSE_CODE(0x1502, "Positioning error detected by read of medium")
SENSE_CODE(0x1600, "Data synchronization mark error")
SENSE_CODE(0x1601, "Data sync error - data rewritten")
SENSE_CODE(0x1602, "Data sync error - recommend rewrite")
SENSE_CODE(0x1603, "Data sync error - data auto-reallocated")
SENSE_CODE(0x1604, "Data sync error - recommend reassignment")
SENSE_CODE(0x1700, "Recovered data with no error correction applied")
SENSE_CODE(0x1701, "Recovered data with retries")
SENSE_CODE(0x1702, "Recovered data with positive head offset")
SENSE_CODE(0x1703, "Recovered data with negative head offset")
SENSE_CODE(0x1704, "Recovered data with retries and/or circ applied")
SENSE_CODE(0x1705, "Recovered data using previous sector id")
SENSE_CODE(0x1706, "Recovered data without ECC - data auto-reallocated")
SENSE_CODE(0x1707, "Recovered data without ECC - recommend reassignment")
SENSE_CODE(0x1708, "Recovered data without ECC - recommend rewrite")
SENSE_CODE(0x1709, "Recovered data without ECC - data rewritten")
SENSE_CODE(0x1800, "Recovered data with error correction applied")
SENSE_CODE(0x1801, "Recovered data with error corr. & retries applied")
SENSE_CODE(0x1802, "Recovered data - data auto-reallocated")
SENSE_CODE(0x1803, "Recovered data with CIRC")
SENSE_CODE(0x1804, "Recovered data with L-EC")
SENSE_CODE(0x1805, "Recovered data - recommend reassignment")
SENSE_CODE(0x1806, "Recovered data - recommend rewrite")
SENSE_CODE(0x1807, "Recovered data with ECC - data rewritten")
SENSE_CODE(0x1808, "Recovered data with linking")
SENSE_CODE(0x1900, "Defect list error")
SENSE_CODE(0x1901, "Defect list not available")
SENSE_CODE(0x1902, "Defect list error in primary list")
SENSE_CODE(0x1903, "Defect list error in grown list")
SENSE_CODE(0x1A00, "Parameter list length error")
SENSE_CODE(0x1B00, "Synchronous data transfer error")
SENSE_CODE(0x1C00, "Defect list not found")
SENSE_CODE(0x1C01, "Primary defect list not found")
SENSE_CODE(0x1C02, "Grown defect list not found")
SENSE_CODE(0x1D00, "Miscompare during verify operation")
SENSE_CODE(0x1D01, "Miscompare verify of unmapped LBA")
SENSE_CODE(0x1E00, "Recovered id with ECC correction")
SENSE_CODE(0x1F00, "Partial defect list transfer")
SENSE_CODE(0x2000, "Invalid command operation code")
SENSE_CODE(0x2001, "Access denied - initiator pending-enrolled")
SENSE_CODE(0x2002, "Access denied - no access rights")
SENSE_CODE(0x2003, "Access denied - invalid mgmt id key")
SENSE_CODE(0x2004, "Illegal command while in write capable state")
SENSE_CODE(0x2005, "Obsolete")
SENSE_CODE(0x2006, "Illegal command while in explicit address mode")
SENSE_CODE(0x2007, "Illegal command while in implicit address mode")
SENSE_CODE(0x2008, "Access denied - enrollment conflict")
SENSE_CODE(0x2009, "Access denied - invalid LU identifier")
SENSE_CODE(0x200A, "Access denied - invalid proxy token")
SENSE_CODE(0x200B, "Access denied - ACL LUN conflict")
SENSE_CODE(0x200C, "Illegal command when not in append-only mode")
SENSE_CODE(0x2100, "Logical block address out of range")
SENSE_CODE(0x2101, "Invalid element address")
SENSE_CODE(0x2102, "Invalid address for write")
SENSE_CODE(0x2103, "Invalid write crossing layer jump")
SENSE_CODE(0x2104, "Unaligned write command")
SENSE_CODE(0x2105, "Write boundary violation")
SENSE_CODE(0x2106, "Attempt to read invalid data")
SENSE_CODE(0x2107, "Read boundary violation")
SENSE_CODE(0x2200, "Illegal function (use 20 00, 24 00, or 26 00)")
SENSE_CODE(0x2300, "Invalid token operation, cause not reportable")
SENSE_CODE(0x2301, "Invalid token operation, unsupported token type")
SENSE_CODE(0x2302, "Invalid token operation, remote token usage not supported")
SENSE_CODE(0x2303, "Invalid token operation, remote rod token creation not supported")
SENSE_CODE(0x2304, "Invalid token operation, token unknown")
SENSE_CODE(0x2305, "Invalid token operation, token corrupt")
SENSE_CODE(0x2306, "Invalid token operation, token revoked")
SENSE_CODE(0x2307, "Invalid token operation, token expired")
SENSE_CODE(0x2308, "Invalid token operation, token cancelled")
SENSE_CODE(0x2309, "Invalid token operation, token deleted")
SENSE_CODE(0x230A, "Invalid token operation, invalid token length")
SENSE_CODE(0x2400, "Invalid field in cdb")
SENSE_CODE(0x2401, "CDB decryption error")
SENSE_CODE(0x2402, "Obsolete")
SENSE_CODE(0x2403, "Obsolete")
SENSE_CODE(0x2404, "Security audit value frozen")
SENSE_CODE(0x2405, "Security working key frozen")
SENSE_CODE(0x2406, "Nonce not unique")
SENSE_CODE(0x2407, "Nonce timestamp out of range")
SENSE_CODE(0x2408, "Invalid XCDB")
SENSE_CODE(0x2500, "Logical unit not supported")
SENSE_CODE(0x2600, "Invalid field in parameter list")
SENSE_CODE(0x2601, "Parameter not supported")
SENSE_CODE(0x2602, "Parameter value invalid")
SENSE_CODE(0x2603, "Threshold parameters not supported")
SENSE_CODE(0x2604, "Invalid release of persistent reservation")
SENSE_CODE(0x2605, "Data decryption error")
SENSE_CODE(0x2606, "Too many target descriptors")
SENSE_CODE(0x2607, "Unsupported target descriptor type code")
SENSE_CODE(0x2608, "Too many segment descriptors")
SENSE_CODE(0x2609, "Unsupported segment descriptor type code")
SENSE_CODE(0x260A, "Unexpected inexact segment")
SENSE_CODE(0x260B, "Inline data length exceeded")
SENSE_CODE(0x260C, "Invalid operation for copy source or destination")
SENSE_CODE(0x260D, "Copy segment granularity violation")
SENSE_CODE(0x260E, "Invalid parameter while port is enabled")
SENSE_CODE(0x260F, "Invalid data-out buffer integrity check value")
SENSE_CODE(0x2610, "Data decryption key fail limit reached")
SENSE_CODE(0x2611, "Incomplete key-associated data set")
SENSE_CODE(0x2612, "Vendor specific key reference not found")
SENSE_CODE(0x2700, "Write protected")
SENSE_CODE(0x2701, "Hardware write protected")
SENSE_CODE(0x2702, "Logical unit software write protected")
SENSE_CODE(0x2703, "Associated write protect")
SENSE_CODE(0x2704, "Persistent write protect")
SENSE_CODE(0x2705, "Permanent write protect")
SENSE_CODE(0x2706, "Conditional write protect")
SENSE_CODE(0x2707, "Space allocation failed write protect")
SENSE_CODE(0x2708, "Zone is read only")
SENSE_CODE(0x2800, "Not ready to ready change, medium may have changed")
SENSE_CODE(0x2801, "Import or export element accessed")
SENSE_CODE(0x2802, "Format-layer may have changed")
SENSE_CODE(0x2803, "Import/export element accessed, medium changed")
SENSE_CODE(0x2900, "Power on, reset, or bus device reset occurred")
SENSE_CODE(0x2901, "Power on occurred")
SENSE_CODE(0x2902, "Scsi bus reset occurred")
SENSE_CODE(0x2903, "Bus device reset function occurred")
SENSE_CODE(0x2904, "Device internal reset")
SENSE_CODE(0x2905, "Transceiver mode changed to single-ended")
SENSE_CODE(0x2906, "Transceiver mode changed to lvd")
SENSE_CODE(0x2907, "I_T nexus loss occurred")
SENSE_CODE(0x2A00, "Parameters changed")
SENSE_CODE(0x2A01, "Mode parameters changed")
SENSE_CODE(0x2A02, "Log parameters changed")
SENSE_CODE(0x2A03, "Reservations preempted")
SENSE_CODE(0x2A04, "Reservations released")
SENSE_CODE(0x2A05, "Registrations preempted")
SENSE_CODE(0x2A06, "Asymmetric access state changed")
SENSE_CODE(0x2A07, "Implicit asymmetric access state transition failed")
SENSE_CODE(0x2A08, "Priority changed")
SENSE_CODE(0x2A09, "Capacity data has changed")
SENSE_CODE(0x2A0A, "Error history I_T nexus cleared")
SENSE_CODE(0x2A0B, "Error history snapshot released")
SENSE_CODE(0x2A0C, "Error recovery attributes have changed")
SENSE_CODE(0x2A0D, "Data encryption capabilities changed")
SENSE_CODE(0x2A10, "Timestamp changed")
SENSE_CODE(0x2A11, "Data encryption parameters changed by another i_t nexus")
SENSE_CODE(0x2A12, "Data encryption parameters changed by vendor specific event")
SENSE_CODE(0x2A13, "Data encryption key instance counter has changed")
SENSE_CODE(0x2A14, "SA creation capabilities data has changed")
SENSE_CODE(0x2A15, "Medium removal prevention preempted")
SENSE_CODE(0x2B00, "Copy cannot execute since host cannot disconnect")
SENSE_CODE(0x2C00, "Command sequence error")
SENSE_CODE(0x2C01, "Too many windows specified")
SENSE_CODE(0x2C02, "Invalid combination of windows specified")
SENSE_CODE(0x2C03, "Current program area is not empty")
SENSE_CODE(0x2C04, "Current program area is empty")
SENSE_CODE(0x2C05, "Illegal power condition request")
SENSE_CODE(0x2C06, "Persistent prevent conflict")
SENSE_CODE(0x2C07, "Previous busy status")
SENSE_CODE(0x2C08, "Previous task set full status")
SENSE_CODE(0x2C09, "Previous reservation conflict status")
SENSE_CODE(0x2C0A, "Partition or collection contains user objects")
SENSE_CODE(0x2C0B, "Not reserved")
SENSE_CODE(0x2C0C, "Orwrite generation does not match")
SENSE_CODE(0x2C0D, "Reset write pointer not allowed")
SENSE_CODE(0x2C0E, "Zone is offline")
SENSE_CODE(0x2D00, "Overwrite error on update in place")
SENSE_CODE(0x2E00, "Insufficient time for operation")
SENSE_CODE(0x2E01, "Command timeout before processing")
SENSE_CODE(0x2E02, "Command timeout during processing")
SENSE_CODE(0x2E03, "Command timeout during processing due to error recovery")
SENSE_CODE(0x2F00, "Commands cleared by another initiator")
SENSE_CODE(0x2F01, "Commands cleared by power loss notification")
SENSE_CODE(0x2F02, "Commands cleared by device server")
SENSE_CODE(0x2F03, "Some commands cleared by queuing layer event")
SENSE_CODE(0x3000, "Incompatible medium installed")
SENSE_CODE(0x3001, "Cannot read medium - unknown format")
SENSE_CODE(0x3002, "Cannot read medium - incompatible format")
SENSE_CODE(0x3003, "Cleaning cartridge installed")
SENSE_CODE(0x3004, "Cannot write medium - unknown format")
SENSE_CODE(0x3005, "Cannot write medium - incompatible format")
SENSE_CODE(0x3006, "Cannot format medium - incompatible medium")
SENSE_CODE(0x3007, "Cleaning failure")
SENSE_CODE(0x3008, "Cannot write - application code mismatch")
SENSE_CODE(0x3009, "Current session not fixated for append")
SENSE_CODE(0x300A, "Cleaning request rejected")
SENSE_CODE(0x300C, "WORM medium - overwrite attempted")
SENSE_CODE(0x300D, "WORM medium - integrity check")
SENSE_CODE(0x3010, "Medium not formatted")
SENSE_CODE(0x3011, "Incompatible volume type")
SENSE_CODE(0x3012, "Incompatible volume qualifier")
SENSE_CODE(0x3013, "Cleaning volume expired")
SENSE_CODE(0x3100, "Medium format corrupted")
SENSE_CODE(0x3101, "Format command failed")
SENSE_CODE(0x3102, "Zoned formatting failed due to spare linking")
SENSE_CODE(0x3103, "Sanitize command failed")
SENSE_CODE(0x3200, "No defect spare location available")
SENSE_CODE(0x3201, "Defect list update failure")
SENSE_CODE(0x3300, "Tape length error")
SENSE_CODE(0x3400, "Enclosure failure")
SENSE_CODE(0x3500, "Enclosure services failure")
SENSE_CODE(0x3501, "Unsupported enclosure function")
SENSE_CODE(0x3502, "Enclosure services unavailable")
SENSE_CODE(0x3503, "Enclosure services transfer failure")
SENSE_CODE(0x3504, "Enclosure services transfer refused")
SENSE_CODE(0x3505, "Enclosure services checksum error")
SENSE_CODE(0x3600, "Ribbon, ink, or toner failure")
SENSE_CODE(0x3700, "Rounded parameter")
SENSE_CODE(0x3800, "Event status notification")
SENSE_CODE(0x3802, "Esn - power management class event")
SENSE_CODE(0x3804, "Esn - media class event")
SENSE_CODE(0x3806, "Esn - device busy class event")
SENSE_CODE(0x3807, "Thin Provisioning soft threshold reached")
SENSE_CODE(0x3900, "Saving parameters not supported")
SENSE_CODE(0x3A00, "Medium not present")
SENSE_CODE(0x3A01, "Medium not present - tray closed")
SENSE_CODE(0x3A02, "Medium not present - tray open")
SENSE_CODE(0x3A03, "Medium not present - loadable")
SENSE_CODE(0x3A04, "Medium not present - medium auxiliary memory accessible")
SENSE_CODE(0x3B00, "Sequential positioning error")
SENSE_CODE(0x3B01, "Tape position error at beginning-of-medium")
SENSE_CODE(0x3B02, "Tape position error at end-of-medium")
SENSE_CODE(0x3B03, "Tape or electronic vertical forms unit not ready")
SENSE_CODE(0x3B04, "Slew failure")
SENSE_CODE(0x3B05, "Paper jam")
SENSE_CODE(0x3B06, "Failed to sense top-of-form")
SENSE_CODE(0x3B07, "Failed to sense bottom-of-form")
SENSE_CODE(0x3B08, "Reposition error")
SENSE_CODE(0x3B09, "Read past end of medium")
SENSE_CODE(0x3B0A, "Read past beginning of medium")
SENSE_CODE(0x3B0B, "Position past end of medium")
SENSE_CODE(0x3B0C, "Position past beginning of medium")
SENSE_CODE(0x3B0D, "Medium destination element full")
SENSE_CODE(0x3B0E, "Medium source element empty")
SENSE_CODE(0x3B0F, "End of medium reached")
SENSE_CODE(0x3B11, "Medium magazine not accessible")
SENSE_CODE(0x3B12, "Medium magazine removed")
SENSE_CODE(0x3B13, "Medium magazine inserted")
SENSE_CODE(0x3B14, "Medium magazine locked")
SENSE_CODE(0x3B15, "Medium magazine unlocked")
SENSE_CODE(0x3B16, "Mechanical positioning or changer error")
SENSE_CODE(0x3B17, "Read past end of user object")
SENSE_CODE(0x3B18, "Element disabled")
SENSE_CODE(0x3B19, "Element enabled")
SENSE_CODE(0x3B1A, "Data transfer device removed")
SENSE_CODE(0x3B1B, "Data transfer device inserted")
SENSE_CODE(0x3B1C, "Too many logical objects on partition to support operation")
SENSE_CODE(0x3D00, "Invalid bits in identify message")
SENSE_CODE(0x3E00, "Logical unit has not self-configured yet")
SENSE_CODE(0x3E01, "Logical unit failure")
SENSE_CODE(0x3E02, "Timeout on logical unit")
SENSE_CODE(0x3E03, "Logical unit failed self-test")
SENSE_CODE(0x3E04, "Logical unit unable to update self-test log")
SENSE_CODE(0x3F00, "Target operating conditions have changed")
SENSE_CODE(0x3F01, "Microcode has been changed")
SENSE_CODE(0x3F02, "Changed operating definition")
SENSE_CODE(0x3F03, "Inquiry data has changed")
SENSE_CODE(0x3F04, "Component device attached")
SENSE_CODE(0x3F05, "Device identifier changed")
SENSE_CODE(0x3F06, "Redundancy group created or modified")
SENSE_CODE(0x3F07, "Redundancy group deleted")
SENSE_CODE(0x3F08, "Spare created or modified")
SENSE_CODE(0x3F09, "Spare deleted")
SENSE_CODE(0x3F0A, "Volume set created or modified")
SENSE_CODE(0x3F0B, "Volume set deleted")
SENSE_CODE(0x3F0C, "Volume set deassigned")
SENSE_CODE(0x3F0D, "Volume set reassigned")
SENSE_CODE(0x3F0E, "Reported luns data has changed")
SENSE_CODE(0x3F0F, "Echo buffer overwritten")
SENSE_CODE(0x3F10, "Medium loadable")
SENSE_CODE(0x3F11, "Medium auxiliary memory accessible")
SENSE_CODE(0x3F12, "iSCSI IP address added")
SENSE_CODE(0x3F13, "iSCSI IP address removed")
SENSE_CODE(0x3F14, "iSCSI IP address changed")
SENSE_CODE(0x3F15, "Inspect referrals sense descriptors")
SENSE_CODE(0x3F16, "Microcode has been changed without reset")
/*
* SENSE_CODE(0x40NN, "Ram failure")
* SENSE_CODE(0x40NN, "Diagnostic failure on component nn")
* SENSE_CODE(0x41NN, "Data path failure")
* SENSE_CODE(0x42NN, "Power-on or self-test failure")
*/
SENSE_CODE(0x4300, "Message error")
SENSE_CODE(0x4400, "Internal target failure")
SENSE_CODE(0x4401, "Persistent reservation information lost")
SENSE_CODE(0x4471, "ATA device failed set features")
SENSE_CODE(0x4500, "Select or reselect failure")
SENSE_CODE(0x4600, "Unsuccessful soft reset")
SENSE_CODE(0x4700, "Scsi parity error")
SENSE_CODE(0x4701, "Data phase CRC error detected")
SENSE_CODE(0x4702, "Scsi parity error detected during st data phase")
SENSE_CODE(0x4703, "Information unit iuCRC error detected")
SENSE_CODE(0x4704, "Asynchronous information protection error detected")
SENSE_CODE(0x4705, "Protocol service CRC error")
SENSE_CODE(0x4706, "Phy test function in progress")
SENSE_CODE(0x477f, "Some commands cleared by iSCSI Protocol event")
SENSE_CODE(0x4800, "Initiator detected error message received")
SENSE_CODE(0x4900, "Invalid message error")
SENSE_CODE(0x4A00, "Command phase error")
SENSE_CODE(0x4B00, "Data phase error")
SENSE_CODE(0x4B01, "Invalid target port transfer tag received")
SENSE_CODE(0x4B02, "Too much write data")
SENSE_CODE(0x4B03, "Ack/nak timeout")
SENSE_CODE(0x4B04, "Nak received")
SENSE_CODE(0x4B05, "Data offset error")
SENSE_CODE(0x4B06, "Initiator response timeout")
SENSE_CODE(0x4B07, "Connection lost")
SENSE_CODE(0x4B08, "Data-in buffer overflow - data buffer size")
SENSE_CODE(0x4B09, "Data-in buffer overflow - data buffer descriptor area")
SENSE_CODE(0x4B0A, "Data-in buffer error")
SENSE_CODE(0x4B0B, "Data-out buffer overflow - data buffer size")
SENSE_CODE(0x4B0C, "Data-out buffer overflow - data buffer descriptor area")
SENSE_CODE(0x4B0D, "Data-out buffer error")
SENSE_CODE(0x4B0E, "PCIe fabric error")
SENSE_CODE(0x4B0F, "PCIe completion timeout")
SENSE_CODE(0x4B10, "PCIe completer abort")
SENSE_CODE(0x4B11, "PCIe poisoned tlp received")
SENSE_CODE(0x4B12, "PCIe eCRC check failed")
SENSE_CODE(0x4B13, "PCIe unsupported request")
SENSE_CODE(0x4B14, "PCIe acs violation")
SENSE_CODE(0x4B15, "PCIe tlp prefix blocked")
SENSE_CODE(0x4C00, "Logical unit failed self-configuration")
/*
* SENSE_CODE(0x4DNN, "Tagged overlapped commands (nn = queue tag)")
*/
SENSE_CODE(0x4E00, "Overlapped commands attempted")
SENSE_CODE(0x5000, "Write append error")
SENSE_CODE(0x5001, "Write append position error")
SENSE_CODE(0x5002, "Position error related to timing")
SENSE_CODE(0x5100, "Erase failure")
SENSE_CODE(0x5101, "Erase failure - incomplete erase operation detected")
SENSE_CODE(0x5200, "Cartridge fault")
SENSE_CODE(0x5300, "Media load or eject failed")
SENSE_CODE(0x5301, "Unload tape failure")
SENSE_CODE(0x5302, "Medium removal prevented")
SENSE_CODE(0x5303, "Medium removal prevented by data transfer element")
SENSE_CODE(0x5304, "Medium thread or unthread failure")
SENSE_CODE(0x5305, "Volume identifier invalid")
SENSE_CODE(0x5306, "Volume identifier missing")
SENSE_CODE(0x5307, "Duplicate volume identifier")
SENSE_CODE(0x5308, "Element status unknown")
SENSE_CODE(0x5309, "Data transfer device error - load failed")
SENSE_CODE(0x530a, "Data transfer device error - unload failed")
SENSE_CODE(0x530b, "Data transfer device error - unload missing")
SENSE_CODE(0x530c, "Data transfer device error - eject failed")
SENSE_CODE(0x530d, "Data transfer device error - library communication failed")
SENSE_CODE(0x5400, "Scsi to host system interface failure")
SENSE_CODE(0x5500, "System resource failure")
SENSE_CODE(0x5501, "System buffer full")
SENSE_CODE(0x5502, "Insufficient reservation resources")
SENSE_CODE(0x5503, "Insufficient resources")
SENSE_CODE(0x5504, "Insufficient registration resources")
SENSE_CODE(0x5505, "Insufficient access control resources")
SENSE_CODE(0x5506, "Auxiliary memory out of space")
SENSE_CODE(0x5507, "Quota error")
SENSE_CODE(0x5508, "Maximum number of supplemental decryption keys exceeded")
SENSE_CODE(0x5509, "Medium auxiliary memory not accessible")
SENSE_CODE(0x550A, "Data currently unavailable")
SENSE_CODE(0x550B, "Insufficient power for operation")
SENSE_CODE(0x550C, "Insufficient resources to create rod")
SENSE_CODE(0x550D, "Insufficient resources to create rod token")
SENSE_CODE(0x550E, "Insufficient zone resources")
SENSE_CODE(0x5700, "Unable to recover table-of-contents")
SENSE_CODE(0x5800, "Generation does not exist")
SENSE_CODE(0x5900, "Updated block read")
SENSE_CODE(0x5A00, "Operator request or state change input")
SENSE_CODE(0x5A01, "Operator medium removal request")
SENSE_CODE(0x5A02, "Operator selected write protect")
SENSE_CODE(0x5A03, "Operator selected write permit")
SENSE_CODE(0x5B00, "Log exception")
SENSE_CODE(0x5B01, "Threshold condition met")
SENSE_CODE(0x5B02, "Log counter at maximum")
SENSE_CODE(0x5B03, "Log list codes exhausted")
SENSE_CODE(0x5C00, "Rpl status change")
SENSE_CODE(0x5C01, "Spindles synchronized")
SENSE_CODE(0x5C02, "Spindles not synchronized")
SENSE_CODE(0x5D00, "Failure prediction threshold exceeded")
SENSE_CODE(0x5D01, "Media failure prediction threshold exceeded")
SENSE_CODE(0x5D02, "Logical unit failure prediction threshold exceeded")
SENSE_CODE(0x5D03, "Spare area exhaustion prediction threshold exceeded")
SENSE_CODE(0x5D10, "Hardware impending failure general hard drive failure")
SENSE_CODE(0x5D11, "Hardware impending failure drive error rate too high")
SENSE_CODE(0x5D12, "Hardware impending failure data error rate too high")
SENSE_CODE(0x5D13, "Hardware impending failure seek error rate too high")
SENSE_CODE(0x5D14, "Hardware impending failure too many block reassigns")
SENSE_CODE(0x5D15, "Hardware impending failure access times too high")
SENSE_CODE(0x5D16, "Hardware impending failure start unit times too high")
SENSE_CODE(0x5D17, "Hardware impending failure channel parametrics")
SENSE_CODE(0x5D18, "Hardware impending failure controller detected")
SENSE_CODE(0x5D19, "Hardware impending failure throughput performance")
SENSE_CODE(0x5D1A, "Hardware impending failure seek time performance")
SENSE_CODE(0x5D1B, "Hardware impending failure spin-up retry count")
SENSE_CODE(0x5D1C, "Hardware impending failure drive calibration retry count")
SENSE_CODE(0x5D20, "Controller impending failure general hard drive failure")
SENSE_CODE(0x5D21, "Controller impending failure drive error rate too high")
SENSE_CODE(0x5D22, "Controller impending failure data error rate too high")
SENSE_CODE(0x5D23, "Controller impending failure seek error rate too high")
SENSE_CODE(0x5D24, "Controller impending failure too many block reassigns")
SENSE_CODE(0x5D25, "Controller impending failure access times too high")
SENSE_CODE(0x5D26, "Controller impending failure start unit times too high")
SENSE_CODE(0x5D27, "Controller impending failure channel parametrics")
SENSE_CODE(0x5D28, "Controller impending failure controller detected")
SENSE_CODE(0x5D29, "Controller impending failure throughput performance")
SENSE_CODE(0x5D2A, "Controller impending failure seek time performance")
SENSE_CODE(0x5D2B, "Controller impending failure spin-up retry count")
SENSE_CODE(0x5D2C, "Controller impending failure drive calibration retry count")
SENSE_CODE(0x5D30, "Data channel impending failure general hard drive failure")
SENSE_CODE(0x5D31, "Data channel impending failure drive error rate too high")
SENSE_CODE(0x5D32, "Data channel impending failure data error rate too high")
SENSE_CODE(0x5D33, "Data channel impending failure seek error rate too high")
SENSE_CODE(0x5D34, "Data channel impending failure too many block reassigns")
SENSE_CODE(0x5D35, "Data channel impending failure access times too high")
SENSE_CODE(0x5D36, "Data channel impending failure start unit times too high")
SENSE_CODE(0x5D37, "Data channel impending failure channel parametrics")
SENSE_CODE(0x5D38, "Data channel impending failure controller detected")
SENSE_CODE(0x5D39, "Data channel impending failure throughput performance")
SENSE_CODE(0x5D3A, "Data channel impending failure seek time performance")
SENSE_CODE(0x5D3B, "Data channel impending failure spin-up retry count")
SENSE_CODE(0x5D3C, "Data channel impending failure drive calibration retry count")
SENSE_CODE(0x5D40, "Servo impending failure general hard drive failure")
SENSE_CODE(0x5D41, "Servo impending failure drive error rate too high")
SENSE_CODE(0x5D42, "Servo impending failure data error rate too high")
SENSE_CODE(0x5D43, "Servo impending failure seek error rate too high")
SENSE_CODE(0x5D44, "Servo impending failure too many block reassigns")
SENSE_CODE(0x5D45, "Servo impending failure access times too high")
SENSE_CODE(0x5D46, "Servo impending failure start unit times too high")
SENSE_CODE(0x5D47, "Servo impending failure channel parametrics")
SENSE_CODE(0x5D48, "Servo impending failure controller detected")
SENSE_CODE(0x5D49, "Servo impending failure throughput performance")
SENSE_CODE(0x5D4A, "Servo impending failure seek time performance")
SENSE_CODE(0x5D4B, "Servo impending failure spin-up retry count")
SENSE_CODE(0x5D4C, "Servo impending failure drive calibration retry count")
SENSE_CODE(0x5D50, "Spindle impending failure general hard drive failure")
SENSE_CODE(0x5D51, "Spindle impending failure drive error rate too high")
SENSE_CODE(0x5D52, "Spindle impending failure data error rate too high")
SENSE_CODE(0x5D53, "Spindle impending failure seek error rate too high")
SENSE_CODE(0x5D54, "Spindle impending failure too many block reassigns")
SENSE_CODE(0x5D55, "Spindle impending failure access times too high")
SENSE_CODE(0x5D56, "Spindle impending failure start unit times too high")
SENSE_CODE(0x5D57, "Spindle impending failure channel parametrics")
SENSE_CODE(0x5D58, "Spindle impending failure controller detected")
SENSE_CODE(0x5D59, "Spindle impending failure throughput performance")
SENSE_CODE(0x5D5A, "Spindle impending failure seek time performance")
SENSE_CODE(0x5D5B, "Spindle impending failure spin-up retry count")
SENSE_CODE(0x5D5C, "Spindle impending failure drive calibration retry count")
SENSE_CODE(0x5D60, "Firmware impending failure general hard drive failure")
SENSE_CODE(0x5D61, "Firmware impending failure drive error rate too high")
SENSE_CODE(0x5D62, "Firmware impending failure data error rate too high")
SENSE_CODE(0x5D63, "Firmware impending failure seek error rate too high")
SENSE_CODE(0x5D64, "Firmware impending failure too many block reassigns")
SENSE_CODE(0x5D65, "Firmware impending failure access times too high")
SENSE_CODE(0x5D66, "Firmware impending failure start unit times too high")
SENSE_CODE(0x5D67, "Firmware impending failure channel parametrics")
SENSE_CODE(0x5D68, "Firmware impending failure controller detected")
SENSE_CODE(0x5D69, "Firmware impending failure throughput performance")
SENSE_CODE(0x5D6A, "Firmware impending failure seek time performance")
SENSE_CODE(0x5D6B, "Firmware impending failure spin-up retry count")
SENSE_CODE(0x5D6C, "Firmware impending failure drive calibration retry count")
SENSE_CODE(0x5DFF, "Failure prediction threshold exceeded (false)")
SENSE_CODE(0x5E00, "Low power condition on")
SENSE_CODE(0x5E01, "Idle condition activated by timer")
SENSE_CODE(0x5E02, "Standby condition activated by timer")
SENSE_CODE(0x5E03, "Idle condition activated by command")
SENSE_CODE(0x5E04, "Standby condition activated by command")
SENSE_CODE(0x5E05, "Idle_b condition activated by timer")
SENSE_CODE(0x5E06, "Idle_b condition activated by command")
SENSE_CODE(0x5E07, "Idle_c condition activated by timer")
SENSE_CODE(0x5E08, "Idle_c condition activated by command")
SENSE_CODE(0x5E09, "Standby_y condition activated by timer")
SENSE_CODE(0x5E0A, "Standby_y condition activated by command")
SENSE_CODE(0x5E41, "Power state change to active")
SENSE_CODE(0x5E42, "Power state change to idle")
SENSE_CODE(0x5E43, "Power state change to standby")
SENSE_CODE(0x5E45, "Power state change to sleep")
SENSE_CODE(0x5E47, "Power state change to device control")
SENSE_CODE(0x6000, "Lamp failure")
SENSE_CODE(0x6100, "Video acquisition error")
SENSE_CODE(0x6101, "Unable to acquire video")
SENSE_CODE(0x6102, "Out of focus")
SENSE_CODE(0x6200, "Scan head positioning error")
SENSE_CODE(0x6300, "End of user area encountered on this track")
SENSE_CODE(0x6301, "Packet does not fit in available space")
SENSE_CODE(0x6400, "Illegal mode for this track")
SENSE_CODE(0x6401, "Invalid packet size")
SENSE_CODE(0x6500, "Voltage fault")
SENSE_CODE(0x6600, "Automatic document feeder cover up")
SENSE_CODE(0x6601, "Automatic document feeder lift up")
SENSE_CODE(0x6602, "Document jam in automatic document feeder")
SENSE_CODE(0x6603, "Document miss feed automatic in document feeder")
SENSE_CODE(0x6700, "Configuration failure")
SENSE_CODE(0x6701, "Configuration of incapable logical units failed")
SENSE_CODE(0x6702, "Add logical unit failed")
SENSE_CODE(0x6703, "Modification of logical unit failed")
SENSE_CODE(0x6704, "Exchange of logical unit failed")
SENSE_CODE(0x6705, "Remove of logical unit failed")
SENSE_CODE(0x6706, "Attachment of logical unit failed")
SENSE_CODE(0x6707, "Creation of logical unit failed")
SENSE_CODE(0x6708, "Assign failure occurred")
SENSE_CODE(0x6709, "Multiply assigned logical unit")
SENSE_CODE(0x670A, "Set target port groups command failed")
SENSE_CODE(0x670B, "ATA device feature not enabled")
SENSE_CODE(0x6800, "Logical unit not configured")
SENSE_CODE(0x6801, "Subsidiary logical unit not configured")
SENSE_CODE(0x6900, "Data loss on logical unit")
SENSE_CODE(0x6901, "Multiple logical unit failures")
SENSE_CODE(0x6902, "Parity/data mismatch")
SENSE_CODE(0x6A00, "Informational, refer to log")
SENSE_CODE(0x6B00, "State change has occurred")
SENSE_CODE(0x6B01, "Redundancy level got better")
SENSE_CODE(0x6B02, "Redundancy level got worse")
SENSE_CODE(0x6C00, "Rebuild failure occurred")
SENSE_CODE(0x6D00, "Recalculate failure occurred")
SENSE_CODE(0x6E00, "Command to logical unit failed")
SENSE_CODE(0x6F00, "Copy protection key exchange failure - authentication failure")
SENSE_CODE(0x6F01, "Copy protection key exchange failure - key not present")
SENSE_CODE(0x6F02, "Copy protection key exchange failure - key not established")
SENSE_CODE(0x6F03, "Read of scrambled sector without authentication")
SENSE_CODE(0x6F04, "Media region code is mismatched to logical unit region")
SENSE_CODE(0x6F05, "Drive region must be permanent/region reset count error")
SENSE_CODE(0x6F06, "Insufficient block count for binding nonce recording")
SENSE_CODE(0x6F07, "Conflict in binding nonce recording")
/*
* SENSE_CODE(0x70NN, "Decompression exception short algorithm id of nn")
*/
SENSE_CODE(0x7100, "Decompression exception long algorithm id")
SENSE_CODE(0x7200, "Session fixation error")
SENSE_CODE(0x7201, "Session fixation error writing lead-in")
SENSE_CODE(0x7202, "Session fixation error writing lead-out")
SENSE_CODE(0x7203, "Session fixation error - incomplete track in session")
SENSE_CODE(0x7204, "Empty or partially written reserved track")
SENSE_CODE(0x7205, "No more track reservations allowed")
SENSE_CODE(0x7206, "RMZ extension is not allowed")
SENSE_CODE(0x7207, "No more test zone extensions are allowed")
SENSE_CODE(0x7300, "Cd control error")
SENSE_CODE(0x7301, "Power calibration area almost full")
SENSE_CODE(0x7302, "Power calibration area is full")
SENSE_CODE(0x7303, "Power calibration area error")
SENSE_CODE(0x7304, "Program memory area update failure")
SENSE_CODE(0x7305, "Program memory area is full")
SENSE_CODE(0x7306, "RMA/PMA is almost full")
SENSE_CODE(0x7310, "Current power calibration area almost full")
SENSE_CODE(0x7311, "Current power calibration area is full")
SENSE_CODE(0x7317, "RDZ is full")
SENSE_CODE(0x7400, "Security error")
SENSE_CODE(0x7401, "Unable to decrypt data")
SENSE_CODE(0x7402, "Unencrypted data encountered while decrypting")
SENSE_CODE(0x7403, "Incorrect data encryption key")
SENSE_CODE(0x7404, "Cryptographic integrity validation failed")
SENSE_CODE(0x7405, "Error decrypting data")
SENSE_CODE(0x7406, "Unknown signature verification key")
SENSE_CODE(0x7407, "Encryption parameters not useable")
SENSE_CODE(0x7408, "Digital signature validation failure")
SENSE_CODE(0x7409, "Encryption mode mismatch on read")
SENSE_CODE(0x740A, "Encrypted block not raw read enabled")
SENSE_CODE(0x740B, "Incorrect Encryption parameters")
SENSE_CODE(0x740C, "Unable to decrypt parameter list")
SENSE_CODE(0x740D, "Encryption algorithm disabled")
SENSE_CODE(0x7410, "SA creation parameter value invalid")
SENSE_CODE(0x7411, "SA creation parameter value rejected")
SENSE_CODE(0x7412, "Invalid SA usage")
SENSE_CODE(0x7421, "Data Encryption configuration prevented")
SENSE_CODE(0x7430, "SA creation parameter not supported")
SENSE_CODE(0x7440, "Authentication failed")
SENSE_CODE(0x7461, "External data encryption key manager access error")
SENSE_CODE(0x7462, "External data encryption key manager error")
SENSE_CODE(0x7463, "External data encryption key not found")
SENSE_CODE(0x7464, "External data encryption request not authorized")
SENSE_CODE(0x746E, "External data encryption control timeout")
SENSE_CODE(0x746F, "External data encryption control error")
SENSE_CODE(0x7471, "Logical unit access not authorized")
SENSE_CODE(0x7479, "Security conflict in translated device")

View file

@ -95,6 +95,8 @@
#define SNIC_DEV_RST_NOTSUP BIT(25)
#define SNIC_SCSI_CLEANUP BIT(26)
#define SNIC_HOST_RESET_ISSUED BIT(27)
#define SNIC_HOST_RESET_CMD_TERM \
(SNIC_DEV_RST_NOTSUP | SNIC_SCSI_CLEANUP | SNIC_HOST_RESET_ISSUED)
#define SNIC_ABTS_TIMEOUT 30000 /* msec */
#define SNIC_LUN_RESET_TIMEOUT 30000 /* msec */
@ -216,9 +218,10 @@ enum snic_msix_intr_index {
SNIC_MSIX_INTR_MAX,
};
#define SNIC_INTRHDLR_NAMSZ (2 * IFNAMSIZ)
struct snic_msix_entry {
int requested;
char devname[IFNAMSIZ];
char devname[SNIC_INTRHDLR_NAMSZ];
irqreturn_t (*isr)(int, void *);
void *devid;
};

View file

@ -39,17 +39,15 @@ snic_handle_link(struct work_struct *work)
{
struct snic *snic = container_of(work, struct snic, link_work);
if (snic->config.xpt_type != SNIC_DAS) {
SNIC_HOST_INFO(snic->shost, "Link Event Received.\n");
SNIC_ASSERT_NOT_IMPL(1);
if (snic->config.xpt_type == SNIC_DAS)
return;
}
snic->link_status = svnic_dev_link_status(snic->vdev);
snic->link_down_cnt = svnic_dev_link_down_cnt(snic->vdev);
SNIC_HOST_INFO(snic->shost, "Link Event: Link %s.\n",
((snic->link_status) ? "Up" : "Down"));
SNIC_ASSERT_NOT_IMPL(1);
}

View file

@ -264,12 +264,14 @@ snic_stats_show(struct seq_file *sfp, void *data)
"Aborts Fail : %lld\n"
"Aborts Driver Timeout : %lld\n"
"Abort FW Timeout : %lld\n"
"Abort IO NOT Found : %lld\n",
"Abort IO NOT Found : %lld\n"
"Abort Queuing Failed : %lld\n",
(u64) atomic64_read(&stats->abts.num),
(u64) atomic64_read(&stats->abts.fail),
(u64) atomic64_read(&stats->abts.drv_tmo),
(u64) atomic64_read(&stats->abts.fw_tmo),
(u64) atomic64_read(&stats->abts.io_not_found));
(u64) atomic64_read(&stats->abts.io_not_found),
(u64) atomic64_read(&stats->abts.q_fail));
/* Dump Reset Stats */
seq_printf(sfp,
@ -316,7 +318,9 @@ snic_stats_show(struct seq_file *sfp, void *data)
seq_printf(sfp,
"Last ISR Time : %llu (%8lu.%8lu)\n"
"Last Ack Time : %llu (%8lu.%8lu)\n"
"ISRs : %llu\n"
"Ack ISRs : %llu\n"
"IO Cmpl ISRs : %llu\n"
"Err Notify ISRs : %llu\n"
"Max CQ Entries : %lld\n"
"Data Count Mismatch : %lld\n"
"IOs w/ Timeout Status : %lld\n"
@ -324,12 +328,17 @@ snic_stats_show(struct seq_file *sfp, void *data)
"IOs w/ SGL Invalid Stat : %lld\n"
"WQ Desc Alloc Fail : %lld\n"
"Queue Full : %lld\n"
"Queue Ramp Up : %lld\n"
"Queue Ramp Down : %lld\n"
"Queue Last Queue Depth : %lld\n"
"Target Not Ready : %lld\n",
(u64) stats->misc.last_isr_time,
last_isr_tms.tv_sec, last_isr_tms.tv_nsec,
(u64)stats->misc.last_ack_time,
last_ack_tms.tv_sec, last_ack_tms.tv_nsec,
(u64) atomic64_read(&stats->misc.isr_cnt),
(u64) atomic64_read(&stats->misc.ack_isr_cnt),
(u64) atomic64_read(&stats->misc.cmpl_isr_cnt),
(u64) atomic64_read(&stats->misc.errnotify_isr_cnt),
(u64) atomic64_read(&stats->misc.max_cq_ents),
(u64) atomic64_read(&stats->misc.data_cnt_mismat),
(u64) atomic64_read(&stats->misc.io_tmo),
@ -337,6 +346,9 @@ snic_stats_show(struct seq_file *sfp, void *data)
(u64) atomic64_read(&stats->misc.sgl_inval),
(u64) atomic64_read(&stats->misc.wq_alloc_fail),
(u64) atomic64_read(&stats->misc.qfull),
(u64) atomic64_read(&stats->misc.qsz_rampup),
(u64) atomic64_read(&stats->misc.qsz_rampdown),
(u64) atomic64_read(&stats->misc.last_qsz),
(u64) atomic64_read(&stats->misc.tgt_not_rdy));
return 0;

View file

@ -171,7 +171,7 @@ snic_scsi_scan_tgt(struct work_struct *work)
tgt->channel,
tgt->scsi_tgt_id,
SCAN_WILD_CARD,
1);
SCSI_SCAN_RESCAN);
spin_lock_irqsave(shost->host_lock, flags);
tgt->flags &= ~SNIC_TGT_SCAN_PENDING;
@ -480,10 +480,21 @@ int
snic_disc_start(struct snic *snic)
{
struct snic_disc *disc = &snic->disc;
unsigned long flags;
int ret = 0;
SNIC_SCSI_DBG(snic->shost, "Discovery Start.\n");
spin_lock_irqsave(&snic->snic_lock, flags);
if (snic->in_remove) {
spin_unlock_irqrestore(&snic->snic_lock, flags);
SNIC_ERR("snic driver removal in progress ...\n");
ret = 0;
return ret;
}
spin_unlock_irqrestore(&snic->snic_lock, flags);
mutex_lock(&disc->mutex);
if (disc->state == SNIC_DISC_PENDING) {
disc->req_cnt++;
@ -533,6 +544,8 @@ snic_tgt_del_all(struct snic *snic)
struct list_head *cur, *nxt;
unsigned long flags;
scsi_flush_work(snic->shost);
mutex_lock(&snic->disc.mutex);
spin_lock_irqsave(snic->shost->host_lock, flags);
@ -545,7 +558,7 @@ snic_tgt_del_all(struct snic *snic)
tgt = NULL;
}
spin_unlock_irqrestore(snic->shost->host_lock, flags);
scsi_flush_work(snic->shost);
mutex_unlock(&snic->disc.mutex);
flush_workqueue(snic_glob->event_q);
} /* end of snic_tgt_del_all */

View file

@ -414,7 +414,7 @@ enum snic_ev_type {
/* Payload 88 bytes = 128 - 24 - 16 */
#define SNIC_HOST_REQ_PAYLOAD ((int)(SNIC_HOST_REQ_LEN - \
sizeof(struct snic_io_hdr) - \
(2 * sizeof(u64))))
(2 * sizeof(u64)) - sizeof(ulong)))
/*
* snic_host_req: host -> firmware request
@ -448,6 +448,8 @@ struct snic_host_req {
/* hba reset */
struct snic_hba_reset reset;
} u;
ulong req_pa;
}; /* end of snic_host_req structure */

View file

@ -48,7 +48,7 @@ snic_wq_cmpl_frame_send(struct vnic_wq *wq,
SNIC_TRC(snic->shost->host_no, 0, 0,
((ulong)(buf->os_buf) - sizeof(struct snic_req_info)), 0, 0,
0);
pci_unmap_single(snic->pdev, buf->dma_addr, buf->len, PCI_DMA_TODEVICE);
buf->os_buf = NULL;
}
@ -137,13 +137,36 @@ snic_select_wq(struct snic *snic)
return 0;
}
static int
snic_wqdesc_avail(struct snic *snic, int q_num, int req_type)
{
int nr_wqdesc = snic->config.wq_enet_desc_count;
if (q_num > 0) {
/*
* Multi Queue case, additional care is required.
* Per WQ active requests need to be maintained.
*/
SNIC_HOST_INFO(snic->shost, "desc_avail: Multi Queue case.\n");
SNIC_BUG_ON(q_num > 0);
return -1;
}
nr_wqdesc -= atomic64_read(&snic->s_stats.fw.actv_reqs);
return ((req_type == SNIC_REQ_HBA_RESET) ? nr_wqdesc : nr_wqdesc - 1);
}
int
snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
{
dma_addr_t pa = 0;
unsigned long flags;
struct snic_fw_stats *fwstats = &snic->s_stats.fw;
struct snic_host_req *req = (struct snic_host_req *) os_buf;
long act_reqs;
long desc_avail = 0;
int q_num = 0;
snic_print_desc(__func__, os_buf, len);
@ -156,11 +179,15 @@ snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
return -ENOMEM;
}
req->req_pa = (ulong)pa;
q_num = snic_select_wq(snic);
spin_lock_irqsave(&snic->wq_lock[q_num], flags);
if (!svnic_wq_desc_avail(snic->wq)) {
desc_avail = snic_wqdesc_avail(snic, q_num, req->hdr.type);
if (desc_avail <= 0) {
pci_unmap_single(snic->pdev, pa, len, PCI_DMA_TODEVICE);
req->req_pa = 0;
spin_unlock_irqrestore(&snic->wq_lock[q_num], flags);
atomic64_inc(&snic->s_stats.misc.wq_alloc_fail);
SNIC_DBG("host = %d, WQ is Full\n", snic->shost->host_no);
@ -169,10 +196,13 @@ snic_queue_wq_desc(struct snic *snic, void *os_buf, u16 len)
}
snic_queue_wq_eth_desc(&snic->wq[q_num], os_buf, pa, len, 0, 0, 1);
/*
* Update stats
* note: when multi queue enabled, fw actv_reqs should be per queue.
*/
act_reqs = atomic64_inc_return(&fwstats->actv_reqs);
spin_unlock_irqrestore(&snic->wq_lock[q_num], flags);
/* Update stats */
act_reqs = atomic64_inc_return(&fwstats->actv_reqs);
if (act_reqs > atomic64_read(&fwstats->max_actv_reqs))
atomic64_set(&fwstats->max_actv_reqs, act_reqs);
@ -318,11 +348,31 @@ snic_req_free(struct snic *snic, struct snic_req_info *rqi)
"Req_free:rqi %p:ioreq %p:abt %p:dr %p\n",
rqi, rqi->req, rqi->abort_req, rqi->dr_req);
if (rqi->abort_req)
mempool_free(rqi->abort_req, snic->req_pool[SNIC_REQ_TM_CACHE]);
if (rqi->abort_req) {
if (rqi->abort_req->req_pa)
pci_unmap_single(snic->pdev,
rqi->abort_req->req_pa,
sizeof(struct snic_host_req),
PCI_DMA_TODEVICE);
mempool_free(rqi->abort_req, snic->req_pool[SNIC_REQ_TM_CACHE]);
}
if (rqi->dr_req) {
if (rqi->dr_req->req_pa)
pci_unmap_single(snic->pdev,
rqi->dr_req->req_pa,
sizeof(struct snic_host_req),
PCI_DMA_TODEVICE);
if (rqi->dr_req)
mempool_free(rqi->dr_req, snic->req_pool[SNIC_REQ_TM_CACHE]);
}
if (rqi->req->req_pa)
pci_unmap_single(snic->pdev,
rqi->req->req_pa,
rqi->req_len,
PCI_DMA_TODEVICE);
mempool_free(rqi, snic->req_pool[rqi->rq_pool_type]);
}

View file

@ -38,7 +38,7 @@ snic_isr_msix_wq(int irq, void *data)
unsigned long wq_work_done = 0;
snic->s_stats.misc.last_isr_time = jiffies;
atomic64_inc(&snic->s_stats.misc.isr_cnt);
atomic64_inc(&snic->s_stats.misc.ack_isr_cnt);
wq_work_done = snic_wq_cmpl_handler(snic, -1);
svnic_intr_return_credits(&snic->intr[SNIC_MSIX_WQ],
@ -56,7 +56,7 @@ snic_isr_msix_io_cmpl(int irq, void *data)
unsigned long iocmpl_work_done = 0;
snic->s_stats.misc.last_isr_time = jiffies;
atomic64_inc(&snic->s_stats.misc.isr_cnt);
atomic64_inc(&snic->s_stats.misc.cmpl_isr_cnt);
iocmpl_work_done = snic_fwcq_cmpl_handler(snic, -1);
svnic_intr_return_credits(&snic->intr[SNIC_MSIX_IO_CMPL],
@ -73,7 +73,7 @@ snic_isr_msix_err_notify(int irq, void *data)
struct snic *snic = data;
snic->s_stats.misc.last_isr_time = jiffies;
atomic64_inc(&snic->s_stats.misc.isr_cnt);
atomic64_inc(&snic->s_stats.misc.errnotify_isr_cnt);
svnic_intr_return_all_credits(&snic->intr[SNIC_MSIX_ERR_NOTIFY]);
snic_log_q_error(snic);

View file

@ -98,11 +98,18 @@ snic_slave_configure(struct scsi_device *sdev)
static int
snic_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
struct snic *snic = shost_priv(sdev->host);
int qsz = 0;
qsz = min_t(u32, qdepth, SNIC_MAX_QUEUE_DEPTH);
if (qsz < sdev->queue_depth)
atomic64_inc(&snic->s_stats.misc.qsz_rampdown);
else if (qsz > sdev->queue_depth)
atomic64_inc(&snic->s_stats.misc.qsz_rampup);
atomic64_set(&snic->s_stats.misc.last_qsz, sdev->queue_depth);
scsi_change_queue_depth(sdev, qsz);
SNIC_INFO("QDepth Changed to %d\n", sdev->queue_depth);
return sdev->queue_depth;
}
@ -624,19 +631,6 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_free_tmreq_pool;
}
/*
* Initialization done with PCI system, hardware, firmware.
* Add shost to SCSI
*/
ret = snic_add_host(shost, pdev);
if (ret) {
SNIC_HOST_ERR(shost,
"Adding scsi host Failed ... exiting. %d\n",
ret);
goto err_notify_unset;
}
spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
list_add_tail(&snic->list, &snic_glob->snic_list);
spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);
@ -669,8 +663,6 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < snic->intr_count; i++)
svnic_intr_unmask(&snic->intr[i]);
snic_set_state(snic, SNIC_ONLINE);
/* Get snic params */
ret = snic_get_conf(snic);
if (ret) {
@ -681,6 +673,21 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_get_conf;
}
/*
* Initialization done with PCI system, hardware, firmware.
* Add shost to SCSI
*/
ret = snic_add_host(shost, pdev);
if (ret) {
SNIC_HOST_ERR(shost,
"Adding scsi host Failed ... exiting. %d\n",
ret);
goto err_get_conf;
}
snic_set_state(snic, SNIC_ONLINE);
ret = snic_disc_start(snic);
if (ret) {
SNIC_HOST_ERR(shost, "snic_probe:Discovery Failed w err = %d\n",
@ -705,6 +712,8 @@ err_req_intr:
svnic_dev_disable(snic->vdev);
err_vdev_enable:
svnic_dev_notify_unset(snic->vdev);
for (i = 0; i < snic->wq_count; i++) {
int rc = 0;
@ -718,9 +727,6 @@ err_vdev_enable:
}
snic_del_host(snic->shost);
err_notify_unset:
svnic_dev_notify_unset(snic->vdev);
err_free_tmreq_pool:
mempool_destroy(snic->req_pool[SNIC_REQ_TM_CACHE]);

Some files were not shown because too many files have changed in this diff Show more