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

📄 pciehp_hpc.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (retval) {		err("%s: Cannot check for power fault\n", __FUNCTION__);		return retval;	}	pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);	return pwr_fault;}static int hpc_get_emi_status(struct slot *slot, u8 *status){	struct controller *ctrl = slot->ctrl;	u16 slot_status;	int retval = 0;	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);	if (retval) {		err("%s : Cannot check EMI status\n", __FUNCTION__);		return retval;	}	*status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;	return retval;}static int hpc_toggle_emi(struct slot *slot){	u16 slot_cmd;	u16 cmd_mask;	int rc;	slot_cmd = EMI_CTRL;	cmd_mask = EMI_CTRL;	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd | HP_INTR_ENABLE;		cmd_mask = cmd_mask | HP_INTR_ENABLE;	}	rc = pcie_write_cmd(slot, slot_cmd, cmd_mask);	slot->last_emi_toggle = get_seconds();	return rc;}static int hpc_set_attention_status(struct slot *slot, u8 value){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	int rc;	cmd_mask = ATTN_LED_CTRL;	switch (value) {		case 0 :	/* turn off */			slot_cmd = 0x00C0;			break;		case 1:		/* turn on */			slot_cmd = 0x0040;			break;		case 2:		/* turn blink */			slot_cmd = 0x0080;			break;		default:			return -1;	}	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd | HP_INTR_ENABLE;		cmd_mask = cmd_mask | HP_INTR_ENABLE;	}	rc = pcie_write_cmd(slot, slot_cmd, cmd_mask);	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);	return rc;}static void hpc_set_green_led_on(struct slot *slot){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	slot_cmd = 0x0100;	cmd_mask = PWR_LED_CTRL;	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd | HP_INTR_ENABLE;		cmd_mask = cmd_mask | HP_INTR_ENABLE;	}	pcie_write_cmd(slot, slot_cmd, cmd_mask);	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);}static void hpc_set_green_led_off(struct slot *slot){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	slot_cmd = 0x0300;	cmd_mask = PWR_LED_CTRL;	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd | HP_INTR_ENABLE;		cmd_mask = cmd_mask | HP_INTR_ENABLE;	}	pcie_write_cmd(slot, slot_cmd, cmd_mask);	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);}static void hpc_set_green_led_blink(struct slot *slot){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	slot_cmd = 0x0200;	cmd_mask = PWR_LED_CTRL;	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd | HP_INTR_ENABLE;		cmd_mask = cmd_mask | HP_INTR_ENABLE;	}	pcie_write_cmd(slot, slot_cmd, cmd_mask);	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);}static void hpc_release_ctlr(struct controller *ctrl){	if (pciehp_poll_mode)		del_timer(&ctrl->poll_timer);	else		free_irq(ctrl->pci_dev->irq, ctrl);	/*	 * If this is the last controller to be released, destroy the	 * pciehp work queue	 */	if (atomic_dec_and_test(&pciehp_num_controllers))		destroy_workqueue(pciehp_wq);}static int hpc_power_on_slot(struct slot * slot){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	u16 slot_status;	int retval = 0;	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);	/* Clear sticky power-fault bit from previous power failures */	retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);	if (retval) {		err("%s: Cannot read SLOTSTATUS register\n", __FUNCTION__);		return retval;	}	slot_status &= PWR_FAULT_DETECTED;	if (slot_status) {		retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status);		if (retval) {			err("%s: Cannot write to SLOTSTATUS register\n",			    __FUNCTION__);			return retval;		}	}	slot_cmd = POWER_ON;	cmd_mask = PWR_CTRL;	/* Enable detection that we turned off at slot power-off time */	if (!pciehp_poll_mode) {		slot_cmd = slot_cmd |		           PWR_FAULT_DETECT_ENABLE |		           MRL_DETECT_ENABLE |		           PRSN_DETECT_ENABLE |		           HP_INTR_ENABLE;		cmd_mask = cmd_mask |		           PWR_FAULT_DETECT_ENABLE |		           MRL_DETECT_ENABLE |		           PRSN_DETECT_ENABLE |		           HP_INTR_ENABLE;	}	retval = pcie_write_cmd(slot, slot_cmd, cmd_mask);	if (retval) {		err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd);		return -1;	}	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);	return retval;}static int hpc_power_off_slot(struct slot * slot){	struct controller *ctrl = slot->ctrl;	u16 slot_cmd;	u16 cmd_mask;	int retval = 0;	dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot);	slot_cmd = POWER_OFF;	cmd_mask = PWR_CTRL;	/*	 * If we get MRL or presence detect interrupts now, the isr	 * will notice the sticky power-fault bit too and issue power	 * indicator change commands. This will lead to an endless loop	 * of command completions, since the power-fault bit remains on	 * till the slot is powered on again.	 */	if (!pciehp_poll_mode) {		slot_cmd = (slot_cmd &		            ~PWR_FAULT_DETECT_ENABLE &		            ~MRL_DETECT_ENABLE &		            ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE;		cmd_mask = cmd_mask |			   PWR_FAULT_DETECT_ENABLE |			   MRL_DETECT_ENABLE |			   PRSN_DETECT_ENABLE |			   HP_INTR_ENABLE;	}	retval = pcie_write_cmd(slot, slot_cmd, cmd_mask);	if (retval) {		err("%s: Write command failed!\n", __FUNCTION__);		return -1;	}	dbg("%s: SLOTCTRL %x write cmd %x\n",	    __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd);	return retval;}static irqreturn_t pcie_isr(int irq, void *dev_id){	struct controller *ctrl = (struct controller *)dev_id;	u16 slot_status, intr_detect, intr_loc;	u16 temp_word;	int hp_slot = 0;	/* only 1 slot per PCI Express port */	int rc = 0;	unsigned long flags;	rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);	if (rc) {		err("%s: Cannot read SLOTSTATUS register\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) {		spin_lock_irqsave(&ctrl->lock, flags);		rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);		if (rc) {			err("%s: Cannot read SLOT_CTRL register\n",			    __FUNCTION__);			spin_unlock_irqrestore(&ctrl->lock, flags);			return IRQ_NONE;		}		dbg("%s: pciehp_readw(SLOTCTRL) with value %x\n",		    __FUNCTION__, temp_word);		temp_word = (temp_word & ~HP_INTR_ENABLE &			     ~CMD_CMPL_INTR_ENABLE) | 0x00;		rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);		if (rc) {			err("%s: Cannot write to SLOTCTRL register\n",			    __FUNCTION__);			spin_unlock_irqrestore(&ctrl->lock, flags);			return IRQ_NONE;		}		spin_unlock_irqrestore(&ctrl->lock, flags);		rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);		if (rc) {			err("%s: Cannot read SLOT_STATUS register\n",			    __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: pciehp_readw(SLOTSTATUS) with value %x\n",		    __FUNCTION__, slot_status);		/* Clear command complete interrupt caused by this write */		temp_word = 0x1f;		rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);		if (rc) {			err("%s: Cannot write to SLOTSTATUS register\n",			    __FUNCTION__);			return IRQ_NONE;		}	}	if (intr_loc & CMD_COMPLETED) {		/*		 * Command Complete Interrupt Pending		 */		ctrl->cmd_busy = 0;		wake_up_interruptible(&ctrl->queue);	}	if (intr_loc & MRL_SENS_CHANGED)		pciehp_handle_switch_change(hp_slot, ctrl);	if (intr_loc & ATTN_BUTTN_PRESSED)		pciehp_handle_attention_button(hp_slot, ctrl);	if (intr_loc & PRSN_DETECT_CHANGED)		pciehp_handle_presence_change(hp_slot, ctrl);	if (intr_loc & PWR_FAULT_DETECTED)		pciehp_handle_power_fault(hp_slot, ctrl);	/* Clear all events after serving them */	temp_word = 0x1F;	rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);	if (rc) {		err("%s: Cannot write to SLOTSTATUS register\n", __FUNCTION__);		return IRQ_NONE;	}	/* Unmask Hot-plug Interrupt Enable */	if (!pciehp_poll_mode) {		spin_lock_irqsave(&ctrl->lock, flags);		rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word);		if (rc) {			err("%s: Cannot read SLOTCTRL register\n",			    __FUNCTION__);			spin_unlock_irqrestore(&ctrl->lock, flags);			return IRQ_NONE;		}		dbg("%s: Unmask Hot-plug Interrupt Enable\n", __FUNCTION__);		temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE;		rc = pciehp_writew(ctrl, SLOTCTRL, temp_word);		if (rc) {			err("%s: Cannot write to SLOTCTRL register\n",			    __FUNCTION__);			spin_unlock_irqrestore(&ctrl->lock, flags);			return IRQ_NONE;		}		spin_unlock_irqrestore(&ctrl->lock, flags);		rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);		if (rc) {			err("%s: Cannot read SLOT_STATUS register\n",			    __FUNCTION__);			return IRQ_NONE;		}		/* Clear command complete interrupt caused by this write */		temp_word = 0x1F;		rc = pciehp_writew(ctrl, SLOTSTATUS, temp_word);		if (rc) {			err("%s: Cannot write to SLOTSTATUS failed\n",			    __FUNCTION__);			return IRQ_NONE;		}		dbg("%s: pciehp_writew(SLOTSTATUS) with value %x\n",		    __FUNCTION__, temp_word);	}	return IRQ_HANDLED;}static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value){	struct controller *ctrl = slot->ctrl;	enum pcie_link_speed lnk_speed;	u32	lnk_cap;	int retval = 0;	retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);	if (retval) {		err("%s: Cannot read LNKCAP register\n", __FUNCTION__);		return retval;	}	switch (lnk_cap & 0x000F) {	case 1:		lnk_speed = PCIE_2PT5GB;		break;	default:		lnk_speed = PCIE_LNK_SPEED_UNKNOWN;		break;	}	*value = lnk_speed;	dbg("Max link speed = %d\n", lnk_speed);	return retval;}static int hpc_get_max_lnk_width(struct slot *slot,				 enum pcie_link_width *value){	struct controller *ctrl = slot->ctrl;	enum pcie_link_width lnk_wdth;	u32	lnk_cap;	int retval = 0;	retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);	if (retval) {		err("%s: Cannot read LNKCAP register\n", __FUNCTION__);		return retval;	}	switch ((lnk_cap & 0x03F0) >> 4){	case 0:		lnk_wdth = PCIE_LNK_WIDTH_RESRV;		break;	case 1:		lnk_wdth = PCIE_LNK_X1;		break;	case 2:		lnk_wdth = PCIE_LNK_X2;		break;	case 4:

⌨️ 快捷键说明

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