master/mailbox.c
changeset 1337 0253c74d0940
parent 1326 ef907b0b5125
child 1338 eb31b5a135da
equal deleted inserted replaced
1336:e27b37e80a99 1337:0253c74d0940
    51                                     size_t size /**< size of the data */
    51                                     size_t size /**< size of the data */
    52                                     )
    52                                     )
    53 {
    53 {
    54     size_t total_size;
    54     size_t total_size;
    55     int ret;
    55     int ret;
       
    56     uint16_t mailbox_offset, mailbox_size;
    56 
    57 
    57     if (unlikely(!slave->sii.mailbox_protocols)) {
    58     if (unlikely(!slave->sii.mailbox_protocols)) {
    58         EC_ERR("Slave %u does not support mailbox communication!\n",
    59         EC_ERR("Slave %u does not support mailbox communication!\n",
    59                slave->ring_position);
    60                slave->ring_position);
    60         return ERR_PTR(-EPROTONOSUPPORT);
    61         return ERR_PTR(-EPROTONOSUPPORT);
    61     }
    62     }
    62 
    63 
    63     total_size = EC_MBOX_HEADER_SIZE + size;
    64     total_size = EC_MBOX_HEADER_SIZE + size;
    64     if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
    65 
       
    66     if (slave->current_state != EC_SLAVE_STATE_BOOT) {
       
    67         mailbox_offset = slave->sii.std_rx_mailbox_offset;
       
    68         mailbox_size = slave->sii.std_rx_mailbox_size;
       
    69     } else {
       
    70         mailbox_offset = slave->sii.boot_rx_mailbox_offset;
       
    71         mailbox_size = slave->sii.boot_rx_mailbox_size;
       
    72     }
       
    73 
       
    74     if (unlikely(total_size > mailbox_size)) {
    65         EC_ERR("Data size does not fit in mailbox!\n");
    75         EC_ERR("Data size does not fit in mailbox!\n");
    66         return ERR_PTR(-EOVERFLOW);
    76         return ERR_PTR(-EOVERFLOW);
    67     }
    77     }
    68 
    78 
    69     ret = ec_datagram_fpwr(datagram, slave->station_address,
    79     ret = ec_datagram_fpwr(datagram, slave->station_address,
    70                          slave->sii.rx_mailbox_offset,
    80             mailbox_offset, mailbox_size);
    71                          slave->sii.rx_mailbox_size);
       
    72     if (ret)
    81     if (ret)
    73         return ERR_PTR(ret);
    82         return ERR_PTR(ret);
    74 
    83 
    75     EC_WRITE_U16(datagram->data,     size); // mailbox service data length
    84     EC_WRITE_U16(datagram->data,     size); // mailbox service data length
    76     EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
    85     EC_WRITE_U16(datagram->data + 2, slave->station_address); // station addr.
   121 
   130 
   122 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
   131 int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
   123                                 ec_datagram_t *datagram /**< datagram */
   132                                 ec_datagram_t *datagram /**< datagram */
   124                                 )
   133                                 )
   125 {
   134 {
   126     int ret = ec_datagram_fprd(datagram, slave->station_address,
   135     int ret;
   127                          slave->sii.tx_mailbox_offset,
   136     uint16_t mailbox_offset, mailbox_size;
   128                          slave->sii.tx_mailbox_size);
   137 
       
   138     if (slave->current_state != EC_SLAVE_STATE_BOOT) {
       
   139         mailbox_offset = slave->sii.std_tx_mailbox_offset;
       
   140         mailbox_size = slave->sii.std_tx_mailbox_size;
       
   141     } else {
       
   142         mailbox_offset = slave->sii.boot_tx_mailbox_offset;
       
   143         mailbox_size = slave->sii.boot_tx_mailbox_size;
       
   144     }
       
   145 
       
   146     ret = ec_datagram_fprd(datagram, slave->station_address,
       
   147             mailbox_offset, mailbox_size);
   129     if (ret)
   148     if (ret)
   130         return ret;
   149         return ret;
   131 
   150 
   132     ec_datagram_zero(datagram);
   151     ec_datagram_zero(datagram);
   133     return 0;
   152     return 0;
   162                              uint8_t *type, /**< expected mailbox protocol */
   181                              uint8_t *type, /**< expected mailbox protocol */
   163                              size_t *size /**< size of the received data */
   182                              size_t *size /**< size of the received data */
   164                              )
   183                              )
   165 {
   184 {
   166     size_t data_size;
   185     size_t data_size;
       
   186     uint16_t mailbox_offset, mailbox_size;
       
   187 
       
   188     if (slave->current_state != EC_SLAVE_STATE_BOOT) {
       
   189         mailbox_offset = slave->sii.std_tx_mailbox_offset;
       
   190         mailbox_size = slave->sii.std_tx_mailbox_size;
       
   191     } else {
       
   192         mailbox_offset = slave->sii.boot_tx_mailbox_offset;
       
   193         mailbox_size = slave->sii.boot_tx_mailbox_size;
       
   194     }
   167 
   195 
   168     data_size = EC_READ_U16(datagram->data);
   196     data_size = EC_READ_U16(datagram->data);
   169 
   197 
   170     if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) {
   198     if (data_size + EC_MBOX_HEADER_SIZE > mailbox_size) {
   171         EC_ERR("Corrupt mailbox response received from slave %u!\n",
   199         EC_ERR("Corrupt mailbox response received from slave %u!\n",
   172                slave->ring_position);
   200                 slave->ring_position);
   173         ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
   201         ec_print_data(datagram->data, mailbox_size);
   174         return ERR_PTR(-EPROTO);
   202         return ERR_PTR(-EPROTO);
   175     }
   203     }
   176 
   204 
   177     *type = EC_READ_U8(datagram->data + 5) & 0x0F;
   205     *type = EC_READ_U8(datagram->data + 5) & 0x0F;
   178     *size = data_size;
   206     *size = data_size;
   183 
   211 
   184         EC_ERR("Mailbox error response received from slave %u - ",
   212         EC_ERR("Mailbox error response received from slave %u - ",
   185                 slave->ring_position);
   213                 slave->ring_position);
   186 
   214 
   187         for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
   215         for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
   188             if (mbox_msg->code != code) continue;
   216             if (mbox_msg->code != code)
       
   217                 continue;
   189             printk("Code 0x%04X: \"%s\".\n",
   218             printk("Code 0x%04X: \"%s\".\n",
   190                    mbox_msg->code, mbox_msg->message);
   219                     mbox_msg->code, mbox_msg->message);
   191             break;
   220             break;
   192         }
   221         }
   193 
   222 
   194         if (!mbox_msg->code)
   223         if (!mbox_msg->code)
   195             printk("Unknown error reply code 0x%04X.\n", code);
   224             printk("Unknown error reply code 0x%04X.\n", code);