aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@titanic.(none)>2005-11-04 23:29:52 -0500
committerJames Bottomley <jejb@titanic.(none)>2005-11-04 23:29:52 -0500
commit849a8924a6740ecbf9711e015beca69425f0c429 (patch)
tree2bae44c5fb170a655696b7253eec7ee13c6fa437 /drivers/scsi/scsi_transport_fc.c
parent7015faa7df829876a0f931cd18aa6d7c24a1b581 (diff)
parentee807c2d43b54183c16580857837dae8ccb2ed22 (diff)
Merge by Hand
Conflicts in dec_esp.c (Thanks Bacchus), scsi_transport_iscsi.c and scsi_transport_fc.h Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c476
1 files changed, 304 insertions, 172 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index b856e140e65f..6cd5931d9a54 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -33,8 +33,6 @@
33#include <scsi/scsi_transport_fc.h> 33#include <scsi/scsi_transport_fc.h>
34#include "scsi_priv.h" 34#include "scsi_priv.h"
35 35
36#define FC_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a)
37
38/* 36/*
39 * Redefine so that we can have same named attributes in the 37 * Redefine so that we can have same named attributes in the
40 * sdev/starget/host objects. 38 * sdev/starget/host objects.
@@ -213,7 +211,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
213#define FC_MGMTSRVR_PORTID 0x00000a 211#define FC_MGMTSRVR_PORTID 0x00000a
214 212
215 213
216static void fc_timeout_blocked_rport(void *data); 214static void fc_timeout_deleted_rport(void *data);
217static void fc_scsi_scan_rport(void *data); 215static void fc_scsi_scan_rport(void *data);
218static void fc_rport_terminate(struct fc_rport *rport); 216static void fc_rport_terminate(struct fc_rport *rport);
219 217
@@ -223,7 +221,7 @@ static void fc_rport_terminate(struct fc_rport *rport);
223 */ 221 */
224#define FC_STARGET_NUM_ATTRS 3 222#define FC_STARGET_NUM_ATTRS 3
225#define FC_RPORT_NUM_ATTRS 9 223#define FC_RPORT_NUM_ATTRS 9
226#define FC_HOST_NUM_ATTRS 15 224#define FC_HOST_NUM_ATTRS 16
227 225
228struct fc_internal { 226struct fc_internal {
229 struct scsi_transport_template t; 227 struct scsi_transport_template t;
@@ -387,7 +385,9 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \
387 struct fc_rport *rport = transport_class_to_rport(cdev); \ 385 struct fc_rport *rport = transport_class_to_rport(cdev); \
388 struct Scsi_Host *shost = rport_to_shost(rport); \ 386 struct Scsi_Host *shost = rport_to_shost(rport); \
389 struct fc_internal *i = to_fc_internal(shost->transportt); \ 387 struct fc_internal *i = to_fc_internal(shost->transportt); \
390 if (i->f->get_rport_##field) \ 388 if ((i->f->get_rport_##field) && \
389 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \
390 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \
391 i->f->get_rport_##field(rport); \ 391 i->f->get_rport_##field(rport); \
392 return snprintf(buf, sz, format_string, cast rport->field); \ 392 return snprintf(buf, sz, format_string, cast rport->field); \
393} 393}
@@ -401,6 +401,9 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \
401 struct fc_rport *rport = transport_class_to_rport(cdev); \ 401 struct fc_rport *rport = transport_class_to_rport(cdev); \
402 struct Scsi_Host *shost = rport_to_shost(rport); \ 402 struct Scsi_Host *shost = rport_to_shost(rport); \
403 struct fc_internal *i = to_fc_internal(shost->transportt); \ 403 struct fc_internal *i = to_fc_internal(shost->transportt); \
404 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
405 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
406 return -EBUSY; \
404 val = simple_strtoul(buf, NULL, 0); \ 407 val = simple_strtoul(buf, NULL, 0); \
405 i->f->set_rport_##field(rport, val); \ 408 i->f->set_rport_##field(rport, val); \
406 return count; \ 409 return count; \
@@ -503,7 +506,29 @@ static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
503 506
504/* Dynamic Remote Port Attributes */ 507/* Dynamic Remote Port Attributes */
505 508
506fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20); 509/*
510 * dev_loss_tmo attribute
511 */
512fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
513static ssize_t
514store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
515 size_t count)
516{
517 int val;
518 struct fc_rport *rport = transport_class_to_rport(cdev);
519 struct Scsi_Host *shost = rport_to_shost(rport);
520 struct fc_internal *i = to_fc_internal(shost->transportt);
521 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
522 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
523 return -EBUSY;
524 val = simple_strtoul(buf, NULL, 0);
525 if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
526 return -EINVAL;
527 i->f->set_rport_dev_loss_tmo(rport, val);
528 return count;
529}
530static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
531 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
507 532
508 533
509/* Private Remote Port Attributes */ 534/* Private Remote Port Attributes */
@@ -716,9 +741,11 @@ static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
716 count++ 741 count++
717 742
718#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 743#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
744{ \
719 i->private_host_attrs[count] = class_device_attr_host_##field; \ 745 i->private_host_attrs[count] = class_device_attr_host_##field; \
720 i->host_attrs[count] = &i->private_host_attrs[count]; \ 746 i->host_attrs[count] = &i->private_host_attrs[count]; \
721 count++ 747 count++; \
748}
722 749
723 750
724/* Fixed Host Attributes */ 751/* Fixed Host Attributes */
@@ -856,6 +883,26 @@ static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
856 show_fc_private_host_tgtid_bind_type, 883 show_fc_private_host_tgtid_bind_type,
857 store_fc_private_host_tgtid_bind_type); 884 store_fc_private_host_tgtid_bind_type);
858 885
886static ssize_t
887store_fc_private_host_issue_lip(struct class_device *cdev,
888 const char *buf, size_t count)
889{
890 struct Scsi_Host *shost = transport_class_to_shost(cdev);
891 struct fc_internal *i = to_fc_internal(shost->transportt);
892 int ret;
893
894 /* ignore any data value written to the attribute */
895 if (i->f->issue_fc_host_lip) {
896 ret = i->f->issue_fc_host_lip(shost);
897 return ret ? ret: count;
898 }
899
900 return -ENOENT;
901}
902
903static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
904 store_fc_private_host_issue_lip);
905
859/* 906/*
860 * Host Statistics Management 907 * Host Statistics Management
861 */ 908 */
@@ -1122,6 +1169,8 @@ fc_attach_transport(struct fc_function_template *ft)
1122 1169
1123 /* Transport-managed attributes */ 1170 /* Transport-managed attributes */
1124 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1171 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
1172 if (ft->issue_fc_host_lip)
1173 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
1125 1174
1126 BUG_ON(count > FC_HOST_NUM_ATTRS); 1175 BUG_ON(count > FC_HOST_NUM_ATTRS);
1127 1176
@@ -1193,6 +1242,25 @@ fc_remove_host(struct Scsi_Host *shost)
1193} 1242}
1194EXPORT_SYMBOL(fc_remove_host); 1243EXPORT_SYMBOL(fc_remove_host);
1195 1244
1245/*
1246 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1247 * @rport: The remote port to be operated on
1248 */
1249static void
1250fc_rport_tgt_remove(struct fc_rport *rport)
1251{
1252 struct Scsi_Host *shost = rport_to_shost(rport);
1253
1254 scsi_target_unblock(&rport->dev);
1255
1256 /* Stop anything on the workq */
1257 if (!cancel_delayed_work(&rport->dev_loss_work))
1258 flush_scheduled_work();
1259 scsi_flush_work(shost);
1260
1261 scsi_remove_target(&rport->dev);
1262}
1263
1196/** 1264/**
1197 * fc_rport_create - allocates and creates a remote FC port. 1265 * fc_rport_create - allocates and creates a remote FC port.
1198 * @shost: scsi host the remote port is connected to. 1266 * @shost: scsi host the remote port is connected to.
@@ -1239,7 +1307,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1239 rport->dd_data = &rport[1]; 1307 rport->dd_data = &rport[1];
1240 rport->channel = channel; 1308 rport->channel = channel;
1241 1309
1242 INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport); 1310 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
1243 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1311 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
1244 1312
1245 spin_lock_irqsave(shost->host_lock, flags); 1313 spin_lock_irqsave(shost->host_lock, flags);
@@ -1331,17 +1399,93 @@ struct fc_rport *
1331fc_remote_port_add(struct Scsi_Host *shost, int channel, 1399fc_remote_port_add(struct Scsi_Host *shost, int channel,
1332 struct fc_rport_identifiers *ids) 1400 struct fc_rport_identifiers *ids)
1333{ 1401{
1402 struct fc_internal *fci = to_fc_internal(shost->transportt);
1334 struct fc_rport *rport; 1403 struct fc_rport *rport;
1335 unsigned long flags; 1404 unsigned long flags;
1336 int match = 0; 1405 int match = 0;
1337 1406
1407 /*
1408 * Search the list of "active" rports, for an rport that has been
1409 * deleted, but we've held off the real delete while the target
1410 * is in a "blocked" state.
1411 */
1412 spin_lock_irqsave(shost->host_lock, flags);
1413
1414 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1415
1416 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
1417 (rport->channel == channel)) {
1418
1419 switch (fc_host_tgtid_bind_type(shost)) {
1420 case FC_TGTID_BIND_BY_WWPN:
1421 case FC_TGTID_BIND_NONE:
1422 if (rport->port_name == ids->port_name)
1423 match = 1;
1424 break;
1425 case FC_TGTID_BIND_BY_WWNN:
1426 if (rport->node_name == ids->node_name)
1427 match = 1;
1428 break;
1429 case FC_TGTID_BIND_BY_ID:
1430 if (rport->port_id == ids->port_id)
1431 match = 1;
1432 break;
1433 }
1434
1435 if (match) {
1436 struct work_struct *work =
1437 &rport->dev_loss_work;
1438
1439 memcpy(&rport->node_name, &ids->node_name,
1440 sizeof(rport->node_name));
1441 memcpy(&rport->port_name, &ids->port_name,
1442 sizeof(rport->port_name));
1443 rport->port_id = ids->port_id;
1444
1445 rport->port_state = FC_PORTSTATE_ONLINE;
1446 rport->roles = ids->roles;
1447
1448 spin_unlock_irqrestore(shost->host_lock, flags);
1449
1450 if (fci->f->dd_fcrport_size)
1451 memset(rport->dd_data, 0,
1452 fci->f->dd_fcrport_size);
1453
1454 /*
1455 * If we were blocked, we were a target.
1456 * If no longer a target, we leave the timer
1457 * running in case the port changes roles
1458 * prior to the timer expiring. If the timer
1459 * fires, the target will be torn down.
1460 */
1461 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
1462 return rport;
1463
1464 /* restart the target */
1465
1466 /*
1467 * Stop the target timer first. Take no action
1468 * on the del_timer failure as the state
1469 * machine state change will validate the
1470 * transaction.
1471 */
1472 if (!cancel_delayed_work(work))
1473 flush_scheduled_work();
1474
1475 /* initiate a scan of the target */
1476 scsi_queue_work(shost, &rport->scan_work);
1477
1478 return rport;
1479 }
1480 }
1481 }
1482
1483 /* Search the bindings array */
1338 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && 1484 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) &&
1339 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { 1485 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) {
1340 1486
1341 /* search for a matching consistent binding */ 1487 /* search for a matching consistent binding */
1342 1488
1343 spin_lock_irqsave(shost->host_lock, flags);
1344
1345 list_for_each_entry(rport, &fc_host_rport_bindings(shost), 1489 list_for_each_entry(rport, &fc_host_rport_bindings(shost),
1346 peers) { 1490 peers) {
1347 if (rport->channel != channel) 1491 if (rport->channel != channel)
@@ -1371,8 +1515,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1371 } 1515 }
1372 } 1516 }
1373 1517
1374 spin_unlock_irqrestore(shost->host_lock, flags);
1375
1376 if (match) { 1518 if (match) {
1377 memcpy(&rport->node_name, &ids->node_name, 1519 memcpy(&rport->node_name, &ids->node_name,
1378 sizeof(rport->node_name)); 1520 sizeof(rport->node_name));
@@ -1382,6 +1524,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1382 rport->roles = ids->roles; 1524 rport->roles = ids->roles;
1383 rport->port_state = FC_PORTSTATE_ONLINE; 1525 rport->port_state = FC_PORTSTATE_ONLINE;
1384 1526
1527 spin_unlock_irqrestore(shost->host_lock, flags);
1528
1529 if (fci->f->dd_fcrport_size)
1530 memset(rport->dd_data, 0,
1531 fci->f->dd_fcrport_size);
1532
1385 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1533 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
1386 /* initiate a scan of the target */ 1534 /* initiate a scan of the target */
1387 scsi_queue_work(shost, &rport->scan_work); 1535 scsi_queue_work(shost, &rport->scan_work);
@@ -1390,6 +1538,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1390 } 1538 }
1391 } 1539 }
1392 1540
1541 spin_unlock_irqrestore(shost->host_lock, flags);
1542
1393 /* No consistent binding found - create new remote port entry */ 1543 /* No consistent binding found - create new remote port entry */
1394 rport = fc_rport_create(shost, channel, ids); 1544 rport = fc_rport_create(shost, channel, ids);
1395 1545
@@ -1398,25 +1548,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1398EXPORT_SYMBOL(fc_remote_port_add); 1548EXPORT_SYMBOL(fc_remote_port_add);
1399 1549
1400/* 1550/*
1401 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1402 * @rport: The remote port to be operated on
1403 */
1404static void
1405fc_rport_tgt_remove(struct fc_rport *rport)
1406{
1407 struct Scsi_Host *shost = rport_to_shost(rport);
1408
1409 scsi_target_unblock(&rport->dev);
1410
1411 /* Stop anything on the workq */
1412 if (!cancel_delayed_work(&rport->dev_loss_work))
1413 flush_scheduled_work();
1414 scsi_flush_work(shost);
1415
1416 scsi_remove_target(&rport->dev);
1417}
1418
1419/*
1420 * fc_rport_terminate - this routine tears down and deallocates a remote port. 1551 * fc_rport_terminate - this routine tears down and deallocates a remote port.
1421 * @rport: The remote port to be terminated 1552 * @rport: The remote port to be terminated
1422 * 1553 *
@@ -1449,24 +1580,44 @@ fc_rport_terminate(struct fc_rport *rport)
1449 * The LLDD calls this routine to notify the transport that a remote 1580 * The LLDD calls this routine to notify the transport that a remote
1450 * port is no longer part of the topology. Note: Although a port 1581 * port is no longer part of the topology. Note: Although a port
1451 * may no longer be part of the topology, it may persist in the remote 1582 * may no longer be part of the topology, it may persist in the remote
1452 * ports displayed by the fc_host. This is done so that target id 1583 * ports displayed by the fc_host. We do this under 2 conditions:
1453 * mappings (managed via the remote port structures), are always visible 1584 * - If the port was a scsi target, we delay its deletion by "blocking" it.
1454 * as long as the mapping is valid, regardless of port state, 1585 * This allows the port to temporarily disappear, then reappear without
1586 * disrupting the SCSI device tree attached to it. During the "blocked"
1587 * period the port will still exist.
1588 * - If the port was a scsi target and disappears for longer than we
1589 * expect, we'll delete the port and the tear down the SCSI device tree
1590 * attached to it. However, we want to semi-persist the target id assigned
1591 * to that port if it eventually does exist. The port structure will
1592 * remain (although with minimal information) so that the target id
1593 * bindings remails.
1455 * 1594 *
1456 * If the remote port is not an FCP Target, it will be fully torn down 1595 * If the remote port is not an FCP Target, it will be fully torn down
1457 * and deallocated, including the fc_remote_port class device. 1596 * and deallocated, including the fc_remote_port class device.
1458 * 1597 *
1459 * If the remote port is an FCP Target, the port structure will be 1598 * If the remote port is an FCP Target, the port will be placed in a
1460 * marked as Not Present, but will remain as long as there is a valid 1599 * temporary blocked state. From the LLDD's perspective, the rport no
1461 * SCSI target id mapping associated with the port structure. Validity 1600 * longer exists. From the SCSI midlayer's perspective, the SCSI target
1462 * is determined by the binding type. If binding by wwpn, then the port 1601 * exists, but all sdevs on it are blocked from further I/O. The following
1463 * structure is always valid and will not be deallocated until the host 1602 * is then expected:
1464 * is removed. If binding by wwnn, then the port structure is valid 1603 * If the remote port does not return (signaled by a LLDD call to
1465 * until another port with the same node name is found in the topology. 1604 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the
1466 * If binding by port id (fc address), then the port structure is valid 1605 * scsi target is removed - killing all outstanding i/o and removing the
1467 * valid until another port with the same address is identified. 1606 * scsi devices attached ot it. The port structure will be marked Not
1607 * Present and be partially cleared, leaving only enough information to
1608 * recognize the remote port relative to the scsi target id binding if
1609 * it later appears. The port will remain as long as there is a valid
1610 * binding (e.g. until the user changes the binding type or unloads the
1611 * scsi host with the binding).
1468 * 1612 *
1469 * Called from interrupt or normal process context. 1613 * If the remote port returns within the dev_loss_tmo value (and matches
1614 * according to the target id binding type), the port structure will be
1615 * reused. If it is no longer a SCSI target, the target will be torn
1616 * down. If it continues to be a SCSI target, then the target will be
1617 * unblocked (allowing i/o to be resumed), and a scan will be activated
1618 * to ensure that all luns are detected.
1619 *
1620 * Called from normal process context only - cannot be called from interrupt.
1470 * 1621 *
1471 * Notes: 1622 * Notes:
1472 * This routine assumes no locks are held on entry. 1623 * This routine assumes no locks are held on entry.
@@ -1474,53 +1625,20 @@ fc_rport_terminate(struct fc_rport *rport)
1474void 1625void
1475fc_remote_port_delete(struct fc_rport *rport) 1626fc_remote_port_delete(struct fc_rport *rport)
1476{ 1627{
1477 struct Scsi_Host *shost = rport_to_shost(rport); 1628 int timeout = rport->dev_loss_tmo;
1478 unsigned long flags;
1479 1629
1480 /* If no scsi target id mapping or consistent binding type, delete it */ 1630 /* If no scsi target id mapping, delete it */
1481 if ((rport->scsi_target_id == -1) || 1631 if (rport->scsi_target_id == -1) {
1482 (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) {
1483 fc_rport_terminate(rport); 1632 fc_rport_terminate(rport);
1484 return; 1633 return;
1485 } 1634 }
1486 1635
1487 fc_rport_tgt_remove(rport); 1636 scsi_target_block(&rport->dev);
1488 1637
1489 spin_lock_irqsave(shost->host_lock, flags); 1638 /* cap the length the devices can be blocked until they are deleted */
1490 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); 1639 schedule_delayed_work(&rport->dev_loss_work, timeout * HZ);
1491 spin_unlock_irqrestore(shost->host_lock, flags);
1492 1640
1493 /* 1641 rport->port_state = FC_PORTSTATE_BLOCKED;
1494 * Note: We do not remove or clear the hostdata area. This allows
1495 * host-specific target data to persist along with the
1496 * scsi_target_id. It's up to the host to manage it's hostdata area.
1497 */
1498
1499 /*
1500 * Reinitialize port attributes that may change if the port comes back.
1501 */
1502 rport->maxframe_size = -1;
1503 rport->supported_classes = FC_COS_UNSPECIFIED;
1504 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1505 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1506
1507 /* remove the identifiers that aren't used in the consisting binding */
1508 switch (fc_host_tgtid_bind_type(shost)) {
1509 case FC_TGTID_BIND_BY_WWPN:
1510 rport->node_name = -1;
1511 rport->port_id = -1;
1512 break;
1513 case FC_TGTID_BIND_BY_WWNN:
1514 rport->port_name = -1;
1515 rport->port_id = -1;
1516 break;
1517 case FC_TGTID_BIND_BY_ID:
1518 rport->node_name = -1;
1519 rport->port_name = -1;
1520 break;
1521 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1522 break;
1523 }
1524} 1642}
1525EXPORT_SYMBOL(fc_remote_port_delete); 1643EXPORT_SYMBOL(fc_remote_port_delete);
1526 1644
@@ -1553,127 +1671,140 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
1553 unsigned long flags; 1671 unsigned long flags;
1554 int create = 0; 1672 int create = 0;
1555 1673
1556 rport->roles = roles;
1557
1558 spin_lock_irqsave(shost->host_lock, flags); 1674 spin_lock_irqsave(shost->host_lock, flags);
1559 if ((rport->scsi_target_id == -1) && 1675 if (roles & FC_RPORT_ROLE_FCP_TARGET) {
1560 (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 1676 if (rport->scsi_target_id == -1) {
1561 rport->scsi_target_id = fc_host->next_target_id++; 1677 rport->scsi_target_id = fc_host->next_target_id++;
1562 create = 1; 1678 create = 1;
1679 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
1680 create = 1;
1563 } 1681 }
1564 spin_unlock_irqrestore(shost->host_lock, flags); 1682 spin_unlock_irqrestore(shost->host_lock, flags);
1565 1683
1566 if (create) 1684 rport->roles = roles;
1685
1686 if (create) {
1687 /*
1688 * There may have been a delete timer running on the
1689 * port. Ensure that it is cancelled as we now know
1690 * the port is an FCP Target.
1691 * Note: we know the rport is exists and in an online
1692 * state as the LLDD would not have had an rport
1693 * reference to pass us.
1694 *
1695 * Take no action on the del_timer failure as the state
1696 * machine state change will validate the
1697 * transaction.
1698 */
1699 if (!cancel_delayed_work(&rport->dev_loss_work))
1700 flush_scheduled_work();
1701
1567 /* initiate a scan of the target */ 1702 /* initiate a scan of the target */
1568 scsi_queue_work(shost, &rport->scan_work); 1703 scsi_queue_work(shost, &rport->scan_work);
1704 }
1569} 1705}
1570EXPORT_SYMBOL(fc_remote_port_rolechg); 1706EXPORT_SYMBOL(fc_remote_port_rolechg);
1571 1707
1572/** 1708/**
1573 * fc_timeout_blocked_rport - Timeout handler for blocked remote port 1709 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that
1574 * that fails to return in the alloted time. 1710 * was a SCSI target (thus was blocked), and failed
1575 * @data: scsi target that failed to reappear in the alloted time. 1711 * to return in the alloted time.
1712 *
1713 * @data: rport target that failed to reappear in the alloted time.
1576 **/ 1714 **/
1577static void 1715static void
1578fc_timeout_blocked_rport(void *data) 1716fc_timeout_deleted_rport(void *data)
1579{ 1717{
1580 struct fc_rport *rport = (struct fc_rport *)data; 1718 struct fc_rport *rport = (struct fc_rport *)data;
1719 struct Scsi_Host *shost = rport_to_shost(rport);
1720 unsigned long flags;
1581 1721
1582 rport->port_state = FC_PORTSTATE_OFFLINE; 1722 spin_lock_irqsave(shost->host_lock, flags);
1583
1584 dev_printk(KERN_ERR, &rport->dev,
1585 "blocked FC remote port time out: removing target\n");
1586 1723
1587 /* 1724 /*
1588 * As this only occurs if the remote port (scsi target) 1725 * If the port is ONLINE, then it came back, but was no longer an
1589 * went away and didn't come back - we'll remove 1726 * FCP target. Thus we need to tear down the scsi_target on it.
1590 * all attached scsi devices.
1591 */ 1727 */
1592 scsi_target_unblock(&rport->dev); 1728 if (rport->port_state == FC_PORTSTATE_ONLINE) {
1593 scsi_remove_target(&rport->dev); 1729 spin_unlock_irqrestore(shost->host_lock, flags);
1594}
1595 1730
1596/** 1731 dev_printk(KERN_ERR, &rport->dev,
1597 * fc_remote_port_block - temporarily block any scsi traffic to a remote port. 1732 "blocked FC remote port time out: removing target\n");
1598 * @rport: remote port to be blocked.
1599 *
1600 * scsi lldd's with a FC transport call this routine to temporarily stop
1601 * all scsi traffic to a remote port. If the port is not a SCSI target,
1602 * no action is taken. If the port is a SCSI target, all attached devices
1603 * are placed into a SDEV_BLOCK state and a timer is started. The timer is
1604 * represents the maximum amount of time the port may be blocked. If the
1605 * timer expires, the port is considered non-existent and the attached
1606 * scsi devices will be removed.
1607 *
1608 * Called from interrupt or normal process context.
1609 *
1610 * Returns zero if successful or error if not
1611 *
1612 * Notes:
1613 * This routine assumes no locks are held on entry.
1614 *
1615 * The timeout and timer types are extracted from the fc transport
1616 * attributes from the caller's rport pointer.
1617 **/
1618int
1619fc_remote_port_block(struct fc_rport *rport)
1620{
1621 int timeout = rport->dev_loss_tmo;
1622 struct work_struct *work = &rport->dev_loss_work;
1623 1733
1624 if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) 1734 fc_rport_tgt_remove(rport);
1625 return -EINVAL;
1626 1735
1627 scsi_target_block(&rport->dev); 1736 return;
1737 }
1628 1738
1629 /* cap the length the devices can be blocked */ 1739 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
1630 schedule_delayed_work(work, timeout * HZ); 1740 spin_unlock_irqrestore(shost->host_lock, flags);
1741 dev_printk(KERN_ERR, &rport->dev,
1742 "blocked FC remote port time out: leaving target alone\n");
1743 return;
1744 }
1631 1745
1632 rport->port_state = FC_PORTSTATE_BLOCKED; 1746 if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) {
1633 return 0; 1747 spin_unlock_irqrestore(shost->host_lock, flags);
1634} 1748 dev_printk(KERN_ERR, &rport->dev,
1635EXPORT_SYMBOL(fc_remote_port_block); 1749 "blocked FC remote port time out: removing target\n");
1750 fc_rport_terminate(rport);
1751 return;
1752 }
1636 1753
1637/** 1754 dev_printk(KERN_ERR, &rport->dev,
1638 * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port. 1755 "blocked FC remote port time out: removing target and "
1639 * @rport: remote port to be unblocked. 1756 "saving binding\n");
1640 * 1757
1641 * scsi lld's with a FC transport call this routine to restart IO to all 1758 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
1642 * devices associated with the caller's scsi target following a fc_target_block
1643 * request. Called from interrupt or normal process context.
1644 *
1645 * Notes:
1646 * This routine assumes no locks are held on entry.
1647 **/
1648 void
1649fc_remote_port_unblock(struct fc_rport *rport)
1650{
1651 struct work_struct *work = &rport->dev_loss_work;
1652 struct Scsi_Host *shost = rport_to_shost(rport);
1653 1759
1654 /* 1760 /*
1655 * Stop the target timer first. Take no action on the del_timer 1761 * Note: We do not remove or clear the hostdata area. This allows
1656 * failure as the state machine state change will validate the 1762 * host-specific target data to persist along with the
1657 * transaction. 1763 * scsi_target_id. It's up to the host to manage it's hostdata area.
1658 */ 1764 */
1659 if (!cancel_delayed_work(work))
1660 flush_scheduled_work();
1661 1765
1662 if (rport->port_state == FC_PORTSTATE_OFFLINE) 1766 /*
1663 /* 1767 * Reinitialize port attributes that may change if the port comes back.
1664 * initiate a scan of the target as the target has 1768 */
1665 * been torn down. 1769 rport->maxframe_size = -1;
1666 */ 1770 rport->supported_classes = FC_COS_UNSPECIFIED;
1667 scsi_queue_work(shost, &rport->scan_work); 1771 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1668 else 1772 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1669 scsi_target_unblock(&rport->dev);
1670 1773
1671 rport->port_state = FC_PORTSTATE_ONLINE; 1774 /* remove the identifiers that aren't used in the consisting binding */
1775 switch (fc_host_tgtid_bind_type(shost)) {
1776 case FC_TGTID_BIND_BY_WWPN:
1777 rport->node_name = -1;
1778 rport->port_id = -1;
1779 break;
1780 case FC_TGTID_BIND_BY_WWNN:
1781 rport->port_name = -1;
1782 rport->port_id = -1;
1783 break;
1784 case FC_TGTID_BIND_BY_ID:
1785 rport->node_name = -1;
1786 rport->port_name = -1;
1787 break;
1788 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1789 break;
1790 }
1791
1792 spin_unlock_irqrestore(shost->host_lock, flags);
1793
1794 /*
1795 * As this only occurs if the remote port (scsi target)
1796 * went away and didn't come back - we'll remove
1797 * all attached scsi devices.
1798 */
1799 fc_rport_tgt_remove(rport);
1672} 1800}
1673EXPORT_SYMBOL(fc_remote_port_unblock);
1674 1801
1675/** 1802/**
1676 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 1803 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
1804 *
1805 * Will unblock the target (in case it went away and has now come back),
1806 * then invoke a scan.
1807 *
1677 * @data: remote port to be scanned. 1808 * @data: remote port to be scanned.
1678 **/ 1809 **/
1679static void 1810static void
@@ -1681,6 +1812,7 @@ fc_scsi_scan_rport(void *data)
1681{ 1812{
1682 struct fc_rport *rport = (struct fc_rport *)data; 1813 struct fc_rport *rport = (struct fc_rport *)data;
1683 1814
1815 scsi_target_unblock(&rport->dev);
1684 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, 1816 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id,
1685 SCAN_WILD_CARD, 1); 1817 SCAN_WILD_CARD, 1);
1686} 1818}