aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorJames.Smart@Emulex.Com <James.Smart@Emulex.Com>2005-10-18 12:03:35 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-10-28 22:20:07 -0400
commit19a7b4aebf9ad435c69a7e39930338499af4d152 (patch)
tree6d1c4cbc822009c8facb219dcd955d52070655d1 /drivers/scsi/scsi_transport_fc.c
parent422c0d61d591cbfb70f029e13505fb437e169d68 (diff)
[SCSI] update fc_transport for removal of block/unblock functions
We recently went back to implement a board reset. When we perform the reset, we wanted to tear down the internal data structures and rebuild them. Unfortunately, when it came to the rport structure, things were odd. If we deleted them, the scsi targets and sdevs would be torn down. Not a good thing for a temporary reset. We could block the rports, but we either maintain the internal structures to keep the rport reference (perhaps even replicating what's in the transport), or we have to fatten the fc transport with new search routines to find the rport (and deal with a case of a dangling rport that the driver forgets). It dawned on me that we had actually reached this state incorrectly. When the fc transport first started, we did the block/unblock first, then added the rport interface. The purpose of block/unblock is to hide the temporary disappearance of the rport (e.g. being deleted, then readded). Why are we making the driver do the block/unblock ? We should be making the transport have only an rport add/delete, and the let the transport handle the block/unblock. So... This patch removes the existing fc_remote_port_block/unblock functions. It moves the block/unblock functionality into the fc_remote_port_add/delete functions. Updates for the lpfc driver are included. Qlogic driver updates are also enclosed, thanks to the contributions of Andrew Vasquez. [Note: the qla2xxx changes are relative to the scsi-misc-2.6 tree as of this morning - which does not include the recent patches sent by Andrew]. The zfcp driver does not use the block/unblock functions. One last comment: The resulting behavior feels very clean. The LLDD is concerned only with add/delete, which corresponds to the physical disappearance. However, the fact that the scsi target and sdevs are not immediately torn down after the LLDD calls delete causes an interesting scenario... the midlayer can call the xxx_slave_alloc and xxx_queuecommand functions with a sdev that is at the location the rport used to be. The driver must validate the device exists when it first enters these functions. In thinking about it, this has always been the case for the LLDD and these routines. The existing drivers already check for existence. However, this highlights that simple validation via data structure dereferencing needs to be watched. To deal with this, a new transport function, fc_remote_port_chkready() was created that LLDDs should call when they first enter these two routines. It validates the rport state, and returns a scsi result which could be returned. In addition to solving the above, it also creates consistent behavior from the LLDD's when the block and deletes are occuring. Rejections fixed up and 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.c446
1 files changed, 278 insertions, 168 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 27702097b7fc..ca098fc2a607 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -210,7 +210,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
210#define FC_MGMTSRVR_PORTID 0x00000a 210#define FC_MGMTSRVR_PORTID 0x00000a
211 211
212 212
213static void fc_timeout_blocked_rport(void *data); 213static void fc_timeout_deleted_rport(void *data);
214static void fc_scsi_scan_rport(void *data); 214static void fc_scsi_scan_rport(void *data);
215static void fc_rport_terminate(struct fc_rport *rport); 215static void fc_rport_terminate(struct fc_rport *rport);
216 216
@@ -384,7 +384,9 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \
384 struct fc_rport *rport = transport_class_to_rport(cdev); \ 384 struct fc_rport *rport = transport_class_to_rport(cdev); \
385 struct Scsi_Host *shost = rport_to_shost(rport); \ 385 struct Scsi_Host *shost = rport_to_shost(rport); \
386 struct fc_internal *i = to_fc_internal(shost->transportt); \ 386 struct fc_internal *i = to_fc_internal(shost->transportt); \
387 if (i->f->get_rport_##field) \ 387 if ((i->f->get_rport_##field) && \
388 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \
389 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \
388 i->f->get_rport_##field(rport); \ 390 i->f->get_rport_##field(rport); \
389 return snprintf(buf, sz, format_string, cast rport->field); \ 391 return snprintf(buf, sz, format_string, cast rport->field); \
390} 392}
@@ -398,6 +400,9 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \
398 struct fc_rport *rport = transport_class_to_rport(cdev); \ 400 struct fc_rport *rport = transport_class_to_rport(cdev); \
399 struct Scsi_Host *shost = rport_to_shost(rport); \ 401 struct Scsi_Host *shost = rport_to_shost(rport); \
400 struct fc_internal *i = to_fc_internal(shost->transportt); \ 402 struct fc_internal *i = to_fc_internal(shost->transportt); \
403 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
404 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
405 return -EBUSY; \
401 val = simple_strtoul(buf, NULL, 0); \ 406 val = simple_strtoul(buf, NULL, 0); \
402 i->f->set_rport_##field(rport, val); \ 407 i->f->set_rport_##field(rport, val); \
403 return count; \ 408 return count; \
@@ -500,7 +505,29 @@ static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
500 505
501/* Dynamic Remote Port Attributes */ 506/* Dynamic Remote Port Attributes */
502 507
503fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20); 508/*
509 * dev_loss_tmo attribute
510 */
511fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
512static ssize_t
513store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
514 size_t count)
515{
516 int val;
517 struct fc_rport *rport = transport_class_to_rport(cdev);
518 struct Scsi_Host *shost = rport_to_shost(rport);
519 struct fc_internal *i = to_fc_internal(shost->transportt);
520 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
521 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
522 return -EBUSY;
523 val = simple_strtoul(buf, NULL, 0);
524 if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
525 return -EINVAL;
526 i->f->set_rport_dev_loss_tmo(rport, val);
527 return count;
528}
529static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
530 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
504 531
505 532
506/* Private Remote Port Attributes */ 533/* Private Remote Port Attributes */
@@ -1214,6 +1241,25 @@ fc_remove_host(struct Scsi_Host *shost)
1214} 1241}
1215EXPORT_SYMBOL(fc_remove_host); 1242EXPORT_SYMBOL(fc_remove_host);
1216 1243
1244/*
1245 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1246 * @rport: The remote port to be operated on
1247 */
1248static void
1249fc_rport_tgt_remove(struct fc_rport *rport)
1250{
1251 struct Scsi_Host *shost = rport_to_shost(rport);
1252
1253 scsi_target_unblock(&rport->dev);
1254
1255 /* Stop anything on the workq */
1256 if (!cancel_delayed_work(&rport->dev_loss_work))
1257 flush_scheduled_work();
1258 scsi_flush_work(shost);
1259
1260 scsi_remove_target(&rport->dev);
1261}
1262
1217/** 1263/**
1218 * fc_rport_create - allocates and creates a remote FC port. 1264 * fc_rport_create - allocates and creates a remote FC port.
1219 * @shost: scsi host the remote port is connected to. 1265 * @shost: scsi host the remote port is connected to.
@@ -1260,7 +1306,7 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1260 rport->dd_data = &rport[1]; 1306 rport->dd_data = &rport[1];
1261 rport->channel = channel; 1307 rport->channel = channel;
1262 1308
1263 INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport); 1309 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
1264 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1310 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
1265 1311
1266 spin_lock_irqsave(shost->host_lock, flags); 1312 spin_lock_irqsave(shost->host_lock, flags);
@@ -1352,17 +1398,93 @@ struct fc_rport *
1352fc_remote_port_add(struct Scsi_Host *shost, int channel, 1398fc_remote_port_add(struct Scsi_Host *shost, int channel,
1353 struct fc_rport_identifiers *ids) 1399 struct fc_rport_identifiers *ids)
1354{ 1400{
1401 struct fc_internal *fci = to_fc_internal(shost->transportt);
1355 struct fc_rport *rport; 1402 struct fc_rport *rport;
1356 unsigned long flags; 1403 unsigned long flags;
1357 int match = 0; 1404 int match = 0;
1358 1405
1406 /*
1407 * Search the list of "active" rports, for an rport that has been
1408 * deleted, but we've held off the real delete while the target
1409 * is in a "blocked" state.
1410 */
1411 spin_lock_irqsave(shost->host_lock, flags);
1412
1413 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1414
1415 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
1416 (rport->channel == channel)) {
1417
1418 switch (fc_host_tgtid_bind_type(shost)) {
1419 case FC_TGTID_BIND_BY_WWPN:
1420 case FC_TGTID_BIND_NONE:
1421 if (rport->port_name == ids->port_name)
1422 match = 1;
1423 break;
1424 case FC_TGTID_BIND_BY_WWNN:
1425 if (rport->node_name == ids->node_name)
1426 match = 1;
1427 break;
1428 case FC_TGTID_BIND_BY_ID:
1429 if (rport->port_id == ids->port_id)
1430 match = 1;
1431 break;
1432 }
1433
1434 if (match) {
1435 struct work_struct *work =
1436 &rport->dev_loss_work;
1437
1438 memcpy(&rport->node_name, &ids->node_name,
1439 sizeof(rport->node_name));
1440 memcpy(&rport->port_name, &ids->port_name,
1441 sizeof(rport->port_name));
1442 rport->port_id = ids->port_id;
1443
1444 rport->port_state = FC_PORTSTATE_ONLINE;
1445 rport->roles = ids->roles;
1446
1447 spin_unlock_irqrestore(shost->host_lock, flags);
1448
1449 if (fci->f->dd_fcrport_size)
1450 memset(rport->dd_data, 0,
1451 fci->f->dd_fcrport_size);
1452
1453 /*
1454 * If we were blocked, we were a target.
1455 * If no longer a target, we leave the timer
1456 * running in case the port changes roles
1457 * prior to the timer expiring. If the timer
1458 * fires, the target will be torn down.
1459 */
1460 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
1461 return rport;
1462
1463 /* restart the target */
1464
1465 /*
1466 * Stop the target timer first. Take no action
1467 * on the del_timer failure as the state
1468 * machine state change will validate the
1469 * transaction.
1470 */
1471 if (!cancel_delayed_work(work))
1472 flush_scheduled_work();
1473
1474 /* initiate a scan of the target */
1475 scsi_queue_work(shost, &rport->scan_work);
1476
1477 return rport;
1478 }
1479 }
1480 }
1481
1482 /* Search the bindings array */
1359 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && 1483 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) &&
1360 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { 1484 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) {
1361 1485
1362 /* search for a matching consistent binding */ 1486 /* search for a matching consistent binding */
1363 1487
1364 spin_lock_irqsave(shost->host_lock, flags);
1365
1366 list_for_each_entry(rport, &fc_host_rport_bindings(shost), 1488 list_for_each_entry(rport, &fc_host_rport_bindings(shost),
1367 peers) { 1489 peers) {
1368 if (rport->channel != channel) 1490 if (rport->channel != channel)
@@ -1392,8 +1514,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1392 } 1514 }
1393 } 1515 }
1394 1516
1395 spin_unlock_irqrestore(shost->host_lock, flags);
1396
1397 if (match) { 1517 if (match) {
1398 memcpy(&rport->node_name, &ids->node_name, 1518 memcpy(&rport->node_name, &ids->node_name,
1399 sizeof(rport->node_name)); 1519 sizeof(rport->node_name));
@@ -1403,6 +1523,12 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1403 rport->roles = ids->roles; 1523 rport->roles = ids->roles;
1404 rport->port_state = FC_PORTSTATE_ONLINE; 1524 rport->port_state = FC_PORTSTATE_ONLINE;
1405 1525
1526 spin_unlock_irqrestore(shost->host_lock, flags);
1527
1528 if (fci->f->dd_fcrport_size)
1529 memset(rport->dd_data, 0,
1530 fci->f->dd_fcrport_size);
1531
1406 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1532 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
1407 /* initiate a scan of the target */ 1533 /* initiate a scan of the target */
1408 scsi_queue_work(shost, &rport->scan_work); 1534 scsi_queue_work(shost, &rport->scan_work);
@@ -1411,6 +1537,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1411 } 1537 }
1412 } 1538 }
1413 1539
1540 spin_unlock_irqrestore(shost->host_lock, flags);
1541
1414 /* No consistent binding found - create new remote port entry */ 1542 /* No consistent binding found - create new remote port entry */
1415 rport = fc_rport_create(shost, channel, ids); 1543 rport = fc_rport_create(shost, channel, ids);
1416 1544
@@ -1419,25 +1547,6 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1419EXPORT_SYMBOL(fc_remote_port_add); 1547EXPORT_SYMBOL(fc_remote_port_add);
1420 1548
1421/* 1549/*
1422 * fc_rport_tgt_remove - Removes the scsi target on the remote port
1423 * @rport: The remote port to be operated on
1424 */
1425static void
1426fc_rport_tgt_remove(struct fc_rport *rport)
1427{
1428 struct Scsi_Host *shost = rport_to_shost(rport);
1429
1430 scsi_target_unblock(&rport->dev);
1431
1432 /* Stop anything on the workq */
1433 if (!cancel_delayed_work(&rport->dev_loss_work))
1434 flush_scheduled_work();
1435 scsi_flush_work(shost);
1436
1437 scsi_remove_target(&rport->dev);
1438}
1439
1440/*
1441 * fc_rport_terminate - this routine tears down and deallocates a remote port. 1550 * fc_rport_terminate - this routine tears down and deallocates a remote port.
1442 * @rport: The remote port to be terminated 1551 * @rport: The remote port to be terminated
1443 * 1552 *
@@ -1470,24 +1579,44 @@ fc_rport_terminate(struct fc_rport *rport)
1470 * The LLDD calls this routine to notify the transport that a remote 1579 * The LLDD calls this routine to notify the transport that a remote
1471 * port is no longer part of the topology. Note: Although a port 1580 * port is no longer part of the topology. Note: Although a port
1472 * may no longer be part of the topology, it may persist in the remote 1581 * may no longer be part of the topology, it may persist in the remote
1473 * ports displayed by the fc_host. This is done so that target id 1582 * ports displayed by the fc_host. We do this under 2 conditions:
1474 * mappings (managed via the remote port structures), are always visible 1583 * - If the port was a scsi target, we delay its deletion by "blocking" it.
1475 * as long as the mapping is valid, regardless of port state, 1584 * This allows the port to temporarily disappear, then reappear without
1585 * disrupting the SCSI device tree attached to it. During the "blocked"
1586 * period the port will still exist.
1587 * - If the port was a scsi target and disappears for longer than we
1588 * expect, we'll delete the port and the tear down the SCSI device tree
1589 * attached to it. However, we want to semi-persist the target id assigned
1590 * to that port if it eventually does exist. The port structure will
1591 * remain (although with minimal information) so that the target id
1592 * bindings remails.
1476 * 1593 *
1477 * If the remote port is not an FCP Target, it will be fully torn down 1594 * If the remote port is not an FCP Target, it will be fully torn down
1478 * and deallocated, including the fc_remote_port class device. 1595 * and deallocated, including the fc_remote_port class device.
1479 * 1596 *
1480 * If the remote port is an FCP Target, the port structure will be 1597 * If the remote port is an FCP Target, the port will be placed in a
1481 * marked as Not Present, but will remain as long as there is a valid 1598 * temporary blocked state. From the LLDD's perspective, the rport no
1482 * SCSI target id mapping associated with the port structure. Validity 1599 * longer exists. From the SCSI midlayer's perspective, the SCSI target
1483 * is determined by the binding type. If binding by wwpn, then the port 1600 * exists, but all sdevs on it are blocked from further I/O. The following
1484 * structure is always valid and will not be deallocated until the host 1601 * is then expected:
1485 * is removed. If binding by wwnn, then the port structure is valid 1602 * If the remote port does not return (signaled by a LLDD call to
1486 * until another port with the same node name is found in the topology. 1603 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the
1487 * If binding by port id (fc address), then the port structure is valid 1604 * scsi target is removed - killing all outstanding i/o and removing the
1488 * valid until another port with the same address is identified. 1605 * scsi devices attached ot it. The port structure will be marked Not
1606 * Present and be partially cleared, leaving only enough information to
1607 * recognize the remote port relative to the scsi target id binding if
1608 * it later appears. The port will remain as long as there is a valid
1609 * binding (e.g. until the user changes the binding type or unloads the
1610 * scsi host with the binding).
1489 * 1611 *
1490 * Called from interrupt or normal process context. 1612 * If the remote port returns within the dev_loss_tmo value (and matches
1613 * according to the target id binding type), the port structure will be
1614 * reused. If it is no longer a SCSI target, the target will be torn
1615 * down. If it continues to be a SCSI target, then the target will be
1616 * unblocked (allowing i/o to be resumed), and a scan will be activated
1617 * to ensure that all luns are detected.
1618 *
1619 * Called from normal process context only - cannot be called from interrupt.
1491 * 1620 *
1492 * Notes: 1621 * Notes:
1493 * This routine assumes no locks are held on entry. 1622 * This routine assumes no locks are held on entry.
@@ -1495,53 +1624,20 @@ fc_rport_terminate(struct fc_rport *rport)
1495void 1624void
1496fc_remote_port_delete(struct fc_rport *rport) 1625fc_remote_port_delete(struct fc_rport *rport)
1497{ 1626{
1498 struct Scsi_Host *shost = rport_to_shost(rport); 1627 int timeout = rport->dev_loss_tmo;
1499 unsigned long flags;
1500 1628
1501 /* If no scsi target id mapping or consistent binding type, delete it */ 1629 /* If no scsi target id mapping, delete it */
1502 if ((rport->scsi_target_id == -1) || 1630 if (rport->scsi_target_id == -1) {
1503 (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) {
1504 fc_rport_terminate(rport); 1631 fc_rport_terminate(rport);
1505 return; 1632 return;
1506 } 1633 }
1507 1634
1508 fc_rport_tgt_remove(rport); 1635 scsi_target_block(&rport->dev);
1509
1510 spin_lock_irqsave(shost->host_lock, flags);
1511 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
1512 spin_unlock_irqrestore(shost->host_lock, flags);
1513
1514 /*
1515 * Note: We do not remove or clear the hostdata area. This allows
1516 * host-specific target data to persist along with the
1517 * scsi_target_id. It's up to the host to manage it's hostdata area.
1518 */
1519 1636
1520 /* 1637 /* cap the length the devices can be blocked until they are deleted */
1521 * Reinitialize port attributes that may change if the port comes back. 1638 schedule_delayed_work(&rport->dev_loss_work, timeout * HZ);
1522 */
1523 rport->maxframe_size = -1;
1524 rport->supported_classes = FC_COS_UNSPECIFIED;
1525 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1526 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1527 1639
1528 /* remove the identifiers that aren't used in the consisting binding */ 1640 rport->port_state = FC_PORTSTATE_BLOCKED;
1529 switch (fc_host_tgtid_bind_type(shost)) {
1530 case FC_TGTID_BIND_BY_WWPN:
1531 rport->node_name = -1;
1532 rport->port_id = -1;
1533 break;
1534 case FC_TGTID_BIND_BY_WWNN:
1535 rport->port_name = -1;
1536 rport->port_id = -1;
1537 break;
1538 case FC_TGTID_BIND_BY_ID:
1539 rport->node_name = -1;
1540 rport->port_name = -1;
1541 break;
1542 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1543 break;
1544 }
1545} 1641}
1546EXPORT_SYMBOL(fc_remote_port_delete); 1642EXPORT_SYMBOL(fc_remote_port_delete);
1547 1643
@@ -1574,127 +1670,140 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
1574 unsigned long flags; 1670 unsigned long flags;
1575 int create = 0; 1671 int create = 0;
1576 1672
1577 rport->roles = roles;
1578
1579 spin_lock_irqsave(shost->host_lock, flags); 1673 spin_lock_irqsave(shost->host_lock, flags);
1580 if ((rport->scsi_target_id == -1) && 1674 if (roles & FC_RPORT_ROLE_FCP_TARGET) {
1581 (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 1675 if (rport->scsi_target_id == -1) {
1582 rport->scsi_target_id = fc_host->next_target_id++; 1676 rport->scsi_target_id = fc_host->next_target_id++;
1583 create = 1; 1677 create = 1;
1678 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
1679 create = 1;
1584 } 1680 }
1585 spin_unlock_irqrestore(shost->host_lock, flags); 1681 spin_unlock_irqrestore(shost->host_lock, flags);
1586 1682
1587 if (create) 1683 rport->roles = roles;
1684
1685 if (create) {
1686 /*
1687 * There may have been a delete timer running on the
1688 * port. Ensure that it is cancelled as we now know
1689 * the port is an FCP Target.
1690 * Note: we know the rport is exists and in an online
1691 * state as the LLDD would not have had an rport
1692 * reference to pass us.
1693 *
1694 * Take no action on the del_timer failure as the state
1695 * machine state change will validate the
1696 * transaction.
1697 */
1698 if (!cancel_delayed_work(&rport->dev_loss_work))
1699 flush_scheduled_work();
1700
1588 /* initiate a scan of the target */ 1701 /* initiate a scan of the target */
1589 scsi_queue_work(shost, &rport->scan_work); 1702 scsi_queue_work(shost, &rport->scan_work);
1703 }
1590} 1704}
1591EXPORT_SYMBOL(fc_remote_port_rolechg); 1705EXPORT_SYMBOL(fc_remote_port_rolechg);
1592 1706
1593/** 1707/**
1594 * fc_timeout_blocked_rport - Timeout handler for blocked remote port 1708 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that
1595 * that fails to return in the alloted time. 1709 * was a SCSI target (thus was blocked), and failed
1596 * @data: scsi target that failed to reappear in the alloted time. 1710 * to return in the alloted time.
1711 *
1712 * @data: rport target that failed to reappear in the alloted time.
1597 **/ 1713 **/
1598static void 1714static void
1599fc_timeout_blocked_rport(void *data) 1715fc_timeout_deleted_rport(void *data)
1600{ 1716{
1601 struct fc_rport *rport = (struct fc_rport *)data; 1717 struct fc_rport *rport = (struct fc_rport *)data;
1718 struct Scsi_Host *shost = rport_to_shost(rport);
1719 unsigned long flags;
1602 1720
1603 rport->port_state = FC_PORTSTATE_OFFLINE; 1721 spin_lock_irqsave(shost->host_lock, flags);
1604
1605 dev_printk(KERN_ERR, &rport->dev,
1606 "blocked FC remote port time out: removing target\n");
1607 1722
1608 /* 1723 /*
1609 * As this only occurs if the remote port (scsi target) 1724 * If the port is ONLINE, then it came back, but was no longer an
1610 * went away and didn't come back - we'll remove 1725 * FCP target. Thus we need to tear down the scsi_target on it.
1611 * all attached scsi devices.
1612 */ 1726 */
1613 scsi_target_unblock(&rport->dev); 1727 if (rport->port_state == FC_PORTSTATE_ONLINE) {
1614 scsi_remove_target(&rport->dev); 1728 spin_unlock_irqrestore(shost->host_lock, flags);
1615}
1616 1729
1617/** 1730 dev_printk(KERN_ERR, &rport->dev,
1618 * fc_remote_port_block - temporarily block any scsi traffic to a remote port. 1731 "blocked FC remote port time out: removing target\n");
1619 * @rport: remote port to be blocked.
1620 *
1621 * scsi lldd's with a FC transport call this routine to temporarily stop
1622 * all scsi traffic to a remote port. If the port is not a SCSI target,
1623 * no action is taken. If the port is a SCSI target, all attached devices
1624 * are placed into a SDEV_BLOCK state and a timer is started. The timer is
1625 * represents the maximum amount of time the port may be blocked. If the
1626 * timer expires, the port is considered non-existent and the attached
1627 * scsi devices will be removed.
1628 *
1629 * Called from interrupt or normal process context.
1630 *
1631 * Returns zero if successful or error if not
1632 *
1633 * Notes:
1634 * This routine assumes no locks are held on entry.
1635 *
1636 * The timeout and timer types are extracted from the fc transport
1637 * attributes from the caller's rport pointer.
1638 **/
1639int
1640fc_remote_port_block(struct fc_rport *rport)
1641{
1642 int timeout = rport->dev_loss_tmo;
1643 struct work_struct *work = &rport->dev_loss_work;
1644 1732
1645 if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) 1733 fc_rport_tgt_remove(rport);
1646 return -EINVAL;
1647 1734
1648 scsi_target_block(&rport->dev); 1735 return;
1736 }
1649 1737
1650 /* cap the length the devices can be blocked */ 1738 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
1651 schedule_delayed_work(work, timeout * HZ); 1739 spin_unlock_irqrestore(shost->host_lock, flags);
1740 dev_printk(KERN_ERR, &rport->dev,
1741 "blocked FC remote port time out: leaving target alone\n");
1742 return;
1743 }
1652 1744
1653 rport->port_state = FC_PORTSTATE_BLOCKED; 1745 if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) {
1654 return 0; 1746 spin_unlock_irqrestore(shost->host_lock, flags);
1655} 1747 dev_printk(KERN_ERR, &rport->dev,
1656EXPORT_SYMBOL(fc_remote_port_block); 1748 "blocked FC remote port time out: removing target\n");
1749 fc_rport_terminate(rport);
1750 return;
1751 }
1657 1752
1658/** 1753 dev_printk(KERN_ERR, &rport->dev,
1659 * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port. 1754 "blocked FC remote port time out: removing target and "
1660 * @rport: remote port to be unblocked. 1755 "saving binding\n");
1661 * 1756
1662 * scsi lld's with a FC transport call this routine to restart IO to all 1757 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost));
1663 * devices associated with the caller's scsi target following a fc_target_block
1664 * request. Called from interrupt or normal process context.
1665 *
1666 * Notes:
1667 * This routine assumes no locks are held on entry.
1668 **/
1669 void
1670fc_remote_port_unblock(struct fc_rport *rport)
1671{
1672 struct work_struct *work = &rport->dev_loss_work;
1673 struct Scsi_Host *shost = rport_to_shost(rport);
1674 1758
1675 /* 1759 /*
1676 * Stop the target timer first. Take no action on the del_timer 1760 * Note: We do not remove or clear the hostdata area. This allows
1677 * failure as the state machine state change will validate the 1761 * host-specific target data to persist along with the
1678 * transaction. 1762 * scsi_target_id. It's up to the host to manage it's hostdata area.
1679 */ 1763 */
1680 if (!cancel_delayed_work(work))
1681 flush_scheduled_work();
1682 1764
1683 if (rport->port_state == FC_PORTSTATE_OFFLINE) 1765 /*
1684 /* 1766 * Reinitialize port attributes that may change if the port comes back.
1685 * initiate a scan of the target as the target has 1767 */
1686 * been torn down. 1768 rport->maxframe_size = -1;
1687 */ 1769 rport->supported_classes = FC_COS_UNSPECIFIED;
1688 scsi_queue_work(shost, &rport->scan_work); 1770 rport->roles = FC_RPORT_ROLE_UNKNOWN;
1689 else 1771 rport->port_state = FC_PORTSTATE_NOTPRESENT;
1690 scsi_target_unblock(&rport->dev);
1691 1772
1692 rport->port_state = FC_PORTSTATE_ONLINE; 1773 /* remove the identifiers that aren't used in the consisting binding */
1774 switch (fc_host_tgtid_bind_type(shost)) {
1775 case FC_TGTID_BIND_BY_WWPN:
1776 rport->node_name = -1;
1777 rport->port_id = -1;
1778 break;
1779 case FC_TGTID_BIND_BY_WWNN:
1780 rport->port_name = -1;
1781 rport->port_id = -1;
1782 break;
1783 case FC_TGTID_BIND_BY_ID:
1784 rport->node_name = -1;
1785 rport->port_name = -1;
1786 break;
1787 case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1788 break;
1789 }
1790
1791 spin_unlock_irqrestore(shost->host_lock, flags);
1792
1793 /*
1794 * As this only occurs if the remote port (scsi target)
1795 * went away and didn't come back - we'll remove
1796 * all attached scsi devices.
1797 */
1798 fc_rport_tgt_remove(rport);
1693} 1799}
1694EXPORT_SYMBOL(fc_remote_port_unblock);
1695 1800
1696/** 1801/**
1697 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 1802 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
1803 *
1804 * Will unblock the target (in case it went away and has now come back),
1805 * then invoke a scan.
1806 *
1698 * @data: remote port to be scanned. 1807 * @data: remote port to be scanned.
1699 **/ 1808 **/
1700static void 1809static void
@@ -1702,6 +1811,7 @@ fc_scsi_scan_rport(void *data)
1702{ 1811{
1703 struct fc_rport *rport = (struct fc_rport *)data; 1812 struct fc_rport *rport = (struct fc_rport *)data;
1704 1813
1814 scsi_target_unblock(&rport->dev);
1705 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, 1815 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id,
1706 SCAN_WILD_CARD, 1); 1816 SCAN_WILD_CARD, 1);
1707} 1817}