Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 115442
b: refs/heads/master
c: fff9d40
h: refs/heads/master
v: v3
  • Loading branch information
Mike Christie authored and James Bottomley committed Oct 13, 2008
1 parent 671c207 commit 27409f1
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 21 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a93ce0244f2e94dd48e0b4a2742a4e3bf196ab53
refs/heads/master: fff9d40ce0eb4b46f3e186823ceab6bc02c3e5d3
47 changes: 28 additions & 19 deletions trunk/drivers/scsi/scsi_transport_fc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2133,8 +2133,7 @@ fc_attach_transport(struct fc_function_template *ft)
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
if (ft->terminate_rport_io)
SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);

BUG_ON(count > FC_RPORT_NUM_ATTRS);

Expand Down Expand Up @@ -2328,6 +2327,22 @@ fc_remove_host(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(fc_remove_host);

static void fc_terminate_rport_io(struct fc_rport *rport)
{
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);

/* Involve the LLDD if possible to terminate all io on the rport. */
if (i->f->terminate_rport_io)
i->f->terminate_rport_io(rport);

/*
* must unblock to flush queued IO. The caller will have set
* the port_state or flags, so that fc_remote_port_chkready will
* fail IO.
*/
scsi_target_unblock(&rport->dev);
}

/**
* fc_starget_delete - called to delete the scsi decendents of an rport
Expand All @@ -2340,13 +2355,8 @@ fc_starget_delete(struct work_struct *work)
{
struct fc_rport *rport =
container_of(work, struct fc_rport, stgt_delete_work);
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);

/* Involve the LLDD if possible to terminate all io on the rport. */
if (i->f->terminate_rport_io)
i->f->terminate_rport_io(rport);

fc_terminate_rport_io(rport);
scsi_remove_target(&rport->dev);
}

Expand All @@ -2372,10 +2382,7 @@ fc_rport_final_delete(struct work_struct *work)
if (rport->flags & FC_RPORT_SCAN_PENDING)
scsi_flush_work(shost);

/* involve the LLDD to terminate all pending i/o */
if (i->f->terminate_rport_io)
i->f->terminate_rport_io(rport);

fc_terminate_rport_io(rport);
/*
* Cancel any outstanding timers. These should really exist
* only when rmmod'ing the LLDD and we're asking for
Expand Down Expand Up @@ -2639,7 +2646,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,

spin_lock_irqsave(shost->host_lock, flags);

rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
FC_RPORT_DEVLOSS_PENDING);

/* if target, initiate a scan */
if (rport->scsi_target_id != -1) {
Expand Down Expand Up @@ -2702,6 +2710,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
rport->port_id = ids->port_id;
rport->roles = ids->roles;
rport->port_state = FC_PORTSTATE_ONLINE;
rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;

if (fci->f->dd_fcrport_size)
memset(rport->dd_data, 0,
Expand Down Expand Up @@ -2784,7 +2793,6 @@ void
fc_remote_port_delete(struct fc_rport *rport)
{
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);
int timeout = rport->dev_loss_tmo;
unsigned long flags;

Expand Down Expand Up @@ -2830,7 +2838,7 @@ fc_remote_port_delete(struct fc_rport *rport)

/* see if we need to kill io faster than waiting for device loss */
if ((rport->fast_io_fail_tmo != -1) &&
(rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io))
(rport->fast_io_fail_tmo < timeout))
fc_queue_devloss_work(shost, &rport->fail_io_work,
rport->fast_io_fail_tmo * HZ);

Expand Down Expand Up @@ -2906,7 +2914,8 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
fc_flush_devloss(shost);

spin_lock_irqsave(shost->host_lock, flags);
rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
FC_RPORT_DEVLOSS_PENDING);
spin_unlock_irqrestore(shost->host_lock, flags);

/* ensure any stgt delete functions are done */
Expand Down Expand Up @@ -3001,6 +3010,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
rport->supported_classes = FC_COS_UNSPECIFIED;
rport->roles = FC_PORT_ROLE_UNKNOWN;
rport->port_state = FC_PORTSTATE_NOTPRESENT;
rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;

/* remove the identifiers that aren't used in the consisting binding */
switch (fc_host->tgtid_bind_type) {
Expand Down Expand Up @@ -3043,13 +3053,12 @@ fc_timeout_fail_rport_io(struct work_struct *work)
{
struct fc_rport *rport =
container_of(work, struct fc_rport, fail_io_work.work);
struct Scsi_Host *shost = rport_to_shost(rport);
struct fc_internal *i = to_fc_internal(shost->transportt);

if (rport->port_state != FC_PORTSTATE_BLOCKED)
return;

i->f->terminate_rport_io(rport);
rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
fc_terminate_rport_io(rport);
}

/**
Expand Down
6 changes: 5 additions & 1 deletion trunk/include/scsi/scsi_transport_fc.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ struct fc_rport { /* aka fc_starget_attrs */
/* bit field values for struct fc_rport "flags" field: */
#define FC_RPORT_DEVLOSS_PENDING 0x01
#define FC_RPORT_SCAN_PENDING 0x02
#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x03

#define dev_to_rport(d) \
container_of(d, struct fc_rport, dev)
Expand Down Expand Up @@ -683,7 +684,10 @@ fc_remote_port_chkready(struct fc_rport *rport)
result = DID_NO_CONNECT << 16;
break;
case FC_PORTSTATE_BLOCKED:
result = DID_IMM_RETRY << 16;
if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
result = DID_NO_CONNECT << 16;
else
result = DID_IMM_RETRY << 16;
break;
default:
result = DID_NO_CONNECT << 16;
Expand Down

0 comments on commit 27409f1

Please sign in to comment.