Commit dafde947 authored by Mahesh Rajashekhara's avatar Mahesh Rajashekhara Committed by James Bottomley
Browse files

aacraid: IOP RESET command handling changes



This patch fixes the IOP_RESET issue. Sending IOP_RESET command need to wait
for only 10 sec instead of 5 minutes in case of firmware does not response
IOP_RESET command.  Disable interrupt before setup interrupt routine to
prevent spurious interrupts.

Signed-off-by: default avatarMahesh Rajashekhara <Mahesh.Rajashekhara@pmcs.com>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarMurthy Bhat <Murthy.Bhat@pmcs.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent a7129a54
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1216,6 +1216,7 @@ struct aac_dev
	int			sync_mode;
	struct fib		*sync_fib;
	struct list_head	sync_fib_list;
	u32			doorbell_mask;
	u32			max_msix;	/* max. MSI-X vectors */
	u32			vector_cap;	/* MSI-X vector capab.*/
	int			msi_enabled;	/* MSI/MSI-X enabled */
+3 −1
Original line number Diff line number Diff line
@@ -358,8 +358,10 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
	dev->raw_io_interface = dev->raw_io_64 = 0;

	if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
		0, 0, 0, 0, 0, 0, status+0, status+1, status+2, NULL, NULL)) &&
		0, 0, 0, 0, 0, 0,
		status+0, status+1, status+2, status+3, NULL)) &&
	 		(status[0] == 0x00000001)) {
		dev->doorbell_mask = status[3];
		if (status[1] & le32_to_cpu(AAC_OPT_NEW_COMM_64))
			dev->raw_io_64 = 1;
		dev->sync_mode = aac_sync_mode;
+27 −9
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
	u32 *status, u32 * r1, u32 * r2, u32 * r3, u32 * r4)
{
	unsigned long start;
	unsigned long delay;
	int ok;

	/*
@@ -246,10 +247,14 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command,
		ok = 0;
		start = jiffies;

		/*
		 *	Wait up to 5 minutes
		 */
		while (time_before(jiffies, start+300*HZ)) {
		if (command == IOP_RESET_ALWAYS) {
			/* Wait up to 10 sec */
			delay = 10*HZ;
		} else {
			/* Wait up to 5 minutes */
			delay = 300*HZ;
		}
		while (time_before(jiffies, start+delay)) {
			udelay(5);	/* Delay 5 microseconds to let Mon960 get info. */
			/*
			 *	Mon960 will set doorbell0 bit when it has completed the command.
@@ -574,10 +579,17 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
		if (bled)
			printk(KERN_ERR "%s%d: adapter kernel panic'd %x.\n",
				dev->name, dev->id, bled);
		dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
		bled = aac_adapter_sync_cmd(dev, IOP_RESET_ALWAYS,
			0, 0, 0, 0, 0, 0, &var, &reset_mask, NULL, NULL, NULL);
			if (bled || (var != 0x00000001))
		if ((bled || (var != 0x00000001)) &&
		    !dev->doorbell_mask)
			return -EINVAL;
		else if (dev->doorbell_mask) {
			reset_mask = dev->doorbell_mask;
			bled = 0;
			var = 0x00000001;
		}

		if ((dev->pdev->device == PMC_DEVICE_S7 ||
		    dev->pdev->device == PMC_DEVICE_S8 ||
@@ -587,10 +599,13 @@ static int aac_src_restart_adapter(struct aac_dev *dev, int bled)
			msleep(5000); /* Delay 5 seconds */
		}

		if (dev->supplement_adapter_info.SupportedOptions2 &
			AAC_OPTION_DOORBELL_RESET) {
		if (!bled && (dev->supplement_adapter_info.SupportedOptions2 &
		    AAC_OPTION_DOORBELL_RESET)) {
			src_writel(dev, MUnit.IDR, reset_mask);
			ssleep(45);
		} else {
			src_writel(dev, MUnit.IDR, 0x100);
			ssleep(45);
		}
	}

@@ -612,7 +627,6 @@ int aac_src_select_comm(struct aac_dev *dev, int comm)
{
	switch (comm) {
	case AAC_COMM_MESSAGE:
		dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;
		dev->a_ops.adapter_intr = aac_src_intr_message;
		dev->a_ops.adapter_deliver = aac_src_deliver_message;
		break;
@@ -710,6 +724,7 @@ int aac_src_init(struct aac_dev *dev)
	 */
	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
	dev->a_ops.adapter_notify = aac_src_notify_adapter;
	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
	dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -747,6 +762,7 @@ int aac_src_init(struct aac_dev *dev)
	dev->dbg_base = pci_resource_start(dev->pdev, 2);
	dev->dbg_base_mapped = dev->regs.src.bar1;
	dev->dbg_size = AAC_MIN_SRC_BAR1_SIZE;
	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;

	aac_adapter_enable_int(dev);

@@ -873,6 +889,7 @@ int aac_srcv_init(struct aac_dev *dev)
	 */
	dev->a_ops.adapter_interrupt = aac_src_interrupt_adapter;
	dev->a_ops.adapter_disable_int = aac_src_disable_interrupt;
	dev->a_ops.adapter_enable_int = aac_src_disable_interrupt;
	dev->a_ops.adapter_notify = aac_src_notify_adapter;
	dev->a_ops.adapter_sync_cmd = src_sync_cmd;
	dev->a_ops.adapter_check_health = aac_src_check_health;
@@ -930,6 +947,7 @@ int aac_srcv_init(struct aac_dev *dev)
	dev->dbg_base = dev->base_start;
	dev->dbg_base_mapped = dev->base;
	dev->dbg_size = dev->base_size;
	dev->a_ops.adapter_enable_int = aac_src_enable_interrupt_message;

	aac_adapter_enable_int(dev);