<html><body><p><tt>Hi Edward,</tt><br><br><tt>I was concerned with bellow piece of code when writing P8 occ driver.</tt><br><tt>Referring to occ spec: </tt><a href="https://github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf"><tt>https://github.com/open-power/docs/blob/master/occ/OCC_OpenPwr_FW_Interfaces.pdf</tt></a><br><tt>Section: </tt><tt>1.6.2 OCC Command/Response Sequence and Appendix A: Return codes.</tt><br><br><tt>OCC responds a command with different return code. Currently, the occ driver regards any return code</tt><br><tt>other than 0x0 (Succeed) as error. But we may need to handle occ return code properly,</tt><br><tt>e.g: for 0xFF (command in progress), we might not regard it as an error.</tt><br><tt><br>> +<br>> +static u8 occ_send_cmd(struct occ *driver, u8 seq, u8 type, u16 length,<br>> +             u8 *data, u8 *resp)<br>> +{<br>> +   u32 cmd1, cmd2;<br>> +   u16 checksum;<br>> +   int i;<br>> +<br>> +   length = cpu_to_le16(length);<br>> +   cmd1 = (seq << 24) | (type << 16) | length;<br>> +   memcpy(&cmd2, data, length);<br>> +   cmd2 <<= ((4 - length) * 8);<br>> +<br>> +   /* checksum: sum of every bytes of cmd1, cmd2 */<br>> +   checksum = 0;<br>> +   for (i = 0; i < 4; i++)<br>> +      checksum += (cmd1 >> (i * 8)) & 0xFF;<br>> +   for (i = 0; i < 4; i++)<br>> +      checksum += (cmd2 >> (i * 8)) & 0xFF;<br>> +   cmd2 |= checksum << ((2 - length) * 8);<br>> +<br>> +   /* Init OCB */<br>> +   driver->bus_ops.putscom(driver->bus, OCB_STATUS_CONTROL_OR, 0x08000000,<br>> +            0x00000000);<br>> +   driver->bus_ops.putscom(driver->bus, OCB_STATUS_CONTROL_AND,<br>> +            0xFBFFFFFF, 0xFFFFFFFF);<br>> +<br>> +   /* Send command */<br>> +   driver->bus_ops.putscom(driver->bus, OCB_ADDRESS,<br>> +            driver->config.command_addr, 0x00000000);<br>> +   driver->bus_ops.putscom(driver->bus, OCB_ADDRESS,<br>> +            driver->config.command_addr, 0x00000000);<br>> +   driver->bus_ops.putscom(driver->bus, OCB_DATA, cmd1, cmd2);<br>> +<br>> +   /* Trigger attention */<br>> +   driver->bus_ops.putscom(driver->bus, ATTN_DATA, 0x01010000,<br>> +            0x00000000);<br>> +<br>> +   /* Get response data */<br>> +   driver->bus_ops.putscom(driver->bus, OCB_ADDRESS,<br>> +            driver->config.response_addr, 0x00000000);<br>> +   driver->bus_ops.getscom(driver->bus, OCB_DATA, resp, 0);<br>> +<br>> +   /* return status */<br>> +   return resp[2];<br>> +}<br>> +<br></tt><br><tt>Thanks,</tt><br><tt>-Yi</tt><BR>
</body></html>