aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2010-09-15 17:52:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-07 18:09:44 -0400
commit43ca910a9c90566308f39f51ac03a55f94a5f83c (patch)
treea0ced12dbeebd12b0b5ae113ccfc6c6b823bb9e8 /drivers/scsi/scsi_transport_fc.c
parent0af5d708aae3aef1f98a1c689007b92db2c10277 (diff)
[SCSI] fc class: add fc host dev loss sysfs file
This adds a fc host dev loss sysfs file. Instead of calling into the driver using the get_host_def_dev_loss_tmo callback, we allow drivers to init the dev loss like is done for other fc host params, and then the fc class will handle updating the value if the user writes to the new sysfs file. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c124
1 files changed, 88 insertions, 36 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 78486d540652..998c01be3234 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -53,6 +53,25 @@ static void fc_bsg_remove(struct request_queue *);
53static void fc_bsg_goose_queue(struct fc_rport *); 53static void fc_bsg_goose_queue(struct fc_rport *);
54 54
55/* 55/*
56 * Module Parameters
57 */
58
59/*
60 * dev_loss_tmo: the default number of seconds that the FC transport
61 * should insulate the loss of a remote port.
62 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
63 */
64static unsigned int fc_dev_loss_tmo = 60; /* seconds */
65
66module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
67MODULE_PARM_DESC(dev_loss_tmo,
68 "Maximum number of seconds that the FC transport should"
69 " insulate the loss of a remote port. Once this value is"
70 " exceeded, the scsi target is removed. Value should be"
71 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
72 " fast_io_fail_tmo is not set.");
73
74/*
56 * Redefine so that we can have same named attributes in the 75 * Redefine so that we can have same named attributes in the
57 * sdev/starget/host objects. 76 * sdev/starget/host objects.
58 */ 77 */
@@ -408,6 +427,7 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
408 if (!fc_host->work_q) 427 if (!fc_host->work_q)
409 return -ENOMEM; 428 return -ENOMEM;
410 429
430 fc_host->dev_loss_tmo = fc_dev_loss_tmo;
411 snprintf(fc_host->devloss_work_q_name, 431 snprintf(fc_host->devloss_work_q_name,
412 sizeof(fc_host->devloss_work_q_name), 432 sizeof(fc_host->devloss_work_q_name),
413 "fc_dl_%d", shost->host_no); 433 "fc_dl_%d", shost->host_no);
@@ -462,25 +482,6 @@ static DECLARE_TRANSPORT_CLASS(fc_vport_class,
462 NULL); 482 NULL);
463 483
464/* 484/*
465 * Module Parameters
466 */
467
468/*
469 * dev_loss_tmo: the default number of seconds that the FC transport
470 * should insulate the loss of a remote port.
471 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
472 */
473static unsigned int fc_dev_loss_tmo = 60; /* seconds */
474
475module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
476MODULE_PARM_DESC(dev_loss_tmo,
477 "Maximum number of seconds that the FC transport should"
478 " insulate the loss of a remote port. Once this value is"
479 " exceeded, the scsi target is removed. Value should be"
480 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
481 " fast_io_fail_tmo is not set.");
482
483/*
484 * Netlink Infrastructure 485 * Netlink Infrastructure
485 */ 486 */
486 487
@@ -830,24 +831,32 @@ static FC_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
830/* 831/*
831 * dev_loss_tmo attribute 832 * dev_loss_tmo attribute
832 */ 833 */
833fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 834static int fc_str_to_dev_loss(const char *buf, unsigned long *val)
834static ssize_t 835{
835store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 836 char *cp;
836 const char *buf, size_t count) 837
838 *val = simple_strtoul(buf, &cp, 0);
839 if ((*cp && (*cp != '\n')) || (*val < 0))
840 return -EINVAL;
841 /*
842 * Check for overflow; dev_loss_tmo is u32
843 */
844 if (*val > UINT_MAX)
845 return -EINVAL;
846
847 return 0;
848}
849
850static int fc_rport_set_dev_loss_tmo(struct fc_rport *rport,
851 unsigned long val)
837{ 852{
838 unsigned long val;
839 struct fc_rport *rport = transport_class_to_rport(dev);
840 struct Scsi_Host *shost = rport_to_shost(rport); 853 struct Scsi_Host *shost = rport_to_shost(rport);
841 struct fc_internal *i = to_fc_internal(shost->transportt); 854 struct fc_internal *i = to_fc_internal(shost->transportt);
842 char *cp; 855
843 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 856 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
844 (rport->port_state == FC_PORTSTATE_DELETED) || 857 (rport->port_state == FC_PORTSTATE_DELETED) ||
845 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 858 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
846 return -EBUSY; 859 return -EBUSY;
847 val = simple_strtoul(buf, &cp, 0);
848 if ((*cp && (*cp != '\n')) || (val < 0))
849 return -EINVAL;
850
851 /* 860 /*
852 * Check for overflow; dev_loss_tmo is u32 861 * Check for overflow; dev_loss_tmo is u32
853 */ 862 */
@@ -863,6 +872,25 @@ store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
863 return -EINVAL; 872 return -EINVAL;
864 873
865 i->f->set_rport_dev_loss_tmo(rport, val); 874 i->f->set_rport_dev_loss_tmo(rport, val);
875 return 0;
876}
877
878fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
879static ssize_t
880store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
881 const char *buf, size_t count)
882{
883 struct fc_rport *rport = transport_class_to_rport(dev);
884 unsigned long val;
885 int rc;
886
887 rc = fc_str_to_dev_loss(buf, &val);
888 if (rc)
889 return rc;
890
891 rc = fc_rport_set_dev_loss_tmo(rport, val);
892 if (rc)
893 return rc;
866 return count; 894 return count;
867} 895}
868static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, 896static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
@@ -1608,8 +1636,35 @@ store_fc_private_host_issue_lip(struct device *dev,
1608static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, 1636static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
1609 store_fc_private_host_issue_lip); 1637 store_fc_private_host_issue_lip);
1610 1638
1611fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20); 1639static ssize_t
1640store_fc_private_host_dev_loss_tmo(struct device *dev,
1641 struct device_attribute *attr,
1642 const char *buf, size_t count)
1643{
1644 struct Scsi_Host *shost = transport_class_to_shost(dev);
1645 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1646 struct fc_rport *rport;
1647 unsigned long val, flags;
1648 int rc;
1649
1650 rc = fc_str_to_dev_loss(buf, &val);
1651 if (rc)
1652 return rc;
1653
1654 fc_host_dev_loss_tmo(shost) = val;
1655 spin_lock_irqsave(shost->host_lock, flags);
1656 list_for_each_entry(rport, &fc_host->rports, peers)
1657 fc_rport_set_dev_loss_tmo(rport, val);
1658 spin_unlock_irqrestore(shost->host_lock, flags);
1659 return count;
1660}
1612 1661
1662fc_private_host_show_function(dev_loss_tmo, "%d\n", 20, );
1663static FC_DEVICE_ATTR(host, dev_loss_tmo, S_IRUGO | S_IWUSR,
1664 show_fc_host_dev_loss_tmo,
1665 store_fc_private_host_dev_loss_tmo);
1666
1667fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20);
1613 1668
1614/* 1669/*
1615 * Host Statistics Management 1670 * Host Statistics Management
@@ -2165,6 +2220,7 @@ fc_attach_transport(struct fc_function_template *ft)
2165 SETUP_HOST_ATTRIBUTE_RW(system_hostname); 2220 SETUP_HOST_ATTRIBUTE_RW(system_hostname);
2166 2221
2167 /* Transport-managed attributes */ 2222 /* Transport-managed attributes */
2223 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
2168 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 2224 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
2169 if (ft->issue_fc_host_lip) 2225 if (ft->issue_fc_host_lip)
2170 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); 2226 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
@@ -2525,11 +2581,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
2525 2581
2526 rport->maxframe_size = -1; 2582 rport->maxframe_size = -1;
2527 rport->supported_classes = FC_COS_UNSPECIFIED; 2583 rport->supported_classes = FC_COS_UNSPECIFIED;
2528 if (fci->f->get_host_def_dev_loss_tmo) { 2584 rport->dev_loss_tmo = fc_host->dev_loss_tmo;
2529 fci->f->get_host_def_dev_loss_tmo(shost);
2530 rport->dev_loss_tmo = fc_host_def_dev_loss_tmo(shost);
2531 } else
2532 rport->dev_loss_tmo = fc_dev_loss_tmo;
2533 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 2585 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
2534 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 2586 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
2535 rport->port_id = ids->port_id; 2587 rport->port_id = ids->port_id;