master/fsm_soe.c
branchstable-1.5
changeset 2648 0f4b7d799c44
parent 2498 9cdd7669dc0b
equal deleted inserted replaced
2640:b11e1014edfe 2648:0f4b7d799c44
    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 /*****************************************************************************/