📄 ibmphp_hpc.c
字号:
}static u8 pci_ctrl_read (struct controller *ctrl, u8 offset){ u8 data = 0x00; debug ("inside pci_ctrl_read\n"); if (ctrl->ctrl_dev) pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data); return data;}static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data){ u8 rc = -ENODEV; debug ("inside pci_ctrl_write\n"); if (ctrl->ctrl_dev) { pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data); rc = 0; } return rc;}static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset){ u8 rc; switch (ctlr->ctlr_type) { case 0: rc = isa_ctrl_read (ctlr, offset); break; case 1: rc = pci_ctrl_read (ctlr, offset); break; case 2: case 4: rc = i2c_ctrl_read (ctlr, base, offset); break; default: return -ENODEV; } return rc;}static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data){ u8 rc = 0; switch (ctlr->ctlr_type) { case 0: isa_ctrl_write(ctlr, offset, data); break; case 1: rc = pci_ctrl_write (ctlr, offset, data); break; case 2: case 4: rc = i2c_ctrl_write(ctlr, base, offset, data); break; default: return -ENODEV; } return rc;}/*----------------------------------------------------------------------* Name: hpc_writecmdtoindex()** Action: convert a write command to proper index within a controller** Return index, HPC_ERROR*---------------------------------------------------------------------*/static u8 hpc_writecmdtoindex (u8 cmd, u8 index){ u8 rc; switch (cmd) { case HPC_CTLR_ENABLEIRQ: // 0x00.N.15 case HPC_CTLR_CLEARIRQ: // 0x06.N.15 case HPC_CTLR_RESET: // 0x07.N.15 case HPC_CTLR_IRQSTEER: // 0x08.N.15 case HPC_CTLR_DISABLEIRQ: // 0x01.N.15 case HPC_ALLSLOT_ON: // 0x11.N.15 case HPC_ALLSLOT_OFF: // 0x12.N.15 rc = 0x0F; break; case HPC_SLOT_OFF: // 0x02.Y.0-14 case HPC_SLOT_ON: // 0x03.Y.0-14 case HPC_SLOT_ATTNOFF: // 0x04.N.0-14 case HPC_SLOT_ATTNON: // 0x05.N.0-14 case HPC_SLOT_BLINKLED: // 0x13.N.0-14 rc = index; break; case HPC_BUS_33CONVMODE: case HPC_BUS_66CONVMODE: case HPC_BUS_66PCIXMODE: case HPC_BUS_100PCIXMODE: case HPC_BUS_133PCIXMODE: rc = index + WPG_1ST_BUS_INDEX - 1; break; default: err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd); rc = HPC_ERROR; } return rc;}/*----------------------------------------------------------------------* Name: hpc_readcmdtoindex()** Action: convert a read command to proper index within a controller** Return index, HPC_ERROR*---------------------------------------------------------------------*/static u8 hpc_readcmdtoindex (u8 cmd, u8 index){ u8 rc; switch (cmd) { case READ_CTLRSTATUS: rc = 0x0F; break; case READ_SLOTSTATUS: case READ_ALLSTAT: rc = index; break; case READ_EXTSLOTSTATUS: rc = index + WPG_1ST_EXTSLOT_INDEX; break; case READ_BUSSTATUS: rc = index + WPG_1ST_BUS_INDEX - 1; break; case READ_SLOTLATCHLOWREG: rc = 0x28; break; case READ_REVLEVEL: rc = 0x25; break; case READ_HPCOPTIONS: rc = 0x27; break; default: rc = HPC_ERROR; } return rc;}/*----------------------------------------------------------------------* Name: HPCreadslot()** Action: issue a READ command to HPC** Input: pslot - cannot be NULL for READ_ALLSTAT* pstatus - can be NULL for READ_ALLSTAT** Return 0 or error codes*---------------------------------------------------------------------*/int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus){ void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; struct list_head *pslotlist; u8 index, status; int rc = 0; int busindex; debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus); if ((pslot == NULL) || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) { rc = -EINVAL; err ("%s - Error invalid pointer, rc[%d]\n", __func__, rc); return rc; } if (cmd == READ_BUSSTATUS) { busindex = ibmphp_get_bus_index (pslot->bus); if (busindex < 0) { rc = -EINVAL; err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc); return rc; } else index = (u8) busindex; } else index = pslot->ctlr_index; index = hpc_readcmdtoindex (cmd, index); if (index == HPC_ERROR) { rc = -EINVAL; err ("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc); return rc; } ctlr_ptr = pslot->ctrl; get_hpc_access (); //-------------------------------------------------------------------- // map physical address to logical address //-------------------------------------------------------------------- if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); //-------------------------------------------------------------------- // check controller status before reading //-------------------------------------------------------------------- rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { switch (cmd) { case READ_ALLSTAT: // update the slot structure pslot->ctrl->status = status; pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index); rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX); break; case READ_SLOTSTATUS: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_EXTSLOTSTATUS: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_CTLRSTATUS: // DO NOT update the slot structure *pstatus = status; break; case READ_BUSSTATUS: pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_REVLEVEL: *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_HPCOPTIONS: *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; case READ_SLOTLATCHLOWREG: // DO NOT update the slot structure *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index); break; // Not used case READ_ALLSLOT: list_for_each (pslotlist, &ibmphp_slot_head) { pslot = list_entry (pslotlist, struct slot, ibm_slot_list); index = pslot->ctlr_index; rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index); rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX); } else { err ("%s - Error ctrl_read failed\n", __func__); rc = -EINVAL; break; } } break; default: rc = -EINVAL; break; } } //-------------------------------------------------------------------- // cleanup //-------------------------------------------------------------------- // remove physical to logical address mapping if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) iounmap (wpg_bbar); free_hpc_access (); debug_polling ("%s - Exit rc[%d]\n", __func__, rc); return rc;}/*----------------------------------------------------------------------* Name: ibmphp_hpc_writeslot()** Action: issue a WRITE command to HPC*---------------------------------------------------------------------*/int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd){ void __iomem *wpg_bbar = NULL; struct controller *ctlr_ptr; u8 index, status; int busindex; u8 done; int rc = 0; int timeout; debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd); if (pslot == NULL) { rc = -EINVAL; err ("%s - Error Exit rc[%d]\n", __func__, rc); return rc; } if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) || (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) || (cmd == HPC_BUS_133PCIXMODE)) { busindex = ibmphp_get_bus_index (pslot->bus); if (busindex < 0) { rc = -EINVAL; err ("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc); return rc; } else index = (u8) busindex; } else index = pslot->ctlr_index; index = hpc_writecmdtoindex (cmd, index); if (index == HPC_ERROR) { rc = -EINVAL; err ("%s - Error Exit rc[%d]\n", __func__, rc); return rc; } ctlr_ptr = pslot->ctrl; get_hpc_access (); //-------------------------------------------------------------------- // map physical address to logical address //-------------------------------------------------------------------- if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) { wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__, ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar, ctlr_ptr->u.wpeg_ctlr.i2c_addr); } //-------------------------------------------------------------------- // check controller status before writing //-------------------------------------------------------------------- rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { ctrl_write (ctlr_ptr, wpg_bbar, index, cmd); //-------------------------------------------------------------------- // check controller is still not working on the command //-------------------------------------------------------------------- timeout = CMD_COMPLETE_TOUT_SEC; done = 0; while (!done) { rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status); if (!rc) { if (NEEDTOCHECK_CMDSTATUS (cmd)) { if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES) done = 1; } else done = 1; } if (!done) { msleep(1000); if (timeout < 1) { done = 1; err ("%s - Error command complete timeout\n", __func__); rc = -EFAULT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -