You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This is a large set of updates, mostly for drivers (qla2xxx [including support for new 83xx based card], qla4xxx, mpt2sas, bfa, zfcp, hpsa, be2iscsi, isci, lpfc, ipr, ibmvfc, ibmvscsi, megaraid_sas). There's also a rework for tape adding virtually unlimited numbers of tape drives plus a set of dif fixes for sd and a fix for a live lock on hot remove of SCSI devices. This round includes a signed tag pull of isci-for-3.6 Signed-off-by: James Bottomley <JBottomley@Parallels.com>" Fix up trivial conflict in drivers/scsi/qla2xxx/qla_nx.c due to new PCI helper function use in a function that was removed by this pull. * tag 'scsi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (198 commits) [SCSI] st: remove st_mutex [SCSI] sd: Ensure we correctly disable devices with unknown protection type [SCSI] hpsa: gen8plus Smart Array IDs [SCSI] qla4xxx: Update driver version to 5.03.00-k1 [SCSI] qla4xxx: Disable generating pause frames for ISP83XX [SCSI] qla4xxx: Fix double clearing of risc_intr for ISP83XX [SCSI] qla4xxx: IDC implementation for Loopback [SCSI] qla4xxx: update copyrights in LICENSE.qla4xxx [SCSI] qla4xxx: Fix panic while rmmod [SCSI] qla4xxx: Fail probe_adapter if IRQ allocation fails [SCSI] qla4xxx: Prevent MSI/MSI-X falling back to INTx for ISP82XX [SCSI] qla4xxx: Update idc reg in case of PCI AER [SCSI] qla4xxx: Fix double IDC locking in qla4_8xxx_error_recovery [SCSI] qla4xxx: Clear interrupt while unloading driver for ISP83XX [SCSI] qla4xxx: Print correct IDC version [SCSI] qla4xxx: Added new mbox cmd to pass driver version to FW [SCSI] scsi_dh_alua: Enable STPG for unavailable ports [SCSI] scsi_remove_target: fix softlockup regression on hot remove [SCSI] ibmvscsi: Fix host config length field overflow [SCSI] ibmvscsi: Remove backend abstraction ...
This commit is contained in:
@@ -1350,6 +1350,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
* nohrst, nosrst, norst: suppress hard, soft
|
||||
and both resets.
|
||||
|
||||
* rstonce: only attempt one reset during
|
||||
hot-unplug link recovery
|
||||
|
||||
* dump_id: dump IDENTIFY data.
|
||||
|
||||
If there are multiple matching configurations changing
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
Release Date : Tue. Jun 17, 2012 17:00:00 PST 2012 -
|
||||
(emaild-id:megaraidlinux@lsi.com)
|
||||
Adam Radford/Kashyap Desai
|
||||
Current Version : 00.00.06.18-rc1
|
||||
Old Version : 00.00.06.15-rc1
|
||||
1. Fix Copyright dates.
|
||||
2. Add throttlequeuedepth module parameter.
|
||||
3. Add resetwaittime module parameter.
|
||||
4. Move poll_aen_lock initializer.
|
||||
-------------------------------------------------------------------------------
|
||||
Release Date : Mon. Mar 19, 2012 17:00:00 PST 2012 -
|
||||
(emaild-id:megaraidlinux@lsi.com)
|
||||
Adam Radford
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2003-2011 QLogic Corporation
|
||||
Copyright (c) 2003-2012 QLogic Corporation
|
||||
QLogic Linux FC-FCoE Driver
|
||||
|
||||
This program includes a device driver for Linux 3.x.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2003-2011 QLogic Corporation
|
||||
Copyright (c) 2003-2012 QLogic Corporation
|
||||
QLogic Linux iSCSI Driver
|
||||
|
||||
This program includes a device driver for Linux 3.x.
|
||||
|
||||
@@ -112,10 +112,8 @@ attempted).
|
||||
|
||||
MINOR NUMBERS
|
||||
|
||||
The tape driver currently supports 128 drives by default. This number
|
||||
can be increased by editing st.h and recompiling the driver if
|
||||
necessary. The upper limit is 2^17 drives if 4 modes for each drive
|
||||
are used.
|
||||
The tape driver currently supports up to 2^17 drives if 4 modes for
|
||||
each drive are used.
|
||||
|
||||
The minor numbers consist of the following bit fields:
|
||||
|
||||
|
||||
+7
-1
@@ -1650,7 +1650,6 @@ F: drivers/bcma/
|
||||
F: include/linux/bcma/
|
||||
|
||||
BROCADE BFA FC SCSI DRIVER
|
||||
M: Jing Huang <huangj@brocade.com>
|
||||
M: Krishna C Gudipati <kgudipat@brocade.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
@@ -3438,6 +3437,13 @@ L: netdev@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/net/ethernet/ibm/ibmveth.*
|
||||
|
||||
IBM Power Virtual SCSI/FC Device Drivers
|
||||
M: Robert Jennings <rcj@linux.vnet.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ibmvscsi/
|
||||
X: drivers/scsi/ibmvscsi/ibmvstgt.c
|
||||
|
||||
IBM ServeRAID RAID DRIVER
|
||||
P: Jack Hammer
|
||||
M: Dave Jeffery <ipslinux@adaptec.com>
|
||||
|
||||
+49
-20
@@ -5273,16 +5273,20 @@ bool ata_link_offline(struct ata_link *link)
|
||||
#ifdef CONFIG_PM
|
||||
static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
|
||||
unsigned int action, unsigned int ehi_flags,
|
||||
int wait)
|
||||
int *async)
|
||||
{
|
||||
struct ata_link *link;
|
||||
unsigned long flags;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
/* Previous resume operation might still be in
|
||||
* progress. Wait for PM_PENDING to clear.
|
||||
*/
|
||||
if (ap->pflags & ATA_PFLAG_PM_PENDING) {
|
||||
if (async) {
|
||||
*async = -EAGAIN;
|
||||
return 0;
|
||||
}
|
||||
ata_port_wait_eh(ap);
|
||||
WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
|
||||
}
|
||||
@@ -5291,10 +5295,10 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
|
||||
spin_lock_irqsave(ap->lock, flags);
|
||||
|
||||
ap->pm_mesg = mesg;
|
||||
if (wait) {
|
||||
rc = 0;
|
||||
if (async)
|
||||
ap->pm_result = async;
|
||||
else
|
||||
ap->pm_result = &rc;
|
||||
}
|
||||
|
||||
ap->pflags |= ATA_PFLAG_PM_PENDING;
|
||||
ata_for_each_link(link, ap, HOST_FIRST) {
|
||||
@@ -5307,7 +5311,7 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
|
||||
spin_unlock_irqrestore(ap->lock, flags);
|
||||
|
||||
/* wait and check result */
|
||||
if (wait) {
|
||||
if (!async) {
|
||||
ata_port_wait_eh(ap);
|
||||
WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING);
|
||||
}
|
||||
@@ -5315,9 +5319,8 @@ static int ata_port_request_pm(struct ata_port *ap, pm_message_t mesg,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
|
||||
static int __ata_port_suspend_common(struct ata_port *ap, pm_message_t mesg, int *async)
|
||||
{
|
||||
struct ata_port *ap = to_ata_port(dev);
|
||||
unsigned int ehi_flags = ATA_EHI_QUIET;
|
||||
int rc;
|
||||
|
||||
@@ -5332,10 +5335,17 @@ static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
|
||||
if (mesg.event == PM_EVENT_SUSPEND)
|
||||
ehi_flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_NO_RECOVERY;
|
||||
|
||||
rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, 1);
|
||||
rc = ata_port_request_pm(ap, mesg, 0, ehi_flags, async);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ata_port_suspend_common(struct device *dev, pm_message_t mesg)
|
||||
{
|
||||
struct ata_port *ap = to_ata_port(dev);
|
||||
|
||||
return __ata_port_suspend_common(ap, mesg, NULL);
|
||||
}
|
||||
|
||||
static int ata_port_suspend(struct device *dev)
|
||||
{
|
||||
if (pm_runtime_suspended(dev))
|
||||
@@ -5360,16 +5370,22 @@ static int ata_port_poweroff(struct device *dev)
|
||||
return ata_port_suspend_common(dev, PMSG_HIBERNATE);
|
||||
}
|
||||
|
||||
static int ata_port_resume_common(struct device *dev)
|
||||
static int __ata_port_resume_common(struct ata_port *ap, int *async)
|
||||
{
|
||||
struct ata_port *ap = to_ata_port(dev);
|
||||
int rc;
|
||||
|
||||
rc = ata_port_request_pm(ap, PMSG_ON, ATA_EH_RESET,
|
||||
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 1);
|
||||
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, async);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int ata_port_resume_common(struct device *dev)
|
||||
{
|
||||
struct ata_port *ap = to_ata_port(dev);
|
||||
|
||||
return __ata_port_resume_common(ap, NULL);
|
||||
}
|
||||
|
||||
static int ata_port_resume(struct device *dev)
|
||||
{
|
||||
int rc;
|
||||
@@ -5402,6 +5418,24 @@ static const struct dev_pm_ops ata_port_pm_ops = {
|
||||
.runtime_idle = ata_port_runtime_idle,
|
||||
};
|
||||
|
||||
/* sas ports don't participate in pm runtime management of ata_ports,
|
||||
* and need to resume ata devices at the domain level, not the per-port
|
||||
* level. sas suspend/resume is async to allow parallel port recovery
|
||||
* since sas has multiple ata_port instances per Scsi_Host.
|
||||
*/
|
||||
int ata_sas_port_async_suspend(struct ata_port *ap, int *async)
|
||||
{
|
||||
return __ata_port_suspend_common(ap, PMSG_SUSPEND, async);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sas_port_async_suspend);
|
||||
|
||||
int ata_sas_port_async_resume(struct ata_port *ap, int *async)
|
||||
{
|
||||
return __ata_port_resume_common(ap, async);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ata_sas_port_async_resume);
|
||||
|
||||
|
||||
/**
|
||||
* ata_host_suspend - suspend host
|
||||
* @host: host to suspend
|
||||
@@ -5947,24 +5981,18 @@ int ata_host_start(struct ata_host *host)
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_sas_host_init - Initialize a host struct
|
||||
* ata_sas_host_init - Initialize a host struct for sas (ipr, libsas)
|
||||
* @host: host to initialize
|
||||
* @dev: device host is attached to
|
||||
* @flags: host flags
|
||||
* @ops: port_ops
|
||||
*
|
||||
* LOCKING:
|
||||
* PCI/etc. bus probe sem.
|
||||
*
|
||||
*/
|
||||
/* KILLME - the only user left is ipr */
|
||||
void ata_host_init(struct ata_host *host, struct device *dev,
|
||||
unsigned long flags, struct ata_port_operations *ops)
|
||||
struct ata_port_operations *ops)
|
||||
{
|
||||
spin_lock_init(&host->lock);
|
||||
mutex_init(&host->eh_mutex);
|
||||
host->dev = dev;
|
||||
host->flags = flags;
|
||||
host->ops = ops;
|
||||
}
|
||||
|
||||
@@ -6408,6 +6436,7 @@ static int __init ata_parse_force_one(char **cur,
|
||||
{ "nohrst", .lflags = ATA_LFLAG_NO_HRST },
|
||||
{ "nosrst", .lflags = ATA_LFLAG_NO_SRST },
|
||||
{ "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
|
||||
{ "rstonce", .lflags = ATA_LFLAG_RST_ONCE },
|
||||
};
|
||||
char *start = *cur, *p = *cur;
|
||||
char *id, *val, *endp;
|
||||
|
||||
@@ -2625,6 +2625,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
|
||||
*/
|
||||
while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX)
|
||||
max_tries++;
|
||||
if (link->flags & ATA_LFLAG_RST_ONCE)
|
||||
max_tries = 1;
|
||||
if (link->flags & ATA_LFLAG_NO_HRST)
|
||||
hardreset = NULL;
|
||||
if (link->flags & ATA_LFLAG_NO_SRST)
|
||||
|
||||
@@ -1666,7 +1666,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
|
||||
if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
|
||||
printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
|
||||
"MEM failed\n", ioc->name);
|
||||
return r;
|
||||
goto out_pci_disable_device;
|
||||
}
|
||||
|
||||
if (sizeof(dma_addr_t) > 4) {
|
||||
@@ -1690,8 +1690,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
|
||||
} else {
|
||||
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
|
||||
ioc->name, pci_name(pdev));
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
return r;
|
||||
goto out_pci_release_region;
|
||||
}
|
||||
} else {
|
||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
|
||||
@@ -1704,8 +1703,7 @@ mpt_mapresources(MPT_ADAPTER *ioc)
|
||||
} else {
|
||||
printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
|
||||
ioc->name, pci_name(pdev));
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
return r;
|
||||
goto out_pci_release_region;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1735,8 +1733,8 @@ mpt_mapresources(MPT_ADAPTER *ioc)
|
||||
if (mem == NULL) {
|
||||
printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
|
||||
" memory!\n", ioc->name);
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
return -EINVAL;
|
||||
r = -EINVAL;
|
||||
goto out_pci_release_region;
|
||||
}
|
||||
ioc->memmap = mem;
|
||||
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
|
||||
@@ -1750,6 +1748,12 @@ mpt_mapresources(MPT_ADAPTER *ioc)
|
||||
ioc->pio_chip = (SYSIF_REGS __iomem *)port;
|
||||
|
||||
return 0;
|
||||
|
||||
out_pci_release_region:
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
out_pci_disable_device:
|
||||
pci_disable_device(pdev);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||
|
||||
@@ -519,6 +519,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
|
||||
|
||||
rwlock_init(&port->unit_list_lock);
|
||||
INIT_LIST_HEAD(&port->unit_list);
|
||||
atomic_set(&port->units, 0);
|
||||
|
||||
INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
|
||||
INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
|
||||
|
||||
@@ -39,19 +39,25 @@ void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter)
|
||||
spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags);
|
||||
}
|
||||
|
||||
static int zfcp_ccw_activate(struct ccw_device *cdev)
|
||||
|
||||
/**
|
||||
* zfcp_ccw_activate - activate adapter and wait for it to finish
|
||||
* @cdev: pointer to belonging ccw device
|
||||
* @clear: Status flags to clear.
|
||||
* @tag: s390dbf trace record tag
|
||||
*/
|
||||
static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
|
||||
{
|
||||
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
|
||||
|
||||
if (!adapter)
|
||||
return 0;
|
||||
|
||||
zfcp_erp_clear_adapter_status(adapter, clear);
|
||||
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"ccresu2");
|
||||
tag);
|
||||
zfcp_erp_wait(adapter);
|
||||
flush_work(&adapter->scan_work);
|
||||
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
|
||||
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
|
||||
@@ -164,7 +170,36 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
|
||||
BUG_ON(!zfcp_reqlist_isempty(adapter->req_list));
|
||||
adapter->req_no = 0;
|
||||
|
||||
zfcp_ccw_activate(cdev);
|
||||
zfcp_ccw_activate(cdev, 0, "ccsonl1");
|
||||
/* scan for remote ports
|
||||
either at the end of any successful adapter recovery
|
||||
or only after the adapter recovery for setting a device online */
|
||||
zfcp_fc_inverse_conditional_port_scan(adapter);
|
||||
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_ccw_offline_sync - shut down adapter and wait for it to finish
|
||||
* @cdev: pointer to belonging ccw device
|
||||
* @set: Status flags to set.
|
||||
* @tag: s390dbf trace record tag
|
||||
*
|
||||
* This function gets called by the common i/o layer and sets an adapter
|
||||
* into state offline.
|
||||
*/
|
||||
static int zfcp_ccw_offline_sync(struct ccw_device *cdev, int set, char *tag)
|
||||
{
|
||||
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
|
||||
|
||||
if (!adapter)
|
||||
return 0;
|
||||
|
||||
zfcp_erp_set_adapter_status(adapter, set);
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, tag);
|
||||
zfcp_erp_wait(adapter);
|
||||
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
return 0;
|
||||
}
|
||||
@@ -178,16 +213,7 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
|
||||
*/
|
||||
static int zfcp_ccw_set_offline(struct ccw_device *cdev)
|
||||
{
|
||||
struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev);
|
||||
|
||||
if (!adapter)
|
||||
return 0;
|
||||
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1");
|
||||
zfcp_erp_wait(adapter);
|
||||
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
return 0;
|
||||
return zfcp_ccw_offline_sync(cdev, 0, "ccsoff1");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -207,6 +233,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
|
||||
|
||||
switch (event) {
|
||||
case CIO_GONE:
|
||||
if (atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
|
||||
zfcp_dbf_hba_basic("ccnigo1", adapter);
|
||||
break;
|
||||
}
|
||||
dev_warn(&cdev->dev, "The FCP device has been detached\n");
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1");
|
||||
break;
|
||||
@@ -216,6 +247,11 @@ static int zfcp_ccw_notify(struct ccw_device *cdev, int event)
|
||||
zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2");
|
||||
break;
|
||||
case CIO_OPER:
|
||||
if (atomic_read(&adapter->status) &
|
||||
ZFCP_STATUS_ADAPTER_SUSPENDED) { /* notification ignore */
|
||||
zfcp_dbf_hba_basic("ccniop1", adapter);
|
||||
break;
|
||||
}
|
||||
dev_info(&cdev->dev, "The FCP device is operational again\n");
|
||||
zfcp_erp_set_adapter_status(adapter,
|
||||
ZFCP_STATUS_COMMON_RUNNING);
|
||||
@@ -251,6 +287,28 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
}
|
||||
|
||||
static int zfcp_ccw_suspend(struct ccw_device *cdev)
|
||||
{
|
||||
zfcp_ccw_offline_sync(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccsusp1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zfcp_ccw_thaw(struct ccw_device *cdev)
|
||||
{
|
||||
/* trace records for thaw and final shutdown during suspend
|
||||
can only be found in system dump until the end of suspend
|
||||
but not after resume because it's based on the memory image
|
||||
right after the very first suspend (freeze) callback */
|
||||
zfcp_ccw_activate(cdev, 0, "ccthaw1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int zfcp_ccw_resume(struct ccw_device *cdev)
|
||||
{
|
||||
zfcp_ccw_activate(cdev, ZFCP_STATUS_ADAPTER_SUSPENDED, "ccresu1");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ccw_driver zfcp_ccw_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
@@ -263,7 +321,7 @@ struct ccw_driver zfcp_ccw_driver = {
|
||||
.set_offline = zfcp_ccw_set_offline,
|
||||
.notify = zfcp_ccw_notify,
|
||||
.shutdown = zfcp_ccw_shutdown,
|
||||
.freeze = zfcp_ccw_set_offline,
|
||||
.thaw = zfcp_ccw_activate,
|
||||
.restore = zfcp_ccw_activate,
|
||||
.freeze = zfcp_ccw_suspend,
|
||||
.thaw = zfcp_ccw_thaw,
|
||||
.restore = zfcp_ccw_resume,
|
||||
};
|
||||
|
||||
@@ -293,7 +293,7 @@ void zfcp_cfdc_adapter_access_changed(struct zfcp_adapter *adapter)
|
||||
}
|
||||
read_unlock_irqrestore(&adapter->port_list_lock, flags);
|
||||
|
||||
shost_for_each_device(sdev, port->adapter->scsi_host) {
|
||||
shost_for_each_device(sdev, adapter->scsi_host) {
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
status = atomic_read(&zfcp_sdev->status);
|
||||
if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
|
||||
|
||||
@@ -191,7 +191,7 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
|
||||
length = min((u16)sizeof(struct qdio_buffer),
|
||||
(u16)ZFCP_DBF_PAY_MAX_REC);
|
||||
|
||||
while ((char *)pl[payload->counter] && payload->counter < scount) {
|
||||
while (payload->counter < scount && (char *)pl[payload->counter]) {
|
||||
memcpy(payload->data, (char *)pl[payload->counter], length);
|
||||
debug_event(dbf->pay, 1, payload, zfcp_dbf_plen(length));
|
||||
payload->counter++;
|
||||
@@ -200,6 +200,26 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
|
||||
spin_unlock_irqrestore(&dbf->pay_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_dbf_hba_basic - trace event for basic adapter events
|
||||
* @adapter: pointer to struct zfcp_adapter
|
||||
*/
|
||||
void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_dbf *dbf = adapter->dbf;
|
||||
struct zfcp_dbf_hba *rec = &dbf->hba_buf;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dbf->hba_lock, flags);
|
||||
memset(rec, 0, sizeof(*rec));
|
||||
|
||||
memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
|
||||
rec->id = ZFCP_DBF_HBA_BASIC;
|
||||
|
||||
debug_event(dbf->hba, 1, rec, sizeof(*rec));
|
||||
spin_unlock_irqrestore(&dbf->hba_lock, flags);
|
||||
}
|
||||
|
||||
static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
|
||||
struct zfcp_adapter *adapter,
|
||||
struct zfcp_port *port,
|
||||
|
||||
@@ -154,6 +154,7 @@ enum zfcp_dbf_hba_id {
|
||||
ZFCP_DBF_HBA_RES = 1,
|
||||
ZFCP_DBF_HBA_USS = 2,
|
||||
ZFCP_DBF_HBA_BIT = 3,
|
||||
ZFCP_DBF_HBA_BASIC = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -77,6 +77,7 @@ struct zfcp_reqlist;
|
||||
#define ZFCP_STATUS_ADAPTER_SIOSL_ISSUED 0x00000004
|
||||
#define ZFCP_STATUS_ADAPTER_XCONFIG_OK 0x00000008
|
||||
#define ZFCP_STATUS_ADAPTER_HOST_CON_INIT 0x00000010
|
||||
#define ZFCP_STATUS_ADAPTER_SUSPENDED 0x00000040
|
||||
#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100
|
||||
#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200
|
||||
#define ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED 0x00000400
|
||||
@@ -204,6 +205,7 @@ struct zfcp_port {
|
||||
struct zfcp_adapter *adapter; /* adapter used to access port */
|
||||
struct list_head unit_list; /* head of logical unit list */
|
||||
rwlock_t unit_list_lock; /* unit list lock */
|
||||
atomic_t units; /* zfcp_unit count */
|
||||
atomic_t status; /* status of this remote port */
|
||||
u64 wwnn; /* WWNN if known */
|
||||
u64 wwpn; /* WWPN */
|
||||
|
||||
@@ -1230,7 +1230,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
|
||||
case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
|
||||
if (result == ZFCP_ERP_SUCCEEDED) {
|
||||
register_service_level(&adapter->service_level);
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
zfcp_fc_conditional_port_scan(adapter);
|
||||
queue_work(adapter->work_queue, &adapter->ns_up_work);
|
||||
} else
|
||||
unregister_service_level(&adapter->service_level);
|
||||
|
||||
@@ -54,6 +54,7 @@ extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
|
||||
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
|
||||
extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
|
||||
extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
|
||||
extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *);
|
||||
extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
|
||||
extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
|
||||
extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
|
||||
@@ -98,6 +99,8 @@ extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
|
||||
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
|
||||
extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
|
||||
extern void zfcp_fc_sym_name_update(struct work_struct *);
|
||||
extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
|
||||
extern void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *);
|
||||
|
||||
/* zfcp_fsf.c */
|
||||
extern struct kmem_cache *zfcp_fsf_qtcb_cache;
|
||||
@@ -158,6 +161,7 @@ extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int);
|
||||
extern struct attribute_group zfcp_sysfs_unit_attrs;
|
||||
extern struct attribute_group zfcp_sysfs_adapter_attrs;
|
||||
extern struct attribute_group zfcp_sysfs_port_attrs;
|
||||
extern struct mutex zfcp_sysfs_port_units_mutex;
|
||||
extern struct device_attribute *zfcp_sysfs_sdev_attrs[];
|
||||
extern struct device_attribute *zfcp_sysfs_shost_attrs[];
|
||||
|
||||
|
||||
@@ -26,6 +26,27 @@ static u32 zfcp_fc_rscn_range_mask[] = {
|
||||
[ELS_ADDR_FMT_FAB] = 0x000000,
|
||||
};
|
||||
|
||||
static bool no_auto_port_rescan;
|
||||
module_param_named(no_auto_port_rescan, no_auto_port_rescan, bool, 0600);
|
||||
MODULE_PARM_DESC(no_auto_port_rescan,
|
||||
"no automatic port_rescan (default off)");
|
||||
|
||||
void zfcp_fc_conditional_port_scan(struct zfcp_adapter *adapter)
|
||||
{
|
||||
if (no_auto_port_rescan)
|
||||
return;
|
||||
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
}
|
||||
|
||||
void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *adapter)
|
||||
{
|
||||
if (!no_auto_port_rescan)
|
||||
return;
|
||||
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
}
|
||||
|
||||
/**
|
||||
* zfcp_fc_post_event - post event to userspace via fc_transport
|
||||
* @work: work struct with enqueued events
|
||||
@@ -206,7 +227,7 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
|
||||
zfcp_fc_enqueue_event(fsf_req->adapter, FCH_EVT_RSCN,
|
||||
*(u32 *)page);
|
||||
}
|
||||
queue_work(fsf_req->adapter->work_queue, &fsf_req->adapter->scan_work);
|
||||
zfcp_fc_conditional_port_scan(fsf_req->adapter);
|
||||
}
|
||||
|
||||
static void zfcp_fc_incoming_wwpn(struct zfcp_fsf_req *req, u64 wwpn)
|
||||
|
||||
@@ -219,7 +219,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
|
||||
return;
|
||||
}
|
||||
|
||||
zfcp_dbf_hba_fsf_uss("fssrh_2", req);
|
||||
zfcp_dbf_hba_fsf_uss("fssrh_4", req);
|
||||
|
||||
switch (sr_buf->status_type) {
|
||||
case FSF_STATUS_READ_PORT_CLOSED:
|
||||
@@ -257,7 +257,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req)
|
||||
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_ACT_UPDATED)
|
||||
zfcp_cfdc_adapter_access_changed(adapter);
|
||||
if (sr_buf->status_subtype & FSF_STATUS_READ_SUB_INCOMING_ELS)
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
zfcp_fc_conditional_port_scan(adapter);
|
||||
break;
|
||||
case FSF_STATUS_READ_CFDC_UPDATED:
|
||||
zfcp_cfdc_adapter_access_changed(adapter);
|
||||
@@ -437,6 +437,34 @@ void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *adapter)
|
||||
}
|
||||
}
|
||||
|
||||
#define ZFCP_FSF_PORTSPEED_1GBIT (1 << 0)
|
||||
#define ZFCP_FSF_PORTSPEED_2GBIT (1 << 1)
|
||||
#define ZFCP_FSF_PORTSPEED_4GBIT (1 << 2)
|
||||
#define ZFCP_FSF_PORTSPEED_10GBIT (1 << 3)
|
||||
#define ZFCP_FSF_PORTSPEED_8GBIT (1 << 4)
|
||||
#define ZFCP_FSF_PORTSPEED_16GBIT (1 << 5)
|
||||
#define ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED (1 << 15)
|
||||
|
||||
static u32 zfcp_fsf_convert_portspeed(u32 fsf_speed)
|
||||
{
|
||||
u32 fdmi_speed = 0;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_1GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_1GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_2GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_2GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_4GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_4GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_10GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_10GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_8GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_8GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_16GBIT)
|
||||
fdmi_speed |= FC_PORTSPEED_16GBIT;
|
||||
if (fsf_speed & ZFCP_FSF_PORTSPEED_NOT_NEGOTIATED)
|
||||
fdmi_speed |= FC_PORTSPEED_NOT_NEGOTIATED;
|
||||
return fdmi_speed;
|
||||
}
|
||||
|
||||
static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct fsf_qtcb_bottom_config *bottom = &req->qtcb->bottom.config;
|
||||
@@ -456,7 +484,8 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
|
||||
fc_host_port_name(shost) = nsp->fl_wwpn;
|
||||
fc_host_node_name(shost) = nsp->fl_wwnn;
|
||||
fc_host_port_id(shost) = ntoh24(bottom->s_id);
|
||||
fc_host_speed(shost) = bottom->fc_link_speed;
|
||||
fc_host_speed(shost) =
|
||||
zfcp_fsf_convert_portspeed(bottom->fc_link_speed);
|
||||
fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;
|
||||
|
||||
adapter->hydra_version = bottom->adapter_type;
|
||||
@@ -580,7 +609,8 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
|
||||
} else
|
||||
fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
|
||||
fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
|
||||
fc_host_supported_speeds(shost) = bottom->supported_speed;
|
||||
fc_host_supported_speeds(shost) =
|
||||
zfcp_fsf_convert_portspeed(bottom->supported_speed);
|
||||
memcpy(fc_host_supported_fc4s(shost), bottom->supported_fc4_types,
|
||||
FC_FC4_LIST_SIZE);
|
||||
memcpy(fc_host_active_fc4s(shost), bottom->active_fc4_types,
|
||||
@@ -771,12 +801,14 @@ out:
|
||||
static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct scsi_device *sdev = req->data;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
union fsf_status_qual *fsq = &req->qtcb->header.fsf_status_qual;
|
||||
|
||||
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
|
||||
return;
|
||||
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
switch (req->qtcb->header.fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
if (fsq->word[0] == fsq->word[1]) {
|
||||
@@ -885,7 +917,7 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req)
|
||||
|
||||
switch (header->fsf_status) {
|
||||
case FSF_GOOD:
|
||||
zfcp_dbf_san_res("fsscth1", req);
|
||||
zfcp_dbf_san_res("fsscth2", req);
|
||||
ct->status = 0;
|
||||
break;
|
||||
case FSF_SERVICE_CLASS_NOT_SUPPORTED:
|
||||
@@ -1739,13 +1771,15 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct zfcp_adapter *adapter = req->adapter;
|
||||
struct scsi_device *sdev = req->data;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
struct fsf_qtcb_header *header = &req->qtcb->header;
|
||||
struct fsf_qtcb_bottom_support *bottom = &req->qtcb->bottom.support;
|
||||
|
||||
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
|
||||
return;
|
||||
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_BOXED |
|
||||
ZFCP_STATUS_LUN_SHARED |
|
||||
@@ -1856,11 +1890,13 @@ out:
|
||||
static void zfcp_fsf_close_lun_handler(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct scsi_device *sdev = req->data;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
|
||||
if (req->status & ZFCP_STATUS_FSFREQ_ERROR)
|
||||
return;
|
||||
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
switch (req->qtcb->header.fsf_status) {
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
zfcp_erp_adapter_reopen(zfcp_sdev->port->adapter, 0, "fscuh_1");
|
||||
@@ -1950,7 +1986,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
|
||||
{
|
||||
struct fsf_qual_latency_info *lat_in;
|
||||
struct latency_cont *lat = NULL;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scsi->device);
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
struct zfcp_blk_drv_data blktrc;
|
||||
int ticks = req->adapter->timer_ticks;
|
||||
|
||||
@@ -1965,6 +2001,7 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
|
||||
|
||||
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA &&
|
||||
!(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
|
||||
zfcp_sdev = sdev_to_zfcp(scsi->device);
|
||||
blktrc.flags |= ZFCP_BLK_LAT_VALID;
|
||||
blktrc.channel_lat = lat_in->channel_lat * ticks;
|
||||
blktrc.fabric_lat = lat_in->fabric_lat * ticks;
|
||||
@@ -2002,12 +2039,14 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct scsi_cmnd *scmnd = req->data;
|
||||
struct scsi_device *sdev = scmnd->device;
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
struct zfcp_scsi_dev *zfcp_sdev;
|
||||
struct fsf_qtcb_header *header = &req->qtcb->header;
|
||||
|
||||
if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR))
|
||||
return;
|
||||
|
||||
zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
||||
switch (header->fsf_status) {
|
||||
case FSF_HANDLE_MISMATCH:
|
||||
case FSF_PORT_HANDLE_NOT_VALID:
|
||||
|
||||
@@ -102,18 +102,22 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
|
||||
{
|
||||
struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm;
|
||||
struct zfcp_adapter *adapter = qdio->adapter;
|
||||
struct qdio_buffer_element *sbale;
|
||||
int sbal_no, sbal_idx;
|
||||
void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
|
||||
u64 req_id;
|
||||
u8 scount;
|
||||
|
||||
if (unlikely(qdio_err)) {
|
||||
memset(pl, 0, ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
|
||||
if (zfcp_adapter_multi_buffer_active(adapter)) {
|
||||
void *pl[ZFCP_QDIO_MAX_SBALS_PER_REQ + 1];
|
||||
struct qdio_buffer_element *sbale;
|
||||
u64 req_id;
|
||||
u8 scount;
|
||||
|
||||
memset(pl, 0,
|
||||
ZFCP_QDIO_MAX_SBALS_PER_REQ * sizeof(void *));
|
||||
sbale = qdio->res_q[idx]->element;
|
||||
req_id = (u64) sbale->addr;
|
||||
scount = sbale->scount + 1; /* incl. signaling SBAL */
|
||||
scount = min(sbale->scount + 1,
|
||||
ZFCP_QDIO_MAX_SBALS_PER_REQ + 1);
|
||||
/* incl. signaling SBAL */
|
||||
|
||||
for (sbal_no = 0; sbal_no < scount; sbal_no++) {
|
||||
sbal_idx = (idx + sbal_no) %
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user