56 |
56 |
57 /** Size of all SoE headers. |
57 /** Size of all SoE headers. |
58 */ |
58 */ |
59 #define EC_SOE_SIZE 0x04 |
59 #define EC_SOE_SIZE 0x04 |
60 |
60 |
|
61 /** SoE header size. |
|
62 */ |
|
63 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE) |
|
64 |
61 /** SoE response timeout [ms]. |
65 /** SoE response timeout [ms]. |
62 */ |
66 */ |
63 #define EC_SOE_RESPONSE_TIMEOUT 1000 |
67 #define EC_SOE_RESPONSE_TIMEOUT 1000 |
64 |
68 |
65 /*****************************************************************************/ |
69 /*****************************************************************************/ |
235 EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5); |
239 EC_WRITE_U8(data, OPCODE_READ_REQUEST | (request->drive_no & 0x07) << 5); |
236 EC_WRITE_U8(data + 1, 1 << 6); // request value |
240 EC_WRITE_U8(data + 1, 1 << 6); // request value |
237 EC_WRITE_U16(data + 2, request->idn); |
241 EC_WRITE_U16(data + 2, request->idn); |
238 |
242 |
239 if (master->debug_level) { |
243 if (master->debug_level) { |
240 EC_SLAVE_DBG(slave, 0, "SCC read request:\n"); |
244 EC_SLAVE_DBG(slave, 0, "SSC read request:\n"); |
241 ec_print_data(data, EC_SOE_SIZE); |
245 ec_print_data(data, EC_SOE_SIZE); |
242 } |
246 } |
243 |
247 |
244 fsm->request->jiffies_sent = jiffies; |
248 fsm->request->jiffies_sent = jiffies; |
245 fsm->state = ec_fsm_soe_read_request; |
249 fsm->state = ec_fsm_soe_read_request; |
432 ec_fsm_soe_print_error(fsm); |
436 ec_fsm_soe_print_error(fsm); |
433 return; |
437 return; |
434 } |
438 } |
435 |
439 |
436 if (master->debug_level) { |
440 if (master->debug_level) { |
437 EC_SLAVE_DBG(slave, 0, "SCC read response:\n"); |
441 EC_SLAVE_DBG(slave, 0, "SSC read response:\n"); |
438 ec_print_data(data, rec_size); |
442 ec_print_data(data, rec_size); |
439 } |
443 } |
440 |
444 |
441 if (mbox_prot != EC_MBOX_TYPE_SOE) { |
445 if (mbox_prot != EC_MBOX_TYPE_SOE) { |
442 fsm->state = ec_fsm_soe_error; |
446 fsm->state = ec_fsm_soe_error; |
526 { |
530 { |
527 ec_slave_t *slave = fsm->slave; |
531 ec_slave_t *slave = fsm->slave; |
528 ec_master_t *master = slave->master; |
532 ec_master_t *master = slave->master; |
529 ec_soe_request_t *req = fsm->request; |
533 ec_soe_request_t *req = fsm->request; |
530 uint8_t incomplete, *data; |
534 uint8_t incomplete, *data; |
531 size_t header_size, max_fragment_size, remaining_size; |
535 size_t max_fragment_size, remaining_size; |
532 uint16_t fragments_left; |
536 uint16_t fragments_left; |
533 |
537 |
534 header_size = EC_MBOX_HEADER_SIZE + EC_SOE_SIZE; |
|
535 if (slave->configured_rx_mailbox_size <= header_size) { |
|
536 EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n", |
|
537 slave->configured_rx_mailbox_size); |
|
538 fsm->state = ec_fsm_soe_error; |
|
539 ec_fsm_soe_print_error(fsm); |
|
540 return; |
|
541 } |
|
542 |
|
543 remaining_size = req->data_size - fsm->offset; |
538 remaining_size = req->data_size - fsm->offset; |
544 max_fragment_size = slave->configured_rx_mailbox_size - header_size; |
539 max_fragment_size = slave->configured_rx_mailbox_size - EC_SOE_HEADER_SIZE; |
545 incomplete = remaining_size > max_fragment_size; |
540 incomplete = remaining_size > max_fragment_size; |
546 fsm->fragment_size = incomplete ? max_fragment_size : remaining_size; |
541 fsm->fragment_size = incomplete ? max_fragment_size : remaining_size; |
547 fragments_left = remaining_size / fsm->fragment_size - 1; |
542 fragments_left = remaining_size / fsm->fragment_size - 1; |
548 if (remaining_size % fsm->fragment_size) { |
543 if (remaining_size % fsm->fragment_size) { |
549 fragments_left++; |
544 fragments_left++; |
559 |
554 |
560 EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 | |
555 EC_WRITE_U8(data, OPCODE_WRITE_REQUEST | incomplete << 3 | |
561 (req->drive_no & 0x07) << 5); |
556 (req->drive_no & 0x07) << 5); |
562 EC_WRITE_U8(data + 1, 1 << 6); // only value included |
557 EC_WRITE_U8(data + 1, 1 << 6); // only value included |
563 EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn); |
558 EC_WRITE_U16(data + 2, incomplete ? fragments_left : req->idn); |
564 memcpy(data + 4, req->data + fsm->offset, fsm->fragment_size); |
559 memcpy(data + EC_SOE_SIZE, req->data + fsm->offset, fsm->fragment_size); |
565 |
560 |
566 if (master->debug_level) { |
561 if (master->debug_level) { |
567 EC_SLAVE_DBG(slave, 0, "SCC write request:\n"); |
562 EC_SLAVE_DBG(slave, 0, "SSC write request:\n"); |
568 ec_print_data(data, EC_SOE_SIZE + fsm->fragment_size); |
563 ec_print_data(data, EC_SOE_SIZE + fsm->fragment_size); |
569 } |
564 } |
570 |
565 |
571 req->jiffies_sent = jiffies; |
566 req->jiffies_sent = jiffies; |
572 fsm->state = ec_fsm_soe_write_request; |
567 fsm->state = ec_fsm_soe_write_request; |
587 EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n", |
582 EC_SLAVE_DBG(slave, 1, "Writing IDN 0x%04X of drive %u (%zu byte).\n", |
588 req->idn, req->drive_no, req->data_size); |
583 req->idn, req->drive_no, req->data_size); |
589 |
584 |
590 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) { |
585 if (!(slave->sii.mailbox_protocols & EC_MBOX_SOE)) { |
591 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n"); |
586 EC_SLAVE_ERR(slave, "Slave does not support SoE!\n"); |
|
587 fsm->state = ec_fsm_soe_error; |
|
588 ec_fsm_soe_print_error(fsm); |
|
589 return; |
|
590 } |
|
591 |
|
592 if (slave->configured_rx_mailbox_size <= EC_SOE_HEADER_SIZE) { |
|
593 EC_SLAVE_ERR(slave, "Mailbox size (%u) too small for SoE write.\n", |
|
594 slave->configured_rx_mailbox_size); |
592 fsm->state = ec_fsm_soe_error; |
595 fsm->state = ec_fsm_soe_error; |
593 ec_fsm_soe_print_error(fsm); |
596 ec_fsm_soe_print_error(fsm); |
594 return; |
597 return; |
595 } |
598 } |
596 |
599 |
640 ec_datagram_print_wc_error(fsm->datagram); |
643 ec_datagram_print_wc_error(fsm->datagram); |
641 ec_fsm_soe_print_error(fsm); |
644 ec_fsm_soe_print_error(fsm); |
642 return; |
645 return; |
643 } |
646 } |
644 |
647 |
645 fsm->jiffies_start = fsm->datagram->jiffies_sent; |
648 // fragment successfully sent |
646 |
649 fsm->offset += fsm->fragment_size; |
647 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
650 |
648 fsm->retries = EC_FSM_RETRIES; |
651 if (fsm->offset < fsm->request->data_size) { |
649 fsm->state = ec_fsm_soe_write_check; |
652 // next fragment |
|
653 fsm->retries = EC_FSM_RETRIES; |
|
654 ec_fsm_soe_write_next_fragment(fsm, datagram); |
|
655 } else { |
|
656 // all fragments sent; query response |
|
657 fsm->jiffies_start = fsm->datagram->jiffies_sent; |
|
658 ec_slave_mbox_prepare_check(slave, datagram); // can not fail. |
|
659 fsm->retries = EC_FSM_RETRIES; |
|
660 fsm->state = ec_fsm_soe_write_check; |
|
661 } |
650 } |
662 } |
651 |
663 |
652 /*****************************************************************************/ |
664 /*****************************************************************************/ |
653 |
665 |
654 /** CoE state: WRITE CHECK. |
666 /** CoE state: WRITE CHECK. |
747 ec_fsm_soe_print_error(fsm); |
759 ec_fsm_soe_print_error(fsm); |
748 return; |
760 return; |
749 } |
761 } |
750 |
762 |
751 if (master->debug_level) { |
763 if (master->debug_level) { |
752 EC_SLAVE_DBG(slave, 0, "SCC write response:\n"); |
764 EC_SLAVE_DBG(slave, 0, "SSC write response:\n"); |
753 ec_print_data(data, rec_size); |
765 ec_print_data(data, rec_size); |
754 } |
766 } |
755 |
767 |
756 if (mbox_prot != EC_MBOX_TYPE_SOE) { |
768 if (mbox_prot != EC_MBOX_TYPE_SOE) { |
757 fsm->state = ec_fsm_soe_error; |
769 fsm->state = ec_fsm_soe_error; |
802 ec_print_soe_error(slave, req->error_code); |
814 ec_print_soe_error(slave, req->error_code); |
803 } |
815 } |
804 ec_print_data(data, rec_size); |
816 ec_print_data(data, rec_size); |
805 ec_fsm_soe_print_error(fsm); |
817 ec_fsm_soe_print_error(fsm); |
806 fsm->state = ec_fsm_soe_error; |
818 fsm->state = ec_fsm_soe_error; |
807 return; |
|
808 } else { |
819 } else { |
809 req->error_code = 0x0000; |
820 req->error_code = 0x0000; |
810 } |
|
811 |
|
812 fsm->offset += fsm->fragment_size; |
|
813 |
|
814 if (fsm->offset < req->data_size) { |
|
815 fsm->retries = EC_FSM_RETRIES; |
|
816 ec_fsm_soe_write_next_fragment(fsm, datagram); |
|
817 } else { |
|
818 fsm->state = ec_fsm_soe_end; // success |
821 fsm->state = ec_fsm_soe_end; // success |
819 } |
822 } |
820 } |
823 } |
821 |
824 |
822 /*****************************************************************************/ |
825 /*****************************************************************************/ |