diff --git a/sys/powerpc/powernv/opal_i2c.c b/sys/powerpc/powernv/opal_i2c.c index 1cbdaca78372..a4e0dd957b09 100644 --- a/sys/powerpc/powernv/opal_i2c.c +++ b/sys/powerpc/powernv/opal_i2c.c @@ -167,16 +167,19 @@ static int i2c_opal_send_request(uint32_t bus_id, struct opal_i2c_request *req) { struct opal_msg msg; - int token, rc; + uint64_t token; + uint64_t msg_addr; + int rc; /* * XXX: - * Async tokens should be managed globally. Since there is - * only one place now, use hardcoded value. + * Async tokens should be managed globally. Since there are only a very + * few places now, use a punning of the stack address of the message. */ - token = 0x112233; + token = (uintptr_t)&msg; memset(&msg, 0, sizeof(msg)); + msg_addr = pmap_kextract((vm_offset_t)&msg); rc = opal_call(OPAL_I2C_REQUEST, token, bus_id, pmap_kextract((uint64_t)req)); @@ -185,7 +188,7 @@ i2c_opal_send_request(uint32_t bus_id, struct opal_i2c_request *req) do { rc = opal_call(OPAL_CHECK_ASYNC_COMPLETION, - pmap_kextract((uint64_t)&msg), sizeof(msg), token); + msg_addr, sizeof(msg), token); } while (rc == OPAL_BUSY); if (rc != OPAL_SUCCESS) @@ -207,20 +210,13 @@ opal_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) memset(&req, 0, sizeof(req)); - /* XXX: Currently OPAL can parse only 1 message */ - if (nmsgs > 1) { - device_printf(dev, - "trying to parse %d messages, while only 1 is supported\n", nmsgs); - return (ENOMEM); - } - I2C_LOCK(sc); for (i = 0; i < nmsgs; i++) { req.type = (msgs[i].flags & IIC_M_RD) ? OPAL_I2C_RAW_READ : OPAL_I2C_RAW_WRITE; - req.addr = htobe16(msgs[0].slave); - req.size = htobe32(msgs[0].len); - req.buffer_pa = htobe64(pmap_kextract((uint64_t)msgs[0].buf)); + req.addr = htobe16(msgs[i].slave >> 1); + req.size = htobe32(msgs[i].len); + req.buffer_pa = htobe64(pmap_kextract((uint64_t)msgs[i].buf)); err = i2c_opal_send_request(sc->opal_id, &req); }