提交 675e0655 编写于 作者: L Linus Torvalds

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
  ...
...@@ -23,11 +23,10 @@ supported by the driver. ...@@ -23,11 +23,10 @@ supported by the driver.
If the default configuration does not work for you, you can use the kernel If the default configuration does not work for you, you can use the kernel
command lines (eg using the lilo append command): command lines (eg using the lilo append command):
ncr5380=port,irq,dma ncr5380=addr,irq
ncr53c400=port,irq ncr53c400=addr,irq
or ncr53c400a=addr,irq
ncr5380=base,irq,dma dtc3181e=addr,irq
ncr53c400=base,irq
The driver does not probe for any addresses or ports other than those in The driver does not probe for any addresses or ports other than those in
the OVERRIDE or given to the kernel as above. the OVERRIDE or given to the kernel as above.
...@@ -36,19 +35,17 @@ This driver provides some information on what it has detected in ...@@ -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 /proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
time. More info to come in the future. 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. This driver works as a module.
When included as a module, parameters can be passed on the insmod/modprobe When included as a module, parameters can be passed on the insmod/modprobe
command line: command line:
ncr_irq=xx the interrupt ncr_irq=xx the interrupt
ncr_addr=xx the port or base address (for port or memory ncr_addr=xx the port or base address (for port or memory
mapped, resp.) mapped, resp.)
ncr_dma=xx the DMA
ncr_5380=1 to set up for a NCR5380 board ncr_5380=1 to set up for a NCR5380 board
ncr_53c400=1 to set up for a NCR53C400 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. e.g.
modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
for a port mapped NCR5380 board or for a port mapped NCR5380 board or
......
...@@ -27,13 +27,15 @@ parameters may be changed at runtime by the command ...@@ -27,13 +27,15 @@ parameters may be changed at runtime by the command
aic79xx= [HW,SCSI] aic79xx= [HW,SCSI]
See Documentation/scsi/aic79xx.txt. See Documentation/scsi/aic79xx.txt.
atascsi= [HW,SCSI] Atari SCSI atascsi= [HW,SCSI]
See drivers/scsi/atari_scsi.c.
BusLogic= [HW,SCSI] BusLogic= [HW,SCSI]
See drivers/scsi/BusLogic.c, comment before function See drivers/scsi/BusLogic.c, comment before function
BusLogic_ParseDriverOptions(). BusLogic_ParseDriverOptions().
dtc3181e= [HW,SCSI] dtc3181e= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
eata= [HW,SCSI] eata= [HW,SCSI]
...@@ -51,8 +53,8 @@ parameters may be changed at runtime by the command ...@@ -51,8 +53,8 @@ parameters may be changed at runtime by the command
ips= [HW,SCSI] Adaptec / IBM ServeRAID controller ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
See header of drivers/scsi/ips.c. See header of drivers/scsi/ips.c.
mac5380= [HW,SCSI] Format: mac5380= [HW,SCSI]
<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> See drivers/scsi/mac_scsi.c.
max_luns= [SCSI] Maximum number of LUNs to probe. max_luns= [SCSI] Maximum number of LUNs to probe.
Should be between 1 and 2^32-1. Should be between 1 and 2^32-1.
...@@ -65,10 +67,13 @@ parameters may be changed at runtime by the command ...@@ -65,10 +67,13 @@ parameters may be changed at runtime by the command
See header of drivers/scsi/NCR_D700.c. See header of drivers/scsi/NCR_D700.c.
ncr5380= [HW,SCSI] ncr5380= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c400= [HW,SCSI] ncr53c400= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c400a= [HW,SCSI] ncr53c400a= [HW,SCSI]
See Documentation/scsi/g_NCR5380.txt.
ncr53c406a= [HW,SCSI] ncr53c406a= [HW,SCSI]
......
...@@ -7593,10 +7593,10 @@ M: Michael Schmitz <schmitzmic@gmail.com> ...@@ -7593,10 +7593,10 @@ M: Michael Schmitz <schmitzmic@gmail.com>
L: linux-scsi@vger.kernel.org L: linux-scsi@vger.kernel.org
S: Maintained S: Maintained
F: Documentation/scsi/g_NCR5380.txt F: Documentation/scsi/g_NCR5380.txt
F: Documentation/scsi/dtc3x80.txt
F: drivers/scsi/NCR5380.* F: drivers/scsi/NCR5380.*
F: drivers/scsi/arm/cumana_1.c F: drivers/scsi/arm/cumana_1.c
F: drivers/scsi/arm/oak.c F: drivers/scsi/arm/oak.c
F: drivers/scsi/atari_NCR5380.c
F: drivers/scsi/atari_scsi.* F: drivers/scsi/atari_scsi.*
F: drivers/scsi/dmx3191d.c F: drivers/scsi/dmx3191d.c
F: drivers/scsi/dtc.* F: drivers/scsi/dtc.*
......
...@@ -294,7 +294,7 @@ static int icside_dma_init(struct pata_icside_info *info) ...@@ -294,7 +294,7 @@ static int icside_dma_init(struct pata_icside_info *info)
static struct scsi_host_template pata_icside_sht = { static struct scsi_host_template pata_icside_sht = {
ATA_BASE_SHT(DRV_NAME), ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
}; };
......
...@@ -81,7 +81,7 @@ MODULE_PARM_DESC(cmd_sg_entries, ...@@ -81,7 +81,7 @@ MODULE_PARM_DESC(cmd_sg_entries,
module_param(indirect_sg_entries, uint, 0444); module_param(indirect_sg_entries, uint, 0444);
MODULE_PARM_DESC(indirect_sg_entries, 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_param(allow_ext_sg, bool, 0444);
MODULE_PARM_DESC(allow_ext_sg, MODULE_PARM_DESC(allow_ext_sg,
...@@ -2819,7 +2819,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) ...@@ -2819,7 +2819,7 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
spin_unlock(&host->target_lock); spin_unlock(&host->target_lock);
scsi_scan_target(&target->scsi_host->shost_gendev, 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 || if (srp_connected_ch(target) < target->ch_count ||
target->qp_in_error) { target->qp_in_error) {
...@@ -3097,7 +3097,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target) ...@@ -3097,7 +3097,7 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
case SRP_OPT_SG_TABLESIZE: case SRP_OPT_SG_TABLESIZE:
if (match_int(args, &token) || token < 1 || 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", pr_warn("bad max sg_tablesize parameter '%s'\n",
p); p);
goto out; goto out;
......
...@@ -2281,7 +2281,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ...@@ -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), dma_addr_out = pci_map_single(ioc->pcidev, bio_data(req->bio),
blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL); blk_rq_bytes(req), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_out) if (pci_dma_mapping_error(ioc->pcidev, dma_addr_out))
goto put_mf; goto put_mf;
ioc->add_sge(psge, flagsLength, dma_addr_out); ioc->add_sge(psge, flagsLength, dma_addr_out);
psge += ioc->SGE_size; psge += ioc->SGE_size;
...@@ -2296,7 +2296,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, ...@@ -2296,7 +2296,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
flagsLength |= blk_rq_bytes(rsp) + 4; flagsLength |= blk_rq_bytes(rsp) + 4;
dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio), dma_addr_in = pci_map_single(ioc->pcidev, bio_data(rsp->bio),
blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL); blk_rq_bytes(rsp), PCI_DMA_BIDIRECTIONAL);
if (!dma_addr_in) if (pci_dma_mapping_error(ioc->pcidev, dma_addr_in))
goto unmap; goto unmap;
ioc->add_sge(psge, flagsLength, dma_addr_in); ioc->add_sge(psge, flagsLength, dma_addr_in);
......
...@@ -1150,7 +1150,7 @@ static void mpt_work_wrapper(struct work_struct *work) ...@@ -1150,7 +1150,7 @@ static void mpt_work_wrapper(struct work_struct *work)
} }
shost_printk(KERN_INFO, shost, MYIOC_s_FMT shost_printk(KERN_INFO, shost, MYIOC_s_FMT
"Integrated RAID detects new device %d\n", ioc->name, disk); "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) ...@@ -26,7 +26,8 @@ void zfcp_unit_scsi_scan(struct zfcp_unit *unit)
lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun); lun = scsilun_to_int((struct scsi_lun *) &unit->fcp_lun);
if (rport && rport->port_state == FC_PORTSTATE_ONLINE) 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) static void zfcp_unit_scsi_scan_work(struct work_struct *work)
......
...@@ -17,6 +17,7 @@ config SCSI ...@@ -17,6 +17,7 @@ config SCSI
tristate "SCSI device support" tristate "SCSI device support"
depends on BLOCK depends on BLOCK
select SCSI_DMA if HAS_DMA select SCSI_DMA if HAS_DMA
select SG_POOL
---help--- ---help---
If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or 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 any other SCSI device under Linux, say Y and make sure that you know
...@@ -202,12 +203,12 @@ config SCSI_ENCLOSURE ...@@ -202,12 +203,12 @@ config SCSI_ENCLOSURE
certain enclosure conditions to be reported and is not required. certain enclosure conditions to be reported and is not required.
config SCSI_CONSTANTS config SCSI_CONSTANTS
bool "Verbose SCSI error reporting (kernel size +=75K)" bool "Verbose SCSI error reporting (kernel size += 36K)"
depends on SCSI depends on SCSI
help help
The error messages regarding your SCSI hardware will be easier to The error messages regarding your SCSI hardware will be easier to
understand if you say Y here; it will enlarge your kernel by about 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 config SCSI_LOGGING
bool "SCSI logging facility" bool "SCSI logging facility"
...@@ -813,17 +814,6 @@ config SCSI_GENERIC_NCR5380_MMIO ...@@ -813,17 +814,6 @@ config SCSI_GENERIC_NCR5380_MMIO
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called g_NCR5380_mmio. 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 config SCSI_IPS
tristate "IBM ServeRAID support" tristate "IBM ServeRAID support"
depends on PCI && SCSI depends on PCI && SCSI
......
此差异已折叠。
...@@ -199,13 +199,6 @@ ...@@ -199,13 +199,6 @@
#define PHASE_SR_TO_TCR(phase) ((phase) >> 2) #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 * These are "special" values for the irq and dma_channel fields of the
* Scsi_Host structure * Scsi_Host structure
...@@ -220,28 +213,17 @@ ...@@ -220,28 +213,17 @@
#define NO_IRQ 0 #define NO_IRQ 0
#endif #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_NO_PSEUDO_DMA 8 /* Inhibit DMA */
#define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */ #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 */ #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 { struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */ NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */ struct Scsi_Host *host; /* Host backpointer */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */ unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char busy[8]; /* index = target, bit = lun */ unsigned char busy[8]; /* index = target, bit = lun */
#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
int dma_len; /* requested length of DMA */ int dma_len; /* requested length of DMA */
#endif
unsigned char last_message; /* last message OUT */ unsigned char last_message; /* last message OUT */
struct scsi_cmnd *connected; /* currently connected cmnd */ struct scsi_cmnd *connected; /* currently connected cmnd */
struct scsi_cmnd *selecting; /* cmnd to be connected */ struct scsi_cmnd *selecting; /* cmnd to be connected */
...@@ -256,13 +238,6 @@ struct NCR5380_hostdata { ...@@ -256,13 +238,6 @@ struct NCR5380_hostdata {
int read_overruns; /* number of bytes to cut from a int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */ * transfer to handle chip overruns */
struct work_struct main_task; 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; struct workqueue_struct *work_q;
unsigned long accesses_per_ms; /* chip register accesses per ms */ unsigned long accesses_per_ms; /* chip register accesses per ms */
}; };
...@@ -305,132 +280,20 @@ static void NCR5380_print(struct Scsi_Host *instance); ...@@ -305,132 +280,20 @@ static void NCR5380_print(struct Scsi_Host *instance);
#define NCR5380_dprint_phase(flg, arg) do {} while (0) #define NCR5380_dprint_phase(flg, arg) do {} while (0)
#endif #endif
#if defined(AUTOPROBE_IRQ)
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); 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_init(struct Scsi_Host *instance, int flags);
static int NCR5380_maybe_reset_bus(struct Scsi_Host *); static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
static void NCR5380_exit(struct Scsi_Host *instance); static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(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); static irqreturn_t NCR5380_intr(int irq, void *dev_id);
#endif
static void NCR5380_main(struct work_struct *work); static void NCR5380_main(struct work_struct *work);
static const char *NCR5380_info(struct Scsi_Host *instance); static const char *NCR5380_info(struct Scsi_Host *instance);
static void NCR5380_reselect(struct Scsi_Host *instance); static void NCR5380_reselect(struct Scsi_Host *instance);
static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *); 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); 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_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 /* __KERNEL__ */
#endif /* NCR5380_H */ #endif /* NCR5380_H */
...@@ -555,8 +555,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) ...@@ -555,8 +555,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata; dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext); aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_name *) fib_data(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) ...@@ -1037,8 +1035,6 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
dev = (struct aac_dev *)scsicmd->device->host->hostdata; dev = (struct aac_dev *)scsicmd->device->host->hostdata;
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -ENOMEM;
aac_fib_init(cmd_fibcontext); aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext); dinfo = (struct aac_get_serial *) fib_data(cmd_fibcontext);
...@@ -1950,10 +1946,6 @@ static int aac_read(struct scsi_cmnd * scsicmd) ...@@ -1950,10 +1946,6 @@ static int aac_read(struct scsi_cmnd * scsicmd)
* Alocate and initialize a Fib * Alocate and initialize a Fib
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); 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); status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
...@@ -2048,16 +2040,6 @@ static int aac_write(struct scsi_cmnd * scsicmd) ...@@ -2048,16 +2040,6 @@ static int aac_write(struct scsi_cmnd * scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command * Allocate and initialize a Fib then setup a BlockWrite command
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); 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); status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
...@@ -2283,8 +2265,6 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd) ...@@ -2283,8 +2265,6 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
* Allocate and initialize a Fib * Allocate and initialize a Fib
*/ */
cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(aac, scsicmd);
if (!cmd_fibcontext)
return SCSI_MLQUEUE_HOST_BUSY;
aac_fib_init(cmd_fibcontext); aac_fib_init(cmd_fibcontext);
...@@ -3184,8 +3164,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd) ...@@ -3184,8 +3164,6 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command * Allocate and initialize a Fib then setup a BlockWrite command
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
if (!cmd_fibcontext)
return -1;
status = aac_adapter_scsi(cmd_fibcontext, scsicmd); status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
......
...@@ -29,6 +29,7 @@ enum { ...@@ -29,6 +29,7 @@ enum {
#define AAC_INT_MODE_MSI (1<<1) #define AAC_INT_MODE_MSI (1<<1)
#define AAC_INT_MODE_AIF (1<<2) #define AAC_INT_MODE_AIF (1<<2)
#define AAC_INT_MODE_SYNC (1<<3) #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_INTX 0xfffffffb
#define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa #define AAC_INT_ENABLE_TYPE1_MSIX 0xfffffffa
...@@ -62,7 +63,7 @@ enum { ...@@ -62,7 +63,7 @@ enum {
#define PMC_GLOBAL_INT_BIT0 0x00000001 #define PMC_GLOBAL_INT_BIT0 0x00000001
#ifndef AAC_DRIVER_BUILD #ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 41052 # define AAC_DRIVER_BUILD 41066
# define AAC_DRIVER_BRANCH "-ms" # define AAC_DRIVER_BRANCH "-ms"
#endif #endif
#define MAXIMUM_NUM_CONTAINERS 32 #define MAXIMUM_NUM_CONTAINERS 32
...@@ -720,7 +721,7 @@ struct sa_registers { ...@@ -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_readw(AEP, CSR) readl(&((AEP)->regs.sa->CSR))
#define sa_readl(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; ...@@ -2065,6 +2066,10 @@ extern struct aac_common aac_config;
#define AifEnAddJBOD 30 /* JBOD created */ #define AifEnAddJBOD 30 /* JBOD created */
#define AifEnDeleteJBOD 31 /* JBOD deleted */ #define AifEnDeleteJBOD 31 /* JBOD deleted */
#define AifBuManagerEvent 42 /* Bu management*/
#define AifBuCacheDataLoss 10
#define AifBuCacheDataRecover 11
#define AifCmdJobProgress 2 /* Progress report */ #define AifCmdJobProgress 2 /* Progress report */
#define AifJobCtrZero 101 /* Array Zero progress */ #define AifJobCtrZero 101 /* Array Zero progress */
#define AifJobStsSuccess 1 /* Job completes */ #define AifJobStsSuccess 1 /* Job completes */
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
...@@ -47,6 +48,20 @@ struct aac_common aac_config = { ...@@ -47,6 +48,20 @@ struct aac_common aac_config = {
.irq_mod = 1 .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) static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
{ {
unsigned char *base; unsigned char *base;
...@@ -91,7 +106,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co ...@@ -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); init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
if (dev->max_fib_size != sizeof(struct hw_fib)) if (dev->max_fib_size != sizeof(struct hw_fib))
init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4); 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); init->fsrev = cpu_to_le32(dev->fsrev);
/* /*
...@@ -378,21 +393,8 @@ void aac_define_int_mode(struct aac_dev *dev) ...@@ -378,21 +393,8 @@ void aac_define_int_mode(struct aac_dev *dev)
msi_count = i; msi_count = i;
} else { } else {
dev->msi_enabled = 0; dev->msi_enabled = 0;
printk(KERN_ERR "%s%d: MSIX not supported!! Will try MSI 0x%x.\n", dev_err(&dev->pdev->dev,
dev->name, dev->id, i); "MSIX not supported!! Will try INTX 0x%x.\n", 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);
} }
} }
...@@ -427,6 +429,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) ...@@ -427,6 +429,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
dev->comm_interface = AAC_COMM_PRODUCER; dev->comm_interface = AAC_COMM_PRODUCER;
dev->raw_io_interface = dev->raw_io_64 = 0; 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, if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
status+0, status+1, status+2, status+3, NULL)) && 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, ...@@ -637,10 +637,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
} }
return -EFAULT; return -EFAULT;
} }
/* We used to udelay() here but that absorbed /*
* a CPU when a timeout occured. Not very * Allow other processes / CPUS to use core
* useful. */ */
cpu_relax(); schedule();
} }
} else if (down_interruptible(&fibptr->event_wait)) { } else if (down_interruptible(&fibptr->event_wait)) {
/* Do nothing ... satisfy /* Do nothing ... satisfy
...@@ -901,6 +901,31 @@ void aac_printf(struct aac_dev *dev, u32 val) ...@@ -901,6 +901,31 @@ void aac_printf(struct aac_dev *dev, u32 val)
memset(cp, 0, 256); 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 * 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) ...@@ -1154,6 +1179,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
ADD : DELETE; ADD : DELETE;
break; break;
} }
case AifBuManagerEvent:
aac_handle_aif_bu(dev, aifcmd);
break; break;
} }
...@@ -1996,6 +2023,10 @@ int aac_command_thread(void *data) ...@@ -1996,6 +2023,10 @@ int aac_command_thread(void *data)
if (difference <= 0) if (difference <= 0)
difference = 1; difference = 1;
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (kthread_should_stop())
break;
schedule_timeout(difference); schedule_timeout(difference);
if (kthread_should_stop()) if (kthread_should_stop())
......
...@@ -392,9 +392,10 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, ...@@ -392,9 +392,10 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index,
if (likely(fib->callback && fib->callback_data)) { if (likely(fib->callback && fib->callback_data)) {
fib->flags &= FIB_CONTEXT_FLAG_FASTRESP; fib->flags &= FIB_CONTEXT_FLAG_FASTRESP;
fib->callback(fib->callback_data, fib); fib->callback(fib->callback_data, fib);
} else { } else
aac_fib_complete(fib); dev_info(&dev->pdev->dev,
} "Invalid callback_fib[%d] (*%p)(%p)\n",
index, fib->callback, fib->callback_data);
} else { } else {
unsigned long flagv; unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n")); 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) ...@@ -1299,6 +1299,8 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
else else
shost->this_id = shost->max_id; 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 * dmb - we may need to move the setting of these parms somewhere else once
* we get a fib that can report the actual numbers * we get a fib that can report the actual numbers
...@@ -1431,8 +1433,8 @@ static int aac_acquire_resources(struct aac_dev *dev) ...@@ -1431,8 +1433,8 @@ static int aac_acquire_resources(struct aac_dev *dev)
/* After EEH recovery or suspend resume, max_msix count /* After EEH recovery or suspend resume, max_msix count
* may change, therfore updating in init as well. * may change, therfore updating in init as well.
*/ */
aac_adapter_start(dev);
dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix); dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
aac_adapter_start(dev);
} }
return 0; return 0;
......
...@@ -135,7 +135,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) ...@@ -135,7 +135,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
if (mode & AAC_INT_MODE_AIF) { if (mode & AAC_INT_MODE_AIF) {
/* handle 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) if (dev->msi_enabled)
aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT); aac_src_access_devreg(dev, AAC_CLEAR_AIF_BIT);
mode = 0; mode = 0;
......
...@@ -13,13 +13,14 @@ ...@@ -13,13 +13,14 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#define PSEUDO_DMA
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_read(reg) cumanascsi_read(instance, reg) #define NCR5380_read(reg) cumanascsi_read(instance, reg)
#define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value) #define NCR5380_write(reg, value) cumanascsi_write(instance, reg, value)
#define NCR5380_dma_xfer_len(instance, cmd, phase) (cmd->transfersize) #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_intr cumanascsi_intr
#define NCR5380_queue_command cumanascsi_queue_command #define NCR5380_queue_command cumanascsi_queue_command
...@@ -41,8 +42,8 @@ void cumanascsi_setup(char *str, int *ints) ...@@ -41,8 +42,8 @@ void cumanascsi_setup(char *str, int *ints)
#define L(v) (((v)<<16)|((v) & 0x0000ffff)) #define L(v) (((v)<<16)|((v) & 0x0000ffff))
#define H(v) (((v)>>16)|((v) & 0xffff0000)) #define H(v) (((v)>>16)|((v) & 0xffff0000))
static inline int static inline int cumanascsi_pwrite(struct Scsi_Host *host,
NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len) unsigned char *addr, int len)
{ {
unsigned long *laddr; unsigned long *laddr;
void __iomem *dma = priv(host)->dma + 0x2000; void __iomem *dma = priv(host)->dma + 0x2000;
...@@ -101,11 +102,14 @@ NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len) ...@@ -101,11 +102,14 @@ NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
} }
end: end:
writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
return len;
if (len)
return -1;
return 0;
} }
static inline int static inline int cumanascsi_pread(struct Scsi_Host *host,
NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len) unsigned char *addr, int len)
{ {
unsigned long *laddr; unsigned long *laddr;
void __iomem *dma = priv(host)->dma + 0x2000; void __iomem *dma = priv(host)->dma + 0x2000;
...@@ -163,7 +167,10 @@ NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len) ...@@ -163,7 +167,10 @@ NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
} }
end: end:
writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL); 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) static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
...@@ -239,7 +246,7 @@ static int cumanascsi1_probe(struct expansion_card *ec, ...@@ -239,7 +246,7 @@ static int cumanascsi1_probe(struct expansion_card *ec,
host->irq = ec->irq; host->irq = ec->irq;
ret = NCR5380_init(host, 0); ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
if (ret) if (ret)
goto out_unmap; goto out_unmap;
......
...@@ -365,7 +365,7 @@ static struct scsi_host_template cumanascsi2_template = { ...@@ -365,7 +365,7 @@ static struct scsi_host_template cumanascsi2_template = {
.eh_abort_handler = fas216_eh_abort, .eh_abort_handler = fas216_eh_abort,
.can_queue = 1, .can_queue = 1,
.this_id = 7, .this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.proc_name = "cumanascsi2", .proc_name = "cumanascsi2",
......
...@@ -484,7 +484,7 @@ static struct scsi_host_template eesox_template = { ...@@ -484,7 +484,7 @@ static struct scsi_host_template eesox_template = {
.eh_abort_handler = fas216_eh_abort, .eh_abort_handler = fas216_eh_abort,
.can_queue = 1, .can_queue = 1,
.this_id = 7, .this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.proc_name = "eesox", .proc_name = "eesox",
......
...@@ -14,9 +14,6 @@ ...@@ -14,9 +14,6 @@
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
/*#define PSEUDO_DMA*/
#define DONT_USE_INTR
#define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata) #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_read(reg) \ #define NCR5380_read(reg) \
...@@ -24,7 +21,10 @@ ...@@ -24,7 +21,10 @@
#define NCR5380_write(reg, value) \ #define NCR5380_write(reg, value) \
writeb(value, priv(instance)->base + ((reg) << 2)) 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_queue_command oakscsi_queue_command
#define NCR5380_info oakscsi_info #define NCR5380_info oakscsi_info
...@@ -40,23 +40,23 @@ ...@@ -40,23 +40,23 @@
#define STAT ((128 + 16) << 2) #define STAT ((128 + 16) << 2)
#define DATA ((128 + 8) << 2) #define DATA ((128 + 8) << 2)
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, static inline int oakscsi_pwrite(struct Scsi_Host *instance,
int len) unsigned char *addr, int len)
{ {
void __iomem *base = priv(instance)->base; void __iomem *base = priv(instance)->base;
printk("writing %p len %d\n",addr, len); printk("writing %p len %d\n",addr, len);
if(!len) return -1;
while(1) while(1)
{ {
int status; int status;
while (((status = readw(base + STAT)) & 0x100)==0); while (((status = readw(base + STAT)) & 0x100)==0);
} }
return 0;
} }
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, static inline int oakscsi_pread(struct Scsi_Host *instance,
int len) unsigned char *addr, int len)
{ {
void __iomem *base = priv(instance)->base; void __iomem *base = priv(instance)->base;
printk("reading %p len %d\n", addr, len); printk("reading %p len %d\n", addr, len);
...@@ -73,7 +73,7 @@ printk("reading %p len %d\n", addr, len); ...@@ -73,7 +73,7 @@ printk("reading %p len %d\n", addr, len);
if(status & 0x200 || !timeout) if(status & 0x200 || !timeout)
{ {
printk("status = %08X\n", status); 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) ...@@ -143,7 +143,7 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
host->irq = NO_IRQ; host->irq = NO_IRQ;
host->n_io_port = 255; host->n_io_port = 255;
ret = NCR5380_init(host, 0); ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
if (ret) if (ret)
goto out_unmap; goto out_unmap;
......
...@@ -291,7 +291,7 @@ static struct scsi_host_template powertecscsi_template = { ...@@ -291,7 +291,7 @@ static struct scsi_host_template powertecscsi_template = {
.can_queue = 8, .can_queue = 8,
.this_id = 7, .this_id = 7,
.sg_tablesize = SCSI_MAX_SG_CHAIN_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
......
此差异已折叠。
...@@ -14,55 +14,23 @@ ...@@ -14,55 +14,23 @@
* *
*/ */
/*
/**************************************************************************/ * Notes for Falcon SCSI DMA
/* */ *
/* Notes for Falcon SCSI: */ * The 5380 device is one of several that all share the DMA chip. Hence
/* ---------------------- */ * "locking" and "unlocking" access to this chip is required.
/* */ *
/* Since the Falcon SCSI uses the ST-DMA chip, that is shared among */ * Two possible schemes for ST DMA acquisition by atari_scsi are:
/* several device drivers, locking and unlocking the access to this */ * 1) The lock is taken for each command separately (i.e. can_queue == 1).
/* chip is required. But locking is not possible from an interrupt, */ * 2) The lock is taken when the first command arrives and released
/* since it puts the process to sleep if the lock is not available. */ * when the last command is finished (i.e. can_queue > 1).
/* This prevents "late" locking of the DMA chip, i.e. locking it just */ *
/* before using it, since in case of disconnection-reconnection */ * The first alternative limits SCSI bus utilization, since interleaving
/* commands, the DMA is started from the reselection interrupt. */ * 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
/* Two possible schemes for ST-DMA-locking would be: */ * allow the IDE and floppy drivers equal access to the ST DMA chip
/* 1) The lock is taken for each command separately and disconnecting */ * the default is can_queue == 1.
/* 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! */
/* */
/**************************************************************************/
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -83,13 +51,10 @@ ...@@ -83,13 +51,10 @@
#include <scsi/scsi_host.h> #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 #define DMA_MIN_SIZE 32
/* Definitions for the core NCR5380 driver. */
#define NCR5380_implementation_fields /* none */ #define NCR5380_implementation_fields /* none */
#define NCR5380_read(reg) atari_scsi_reg_read(reg) #define NCR5380_read(reg) atari_scsi_reg_read(reg)
...@@ -99,9 +64,9 @@ ...@@ -99,9 +64,9 @@
#define NCR5380_abort atari_scsi_abort #define NCR5380_abort atari_scsi_abort
#define NCR5380_info atari_scsi_info #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) 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) atari_scsi_dma_setup(instance, data, count, 1)
#define NCR5380_dma_residual(instance) \ #define NCR5380_dma_residual(instance) \
atari_scsi_dma_residual(instance) atari_scsi_dma_residual(instance)
...@@ -159,14 +124,11 @@ static inline unsigned long SCSI_DMA_GETADR(void) ...@@ -159,14 +124,11 @@ static inline unsigned long SCSI_DMA_GETADR(void)
return adr; return adr;
} }
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void); static void atari_scsi_fetch_restbytes(void);
#endif
static unsigned char (*atari_scsi_reg_read)(unsigned char reg); static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
static void (*atari_scsi_reg_write)(unsigned char reg, unsigned char value); 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 unsigned long atari_dma_residual, atari_dma_startaddr;
static short atari_dma_active; static short atari_dma_active;
/* pointer to the dribble buffer */ /* pointer to the dribble buffer */
...@@ -185,7 +147,6 @@ static char *atari_dma_orig_addr; ...@@ -185,7 +147,6 @@ static char *atari_dma_orig_addr;
/* mask for address bits that can't be used with the ST-DMA */ /* mask for address bits that can't be used with the ST-DMA */
static unsigned long atari_dma_stram_mask; static unsigned long atari_dma_stram_mask;
#define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0) #define STRAM_ADDR(a) (((a) & atari_dma_stram_mask) == 0)
#endif
static int setup_can_queue = -1; static int setup_can_queue = -1;
module_param(setup_can_queue, int, 0); module_param(setup_can_queue, int, 0);
...@@ -193,16 +154,12 @@ static int setup_cmd_per_lun = -1; ...@@ -193,16 +154,12 @@ static int setup_cmd_per_lun = -1;
module_param(setup_cmd_per_lun, int, 0); module_param(setup_cmd_per_lun, int, 0);
static int setup_sg_tablesize = -1; static int setup_sg_tablesize = -1;
module_param(setup_sg_tablesize, int, 0); 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; static int setup_hostid = -1;
module_param(setup_hostid, int, 0); module_param(setup_hostid, int, 0);
static int setup_toshiba_delay = -1; static int setup_toshiba_delay = -1;
module_param(setup_toshiba_delay, int, 0); module_param(setup_toshiba_delay, int, 0);
#if defined(REAL_DMA)
static int scsi_dma_is_ignored_buserr(unsigned char dma_stat) static int scsi_dma_is_ignored_buserr(unsigned char dma_stat)
{ {
int i; int i;
...@@ -255,12 +212,9 @@ static void scsi_dma_buserr(int irq, void *dummy) ...@@ -255,12 +212,9 @@ static void scsi_dma_buserr(int irq, void *dummy)
} }
#endif #endif
#endif
static irqreturn_t scsi_tt_intr(int irq, void *dev) static irqreturn_t scsi_tt_intr(int irq, void *dev)
{ {
#ifdef REAL_DMA
struct Scsi_Host *instance = dev; struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat; int dma_stat;
...@@ -342,8 +296,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev) ...@@ -342,8 +296,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev)
tt_scsi_dma.dma_ctrl = 0; tt_scsi_dma.dma_ctrl = 0;
} }
#endif /* REAL_DMA */
NCR5380_intr(irq, dev); NCR5380_intr(irq, dev);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -352,7 +304,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev) ...@@ -352,7 +304,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dev)
static irqreturn_t scsi_falcon_intr(int irq, void *dev) static irqreturn_t scsi_falcon_intr(int irq, void *dev)
{ {
#ifdef REAL_DMA
struct Scsi_Host *instance = dev; struct Scsi_Host *instance = dev;
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
int dma_stat; int dma_stat;
...@@ -405,15 +356,12 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dev) ...@@ -405,15 +356,12 @@ static irqreturn_t scsi_falcon_intr(int irq, void *dev)
atari_dma_orig_addr = NULL; atari_dma_orig_addr = NULL;
} }
#endif /* REAL_DMA */
NCR5380_intr(irq, dev); NCR5380_intr(irq, dev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void) static void atari_scsi_fetch_restbytes(void)
{ {
int nr; int nr;
...@@ -436,7 +384,6 @@ static void atari_scsi_fetch_restbytes(void) ...@@ -436,7 +384,6 @@ static void atari_scsi_fetch_restbytes(void)
*dst++ = *src++; *dst++ = *src++;
} }
} }
#endif /* REAL_DMA */
/* This function releases the lock on the DMA chip if there is no /* 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) ...@@ -464,6 +411,10 @@ static int falcon_get_lock(struct Scsi_Host *instance)
if (IS_A_TT()) if (IS_A_TT())
return 1; return 1;
if (stdma_is_locked_by(scsi_falcon_intr) &&
instance->hostt->can_queue > 1)
return 1;
if (in_interrupt()) if (in_interrupt())
return stdma_try_lock(scsi_falcon_intr, instance); return stdma_try_lock(scsi_falcon_intr, instance);
...@@ -495,8 +446,7 @@ static int __init atari_scsi_setup(char *str) ...@@ -495,8 +446,7 @@ static int __init atari_scsi_setup(char *str)
setup_sg_tablesize = ints[3]; setup_sg_tablesize = ints[3];
if (ints[0] >= 4) if (ints[0] >= 4)
setup_hostid = ints[4]; setup_hostid = ints[4];
if (ints[0] >= 5) /* ints[5] (use_tagged_queuing) is ignored */
setup_use_tagged_queuing = ints[5];
/* ints[6] (use_pdma) is ignored */ /* ints[6] (use_pdma) is ignored */
if (ints[0] >= 7) if (ints[0] >= 7)
setup_toshiba_delay = ints[7]; setup_toshiba_delay = ints[7];
...@@ -508,8 +458,6 @@ __setup("atascsi=", atari_scsi_setup); ...@@ -508,8 +458,6 @@ __setup("atascsi=", atari_scsi_setup);
#endif /* !MODULE */ #endif /* !MODULE */
#if defined(REAL_DMA)
static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
void *data, unsigned long count, void *data, unsigned long count,
int dir) int dir)
...@@ -545,9 +493,6 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance, ...@@ -545,9 +493,6 @@ static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
*/ */
dma_cache_maintenance(addr, count, dir); dma_cache_maintenance(addr, count, dir);
if (count == 0)
printk(KERN_NOTICE "SCSI warning: DMA programmed for 0 bytes !\n");
if (IS_A_TT()) { if (IS_A_TT()) {
tt_scsi_dma.dma_ctrl = dir; tt_scsi_dma.dma_ctrl = dir;
SCSI_DMA_WRITE_P(dma_addr, addr); SCSI_DMA_WRITE_P(dma_addr, addr);
...@@ -624,6 +569,9 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, ...@@ -624,6 +569,9 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
{ {
unsigned long possible_len, limit; unsigned long possible_len, limit;
if (wanted_len < DMA_MIN_SIZE)
return 0;
if (IS_A_TT()) if (IS_A_TT())
/* TT SCSI DMA can transfer arbitrary #bytes */ /* TT SCSI DMA can transfer arbitrary #bytes */
return wanted_len; return wanted_len;
...@@ -703,9 +651,6 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len, ...@@ -703,9 +651,6 @@ static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
} }
#endif /* REAL_DMA */
/* NCR5380 register access functions /* NCR5380 register access functions
* *
* There are separate functions for TT and Falcon, because the access * 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) ...@@ -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) static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
{ {
...@@ -745,7 +690,6 @@ 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); local_irq_save(flags);
#ifdef REAL_DMA
/* Abort a maybe active DMA transfer */ /* Abort a maybe active DMA transfer */
if (IS_A_TT()) { if (IS_A_TT()) {
tt_scsi_dma.dma_ctrl = 0; tt_scsi_dma.dma_ctrl = 0;
...@@ -754,7 +698,6 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd) ...@@ -754,7 +698,6 @@ static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
atari_dma_active = 0; atari_dma_active = 0;
atari_dma_orig_addr = NULL; atari_dma_orig_addr = NULL;
} }
#endif
rv = NCR5380_bus_reset(cmd); rv = NCR5380_bus_reset(cmd);
...@@ -781,6 +724,7 @@ static struct scsi_host_template atari_scsi_template = { ...@@ -781,6 +724,7 @@ static struct scsi_host_template atari_scsi_template = {
.eh_abort_handler = atari_scsi_abort, .eh_abort_handler = atari_scsi_abort,
.eh_bus_reset_handler = atari_scsi_bus_reset, .eh_bus_reset_handler = atari_scsi_bus_reset,
.this_id = 7, .this_id = 7,
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
}; };
...@@ -804,24 +748,11 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -804,24 +748,11 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
atari_scsi_reg_write = atari_scsi_falcon_reg_write; 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)) { if (ATARIHW_PRESENT(TT_SCSI)) {
atari_scsi_template.can_queue = 16; atari_scsi_template.can_queue = 16;
atari_scsi_template.cmd_per_lun = 8;
atari_scsi_template.sg_tablesize = SG_ALL; atari_scsi_template.sg_tablesize = SG_ALL;
} else { } else {
atari_scsi_template.can_queue = 8; atari_scsi_template.can_queue = 1;
atari_scsi_template.cmd_per_lun = 1;
atari_scsi_template.sg_tablesize = SG_NONE; atari_scsi_template.sg_tablesize = SG_NONE;
} }
...@@ -850,8 +781,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -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 /* 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 * memory block, since there's always ST-Ram in a Falcon), then
* allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers * allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
...@@ -867,7 +796,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -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_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
atari_dma_orig_addr = 0; atari_dma_orig_addr = 0;
} }
#endif
instance = scsi_host_alloc(&atari_scsi_template, instance = scsi_host_alloc(&atari_scsi_template,
sizeof(struct NCR5380_hostdata)); sizeof(struct NCR5380_hostdata));
...@@ -879,9 +807,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -879,9 +807,6 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
instance->irq = irq->start; instance->irq = irq->start;
host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP; 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; host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
error = NCR5380_init(instance, host_flags); error = NCR5380_init(instance, host_flags);
...@@ -897,7 +822,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -897,7 +822,7 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
goto fail_irq; goto fail_irq;
} }
tt_mfp.active_edge |= 0x80; /* SCSI int on L->H */ tt_mfp.active_edge |= 0x80; /* SCSI int on L->H */
#ifdef REAL_DMA
tt_scsi_dma.dma_ctrl = 0; tt_scsi_dma.dma_ctrl = 0;
atari_dma_residual = 0; atari_dma_residual = 0;
...@@ -919,17 +844,14 @@ static int __init atari_scsi_probe(struct platform_device *pdev) ...@@ -919,17 +844,14 @@ static int __init atari_scsi_probe(struct platform_device *pdev)
hostdata->read_overruns = 4; hostdata->read_overruns = 4;
} }
#endif
} else { } else {
/* Nothing to do for the interrupt: the ST-DMA is initialized /* Nothing to do for the interrupt: the ST-DMA is initialized
* already. * already.
*/ */
#ifdef REAL_DMA
atari_dma_residual = 0; atari_dma_residual = 0;
atari_dma_active = 0; atari_dma_active = 0;
atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000 atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
: 0xff000000); : 0xff000000);
#endif
} }
NCR5380_maybe_reset_bus(instance); NCR5380_maybe_reset_bus(instance);
......
...@@ -874,8 +874,8 @@ bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad, ...@@ -874,8 +874,8 @@ bfa_status_t bfa_fcb_rport_alloc(struct bfad_s *bfad,
/* /*
* itnim callbacks * itnim callbacks
*/ */
void bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim, int bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
struct bfad_itnim_s **itnim_drv); struct bfad_itnim_s **itnim_drv);
void bfa_fcb_itnim_free(struct bfad_s *bfad, void bfa_fcb_itnim_free(struct bfad_s *bfad,
struct bfad_itnim_s *itnim_drv); struct bfad_itnim_s *itnim_drv);
void bfa_fcb_itnim_online(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) ...@@ -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_lport_s *port = rport->port;
struct bfa_fcs_itnim_s *itnim; struct bfa_fcs_itnim_s *itnim;
struct bfad_itnim_s *itnim_drv; struct bfad_itnim_s *itnim_drv;
int ret;
/* /*
* call bfad to allocate the itnim * call bfad to allocate the itnim
*/ */
bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv); ret = bfa_fcb_itnim_alloc(port->fcs->bfad, &itnim, &itnim_drv);
if (itnim == NULL) { if (ret) {
bfa_trc(port->fcs, rport->pwwn); bfa_trc(port->fcs, rport->pwwn);
return NULL; return NULL;
} }
......
...@@ -440,13 +440,13 @@ bfad_im_slave_destroy(struct scsi_device *sdev) ...@@ -440,13 +440,13 @@ bfad_im_slave_destroy(struct scsi_device *sdev)
* BFA FCS itnim alloc callback, after successful PRLI * BFA FCS itnim alloc callback, after successful PRLI
* Context: Interrupt * Context: Interrupt
*/ */
void int
bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim, bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim,
struct bfad_itnim_s **itnim_drv) struct bfad_itnim_s **itnim_drv)
{ {
*itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC); *itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC);
if (*itnim_drv == NULL) if (*itnim_drv == NULL)
return; return -ENOMEM;
(*itnim_drv)->im = bfad->im; (*itnim_drv)->im = bfad->im;
*itnim = &(*itnim_drv)->fcs_itnim; *itnim = &(*itnim_drv)->fcs_itnim;
...@@ -457,6 +457,7 @@ bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **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); INIT_WORK(&(*itnim_drv)->itnim_work, bfad_im_itnim_work_handler);
bfad->bfad_flags |= BFAD_RPORT_ONLINE; bfad->bfad_flags |= BFAD_RPORT_ONLINE;
return 0;
} }
/* /*
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
#include "bnx2fc_constants.h" #include "bnx2fc_constants.h"
#define BNX2FC_NAME "bnx2fc" #define BNX2FC_NAME "bnx2fc"
#define BNX2FC_VERSION "2.9.6" #define BNX2FC_VERSION "2.10.3"
#define PFX "bnx2fc: " #define PFX "bnx2fc: "
...@@ -261,6 +261,7 @@ struct bnx2fc_interface { ...@@ -261,6 +261,7 @@ struct bnx2fc_interface {
u8 vlan_enabled; u8 vlan_enabled;
int vlan_id; int vlan_id;
bool enabled; bool enabled;
u8 tm_timeout;
}; };
#define bnx2fc_from_ctlr(x) \ #define bnx2fc_from_ctlr(x) \
......
此差异已折叠。
...@@ -179,12 +179,24 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code) ...@@ -179,12 +179,24 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
bnx2fc_unmap_sg_list(io_req); bnx2fc_unmap_sg_list(io_req);
io_req->sc_cmd = NULL; io_req->sc_cmd = NULL;
/* Sanity checks before returning command to mid-layer */
if (!sc_cmd) { if (!sc_cmd) {
printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. " printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. "
"IO(0x%x) already cleaned up\n", "IO(0x%x) already cleaned up\n",
io_req->xid); io_req->xid);
return; 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; sc_cmd->result = err_code << 16;
BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n", BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n",
...@@ -770,7 +782,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags) ...@@ -770,7 +782,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
spin_unlock_bh(&tgt->tgt_lock); spin_unlock_bh(&tgt->tgt_lock);
rc = wait_for_completion_timeout(&io_req->tm_done, rc = wait_for_completion_timeout(&io_req->tm_done,
BNX2FC_TM_TIMEOUT * HZ); interface->tm_timeout * HZ);
spin_lock_bh(&tgt->tgt_lock); spin_lock_bh(&tgt->tgt_lock);
io_req->wait_for_comp = 0; io_req->wait_for_comp = 0;
......
...@@ -675,7 +675,7 @@ bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid) ...@@ -675,7 +675,7 @@ bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{ {
struct list_head *list; struct list_head *list;
struct list_head *tmp; struct list_head *tmp;
struct bnx2i_endpoint *ep; struct bnx2i_endpoint *ep = NULL;
read_lock_bh(&hba->ep_rdwr_lock); read_lock_bh(&hba->ep_rdwr_lock);
list_for_each_safe(list, tmp, &hba->ep_ofld_list) { 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) ...@@ -703,7 +703,7 @@ bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid)
{ {
struct list_head *list; struct list_head *list;
struct list_head *tmp; struct list_head *tmp;
struct bnx2i_endpoint *ep; struct bnx2i_endpoint *ep = NULL;
read_lock_bh(&hba->ep_rdwr_lock); read_lock_bh(&hba->ep_rdwr_lock);
list_for_each_safe(list, tmp, &hba->ep_destroy_list) { list_for_each_safe(list, tmp, &hba->ep_destroy_list) {
......
此差异已折叠。
...@@ -1615,6 +1615,13 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi) ...@@ -1615,6 +1615,13 @@ static int recover_context(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
* place at the same time and the failure was due to CXL services being * place at the same time and the failure was due to CXL services being
* unable to keep up. * 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 * 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 * 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 * 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, ...@@ -1642,9 +1649,17 @@ static int cxlflash_afu_recover(struct scsi_device *sdev,
int rc = 0; int rc = 0;
atomic_inc(&cfg->recovery_threads); atomic_inc(&cfg->recovery_threads);
up_read(&cfg->ioctl_rwsem);
rc = mutex_lock_interruptible(mutex); rc = mutex_lock_interruptible(mutex);
down_read(&cfg->ioctl_rwsem);
if (rc) if (rc)
goto out; 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", dev_dbg(dev, "%s: reason 0x%016llX rctxid=%016llX\n",
__func__, recover->reason, rctxid); __func__, recover->reason, rctxid);
......
此差异已折叠。
此差异已折叠。
...@@ -21,14 +21,17 @@ ...@@ -21,14 +21,17 @@
#define NCR5380_dma_xfer_len(instance, cmd, phase) \ #define NCR5380_dma_xfer_len(instance, cmd, phase) \
dtc_dma_xfer_len(cmd) 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_intr dtc_intr
#define NCR5380_queue_command dtc_queue_command #define NCR5380_queue_command dtc_queue_command
#define NCR5380_abort dtc_abort #define NCR5380_abort dtc_abort
#define NCR5380_bus_reset dtc_bus_reset #define NCR5380_bus_reset dtc_bus_reset
#define NCR5380_info dtc_info #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 /* 15 12 11 10
1001 1100 0000 0000 */ 1001 1100 0000 0000 */
......
...@@ -729,6 +729,7 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev ...@@ -729,6 +729,7 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev
break; break;
case 0x24: case 0x24:
SD(sh)->EATA_revision = 'z'; SD(sh)->EATA_revision = 'z';
break;
default: default:
SD(sh)->EATA_revision = '?'; SD(sh)->EATA_revision = '?';
} }
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册