Skip to content

Commit

Permalink
Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/jejb/scsi

Pull SCSI fixes from James Bottomley:
 "This is mostly fixes for driver specific issues (nine of them) and the
  storvsc performance improvement with interrupt handling which was
  dropped from the previous fixes pull request.

  We also have two regressions: one is a double call_rcu() in ATA error
  handling and the other is a missed conversion to BLK_STS_OK in
  __scsi_error_from_host_byte()"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: qedi: Fix kernel crash during port toggle
  scsi: qla2xxx: Fix FC-NVMe LUN discovery
  scsi: core: return BLK_STS_OK for DID_OK in __scsi_error_from_host_byte()
  scsi: core: Avoid that ATA error handling can trigger a kernel hang or oops
  scsi: qla2xxx: ensure async flags are reset correctly
  scsi: qla2xxx: do not check login_state if no loop id is assigned
  scsi: qla2xxx: Fixup locking for session deletion
  scsi: qla2xxx: Fix NULL pointer crash due to active timer for ABTS
  scsi: mpt3sas: wait for and flush running commands on shutdown/unload
  scsi: mpt3sas: fix oops in error handlers after shutdown/unload
  scsi: storvsc: Spread interrupts when picking a channel for I/O requests
  scsi: megaraid_sas: Do not use 32-bit atomic request descriptor for Ventura controllers
  • Loading branch information
Linus Torvalds committed Mar 7, 2018
2 parents 86f8477 + 967823d commit be75b1b
Show file tree
Hide file tree
Showing 16 changed files with 115 additions and 76 deletions.
3 changes: 0 additions & 3 deletions drivers/scsi/hosts.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,6 @@ static void scsi_host_dev_release(struct device *dev)
if (shost->work_q)
destroy_workqueue(shost->work_q);

destroy_rcu_head(&shost->rcu);

if (shost->shost_state == SHOST_CREATED) {
/*
* Free the shost_dev device name here if scsi_host_alloc()
Expand Down Expand Up @@ -404,7 +402,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
INIT_LIST_HEAD(&shost->starved_list);
init_waitqueue_head(&shost->host_wait);
mutex_init(&shost->scan_mutex);
init_rcu_head(&shost->rcu);

index = ida_simple_get(&host_index_ida, 0, 0, GFP_KERNEL);
if (index < 0)
Expand Down
42 changes: 14 additions & 28 deletions drivers/scsi/megaraid/megaraid_sas_fusion.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,36 +216,30 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance,
/**
* megasas_fire_cmd_fusion - Sends command to the FW
* @instance: Adapter soft state
* @req_desc: 32bit or 64bit Request descriptor
* @req_desc: 64bit Request descriptor
*
* Perform PCI Write. Ventura supports 32 bit Descriptor.
* Prior to Ventura (12G) MR controller supports 64 bit Descriptor.
* Perform PCI Write.
*/

static void
megasas_fire_cmd_fusion(struct megasas_instance *instance,
union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc)
{
if (instance->adapter_type == VENTURA_SERIES)
writel(le32_to_cpu(req_desc->u.low),
&instance->reg_set->inbound_single_queue_port);
else {
#if defined(writeq) && defined(CONFIG_64BIT)
u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
le32_to_cpu(req_desc->u.low));
u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) |
le32_to_cpu(req_desc->u.low));

writeq(req_data, &instance->reg_set->inbound_low_queue_port);
writeq(req_data, &instance->reg_set->inbound_low_queue_port);
#else
unsigned long flags;
spin_lock_irqsave(&instance->hba_lock, flags);
writel(le32_to_cpu(req_desc->u.low),
&instance->reg_set->inbound_low_queue_port);
writel(le32_to_cpu(req_desc->u.high),
&instance->reg_set->inbound_high_queue_port);
mmiowb();
spin_unlock_irqrestore(&instance->hba_lock, flags);
unsigned long flags;
spin_lock_irqsave(&instance->hba_lock, flags);
writel(le32_to_cpu(req_desc->u.low),
&instance->reg_set->inbound_low_queue_port);
writel(le32_to_cpu(req_desc->u.high),
&instance->reg_set->inbound_high_queue_port);
mmiowb();
spin_unlock_irqrestore(&instance->hba_lock, flags);
#endif
}
}

/**
Expand Down Expand Up @@ -982,7 +976,6 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
const char *sys_info;
MFI_CAPABILITIES *drv_ops;
u32 scratch_pad_2;
unsigned long flags;
ktime_t time;
bool cur_fw_64bit_dma_capable;

Expand Down Expand Up @@ -1121,14 +1114,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance)
break;
}

/* For Ventura also IOC INIT required 64 bit Descriptor write. */
spin_lock_irqsave(&instance->hba_lock, flags);
writel(le32_to_cpu(req_desc.u.low),
&instance->reg_set->inbound_low_queue_port);
writel(le32_to_cpu(req_desc.u.high),
&instance->reg_set->inbound_high_queue_port);
mmiowb();
spin_unlock_irqrestore(&instance->hba_lock, flags);
megasas_fire_cmd_fusion(instance, &req_desc);

wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS);

Expand Down
8 changes: 4 additions & 4 deletions drivers/scsi/mpt3sas/mpt3sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -6297,14 +6297,14 @@ _base_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
}

/**
* _wait_for_commands_to_complete - reset controller
* mpt3sas_wait_for_commands_to_complete - reset controller
* @ioc: Pointer to MPT_ADAPTER structure
*
* This function is waiting 10s for all pending commands to complete
* prior to putting controller in reset.
*/
static void
_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
void
mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc)
{
u32 ioc_state;

Expand Down Expand Up @@ -6377,7 +6377,7 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
is_fault = 1;
}
_base_reset_handler(ioc, MPT3_IOC_PRE_RESET);
_wait_for_commands_to_complete(ioc);
mpt3sas_wait_for_commands_to_complete(ioc);
_base_mask_interrupts(ioc);
r = _base_make_ioc_ready(ioc, type);
if (r)
Expand Down
3 changes: 3 additions & 0 deletions drivers/scsi/mpt3sas/mpt3sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,9 @@ void mpt3sas_base_update_missing_delay(struct MPT3SAS_ADAPTER *ioc,

int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);

void
mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);


/* scsih shared API */
struct scsi_cmnd *mpt3sas_scsih_scsi_lookup_get(struct MPT3SAS_ADAPTER *ioc,
Expand Down
21 changes: 16 additions & 5 deletions drivers/scsi/mpt3sas/mpt3sas_scsih.c
Original file line number Diff line number Diff line change
Expand Up @@ -2835,7 +2835,8 @@ scsih_abort(struct scsi_cmnd *scmd)
_scsih_tm_display_info(ioc, scmd);

sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
ioc->remove_host) {
sdev_printk(KERN_INFO, scmd->device,
"device been deleted! scmd(%p)\n", scmd);
scmd->result = DID_NO_CONNECT << 16;
Expand Down Expand Up @@ -2898,7 +2899,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
_scsih_tm_display_info(ioc, scmd);

sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
ioc->remove_host) {
sdev_printk(KERN_INFO, scmd->device,
"device been deleted! scmd(%p)\n", scmd);
scmd->result = DID_NO_CONNECT << 16;
Expand Down Expand Up @@ -2961,7 +2963,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
_scsih_tm_display_info(ioc, scmd);

sas_device_priv_data = scmd->device->hostdata;
if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
if (!sas_device_priv_data || !sas_device_priv_data->sas_target ||
ioc->remove_host) {
starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
scmd);
scmd->result = DID_NO_CONNECT << 16;
Expand Down Expand Up @@ -3019,7 +3022,7 @@ scsih_host_reset(struct scsi_cmnd *scmd)
ioc->name, scmd);
scsi_print_command(scmd);

if (ioc->is_driver_loading) {
if (ioc->is_driver_loading || ioc->remove_host) {
pr_info(MPT3SAS_FMT "Blocking the host reset\n",
ioc->name);
r = FAILED;
Expand Down Expand Up @@ -4453,7 +4456,7 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
st = scsi_cmd_priv(scmd);
mpt3sas_base_clear_st(ioc, st);
scsi_dma_unmap(scmd);
if (ioc->pci_error_recovery)
if (ioc->pci_error_recovery || ioc->remove_host)
scmd->result = DID_NO_CONNECT << 16;
else
scmd->result = DID_RESET << 16;
Expand Down Expand Up @@ -9739,6 +9742,10 @@ static void scsih_remove(struct pci_dev *pdev)
unsigned long flags;

ioc->remove_host = 1;

mpt3sas_wait_for_commands_to_complete(ioc);
_scsih_flush_running_cmds(ioc);

_scsih_fw_event_cleanup_queue(ioc);

spin_lock_irqsave(&ioc->fw_event_lock, flags);
Expand Down Expand Up @@ -9815,6 +9822,10 @@ scsih_shutdown(struct pci_dev *pdev)
unsigned long flags;

ioc->remove_host = 1;

mpt3sas_wait_for_commands_to_complete(ioc);
_scsih_flush_running_cmds(ioc);

_scsih_fw_event_cleanup_queue(ioc);

spin_lock_irqsave(&ioc->fw_event_lock, flags);
Expand Down
5 changes: 5 additions & 0 deletions drivers/scsi/qedi/qedi_fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,11 @@ static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi,

iscsi_cid = cqe->conn_id;
qedi_conn = qedi->cid_que.conn_cid_tbl[iscsi_cid];
if (!qedi_conn) {
QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO,
"icid not found 0x%x\n", cqe->conn_id);
return;
}

/* Based on this itt get the corresponding qedi_cmd */
spin_lock_bh(&qedi_conn->tmf_work_lock);
Expand Down
5 changes: 3 additions & 2 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@
struct name_list_extended {
struct get_name_list_extended *l;
dma_addr_t ldma;
struct list_head fcports; /* protect by sess_list */
struct list_head fcports;
spinlock_t fcports_lock;
u32 size;
u8 sent;
};
/*
* Timeout timer counts in seconds
Expand Down Expand Up @@ -2217,6 +2217,7 @@ typedef struct {

/* FCP-4 types */
#define FC4_TYPE_FCP_SCSI 0x08
#define FC4_TYPE_NVME 0x28
#define FC4_TYPE_OTHER 0x0
#define FC4_TYPE_UNKNOWN 0xff

Expand Down
5 changes: 5 additions & 0 deletions drivers/scsi/qla2xxx/qla_gs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3179,6 +3179,7 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return rval;
}

Expand Down Expand Up @@ -3370,6 +3371,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
sp->free(sp);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
fcport->flags &= ~FCF_ASYNC_ACTIVE;
return rval;
}

Expand Down Expand Up @@ -3971,6 +3973,9 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);

if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled)
qla24xx_async_gpnft(vha, FC4_TYPE_NVME);
}

static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
Expand Down
Loading

0 comments on commit be75b1b

Please sign in to comment.