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:
commit
675e0655c1
117 changed files with 4828 additions and 6470 deletions
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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.*
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)) &&
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 = '?';
|
||||
}
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -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: "
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ********/
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(¤t_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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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])
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
826
drivers/scsi/sense_codes.h
Normal 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")
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue