Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 136285
b: refs/heads/master
c: 63caf36
h: refs/heads/master
i:
  136283: 2a961de
v: v3
  • Loading branch information
Christof Schmitt authored and James Bottomley committed Mar 12, 2009
1 parent 4bdb434 commit 1eb8140
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 100 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: 92cab0d93a1107ad7f6d827fde62d1aa4db15e86
refs/heads/master: 63caf367e1c92e0667a344d9b687c04e6ef054b5
3 changes: 0 additions & 3 deletions trunk/drivers/s390/scsi/zfcp_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -586,9 +586,6 @@ struct zfcp_fsf_req_qtcb {

/********************** ZFCP SPECIFIC DEFINES ********************************/

#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
#define ZFCP_REQ_NO_QTCB 0x00000008

#define ZFCP_SET 0x00000100
#define ZFCP_CLEAR 0x00000200

Expand Down
11 changes: 4 additions & 7 deletions trunk/drivers/s390/scsi/zfcp_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,13 @@ extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
extern int zfcp_fsf_send_ct(struct zfcp_send_ct *, mempool_t *,
struct zfcp_erp_action *);
extern int zfcp_fsf_send_els(struct zfcp_send_els *);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *,
struct zfcp_unit *,
struct scsi_cmnd *, int, int);
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
struct scsi_cmnd *);
extern void zfcp_fsf_req_complete(struct zfcp_fsf_req *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *,
struct zfcp_unit *, u8, int);
extern struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *, u8);
extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long,
struct zfcp_adapter *,
struct zfcp_unit *, int);
struct zfcp_unit *);

/* zfcp_qdio.c */
extern int zfcp_qdio_allocate(struct zfcp_adapter *);
Expand Down
39 changes: 14 additions & 25 deletions trunk/drivers/s390/scsi/zfcp_fsf.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include <linux/blktrace_api.h>
#include "zfcp_ext.h"

#define ZFCP_REQ_AUTO_CLEANUP 0x00000002
#define ZFCP_REQ_NO_QTCB 0x00000008

static void zfcp_fsf_request_timeout_handler(unsigned long data)
{
struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
Expand Down Expand Up @@ -913,27 +916,22 @@ static void zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *req)
/**
* zfcp_fsf_abort_fcp_command - abort running SCSI command
* @old_req_id: unsigned long
* @adapter: pointer to struct zfcp_adapter
* @unit: pointer to struct zfcp_unit
* @req_flags: integer specifying the request flags
* Returns: pointer to struct zfcp_fsf_req
*
* FIXME(design): should be watched by a timeout !!!
*/

struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
struct zfcp_adapter *adapter,
struct zfcp_unit *unit,
int req_flags)
struct zfcp_unit *unit)
{
struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *req = NULL;
struct zfcp_adapter *adapter = unit->port->adapter;

spin_lock_bh(&adapter->req_q_lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
req_flags, adapter->pool.fsf_req_abort);
0, adapter->pool.fsf_req_abort);
if (IS_ERR(req)) {
req = NULL;
goto out;
Expand Down Expand Up @@ -2309,21 +2307,17 @@ static void zfcp_set_fcp_dl(struct fcp_cmnd_iu *fcp_cmd, u32 fcp_dl)

/**
* zfcp_fsf_send_fcp_command_task - initiate an FCP command (for a SCSI command)
* @adapter: adapter where scsi command is issued
* @unit: unit where command is sent to
* @scsi_cmnd: scsi command to be sent
* @timer: timer to be started when request is initiated
* @req_flags: flags for fsf_request
*/
int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd,
int use_timer, int req_flags)
int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
struct scsi_cmnd *scsi_cmnd)
{
struct zfcp_fsf_req *req;
struct fcp_cmnd_iu *fcp_cmnd_iu;
unsigned int sbtype;
int real_bytes, retval = -EIO;
struct zfcp_adapter *adapter = unit->port->adapter;

if (unlikely(!(atomic_read(&unit->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
Expand All @@ -2332,7 +2326,8 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
spin_lock(&adapter->req_q_lock);
if (!zfcp_fsf_sbal_available(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND,
ZFCP_REQ_AUTO_CLEANUP,
adapter->pool.fsf_req_scsi);
if (IS_ERR(req)) {
retval = PTR_ERR(req);
Expand Down Expand Up @@ -2414,9 +2409,6 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,

zfcp_set_fcp_dl(fcp_cmnd_iu, real_bytes);

if (use_timer)
zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);

retval = zfcp_fsf_req_send(req);
if (unlikely(retval))
goto failed_scsi_cmnd;
Expand All @@ -2434,19 +2426,16 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,

/**
* zfcp_fsf_send_fcp_ctm - send SCSI task management command
* @adapter: pointer to struct zfcp-adapter
* @unit: pointer to struct zfcp_unit
* @tm_flags: unsigned byte for task management flags
* @req_flags: int request flags
* Returns: on success pointer to struct fsf_req, NULL otherwise
*/
struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
struct zfcp_unit *unit,
u8 tm_flags, int req_flags)
struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
{
struct qdio_buffer_element *sbale;
struct zfcp_fsf_req *req = NULL;
struct fcp_cmnd_iu *fcp_cmnd_iu;
struct zfcp_adapter *adapter = unit->port->adapter;

if (unlikely(!(atomic_read(&unit->status) &
ZFCP_STATUS_COMMON_UNBLOCKED)))
Expand All @@ -2455,7 +2444,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
spin_lock_bh(&adapter->req_q_lock);
if (zfcp_fsf_req_sbal_get(adapter))
goto out;
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, 0,
adapter->pool.fsf_req_scsi);
if (IS_ERR(req)) {
req = NULL;
Expand Down
124 changes: 60 additions & 64 deletions trunk/drivers/s390/scsi/zfcp_scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *scpnt,
return 0;;
}

ret = zfcp_fsf_send_fcp_command_task(adapter, unit, scpnt, 0,
ZFCP_REQ_AUTO_CLEANUP);
ret = zfcp_fsf_send_fcp_command_task(unit, scpnt);
if (unlikely(ret == -EBUSY))
return SCSI_MLQUEUE_DEVICE_BUSY;
else if (unlikely(ret < 0))
Expand Down Expand Up @@ -145,79 +144,91 @@ static int zfcp_scsi_slave_alloc(struct scsi_device *sdp)

static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
{
struct Scsi_Host *scsi_host;
struct zfcp_adapter *adapter;
struct zfcp_unit *unit;
struct zfcp_fsf_req *fsf_req;
struct Scsi_Host *scsi_host = scpnt->device->host;
struct zfcp_adapter *adapter =
(struct zfcp_adapter *) scsi_host->hostdata[0];
struct zfcp_unit *unit = scpnt->device->hostdata;
struct zfcp_fsf_req *old_req, *abrt_req;
unsigned long flags;
unsigned long old_req_id = (unsigned long) scpnt->host_scribble;
int retval = SUCCESS;

scsi_host = scpnt->device->host;
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
unit = scpnt->device->hostdata;
int retry = 3;

/* avoid race condition between late normal completion and abort */
write_lock_irqsave(&adapter->abort_lock, flags);

/* Check whether corresponding fsf_req is still pending */
spin_lock(&adapter->req_list_lock);
fsf_req = zfcp_reqlist_find(adapter, old_req_id);
old_req = zfcp_reqlist_find(adapter, old_req_id);
spin_unlock(&adapter->req_list_lock);
if (!fsf_req) {
if (!old_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags);
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0);
return retval;
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL,
old_req_id);
return SUCCESS;
}
fsf_req->data = NULL;
old_req->data = NULL;

/* don't access old fsf_req after releasing the abort_lock */
write_unlock_irqrestore(&adapter->abort_lock, flags);

fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0);
if (!fsf_req) {
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
old_req_id);
retval = FAILED;
return retval;
while (retry--) {
abrt_req = zfcp_fsf_abort_fcp_command(old_req_id, unit);
if (abrt_req)
break;

zfcp_erp_wait(adapter);
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
old_req_id);
return SUCCESS;
}
}
if (!abrt_req)
return FAILED;

__wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
wait_event(abrt_req->completion_wq,
abrt_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0);
} else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0);
} else {
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0);
if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED)
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, abrt_req, 0);
else if (abrt_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED)
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, abrt_req, 0);
else {
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, abrt_req, 0);
retval = FAILED;
}
zfcp_fsf_req_free(fsf_req);

zfcp_fsf_req_free(abrt_req);
return retval;
}

static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
struct scsi_cmnd *scpnt)
static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
{
struct zfcp_unit *unit = scpnt->device->hostdata;
struct zfcp_adapter *adapter = unit->port->adapter;
struct zfcp_fsf_req *fsf_req;
int retval = SUCCESS;

/* issue task management function */
fsf_req = zfcp_fsf_send_fcp_ctm(adapter, unit, tm_flags, 0);
if (!fsf_req) {
zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);
return FAILED;
int retry = 3;

while (retry--) {
fsf_req = zfcp_fsf_send_fcp_ctm(unit, tm_flags);
if (fsf_req)
break;

zfcp_erp_wait(adapter);
if (!(atomic_read(&adapter->status) &
ZFCP_STATUS_COMMON_RUNNING)) {
zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit,
scpnt);
return SUCCESS;
}
}
if (!fsf_req)
return FAILED;

__wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
wait_event(fsf_req->completion_wq,
fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);

/*
* check completion status of task management function
*/
if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);
retval = FAILED;
Expand All @@ -228,39 +239,24 @@ static int zfcp_task_mgmt_function(struct zfcp_unit *unit, u8 tm_flags,
zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);

zfcp_fsf_req_free(fsf_req);

return retval;
}

static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
{
struct zfcp_unit *unit = scpnt->device->hostdata;

if (!unit) {
WARN_ON(1);
return SUCCESS;
}
return zfcp_task_mgmt_function(unit, FCP_LOGICAL_UNIT_RESET, scpnt);
return zfcp_task_mgmt_function(scpnt, FCP_LOGICAL_UNIT_RESET);
}

static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
{
struct zfcp_unit *unit = scpnt->device->hostdata;

if (!unit) {
WARN_ON(1);
return SUCCESS;
}
return zfcp_task_mgmt_function(unit, FCP_TARGET_RESET, scpnt);
return zfcp_task_mgmt_function(scpnt, FCP_TARGET_RESET);
}

static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
{
struct zfcp_unit *unit;
struct zfcp_adapter *adapter;
struct zfcp_unit *unit = scpnt->device->hostdata;
struct zfcp_adapter *adapter = unit->port->adapter;

unit = scpnt->device->hostdata;
adapter = unit->port->adapter;
zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt);
zfcp_erp_wait(adapter);

Expand Down

0 comments on commit 1eb8140

Please sign in to comment.