Commit c5dfd106 authored by Don Brace's avatar Don Brace Committed by Martin K. Petersen
Browse files

scsi: hpsa: correct device resets

Correct a race condition that occurs between the reset handler and the
completion handler. There are times when the wait_event condition is
never met due to this race condition and the reset never completes.

The reset_pending field is NULL initially.

  t  Reset Handler Thread     Completion Thread
  -- --------------------     -----------------
  t1                          if (c->reset_pending)
  t2 c->reset_pending = dev;     if (atomic_dev_and_test(counter))
  t3 atomic_inc(counter)             wait_up_all(event_sync_wait_queue)
  t4
  t5 wait_event(...counter == 0)

Kernel.org Bugzilla:
           https://bugzilla.kernel.org/show_bug.cgi?id=1994350


           Bug 199435 - HPSA + P420i resetting logical Direct-Access
                        never complete

Reviewed-by: default avatarJustin Lindley <justin.lindley@microsemi.com>
Reviewed-by: default avatarDavid Carroll <david.carroll@microsemi.com>
Reviewed-by: default avatarScott Teel <scott.teel@microsemi.com>
Signed-off-by: default avatarDon Brace <don.brace@microsemi.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9e33f0d5
Loading
Loading
Loading
Loading
+85 −88
Original line number Original line Diff line number Diff line
@@ -346,11 +346,6 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c)
	return c->scsi_cmd == SCSI_CMD_IDLE;
	return c->scsi_cmd == SCSI_CMD_IDLE;
}
}


static inline bool hpsa_is_pending_event(struct CommandList *c)
{
	return c->reset_pending;
}

/* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
/* extract sense key, asc, and ascq from sense data.  -1 means invalid. */
static void decode_sense_data(const u8 *sense_data, int sense_data_len,
static void decode_sense_data(const u8 *sense_data, int sense_data_len,
			u8 *sense_key, u8 *asc, u8 *ascq)
			u8 *sense_key, u8 *asc, u8 *ascq)
@@ -1146,6 +1141,8 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,
{
{
	dial_down_lockup_detection_during_fw_flash(h, c);
	dial_down_lockup_detection_during_fw_flash(h, c);
	atomic_inc(&h->commands_outstanding);
	atomic_inc(&h->commands_outstanding);
	if (c->device)
		atomic_inc(&c->device->commands_outstanding);


	reply_queue = h->reply_map[raw_smp_processor_id()];
	reply_queue = h->reply_map[raw_smp_processor_id()];
	switch (c->cmd_type) {
	switch (c->cmd_type) {
@@ -1169,9 +1166,6 @@ static void __enqueue_cmd_and_start_io(struct ctlr_info *h,


static void enqueue_cmd_and_start_io(struct ctlr_info *h, struct CommandList *c)
static void enqueue_cmd_and_start_io(struct ctlr_info *h, struct CommandList *c)
{
{
	if (unlikely(hpsa_is_pending_event(c)))
		return finish_cmd(c);

	__enqueue_cmd_and_start_io(h, c, DEFAULT_REPLY_QUEUE);
	__enqueue_cmd_and_start_io(h, c, DEFAULT_REPLY_QUEUE);
}
}


@@ -2434,13 +2428,16 @@ static int handle_ioaccel_mode2_error(struct ctlr_info *h,
		break;
		break;
	}
	}


	if (dev->in_reset)
		retry = 0;

	return retry;	/* retry on raid path? */
	return retry;	/* retry on raid path? */
}
}


static void hpsa_cmd_resolve_events(struct ctlr_info *h,
static void hpsa_cmd_resolve_events(struct ctlr_info *h,
		struct CommandList *c)
		struct CommandList *c)
{
{
	bool do_wake = false;
	struct hpsa_scsi_dev_t *dev = c->device;


	/*
	/*
	 * Reset c->scsi_cmd here so that the reset handler will know
	 * Reset c->scsi_cmd here so that the reset handler will know
@@ -2449,26 +2446,13 @@ static void hpsa_cmd_resolve_events(struct ctlr_info *h,
	 */
	 */
	c->scsi_cmd = SCSI_CMD_IDLE;
	c->scsi_cmd = SCSI_CMD_IDLE;
	mb();	/* Declare command idle before checking for pending events. */
	mb();	/* Declare command idle before checking for pending events. */
	if (c->reset_pending) {
	if (dev) {
		unsigned long flags;
		atomic_dec(&dev->commands_outstanding);
		struct hpsa_scsi_dev_t *dev;
		if (dev->in_reset &&

			atomic_read(&dev->commands_outstanding) <= 0)
		/*
		 * There appears to be a reset pending; lock the lock and
		 * reconfirm.  If so, then decrement the count of outstanding
		 * commands and wake the reset command if this is the last one.
		 */
		spin_lock_irqsave(&h->lock, flags);
		dev = c->reset_pending;		/* Re-fetch under the lock. */
		if (dev && atomic_dec_and_test(&dev->reset_cmds_out))
			do_wake = true;
		c->reset_pending = NULL;
		spin_unlock_irqrestore(&h->lock, flags);
	}

	if (do_wake)
			wake_up_all(&h->event_sync_wait_queue);
			wake_up_all(&h->event_sync_wait_queue);
	}
	}
}


static void hpsa_cmd_resolve_and_free(struct ctlr_info *h,
static void hpsa_cmd_resolve_and_free(struct ctlr_info *h,
				      struct CommandList *c)
				      struct CommandList *c)
@@ -2516,6 +2500,11 @@ static void process_ioaccel2_completion(struct ctlr_info *h,
			dev->offload_to_be_enabled = 0;
			dev->offload_to_be_enabled = 0;
		}
		}


		if (dev->in_reset) {
			cmd->result = DID_RESET << 16;
			return hpsa_cmd_free_and_done(h, c, cmd);
		}

		return hpsa_retry_cmd(h, c);
		return hpsa_retry_cmd(h, c);
	}
	}


