Commit 3467b907 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SCSI fixes from James Bottomley:
 "Thirteen fixes, seven of which are for IBM fibre channel and three
  additional for fairly serious bugs in drivers (qla2xxx, mpt3sas,
  aacraid).

  Of the three core fixes, the most significant is probably the missed
  run queue causing an indefinite hang. The others are fixing a
  potential use after free on device close and silencing an incorrect
  warning"

* tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi:
  scsi: ibmvfc: Clean up transport events
  scsi: ibmvfc: Byte swap status and error codes when logging
  scsi: ibmvfc: Add failed PRLI to cmd_status lookup array
  scsi: ibmvfc: Remove "failed" from logged errors
  scsi: zfcp: reduce flood of fcrscn1 trace records on multi-element RSCN
  scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP devices
  scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host
  scsi: sd: Quiesce warning if device does not report optimal I/O size
  scsi: sd: Fix a race between closing an sd device and sd I/O
  scsi: core: Run queue when state is set to running after being blocked
  scsi: qla4xxx: fix a potential NULL pointer dereference
  scsi: aacraid: Insure we don't access PCIe space during AER/EEH
  scsi: mpt3sas: Fix kernel panic during expander reset
parents 4ad52836 d6e2635b
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -624,6 +624,20 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
	add_timer(&erp_action->timer);
}

void zfcp_erp_port_forced_reopen_all(struct zfcp_adapter *adapter,
				     int clear, char *dbftag)
{
	unsigned long flags;
	struct zfcp_port *port;

	write_lock_irqsave(&adapter->erp_lock, flags);
	read_lock(&adapter->port_list_lock);
	list_for_each_entry(port, &adapter->port_list, list)
		_zfcp_erp_port_forced_reopen(port, clear, dbftag);
	read_unlock(&adapter->port_list_lock);
	write_unlock_irqrestore(&adapter->erp_lock, flags);
}

static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
				      int clear, char *dbftag)
{
@@ -1341,6 +1355,9 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port)
		struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
		int lun_status;

		if (sdev->sdev_state == SDEV_DEL ||
		    sdev->sdev_state == SDEV_CANCEL)
			continue;
		if (zsdev->port != port)
			continue;
		/* LUN under port of interest */
+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ extern void zfcp_erp_port_reopen(struct zfcp_port *port, int clear,
				 char *dbftag);
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *);
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *);
extern void zfcp_erp_port_forced_reopen_all(struct zfcp_adapter *adapter,
					    int clear, char *dbftag);
extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
extern void zfcp_erp_clear_lun_status(struct scsi_device *, u32);
extern void zfcp_erp_lun_reopen(struct scsi_device *, int, char *);
+17 −4
Original line number Diff line number Diff line
@@ -239,10 +239,6 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
	list_for_each_entry(port, &adapter->port_list, list) {
		if ((port->d_id & range) == (ntoh24(page->rscn_fid) & range))
			zfcp_fc_test_link(port);
		if (!port->d_id)
			zfcp_erp_port_reopen(port,
					     ZFCP_STATUS_COMMON_ERP_FAILED,
					     "fcrscn1");
	}
	read_unlock_irqrestore(&adapter->port_list_lock, flags);
}
@@ -250,6 +246,7 @@ static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
{
	struct fsf_status_read_buffer *status_buffer = (void *)fsf_req->data;
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct fc_els_rscn *head;
	struct fc_els_rscn_page *page;
	u16 i;
@@ -263,6 +260,22 @@ static void zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req)
	no_entries = be16_to_cpu(head->rscn_plen) /
		sizeof(struct fc_els_rscn_page);

	if (no_entries > 1) {
		/* handle failed ports */
		unsigned long flags;
		struct zfcp_port *port;

		read_lock_irqsave(&adapter->port_list_lock, flags);
		list_for_each_entry(port, &adapter->port_list, list) {
			if (port->d_id)
				continue;
			zfcp_erp_port_reopen(port,
					     ZFCP_STATUS_COMMON_ERP_FAILED,
					     "fcrscn1");
		}
		read_unlock_irqrestore(&adapter->port_list_lock, flags);
	}

	for (i = 1; i < no_entries; i++) {
		/* skip head and start with 1st element */
		page++;
+4 −0
Original line number Diff line number Diff line
@@ -368,6 +368,10 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
	int ret = SUCCESS, fc_ret;

	if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE)) {
		zfcp_erp_port_forced_reopen_all(adapter, 0, "schrh_p");
		zfcp_erp_wait(adapter);
	}
	zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
	zfcp_erp_wait(adapter);
	fc_ret = fc_block_scsi_eh(scpnt);
+6 −1
Original line number Diff line number Diff line
@@ -2640,9 +2640,14 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
	return capacity;
}

static inline int aac_pci_offline(struct aac_dev *dev)
{
	return pci_channel_offline(dev->pdev) || dev->handle_pci_error;
}

static inline int aac_adapter_check_health(struct aac_dev *dev)
{
	if (unlikely(pci_channel_offline(dev->pdev)))
	if (unlikely(aac_pci_offline(dev)))
		return -1;

	return (dev)->a_ops.adapter_check_health(dev);
Loading