Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 35059
b: refs/heads/master
c: 4eff4a3
h: refs/heads/master
i:
  35057: 0e55d7a
  35055: 0fbfc8e
v: v3
  • Loading branch information
Andreas Herrmann authored and James Bottomley committed Sep 23, 2006
1 parent 2ce8783 commit 0377b98
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 50 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: dd52e0eaf891cd85bf2ca057c15ed6bfd76db4e6
refs/heads/master: 4eff4a36516d72e4f6ede901141214a7e05607e7
4 changes: 4 additions & 0 deletions trunk/drivers/s390/scsi/zfcp_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ struct zfcp_fsf_req *zfcp_reqlist_ismember(struct zfcp_adapter *adapter,
struct zfcp_fsf_req *request, *tmp;
unsigned int i;

/* 0 is reserved as an invalid req_id */
if (req_id == 0)
return NULL;

i = req_id % REQUEST_LIST_SIZE;

list_for_each_entry_safe(request, tmp, &adapter->req_list[i], list)
Expand Down
13 changes: 6 additions & 7 deletions trunk/drivers/s390/scsi/zfcp_dbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *fsf_req,
struct zfcp_fsf_req *old_fsf_req)
unsigned long old_req_id)
{
struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
Expand Down Expand Up @@ -768,8 +768,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
rec->fsf_seqno = fsf_req->seq_no;
rec->fsf_issued = fsf_req->issued;
}
rec->type.old_fsf_reqid =
(unsigned long) old_fsf_req;
rec->type.old_fsf_reqid = old_req_id;
} else {
strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
dump->total_size = buflen;
Expand All @@ -794,17 +793,17 @@ zfcp_scsi_dbf_event_result(const char *tag, int level,
struct zfcp_fsf_req *fsf_req)
{
_zfcp_scsi_dbf_event_common("rslt", tag, level,
adapter, scsi_cmnd, fsf_req, NULL);
adapter, scsi_cmnd, fsf_req, 0);
}

inline void
zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *new_fsf_req,
struct zfcp_fsf_req *old_fsf_req)
unsigned long old_req_id)
{
_zfcp_scsi_dbf_event_common("abrt", tag, 1,
adapter, scsi_cmnd, new_fsf_req, old_fsf_req);
adapter, scsi_cmnd, new_fsf_req, old_req_id);
}

inline void
Expand All @@ -814,7 +813,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
struct zfcp_adapter *adapter = unit->port->adapter;

_zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
tag, 1, adapter, scsi_cmnd, NULL, NULL);
tag, 1, adapter, scsi_cmnd, NULL, 0);
}

static int
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
struct zfcp_fsf_req *);
extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
struct scsi_cmnd *, struct zfcp_fsf_req *,
struct zfcp_fsf_req *);
unsigned long);
extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
struct scsi_cmnd *);
extern void zfcp_reqlist_add(struct zfcp_adapter *, struct zfcp_fsf_req *);
Expand Down
9 changes: 4 additions & 5 deletions trunk/drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -3527,7 +3527,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
fsf_req->unit = unit;

/* associate FSF request with SCSI request (for look up on abort) */
scsi_cmnd->host_scribble = (char *) fsf_req;
scsi_cmnd->host_scribble = (unsigned char *) fsf_req->req_id;

/* associate SCSI command with FSF request */
fsf_req->data = (unsigned long) scsi_cmnd;
Expand Down Expand Up @@ -4667,7 +4667,6 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
{
volatile struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *fsf_req = NULL;
unsigned long flags;
int ret = 0;
struct zfcp_qdio_queue *req_queue = &adapter->request_queue;

Expand All @@ -4684,10 +4683,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags,
fsf_req->fsf_command = fsf_cmd;
INIT_LIST_HEAD(&fsf_req->list);

/* unique request id */
spin_lock_irqsave(&adapter->req_list_lock, flags);
/* this is serialized (we are holding req_queue-lock of adapter */
if (adapter->req_no == 0)
adapter->req_no++;
fsf_req->req_id = adapter->req_no++;
spin_unlock_irqrestore(&adapter->req_list_lock, flags);

zfcp_fsf_req_qtcb_init(fsf_req);

Expand Down
63 changes: 27 additions & 36 deletions trunk/drivers/s390/scsi/zfcp_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,16 +378,15 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
* will handle late commands. (Usually, the normal completion of late
* commands is ignored with respect to the running abort operation.)
*/
int
zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
struct Scsi_Host *scsi_host;
struct zfcp_adapter *adapter;
struct zfcp_unit *unit;
int retval = SUCCESS;
struct zfcp_fsf_req *new_fsf_req = NULL;
struct zfcp_fsf_req *old_fsf_req;
struct zfcp_fsf_req *fsf_req;
unsigned long flags;
unsigned long old_req_id;
int retval = SUCCESS;

scsi_host = scpnt->device->host;
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
Expand All @@ -399,55 +398,47 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
/* avoid race condition between late normal completion and abort */
write_lock_irqsave(&adapter->abort_lock, flags);

/*
* Check whether command has just completed and can not be aborted.
* Even if the command has just been completed late, we can access
* scpnt since the SCSI stack does not release it at least until
* this routine returns. (scpnt is parameter passed to this routine
* and must not disappear during abort even on late completion.)
*/
old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
if (!old_fsf_req) {
/* Check whether corresponding fsf_req is still pending */
spin_lock(&adapter->req_list_lock);
fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long)
scpnt->host_scribble);
spin_unlock(&adapter->req_list_lock);
if (!fsf_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags);
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL);
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0);
retval = SUCCESS;
goto out;
}
old_fsf_req->data = 0;
old_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
fsf_req->data = 0;
fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
old_req_id = fsf_req->req_id;

/* don't access old_fsf_req after releasing the abort_lock */
/* don't access old fsf_req after releasing the abort_lock */
write_unlock_irqrestore(&adapter->abort_lock, flags);
/* call FSF routine which does the abort */
new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,
adapter, unit, 0);
if (!new_fsf_req) {

fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0);
if (!fsf_req) {
ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
old_fsf_req);
old_req_id);
retval = FAILED;
goto out;
}

/* wait for completion of abort */
__wait_event(new_fsf_req->completion_wq,
new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
__wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

/* status should be valid since signals were not permitted */
if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req,
NULL);
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0);
retval = SUCCESS;
} else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req,
NULL);
} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0);
retval = SUCCESS;
} else {
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req,
NULL);
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0);
retval = FAILED;
}
zfcp_fsf_req_free(new_fsf_req);
zfcp_fsf_req_free(fsf_req);
out:
return retval;
}
Expand Down

0 comments on commit 0377b98

Please sign in to comment.