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

Commit d29aadda authored by Kenji Kaneshige's avatar Kenji Kaneshige Committed by Greg Kroah-Hartman
Browse files

[PATCH] shpchp - cleanup check command status



This patch cleanups codes that check the command status. For this, it
introduces a new semaphore "cmd_sem" for each controller.

Signed-off-by: default avatarKenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent a4534560
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ struct event_info {
struct controller {
	struct list_head ctrl_list;
	struct mutex crit_sect;		/* critical section mutex */
	struct mutex cmd_lock;		/* command lock */
	struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
	int num_slots;			/* Number of slots on ctlr */
	int slot_num_inc;		/* 1 or -1 */
+1 −119
Original line number Diff line number Diff line
@@ -242,21 +242,10 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
	int rc = 0;

	dbg("%s: change to speed %d\n", __FUNCTION__, speed);
	mutex_lock(&ctrl->crit_sect);
	if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
		err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
		mutex_unlock(&ctrl->crit_sect);
		return WRONG_BUS_FREQUENCY;
	}
		
	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
		err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
			  __FUNCTION__);
		err("%s: Error code (%d)\n", __FUNCTION__, rc);
		mutex_unlock(&ctrl->crit_sect);
		return WRONG_BUS_FREQUENCY;
	}
	mutex_unlock(&ctrl->crit_sect);
	return rc;
}

@@ -330,15 +319,6 @@ static int board_added(struct slot *p_slot)
		return -1;
	}
	
	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
	if (rc) {
		err("%s: Failed to power on slot, error code(%d)\n", __FUNCTION__, rc);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return -1;
	}

	
	if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
		if (slots_not_empty)
			return WRONG_BUS_FREQUENCY;
@@ -349,25 +329,12 @@ static int board_added(struct slot *p_slot)
			return WRONG_BUS_FREQUENCY;
		}
		
		if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
			err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
				  __FUNCTION__);
			err("%s: Error code (%d)\n", __FUNCTION__, rc);
			mutex_unlock(&ctrl->crit_sect);
			return WRONG_BUS_FREQUENCY;
		}
		/* turn on board, blink green LED, turn off Amber LED */
		if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
			err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
			mutex_unlock(&ctrl->crit_sect);
			return rc;
		}

		if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
			err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
			mutex_unlock(&ctrl->crit_sect);
			return rc;  
		}
	}
 
	rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
@@ -481,22 +448,12 @@ static int board_added(struct slot *p_slot)
				return rc;
	}

	mutex_lock(&ctrl->crit_sect);
	/* turn on board, blink green LED, turn off Amber LED */
	if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
		err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
		err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	mutex_unlock(&ctrl->crit_sect);

	/* Wait for ~1 second */
	wait_for_ctrl_irq (ctrl);

@@ -520,40 +477,18 @@ static int board_added(struct slot *p_slot)
	p_slot->is_a_board = 0x01;
	p_slot->pwr_save = 1;

	/* Wait for exclusive access to hardware */
	mutex_lock(&ctrl->crit_sect);

	p_slot->hpc_ops->green_led_on(p_slot);

	/* Done with exclusive hardware access */
	mutex_unlock(&ctrl->crit_sect);

	return 0;

