00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035
00036
00037 #include "globals.h"
00038 #include "master.h"
00039 #include "mailbox.h"
00040 #include "fsm_soe.h"
00041
00042
00043
00046 #define EC_MBOX_TYPE_SOE 0x05
00047
00050 enum ec_soe_opcodes {
00051 OPCODE_READ_REQUEST = 0x01,
00052 OPCODE_READ_RESPONSE = 0x02,
00053 OPCODE_WRITE_REQUEST = 0x03,
00054 OPCODE_WRITE_RESPONSE = 0x04
00055 };
00056
00059 #define EC_SOE_SIZE 0x04
00060
00063 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
00064
00067 #define EC_SOE_RESPONSE_TIMEOUT 1000
00068
00069
00070
00071 void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *);
00072 void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *);
00073 void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *);
00074 void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *);
00075
00076 void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *);
00077 void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *);
00078 void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *);
00079 void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *);
00080
00081 void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *);
00082 void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *);
00083
00084
00085
00086 extern const ec_code_msg_t soe_error_codes[];
00087
00088
00089
00092 void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
00093 {
00094 const ec_code_msg_t *error_msg;
00095
00096 for (error_msg = soe_error_codes; error_msg->code; error_msg++) {
00097 if (error_msg->code == error_code) {
00098 EC_SLAVE_ERR(slave, "SoE error 0x%04X: \"%s\".\n",
00099 error_msg->code, error_msg->message);
00100 return;
00101 }
00102 }
00103
00104 EC_SLAVE_ERR(slave, "Unknown SoE error 0x%04X.\n", error_code);
00105 }
00106
00107
00108
00111 void ec_fsm_soe_init(
00112 ec_fsm_soe_t *fsm
00113 )
00114 {
00115 fsm->state = NULL;
00116 fsm->datagram = NULL;
00117 fsm->fragment_size = 0;
00118 }
00119
00120
00121
00124 void ec_fsm_soe_clear(
00125 ec_fsm_soe_t *fsm
00126 )
00127 {
00128 }
00129
00130
00131
00134 void ec_fsm_soe_transfer(
00135 ec_fsm_soe_t *fsm,
00136 ec_slave_t *slave,
00137 ec_soe_request_t *request
00138 )
00139 {
00140 fsm->slave = slave;
00141 fsm->request = request;
00142
00143 if (request->dir == EC_DIR_OUTPUT) {
00144 fsm->state = ec_fsm_soe_write_start;
00145 } else {
00146 fsm->state = ec_fsm_soe_read_start;
00147 }
00148 }
00149
00150
00151
00156 int ec_fsm_soe_exec(
00157 ec_fsm_soe_t *fsm,
00158 ec_datagram_t *datagram
00159 )
00160 {
00161 int datagram_used = 0;
00162
00163 if (fsm->datagram &&
00164 (fsm->datagram->state == EC_DATAGRAM_INIT ||
00165 fsm->datagram->state == EC_DATAGRAM_QUEUED ||
00166 fsm->datagram->state == EC_DATAGRAM_SENT)) {
00167
00168 return datagram_used;
00169 }
00170
00171 fsm->state(fsm, datagram);
00172
00173 datagram_used =
00174 fsm->state != ec_fsm_soe_end && fsm->state != ec_fsm_soe_error;
00175
00176 if (datagram_used) {
00177 fsm->datagram = datagram;
00178 } else {
00179 fsm->datagram = NULL;
00180 }
00181
00182 return datagram_used;
00183 }
00184
00185
00186
00191 int ec_fsm_soe_success(const ec_fsm_soe_t *fsm )
00192 {
00193 return fsm->state == ec_fsm_soe_end;
00194 }
00195
00196
00197
00200 void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm )
00201 {
00202 ec_soe_request_t *request = fsm->request;
00203
00204 EC_SLAVE_ERR(fsm->slave, "");
00205
00206 if (request->dir == EC_DIR_OUTPUT) {
00207 printk("Writing");
00208 } else {
00209 printk("Reading");
00210 }
00211
00212 printk(" IDN 0x%04X failed.\n", request->idn);
00213 }
00214
00215
00216
00217
00218
00223 int ec_fsm_soe_prepare_read(
00224 ec_fsm_soe_t *fsm,
00225 ec_datagram_t *datagram
00226 )
00227 {
00228 uint8_t *data;
00229 ec_slave_t *slave = fsm->slave;
00230 ec_master_t *master = slave->master;
00231 ec_soe_request_t *request = fsm->request;
00232
00233 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
00234 EC_SOE_SIZE);
00235 if (IS_ERR(data)) {
00236 return PTR_ERR(data);
00237 }
00238
00239 EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5);
00240 EC_WRITE_U8(data + 1, 1 << 6);
00241 EC_WRITE_U16(data + 2, request->idn);
00242
00243 if (master->debug_level) {
00244 EC_SLAVE_DBG(slave, 0, "SSC read request:\n");
00245 ec_print_data(data, EC_SOE_SIZE);
00246 }
00247
00248 fsm->request->jiffies_sent = jiffies;
00249 fsm->state = ec_fsm_soe_read_request;
00250
00251 return 0;
00252 }
00253
00254
00255
00258 void ec_fsm_soe_read_start(
00259 ec_fsm_soe_t *fsm,
00260 ec_datagram_t *datagram
00261 )
00262 {
00263 ec_slave_t *slave = fsm->slave;
00264 ec_soe_request_t *request = fsm->request;
00265
00266 EC_SLAVE_DBG(slave, 1, "Reading IDN 0x%04X of drive %u.\n", request->idn,
00267 request->drive_no);
00268
00269 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
00270 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
00271 fsm->state = ec_fsm_soe_error;
00272 ec_fsm_soe_print_error(fsm);
00273 return;
00274 }
00275
00276 request->data_size = 0;
00277 fsm->retries = EC_FSM_RETRIES;
00278
00279 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
00280 fsm->state = ec_fsm_soe_error;
00281 ec_fsm_soe_print_error(fsm);
00282 }
00283 }
00284
00285
00286
00289 void ec_fsm_soe_read_request(
00290 ec_fsm_soe_t *fsm,
00291 ec_datagram_t *datagram
00292 )
00293 {
00294 ec_slave_t *slave = fsm->slave;
00295 unsigned long diff_ms;
00296
00297 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00298 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
00299 fsm->state = ec_fsm_soe_error;
00300 ec_fsm_soe_print_error(fsm);
00301 }
00302 return;
00303 }
00304
00305 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00306 fsm->state = ec_fsm_soe_error;
00307 EC_SLAVE_ERR(slave, "Failed to receive SoE read request: ");
00308 ec_datagram_print_state(fsm->datagram);
00309 ec_fsm_soe_print_error(fsm);
00310 return;
00311 }
00312
00313 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
00314
00315 if (fsm->datagram->working_counter != 1) {
00316 if (!fsm->datagram->working_counter) {
00317 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
00318
00319 if (ec_fsm_soe_prepare_read(fsm, datagram)) {
00320 fsm->state = ec_fsm_soe_error;
00321 ec_fsm_soe_print_error(fsm);
00322 }
00323 return;
00324 }
00325 }
00326 fsm->state = ec_fsm_soe_error;
00327 EC_SLAVE_ERR(slave, "Reception of SoE read request"
00328 " failed after %lu ms: ", diff_ms);
00329 ec_datagram_print_wc_error(fsm->datagram);
00330 ec_fsm_soe_print_error(fsm);
00331 return;
00332 }
00333
00334 fsm->jiffies_start = fsm->datagram->jiffies_sent;
00335 ec_slave_mbox_prepare_check(slave, datagram);
00336 fsm->retries = EC_FSM_RETRIES;
00337 fsm->state = ec_fsm_soe_read_check;
00338 }
00339
00340
00341
00344 void ec_fsm_soe_read_check(
00345 ec_fsm_soe_t *fsm,
00346 ec_datagram_t *datagram
00347 )
00348 {
00349 ec_slave_t *slave = fsm->slave;
00350
00351 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00352 ec_slave_mbox_prepare_check(slave, datagram);
00353 return;
00354 }
00355
00356 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00357 fsm->state = ec_fsm_soe_error;
00358 EC_SLAVE_ERR(slave, "Failed to receive SoE mailbox check datagram: ");
00359 ec_datagram_print_state(fsm->datagram);
00360 ec_fsm_soe_print_error(fsm);
00361 return;
00362 }
00363
00364 if (fsm->datagram->working_counter != 1) {
00365 fsm->state = ec_fsm_soe_error;
00366 EC_SLAVE_ERR(slave, "Reception of SoE mailbox check"
00367 " datagram failed: ");
00368 ec_datagram_print_wc_error(fsm->datagram);
00369 ec_fsm_soe_print_error(fsm);
00370 return;
00371 }
00372
00373 if (!ec_slave_mbox_check(fsm->datagram)) {
00374 unsigned long diff_ms =
00375 (fsm->datagram->jiffies_received - fsm->jiffies_start) *
00376 1000 / HZ;
00377 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
00378 fsm->state = ec_fsm_soe_error;
00379 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting for"
00380 " read response.\n", diff_ms);
00381 ec_fsm_soe_print_error(fsm);
00382 return;
00383 }
00384
00385 ec_slave_mbox_prepare_check(slave, datagram);
00386 fsm->retries = EC_FSM_RETRIES;
00387 return;
00388 }
00389
00390
00391 ec_slave_mbox_prepare_fetch(slave, datagram);
00392 fsm->retries = EC_FSM_RETRIES;
00393 fsm->state = ec_fsm_soe_read_response;
00394 }
00395
00396
00397
00400 void ec_fsm_soe_read_response(
00401 ec_fsm_soe_t *fsm,
00402 ec_datagram_t *datagram
00403 )
00404 {
00405 ec_slave_t *slave = fsm->slave;
00406 ec_master_t *master = slave->master;
00407 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
00408 value_included;
00409 size_t rec_size, data_size;
00410 ec_soe_request_t *req = fsm->request;
00411
00412 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00413 ec_slave_mbox_prepare_fetch(slave, datagram);
00414 return;
00415 }
00416
00417 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00418 fsm->state = ec_fsm_soe_error;
00419 EC_SLAVE_ERR(slave, "Failed to receive SoE read response datagram: ");
00420 ec_datagram_print_state(fsm->datagram);
00421 ec_fsm_soe_print_error(fsm);
00422 return;
00423 }
00424
00425 if (fsm->datagram->working_counter != 1) {
00426 fsm->state = ec_fsm_soe_error;
00427 EC_SLAVE_ERR(slave, "Reception of SoE read response failed: ");
00428 ec_datagram_print_wc_error(fsm->datagram);
00429 ec_fsm_soe_print_error(fsm);
00430 return;
00431 }
00432
00433 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
00434 if (IS_ERR(data)) {
00435 fsm->state = ec_fsm_soe_error;
00436 ec_fsm_soe_print_error(fsm);
00437 return;
00438 }
00439
00440 if (master->debug_level) {
00441 EC_SLAVE_DBG(slave, 0, "SSC read response:\n");
00442 ec_print_data(data, rec_size);
00443 }
00444
00445 if (mbox_prot != EC_MBOX_TYPE_SOE) {
00446 fsm->state = ec_fsm_soe_error;
00447 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
00448 mbox_prot);
00449 ec_fsm_soe_print_error(fsm);
00450 return;
00451 }
00452
00453 if (rec_size < EC_SOE_SIZE) {
00454 fsm->state = ec_fsm_soe_error;
00455 EC_SLAVE_ERR(slave, "Received currupted SoE read response"
00456 " (%zu bytes)!\n", rec_size);
00457 ec_print_data(data, rec_size);
00458 ec_fsm_soe_print_error(fsm);
00459 return;
00460 }
00461
00462 header = EC_READ_U8(data);
00463 opcode = header & 0x7;
00464 incomplete = (header >> 3) & 1;
00465 error_flag = (header >> 4) & 1;
00466
00467 if (opcode != OPCODE_READ_RESPONSE) {
00468 EC_SLAVE_ERR(slave, "Received no read response (opcode %x).\n",
00469 opcode);
00470 ec_print_data(data, rec_size);
00471 ec_fsm_soe_print_error(fsm);
00472 fsm->state = ec_fsm_soe_error;
00473 return;
00474 }
00475
00476 if (error_flag) {
00477 req->error_code = EC_READ_U16(data + rec_size - 2);
00478 EC_SLAVE_ERR(slave, "Received error response:\n");
00479 ec_print_soe_error(slave, req->error_code);
00480 ec_fsm_soe_print_error(fsm);
00481 fsm->state = ec_fsm_soe_error;
00482 return;
00483 } else {
00484 req->error_code = 0x0000;
00485 }
00486
00487 value_included = (EC_READ_U8(data + 1) >> 6) & 1;
00488 if (!value_included) {
00489 EC_SLAVE_ERR(slave, "No value included!\n");
00490 ec_fsm_soe_print_error(fsm);
00491 fsm->state = ec_fsm_soe_error;
00492 return;
00493 }
00494
00495 data_size = rec_size - EC_SOE_SIZE;
00496 if (ec_soe_request_append_data(req,
00497 data + EC_SOE_SIZE, data_size)) {
00498 fsm->state = ec_fsm_soe_error;
00499 ec_fsm_soe_print_error(fsm);
00500 return;
00501 }
00502
00503 if (incomplete) {
00504 EC_SLAVE_DBG(slave, 1, "SoE data incomplete. Waiting for fragment"
00505 " at offset %zu.\n", req->data_size);
00506 fsm->jiffies_start = fsm->datagram->jiffies_sent;
00507 ec_slave_mbox_prepare_check(slave, datagram);
00508 fsm->retries = EC_FSM_RETRIES;
00509 fsm->state = ec_fsm_soe_read_check;
00510 } else {
00511 if (master->debug_level) {
00512 EC_SLAVE_DBG(slave, 0, "IDN data:\n");
00513 ec_print_data(req->data, req->data_size);
00514 }
00515
00516 fsm->state = ec_fsm_soe_end;
00517 }
00518 }
00519
00520
00521
00522
00523
00526 void ec_fsm_soe_write_next_fragment(
00527 ec_fsm_soe_t *fsm,
00528 ec_datagram_t *datagram
00529 )
00530 {
00531 ec_slave_t *slave = fsm->slave;
00532 ec_master_t *master = slave->master;
00533 ec_soe_request_t *req = fsm->request;
00534 uint8_t incomplete, *data;
00535 size_t max_fragment_size, remaining_size;
00536 uint16_t fragments_left;
00537
00538 remaining_size = req->data_size - fsm->offset;
00539 max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE;
00540 incomplete = remaining_size > max_fragment_size;
00541 fsm->fragment_size = incomplete ? max_fragment_size : remaining_size;
00542 fragments_left = remaining_size / fsm->fragment_size - 1;
00543 if (remaining_size % fsm->fragment_size) {
00544 fragments_left++;
00545 }
00546
00547 data = ec_slave_mbox_prepare_send(slave, datagram, EC_MBOX_TYPE_SOE,
00548 EC_SOE_SIZE + fsm->fragment_size);
00549 if (IS_ERR(data)) {
00550 fsm->state = ec_fsm_soe_error;
00551 ec_fsm_soe_print_error(fsm);
00552 return;
00553 }
00554
00555 EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 |
00556 (req->drive_no & 0x07) << 5);
00557 EC_WRITE_U8(data + 1, 1 << 6);
00558 EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn);
00559 memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size);
00560
00561 if (master->debug_level) {
00562 EC_SLAVE_DBG(slave, 0, "SSC write request:\n");
00563 ec_print_data(data, EC_SOE_SIZE + fsm->fragment_size);
00564 }
00565
00566 req->jiffies_sent = jiffies;
00567 fsm->state = ec_fsm_soe_write_request;
00568 }
00569
00570
00571
00574 void ec_fsm_soe_write_start(
00575 ec_fsm_soe_t *fsm,
00576 ec_datagram_t *datagram
00577 )
00578 {
00579 ec_slave_t *slave = fsm->slave;
00580 ec_soe_request_t *req = fsm->request;
00581
00582 EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n",
00583 req->idn, req->drive_no, req->data_size);
00584
00585 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) {
00586 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n");
00587 fsm->state = ec_fsm_soe_error;
00588 ec_fsm_soe_print_error(fsm);
00589 return;
00590 }
00591
00592 if (slave->configured_rx_mailbox_size <= EC_SOE_HEADER_SIZE) {
00593 EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n",
00594 slave->configured_rx_mailbox_size);
00595 fsm->state = ec_fsm_soe_error;
00596 ec_fsm_soe_print_error(fsm);
00597 return;
00598 }
00599
00600 fsm->offset = 0;
00601 fsm->retries = EC_FSM_RETRIES;
00602 ec_fsm_soe_write_next_fragment(fsm, datagram);
00603 }
00604
00605
00606
00609 void ec_fsm_soe_write_request(
00610 ec_fsm_soe_t *fsm,
00611 ec_datagram_t *datagram
00612 )
00613 {
00614 ec_slave_t *slave = fsm->slave;
00615 unsigned long diff_ms;
00616
00617 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00618 ec_fsm_soe_write_next_fragment(fsm, datagram);
00619 return;
00620 }
00621
00622 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00623 fsm->state = ec_fsm_soe_error;
00624 EC_SLAVE_ERR(slave, "Failed to receive SoE write request: ");
00625 ec_datagram_print_state(fsm->datagram);
00626 ec_fsm_soe_print_error(fsm);
00627 return;
00628 }
00629
00630 diff_ms = (jiffies - fsm->request->jiffies_sent) * 1000 / HZ;
00631
00632 if (fsm->datagram->working_counter != 1) {
00633 if (!fsm->datagram->working_counter) {
00634 if (diff_ms < EC_SOE_RESPONSE_TIMEOUT) {
00635
00636 ec_fsm_soe_write_next_fragment(fsm, datagram);
00637 return;
00638 }
00639 }
00640 fsm->state = ec_fsm_soe_error;
00641 EC_SLAVE_ERR(slave, "Reception of SoE write request"
00642 " failed after %lu ms: ", diff_ms);
00643 ec_datagram_print_wc_error(fsm->datagram);
00644 ec_fsm_soe_print_error(fsm);
00645 return;
00646 }
00647
00648
00649 fsm->offset += fsm->fragment_size;
00650
00651 if (fsm->offset < fsm->request->data_size) {
00652
00653 fsm->retries = EC_FSM_RETRIES;
00654 ec_fsm_soe_write_next_fragment(fsm, datagram);
00655 } else {
00656
00657 fsm->jiffies_start = fsm->datagram->jiffies_sent;
00658 ec_slave_mbox_prepare_check(slave, datagram);
00659 fsm->retries = EC_FSM_RETRIES;
00660 fsm->state = ec_fsm_soe_write_check;
00661 }
00662 }
00663
00664
00665
00668 void ec_fsm_soe_write_check(
00669 ec_fsm_soe_t *fsm,
00670 ec_datagram_t *datagram
00671 )
00672 {
00673 ec_slave_t *slave = fsm->slave;
00674
00675 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00676 ec_slave_mbox_prepare_check(slave, datagram);
00677 return;
00678 }
00679
00680 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00681 fsm->state = ec_fsm_soe_error;
00682 EC_SLAVE_ERR(slave, "Failed to receive SoE write request datagram: ");
00683 ec_datagram_print_state(fsm->datagram);
00684 ec_fsm_soe_print_error(fsm);
00685 return;
00686 }
00687
00688 if (fsm->datagram->working_counter != 1) {
00689 fsm->state = ec_fsm_soe_error;
00690 EC_SLAVE_ERR(slave, "Reception of SoE write request datagram: ");
00691 ec_datagram_print_wc_error(fsm->datagram);
00692 ec_fsm_soe_print_error(fsm);
00693 return;
00694 }
00695
00696 if (!ec_slave_mbox_check(fsm->datagram)) {
00697 unsigned long diff_ms =
00698 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ;
00699 if (diff_ms >= EC_SOE_RESPONSE_TIMEOUT) {
00700 fsm->state = ec_fsm_soe_error;
00701 EC_SLAVE_ERR(slave, "Timeout after %lu ms while waiting"
00702 " for write response.\n", diff_ms);
00703 ec_fsm_soe_print_error(fsm);
00704 return;
00705 }
00706
00707 ec_slave_mbox_prepare_check(slave, datagram);
00708 fsm->retries = EC_FSM_RETRIES;
00709 return;
00710 }
00711
00712
00713 ec_slave_mbox_prepare_fetch(slave, datagram);
00714 fsm->retries = EC_FSM_RETRIES;
00715 fsm->state = ec_fsm_soe_write_response;
00716 }
00717
00718
00719
00722 void ec_fsm_soe_write_response(
00723 ec_fsm_soe_t *fsm,
00724 ec_datagram_t *datagram
00725 )
00726 {
00727 ec_slave_t *slave = fsm->slave;
00728 ec_master_t *master = slave->master;
00729 ec_soe_request_t *req = fsm->request;
00730 uint8_t *data, mbox_prot, opcode, error_flag;
00731 uint16_t idn;
00732 size_t rec_size;
00733
00734 if (fsm->datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
00735 ec_slave_mbox_prepare_fetch(slave, datagram);
00736 return;
00737 }
00738
00739 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) {
00740 fsm->state = ec_fsm_soe_error;
00741 EC_SLAVE_ERR(slave, "Failed to receive SoE write"
00742 " response datagram: ");
00743 ec_datagram_print_state(fsm->datagram);
00744 ec_fsm_soe_print_error(fsm);
00745 return;
00746 }
00747
00748 if (fsm->datagram->working_counter != 1) {
00749 fsm->state = ec_fsm_soe_error;
00750 EC_SLAVE_ERR(slave, "Reception of SoE write response failed: ");
00751 ec_datagram_print_wc_error(fsm->datagram);
00752 ec_fsm_soe_print_error(fsm);
00753 return;
00754 }
00755
00756 data = ec_slave_mbox_fetch(slave, fsm->datagram, &mbox_prot, &rec_size);
00757 if (IS_ERR(data)) {
00758 fsm->state = ec_fsm_soe_error;
00759 ec_fsm_soe_print_error(fsm);
00760 return;
00761 }
00762
00763 if (master->debug_level) {
00764 EC_SLAVE_DBG(slave, 0, "SSC write response:\n");
00765 ec_print_data(data, rec_size);
00766 }
00767
00768 if (mbox_prot != EC_MBOX_TYPE_SOE) {
00769 fsm->state = ec_fsm_soe_error;
00770 EC_SLAVE_ERR(slave, "Received mailbox protocol 0x%02X as response.\n",
00771 mbox_prot);
00772 ec_fsm_soe_print_error(fsm);
00773 return;
00774 }
00775
00776 if (rec_size < EC_SOE_SIZE) {
00777 fsm->state = ec_fsm_soe_error;
00778 EC_SLAVE_ERR(slave, "Received corrupted SoE write response"
00779 " (%zu bytes)!\n", rec_size);
00780 ec_print_data(data, rec_size);
00781 ec_fsm_soe_print_error(fsm);
00782 return;
00783 }
00784
00785 opcode = EC_READ_U8(data) & 0x7;
00786 if (opcode != OPCODE_WRITE_RESPONSE) {
00787 EC_SLAVE_ERR(slave, "Received no write response"
00788 " (opcode %x).\n", opcode);
00789 ec_print_data(data, rec_size);
00790 ec_fsm_soe_print_error(fsm);
00791 fsm->state = ec_fsm_soe_error;
00792 return;
00793 }
00794
00795 idn = EC_READ_U16(data + 2);
00796 if (idn != req->idn) {
00797 EC_SLAVE_ERR(slave, "Received response for"
00798 " wrong IDN 0x%04x.\n", idn);
00799 ec_print_data(data, rec_size);
00800 ec_fsm_soe_print_error(fsm);
00801 fsm->state = ec_fsm_soe_error;
00802 return;
00803 }
00804
00805 error_flag = (EC_READ_U8(data) >> 4) & 1;
00806 if (error_flag) {
00807 if (rec_size < EC_SOE_SIZE + 2) {
00808 EC_SLAVE_ERR(slave, "Received corrupted error response"
00809 " - error flag set, but received size is %zu.\n",
00810 rec_size);
00811 } else {
00812 req->error_code = EC_READ_U16(data + EC_SOE_SIZE);
00813 EC_SLAVE_ERR(slave, "Received error response:\n");
00814 ec_print_soe_error(slave, req->error_code);
00815 }
00816 ec_print_data(data, rec_size);
00817 ec_fsm_soe_print_error(fsm);
00818 fsm->state = ec_fsm_soe_error;
00819 } else {
00820 req->error_code = 0x0000;
00821 fsm->state = ec_fsm_soe_end;
00822 }
00823 }
00824
00825
00826
00829 void ec_fsm_soe_error(
00830 ec_fsm_soe_t *fsm,
00831 ec_datagram_t *datagram
00832 )
00833 {
00834 }
00835
00836
00837
00840 void ec_fsm_soe_end(
00841 ec_fsm_soe_t *fsm,
00842 ec_datagram_t *datagram
00843 )
00844 {
00845 }
00846
00847