@@ -2621,10 +2610,6 @@ static void complete_scsi_command(struct CommandList *cp)
		return hpsa_cmd_free_and_done(h, cp, cmd);
		return hpsa_cmd_free_and_done(h, cp, cmd);
	}
	}


	if ((unlikely(hpsa_is_pending_event(cp))))
		if (cp->reset_pending)
			return hpsa_cmd_free_and_done(h, cp, cmd);

	if (cp->cmd_type == CMD_IOACCEL2)
	if (cp->cmd_type == CMD_IOACCEL2)
		return process_ioaccel2_completion(h, cp, cmd, dev);
		return process_ioaccel2_completion(h, cp, cmd, dev);


@@ -3074,7 +3059,7 @@ out:
	return rc;
	return rc;
}
}


static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
static int hpsa_send_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
	u8 reset_type, int reply_queue)
	u8 reset_type, int reply_queue)
{
{
	int rc = IO_OK;
	int rc = IO_OK;
@@ -3082,11 +3067,10 @@ static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
	struct ErrorInfo *ei;
	struct ErrorInfo *ei;


	c = cmd_alloc(h);
	c = cmd_alloc(h);

	c->device = dev;


	/* fill_cmd can't fail here, no data buffer to map. */
	/* fill_cmd can't fail here, no data buffer to map. */
	(void) fill_cmd(c, reset_type, h, NULL, 0, 0,
	(void) fill_cmd(c, reset_type, h, NULL, 0, 0, dev->scsi3addr, TYPE_MSG);
			scsi3addr, TYPE_MSG);
	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
	rc = hpsa_scsi_do_simple_cmd(h, c, reply_queue, NO_TIMEOUT);
	if (rc) {
	if (rc) {
		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
		dev_warn(&h->pdev->dev, "Failed to send reset command\n");
@@ -3164,9 +3148,8 @@ static bool hpsa_cmd_dev_match(struct ctlr_info *h, struct CommandList *c,
}
}


static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
	unsigned char *scsi3addr, u8 reset_type, int reply_queue)
	u8 reset_type, int reply_queue)
{
{
	int i;
	int rc = 0;
	int rc = 0;


	/* We can really only handle one reset at a time */
	/* We can really only handle one reset at a time */
@@ -3175,38 +3158,14 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
		return -EINTR;
		return -EINTR;
	}
	}


	BUG_ON(atomic_read(&dev->reset_cmds_out) != 0);
	rc = hpsa_send_reset(h, dev, reset_type, reply_queue);

	if (!rc) {
	for (i = 0; i < h->nr_cmds; i++) {
		/* incremented by sending the reset request */
		struct CommandList *c = h->cmd_pool + i;
		atomic_dec(&dev->commands_outstanding);
		int refcount = atomic_inc_return(&c->refcount);

		if (refcount > 1 && hpsa_cmd_dev_match(h, c, dev, scsi3addr)) {
			unsigned long flags;

			/*
			 * Mark the target command as having a reset pending,
			 * then lock a lock so that the command cannot complete
			 * while we're considering it.  If the command is not
			 * idle then count it; otherwise revoke the event.
			 */
			c->reset_pending = dev;
			spin_lock_irqsave(&h->lock, flags);	/* Implied MB */
			if (!hpsa_is_cmd_idle(c))
				atomic_inc(&dev->reset_cmds_out);
			else
				c->reset_pending = NULL;
			spin_unlock_irqrestore(&h->lock, flags);
		}

		cmd_free(h, c);
	}

	rc = hpsa_send_reset(h, scsi3addr, reset_type, reply_queue);
	if (!rc)
		wait_event(h->event_sync_wait_queue,
		wait_event(h->event_sync_wait_queue,
			atomic_read(&dev->reset_cmds_out) == 0 ||
			atomic_read(&dev->commands_outstanding) <= 0 ||
			lockup_detected(h));
			lockup_detected(h));
	}


	if (unlikely(lockup_detected(h))) {
	if (unlikely(lockup_detected(h))) {
		dev_warn(&h->pdev->dev,
		dev_warn(&h->pdev->dev,
@@ -3214,10 +3173,8 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev,
		rc = -ENODEV;
		rc = -ENODEV;
	}
	}


	if (unlikely(rc))
	if (!rc)
		atomic_set(&dev->reset_cmds_out, 0);
		rc = wait_for_device_to_become_ready(h, dev->scsi3addr, 0);
	else
		rc = wait_for_device_to_become_ready(h, scsi3addr, 0);


	mutex_unlock(&h->reset_mutex);
	mutex_unlock(&h->reset_mutex);
	return rc;
	return rc;
@@ -4846,6 +4803,9 @@ static int hpsa_scsi_ioaccel_direct_map(struct ctlr_info *h,


	c->phys_disk = dev;
	c->phys_disk = dev;


	if (dev->in_reset)
		return -1;

	return hpsa_scsi_ioaccel_queue_command(h, c, dev->ioaccel_handle,
	return hpsa_scsi_ioaccel_queue_command(h, c, dev->ioaccel_handle,
		cmd->cmnd, cmd->cmd_len, dev->scsi3addr, dev);
		cmd->cmnd, cmd->cmd_len, dev->scsi3addr, dev);
}
}
@@ -5031,6 +4991,11 @@ static int hpsa_scsi_ioaccel2_queue_command(struct ctlr_info *h,
	} else
	} else
		cp->sg_count = (u8) use_sg;
		cp->sg_count = (u8) use_sg;


	if (phys_disk->in_reset) {
		cmd->result = DID_RESET << 16;
		return -1;
	}

	enqueue_cmd_and_start_io(h, c);
	enqueue_cmd_and_start_io(h, c);
	return 0;
	return 0;
}
}
@@ -5048,6 +5013,9 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h,
	if (!c->scsi_cmd->device->hostdata)
	if (!c->scsi_cmd->device->hostdata)
		return -1;
		return -1;


	if (phys_disk->in_reset)
		return -1;

	/* Try to honor the device's queue depth */
	/* Try to honor the device's queue depth */
	if (atomic_inc_return(&phys_disk->ioaccel_cmds_out) >
	if (atomic_inc_return(&phys_disk->ioaccel_cmds_out) >
					phys_disk->queue_depth) {
					phys_disk->queue_depth) {
@@ -5131,6 +5099,9 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
	if (!dev)
	if (!dev)
		return -1;
		return -1;


	if (dev->in_reset)
		return -1;

	/* check for valid opcode, get LBA and block count */
	/* check for valid opcode, get LBA and block count */
	switch (cmd->cmnd[0]) {
	switch (cmd->cmnd[0]) {
	case WRITE_6:
	case WRITE_6:
@@ -5435,13 +5406,13 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
 */
 */
static int hpsa_ciss_submit(struct ctlr_info *h,
static int hpsa_ciss_submit(struct ctlr_info *h,
	struct CommandList *c, struct scsi_cmnd *cmd,
	struct CommandList *c, struct scsi_cmnd *cmd,
	unsigned char scsi3addr[])
	struct hpsa_scsi_dev_t *dev)
{
{
	cmd->host_scribble = (unsigned char *) c;
	cmd->host_scribble = (unsigned char *) c;
	c->cmd_type = CMD_SCSI;
	c->cmd_type = CMD_SCSI;
	c->scsi_cmd = cmd;
	c->scsi_cmd = cmd;
	c->Header.ReplyQueue = 0;  /* unused in simple mode */
	c->Header.ReplyQueue = 0;  /* unused in simple mode */
	memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
	memcpy(&c->Header.LUN.LunAddrBytes[0], &dev->scsi3addr[0], 8);
	c->Header.tag = cpu_to_le64((c->cmdindex << DIRECT_LOOKUP_SHIFT));
	c->Header.tag = cpu_to_le64((c->cmdindex << DIRECT_LOOKUP_SHIFT));


	/* Fill in the request block... */
	/* Fill in the request block... */
@@ -5492,6 +5463,12 @@ static int hpsa_ciss_submit(struct ctlr_info *h,
		hpsa_cmd_resolve_and_free(h, c);
		hpsa_cmd_resolve_and_free(h, c);
		return SCSI_MLQUEUE_HOST_BUSY;
		return SCSI_MLQUEUE_HOST_BUSY;
	}
	}

	if (dev->in_reset) {
		hpsa_cmd_resolve_and_free(h, c);
		return SCSI_MLQUEUE_HOST_BUSY;
	}

	enqueue_cmd_and_start_io(h, c);
	enqueue_cmd_and_start_io(h, c);
	/* the cmd'll come back via intr handler in complete_scsi_command()  */
	/* the cmd'll come back via intr handler in complete_scsi_command()  */
	return 0;
	return 0;
@@ -5543,8 +5520,7 @@ static inline void hpsa_cmd_partial_init(struct ctlr_info *h, int index,
}
}


static int hpsa_ioaccel_submit(struct ctlr_info *h,
static int hpsa_ioaccel_submit(struct ctlr_info *h,
		struct CommandList *c, struct scsi_cmnd *cmd,
		struct CommandList *c, struct scsi_cmnd *cmd)
		unsigned char *scsi3addr)
{
{
	struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
	struct hpsa_scsi_dev_t *dev = cmd->device->hostdata;
	int rc = IO_ACCEL_INELIGIBLE;
	int rc = IO_ACCEL_INELIGIBLE;
@@ -5552,6 +5528,9 @@ static int hpsa_ioaccel_submit(struct ctlr_info *h,
	if (!dev)
	if (!dev)
		return SCSI_MLQUEUE_HOST_BUSY;
		return SCSI_MLQUEUE_HOST_BUSY;


	if (dev->in_reset)
		return SCSI_MLQUEUE_HOST_BUSY;

	if (hpsa_simple_mode)
	if (hpsa_simple_mode)
		return IO_ACCEL_INELIGIBLE;
		return IO_ACCEL_INELIGIBLE;


@@ -5587,8 +5566,12 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
		cmd->result = DID_NO_CONNECT << 16;
		cmd->result = DID_NO_CONNECT << 16;
		return hpsa_cmd_free_and_done(c->h, c, cmd);
		return hpsa_cmd_free_and_done(c->h, c, cmd);
	}
	}
	if (c->reset_pending)

	if (dev->in_reset) {
		cmd->result = DID_RESET << 16;
		return hpsa_cmd_free_and_done(c->h, c, cmd);
		return hpsa_cmd_free_and_done(c->h, c, cmd);
	}

	if (c->cmd_type == CMD_IOACCEL2) {
	if (c->cmd_type == CMD_IOACCEL2) {
		struct ctlr_info *h = c->h;
		struct ctlr_info *h = c->h;
		struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
		struct io_accel2_cmd *c2 = &h->ioaccel2_cmd_pool[c->cmdindex];
@@ -5596,7 +5579,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)


		if (c2->error_data.serv_response ==
		if (c2->error_data.serv_response ==
				IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL) {
				IOACCEL2_STATUS_SR_TASK_COMP_SET_FULL) {
			rc = hpsa_ioaccel_submit(h, c, cmd, dev->scsi3addr);
			rc = hpsa_ioaccel_submit(h, c, cmd);
			if (rc == 0)
			if (rc == 0)
				return;
				return;
			if (rc == SCSI_MLQUEUE_HOST_BUSY) {
			if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -5612,7 +5595,7 @@ static void hpsa_command_resubmit_worker(struct work_struct *work)
		}
		}
	}
	}
	hpsa_cmd_partial_init(c->h, c->cmdindex, c);
	hpsa_cmd_partial_init(c->h, c->cmdindex, c);
	if (hpsa_ciss_submit(c->h, c, cmd, dev->scsi3addr)) {
	if (hpsa_ciss_submit(c->h, c, cmd, dev)) {
		/*
		/*
		 * If we get here, it means dma mapping failed. Try
		 * If we get here, it means dma mapping failed. Try
		 * again via scsi mid layer, which will then get
		 * again via scsi mid layer, which will then get
@@ -5631,7 +5614,6 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
{
{
	struct ctlr_info *h;
	struct ctlr_info *h;
	struct hpsa_scsi_dev_t *dev;
	struct hpsa_scsi_dev_t *dev;
	unsigned char scsi3addr[8];
	struct CommandList *c;
	struct CommandList *c;
	int rc = 0;
	int rc = 0;


@@ -5653,13 +5635,15 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
		return 0;
		return 0;
	}
	}


	memcpy(scsi3addr, dev->scsi3addr, sizeof(scsi3addr));

	if (unlikely(lockup_detected(h))) {
	if (unlikely(lockup_detected(h))) {
		cmd->result = DID_NO_CONNECT << 16;
		cmd->result = DID_NO_CONNECT << 16;
		cmd->scsi_done(cmd);
		cmd->scsi_done(cmd);
		return 0;
		return 0;
	}
	}

	if (dev->in_reset)
		return SCSI_MLQUEUE_DEVICE_BUSY;

	c = cmd_tagged_alloc(h, cmd);
	c = cmd_tagged_alloc(h, cmd);
	if (c == NULL)
	if (c == NULL)
		return SCSI_MLQUEUE_DEVICE_BUSY;
		return SCSI_MLQUEUE_DEVICE_BUSY;
@@ -5671,7 +5655,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
	if (likely(cmd->retries == 0 &&
	if (likely(cmd->retries == 0 &&
			!blk_rq_is_passthrough(cmd->request) &&
			!blk_rq_is_passthrough(cmd->request) &&
			h->acciopath_status)) {
			h->acciopath_status)) {
		rc = hpsa_ioaccel_submit(h, c, cmd, scsi3addr);
		rc = hpsa_ioaccel_submit(h, c, cmd);
		if (rc == 0)
		if (rc == 0)
			return 0;
			return 0;
		if (rc == SCSI_MLQUEUE_HOST_BUSY) {
		if (rc == SCSI_MLQUEUE_HOST_BUSY) {
@@ -5679,7 +5663,7 @@ static int hpsa_scsi_queue_command(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
			return SCSI_MLQUEUE_HOST_BUSY;
			return SCSI_MLQUEUE_HOST_BUSY;
		}
		}
	}
	}
	return hpsa_ciss_submit(h, c, cmd, scsi3addr);
	return hpsa_ciss_submit(h, c, cmd, dev);
}
}


static void hpsa_scan_complete(struct ctlr_info *h)
static void hpsa_scan_complete(struct ctlr_info *h)
@@ -5961,6 +5945,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
{
{
	int rc = SUCCESS;
	int rc = SUCCESS;
	int i;
	struct ctlr_info *h;
	struct ctlr_info *h;
	struct hpsa_scsi_dev_t *dev;
	struct hpsa_scsi_dev_t *dev;
	u8 reset_type;
	u8 reset_type;
@@ -6028,9 +6013,19 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
		reset_type == HPSA_DEVICE_RESET_MSG ? "logical " : "physical ");
	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
	hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);


	/*
	 * wait to see if any commands will complete before sending reset
	 */
	dev->in_reset = true; /* block any new cmds from OS for this device */
	for (i = 0; i < 10; i++) {
		if (atomic_read(&dev->commands_outstanding) > 0)
			msleep(1000);
		else
			break;
	}

	/* send a reset to the SCSI LUN which the command was sent to */
	/* send a reset to the SCSI LUN which the command was sent to */
	rc = hpsa_do_reset(h, dev, dev->scsi3addr, reset_type,
	rc = hpsa_do_reset(h, dev, reset_type, DEFAULT_REPLY_QUEUE);
			   DEFAULT_REPLY_QUEUE);
	if (rc == 0)
	if (rc == 0)
		rc = SUCCESS;
		rc = SUCCESS;
	else
	else
@@ -6044,6 +6039,8 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
return_reset_status:
return_reset_status:
	spin_lock_irqsave(&h->reset_lock, flags);
	spin_lock_irqsave(&h->reset_lock, flags);
	h->reset_in_progress = 0;
	h->reset_in_progress = 0;
	if (dev)
		dev->in_reset = false;
	spin_unlock_irqrestore(&h->reset_lock, flags);
	spin_unlock_irqrestore(&h->reset_lock, flags);
	return rc;
	return rc;
}
}
@@ -6157,6 +6154,7 @@ static struct CommandList *cmd_alloc(struct ctlr_info *h)
		break; /* it's ours now. */
		break; /* it's ours now. */
	}
	}
	hpsa_cmd_partial_init(h, i, c);
	hpsa_cmd_partial_init(h, i, c);
	c->device = NULL;
	return c;
	return c;
}
}


@@ -6610,8 +6608,7 @@ static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
	}
	}
}
}


static void hpsa_send_host_reset(struct ctlr_info *h, unsigned char *scsi3addr,
static void hpsa_send_host_reset(struct ctlr_info *h, u8 reset_type)
				u8 reset_type)
{
{
	struct CommandList *c;
	struct CommandList *c;


@@ -8105,7 +8102,7 @@ static int hpsa_request_irqs(struct ctlr_info *h,
static int hpsa_kdump_soft_reset(struct ctlr_info *h)
static int hpsa_kdump_soft_reset(struct ctlr_info *h)
{
{
	int rc;
	int rc;
	hpsa_send_host_reset(h, RAID_CTLR_LUNID, HPSA_RESET_TYPE_CONTROLLER);
	hpsa_send_host_reset(h, HPSA_RESET_TYPE_CONTROLLER);


	dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
	dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
	rc = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY);
	rc = hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY);
+2 −1
Original line number Original line Diff line number Diff line
@@ -76,11 +76,12 @@ struct hpsa_scsi_dev_t {
	unsigned char raid_level;	/* from inquiry page 0xC1 */
	unsigned char raid_level;	/* from inquiry page 0xC1 */
	unsigned char volume_offline;	/* discovered via TUR or VPD */
	unsigned char volume_offline;	/* discovered via TUR or VPD */
	u16 queue_depth;		/* max queue_depth for this device */
	u16 queue_depth;		/* max queue_depth for this device */
	atomic_t reset_cmds_out;	/* Count of commands to-be affected */
	atomic_t commands_outstanding;	/* track commands sent to device */
	atomic_t ioaccel_cmds_out;	/* Only used for physical devices
	atomic_t ioaccel_cmds_out;	/* Only used for physical devices
					 * counts commands sent to physical
					 * counts commands sent to physical
					 * device via "ioaccel" path.
					 * device via "ioaccel" path.
					 */
					 */
	bool in_reset;
	u32 ioaccel_handle;
	u32 ioaccel_handle;
	u8 active_path_index;
	u8 active_path_index;
	u8 path_map;
	u8 path_map;
+1 −1
Original line number Original line Diff line number Diff line
@@ -448,7 +448,7 @@ struct CommandList {
	struct hpsa_scsi_dev_t *phys_disk;
	struct hpsa_scsi_dev_t *phys_disk;


	int abort_pending;
	int abort_pending;
	struct hpsa_scsi_dev_t *reset_pending;
	struct hpsa_scsi_dev_t *device;
	atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */
	atomic_t refcount; /* Must be last to avoid memset in hpsa_cmd_init() */
} __aligned(COMMANDLIST_ALIGNMENT);
} __aligned(COMMANDLIST_ALIGNMENT);