Commit 0375ec58 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull misc SCSI driver updates from James Bottomley:
 "This patch set is a set of driver updates (megaraid_sas, fnic, lpfc,
  ufs, hpsa) we also have a couple of bug fixes (sd out of bounds and
  ibmvfc error handling) and the first round of esas2r checker fixes and
  finally the much anticipated big endian additions for megaraid_sas"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (47 commits)
  [SCSI] fnic: fnic Driver Tuneables Exposed through CLI
  [SCSI] fnic: Kernel panic while running sh/nosh with max lun cfg
  [SCSI] fnic: Hitting BUG_ON(io_req->abts_done) in fnic_rport_exch_reset
  [SCSI] fnic: Remove QUEUE_FULL handling code
  [SCSI] fnic: On system with >1.1TB RAM, VIC fails multipath after boot up
  [SCSI] fnic: FC stat param seconds_since_last_reset not getting updated
  [SCSI] sd: Fix potential out-of-bounds access
  [SCSI] lpfc 8.3.42: Update lpfc version to driver version 8.3.42
  [SCSI] lpfc 8.3.42: Fixed issue of task management commands having a fixed timeout
  [SCSI] lpfc 8.3.42: Fixed inconsistent spin lock usage.
  [SCSI] lpfc 8.3.42: Fix driver's abort loop functionality to skip IOs already getting aborted
  [SCSI] lpfc 8.3.42: Fixed failure to allocate SCSI buffer on PPC64 platform for SLI4 devices
  [SCSI] lpfc 8.3.42: Fix WARN_ON when driver unloads
  [SCSI] lpfc 8.3.42: Avoided making pci bar ioremap call during dual-chute WQ/RQ pci bar selection
  [SCSI] lpfc 8.3.42: Fixed driver iocbq structure's iocb_flag field running out of space
  [SCSI] lpfc 8.3.42: Fix crash on driver load due to cpu affinity logic
  [SCSI] lpfc 8.3.42: Fixed logging format of setting driver sysfs attributes hard to interpret
  [SCSI] lpfc 8.3.42: Fixed back to back RSCNs discovery failure.
  [SCSI] lpfc 8.3.42: Fixed race condition between BSG I/O dispatch and timeout handling
  [SCSI] lpfc 8.3.42: Fixed function mode field defined too small for not recognizing dual-chute mode
  ...
parents bff157b3 fc85799e
Release Date : Sat. Aug 31, 2013 17:00:00 PST 2013 -
(emaild-id:megaraidlinux@lsi.com)
Adam Radford
Kashyap Desai
Sumit Saxena
Current Version : 06.700.06.00-rc1
Old Version : 06.600.18.00-rc1
1. Add High Availability clustering support using shared Logical Disks.
2. Version and Changelog update.
-------------------------------------------------------------------------------
Release Date : Wed. May 15, 2013 17:00:00 PST 2013 -
(emaild-id:megaraidlinux@lsi.com)
Adam Radford
......
......@@ -692,7 +692,7 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
* ID as valid.
*/
if (ahc_get_pci_function(pci) > 0
&& ahc_9005_subdevinfo_valid(vendor, device, subvendor, subdevice)
&& ahc_9005_subdevinfo_valid(device, vendor, subdevice, subvendor)
&& SUBID_9005_MFUNCENB(subdevice) == 0)
return (NULL);
......
......@@ -860,8 +860,13 @@ bool esas2r_process_fs_ioctl(struct esas2r_adapter *a,
return false;
}
if (fsc->command >= cmdcnt) {
fs->status = ATTO_STS_INV_FUNC;
return false;
}
func = cmd_to_fls_func[fsc->command];
if (fsc->command >= cmdcnt || func == 0xFF) {
if (func == 0xFF) {
fs->status = ATTO_STS_INV_FUNC;
return false;
}
......@@ -1355,7 +1360,7 @@ void esas2r_nvram_set_defaults(struct esas2r_adapter *a)
u32 time = jiffies_to_msecs(jiffies);
esas2r_lock_clear_flags(&a->flags, AF_NVR_VALID);
memcpy(n, &default_sas_nvram, sizeof(struct esas2r_sas_nvram));
*n = default_sas_nvram;
n->sas_addr[3] |= 0x0F;
n->sas_addr[4] = HIBYTE(LOWORD(time));
n->sas_addr[5] = LOBYTE(LOWORD(time));
......@@ -1373,7 +1378,7 @@ void esas2r_nvram_get_defaults(struct esas2r_adapter *a,
* address out first.
*/
memcpy(&sas_addr[0], a->nvram->sas_addr, 8);
memcpy(nvram, &default_sas_nvram, sizeof(struct esas2r_sas_nvram));
*nvram = default_sas_nvram;
memcpy(&nvram->sas_addr[0], &sas_addr[0], 8);
}
......
......@@ -665,7 +665,7 @@ void esas2r_kill_adapter(int i)
int esas2r_cleanup(struct Scsi_Host *host)
{
struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata;
struct esas2r_adapter *a;
int index;
if (host == NULL) {
......@@ -678,6 +678,7 @@ int esas2r_cleanup(struct Scsi_Host *host)
}
esas2r_debug("esas2r_cleanup called for host %p", host);
a = (struct esas2r_adapter *)host->hostdata;
index = a->index;
esas2r_kill_adapter(index);
return index;
......@@ -808,7 +809,7 @@ static void esas2r_init_pci_cfg_space(struct esas2r_adapter *a)
int pcie_cap_reg;
pcie_cap_reg = pci_find_capability(a->pcid, PCI_CAP_ID_EXP);
if (0xffff && pcie_cap_reg) {
if (0xffff & pcie_cap_reg) {
u16 devcontrol;
pci_read_config_word(a->pcid, pcie_cap_reg + PCI_EXP_DEVCTL,
......@@ -1550,8 +1551,7 @@ void esas2r_reset_chip(struct esas2r_adapter *a)
* to not overwrite a previous crash that was saved.
*/
if ((a->flags2 & AF2_COREDUMP_AVAIL)
&& !(a->flags2 & AF2_COREDUMP_SAVED)
&& a->fw_coredump_buff) {
&& !(a->flags2 & AF2_COREDUMP_SAVED)) {
esas2r_read_mem_block(a,
a->fw_coredump_buff,
MW_DATA_ADDR_SRAM + 0x80000,
......
......@@ -415,7 +415,7 @@ static int csmi_ioctl_callback(struct esas2r_adapter *a,
lun = tm->lun;
}
if (path > 0 || tid > ESAS2R_MAX_ID) {
if (path > 0) {
rq->func_rsp.ioctl_rsp.csmi.csmi_status = cpu_to_le32(
CSMI_STS_INV_PARAM);
return false;
......
......@@ -302,6 +302,7 @@ static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
if (vi->cmd.cfg.cfg_func == VDA_CFG_GET_INIT) {
struct atto_ioctl_vda_cfg_cmd *cfg = &vi->cmd.cfg;
struct atto_vda_cfg_rsp *rsp = &rq->func_rsp.cfg_rsp;
char buf[sizeof(cfg->data.init.fw_release) + 1];
cfg->data_length =
cpu_to_le32(sizeof(struct atto_vda_cfg_init));
......@@ -309,11 +310,13 @@ static void esas2r_complete_vda_ioctl(struct esas2r_adapter *a,
le32_to_cpu(rsp->vda_version);
cfg->data.init.fw_build = rsp->fw_build;
sprintf((char *)&cfg->data.init.fw_release,
"%1d.%02d",
snprintf(buf, sizeof(buf), "%1d.%02d",
(int)LOBYTE(le16_to_cpu(rsp->fw_release)),
(int)HIBYTE(le16_to_cpu(rsp->fw_release)));
memcpy(&cfg->data.init.fw_release, buf,
sizeof(cfg->data.init.fw_release));
if (LOWORD(LOBYTE(cfg->data.init.fw_build)) == 'A')
cfg->data.init.fw_version =
cfg->data.init.fw_build;
......
......@@ -43,6 +43,8 @@
#define DFX DRV_NAME "%d: "
#define DESC_CLEAN_LOW_WATERMARK 8
#define FNIC_UCSM_DFLT_THROTTLE_CNT_BLD 16 /* UCSM default throttle count */
#define FNIC_MIN_IO_REQ 256 /* Min IO throttle count */
#define FNIC_MAX_IO_REQ 2048 /* scsi_cmnd tag map entries */
#define FNIC_IO_LOCKS 64 /* IO locks: power of 2 */
#define FNIC_DFLT_QUEUE_DEPTH 32
......@@ -154,6 +156,9 @@ do { \
FNIC_CHECK_LOGGING(FNIC_ISR_LOGGING, \
shost_printk(kern_level, host, fmt, ##args);)
#define FNIC_MAIN_NOTE(kern_level, host, fmt, args...) \
shost_printk(kern_level, host, fmt, ##args)
extern const char *fnic_state_str[];
enum fnic_intx_intr_index {
......@@ -215,10 +220,12 @@ struct fnic {
struct vnic_stats *stats;
unsigned long stats_time; /* time of stats update */
unsigned long stats_reset_time; /* time of stats reset */
struct vnic_nic_cfg *nic_cfg;
char name[IFNAMSIZ];
struct timer_list notify_timer; /* used for MSI interrupts */
unsigned int fnic_max_tag_id;
unsigned int err_intr_offset;
unsigned int link_intr_offset;
......@@ -359,4 +366,5 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags)
return ((fnic->state_flags & st_flags) == st_flags);
}
void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long);
void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *);
#endif /* _FNIC_H_ */
......@@ -74,6 +74,10 @@ module_param(fnic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_trace_max_pages, "Total allocated memory pages "
"for fnic trace buffer");
static unsigned int fnic_max_qdepth = FNIC_DFLT_QUEUE_DEPTH;
module_param(fnic_max_qdepth, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(fnic_max_qdepth, "Queue depth to report for each LUN");
static struct libfc_function_template fnic_transport_template = {
.frame_send = fnic_send,
.lport_set_port_id = fnic_set_port_id,
......@@ -91,7 +95,7 @@ static int fnic_slave_alloc(struct scsi_device *sdev)
if (!rport || fc_remote_port_chkready(rport))
return -ENXIO;
scsi_activate_tcq(sdev, FNIC_DFLT_QUEUE_DEPTH);
scsi_activate_tcq(sdev, fnic_max_qdepth);
return 0;
}
......@@ -126,6 +130,7 @@ fnic_set_rport_dev_loss_tmo(struct fc_rport *rport, u32 timeout)
static void fnic_get_host_speed(struct Scsi_Host *shost);
static struct scsi_transport_template *fnic_fc_transport;
static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *);
static void fnic_reset_host_stats(struct Scsi_Host *);
static struct fc_function_template fnic_fc_functions = {
......@@ -153,6 +158,7 @@ static struct fc_function_template fnic_fc_functions = {
.set_rport_dev_loss_tmo = fnic_set_rport_dev_loss_tmo,
.issue_fc_host_lip = fnic_reset,
.get_fc_host_stats = fnic_get_stats,
.reset_fc_host_stats = fnic_reset_host_stats,
.dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
.terminate_rport_io = fnic_terminate_rport_io,
.bsg_request = fc_lport_bsg_request,
......@@ -206,13 +212,116 @@ static struct fc_host_statistics *fnic_get_stats(struct Scsi_Host *host)
stats->error_frames = vs->tx.tx_errors + vs->rx.rx_errors;
stats->dumped_frames = vs->tx.tx_drops + vs->rx.rx_drop;
stats->invalid_crc_count = vs->rx.rx_crc_errors;
stats->seconds_since_last_reset = (jiffies - lp->boot_time) / HZ;
stats->seconds_since_last_reset =
(jiffies - fnic->stats_reset_time) / HZ;
stats->fcp_input_megabytes = div_u64(fnic->fcp_input_bytes, 1000000);
stats->fcp_output_megabytes = div_u64(fnic->fcp_output_bytes, 1000000);
return stats;
}
/*
* fnic_dump_fchost_stats
* note : dumps fc_statistics into system logs
*/
void fnic_dump_fchost_stats(struct Scsi_Host *host,
struct fc_host_statistics *stats)
{
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: seconds since last reset = %llu\n",
stats->seconds_since_last_reset);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: tx frames = %llu\n",
stats->tx_frames);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: tx words = %llu\n",
stats->tx_words);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: rx frames = %llu\n",
stats->rx_frames);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: rx words = %llu\n",
stats->rx_words);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: lip count = %llu\n",
stats->lip_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: nos count = %llu\n",
stats->nos_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: error frames = %llu\n",
stats->error_frames);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: dumped frames = %llu\n",
stats->dumped_frames);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: link failure count = %llu\n",
stats->link_failure_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: loss of sync count = %llu\n",
stats->loss_of_sync_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: loss of signal count = %llu\n",
stats->loss_of_signal_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: prim seq protocol err count = %llu\n",
stats->prim_seq_protocol_err_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: invalid tx word count= %llu\n",
stats->invalid_tx_word_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: invalid crc count = %llu\n",
stats->invalid_crc_count);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: fcp input requests = %llu\n",
stats->fcp_input_requests);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: fcp output requests = %llu\n",
stats->fcp_output_requests);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: fcp control requests = %llu\n",
stats->fcp_control_requests);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: fcp input megabytes = %llu\n",
stats->fcp_input_megabytes);
FNIC_MAIN_NOTE(KERN_NOTICE, host,
"fnic: fcp output megabytes = %llu\n",
stats->fcp_output_megabytes);
return;
}
/*
* fnic_reset_host_stats : clears host stats
* note : called when reset_statistics set under sysfs dir
*/
static void fnic_reset_host_stats(struct Scsi_Host *host)
{
int ret;
struct fc_lport *lp = shost_priv(host);
struct fnic *fnic = lport_priv(lp);
struct fc_host_statistics *stats;
unsigned long flags;
/* dump current stats, before clearing them */
stats = fnic_get_stats(host);
fnic_dump_fchost_stats(host, stats);
spin_lock_irqsave(&fnic->fnic_lock, flags);
ret = vnic_dev_stats_clear(fnic->vdev);
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
if (ret) {
FNIC_MAIN_DBG(KERN_DEBUG, fnic->lport->host,
"fnic: Reset vnic stats failed"
" 0x%x", ret);
return;
}
fnic->stats_reset_time = jiffies;
memset(stats, 0, sizeof(*stats));
return;
}
void fnic_log_q_error(struct fnic *fnic)
{
unsigned int i;
......@@ -447,13 +556,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
host->transportt = fnic_fc_transport;
err = scsi_init_shared_tag_map(host, FNIC_MAX_IO_REQ);
if (err) {
shost_printk(KERN_ERR, fnic->lport->host,
"Unable to alloc shared tag map\n");
goto err_out_free_hba;
}
/* Setup PCI resources */
pci_set_drvdata(pdev, fnic);
......@@ -476,10 +578,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
/* Query PCI controller on system for DMA addressing
* limitation for the device. Try 40-bit first, and
* limitation for the device. Try 64-bit first, and
* fail to 32-bit.
*/
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(40));
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
......@@ -496,10 +598,10 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_release_regions;
}
} else {
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
if (err) {
shost_printk(KERN_ERR, fnic->lport->host,
"Unable to obtain 40-bit DMA "
"Unable to obtain 64-bit DMA "
"for consistent allocations, aborting.\n");
goto err_out_release_regions;
}
......@@ -566,6 +668,22 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
"aborting.\n");
goto err_out_dev_close;
}
/* Configure Maximum Outstanding IO reqs*/
if (fnic->config.io_throttle_count != FNIC_UCSM_DFLT_THROTTLE_CNT_BLD) {
host->can_queue = min_t(u32, FNIC_MAX_IO_REQ,
max_t(u32, FNIC_MIN_IO_REQ,
fnic->config.io_throttle_count));
}
fnic->fnic_max_tag_id = host->can_queue;
err = scsi_init_shared_tag_map(host, fnic->fnic_max_tag_id);
if (err) {
shost_printk(KERN_ERR, fnic->lport->host,
"Unable to alloc shared tag map\n");
goto err_out_dev_close;
}
host->max_lun = fnic->config.luns_per_tgt;
host->max_id = FNIC_MAX_FCP_TARGET;
host->max_cmd_len = FCOE_MAX_CMD_LEN;
......@@ -719,6 +837,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
fc_lport_init_stats(lp);
fnic->stats_reset_time = jiffies;
fc_lport_config(lp);
......
......@@ -111,6 +111,12 @@ static inline spinlock_t *fnic_io_lock_hash(struct fnic *fnic,
return &fnic->io_req_lock[hash];
}
static inline spinlock_t *fnic_io_lock_tag(struct fnic *fnic,
int tag)
{
return &fnic->io_req_lock[tag & (FNIC_IO_LOCKS - 1)];
}
/*
* Unmap the data buffer and sense buffer for an io_req,
* also unmap and free the device-private scatter/gather list.
......@@ -730,7 +736,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
fcpio_tag_id_dec(&tag, &id);
icmnd_cmpl = &desc->u.icmnd_cmpl;
if (id >= FNIC_MAX_IO_REQ) {
if (id >= fnic->fnic_max_tag_id) {
shost_printk(KERN_ERR, fnic->lport->host,
"Tag out of range tag %x hdr status = %s\n",
id, fnic_fcpio_status_to_str(hdr_status));
......@@ -818,38 +824,6 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
if (icmnd_cmpl->flags & FCPIO_ICMND_CMPL_RESID_UNDER)
xfer_len -= icmnd_cmpl->residual;
/*
* If queue_full, then try to reduce queue depth for all
* LUNS on the target. Todo: this should be accompanied
* by a periodic queue_depth rampup based on successful
* IO completion.
*/
if (icmnd_cmpl->scsi_status == QUEUE_FULL) {
struct scsi_device *t_sdev;
int qd = 0;
shost_for_each_device(t_sdev, sc->device->host) {
if (t_sdev->id != sc->device->id)
continue;
if (t_sdev->queue_depth > 1) {
qd = scsi_track_queue_full
(t_sdev,
t_sdev->queue_depth - 1);
if (qd == -1)
qd = t_sdev->host->cmd_per_lun;
shost_printk(KERN_INFO,
fnic->lport->host,
"scsi[%d:%d:%d:%d"
"] queue full detected,"
"new depth = %d\n",
t_sdev->host->host_no,
t_sdev->channel,
t_sdev->id, t_sdev->lun,
t_sdev->queue_depth);
}
}
}
break;
case FCPIO_TIMEOUT: /* request was timed out */
......@@ -939,7 +913,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag);
fcpio_tag_id_dec(&tag, &id);
if ((id & FNIC_TAG_MASK) >= FNIC_MAX_IO_REQ) {
if ((id & FNIC_TAG_MASK) >= fnic->fnic_max_tag_id) {
shost_printk(KERN_ERR, fnic->lport->host,
"Tag out of range tag %x hdr status = %s\n",
id, fnic_fcpio_status_to_str(hdr_status));
......@@ -988,9 +962,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
spin_unlock_irqrestore(io_lock, flags);
return;
}
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
CMD_ABTS_STATUS(sc) = hdr_status;
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"abts cmpl recd. id %d status %s\n",
......@@ -1148,23 +1120,25 @@ int fnic_wq_copy_cmpl_handler(struct fnic *fnic, int copy_work_to_do)
static void fnic_cleanup_io(struct fnic *fnic, int exclude_id)
{
unsigned int i;
int i;
struct fnic_io_req *io_req;
unsigned long flags = 0;
struct scsi_cmnd *sc;
spinlock_t *io_lock;
unsigned long start_time = 0;
for (i = 0; i < FNIC_MAX_IO_REQ; i++) {
for (i = 0; i < fnic->fnic_max_tag_id; i++) {
if (i == exclude_id)
continue;
io_lock = fnic_io_lock_tag(fnic, i);
spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, i);
if (!sc)
if (!sc) {
spin_unlock_irqrestore(io_lock, flags);
continue;
}
io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc);
if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) &&
!(CMD_FLAGS(sc) & FNIC_DEV_RST_DONE)) {
......@@ -1236,7 +1210,7 @@ void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
fcpio_tag_id_dec(&desc->hdr.tag, &id);
id &= FNIC_TAG_MASK;
if (id >= FNIC_MAX_IO_REQ)
if (id >= fnic->fnic_max_tag_id)
return;
sc = scsi_host_find_tag(fnic->lport->host, id);
......@@ -1340,14 +1314,15 @@ static void fnic_rport_exch_reset(struct fnic *fnic, u32 port_id)
if (fnic->in_remove)
return;
for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) {
abt_tag = tag;
io_lock = fnic_io_lock_tag(fnic, tag);
spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, tag);
if (!sc)
if (!sc) {
spin_unlock_irqrestore(io_lock, flags);
continue;
io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags);
}
io_req = (struct fnic_io_req *)CMD_SP(sc);
......@@ -1441,12 +1416,29 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
unsigned long flags;
struct scsi_cmnd *sc;
struct scsi_lun fc_lun;
struct fc_rport_libfc_priv *rdata = rport->dd_data;
struct fc_lport *lport = rdata->local_port;
struct fnic *fnic = lport_priv(lport);
struct fc_rport_libfc_priv *rdata;
struct fc_lport *lport;
struct fnic *fnic;
struct fc_rport *cmd_rport;
enum fnic_ioreq_state old_ioreq_state;
if (!rport) {
printk(KERN_ERR "fnic_terminate_rport_io: rport is NULL\n");
return;
}
rdata = rport->dd_data;
if (!rdata) {
printk(KERN_ERR "fnic_terminate_rport_io: rdata is NULL\n");
return;
}
lport = rdata->local_port;
if (!lport) {
printk(KERN_ERR "fnic_terminate_rport_io: lport is NULL\n");
return;
}
fnic = lport_priv(lport);
FNIC_SCSI_DBG(KERN_DEBUG,
fnic->lport->host, "fnic_terminate_rport_io called"
" wwpn 0x%llx, wwnn0x%llx, rport 0x%p, portid 0x%06x\n",
......@@ -1456,18 +1448,21 @@ void fnic_terminate_rport_io(struct fc_rport *rport)
if (fnic->in_remove)
return;
for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) {
abt_tag = tag;
io_lock = fnic_io_lock_tag(fnic, tag);
spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, tag);
if (!sc)
if (!sc) {
spin_unlock_irqrestore(io_lock, flags);
continue;
}
cmd_rport = starget_to_rport(scsi_target(sc->device));
if (rport != cmd_rport)
if (rport != cmd_rport) {
spin_unlock_irqrestore(io_lock, flags);
continue;
io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags);
}
io_req = (struct fnic_io_req *)CMD_SP(sc);
......@@ -1680,13 +1675,15 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
io_req->abts_done = NULL;
/* fw did not complete abort, timed out */
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) {
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) {
spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT;
ret = FAILED;
goto fnic_abort_cmd_end;
}
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
/*
* firmware completed the abort, check the status,
* free the io_req irrespective of failure or success
......@@ -1784,17 +1781,18 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
DECLARE_COMPLETION_ONSTACK(tm_done);
enum fnic_ioreq_state old_ioreq_state;
for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
for (tag = 0; tag < fnic->fnic_max_tag_id; tag++) {
io_lock = fnic_io_lock_tag(fnic, tag);
spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, tag);
/*
* ignore this lun reset cmd or cmds that do not belong to