⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciehp_hpc.c

📁 底层驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
	return 0;}static int hpc_query_power_fault(struct slot * slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_status;	u8 pwr_fault;	int retval = 0;	u8 status;	DBG_ENTER_ROUTINE 	if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return -1;	}	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status);	if (retval) {		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);		return retval;	}	pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);	status = (pwr_fault != 1) ? 1 : 0;		DBG_LEAVE_ROUTINE	/* Note: Logic 0 => fault */	return status;}static int hpc_set_attention_status(struct slot *slot, u8 value){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd = 0;	u16 slot_ctrl;	int rc = 0;	dbg("%s: \n", __FUNCTION__);	if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return -1;	}	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return -1;	}	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (rc) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return rc;	}	dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);	switch (value) {		case 0 :	/* turn off */			slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0;			break;		case 1:		/* turn on */			slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040;			break;		case 2:		/* turn blink */			slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080;			break;		default:			return -1;	}	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	pcie_write_cmd(slot, slot_cmd);	dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);		return rc;}static void hpc_set_green_led_on(struct slot *slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd;	u16 slot_ctrl;	int rc = 0;       		dbg("%s: \n", __FUNCTION__);		if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return ;	}	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return ;	}	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (rc) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return;	}	dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);	slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100;	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	pcie_write_cmd(slot, slot_cmd);	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);	return;}static void hpc_set_green_led_off(struct slot *slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd;	u16 slot_ctrl;	int rc = 0;	dbg("%s: \n", __FUNCTION__);		if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return ;	}	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return ;	}	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (rc) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return;	}	dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);	slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300;	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	pcie_write_cmd(slot, slot_cmd);	dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);	return;}static void hpc_set_green_led_blink(struct slot *slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd;	u16 slot_ctrl;	int rc = 0; 		dbg("%s: \n", __FUNCTION__);		if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return ;	}	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return ;	}	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (rc) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return;	}	dbg("%s : hp_register_read_word SLOT_CTRL %x\n", __FUNCTION__, slot_ctrl);	slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200;	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	pcie_write_cmd(slot, slot_cmd);	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);	return;}int pcie_get_ctlr_slot_config(struct controller *ctrl,	int *num_ctlr_slots,	/* number of slots in this HPC; only 1 in PCIE  */		int *first_device_num,	/* PCI dev num of the first slot in this PCIE	*/	int *physical_slot_num,	/* phy slot num of the first slot in this PCIE	*/	u8 *ctrlcap){	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;	u32 slot_cap;	int rc = 0;		DBG_ENTER_ROUTINE 	if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return -1;	}	*first_device_num = 0;	*num_ctlr_slots = 1; 	rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap);	if (rc) {		err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__);		return -1;	}		*physical_slot_num = slot_cap >> 19;	dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);		*ctrlcap = slot_cap & 0x0000007f;	DBG_LEAVE_ROUTINE 	return 0;}static void hpc_release_ctlr(struct controller *ctrl){	struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;	struct php_ctlr_state_s *p, *p_prev;	DBG_ENTER_ROUTINE 	if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return ;	}	if (pciehp_poll_mode) {	    del_timer(&php_ctlr->int_poll_timer);	} else {			if (php_ctlr->irq) {			free_irq(php_ctlr->irq, ctrl);			php_ctlr->irq = 0;			if (!pcie_mch_quirk) 				pci_disable_msi(php_ctlr->pci_dev);		}	}	if (php_ctlr->pci_dev) 		php_ctlr->pci_dev = NULL;	spin_lock(&list_lock);	p = php_ctlr_list_head;	p_prev = NULL;	while (p) {		if (p == php_ctlr) {			if (p_prev)				p_prev->pnext = p->pnext;			else				php_ctlr_list_head = p->pnext;			break;		} else {			p_prev = p;			p = p->pnext;		}	}	spin_unlock(&list_lock);	kfree(php_ctlr);	DBG_LEAVE_ROUTINE			  }static int hpc_power_on_slot(struct slot * slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd;	u16 slot_ctrl;	int retval = 0;	DBG_ENTER_ROUTINE 	dbg("%s: \n", __FUNCTION__);		if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return -1;	}	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return -1;	}	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (retval) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return retval;	}	dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),		slot_ctrl);	slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON;	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	retval = pcie_write_cmd(slot, slot_cmd);	if (retval) {		err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);		return -1;	}	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);	DBG_LEAVE_ROUTINE	return retval;}static int hpc_power_off_slot(struct slot * slot){	struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;	u16 slot_cmd;	u16 slot_ctrl;	int retval = 0;	DBG_ENTER_ROUTINE 	dbg("%s: \n", __FUNCTION__);		if (!php_ctlr) {		err("%s: Invalid HPC controller handle!\n", __FUNCTION__);		return -1;	}	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);	slot->hp_slot = 0;	if (slot->hp_slot >= php_ctlr->num_slots) {		err("%s: Invalid HPC slot number!\n", __FUNCTION__);		return -1;	}	retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl);	if (retval) {		err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);		return retval;	}	dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base),		slot_ctrl);	slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF;	if (!pciehp_poll_mode)		slot_cmd = slot_cmd | HP_INTR_ENABLE; 	retval = pcie_write_cmd(slot, slot_cmd);	if (retval) {		err("%s: Write command failed!\n", __FUNCTION__);		return -1;	}	dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd);	DBG_LEAVE_ROUTINE	return retval;}static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs){	struct controller *ctrl = NULL;	struct php_ctlr_state_s *php_ctlr;	u8 schedule_flag = 0;	u16 slot_status, intr_detect, intr_loc;	u16 temp_word;	int hp_slot = 0;	/* only 1 slot per PCI Express port */	int rc = 0;	if (!dev_id)		return IRQ_NONE;	if (!pciehp_poll_mode) { 		ctrl = dev_id;		php_ctlr = ctrl->hpc_ctlr_handle;	} else {		php_ctlr = dev_id;		ctrl = (struct controller *)php_ctlr->callback_instance_id;	}	if (!ctrl) {		dbg("%s: dev_id %p ctlr == NULL\n", __FUNCTION__, (void*) dev_id);		return IRQ_NONE;	}		if (!php_ctlr) {		dbg("%s: php_ctlr == NULL\n", __FUNCTION__);		return IRQ_NONE;	}	rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);	if (rc) {		err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);		return IRQ_NONE;	}	intr_detect = ( ATTN_BUTTN_PRESSED | PWR_FAULT_DETECTED | MRL_SENS_CHANGED |					PRSN_DETECT_CHANGED | CMD_COMPLETED );	intr_loc = slot_status & intr_detect;	/* Check to see if it was our interrupt */	if ( !intr_loc )		return IRQ_NONE;	dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);	/* Mask Hot-plug Interrupt Enable */	if (!pciehp_poll_mode) {		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);		if (rc) {			err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: Set Mask Hot-plug Interrupt Enable\n", __FUNCTION__);		dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);		temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00;		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);		if (rc) {			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);				rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);		if (rc) {			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: hp_register_read_word SLOT_STATUS with value %x\n", __FUNCTION__, slot_status); 				/* Clear command complete interrupt caused by this write */		temp_word = 0x1f;		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);		if (rc) {			err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: hp_register_write_word SLOT_STATUS with value %x\n", __FUNCTION__, temp_word);	}		if (intr_loc & CMD_COMPLETED) {		/* 		 * Command Complete Interrupt Pending 		 */		dbg("%s: In Command Complete Interrupt Pending\n", __FUNCTION__);		wake_up_interruptible(&ctrl->queue);	}	if ((php_ctlr->switch_change_callback) && (intr_loc & MRL_SENS_CHANGED))		schedule_flag += php_ctlr->switch_change_callback(			hp_slot, php_ctlr->callback_instance_id);	if ((php_ctlr->attention_button_callback) && (intr_loc & ATTN_BUTTN_PRESSED))		schedule_flag += php_ctlr->attention_button_callback(			hp_slot, php_ctlr->callback_instance_id);	if ((php_ctlr->presence_change_callback) && (intr_loc & PRSN_DETECT_CHANGED))		schedule_flag += php_ctlr->presence_change_callback(			hp_slot , php_ctlr->callback_instance_id);	if ((php_ctlr->power_fault_callback) && (intr_loc & PWR_FAULT_DETECTED))		schedule_flag += php_ctlr->power_fault_callback(			hp_slot, php_ctlr->callback_instance_id);	/* Clear all events after serving them */	temp_word = 0x1F;	rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word);	if (rc) {		err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__);		return IRQ_NONE;	}	/* Unmask Hot-plug Interrupt Enable */	if (!pciehp_poll_mode) {		rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);		if (rc) {			err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);		dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word);		temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;		rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word);		if (rc) {			err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); 				rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status);		if (rc) {			err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -