mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6: [SCSI] aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree [SCSI] zfcp: Set hardware timeout as requested by BSG request. [SCSI] zfcp: Introduce bsg_timeout callback. [SCSI] scsi_transport_fc: Allow LLD to reset FC BSG timeout [SCSI] zfcp: add missing compat ptr conversion [SCSI] zfcp: Fix linebreak in hba trace [SCSI] zfcp: Issue zfcp_fc_wka_port_put after FC CT BSG request [SCSI] qla2xxx: Update version number to 8.03.01-k10. [SCSI] fc-transport: Use packed modifier for fc_bsg_request structure. [SCSI] qla2xxx: Perform fast mailbox read of flash regardless of size nor address alignment. [SCSI] qla2xxx: Correct FCP2 recovery handling. [SCSI] scsi_lib: Fix bug in completion of bidi commands [SCSI] mptsas: Fix issue with chain pools allocation on katmai [SCSI] aacraid: fix File System going into read-only mode [SCSI] lpfc: fix file permissions
This commit is contained in:
commit
be8cde8b24
25 changed files with 291 additions and 126 deletions
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <asm/compat.h>
|
||||
#include <asm/ccwdev.h>
|
||||
#include "zfcp_def.h"
|
||||
#include "zfcp_ext.h"
|
||||
|
|
@ -163,7 +164,7 @@ static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data,
|
|||
}
|
||||
|
||||
static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
|
||||
unsigned long buffer)
|
||||
unsigned long arg)
|
||||
{
|
||||
struct zfcp_cfdc_data *data;
|
||||
struct zfcp_cfdc_data __user *data_user;
|
||||
|
|
@ -175,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
|
|||
if (command != ZFCP_CFDC_IOC)
|
||||
return -ENOTTY;
|
||||
|
||||
data_user = (void __user *) buffer;
|
||||
if (is_compat_task())
|
||||
data_user = compat_ptr(arg);
|
||||
else
|
||||
data_user = (void __user *)arg;
|
||||
|
||||
if (!data_user)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(char **p,
|
|||
break;
|
||||
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
|
||||
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
|
||||
p += sprintf(*p, "\n");
|
||||
*p += sprintf(*p, "\n");
|
||||
break;
|
||||
|
||||
case FSF_QTCB_OPEN_PORT_WITH_DID:
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *);
|
|||
extern int zfcp_fc_gs_setup(struct zfcp_adapter *);
|
||||
extern void zfcp_fc_gs_destroy(struct zfcp_adapter *);
|
||||
extern int zfcp_fc_exec_bsg_job(struct fc_bsg_job *);
|
||||
extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
|
||||
|
||||
/* zfcp_fsf.c */
|
||||
extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
|
||||
|
|
@ -129,9 +130,9 @@ extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *);
|
|||
extern int zfcp_fsf_status_read(struct zfcp_qdio *);
|
||||
extern int zfcp_status_read_refill(struct zfcp_adapter *adapter);
|
||||
extern int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *, struct zfcp_fsf_ct_els *,
|
||||
mempool_t *);
|
||||
mempool_t *, unsigned int);
|
||||
extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
|
||||
struct zfcp_fsf_ct_els *);
|
||||
struct zfcp_fsf_ct_els *, unsigned int);
|
||||
extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
|
||||
struct scsi_cmnd *);
|
||||
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
|
||||
|
|
|
|||
|
|
@ -258,7 +258,8 @@ static int zfcp_fc_ns_gid_pn_request(struct zfcp_port *port,
|
|||
gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
|
||||
|
||||
ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct,
|
||||
adapter->pool.gid_pn_req);
|
||||
adapter->pool.gid_pn_req,
|
||||
ZFCP_FC_CTELS_TMO);
|
||||
if (!ret) {
|
||||
wait_for_completion(&completion);
|
||||
zfcp_fc_ns_gid_pn_eval(gid_pn);
|
||||
|
|
@ -421,7 +422,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
|
|||
hton24(adisc->adisc_req.adisc_port_id,
|
||||
fc_host_port_id(adapter->scsi_host));
|
||||
|
||||
ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els);
|
||||
ret = zfcp_fsf_send_els(adapter, port->d_id, &adisc->els,
|
||||
ZFCP_FC_CTELS_TMO);
|
||||
if (ret)
|
||||
kmem_cache_free(zfcp_data.adisc_cache, adisc);
|
||||
|
||||
|
|
@ -532,7 +534,8 @@ static int zfcp_fc_send_gpn_ft(struct zfcp_fc_gpn_ft *gpn_ft,
|
|||
ct->req = &gpn_ft->sg_req;
|
||||
ct->resp = gpn_ft->sg_resp;
|
||||
|
||||
ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL);
|
||||
ret = zfcp_fsf_send_ct(&adapter->gs->ds, ct, NULL,
|
||||
ZFCP_FC_CTELS_TMO);
|
||||
if (!ret)
|
||||
wait_for_completion(&completion);
|
||||
return ret;
|
||||
|
|
@ -677,6 +680,44 @@ static void zfcp_fc_ct_els_job_handler(void *data)
|
|||
job->job_done(job);
|
||||
}
|
||||
|
||||
static struct zfcp_fc_wka_port *zfcp_fc_job_wka_port(struct fc_bsg_job *job)
|
||||
{
|
||||
u32 preamble_word1;
|
||||
u8 gs_type;
|
||||
struct zfcp_adapter *adapter;
|
||||
|
||||
preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
|
||||
gs_type = (preamble_word1 & 0xff000000) >> 24;
|
||||
|
||||
adapter = (struct zfcp_adapter *) job->shost->hostdata[0];
|
||||
|
||||
switch (gs_type) {
|
||||
case FC_FST_ALIAS:
|
||||
return &adapter->gs->as;
|
||||
case FC_FST_MGMT:
|
||||
return &adapter->gs->ms;
|
||||
case FC_FST_TIME:
|
||||
return &adapter->gs->ts;
|
||||
break;
|
||||
case FC_FST_DIR:
|
||||
return &adapter->gs->ds;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void zfcp_fc_ct_job_handler(void *data)
|
||||
{
|
||||
struct fc_bsg_job *job = data;
|
||||
struct zfcp_fc_wka_port *wka_port;
|
||||
|
||||
wka_port = zfcp_fc_job_wka_port(job);
|
||||
zfcp_fc_wka_port_put(wka_port);
|
||||
|
||||
zfcp_fc_ct_els_job_handler(data);
|
||||
}
|
||||
|
||||
static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
|
||||
struct zfcp_adapter *adapter)
|
||||
{
|
||||
|
|
@ -695,43 +736,27 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
|
|||
} else
|
||||
d_id = ntoh24(job->request->rqst_data.h_els.port_id);
|
||||
|
||||
return zfcp_fsf_send_els(adapter, d_id, els);
|
||||
els->handler = zfcp_fc_ct_els_job_handler;
|
||||
return zfcp_fsf_send_els(adapter, d_id, els, job->req->timeout / HZ);
|
||||
}
|
||||
|
||||
static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
|
||||
struct zfcp_adapter *adapter)
|
||||
{
|
||||
int ret;
|
||||
u8 gs_type;
|
||||
struct zfcp_fsf_ct_els *ct = job->dd_data;
|
||||
struct zfcp_fc_wka_port *wka_port;
|
||||
u32 preamble_word1;
|
||||
|
||||
preamble_word1 = job->request->rqst_data.r_ct.preamble_word1;
|
||||
gs_type = (preamble_word1 & 0xff000000) >> 24;
|
||||
|
||||
switch (gs_type) {
|
||||
case FC_FST_ALIAS:
|
||||
wka_port = &adapter->gs->as;
|
||||
break;
|
||||
case FC_FST_MGMT:
|
||||
wka_port = &adapter->gs->ms;
|
||||
break;
|
||||
case FC_FST_TIME:
|
||||
wka_port = &adapter->gs->ts;
|
||||
break;
|
||||
case FC_FST_DIR:
|
||||
wka_port = &adapter->gs->ds;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL; /* no such service */
|
||||
}
|
||||
wka_port = zfcp_fc_job_wka_port(job);
|
||||
if (!wka_port)
|
||||
return -EINVAL;
|
||||
|
||||
ret = zfcp_fc_wka_port_get(wka_port);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = zfcp_fsf_send_ct(wka_port, ct, NULL);
|
||||
ct->handler = zfcp_fc_ct_job_handler;
|
||||
ret = zfcp_fsf_send_ct(wka_port, ct, NULL, job->req->timeout / HZ);
|
||||
if (ret)
|
||||
zfcp_fc_wka_port_put(wka_port);
|
||||
|
||||
|
|
@ -752,7 +777,6 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
|
|||
|
||||
ct_els->req = job->request_payload.sg_list;
|
||||
ct_els->resp = job->reply_payload.sg_list;
|
||||
ct_els->handler = zfcp_fc_ct_els_job_handler;
|
||||
ct_els->handler_data = job;
|
||||
|
||||
switch (job->request->msgcode) {
|
||||
|
|
@ -767,6 +791,12 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job)
|
|||
}
|
||||
}
|
||||
|
||||
int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *job)
|
||||
{
|
||||
/* hardware tracks timeout, reset bsg timeout to not interfere */
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
|
||||
{
|
||||
struct zfcp_fc_wka_ports *wka_ports;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
|
||||
(ZFCP_FC_GPN_FT_ENT_PAGE + 1))
|
||||
|
||||
#define ZFCP_FC_CTELS_TMO (2 * FC_DEF_R_A_TOV / 1000)
|
||||
|
||||
/**
|
||||
* struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
|
||||
* @ct_hdr: FC GS common transport header
|
||||
|
|
|
|||
|
|
@ -1068,20 +1068,20 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
|
|||
static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
|
||||
struct scatterlist *sg_req,
|
||||
struct scatterlist *sg_resp,
|
||||
int max_sbals)
|
||||
int max_sbals, unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
unsigned int fcp_chan_timeout;
|
||||
|
||||
ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* common settings for ct/gs and els requests */
|
||||
fcp_chan_timeout = 2 * FC_DEF_R_A_TOV / 1000;
|
||||
if (timeout > 255)
|
||||
timeout = 255; /* max value accepted by hardware */
|
||||
req->qtcb->bottom.support.service_class = FSF_CLASS_3;
|
||||
req->qtcb->bottom.support.timeout = fcp_chan_timeout;
|
||||
zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ);
|
||||
req->qtcb->bottom.support.timeout = timeout;
|
||||
zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1092,7 +1092,8 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
|
|||
* @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
|
||||
*/
|
||||
int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
|
||||
struct zfcp_fsf_ct_els *ct, mempool_t *pool)
|
||||
struct zfcp_fsf_ct_els *ct, mempool_t *pool,
|
||||
unsigned int timeout)
|
||||
{
|
||||
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
||||
struct zfcp_fsf_req *req;
|
||||
|
|
@ -1111,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
|
|||
|
||||
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
|
||||
ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
|
||||
FSF_MAX_SBALS_PER_REQ);
|
||||
FSF_MAX_SBALS_PER_REQ, timeout);
|
||||
if (ret)
|
||||
goto failed_send;
|
||||
|
||||
|
|
@ -1188,7 +1189,7 @@ skip_fsfstatus:
|
|||
* @els: pointer to struct zfcp_send_els with data for the command
|
||||
*/
|
||||
int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
|
||||
struct zfcp_fsf_ct_els *els)
|
||||
struct zfcp_fsf_ct_els *els, unsigned int timeout)
|
||||
{
|
||||
struct zfcp_fsf_req *req;
|
||||
struct zfcp_qdio *qdio = adapter->qdio;
|
||||
|
|
@ -1206,7 +1207,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
|
|||
}
|
||||
|
||||
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
|
||||
ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2);
|
||||
ret = zfcp_fsf_setup_ct_els(req, els->req, els->resp, 2, timeout);
|
||||
|
||||
if (ret)
|
||||
goto failed_send;
|
||||
|
|
|
|||
|
|
@ -652,6 +652,7 @@ struct fc_function_template zfcp_transport_functions = {
|
|||
.show_host_port_state = 1,
|
||||
.show_host_active_fc4s = 1,
|
||||
.bsg_request = zfcp_fc_exec_bsg_job,
|
||||
.bsg_timeout = zfcp_fc_timeout_bsg_job,
|
||||
/* no functions registered for following dynamic attributes but
|
||||
directly set by LLDD */
|
||||
.show_host_port_type = 1,
|
||||
|
|
|
|||
Loading…
Reference in a new issue