| 242 | } |
| 243 | |
| 244 | static int mei_recv_msg(struct mei_header *mei, struct mkhi_header *mkhi, |
| 245 | void *rsp_data, uint32_t rsp_bytes) |
| 246 | { |
| 247 | struct mei_header mei_rsp; |
| 248 | struct mkhi_header mkhi_rsp; |
| 249 | struct mei_csr me, host; |
| 250 | unsigned ndata, n; |
| 251 | unsigned expected; |
| 252 | uint32_t *data; |
| 253 | |
| 254 | /* Total number of dwords to read from circular buffer */ |
| 255 | expected = (rsp_bytes + sizeof(mei_rsp) + sizeof(mkhi_rsp)) >> 2; |
| 256 | if (rsp_bytes & 3) |
| 257 | expected++; |
| 258 | |
| 259 | if (debug) { |
| 260 | printf("expected u32 = %d\n", expected); |
| 261 | } |
| 262 | /* |
| 263 | * The interrupt status bit does not appear to indicate that the |
| 264 | * message has actually been received. Instead we wait until the |
| 265 | * expected number of dwords are present in the circular buffer. |
| 266 | */ |
| 267 | for (n = ME_RETRY; n; --n) { |
| 268 | read_me_csr(&me); |
| 269 | if ((me.buffer_write_ptr - me.buffer_read_ptr) >= expected) |
| 270 | //if (me.interrupt_generate && !me.interrupt_status) |
| 271 | //if (me.interrupt_status) |
| 272 | break; |
| 273 | usleep(ME_DELAY); |
| 274 | } |
| 275 | if (!n) { |
| 276 | printf("ME: timeout waiting for data: expected " |
| 277 | "%u, available %u\n", expected, |
| 278 | me.buffer_write_ptr - me.buffer_read_ptr); |
| 279 | return -1; |
| 280 | } |
| 281 | /* Read and verify MEI response header from the ME */ |
| 282 | mei_read_dword_ptr(&mei_rsp, MEI_ME_CB_RW); |
| 283 | if (!mei_rsp.is_complete) { |
| 284 | printf("ME: response is not complete\n"); |
| 285 | return -1; |
| 286 | } |
| 287 | |
| 288 | /* Handle non-dword responses and expect at least MKHI header */ |
| 289 | ndata = mei_rsp.length >> 2; |
| 290 | if (mei_rsp.length & 3) |
| 291 | ndata++; |
| 292 | if (ndata != (expected - 1)) { //XXX |
| 293 | printf("ME: response is missing data\n"); |
| 294 | //return -1; |
| 295 | } |
| 296 | |
| 297 | /* Read and verify MKHI response header from the ME */ |
| 298 | mei_read_dword_ptr(&mkhi_rsp, MEI_ME_CB_RW); |
| 299 | if (!mkhi_rsp.is_response || |
| 300 | mkhi->group_id != mkhi_rsp.group_id || |
| 301 | mkhi->command != mkhi_rsp.command) { |
no test coverage detected