Commit 42428f74 authored by Swen Schillig's avatar Swen Schillig Committed by James Bottomley

[SCSI] zfcp: Separate qdio attributes from zfcp_fsf_req

Split all qdio related attributes out of zfcp_fsf_req and put it in
new structure.
Signed-off-by: default avatarSwen Schillig <swen@vnet.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 4544683a
...@@ -152,9 +152,9 @@ void _zfcp_hba_dbf_event_fsf_response(const char *tag2, int level, ...@@ -152,9 +152,9 @@ void _zfcp_hba_dbf_event_fsf_response(const char *tag2, int level,
memcpy(response->fsf_status_qual, memcpy(response->fsf_status_qual,
fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
response->fsf_req_status = fsf_req->status; response->fsf_req_status = fsf_req->status;
response->sbal_first = fsf_req->sbal_first; response->sbal_first = fsf_req->queue_req.sbal_first;
response->sbal_last = fsf_req->sbal_last; response->sbal_last = fsf_req->queue_req.sbal_last;
response->sbal_response = fsf_req->sbal_response; response->sbal_response = fsf_req->queue_req.sbal_response;
response->pool = fsf_req->pool != NULL; response->pool = fsf_req->pool != NULL;
response->erp_action = (unsigned long)fsf_req->erp_action; response->erp_action = (unsigned long)fsf_req->erp_action;
......
...@@ -529,36 +529,64 @@ struct zfcp_unit { ...@@ -529,36 +529,64 @@ struct zfcp_unit {
struct work_struct scsi_work; struct work_struct scsi_work;
}; };
/* FSF request */ /**
* struct zfcp_queue_req - queue related values for a request
* @sbal_number: number of free SBALs
* @sbal_first: first SBAL for this request
* @sbal_last: last SBAL for this request
* @sbal_limit: last possible SBAL for this request
* @sbale_curr: current SBALE at creation of this request
* @sbal_response: SBAL used in interrupt
* @qdio_outb_usage: usage of outbound queue
* @qdio_inb_usage: usage of inbound queue
*/
struct zfcp_queue_req {
u8 sbal_number;
u8 sbal_first;
u8 sbal_last;
u8 sbal_limit;
u8 sbale_curr;
u8 sbal_response;
u16 qdio_outb_usage;
u16 qdio_inb_usage;
};
/**
* struct zfcp_fsf_req - basic FSF request structure
* @list: list of FSF requests
* @req_id: unique request ID
* @adapter: adapter this request belongs to
* @queue_req: queue related values
* @completion: used to signal the completion of the request
* @status: status of the request
* @fsf_command: FSF command issued
* @qtcb: associated QTCB
* @seq_no: sequence number of this request
* @data: private data
* @timer: timer data of this request
* @erp_action: reference to erp action if request issued on behalf of ERP
* @pool: reference to memory pool if used for this request
* @issued: time when request was send (STCK)
* @unit: reference to unit if this request is a SCSI request
* @handler: handler which should be called to process response
*/
struct zfcp_fsf_req { struct zfcp_fsf_req {
struct list_head list; /* list of FSF requests */ struct list_head list;
unsigned long req_id; /* unique request ID */ unsigned long req_id;
struct zfcp_adapter *adapter; /* adapter request belongs to */ struct zfcp_adapter *adapter;
u8 sbal_number; /* nr of SBALs free for use */ struct zfcp_queue_req queue_req;
u8 sbal_first; /* first SBAL for this request */ struct completion completion;
u8 sbal_last; /* last SBAL for this request */ u32 status;
u8 sbal_limit; /* last possible SBAL for u32 fsf_command;
this reuest */ struct fsf_qtcb *qtcb;
u8 sbale_curr; /* current SBALE during creation u32 seq_no;
of request */ void *data;
u8 sbal_response; /* SBAL used in interrupt */ struct timer_list timer;
struct completion completion; /* can be used by a routine struct zfcp_erp_action *erp_action;
to wait for completion */ mempool_t *pool;
u32 status; /* status of this request */ unsigned long long issued;
u32 fsf_command; /* FSF Command copy */ struct zfcp_unit *unit;
struct fsf_qtcb *qtcb; /* address of associated QTCB */
u32 seq_no; /* Sequence number of request */
void *data; /* private data of request */
struct timer_list timer; /* used for erp or scsi er */
struct zfcp_erp_action *erp_action; /* used if this request is
issued on behalf of erp */
mempool_t *pool; /* used if request was alloacted
from emergency pool */
unsigned long long issued; /* request sent time (STCK) */
struct zfcp_unit *unit;
void (*handler)(struct zfcp_fsf_req *); void (*handler)(struct zfcp_fsf_req *);
u16 qdio_outb_usage;/* usage of outbound queue */
u16 qdio_inb_usage; /* usage of inbound queue */
}; };
/* driver data */ /* driver data */
......
...@@ -142,10 +142,13 @@ extern void zfcp_fsf_reqid_check(struct zfcp_adapter *, int); ...@@ -142,10 +142,13 @@ extern void zfcp_fsf_reqid_check(struct zfcp_adapter *, int);
/* zfcp_qdio.c */ /* zfcp_qdio.c */
extern int zfcp_qdio_allocate(struct zfcp_adapter *); extern int zfcp_qdio_allocate(struct zfcp_adapter *);
extern void zfcp_qdio_free(struct zfcp_adapter *); extern void zfcp_qdio_free(struct zfcp_adapter *);
extern int zfcp_qdio_send(struct zfcp_fsf_req *); extern int zfcp_qdio_send(struct zfcp_adapter *, struct zfcp_queue_req *);
extern struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *); extern struct qdio_buffer_element
extern struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *); *zfcp_qdio_sbale_req(struct zfcp_adapter *, struct zfcp_queue_req *);
extern int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *, unsigned long, extern struct qdio_buffer_element
*zfcp_qdio_sbale_curr(struct zfcp_adapter *, struct zfcp_queue_req *);
extern int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *,
struct zfcp_queue_req *, unsigned long,
struct scatterlist *, int); struct scatterlist *, int);
extern int zfcp_qdio_open(struct zfcp_adapter *); extern int zfcp_qdio_open(struct zfcp_adapter *);
extern void zfcp_qdio_close(struct zfcp_adapter *); extern void zfcp_qdio_close(struct zfcp_adapter *);
......
...@@ -720,12 +720,12 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter, ...@@ -720,12 +720,12 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
req->adapter = adapter; req->adapter = adapter;
req->fsf_command = fsf_cmd; req->fsf_command = fsf_cmd;
req->req_id = adapter->req_no; req->req_id = adapter->req_no;
req->sbal_number = 1; req->queue_req.sbal_number = 1;
req->sbal_first = req_q->first; req->queue_req.sbal_first = req_q->first;
req->sbal_last = req_q->first; req->queue_req.sbal_last = req_q->first;
req->sbale_curr = 1; req->queue_req.sbale_curr = 1;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].addr = (void *) req->req_id; sbale[0].addr = (void *) req->req_id;
sbale[0].flags |= SBAL_FLAGS0_COMMAND; sbale[0].flags |= SBAL_FLAGS0_COMMAND;
...@@ -774,9 +774,9 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) ...@@ -774,9 +774,9 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
list_add_tail(&req->list, &adapter->req_list[idx]); list_add_tail(&req->list, &adapter->req_list[idx]);
spin_unlock_irqrestore(&adapter->req_list_lock, flags); spin_unlock_irqrestore(&adapter->req_list_lock, flags);
req->qdio_outb_usage = atomic_read(&adapter->req_q.count); req->queue_req.qdio_outb_usage = atomic_read(&adapter->req_q.count);
req->issued = get_clock(); req->issued = get_clock();
if (zfcp_qdio_send(req)) { if (zfcp_qdio_send(adapter, &req->queue_req)) {
del_timer(&req->timer); del_timer(&req->timer);
spin_lock_irqsave(&adapter->req_list_lock, flags); spin_lock_irqsave(&adapter->req_list_lock, flags);
/* lookup request again, list might have changed */ /* lookup request again, list might have changed */
...@@ -819,9 +819,9 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) ...@@ -819,9 +819,9 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
goto out; goto out;
} }
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[2].flags |= SBAL_FLAGS_LAST_ENTRY;
req->sbale_curr = 2; req->queue_req.sbale_curr = 2;
sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC); sr_buf = mempool_alloc(adapter->pool.status_read_data, GFP_ATOMIC);
if (!sr_buf) { if (!sr_buf) {
...@@ -830,7 +830,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) ...@@ -830,7 +830,7 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
} }
memset(sr_buf, 0, sizeof(*sr_buf)); memset(sr_buf, 0, sizeof(*sr_buf));
req->data = sr_buf; req->data = sr_buf;
sbale = zfcp_qdio_sbale_curr(req); sbale = zfcp_qdio_sbale_curr(adapter, &req->queue_req);
sbale->addr = (void *) sr_buf; sbale->addr = (void *) sr_buf;
sbale->length = sizeof(*sr_buf); sbale->length = sizeof(*sr_buf);
...@@ -929,7 +929,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, ...@@ -929,7 +929,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
ZFCP_STATUS_COMMON_UNBLOCKED))) ZFCP_STATUS_COMMON_UNBLOCKED)))
goto out_error_free; goto out_error_free;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1023,8 +1023,10 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, ...@@ -1023,8 +1023,10 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
struct scatterlist *sg_resp, struct scatterlist *sg_resp,
int max_sbals) int max_sbals)
{ {
struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req); struct zfcp_adapter *adapter = req->adapter;
u32 feat = req->adapter->adapter_features; struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(adapter,
&req->queue_req);
u32 feat = adapter->adapter_features;
int bytes; int bytes;
if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) { if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
...@@ -1041,14 +1043,16 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, ...@@ -1041,14 +1043,16 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
return 0; return 0;
} }
bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, bytes = zfcp_qdio_sbals_from_sg(adapter, &req->queue_req,
SBAL_FLAGS0_TYPE_WRITE_READ,
sg_req, max_sbals); sg_req, max_sbals);
if (bytes <= 0) if (bytes <= 0)
return -EIO; return -EIO;
req->qtcb->bottom.support.req_buf_length = bytes; req->qtcb->bottom.support.req_buf_length = bytes;
req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; req->queue_req.sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, bytes = zfcp_qdio_sbals_from_sg(adapter, &req->queue_req,
SBAL_FLAGS0_TYPE_WRITE_READ,
sg_resp, max_sbals); sg_resp, max_sbals);
if (bytes <= 0) if (bytes <= 0)
return -EIO; return -EIO;
...@@ -1241,7 +1245,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) ...@@ -1241,7 +1245,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1283,7 +1287,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, ...@@ -1283,7 +1287,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
goto out_unlock; goto out_unlock;
} }
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
req->handler = zfcp_fsf_exchange_config_data_handler; req->handler = zfcp_fsf_exchange_config_data_handler;
...@@ -1339,7 +1343,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) ...@@ -1339,7 +1343,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1388,7 +1392,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, ...@@ -1388,7 +1392,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
if (data) if (data)
req->data = data; req->data = data;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1509,7 +1513,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) ...@@ -1509,7 +1513,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1579,7 +1583,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) ...@@ -1579,7 +1583,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1656,7 +1660,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port) ...@@ -1656,7 +1660,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_wka_port *wka_port)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1711,7 +1715,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port) ...@@ -1711,7 +1715,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_wka_port *wka_port)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1803,7 +1807,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) ...@@ -1803,7 +1807,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -1976,7 +1980,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) ...@@ -1976,7 +1980,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -2063,7 +2067,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) ...@@ -2063,7 +2067,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; sbale[0].flags |= SBAL_FLAGS0_TYPE_READ;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -2140,8 +2144,8 @@ static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) ...@@ -2140,8 +2144,8 @@ static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
} }
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
trace.flags |= ZFCP_BLK_REQ_ERROR; trace.flags |= ZFCP_BLK_REQ_ERROR;
trace.inb_usage = fsf_req->qdio_inb_usage; trace.inb_usage = fsf_req->queue_req.qdio_inb_usage;
trace.outb_usage = fsf_req->qdio_outb_usage; trace.outb_usage = fsf_req->queue_req.qdio_outb_usage;
blk_add_driver_data(req->q, req, &trace, sizeof(trace)); blk_add_driver_data(req->q, req, &trace, sizeof(trace));
} }
...@@ -2420,11 +2424,11 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit, ...@@ -2420,11 +2424,11 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *unit,
req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32); fcp_cmnd_iu->add_fcp_cdb_length + sizeof(u32);
real_bytes = zfcp_qdio_sbals_from_sg(req, sbtype, real_bytes = zfcp_qdio_sbals_from_sg(adapter, &req->queue_req, sbtype,
scsi_sglist(scsi_cmnd), scsi_sglist(scsi_cmnd),
FSF_MAX_SBALS_PER_REQ); FSF_MAX_SBALS_PER_REQ);
if (unlikely(real_bytes < 0)) { if (unlikely(real_bytes < 0)) {
if (req->sbal_number >= FSF_MAX_SBALS_PER_REQ) { if (req->queue_req.sbal_number >= FSF_MAX_SBALS_PER_REQ) {
dev_err(&adapter->ccw_device->dev, dev_err(&adapter->ccw_device->dev,
"Oversize data package, unit 0x%016Lx " "Oversize data package, unit 0x%016Lx "
"on port 0x%016Lx closed\n", "on port 0x%016Lx closed\n",
...@@ -2492,7 +2496,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags) ...@@ -2492,7 +2496,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_unit *unit, u8 tm_flags)
req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) + req->qtcb->bottom.io.fcp_cmnd_length = sizeof(struct fcp_cmnd_iu) +
sizeof(u32); sizeof(u32);
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE; sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE;
sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY;
...@@ -2555,15 +2559,15 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, ...@@ -2555,15 +2559,15 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
req->handler = zfcp_fsf_control_file_handler; req->handler = zfcp_fsf_control_file_handler;
sbale = zfcp_qdio_sbale_req(req); sbale = zfcp_qdio_sbale_req(adapter, &req->queue_req);
sbale[0].flags |= direction; sbale[0].flags |= direction;
bottom = &req->qtcb->bottom.support; bottom = &req->qtcb->bottom.support;
bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE; bottom->operation_subtype = FSF_CFDC_OPERATION_SUBTYPE;
bottom->option = fsf_cfdc->option; bottom->option = fsf_cfdc->option;
bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg, bytes = zfcp_qdio_sbals_from_sg(adapter, &req->queue_req, direction,
FSF_MAX_SBALS_PER_REQ); fsf_cfdc->sg, FSF_MAX_SBALS_PER_REQ);
if (bytes != ZFCP_CFDC_MAX_SIZE) { if (bytes != ZFCP_CFDC_MAX_SIZE) {
zfcp_fsf_req_free(req); zfcp_fsf_req_free(req);
goto out; goto out;
...@@ -2612,8 +2616,9 @@ void zfcp_fsf_reqid_check(struct zfcp_adapter *adapter, int sbal_idx) ...@@ -2612,8 +2616,9 @@ void zfcp_fsf_reqid_check(struct zfcp_adapter *adapter, int sbal_idx)
list_del(&fsf_req->list); list_del(&fsf_req->list);
spin_unlock_irqrestore(&adapter->req_list_lock, flags); spin_unlock_irqrestore(&adapter->req_list_lock, flags);
fsf_req->sbal_response = sbal_idx; fsf_req->queue_req.sbal_response = sbal_idx;
fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count); fsf_req->queue_req.qdio_inb_usage =
atomic_read(&adapter->resp_q.count);
zfcp_fsf_req_complete(fsf_req); zfcp_fsf_req_complete(fsf_req);
if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY)) if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Setup and helper functions to access QDIO. * Setup and helper functions to access QDIO.
* *
* Copyright IBM Corporation 2002, 2008 * Copyright IBM Corporation 2002, 2009
*/ */
#define KMSG_COMPONENT "zfcp" #define KMSG_COMPONENT "zfcp"
...@@ -165,12 +165,14 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, ...@@ -165,12 +165,14 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
/** /**
* zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req * zfcp_qdio_sbale_req - return ptr to SBALE of req_q for a struct zfcp_fsf_req
* @fsf_req: pointer to struct fsf_req * @adapter: pointer to struct zfcp_adapter
* @q_rec: pointer to struct zfcp_queue_rec
* Returns: pointer to qdio_buffer_element (SBALE) structure * Returns: pointer to qdio_buffer_element (SBALE) structure
*/ */
struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_adapter *adapter,
struct zfcp_queue_req *q_req)
{ {
return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, 0); return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last, 0);
} }
/** /**
...@@ -178,74 +180,80 @@ struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req) ...@@ -178,74 +180,80 @@ struct qdio_buffer_element *zfcp_qdio_sbale_req(struct zfcp_fsf_req *req)
* @fsf_req: pointer to struct fsf_req * @fsf_req: pointer to struct fsf_req
* Returns: pointer to qdio_buffer_element (SBALE) structure * Returns: pointer to qdio_buffer_element (SBALE) structure
*/ */
struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_fsf_req *req) struct qdio_buffer_element *zfcp_qdio_sbale_curr(struct zfcp_adapter *adapter,
struct zfcp_queue_req *q_req)
{ {
return zfcp_qdio_sbale(&req->adapter->req_q, req->sbal_last, return zfcp_qdio_sbale(&adapter->req_q, q_req->sbal_last,
req->sbale_curr); q_req->sbale_curr);
} }
static void zfcp_qdio_sbal_limit(struct zfcp_fsf_req *fsf_req, int max_sbals) static void zfcp_qdio_sbal_limit(struct zfcp_adapter *adapter,
struct zfcp_queue_req *q_req, int max_sbals)
{ {
int count = atomic_read(&fsf_req->adapter->req_q.count); int count = atomic_read(&adapter->req_q.count);
count = min(count, max_sbals); count = min(count, max_sbals);
fsf_req->sbal_limit = (fsf_req->sbal_first + count - 1) q_req->sbal_limit = (q_req->sbal_first + count - 1)
% QDIO_MAX_BUFFERS_PER_Q; % QDIO_MAX_BUFFERS_PER_Q;
} }
static struct qdio_buffer_element * static struct qdio_buffer_element *
zfcp_qdio_sbal_chain(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) zfcp_qdio_sbal_chain(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req,
unsigned long sbtype)
{ {
struct qdio_buffer_element *sbale; struct qdio_buffer_element *sbale;
/* set last entry flag in current SBALE of current SBAL */ /* set last entry flag in current SBALE of current SBAL */
sbale = zfcp_qdio_sbale_curr(fsf_req); sbale = zfcp_qdio_sbale_curr(adapter, q_req);
sbale->flags |= SBAL_FLAGS_LAST_ENTRY; sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
/* don't exceed last allowed SBAL */ /* don't exceed last allowed SBAL */
if (fsf_req->sbal_last == fsf_req->sbal_limit) if (q_req->sbal_last == q_req->sbal_limit)
return NULL; return NULL;
/* set chaining flag in first SBALE of current SBAL */ /* set chaining flag in first SBALE of current SBAL */
sbale = zfcp_qdio_sbale_req(fsf_req); sbale = zfcp_qdio_sbale_req(adapter, q_req);
sbale->flags |= SBAL_FLAGS0_MORE_SBALS; sbale->flags |= SBAL_FLAGS0_MORE_SBALS;
/* calculate index of next SBAL */ /* calculate index of next SBAL */
fsf_req->sbal_last++; q_req->sbal_last++;
fsf_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q; q_req->sbal_last %= QDIO_MAX_BUFFERS_PER_Q;
/* keep this requests number of SBALs up-to-date */ /* keep this requests number of SBALs up-to-date */
fsf_req->sbal_number++; q_req->sbal_number++;
/* start at first SBALE of new SBAL */ /* start at first SBALE of new SBAL */
fsf_req->sbale_curr = 0; q_req->sbale_curr = 0;
/* set storage-block type for new SBAL */ /* set storage-block type for new SBAL */
sbale = zfcp_qdio_sbale_curr(fsf_req); sbale = zfcp_qdio_sbale_curr(adapter, q_req);
sbale->flags |= sbtype; sbale->flags |= sbtype;
return sbale; return sbale;
} }
static struct qdio_buffer_element * static struct qdio_buffer_element *
zfcp_qdio_sbale_next(struct zfcp_fsf_req *fsf_req, unsigned long sbtype) zfcp_qdio_sbale_next(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req,
unsigned int sbtype)
{ {
if (fsf_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL) if (q_req->sbale_curr == ZFCP_LAST_SBALE_PER_SBAL)
return zfcp_qdio_sbal_chain(fsf_req, sbtype); return zfcp_qdio_sbal_chain(adapter, q_req, sbtype);
fsf_req->sbale_curr++; q_req->sbale_curr++;
return zfcp_qdio_sbale_curr(fsf_req); return zfcp_qdio_sbale_curr(adapter, q_req);
} }
static void zfcp_qdio_undo_sbals(struct zfcp_fsf_req *fsf_req) static void zfcp_qdio_undo_sbals(struct zfcp_adapter *adapter,
struct zfcp_queue_req *q_req)
{ {
struct qdio_buffer **sbal = fsf_req->adapter->req_q.sbal; struct qdio_buffer **sbal = adapter->req_q.sbal;
int first = fsf_req->sbal_first; int first = q_req->sbal_first;
int last = fsf_req->sbal_last; int last = q_req->sbal_last;
int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) % int count = (last - first + QDIO_MAX_BUFFERS_PER_Q) %
QDIO_MAX_BUFFERS_PER_Q + 1; QDIO_MAX_BUFFERS_PER_Q + 1;
zfcp_qdio_zero_sbals(sbal, first, count); zfcp_qdio_zero_sbals(sbal, first, count);
} }
static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, static int zfcp_qdio_fill_sbals(struct zfcp_adapter *adapter,
struct zfcp_queue_req *q_req,
unsigned int sbtype, void *start_addr, unsigned int sbtype, void *start_addr,
unsigned int total_length) unsigned int total_length)
{ {
...@@ -256,10 +264,10 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, ...@@ -256,10 +264,10 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
/* split segment up */ /* split segment up */
for (addr = start_addr, remaining = total_length; remaining > 0; for (addr = start_addr, remaining = total_length; remaining > 0;
addr += length, remaining -= length) { addr += length, remaining -= length) {
sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); sbale = zfcp_qdio_sbale_next(adapter, q_req, sbtype);
if (!sbale) { if (!sbale) {
atomic_inc(&fsf_req->adapter->qdio_outb_full); atomic_inc(&adapter->qdio_outb_full);
zfcp_qdio_undo_sbals(fsf_req); zfcp_qdio_undo_sbals(adapter, q_req);
return -EINVAL; return -EINVAL;
} }
...@@ -281,29 +289,31 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, ...@@ -281,29 +289,31 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req,
* @max_sbals: upper bound for number of SBALs to be used * @max_sbals: upper bound for number of SBALs to be used
* Returns: number of bytes, or error (negativ) * Returns: number of bytes, or error (negativ)
*/ */
int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, int zfcp_qdio_sbals_from_sg(struct zfcp_adapter *adapter,
struct scatterlist *sg, int max_sbals) struct zfcp_queue_req *q_req,
unsigned long sbtype, struct scatterlist *sg,
int max_sbals)
{ {
struct qdio_buffer_element *sbale; struct qdio_buffer_element *sbale;
int retval, bytes = 0; int retval, bytes = 0;
/* figure out last allowed SBAL */ /* figure out last allowed SBAL */
zfcp_qdio_sbal_limit(fsf_req, max_sbals); zfcp_qdio_sbal_limit(adapter, q_req, max_sbals);
/* set storage-block type for this request */ /* set storage-block type for this request */
sbale = zfcp_qdio_sbale_req(fsf_req); sbale = zfcp_qdio_sbale_req(adapter, q_req);
sbale->flags |= sbtype; sbale->flags |= sbtype;
for (; sg; sg = sg_next(sg)) { for (; sg; sg = sg_next(sg)) {
retval = zfcp_qdio_fill_sbals(fsf_req, sbtype, sg_virt(sg), retval = zfcp_qdio_fill_sbals(adapter, q_req, sbtype,
sg->length); sg_virt(sg), sg->length);
if (retval < 0) if (retval < 0)
return retval; return retval;
bytes += sg->length; bytes += sg->length;
} }
/* assume that no other SBALEs are to follow in the same SBAL */ /* assume that no other SBALEs are to follow in the same SBAL */
sbale = zfcp_qdio_sbale_curr(fsf_req); sbale = zfcp_qdio_sbale_curr(adapter, q_req);
sbale->flags |= SBAL_FLAGS_LAST_ENTRY; sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
return bytes; return bytes;
...@@ -314,12 +324,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, ...@@ -314,12 +324,11 @@ int zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
* @fsf_req: pointer to struct zfcp_fsf_req * @fsf_req: pointer to struct zfcp_fsf_req
* Returns: 0 on success, error otherwise * Returns: 0 on success, error otherwise
*/ */
int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) int zfcp_qdio_send(struct zfcp_adapter *adapter, struct zfcp_queue_req *q_req)
{ {
struct zfcp_adapter *adapter = fsf_req->adapter;
struct zfcp_qdio_queue *req_q = &adapter->req_q; struct zfcp_qdio_queue *req_q = &adapter->req_q;
int first = fsf_req->sbal_first; int first = q_req->sbal_first;
int count = fsf_req->sbal_number; int count = q_req->sbal_number;
int retval; int retval;
unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment