Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be75b1b8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 86f84779 967823d6
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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()
@@ -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)
+14 −28
Original line number Diff line number Diff line
@@ -216,20 +216,15 @@ 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));
@@ -246,7 +241,6 @@ megasas_fire_cmd_fusion(struct megasas_instance *instance,
	spin_unlock_irqrestore(&instance->hba_lock, flags);
#endif
}
}

/**
 * megasas_fusion_update_can_queue -	Do all Adapter Queue depth related calculations here
@@ -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;

@@ -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);

+4 −4
Original line number Diff line number Diff line
@@ -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;

@@ -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)
+3 −0
Original line number Diff line number Diff line
@@ -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,
+16 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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);
@@ -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);
Loading