mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge remote-tracking branch 'scsi-queue/drivers-for-3.19' into for-linus
Conflicts: drivers/scsi/scsi_debug.c Agreed and tested resolution to a merge problem between a fix in scsi_debug and a driver update Signed-off-by: James Bottomley <[email protected]>
This commit is contained in:
commit
096cbc35ea
154 changed files with 7010 additions and 11822 deletions
|
|
@ -353,9 +353,11 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device)
|
|||
adapter->ccw_device = ccw_device;
|
||||
|
||||
INIT_WORK(&adapter->stat_work, _zfcp_status_read_scheduler);
|
||||
INIT_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
|
||||
INIT_DELAYED_WORK(&adapter->scan_work, zfcp_fc_scan_ports);
|
||||
INIT_WORK(&adapter->ns_up_work, zfcp_fc_sym_name_update);
|
||||
|
||||
adapter->next_port_scan = jiffies;
|
||||
|
||||
if (zfcp_qdio_setup(adapter))
|
||||
goto failed;
|
||||
|
||||
|
|
@ -420,7 +422,7 @@ void zfcp_adapter_unregister(struct zfcp_adapter *adapter)
|
|||
{
|
||||
struct ccw_device *cdev = adapter->ccw_device;
|
||||
|
||||
cancel_work_sync(&adapter->scan_work);
|
||||
cancel_delayed_work_sync(&adapter->scan_work);
|
||||
cancel_work_sync(&adapter->stat_work);
|
||||
cancel_work_sync(&adapter->ns_up_work);
|
||||
zfcp_destroy_adapter_work_queue(adapter);
|
||||
|
|
|
|||
|
|
@ -56,8 +56,22 @@ static int zfcp_ccw_activate(struct ccw_device *cdev, int clear, char *tag)
|
|||
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
tag);
|
||||
|
||||
/*
|
||||
* We want to scan ports here, with some random backoff and without
|
||||
* rate limit. Recovery has already scheduled a port scan for us,
|
||||
* but with both random delay and rate limit. Nevertheless we get
|
||||
* what we want here by flushing the scheduled work after sleeping
|
||||
* an equivalent random time.
|
||||
* Let the port scan random delay elapse first. If recovery finishes
|
||||
* up to that point in time, that would be perfect for both recovery
|
||||
* and port scan. If not, i.e. recovery takes ages, there was no
|
||||
* point in waiting a random delay on top of the time consumed by
|
||||
* recovery.
|
||||
*/
|
||||
msleep(zfcp_fc_port_scan_backoff());
|
||||
zfcp_erp_wait(adapter);
|
||||
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
|
||||
flush_delayed_work(&adapter->scan_work);
|
||||
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
|
||||
|
|
@ -162,11 +176,19 @@ static int zfcp_ccw_set_online(struct ccw_device *cdev)
|
|||
adapter->req_no = 0;
|
||||
|
||||
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 */
|
||||
|
||||
/*
|
||||
* We want to scan ports here, always, with some random delay and
|
||||
* without rate limit - basically what zfcp_ccw_activate() has
|
||||
* achieved for us. Not quite! That port scan depended on
|
||||
* !no_auto_port_rescan. So let's cover the no_auto_port_rescan
|
||||
* case here to make sure a port scan is done unconditionally.
|
||||
* Since zfcp_ccw_activate() has waited the desired random time,
|
||||
* we can immediately schedule and flush a port scan for the
|
||||
* remaining cases.
|
||||
*/
|
||||
zfcp_fc_inverse_conditional_port_scan(adapter);
|
||||
flush_work(&adapter->scan_work); /* ok to call even if nothing queued */
|
||||
flush_delayed_work(&adapter->scan_work);
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,12 +186,13 @@ struct zfcp_adapter {
|
|||
struct fc_host_statistics *fc_stats;
|
||||
struct fsf_qtcb_bottom_port *stats_reset_data;
|
||||
unsigned long stats_reset;
|
||||
struct work_struct scan_work;
|
||||
struct delayed_work scan_work;
|
||||
struct work_struct ns_up_work;
|
||||
struct service_level service_level;
|
||||
struct workqueue_struct *work_queue;
|
||||
struct device_dma_parameters dma_parms;
|
||||
struct zfcp_fc_events events;
|
||||
unsigned long next_port_scan;
|
||||
};
|
||||
|
||||
struct zfcp_port {
|
||||
|
|
|
|||
|
|
@ -821,11 +821,6 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
|
|||
return ZFCP_ERP_CONTINUES;
|
||||
}
|
||||
|
||||
static void zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
|
||||
{
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED, &port->status);
|
||||
}
|
||||
|
||||
static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
|
||||
{
|
||||
struct zfcp_port *port = erp_action->port;
|
||||
|
|
@ -833,7 +828,6 @@ static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
|
|||
|
||||
switch (erp_action->step) {
|
||||
case ZFCP_ERP_STEP_UNINITIALIZED:
|
||||
zfcp_erp_port_strategy_clearstati(port);
|
||||
if ((status & ZFCP_STATUS_PORT_PHYS_OPEN) &&
|
||||
(status & ZFCP_STATUS_COMMON_OPEN))
|
||||
return zfcp_erp_port_forced_strategy_close(erp_action);
|
||||
|
|
@ -933,7 +927,6 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
|
|||
|
||||
switch (erp_action->step) {
|
||||
case ZFCP_ERP_STEP_UNINITIALIZED:
|
||||
zfcp_erp_port_strategy_clearstati(port);
|
||||
if (p_status & ZFCP_STATUS_COMMON_OPEN)
|
||||
return zfcp_erp_port_strategy_close(erp_action);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ 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 unsigned int zfcp_fc_port_scan_backoff(void);
|
||||
extern void zfcp_fc_conditional_port_scan(struct zfcp_adapter *);
|
||||
extern void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/random.h>
|
||||
#include <scsi/fc/fc_els.h>
|
||||
#include <scsi/libfc.h>
|
||||
#include "zfcp_ext.h"
|
||||
|
|
@ -31,12 +32,54 @@ 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)");
|
||||
|
||||
static unsigned int port_scan_backoff = 500;
|
||||
module_param(port_scan_backoff, uint, 0600);
|
||||
MODULE_PARM_DESC(port_scan_backoff,
|
||||
"upper limit of port scan random backoff in msecs (default 500)");
|
||||
|
||||
static unsigned int port_scan_ratelimit = 60000;
|
||||
module_param(port_scan_ratelimit, uint, 0600);
|
||||
MODULE_PARM_DESC(port_scan_ratelimit,
|
||||
"minimum interval between port scans in msecs (default 60000)");
|
||||
|
||||
unsigned int zfcp_fc_port_scan_backoff(void)
|
||||
{
|
||||
if (!port_scan_backoff)
|
||||
return 0;
|
||||
return get_random_int() % port_scan_backoff;
|
||||
}
|
||||
|
||||
static void zfcp_fc_port_scan_time(struct zfcp_adapter *adapter)
|
||||
{
|
||||
unsigned long interval = msecs_to_jiffies(port_scan_ratelimit);
|
||||
unsigned long backoff = msecs_to_jiffies(zfcp_fc_port_scan_backoff());
|
||||
|
||||
adapter->next_port_scan = jiffies + interval + backoff;
|
||||
}
|
||||
|
||||
static void zfcp_fc_port_scan(struct zfcp_adapter *adapter)
|
||||
{
|
||||
unsigned long now = jiffies;
|
||||
unsigned long next = adapter->next_port_scan;
|
||||
unsigned long delay = 0, max;
|
||||
|
||||
/* delay only needed within waiting period */
|
||||
if (time_before(now, next)) {
|
||||
delay = next - now;
|
||||
/* paranoia: never ever delay scans longer than specified */
|
||||
max = msecs_to_jiffies(port_scan_ratelimit + port_scan_backoff);
|
||||
delay = min(delay, max);
|
||||
}
|
||||
|
||||
queue_delayed_work(adapter->work_queue, &adapter->scan_work, delay);
|
||||
}
|
||||
|
||||
void zfcp_fc_conditional_port_scan(struct zfcp_adapter *adapter)
|
||||
{
|
||||
if (no_auto_port_rescan)
|
||||
return;
|
||||
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
zfcp_fc_port_scan(adapter);
|
||||
}
|
||||
|
||||
void zfcp_fc_inverse_conditional_port_scan(struct zfcp_adapter *adapter)
|
||||
|
|
@ -44,7 +87,7 @@ 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_port_scan(adapter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -680,12 +723,15 @@ static int zfcp_fc_eval_gpn_ft(struct zfcp_fc_req *fc_req,
|
|||
*/
|
||||
void zfcp_fc_scan_ports(struct work_struct *work)
|
||||
{
|
||||
struct zfcp_adapter *adapter = container_of(work, struct zfcp_adapter,
|
||||
struct delayed_work *dw = to_delayed_work(work);
|
||||
struct zfcp_adapter *adapter = container_of(dw, struct zfcp_adapter,
|
||||
scan_work);
|
||||
int ret, i;
|
||||
struct zfcp_fc_req *fc_req;
|
||||
int chain, max_entries, buf_num, max_bytes;
|
||||
|
||||
zfcp_fc_port_scan_time(adapter);
|
||||
|
||||
chain = adapter->adapter_features & FSF_FEATURE_ELS_CT_CHAINED_SBALS;
|
||||
buf_num = chain ? ZFCP_FC_GPN_FT_NUM_BUFS : 1;
|
||||
max_entries = chain ? ZFCP_FC_GPN_FT_MAX_ENT : ZFCP_FC_GPN_FT_ENT_PAGE;
|
||||
|
|
|
|||
|
|
@ -1396,8 +1396,7 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
|
|||
port->handle = header->port_handle;
|
||||
atomic_set_mask(ZFCP_STATUS_COMMON_OPEN |
|
||||
ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED |
|
||||
ZFCP_STATUS_COMMON_ACCESS_BOXED,
|
||||
atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
|
||||
&port->status);
|
||||
/* check whether D_ID has changed during open */
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -32,25 +32,6 @@ static bool allow_lun_scan = 1;
|
|||
module_param(allow_lun_scan, bool, 0600);
|
||||
MODULE_PARM_DESC(allow_lun_scan, "For NPIV, scan and attach all storage LUNs");
|
||||
|
||||
static int zfcp_scsi_change_queue_depth(struct scsi_device *sdev, int depth,
|
||||
int reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case SCSI_QDEPTH_DEFAULT:
|
||||
scsi_adjust_queue_depth(sdev, depth);
|
||||
break;
|
||||
case SCSI_QDEPTH_QFULL:
|
||||
scsi_track_queue_full(sdev, depth);
|
||||
break;
|
||||
case SCSI_QDEPTH_RAMP_UP:
|
||||
scsi_adjust_queue_depth(sdev, depth);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return sdev->queue_depth;
|
||||
}
|
||||
|
||||
static void zfcp_scsi_slave_destroy(struct scsi_device *sdev)
|
||||
{
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||
|
|
@ -66,7 +47,7 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdev)
|
|||
static int zfcp_scsi_slave_configure(struct scsi_device *sdp)
|
||||
{
|
||||
if (sdp->tagged_supported)
|
||||
scsi_adjust_queue_depth(sdp, default_depth);
|
||||
scsi_change_queue_depth(sdp, default_depth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -305,7 +286,7 @@ static struct scsi_host_template zfcp_scsi_host_template = {
|
|||
.slave_alloc = zfcp_scsi_slave_alloc,
|
||||
.slave_configure = zfcp_scsi_slave_configure,
|
||||
.slave_destroy = zfcp_scsi_slave_destroy,
|
||||
.change_queue_depth = zfcp_scsi_change_queue_depth,
|
||||
.change_queue_depth = scsi_change_queue_depth,
|
||||
.proc_name = "zfcp",
|
||||
.can_queue = 4096,
|
||||
.this_id = -1,
|
||||
|
|
@ -320,6 +301,7 @@ static struct scsi_host_template zfcp_scsi_host_template = {
|
|||
.use_clustering = 1,
|
||||
.shost_attrs = zfcp_sysfs_shost_attrs,
|
||||
.sdev_attrs = zfcp_sysfs_sdev_attrs,
|
||||
.track_queue_depth = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -73,9 +73,7 @@ ZFCP_DEFINE_ATTR(zfcp_port, port, status, "0x%08x\n",
|
|||
ZFCP_DEFINE_ATTR(zfcp_port, port, in_recovery, "%d\n",
|
||||
(atomic_read(&port->status) &
|
||||
ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
|
||||
ZFCP_DEFINE_ATTR(zfcp_port, port, access_denied, "%d\n",
|
||||
(atomic_read(&port->status) &
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
|
||||
ZFCP_DEFINE_ATTR_CONST(port, access_denied, "%d\n", 0);
|
||||
|
||||
ZFCP_DEFINE_ATTR(zfcp_unit, unit, status, "0x%08x\n",
|
||||
zfcp_unit_sdev_status(unit));
|
||||
|
|
@ -223,9 +221,13 @@ static ssize_t zfcp_sysfs_port_rescan_store(struct device *dev,
|
|||
if (!adapter)
|
||||
return -ENODEV;
|
||||
|
||||
/* sync the user-space- with the kernel-invocation of scan_work */
|
||||
queue_work(adapter->work_queue, &adapter->scan_work);
|
||||
flush_work(&adapter->scan_work);
|
||||
/*
|
||||
* Users wish is our command: immediately schedule and flush a
|
||||
* worker to conduct a synchronous port scan, that is, neither
|
||||
* a random delay nor a rate limit is applied here.
|
||||
*/
|
||||
queue_delayed_work(adapter->work_queue, &adapter->scan_work, 0);
|
||||
flush_delayed_work(&adapter->scan_work);
|
||||
zfcp_ccw_adapter_put(adapter);
|
||||
|
||||
return (ssize_t) count;
|
||||
|
|
@ -439,16 +441,15 @@ static ssize_t zfcp_sysfs_scsi_##_name##_show(struct device *dev, \
|
|||
{ \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); \
|
||||
struct zfcp_port *port = zfcp_sdev->port; \
|
||||
\
|
||||
return sprintf(buf, _format, _value); \
|
||||
} \
|
||||
static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_scsi_##_name##_show, NULL);
|
||||
|
||||
ZFCP_DEFINE_SCSI_ATTR(hba_id, "%s\n",
|
||||
dev_name(&port->adapter->ccw_device->dev));
|
||||
dev_name(&zfcp_sdev->port->adapter->ccw_device->dev));
|
||||
ZFCP_DEFINE_SCSI_ATTR(wwpn, "0x%016llx\n",
|
||||
(unsigned long long) port->wwpn);
|
||||
(unsigned long long) zfcp_sdev->port->wwpn);
|
||||
|
||||
static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
|
|
@ -460,6 +461,49 @@ static ssize_t zfcp_sysfs_scsi_fcp_lun_show(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR(fcp_lun, S_IRUGO, zfcp_sysfs_scsi_fcp_lun_show, NULL);
|
||||
|
||||
ZFCP_DEFINE_SCSI_ATTR(zfcp_access_denied, "%d\n",
|
||||
(atomic_read(&zfcp_sdev->status) &
|
||||
ZFCP_STATUS_COMMON_ACCESS_DENIED) != 0);
|
||||
|
||||
static ssize_t zfcp_sysfs_scsi_zfcp_failed_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
unsigned int status = atomic_read(&sdev_to_zfcp(sdev)->status);
|
||||
unsigned int failed = status & ZFCP_STATUS_COMMON_ERP_FAILED ? 1 : 0;
|
||||
|
||||
return sprintf(buf, "%d\n", failed);
|
||||
}
|
||||
|
||||
static ssize_t zfcp_sysfs_scsi_zfcp_failed_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
unsigned long val;
|
||||
|
||||
if (kstrtoul(buf, 0, &val) || val != 0)
|
||||
return -EINVAL;
|
||||
|
||||
zfcp_erp_set_lun_status(sdev, ZFCP_STATUS_COMMON_RUNNING);
|
||||
zfcp_erp_lun_reopen(sdev, ZFCP_STATUS_COMMON_ERP_FAILED,
|
||||
"syufai3");
|
||||
zfcp_erp_wait(sdev_to_zfcp(sdev)->port->adapter);
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR(zfcp_failed, S_IWUSR | S_IRUGO,
|
||||
zfcp_sysfs_scsi_zfcp_failed_show,
|
||||
zfcp_sysfs_scsi_zfcp_failed_store);
|
||||
|
||||
ZFCP_DEFINE_SCSI_ATTR(zfcp_in_recovery, "%d\n",
|
||||
(atomic_read(&zfcp_sdev->status) &
|
||||
ZFCP_STATUS_COMMON_ERP_INUSE) != 0);
|
||||
|
||||
ZFCP_DEFINE_SCSI_ATTR(zfcp_status, "0x%08x\n",
|
||||
atomic_read(&zfcp_sdev->status));
|
||||
|
||||
struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
|
||||
&dev_attr_fcp_lun,
|
||||
&dev_attr_wwpn,
|
||||
|
|
@ -467,6 +511,10 @@ struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
|
|||
&dev_attr_read_latency,
|
||||
&dev_attr_write_latency,
|
||||
&dev_attr_cmd_latency,
|
||||
&dev_attr_zfcp_access_denied,
|
||||
&dev_attr_zfcp_failed,
|
||||
&dev_attr_zfcp_in_recovery,
|
||||
&dev_attr_zfcp_status,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue