Commit be8cde8b authored by Linus Torvalds's avatar Linus Torvalds

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
parents 981a2edd 534ef056
...@@ -4330,6 +4330,8 @@ initChainBuffers(MPT_ADAPTER *ioc) ...@@ -4330,6 +4330,8 @@ initChainBuffers(MPT_ADAPTER *ioc)
if (ioc->bus_type == SPI) if (ioc->bus_type == SPI)
num_chain *= MPT_SCSI_CAN_QUEUE; num_chain *= MPT_SCSI_CAN_QUEUE;
else if (ioc->bus_type == SAS)
num_chain *= MPT_SAS_CAN_QUEUE;
else else
num_chain *= MPT_FC_CAN_QUEUE; num_chain *= MPT_FC_CAN_QUEUE;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <asm/compat.h>
#include <asm/ccwdev.h> #include <asm/ccwdev.h>
#include "zfcp_def.h" #include "zfcp_def.h"
#include "zfcp_ext.h" #include "zfcp_ext.h"
...@@ -163,7 +164,7 @@ static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data, ...@@ -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, 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 *data;
struct zfcp_cfdc_data __user *data_user; struct zfcp_cfdc_data __user *data_user;
...@@ -175,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command, ...@@ -175,7 +176,11 @@ static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
if (command != ZFCP_CFDC_IOC) if (command != ZFCP_CFDC_IOC)
return -ENOTTY; 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) if (!data_user)
return -EINVAL; return -EINVAL;
......
...@@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(char **p, ...@@ -327,7 +327,7 @@ static void zfcp_dbf_hba_view_response(char **p,
break; break;
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
p += sprintf(*p, "\n"); *p += sprintf(*p, "\n");
break; break;
case FSF_QTCB_OPEN_PORT_WITH_DID: case FSF_QTCB_OPEN_PORT_WITH_DID:
......
...@@ -108,6 +108,7 @@ extern void zfcp_fc_wka_ports_force_offline(struct zfcp_fc_wka_ports *); ...@@ -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 int zfcp_fc_gs_setup(struct zfcp_adapter *);
extern void zfcp_fc_gs_destroy(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_exec_bsg_job(struct fc_bsg_job *);
extern int zfcp_fc_timeout_bsg_job(struct fc_bsg_job *);
/* zfcp_fsf.c */ /* zfcp_fsf.c */
extern int zfcp_fsf_open_port(struct zfcp_erp_action *); extern int zfcp_fsf_open_port(struct zfcp_erp_action *);
...@@ -129,9 +130,9 @@ extern void zfcp_fsf_req_dismiss_all(struct zfcp_adapter *); ...@@ -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_fsf_status_read(struct zfcp_qdio *);
extern int zfcp_status_read_refill(struct zfcp_adapter *adapter); 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 *, 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, 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 *, extern int zfcp_fsf_send_fcp_command_task(struct zfcp_unit *,
struct scsi_cmnd *); struct scsi_cmnd *);
extern void zfcp_fsf_req_free(struct zfcp_fsf_req *); 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, ...@@ -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; gid_pn->gid_pn_req.gid_pn.fn_wwpn = port->wwpn;
ret = zfcp_fsf_send_ct(&adapter->gs->ds, &gid_pn->ct, 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) { if (!ret) {
wait_for_completion(&completion); wait_for_completion(&completion);
zfcp_fc_ns_gid_pn_eval(gid_pn); zfcp_fc_ns_gid_pn_eval(gid_pn);
...@@ -421,7 +422,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port) ...@@ -421,7 +422,8 @@ static int zfcp_fc_adisc(struct zfcp_port *port)
hton24(adisc->adisc_req.adisc_port_id, hton24(adisc->adisc_req.adisc_port_id,
fc_host_port_id(adapter->scsi_host)); 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) if (ret)
kmem_cache_free(zfcp_data.adisc_cache, adisc); 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, ...@@ -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->req = &gpn_ft->sg_req;
ct->resp = gpn_ft->sg_resp; 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) if (!ret)
wait_for_completion(&completion); wait_for_completion(&completion);
return ret; return ret;
...@@ -677,6 +680,44 @@ static void zfcp_fc_ct_els_job_handler(void *data) ...@@ -677,6 +680,44 @@ static void zfcp_fc_ct_els_job_handler(void *data)
job->job_done(job); 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, static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
struct zfcp_adapter *adapter) struct zfcp_adapter *adapter)
{ {
...@@ -695,43 +736,27 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job, ...@@ -695,43 +736,27 @@ static int zfcp_fc_exec_els_job(struct fc_bsg_job *job,
} else } else
d_id = ntoh24(job->request->rqst_data.h_els.port_id); 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, static int zfcp_fc_exec_ct_job(struct fc_bsg_job *job,
struct zfcp_adapter *adapter) struct zfcp_adapter *adapter)
{ {
int ret; int ret;
u8 gs_type;
struct zfcp_fsf_ct_els *ct = job->dd_data; struct zfcp_fsf_ct_els *ct = job->dd_data;
struct zfcp_fc_wka_port *wka_port; struct zfcp_fc_wka_port *wka_port;
u32 preamble_word1;
preamble_word1 = job->request->rqst_data.r_ct.preamble_word1; wka_port = zfcp_fc_job_wka_port(job);
gs_type = (preamble_word1 & 0xff000000) >> 24; if (!wka_port)
return -EINVAL;
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 */
}
ret = zfcp_fc_wka_port_get(wka_port); ret = zfcp_fc_wka_port_get(wka_port);
if (ret) if (ret)
return 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) if (ret)
zfcp_fc_wka_port_put(wka_port); zfcp_fc_wka_port_put(wka_port);
...@@ -752,7 +777,6 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job) ...@@ -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->req = job->request_payload.sg_list;
ct_els->resp = job->reply_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; ct_els->handler_data = job;
switch (job->request->msgcode) { switch (job->request->msgcode) {
...@@ -767,6 +791,12 @@ int zfcp_fc_exec_bsg_job(struct fc_bsg_job *job) ...@@ -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) int zfcp_fc_gs_setup(struct zfcp_adapter *adapter)
{ {
struct zfcp_fc_wka_ports *wka_ports; struct zfcp_fc_wka_ports *wka_ports;
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \ #define ZFCP_FC_GPN_FT_MAX_ENT (ZFCP_FC_GPN_FT_NUM_BUFS * \
(ZFCP_FC_GPN_FT_ENT_PAGE + 1)) (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 * struct zfcp_fc_gid_pn_req - container for ct header plus gid_pn request
* @ct_hdr: FC GS common transport header * @ct_hdr: FC GS common transport header
......
...@@ -1068,20 +1068,20 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, ...@@ -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, static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
struct scatterlist *sg_req, struct scatterlist *sg_req,
struct scatterlist *sg_resp, struct scatterlist *sg_resp,
int max_sbals) int max_sbals, unsigned int timeout)
{ {
int ret; int ret;
unsigned int fcp_chan_timeout;
ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals); ret = zfcp_fsf_setup_ct_els_sbals(req, sg_req, sg_resp, max_sbals);
if (ret) if (ret)
return ret; return ret;
/* common settings for ct/gs and els requests */ /* 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.service_class = FSF_CLASS_3;
req->qtcb->bottom.support.timeout = fcp_chan_timeout; req->qtcb->bottom.support.timeout = timeout;
zfcp_fsf_start_timer(req, (fcp_chan_timeout + 10) * HZ); zfcp_fsf_start_timer(req, (timeout + 10) * HZ);
return 0; return 0;
} }
...@@ -1092,7 +1092,8 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req, ...@@ -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 * @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, 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_qdio *qdio = wka_port->adapter->qdio;
struct zfcp_fsf_req *req; struct zfcp_fsf_req *req;
...@@ -1111,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, ...@@ -1111,7 +1112,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; req->status |= ZFCP_STATUS_FSFREQ_CLEANUP;
ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp, ret = zfcp_fsf_setup_ct_els(req, ct->req, ct->resp,
FSF_MAX_SBALS_PER_REQ); FSF_MAX_SBALS_PER_REQ, timeout);
if (ret) if (ret)
goto failed_send; goto failed_send;
...@@ -1188,7 +1189,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) ...@@ -1188,7 +1189,7 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req)
* @els: pointer to struct zfcp_send_els with data for the command * @els: pointer to struct zfcp_send_els with data for the command
*/ */
int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, 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_fsf_req *req;
struct zfcp_qdio *qdio = adapter->qdio; struct zfcp_qdio *qdio = adapter->qdio;
...@@ -1206,7 +1207,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, ...@@ -1206,7 +1207,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
} }
req->status |= ZFCP_STATUS_FSFREQ_CLEANUP; 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) if (ret)
goto failed_send; goto failed_send;
......
...@@ -652,6 +652,7 @@ struct fc_function_template zfcp_transport_functions = { ...@@ -652,6 +652,7 @@ struct fc_function_template zfcp_transport_functions = {
.show_host_port_state = 1, .show_host_port_state = 1,
.show_host_active_fc4s = 1, .show_host_active_fc4s = 1,
.bsg_request = zfcp_fc_exec_bsg_job, .bsg_request = zfcp_fc_exec_bsg_job,
.bsg_timeout = zfcp_fc_timeout_bsg_job,
/* no functions registered for following dynamic attributes but /* no functions registered for following dynamic attributes but
directly set by LLDD */ directly set by LLDD */
.show_host_port_type = 1, .show_host_port_type = 1,
......
...@@ -293,7 +293,10 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) ...@@ -293,7 +293,10 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
status = -EINVAL; status = -EINVAL;
} }
} }
aac_fib_complete(fibptr); /* Do not set XferState to zero unless receives a response from F/W */
if (status >= 0)
aac_fib_complete(fibptr);
/* Send a CT_COMMIT_CONFIG to enable discovery of devices */ /* Send a CT_COMMIT_CONFIG to enable discovery of devices */
if (status >= 0) { if (status >= 0) {
if ((aac_commit == 1) || commit_flag) { if ((aac_commit == 1) || commit_flag) {
...@@ -310,13 +313,18 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) ...@@ -310,13 +313,18 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag)
FsaNormal, FsaNormal,
1, 1, 1, 1,
NULL, NULL); NULL, NULL);
aac_fib_complete(fibptr); /* Do not set XferState to zero unless
* receives a response from F/W */
if (status >= 0)
aac_fib_complete(fibptr);
} else if (aac_commit == 0) { } else if (aac_commit == 0) {
printk(KERN_WARNING printk(KERN_WARNING
"aac_get_config_status: Foreign device configurations are being ignored\n"); "aac_get_config_status: Foreign device configurations are being ignored\n");
} }
} }
aac_fib_free(fibptr); /* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibptr);
return status; return status;
} }
...@@ -355,7 +363,9 @@ int aac_get_containers(struct aac_dev *dev) ...@@ -355,7 +363,9 @@ int aac_get_containers(struct aac_dev *dev)
maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries); maximum_num_containers = le32_to_cpu(dresp->ContainerSwitchEntries);
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
} }
aac_fib_free(fibptr); /* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibptr);
if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS)
maximum_num_containers = MAXIMUM_NUM_CONTAINERS; maximum_num_containers = MAXIMUM_NUM_CONTAINERS;
...@@ -1245,8 +1255,12 @@ int aac_get_adapter_info(struct aac_dev* dev) ...@@ -1245,8 +1255,12 @@ int aac_get_adapter_info(struct aac_dev* dev)
NULL); NULL);
if (rcode < 0) { if (rcode < 0) {
aac_fib_complete(fibptr); /* FIB should be freed only after
aac_fib_free(fibptr); * getting the response from the F/W */
if (rcode != -ERESTARTSYS) {
aac_fib_complete(fibptr);
aac_fib_free(fibptr);
}
return rcode; return rcode;
} }
memcpy(&dev->adapter_info, info, sizeof(*info)); memcpy(&dev->adapter_info, info, sizeof(*info));
...@@ -1270,6 +1284,12 @@ int aac_get_adapter_info(struct aac_dev* dev) ...@@ -1270,6 +1284,12 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (rcode >= 0) if (rcode >= 0)
memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo)); memcpy(&dev->supplement_adapter_info, sinfo, sizeof(*sinfo));
if (rcode == -ERESTARTSYS) {
fibptr = aac_fib_alloc(dev);
if (!fibptr)
return -ENOMEM;
}
} }
...@@ -1470,9 +1490,11 @@ int aac_get_adapter_info(struct aac_dev* dev) ...@@ -1470,9 +1490,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
(dev->scsi_host_ptr->sg_tablesize * 8) + 112; (dev->scsi_host_ptr->sg_tablesize * 8) + 112;
} }
} }
/* FIB should be freed only after getting the response from the F/W */
aac_fib_complete(fibptr); if (rcode != -ERESTARTSYS) {
aac_fib_free(fibptr); aac_fib_complete(fibptr);
aac_fib_free(fibptr);
}
return rcode; return rcode;
} }
...@@ -1633,6 +1655,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) ...@@ -1633,6 +1655,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
* Alocate and initialize a Fib * Alocate and initialize a Fib
*/ */
if (!(cmd_fibcontext = aac_fib_alloc(dev))) { if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
printk(KERN_WARNING "aac_read: fib allocation failed\n");
return -1; return -1;
} }
...@@ -1712,9 +1735,14 @@ static int aac_write(struct scsi_cmnd * scsicmd) ...@@ -1712,9 +1735,14 @@ static int aac_write(struct scsi_cmnd * scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command * Allocate and initialize a Fib then setup a BlockWrite command
*/ */
if (!(cmd_fibcontext = aac_fib_alloc(dev))) { if (!(cmd_fibcontext = aac_fib_alloc(dev))) {
scsicmd->result = DID_ERROR << 16; /* FIB temporarily unavailable,not catastrophic failure */
scsicmd->scsi_done(scsicmd);
return 0; /* scsicmd->result = DID_ERROR << 16;
* scsicmd->scsi_done(scsicmd);
* return 0;
*/
printk(KERN_WARNING "aac_write: fib allocation failed\n");
return -1;
} }
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/ *----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD #ifndef AAC_DRIVER_BUILD
# define AAC_DRIVER_BUILD 2461 # define AAC_DRIVER_BUILD 24702
# define AAC_DRIVER_BRANCH "-ms" # define AAC_DRIVER_BRANCH "-ms"
#endif #endif
#define MAXIMUM_NUM_CONTAINERS 32 #define MAXIMUM_NUM_CONTAINERS 32
...@@ -1036,6 +1036,9 @@ struct aac_dev ...@@ -1036,6 +1036,9 @@ struct aac_dev
u8 printf_enabled; u8 printf_enabled;
u8 in_reset; u8 in_reset;
u8 msi; u8 msi;
int management_fib_count;
spinlock_t manage_lock;
}; };
#define aac_adapter_interrupt(dev) \ #define aac_adapter_interrupt(dev) \
......
...@@ -153,7 +153,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg) ...@@ -153,7 +153,7 @@ static int ioctl_send_fib(struct aac_dev * dev, void __user *arg)
fibptr->hw_fib_pa = hw_fib_pa; fibptr->hw_fib_pa = hw_fib_pa;
fibptr->hw_fib_va = hw_fib; fibptr->hw_fib_va = hw_fib;
} }
if (retval != -EINTR) if (retval != -ERESTARTSYS)
aac_fib_free(fibptr); aac_fib_free(fibptr);
return retval; return retval;
} }
...@@ -322,7 +322,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg) ...@@ -322,7 +322,7 @@ static int next_getadapter_fib(struct aac_dev * dev, void __user *arg)
} }
if (f.wait) { if (f.wait) {
if(down_interruptible(&fibctx->wait_sem) < 0) { if(down_interruptible(&fibctx->wait_sem) < 0) {
status = -EINTR; status = -ERESTARTSYS;
} else { } else {
/* Lock again and retry */ /* Lock again and retry */
spin_lock_irqsave(&dev->fib_lock, flags); spin_lock_irqsave(&dev->fib_lock, flags);
...@@ -593,10 +593,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -593,10 +593,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
u64 addr; u64 addr;
void* p; void* p;
if (upsg->sg[i].count > if (upsg->sg[i].count >
(dev->adapter_info.options & ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ? AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) : (dev->scsi_host_ptr->max_sectors << 9) :
65536) { 65536)) {
rcode = -EINVAL; rcode = -EINVAL;
goto cleanup; goto cleanup;
} }
...@@ -645,10 +645,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -645,10 +645,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
u64 addr; u64 addr;
void* p; void* p;
if (usg->sg[i].count > if (usg->sg[i].count >
(dev->adapter_info.options & ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ? AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) : (dev->scsi_host_ptr->max_sectors << 9) :
65536) { 65536)) {
rcode = -EINVAL; rcode = -EINVAL;
goto cleanup; goto cleanup;
} }
...@@ -695,10 +695,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -695,10 +695,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
uintptr_t addr; uintptr_t addr;
void* p; void* p;
if (usg->sg[i].count > if (usg->sg[i].count >
(dev->adapter_info.options & ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ? AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) : (dev->scsi_host_ptr->max_sectors << 9) :
65536) { 65536)) {
rcode = -EINVAL; rcode = -EINVAL;
goto cleanup; goto cleanup;
} }
...@@ -734,10 +734,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -734,10 +734,10 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
dma_addr_t addr; dma_addr_t addr;
void* p; void* p;
if (upsg->sg[i].count > if (upsg->sg[i].count >
(dev->adapter_info.options & ((dev->adapter_info.options &
AAC_OPT_NEW_COMM) ? AAC_OPT_NEW_COMM) ?
(dev->scsi_host_ptr->max_sectors << 9) : (dev->scsi_host_ptr->max_sectors << 9) :
65536) { 65536)) {
rcode = -EINVAL; rcode = -EINVAL;
goto cleanup; goto cleanup;
} }
...@@ -772,8 +772,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -772,8 +772,8 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
psg->count = cpu_to_le32(sg_indx+1); psg->count = cpu_to_le32(sg_indx+1);
status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL); status = aac_fib_send(ScsiPortCommand, srbfib, actual_fibsize, FsaNormal, 1, 1, NULL, NULL);
} }
if (status == -EINTR) { if (status == -ERESTARTSYS) {
rcode = -EINTR; rcode = -ERESTARTSYS;
goto cleanup; goto cleanup;
} }
...@@ -810,7 +810,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg) ...@@ -810,7 +810,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
for(i=0; i <= sg_indx; i++){ for(i=0; i <= sg_indx; i++){
kfree(sg_list[i]); kfree(sg_list[i]);
} }
if (rcode != -EINTR) { if (rcode != -ERESTARTSYS) {
aac_fib_complete(srbfib); aac_fib_complete(srbfib);
aac_fib_free(srbfib); aac_fib_free(srbfib);
} }
...@@ -848,7 +848,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg) ...@@ -848,7 +848,7 @@ int aac_do_ioctl(struct aac_dev * dev, int cmd, void __user *arg)
*/ */
status = aac_dev_ioctl(dev, cmd, arg); status = aac_dev_ioctl(dev, cmd, arg);
if(status != -ENOTTY) if (status != -ENOTTY)
return status; return status;
switch (cmd) { switch (cmd) {
......
...@@ -194,7 +194,9 @@ int aac_send_shutdown(struct aac_dev * dev) ...@@ -194,7 +194,9 @@ int aac_send_shutdown(struct aac_dev * dev)
if (status >= 0) if (status >= 0)
aac_fib_complete(fibctx); aac_fib_complete(fibctx);
aac_fib_free(fibctx); /* FIB should be freed only after getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
return status; return status;
} }
...@@ -304,6 +306,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) ...@@ -304,6 +306,8 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
/* /*
* Check the preferred comm settings, defaults from template. * Check the preferred comm settings, defaults from template.
*/ */
dev->management_fib_count = 0;
spin_lock_init(&dev->manage_lock);
dev->max_fib_size = sizeof(struct hw_fib); dev->max_fib_size = sizeof(struct hw_fib);
dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
- sizeof(struct aac_fibhdr) - sizeof(struct aac_fibhdr)
......
...@@ -189,7 +189,14 @@ struct fib *aac_fib_alloc(struct aac_dev *dev) ...@@ -189,7 +189,14 @@ struct fib *aac_fib_alloc(struct aac_dev *dev)
void aac_fib_free(struct fib *fibptr) void aac_fib_free(struct fib *fibptr)
{ {
unsigned long flags; unsigned long flags, flagsv;
spin_lock_irqsave(&fibptr->event_lock, flagsv);
if (fibptr->done == 2) {
spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
return;
}
spin_unlock_irqrestore(&fibptr->event_lock, flagsv);
spin_lock_irqsave(&fibptr->dev->fib_lock, flags); spin_lock_irqsave(&fibptr->dev->fib_lock, flags);
if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)) if (unlikely(fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT))
...@@ -390,6 +397,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, ...@@ -390,6 +397,8 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
struct hw_fib * hw_fib = fibptr->hw_fib_va; struct hw_fib * hw_fib = fibptr->hw_fib_va;
unsigned long flags = 0; unsigned long flags = 0;
unsigned long qflags; unsigned long qflags;
unsigned long mflags = 0;
if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned))) if (!(hw_fib->header.XferState & cpu_to_le32(HostOwned)))
return -EBUSY; return -EBUSY;
...@@ -471,9 +480,31 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, ...@@ -471,9 +480,31 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
if (!dev->queues) if (!dev->queues)
return -EBUSY; return -EBUSY;
if(wait) if (wait) {
spin_lock_irqsave(&dev->manage_lock, mflags);
if (dev->management_fib_count >= AAC_NUM_MGT_FIB) {
printk(KERN_INFO "No management Fibs Available:%d\n",
dev->management_fib_count);
spin_unlock_irqrestore(&dev->manage_lock, mflags);
return -EBUSY;
}
dev->management_fib_count++;
spin_unlock_irqrestore(&dev->manage_lock, mflags);
spin_lock_irqsave(&fibptr->event_lock, flags); spin_lock_irqsave(&fibptr->event_lock, flags);
aac_adapter_deliver(fibptr); }
if (aac_adapter_deliver(fibptr) != 0) {
printk(KERN_ERR "aac_fib_send: returned -EBUSY\n");
if (wait) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
spin_lock_irqsave(&dev->manage_lock, mflags);
dev->management_fib_count--;
spin_unlock_irqrestore(&dev->manage_lock, mflags);
}
return -EBUSY;
}
/* /*
* If the caller wanted us to wait for response wait now. * If the caller wanted us to wait for response wait now.
...@@ -516,14 +547,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, ...@@ -516,14 +547,15 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
udelay(5); udelay(5);
} }
} else if (down_interruptible(&fibptr->event_wait)) { } else if (down_interruptible(&fibptr->event_wait)) {
fibptr->done = 2; /* Do nothing ... satisfy
up(&fibptr->event_wait); * down_interruptible must_check */
} }
spin_lock_irqsave(&fibptr->event_lock, flags); spin_lock_irqsave(&fibptr->event_lock, flags);
if ((fibptr->done == 0) || (fibptr->done == 2)) { if (fibptr->done == 0) {
fibptr->done = 2; /* Tell interrupt we aborted */ fibptr->done = 2; /* Tell interrupt we aborted */
spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_unlock_irqrestore(&fibptr->event_lock, flags);
return -EINTR; return -ERESTARTSYS;
} }
spin_unlock_irqrestore(&fibptr->event_lock, flags); spin_unlock_irqrestore(&fibptr->event_lock, flags);
BUG_ON(fibptr->done == 0); BUG_ON(fibptr->done == 0);
...@@ -689,6 +721,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) ...@@ -689,6 +721,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
int aac_fib_complete(struct fib *fibptr) int aac_fib_complete(struct fib *fibptr)
{ {
unsigned long flags;
struct hw_fib * hw_fib = fibptr->hw_fib_va; struct hw_fib * hw_fib = fibptr->hw_fib_va;
/* /*
...@@ -709,6 +742,13 @@ int aac_fib_complete(struct fib *fibptr) ...@@ -709,6 +742,13 @@ int aac_fib_complete(struct fib *fibptr)
* command is complete that we had sent to the adapter and this * command is complete that we had sent to the adapter and this
* cdb could be reused. * cdb could be reused.
*/ */
spin_lock_irqsave(&fibptr->event_lock, flags);
if (fibptr->done == 2) {
spin_unlock_irqrestore(&fibptr->event_lock, flags);
return 0;
}
spin_unlock_irqrestore(&fibptr->event_lock, flags);
if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) && if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&
(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed))) (hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))
{ {
...@@ -1355,7 +1395,10 @@ int aac_reset_adapter(struct aac_dev * aac, int forced) ...@@ -1355,7 +1395,10 @@ int aac_reset_adapter(struct aac_dev * aac, int forced)
if (status >= 0) if (status >= 0)
aac_fib_complete(fibctx); aac_fib_complete(fibctx);
aac_fib_free(fibctx); /* FIB should be freed only after getting
* the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibctx);
} }
} }
...@@ -1759,6 +1802,7 @@ int aac_command_thread(void *data) ...@@ -1759,6 +1802,7 @@ int aac_command_thread(void *data)
struct fib *fibptr; struct fib *fibptr;
if ((fibptr = aac_fib_alloc(dev))) { if ((fibptr = aac_fib_alloc(dev))) {
int status;
__le32 *info; __le32 *info;
aac_fib_init(fibptr); aac_fib_init(fibptr);
...@@ -1769,15 +1813,21 @@ int aac_command_thread(void *data) ...@@ -1769,15 +1813,21 @@ int aac_command_thread(void *data)
*info = cpu_to_le32(now.tv_sec); *info = cpu_to_le32(now.tv_sec);
(void)aac_fib_send(SendHostTime, status = aac_fib_send(SendHostTime,
fibptr, fibptr,
sizeof(*info), sizeof(*info),
FsaNormal, FsaNormal,
1, 1, 1, 1,
NULL, NULL,
NULL); NULL);
aac_fib_complete(fibptr); /* Do not set XferState to zero unless
aac_fib_free(fibptr); * receives a response from F/W */
if (status >= 0)
aac_fib_complete(fibptr);
/* FIB should be freed only after
* getting the response from the F/W */
if (status != -ERESTARTSYS)
aac_fib_free(fibptr);
} }
difference = (long)(unsigned)update_interval*HZ; difference = (long)(unsigned)update_interval*HZ;
} else { } else {
......
...@@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q) ...@@ -57,9 +57,9 @@ unsigned int aac_response_normal(struct aac_queue * q)
struct hw_fib * hwfib; struct hw_fib * hwfib;
struct fib * fib; struct fib * fib;
int consumed = 0; int consumed = 0;
unsigned long flags; unsigned long flags, mflags;
spin_lock_irqsave(q->lock, flags); spin_lock_irqsave(q->lock, flags);
/* /*
* Keep pulling response QEs off the response queue and waking * Keep pulling response QEs off the response queue and waking
* up the waiters until there are no more QEs. We then return * up the waiters until there are no more QEs. We then return
...@@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q) ...@@ -125,12 +125,21 @@ unsigned int aac_response_normal(struct aac_queue * q)
} else { } else {
unsigned long flagv; unsigned long flagv;
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
if (!fib->done) if (!fib->done) {
fib->done = 1; fib->done = 1;
up(&fib->event_wait); up(&fib->event_wait);
}
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
spin_lock_irqsave(&dev->manage_lock, mflags);
dev->management_fib_count--;
spin_unlock_irqrestore(&dev->manage_lock, mflags);
FIB_COUNTER_INCREMENT(aac_config.NormalRecved); FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
if (fib->done == 2) { if (fib->done == 2) {
spin_lock_irqsave(&fib->event_lock, flagv);
fib->done = 0;
spin_unlock_irqrestore(&fib->event_lock, flagv);
aac_fib_complete(fib); aac_fib_complete(fib);
aac_fib_free(fib); aac_fib_free(fib);
} }
...@@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q) ...@@ -232,6 +241,7 @@ unsigned int aac_command_normal(struct aac_queue *q)
unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
{ {
unsigned long mflags;
dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index)); dprintk((KERN_INFO "aac_intr_normal(%p,%x)\n", dev, index));
if ((index & 0x00000002L)) { if ((index & 0x00000002L)) {
struct hw_fib * hw_fib; struct hw_fib * hw_fib;
...@@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index) ...@@ -320,11 +330,25 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 index)
unsigned long flagv; unsigned long flagv;
dprintk((KERN_INFO "event_wait up\n")); dprintk((KERN_INFO "event_wait up\n"));
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
if (!fib->done) if (!fib->done) {
fib->done = 1; fib->done = 1;
up(&fib->event_wait); up(&fib->event_wait);
}
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
spin_lock_irqsave(&dev->manage_lock, mflags);
dev->management_fib_count--;
spin_unlock_irqrestore(&dev->manage_lock, mflags);
FIB_COUNTER_INCREMENT(aac_config.NormalRecved); FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
if (fib->done == 2) {
spin_lock_irqsave(&fib->event_lock, flagv);
fib->done = 0;
spin_unlock_irqrestore(&fib->event_lock, flagv);
aac_fib_complete(fib);
aac_fib_free(fib);
}
} }
return 0; return 0;
} }
......
...@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ...@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
tinfo->curr.transport_version = 2; tinfo->curr.transport_version = 2;
tinfo->goal.transport_version = 2; tinfo->goal.transport_version = 2;
tinfo->goal.ppr_options = 0; tinfo->goal.ppr_options = 0;
/* if (scb != NULL) {
* Remove any SCBs in the waiting for selection /*
* queue that may also be for this target so * Remove any SCBs in the waiting
* that command ordering is preserved. * for selection queue that may
*/ * also be for this target so that
ahd_freeze_devq(ahd, scb); * command ordering is preserved.
ahd_qinfifo_requeue_tail(ahd, scb); */
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0; printerror = 0;
} }
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
...@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ...@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
MSG_EXT_WDTR_BUS_8_BIT, MSG_EXT_WDTR_BUS_8_BIT,
AHD_TRANS_CUR|AHD_TRANS_GOAL, AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
/* if (scb != NULL) {
* Remove any SCBs in the waiting for selection /*
* queue that may also be for this target so that * Remove any SCBs in the waiting for
* command ordering is preserved. * selection queue that may also be for
*/ * this target so that command ordering
ahd_freeze_devq(ahd, scb); * is preserved.
ahd_qinfifo_requeue_tail(ahd, scb); */
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0; printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
&& ppr_busfree == 0) { && ppr_busfree == 0) {
...@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ...@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
/*ppr_options*/0, /*ppr_options*/0,
AHD_TRANS_CUR|AHD_TRANS_GOAL, AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE); /*paused*/TRUE);
/* if (scb != NULL) {
* Remove any SCBs in the waiting for selection /*
* queue that may also be for this target so that * Remove any SCBs in the waiting for
* command ordering is preserved. * selection queue that may also be for
*/ * this target so that command ordering
ahd_freeze_devq(ahd, scb); * is preserved.
ahd_qinfifo_requeue_tail(ahd, scb); */
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0; printerror = 0;
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
&& ahd_sent_msg(ahd, AHDMSG_1B, && ahd_sent_msg(ahd, AHDMSG_1B,
...@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) ...@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
* the message phases. We check it last in case we * the message phases. We check it last in case we
* had to send some other message that caused a busfree. * had to send some other message that caused a busfree.
*/ */
if (printerror != 0 if (scb != NULL && printerror != 0
&& (lastphase == P_MESGIN || lastphase == P_MESGOUT) && (lastphase == P_MESGIN || lastphase == P_MESGOUT)
&& ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {
......
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
...@@ -1586,8 +1586,7 @@ typedef struct fc_port { ...@@ -1586,8 +1586,7 @@ typedef struct fc_port {
*/ */
#define FCF_FABRIC_DEVICE BIT_0 #define FCF_FABRIC_DEVICE BIT_0
#define FCF_LOGIN_NEEDED BIT_1 #define FCF_LOGIN_NEEDED BIT_1
#define FCF_TAPE_PRESENT BIT_2 #define FCF_FCP2_DEVICE BIT_2
#define FCF_FCP2_DEVICE BIT_3
/* No loop ID flag. */ /* No loop ID flag. */
#define FC_NO_LOOP_ID 0x1000 #define FC_NO_LOOP_ID 0x1000
......
...@@ -205,7 +205,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport, ...@@ -205,7 +205,7 @@ qla2x00_async_login_done(struct scsi_qla_host *vha, fc_port_t *fcport,
switch (data[0]) { switch (data[0]) {
case MBS_COMMAND_COMPLETE: case MBS_COMMAND_COMPLETE:
if (fcport->flags & FCF_TAPE_PRESENT) if (fcport->flags & FCF_FCP2_DEVICE)
opts |= BIT_1; opts |= BIT_1;
rval = qla2x00_get_port_database(vha, fcport, opts); rval = qla2x00_get_port_database(vha, fcport, opts);
if (rval != QLA_SUCCESS) if (rval != QLA_SUCCESS)
...@@ -2726,7 +2726,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) ...@@ -2726,7 +2726,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
/* /*
* Logout all previous fabric devices marked lost, except * Logout all previous fabric devices marked lost, except
* tape devices. * FCP2 devices.
*/ */
list_for_each_entry(fcport, &vha->vp_fcports, list) { list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
...@@ -2739,7 +2739,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) ...@@ -2739,7 +2739,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
qla2x00_mark_device_lost(vha, fcport, qla2x00_mark_device_lost(vha, fcport,
ql2xplogiabsentdevice, 0); ql2xplogiabsentdevice, 0);
if (fcport->loop_id != FC_NO_LOOP_ID && if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_TAPE_PRESENT) == 0 && (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) { fcport->port_type != FCT_BROADCAST) {
ha->isp_ops->fabric_logout(vha, ha->isp_ops->fabric_logout(vha,
...@@ -3018,7 +3018,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha, ...@@ -3018,7 +3018,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
fcport->d_id.b24 = new_fcport->d_id.b24; fcport->d_id.b24 = new_fcport->d_id.b24;
fcport->flags |= FCF_LOGIN_NEEDED; fcport->flags |= FCF_LOGIN_NEEDED;
if (fcport->loop_id != FC_NO_LOOP_ID && if (fcport->loop_id != FC_NO_LOOP_ID &&
(fcport->flags & FCF_TAPE_PRESENT) == 0 && (fcport->flags & FCF_FCP2_DEVICE) == 0 &&
fcport->port_type != FCT_INITIATOR && fcport->port_type != FCT_INITIATOR &&
fcport->port_type != FCT_BROADCAST) { fcport->port_type != FCT_BROADCAST) {
ha->isp_ops->fabric_logout(vha, fcport->loop_id, ha->isp_ops->fabric_logout(vha, fcport->loop_id,
...@@ -3272,9 +3272,9 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport, ...@@ -3272,9 +3272,9 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *vha, fc_port_t *fcport,
rval = qla2x00_fabric_login(vha, fcport, next_loopid); rval = qla2x00_fabric_login(vha, fcport, next_loopid);
if (rval == QLA_SUCCESS) { if (rval == QLA_SUCCESS) {
/* Send an ADISC to tape devices.*/ /* Send an ADISC to FCP2 devices.*/
opts = 0; opts = 0;
if (fcport->flags & FCF_TAPE_PRESENT) if (fcport->flags & FCF_FCP2_DEVICE)
opts |= BIT_1; opts |= BIT_1;
rval = qla2x00_get_port_database(vha, fcport, opts); rval = qla2x00_get_port_database(vha, fcport, opts);
if (rval != QLA_SUCCESS) { if (rval != QLA_SUCCESS) {
......
...@@ -1188,7 +1188,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) ...@@ -1188,7 +1188,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
scsi_qla_host_t *vha = shost_priv(sdev->host); scsi_qla_host_t *vha = shost_priv(sdev->host);
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct fc_rport *rport = starget_to_rport(sdev->sdev_target); struct fc_rport *rport = starget_to_rport(sdev->sdev_target);
fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
struct req_que *req = vha->req; struct req_que *req = vha->req;
if (sdev->tagged_supported) if (sdev->tagged_supported)
...@@ -1197,8 +1196,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev) ...@@ -1197,8 +1196,6 @@ qla2xxx_slave_configure(struct scsi_device *sdev)
scsi_deactivate_tcq(sdev, req->max_q_depth); scsi_deactivate_tcq(sdev, req->max_q_depth);
rport->dev_loss_tmo = ha->port_down_retry_count; rport->dev_loss_tmo = ha->port_down_retry_count;
if (sdev->type == TYPE_TAPE)
fcport->flags |= FCF_TAPE_PRESENT;
return 0; return 0;
} }
...@@ -2805,7 +2802,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha) ...@@ -2805,7 +2802,7 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
fcport->login_retry--; fcport->login_retry--;
if (fcport->flags & FCF_FABRIC_DEVICE) { if (fcport->flags & FCF_FABRIC_DEVICE) {
if (fcport->flags & FCF_TAPE_PRESENT) if (fcport->flags & FCF_FCP2_DEVICE)
ha->isp_ops->fabric_logout(vha, ha->isp_ops->fabric_logout(vha,
fcport->loop_id, fcport->loop_id,
fcport->d_id.b.domain, fcport->d_id.b.domain,
...@@ -3141,7 +3138,10 @@ qla2x00_timer(scsi_qla_host_t *vha) ...@@ -3141,7 +3138,10 @@ qla2x00_timer(scsi_qla_host_t *vha)
if (!IS_QLA2100(ha) && vha->link_down_timeout) if (!IS_QLA2100(ha) && vha->link_down_timeout)
atomic_set(&vha->loop_state, LOOP_DEAD); atomic_set(&vha->loop_state, LOOP_DEAD);
/* Schedule an ISP abort to return any tape commands. */ /*
* Schedule an ISP abort to return any FCP2-device
* commands.
*/
/* NPIV - scan physical port only */ /* NPIV - scan physical port only */
if (!vha->vp_idx) { if (!vha->vp_idx) {
spin_lock_irqsave(&ha->hardware_lock, spin_lock_irqsave(&ha->hardware_lock,
...@@ -3158,7 +3158,7 @@ qla2x00_timer(scsi_qla_host_t *vha) ...@@ -3158,7 +3158,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
if (sp->ctx) if (sp->ctx)
continue; continue;
sfcp = sp->fcport; sfcp = sp->fcport;
if (!(sfcp->flags & FCF_TAPE_PRESENT)) if (!(sfcp->flags & FCF_FCP2_DEVICE))
continue; continue;
set_bit(ISP_ABORT_NEEDED, set_bit(ISP_ABORT_NEEDED,
......
...@@ -2292,11 +2292,14 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf, ...@@ -2292,11 +2292,14 @@ qla25xx_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
uint32_t faddr, left, burst; uint32_t faddr, left, burst;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
if (IS_QLA25XX(ha) || IS_QLA81XX(ha))
goto try_fast;
if (offset & 0xfff) if (offset & 0xfff)
goto slow_read; goto slow_read;
if (length < OPTROM_BURST_SIZE) if (length < OPTROM_BURST_SIZE)
goto slow_read; goto slow_read;
try_fast:
optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE,
&optrom_dma, GFP_KERNEL); &optrom_dma, GFP_KERNEL);
if (!optrom) { if (!optrom) {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
/* /*
* Driver version * Driver version
*/ */
#define QLA2XXX_VERSION "8.03.01-k9" #define QLA2XXX_VERSION "8.03.01-k10"
#define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3 #define QLA_DRIVER_MINOR_VER 3
......
...@@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) ...@@ -749,9 +749,9 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
*/ */
req->next_rq->resid_len = scsi_in(cmd)->resid; req->next_rq->resid_len = scsi_in(cmd)->resid;
scsi_release_buffers(cmd);
blk_end_request_all(req, 0); blk_end_request_all(req, 0);
scsi_release_buffers(cmd);
scsi_next_command(cmd); scsi_next_command(cmd);
return; return;
} }
......
...@@ -3527,7 +3527,10 @@ fc_bsg_job_timeout(struct request *req) ...@@ -3527,7 +3527,10 @@ fc_bsg_job_timeout(struct request *req)
if (!done && i->f->bsg_timeout) { if (!done && i->f->bsg_timeout) {
/* call LLDD to abort the i/o as it has timed out */ /* call LLDD to abort the i/o as it has timed out */
err = i->f->bsg_timeout(job); err = i->f->bsg_timeout(job);
if (err) if (err == -EAGAIN) {
job->ref_cnt--;
return BLK_EH_RESET_TIMER;
} else if (err)
printk(KERN_ERR "ERROR: FC BSG request timeout - LLD " printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
"abort failed with status %d\n", err); "abort failed with status %d\n", err);
} }
......
...@@ -292,7 +292,7 @@ struct fc_bsg_request { ...@@ -292,7 +292,7 @@ struct fc_bsg_request {
struct fc_bsg_rport_els r_els; struct fc_bsg_rport_els r_els;
struct fc_bsg_rport_ct r_ct; struct fc_bsg_rport_ct r_ct;
} rqst_data; } rqst_data;
}; } __attribute__((packed));
/* response (request sense data) structure of the sg_io_v4 */ /* response (request sense data) structure of the sg_io_v4 */
......
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