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); |