mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (73 commits) [SCSI] aic79xx: Add ASC-29320LPE ids to driver [SCSI] stex: version update [SCSI] stex: change wait loop code [SCSI] stex: add new device type support [SCSI] stex: update device id info [SCSI] stex: adjust default queue length [SCSI] stex: add value check in hard reset routine [SCSI] stex: fix controller_info command handling [SCSI] stex: fix biosparam calculation [SCSI] megaraid: fix MMIO casts [SCSI] tgt: fix undefined flush_dcache_page() problem [SCSI] libsas: better error handling in sas_expander.c [SCSI] lpfc 8.1.11 : Change version number to 8.1.11 [SCSI] lpfc 8.1.11 : Misc Fixes [SCSI] lpfc 8.1.11 : Add soft_wwnn sysfs attribute, rename soft_wwn_enable [SCSI] lpfc 8.1.11 : Removed decoding of PCI Subsystem Id [SCSI] lpfc 8.1.11 : Add MSI (Message Signalled Interrupts) support [SCSI] lpfc 8.1.11 : Adjust LOG_FCP logging [SCSI] lpfc 8.1.11 : Fix Memory leaks [SCSI] lpfc 8.1.11 : Fix lpfc_multi_ring_support ...
This commit is contained in:
@@ -1416,6 +1416,11 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
scsi_logging= [SCSI]
|
||||
|
||||
scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
|
||||
discovered. async scans them in kernel threads,
|
||||
allowing boot to proceed. none ignores them, expecting
|
||||
user space to do the scan.
|
||||
|
||||
selinux [SELINUX] Disable or enable SELinux at boot time.
|
||||
Format: { "0" | "1" }
|
||||
See security/selinux/Kconfig help text.
|
||||
|
||||
@@ -375,7 +375,6 @@ Summary:
|
||||
scsi_add_device - creates new scsi device (lu) instance
|
||||
scsi_add_host - perform sysfs registration and set up transport class
|
||||
scsi_adjust_queue_depth - change the queue depth on a SCSI device
|
||||
scsi_assign_lock - replace default host_lock with given lock
|
||||
scsi_bios_ptable - return copy of block device's partition table
|
||||
scsi_block_requests - prevent further commands being queued to given host
|
||||
scsi_deactivate_tcq - turn off tag command queueing
|
||||
@@ -488,20 +487,6 @@ void scsi_adjust_queue_depth(struct scsi_device * sdev, int tagged,
|
||||
int tags)
|
||||
|
||||
|
||||
/**
|
||||
* scsi_assign_lock - replace default host_lock with given lock
|
||||
* @shost: a pointer to a scsi host instance
|
||||
* @lock: pointer to lock to replace host_lock for this host
|
||||
*
|
||||
* Returns nothing
|
||||
*
|
||||
* Might block: no
|
||||
*
|
||||
* Defined in: include/scsi/scsi_host.h .
|
||||
**/
|
||||
void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
|
||||
|
||||
|
||||
/**
|
||||
* scsi_bios_ptable - return copy of block device's partition table
|
||||
* @dev: pointer to block device
|
||||
@@ -1366,17 +1351,11 @@ Locks
|
||||
Each struct Scsi_Host instance has a spin_lock called struct
|
||||
Scsi_Host::default_lock which is initialized in scsi_host_alloc() [found in
|
||||
hosts.c]. Within the same function the struct Scsi_Host::host_lock pointer
|
||||
is initialized to point at default_lock with the scsi_assign_lock() function.
|
||||
Thereafter lock and unlock operations performed by the mid level use the
|
||||
struct Scsi_Host::host_lock pointer.
|
||||
is initialized to point at default_lock. Thereafter lock and unlock
|
||||
operations performed by the mid level use the struct Scsi_Host::host_lock
|
||||
pointer. Previously drivers could override the host_lock pointer but
|
||||
this is not allowed anymore.
|
||||
|
||||
LLDs can override the use of struct Scsi_Host::default_lock by
|
||||
using scsi_assign_lock(). The earliest opportunity to do this would
|
||||
be in the detect() function after it has invoked scsi_register(). It
|
||||
could be replaced by a coarser grain lock (e.g. per driver) or a
|
||||
lock of equal granularity (i.e. per host). Using finer grain locks
|
||||
(e.g. per SCSI device) may be possible by juggling locks in
|
||||
queuecommand().
|
||||
|
||||
Autosense
|
||||
=========
|
||||
|
||||
@@ -277,7 +277,7 @@ static int sg_io(struct file *file, request_queue_t *q,
|
||||
if (rq->bio)
|
||||
blk_queue_bounce(q, &rq->bio);
|
||||
|
||||
rq->timeout = (hdr->timeout * HZ) / 1000;
|
||||
rq->timeout = jiffies_to_msecs(hdr->timeout);
|
||||
if (!rq->timeout)
|
||||
rq->timeout = q->sg_timeout;
|
||||
if (!rq->timeout)
|
||||
|
||||
@@ -622,8 +622,10 @@ NCR_700_scsi_done(struct NCR_700_Host_Parameters *hostdata,
|
||||
dma_unmap_single(hostdata->dev, slot->dma_handle, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
|
||||
/* restore the old result if the request sense was
|
||||
* successful */
|
||||
if(result == 0)
|
||||
if (result == 0)
|
||||
result = cmnd[7];
|
||||
/* restore the original length */
|
||||
SCp->cmd_len = cmnd[8];
|
||||
} else
|
||||
NCR_700_unmap(hostdata, SCp, slot);
|
||||
|
||||
@@ -1007,6 +1009,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
|
||||
* of the command */
|
||||
cmnd[6] = NCR_700_INTERNAL_SENSE_MAGIC;
|
||||
cmnd[7] = hostdata->status[0];
|
||||
cmnd[8] = SCp->cmd_len;
|
||||
SCp->cmd_len = 6; /* command length for
|
||||
* REQUEST_SENSE */
|
||||
slot->pCmd = dma_map_single(hostdata->dev, cmnd, MAX_COMMAND_SIZE, DMA_TO_DEVICE);
|
||||
slot->dma_handle = dma_map_single(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE);
|
||||
slot->SG[0].ins = bS_to_host(SCRIPT_MOVE_DATA_IN | sizeof(SCp->sense_buffer));
|
||||
|
||||
@@ -2186,21 +2186,21 @@ static int __init BusLogic_init(void)
|
||||
|
||||
if (BusLogic_ProbeOptions.NoProbe)
|
||||
return -ENODEV;
|
||||
BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *)
|
||||
kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_ATOMIC);
|
||||
BusLogic_ProbeInfoList =
|
||||
kzalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo), GFP_KERNEL);
|
||||
if (BusLogic_ProbeInfoList == NULL) {
|
||||
BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(BusLogic_ProbeInfoList, 0, BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo));
|
||||
PrototypeHostAdapter = (struct BusLogic_HostAdapter *)
|
||||
kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC);
|
||||
|
||||
PrototypeHostAdapter =
|
||||
kzalloc(sizeof(struct BusLogic_HostAdapter), GFP_KERNEL);
|
||||
if (PrototypeHostAdapter == NULL) {
|
||||
kfree(BusLogic_ProbeInfoList);
|
||||
BusLogic_Error("BusLogic: Unable to allocate Prototype " "Host Adapter\n", NULL);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
|
||||
|
||||
#ifdef MODULE
|
||||
if (BusLogic != NULL)
|
||||
BusLogic_Setup(BusLogic);
|
||||
|
||||
@@ -29,6 +29,13 @@ config SCSI
|
||||
However, do not compile this as a module if your root file system
|
||||
(the one containing the directory /) is located on a SCSI device.
|
||||
|
||||
config SCSI_TGT
|
||||
tristate "SCSI target support"
|
||||
depends on SCSI && EXPERIMENTAL
|
||||
---help---
|
||||
If you want to use SCSI target mode drivers enable this option.
|
||||
If you choose M, the module will be called scsi_tgt.
|
||||
|
||||
config SCSI_NETLINK
|
||||
bool
|
||||
default n
|
||||
@@ -216,6 +223,23 @@ config SCSI_LOGGING
|
||||
there should be no noticeable performance impact as long as you have
|
||||
logging turned off.
|
||||
|
||||
config SCSI_SCAN_ASYNC
|
||||
bool "Asynchronous SCSI scanning"
|
||||
depends on SCSI
|
||||
help
|
||||
The SCSI subsystem can probe for devices while the rest of the
|
||||
system continues booting, and even probe devices on different
|
||||
busses in parallel, leading to a significant speed-up.
|
||||
If you have built SCSI as modules, enabling this option can
|
||||
be a problem as the devices may not have been found by the
|
||||
time your system expects them to have been. You can load the
|
||||
scsi_wait_scan module to ensure that all scans have completed.
|
||||
If you build your SCSI drivers into the kernel, then everything
|
||||
will work fine if you say Y here.
|
||||
|
||||
You can override this choice by specifying scsi_mod.scan="sync"
|
||||
or "async" on the kernel's command line.
|
||||
|
||||
menu "SCSI Transports"
|
||||
depends on SCSI
|
||||
|
||||
@@ -797,6 +821,20 @@ config SCSI_IBMVSCSI
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ibmvscsic.
|
||||
|
||||
config SCSI_IBMVSCSIS
|
||||
tristate "IBM Virtual SCSI Server support"
|
||||
depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP
|
||||
help
|
||||
This is the SRP target driver for IBM pSeries virtual environments.
|
||||
|
||||
The userspace component needed to initialize the driver and
|
||||
documentation can be found:
|
||||
|
||||
http://stgt.berlios.de/
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ibmvstgt.
|
||||
|
||||
config SCSI_INITIO
|
||||
tristate "Initio 9100U(W) support"
|
||||
depends on PCI && SCSI
|
||||
@@ -944,8 +982,13 @@ config SCSI_STEX
|
||||
tristate "Promise SuperTrak EX Series support"
|
||||
depends on PCI && SCSI
|
||||
---help---
|
||||
This driver supports Promise SuperTrak EX8350/8300/16350/16300
|
||||
Storage controllers.
|
||||
This driver supports Promise SuperTrak EX series storage controllers.
|
||||
|
||||
Promise provides Linux RAID configuration utility for these
|
||||
controllers. Please visit <http://www.promise.com> to download.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stex.
|
||||
|
||||
config SCSI_SYM53C8XX_2
|
||||
tristate "SYM53C8XX Version 2 SCSI support"
|
||||
@@ -1026,6 +1069,7 @@ config SCSI_IPR
|
||||
config SCSI_IPR_TRACE
|
||||
bool "enable driver internal trace"
|
||||
depends on SCSI_IPR
|
||||
default y
|
||||
help
|
||||
If you say Y here, the driver will trace all commands issued
|
||||
to the adapter. Performance impact is minimal. Trace can be
|
||||
@@ -1034,6 +1078,7 @@ config SCSI_IPR_TRACE
|
||||
config SCSI_IPR_DUMP
|
||||
bool "enable adapter dump support"
|
||||
depends on SCSI_IPR
|
||||
default y
|
||||
help
|
||||
If you say Y here, the driver will support adapter crash dump.
|
||||
If you enable this support, the iprdump daemon can be used
|
||||
@@ -1734,6 +1779,16 @@ config ZFCP
|
||||
called zfcp. If you want to compile it as a module, say M here
|
||||
and read <file:Documentation/modules.txt>.
|
||||
|
||||
config SCSI_SRP
|
||||
tristate "SCSI RDMA Protocol helper library"
|
||||
depends on SCSI && PCI
|
||||
select SCSI_TGT
|
||||
help
|
||||
If you wish to use SRP target drivers, say Y.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called libsrp.
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/scsi/pcmcia/Kconfig"
|
||||
|
||||
@@ -21,6 +21,7 @@ CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
|
||||
subdir-$(CONFIG_PCMCIA) += pcmcia
|
||||
|
||||
obj-$(CONFIG_SCSI) += scsi_mod.o
|
||||
obj-$(CONFIG_SCSI_TGT) += scsi_tgt.o
|
||||
|
||||
obj-$(CONFIG_RAID_ATTRS) += raid_class.o
|
||||
|
||||
@@ -125,7 +126,9 @@ obj-$(CONFIG_SCSI_FCAL) += fcal.o
|
||||
obj-$(CONFIG_SCSI_LASI700) += 53c700.o lasi700.o
|
||||
obj-$(CONFIG_SCSI_NSP32) += nsp32.o
|
||||
obj-$(CONFIG_SCSI_IPR) += ipr.o
|
||||
obj-$(CONFIG_SCSI_SRP) += libsrp.o
|
||||
obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi/
|
||||
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsi/
|
||||
obj-$(CONFIG_SCSI_HPTIOP) += hptiop.o
|
||||
obj-$(CONFIG_SCSI_STEX) += stex.o
|
||||
|
||||
@@ -141,6 +144,8 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o
|
||||
# This goes last, so that "real" scsi devices probe earlier
|
||||
obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
|
||||
|
||||
obj-$(CONFIG_SCSI) += scsi_wait_scan.o
|
||||
|
||||
scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \
|
||||
scsicam.o scsi_error.o scsi_lib.o \
|
||||
scsi_scan.o scsi_sysfs.o \
|
||||
@@ -149,6 +154,8 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
|
||||
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
|
||||
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
|
||||
|
||||
scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
|
||||
|
||||
sd_mod-objs := sd.o
|
||||
sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o
|
||||
ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \
|
||||
|
||||
@@ -220,9 +220,11 @@ static void *addresses[] = {
|
||||
static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 };
|
||||
#define PORT_COUNT ARRAY_SIZE(ports)
|
||||
|
||||
#ifndef MODULE
|
||||
/* possible interrupt channels */
|
||||
static unsigned short intrs[] = { 10, 11, 12, 15 };
|
||||
#define INTR_COUNT ARRAY_SIZE(intrs)
|
||||
#endif /* !MODULE */
|
||||
|
||||
/* signatures for NCR 53c406a based controllers */
|
||||
#if USE_BIOS
|
||||
@@ -605,6 +607,7 @@ static int NCR53c406a_release(struct Scsi_Host *shost)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
/* called from init/main.c */
|
||||
static int __init NCR53c406a_setup(char *str)
|
||||
{
|
||||
@@ -661,6 +664,8 @@ static int __init NCR53c406a_setup(char *str)
|
||||
|
||||
__setup("ncr53c406a=", NCR53c406a_setup);
|
||||
|
||||
#endif /* !MODULE */
|
||||
|
||||
static const char *NCR53c406a_info(struct Scsi_Host *SChost)
|
||||
{
|
||||
DEB(printk("NCR53c406a_info called\n"));
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef AAC_DRIVER_BUILD
|
||||
# define AAC_DRIVER_BUILD 2409
|
||||
# define AAC_DRIVER_BRANCH "-mh2"
|
||||
# define AAC_DRIVER_BUILD 2423
|
||||
# define AAC_DRIVER_BRANCH "-mh3"
|
||||
#endif
|
||||
#define MAXIMUM_NUM_CONTAINERS 32
|
||||
|
||||
|
||||
@@ -518,6 +518,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
||||
*/
|
||||
unsigned long count = 36000000L; /* 3 minutes */
|
||||
while (down_trylock(&fibptr->event_wait)) {
|
||||
int blink;
|
||||
if (--count == 0) {
|
||||
spin_lock_irqsave(q->lock, qflags);
|
||||
q->numpending--;
|
||||
@@ -530,6 +531,14 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
if ((blink = aac_adapter_check_health(dev)) > 0) {
|
||||
if (wait == -1) {
|
||||
printk(KERN_ERR "aacraid: aac_fib_send: adapter blinkLED 0x%x.\n"
|
||||
"Usually a result of a serious unrecoverable hardware problem\n",
|
||||
blink);
|
||||
}
|
||||
return -EFAULT;
|
||||
}
|
||||
udelay(5);
|
||||
}
|
||||
} else if (down_interruptible(&fibptr->event_wait)) {
|
||||
@@ -1093,6 +1102,20 @@ static int _aac_reset_adapter(struct aac_dev *aac)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop through the fibs, close the synchronous FIBS
|
||||
*/
|
||||
for (index = 0; index < (aac->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); index++) {
|
||||
struct fib *fib = &aac->fibs[index];
|
||||
if (!(fib->hw_fib->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
|
||||
(fib->hw_fib->header.XferState & cpu_to_le32(ResponseExpected))) {
|
||||
unsigned long flagv;
|
||||
spin_lock_irqsave(&fib->event_lock, flagv);
|
||||
up(&fib->event_wait);
|
||||
spin_unlock_irqrestore(&fib->event_lock, flagv);
|
||||
schedule();
|
||||
}
|
||||
}
|
||||
index = aac->cardtype;
|
||||
|
||||
/*
|
||||
|
||||
@@ -586,7 +586,7 @@ static struct scsi_host_template aha1740_template = {
|
||||
|
||||
static int aha1740_probe (struct device *dev)
|
||||
{
|
||||
int slotbase;
|
||||
int slotbase, rc;
|
||||
unsigned int irq_level, irq_type, translation;
|
||||
struct Scsi_Host *shpnt;
|
||||
struct aha1740_hostdata *host;
|
||||
@@ -641,10 +641,16 @@ static int aha1740_probe (struct device *dev)
|
||||
}
|
||||
|
||||
eisa_set_drvdata (edev, shpnt);
|
||||
scsi_add_host (shpnt, dev); /* XXX handle failure */
|
||||
|
||||
rc = scsi_add_host (shpnt, dev);
|
||||
if (rc)
|
||||
goto err_irq;
|
||||
|
||||
scsi_scan_host (shpnt);
|
||||
return 0;
|
||||
|
||||
err_irq:
|
||||
free_irq(irq_level, shpnt);
|
||||
err_unmap:
|
||||
dma_unmap_single (&edev->dev, host->ecb_dma_addr,
|
||||
sizeof (host->ecb), DMA_BIDIRECTIONAL);
|
||||
|
||||
@@ -62,6 +62,7 @@ static struct pci_device_id ahd_linux_pci_id_table[] = {
|
||||
/* aic7901 based controllers */
|
||||
ID(ID_AHA_29320A),
|
||||
ID(ID_AHA_29320ALP),
|
||||
ID(ID_AHA_29320LPE),
|
||||
/* aic7902 based controllers */
|
||||
ID(ID_AHA_29320),
|
||||
ID(ID_AHA_29320B),
|
||||
|
||||
@@ -109,7 +109,13 @@ static struct ahd_pci_identity ahd_pci_ident_table [] =
|
||||
{
|
||||
ID_AHA_29320ALP,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 29320ALP Ultra320 SCSI adapter",
|
||||
"Adaptec 29320ALP PCIx Ultra320 SCSI adapter",
|
||||
ahd_aic7901_setup
|
||||
},
|
||||
{
|
||||
ID_AHA_29320LPE,
|
||||
ID_ALL_MASK,
|
||||
"Adaptec 29320LPE PCIe Ultra320 SCSI adapter",
|
||||
ahd_aic7901_setup
|
||||
},
|
||||
/* aic7901A based controllers */
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#define ID_AIC7901 0x800F9005FFFF9005ull
|
||||
#define ID_AHA_29320A 0x8000900500609005ull
|
||||
#define ID_AHA_29320ALP 0x8017900500449005ull
|
||||
#define ID_AHA_29320LPE 0x8017900500459005ull
|
||||
|
||||
#define ID_AIC7901A 0x801E9005FFFF9005ull
|
||||
#define ID_AHA_29320LP 0x8014900500449005ull
|
||||
|
||||
@@ -724,6 +724,15 @@ static void asd_free_queues(struct asd_ha_struct *asd_ha)
|
||||
|
||||
list_for_each_safe(pos, n, &pending) {
|
||||
struct asd_ascb *ascb = list_entry(pos, struct asd_ascb, list);
|
||||
/*
|
||||
* Delete unexpired ascb timers. This may happen if we issue
|
||||
* a CONTROL PHY scb to an adapter and rmmod before the scb
|
||||
* times out. Apparently we don't wait for the CONTROL PHY
|
||||
* to complete, so it doesn't matter if we kill the timer.
|
||||
*/
|
||||
del_timer_sync(&ascb->timer);
|
||||
WARN_ON(ascb->scb->header.opcode != CONTROL_PHY);
|
||||
|
||||
list_del_init(pos);
|
||||
ASD_DPRINTK("freeing from pending\n");
|
||||
asd_ascb_free(ascb);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
|
||||
#include "aic94xx.h"
|
||||
#include "aic94xx_reg.h"
|
||||
@@ -412,6 +413,39 @@ void asd_invalidate_edb(struct asd_ascb *ascb, int edb_id)
|
||||
}
|
||||
}
|
||||
|
||||
/* hard reset a phy later */
|
||||
static void do_phy_reset_later(void *data)
|
||||
{
|
||||
struct sas_phy *sas_phy = data;
|
||||
int error;
|
||||
|
||||
ASD_DPRINTK("%s: About to hard reset phy %d\n", __FUNCTION__,
|
||||
sas_phy->identify.phy_identifier);
|
||||
/* Reset device port */
|
||||
error = sas_phy_reset(sas_phy, 1);
|
||||
if (error)
|
||||
ASD_DPRINTK("%s: Hard reset of phy %d failed (%d).\n",
|
||||
__FUNCTION__, sas_phy->identify.phy_identifier, error);
|
||||
}
|
||||
|
||||
static void phy_reset_later(struct sas_phy *sas_phy, struct Scsi_Host *shost)
|
||||
{
|
||||
INIT_WORK(&sas_phy->reset_work, do_phy_reset_later, sas_phy);
|
||||
queue_work(shost->work_q, &sas_phy->reset_work);
|
||||
}
|
||||
|
||||
/* start up the ABORT TASK tmf... */
|
||||
static void task_kill_later(struct asd_ascb *ascb)
|
||||
{
|
||||
struct asd_ha_struct *asd_ha = ascb->ha;
|
||||
struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
|
||||
struct Scsi_Host *shost = sas_ha->core.shost;
|
||||
struct sas_task *task = ascb->uldd_task;
|
||||
|
||||
INIT_WORK(&task->abort_work, (void (*)(void *))sas_task_abort, task);
|
||||
queue_work(shost->work_q, &task->abort_work);
|
||||
}
|
||||
|
||||
static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
struct done_list_struct *dl)
|
||||
{
|
||||
@@ -439,6 +473,74 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
ascb->scb->header.opcode);
|
||||
}
|
||||
|
||||
/* Catch these before we mask off the sb_opcode bits */
|
||||
switch (sb_opcode) {
|
||||
case REQ_TASK_ABORT: {
|
||||
struct asd_ascb *a, *b;
|
||||
u16 tc_abort;
|
||||
|
||||
tc_abort = *((u16*)(&dl->status_block[1]));
|
||||
tc_abort = le16_to_cpu(tc_abort);
|
||||
|
||||
ASD_DPRINTK("%s: REQ_TASK_ABORT, reason=0x%X\n",
|
||||
__FUNCTION__, dl->status_block[3]);
|
||||
|
||||
/* Find the pending task and abort it. */
|
||||
list_for_each_entry_safe(a, b, &asd_ha->seq.pend_q, list)
|
||||
if (a->tc_index == tc_abort) {
|
||||
task_kill_later(a);
|
||||
break;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
case REQ_DEVICE_RESET: {
|
||||
struct Scsi_Host *shost = sas_ha->core.shost;
|
||||
struct sas_phy *dev_phy;
|
||||
struct asd_ascb *a;
|
||||
u16 conn_handle;
|
||||
|
||||
conn_handle = *((u16*)(&dl->status_block[1]));
|
||||
conn_handle = le16_to_cpu(conn_handle);
|
||||
|
||||
ASD_DPRINTK("%s: REQ_DEVICE_RESET, reason=0x%X\n", __FUNCTION__,
|
||||
dl->status_block[3]);
|
||||
|
||||
/* Kill all pending tasks and reset the device */
|
||||
dev_phy = NULL;
|
||||
list_for_each_entry(a, &asd_ha->seq.pend_q, list) {
|
||||
struct sas_task *task;
|
||||
struct domain_device *dev;
|
||||
u16 x;
|
||||
|
||||
task = a->uldd_task;
|
||||
if (!task)
|
||||
continue;
|
||||
dev = task->dev;
|
||||
|
||||
x = (unsigned long)dev->lldd_dev;
|
||||
if (x == conn_handle) {
|
||||
dev_phy = dev->port->phy;
|
||||
task_kill_later(a);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset device port */
|
||||
if (!dev_phy) {
|
||||
ASD_DPRINTK("%s: No pending commands; can't reset.\n",
|
||||
__FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
phy_reset_later(dev_phy, shost);
|
||||
goto out;
|
||||
}
|
||||
case SIGNAL_NCQ_ERROR:
|
||||
ASD_DPRINTK("%s: SIGNAL_NCQ_ERROR\n", __FUNCTION__);
|
||||
goto out;
|
||||
case CLEAR_NCQ_ERROR:
|
||||
ASD_DPRINTK("%s: CLEAR_NCQ_ERROR\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
sb_opcode &= ~DL_PHY_MASK;
|
||||
|
||||
switch (sb_opcode) {
|
||||
@@ -469,22 +571,6 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
asd_deform_port(asd_ha, phy);
|
||||
sas_ha->notify_port_event(sas_phy, PORTE_TIMER_EVENT);
|
||||
break;
|
||||
case REQ_TASK_ABORT:
|
||||
ASD_DPRINTK("%s: phy%d: REQ_TASK_ABORT\n", __FUNCTION__,
|
||||
phy_id);
|
||||
break;
|
||||
case REQ_DEVICE_RESET:
|
||||
ASD_DPRINTK("%s: phy%d: REQ_DEVICE_RESET\n", __FUNCTION__,
|
||||
phy_id);
|
||||
break;
|
||||
case SIGNAL_NCQ_ERROR:
|
||||
ASD_DPRINTK("%s: phy%d: SIGNAL_NCQ_ERROR\n", __FUNCTION__,
|
||||
phy_id);
|
||||
break;
|
||||
case CLEAR_NCQ_ERROR:
|
||||
ASD_DPRINTK("%s: phy%d: CLEAR_NCQ_ERROR\n", __FUNCTION__,
|
||||
phy_id);
|
||||
break;
|
||||
default:
|
||||
ASD_DPRINTK("%s: phy%d: unknown event:0x%x\n", __FUNCTION__,
|
||||
phy_id, sb_opcode);
|
||||
@@ -504,7 +590,7 @@ static void escb_tasklet_complete(struct asd_ascb *ascb,
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
asd_invalidate_edb(ascb, edb);
|
||||
}
|
||||
|
||||
|
||||
@@ -294,6 +294,7 @@ static struct Scsi_Host *hosts[FD_MAX_HOSTS + 1] = { NULL };
|
||||
static int user_fifo_count = 0;
|
||||
static int user_fifo_size = 0;
|
||||
|
||||
#ifndef MODULE
|
||||
static int __init fd_mcs_setup(char *str)
|
||||
{
|
||||
static int done_setup = 0;
|
||||
@@ -311,6 +312,7 @@ static int __init fd_mcs_setup(char *str)
|
||||
}
|
||||
|
||||
__setup("fd_mcs=", fd_mcs_setup);
|
||||
#endif /* !MODULE */
|
||||
|
||||
static void print_banner(struct Scsi_Host *shpnt)
|
||||
{
|
||||
|
||||
@@ -263,6 +263,10 @@ static void scsi_host_dev_release(struct device *dev)
|
||||
kthread_stop(shost->ehandler);
|
||||
if (shost->work_q)
|
||||
destroy_workqueue(shost->work_q);
|
||||
if (shost->uspace_req_q) {
|
||||
kfree(shost->uspace_req_q->queuedata);
|
||||
scsi_free_queue(shost->uspace_req_q);
|
||||
}
|
||||
|
||||
scsi_destroy_command_freelist(shost);
|
||||
if (shost->bqt)
|
||||
@@ -301,8 +305,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
|
||||
if (!shost)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&shost->default_lock);
|
||||
scsi_assign_lock(shost, &shost->default_lock);
|
||||
shost->host_lock = &shost->default_lock;
|
||||
spin_lock_init(shost->host_lock);
|
||||
shost->shost_state = SHOST_CREATED;
|
||||
INIT_LIST_HEAD(&shost->__devices);
|
||||
INIT_LIST_HEAD(&shost->__targets);
|
||||
|
||||
@@ -3,3 +3,5 @@ obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o
|
||||
ibmvscsic-y += ibmvscsi.o
|
||||
ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o
|
||||
ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o
|
||||
|
||||
obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o
|
||||
|
||||
958
drivers/scsi/ibmvscsi/ibmvstgt.c
Normal file
958
drivers/scsi/ibmvscsi/ibmvstgt.c
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user