108 fsm->slave = slave; |
108 fsm->slave = slave; |
109 fsm->request = request; |
109 fsm->request = request; |
110 if (request->dir == EC_DIR_OUTPUT) { |
110 if (request->dir == EC_DIR_OUTPUT) { |
111 fsm->state = ec_fsm_soe_write_start; |
111 fsm->state = ec_fsm_soe_write_start; |
112 } else { |
112 } else { |
|
113 fsm->request->data_size = 0; |
113 fsm->state = ec_fsm_soe_read_start; |
114 fsm->state = ec_fsm_soe_read_start; |
114 } |
115 } |
115 } |
116 } |
116 |
117 |
117 /*****************************************************************************/ |
118 /*****************************************************************************/ |
223 ec_datagram_print_wc_error(datagram); |
224 ec_datagram_print_wc_error(datagram); |
224 return; |
225 return; |
225 } |
226 } |
226 |
227 |
227 fsm->jiffies_start = datagram->jiffies_sent; |
228 fsm->jiffies_start = datagram->jiffies_sent; |
228 |
|
229 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
229 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
230 fsm->retries = EC_FSM_RETRIES; |
230 fsm->retries = EC_FSM_RETRIES; |
231 fsm->state = ec_fsm_soe_read_check; |
231 fsm->state = ec_fsm_soe_read_check; |
232 } |
232 } |
233 |
233 |
288 void ec_fsm_soe_read_response(ec_fsm_soe_t *fsm /**< finite state machine */) |
288 void ec_fsm_soe_read_response(ec_fsm_soe_t *fsm /**< finite state machine */) |
289 { |
289 { |
290 ec_datagram_t *datagram = fsm->datagram; |
290 ec_datagram_t *datagram = fsm->datagram; |
291 ec_slave_t *slave = fsm->slave; |
291 ec_slave_t *slave = fsm->slave; |
292 ec_master_t *master = slave->master; |
292 ec_master_t *master = slave->master; |
293 uint8_t *data, mbox_prot, opcode, error_flag, value_included; |
293 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag, |
|
294 value_included; |
294 size_t rec_size, data_size; |
295 size_t rec_size, data_size; |
295 ec_soe_request_t *req = fsm->request; |
296 ec_soe_request_t *req = fsm->request; |
296 |
297 |
297 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
298 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
298 return; // FIXME: request again? |
299 return; // FIXME: request again? |
336 rec_size); |
337 rec_size); |
337 ec_print_data(data, rec_size); |
338 ec_print_data(data, rec_size); |
338 return; |
339 return; |
339 } |
340 } |
340 |
341 |
341 opcode = EC_READ_U8(data) & 0x7; |
342 header = EC_READ_U8(data); |
|
343 opcode = header & 0x7; |
|
344 incomplete = (header >> 3) & 1; |
|
345 error_flag = (header >> 4) & 1; |
|
346 |
342 if (opcode != EC_SOE_OPCODE_READ_RESPONSE) { |
347 if (opcode != EC_SOE_OPCODE_READ_RESPONSE) { |
343 EC_ERR("Received no read response (opcode %x).\n", opcode); |
348 EC_ERR("Received no read response (opcode %x).\n", opcode); |
344 ec_print_data(data, rec_size); |
349 ec_print_data(data, rec_size); |
345 fsm->state = ec_fsm_soe_error; |
350 fsm->state = ec_fsm_soe_error; |
346 return; |
351 return; |
347 } |
352 } |
348 |
353 |
349 error_flag = (EC_READ_U8(data) >> 4) & 1; |
|
350 if (error_flag) { |
354 if (error_flag) { |
351 req->error_code = EC_READ_U16(data + rec_size - 2); |
355 req->error_code = EC_READ_U16(data + rec_size - 2); |
352 EC_ERR("Received error response: 0x%04x.\n", |
356 EC_ERR("Received error response: 0x%04x.\n", |
353 req->error_code); |
357 req->error_code); |
354 fsm->state = ec_fsm_soe_error; |
358 fsm->state = ec_fsm_soe_error; |
363 fsm->state = ec_fsm_soe_error; |
367 fsm->state = ec_fsm_soe_error; |
364 return; |
368 return; |
365 } |
369 } |
366 |
370 |
367 data_size = rec_size - EC_SOE_READ_RESPONSE_SIZE; |
371 data_size = rec_size - EC_SOE_READ_RESPONSE_SIZE; |
368 if (ec_soe_request_copy_data(req, |
372 if (ec_soe_request_append_data(req, |
369 data + EC_SOE_READ_RESPONSE_SIZE, data_size)) { |
373 data + EC_SOE_READ_RESPONSE_SIZE, data_size)) { |
370 fsm->state = ec_fsm_soe_error; |
374 fsm->state = ec_fsm_soe_error; |
371 return; |
375 return; |
372 } |
376 } |
373 |
377 |
374 if (master->debug_level) { |
378 if (incomplete) { |
375 EC_DBG("IDN data:\n"); |
379 if (master->debug_level) { |
376 ec_print_data(req->data, req->data_size); |
380 EC_DBG("SoE data incomplete. Waiting for fragment" |
377 } |
381 " at offset %zu.\n", req->data_size); |
378 |
382 } |
379 fsm->state = ec_fsm_soe_end; // success |
383 fsm->jiffies_start = datagram->jiffies_sent; |
|
384 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
385 fsm->retries = EC_FSM_RETRIES; |
|
386 fsm->state = ec_fsm_soe_read_check; |
|
387 } else { |
|
388 if (master->debug_level) { |
|
389 EC_DBG("IDN data:\n"); |
|
390 ec_print_data(req->data, req->data_size); |
|
391 } |
|
392 |
|
393 fsm->state = ec_fsm_soe_end; // success |
|
394 } |
380 } |
395 } |
381 |
396 |
382 /****************************************************************************** |
397 /****************************************************************************** |
383 * SoE write state machine |
398 * SoE write state machine |
384 *****************************************************************************/ |
399 *****************************************************************************/ |