err_exit:
	/* Wait for exclusive access to hardware */
	mutex_lock(&ctrl->crit_sect);

	/* turn off slot, turn on Amber LED, turn off Green LED */
	rc = p_slot->hpc_ops->slot_disable(p_slot);
	if (rc) {
		err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
	if (rc) {
		err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	/* Done with exclusive hardware access */
	mutex_unlock(&ctrl->crit_sect);

	return(rc);
}

@@ -580,37 +515,19 @@ static int remove_board(struct slot *p_slot)
	if (p_slot->is_a_board)
		p_slot->status = 0x01;

	/* Wait for exclusive access to hardware */
	mutex_lock(&ctrl->crit_sect);

	/* turn off slot, turn on Amber LED, turn off Green LED */
	rc = p_slot->hpc_ops->slot_disable(p_slot);
	if (rc) {
		err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	rc = p_slot->hpc_ops->check_cmd_status(ctrl);
	if (rc) {
		err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}
	
	rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
	if (rc) {
		err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
		/* Done with exclusive hardware access */
		mutex_unlock(&ctrl->crit_sect);
		return rc;
	}

	/* Done with exclusive hardware access */
	mutex_unlock(&ctrl->crit_sect);

	p_slot->pwr_save = 0;
	p_slot->is_a_board = 0;

@@ -654,15 +571,9 @@ static void shpchp_pushbutton_thread (unsigned long slot)
	} else {
		p_slot->state = POWERON_STATE;

		if (shpchp_enable_slot(p_slot)) {
			/* Wait for exclusive access to hardware */
			mutex_lock(&p_slot->ctrl->crit_sect);

		if (shpchp_enable_slot(p_slot))
			p_slot->hpc_ops->green_led_off(p_slot);

			/* Done with exclusive hardware access */
			mutex_unlock(&p_slot->ctrl->crit_sect);
		}
		p_slot->state = STATIC_STATE;
	}

@@ -767,27 +678,12 @@ static void interrupt_event_handler(struct controller *ctrl)

					switch (p_slot->state) {
					case BLINKINGOFF_STATE:
						/* Wait for exclusive access to hardware */
						mutex_lock(&ctrl->crit_sect);

						p_slot->hpc_ops->green_led_on(p_slot);

						p_slot->hpc_ops->set_attention_status(p_slot, 0);

						/* Done with exclusive hardware access */
						mutex_unlock(&ctrl->crit_sect);
						break;
					case BLINKINGON_STATE:
						/* Wait for exclusive access to hardware */
						mutex_lock(&ctrl->crit_sect);

						p_slot->hpc_ops->green_led_off(p_slot);

						p_slot->hpc_ops->set_attention_status(p_slot, 0);

						/* Done with exclusive hardware access */
						mutex_unlock(&ctrl->crit_sect);

						break;
					default:
						warn("Not a valid state\n");
@@ -812,17 +708,10 @@ static void interrupt_event_handler(struct controller *ctrl)
						info(msg_button_on, p_slot->number);
					}

					/* Wait for exclusive access to hardware */
					mutex_lock(&ctrl->crit_sect);

					/* blink green LED and turn off amber */
					p_slot->hpc_ops->green_led_blink(p_slot);
					
					p_slot->hpc_ops->set_attention_status(p_slot, 0);

					/* Done with exclusive hardware access */
					mutex_unlock(&ctrl->crit_sect);

					init_timer(&p_slot->task_event);
					p_slot->task_event.expires = jiffies + 5 * HZ;   /* 5 second delay */
					p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread;
@@ -833,15 +722,8 @@ static void interrupt_event_handler(struct controller *ctrl)
				} else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) {
					/***********POWER FAULT********************/
					dbg("%s: power fault\n", __FUNCTION__);
					/* Wait for exclusive access to hardware */
					mutex_lock(&ctrl->crit_sect);

					p_slot->hpc_ops->set_attention_status(p_slot, 1);
					
					p_slot->hpc_ops->green_led_off(p_slot);

					/* Done with exclusive hardware access */
					mutex_unlock(&ctrl->crit_sect);
				} else {
					/* refresh notification */
					if (p_slot)
+21 −4
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ static spinlock_t list_lock;
static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs);

static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds);
static int hpc_check_cmd_status(struct controller *ctrl);

/* This is the interrupt polling timeout function. */
static void int_poll_timeout(unsigned long lphp_ctlr)
@@ -304,9 +305,12 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)

	DBG_ENTER_ROUTINE 

	mutex_lock(&slot->ctrl->cmd_lock);

	if (!php_ctlr) {
		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
		return -1;
		retval = -EINVAL;
		goto out;
	}

	for (i = 0; i < 10; i++) {
@@ -323,7 +327,8 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
	if (cmd_status & 0x1) { 
		/* After 1 sec and and the controller is still busy */
		err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__);
		return -1;
		retval = -EBUSY;
		goto out;
	}

	++t_slot;
@@ -340,6 +345,17 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
	 * Wait for command completion.
	 */
	retval = shpc_wait_cmd(slot->ctrl);
	if (retval)
		goto out;

	cmd_status = hpc_check_cmd_status(slot->ctrl);
	if (cmd_status) {
		err("%s: Failed to issued command 0x%x (error code = %d)\n",
		    __FUNCTION__, cmd, cmd_status);
		retval = -EIO;
	}
 out:
	mutex_unlock(&slot->ctrl->cmd_lock);

	DBG_LEAVE_ROUTINE 
	return retval;
@@ -1343,7 +1359,6 @@ static struct hpc_ops shpchp_hpc_ops = {
	.green_led_blink		= hpc_set_green_led_blink,
	
	.release_ctlr			= hpc_release_ctlr,
	.check_cmd_status		= hpc_check_cmd_status,
};

inline static int shpc_indirect_creg_read(struct controller *ctrl, int index,
@@ -1455,6 +1470,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
	dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);

	mutex_init(&ctrl->crit_sect);
	mutex_init(&ctrl->cmd_lock);

	/* Setup wait queue */
	init_waitqueue_head(&ctrl->queue);