72 EC_FOE_OPCODE_BUSY = 6 /**< Busy. */ |
72 EC_FOE_OPCODE_BUSY = 6 /**< Busy. */ |
73 } ec_foe_opcode_t; |
73 } ec_foe_opcode_t; |
74 |
74 |
75 /*****************************************************************************/ |
75 /*****************************************************************************/ |
76 |
76 |
77 int ec_foe_prepare_data_send(ec_fsm_foe_t *); |
77 int ec_foe_prepare_data_send(ec_fsm_foe_t *, ec_datagram_t *); |
78 int ec_foe_prepare_wrq_send(ec_fsm_foe_t *); |
78 int ec_foe_prepare_wrq_send(ec_fsm_foe_t *, ec_datagram_t *); |
79 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *); |
79 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *, ec_datagram_t *); |
80 int ec_foe_prepare_send_ack(ec_fsm_foe_t *); |
80 int ec_foe_prepare_send_ack(ec_fsm_foe_t *, ec_datagram_t *); |
81 |
81 |
82 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t); |
82 void ec_foe_set_tx_error(ec_fsm_foe_t *, uint32_t); |
83 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t); |
83 void ec_foe_set_rx_error(ec_fsm_foe_t *, uint32_t); |
84 |
84 |
85 void ec_fsm_foe_write(ec_fsm_foe_t *); |
85 void ec_fsm_foe_end(ec_fsm_foe_t *, ec_datagram_t *); |
86 void ec_fsm_foe_read(ec_fsm_foe_t *); |
86 void ec_fsm_foe_error(ec_fsm_foe_t *, ec_datagram_t *); |
87 void ec_fsm_foe_end(ec_fsm_foe_t *); |
87 |
88 void ec_fsm_foe_error(ec_fsm_foe_t *); |
88 void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *, ec_datagram_t *); |
89 |
89 void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *, ec_datagram_t *); |
90 void ec_fsm_foe_state_wrq_sent(ec_fsm_foe_t *); |
90 |
91 void ec_fsm_foe_state_rrq_sent(ec_fsm_foe_t *); |
91 void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *, ec_datagram_t *); |
92 |
92 void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *, ec_datagram_t *); |
93 void ec_fsm_foe_state_ack_check(ec_fsm_foe_t *); |
93 |
94 void ec_fsm_foe_state_ack_read(ec_fsm_foe_t *); |
94 void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *, ec_datagram_t *); |
95 |
95 |
96 void ec_fsm_foe_state_data_sent(ec_fsm_foe_t *); |
96 void ec_fsm_foe_state_data_check(ec_fsm_foe_t *, ec_datagram_t *); |
97 |
97 void ec_fsm_foe_state_data_read(ec_fsm_foe_t *, ec_datagram_t *); |
98 void ec_fsm_foe_state_data_check(ec_fsm_foe_t *); |
98 void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *, ec_datagram_t *); |
99 void ec_fsm_foe_state_data_read(ec_fsm_foe_t *); |
99 |
100 void ec_fsm_foe_state_sent_ack(ec_fsm_foe_t *); |
100 void ec_fsm_foe_write_start(ec_fsm_foe_t *, ec_datagram_t *); |
101 |
101 void ec_fsm_foe_read_start(ec_fsm_foe_t *, ec_datagram_t *); |
102 void ec_fsm_foe_write_start(ec_fsm_foe_t *); |
|
103 void ec_fsm_foe_read_start(ec_fsm_foe_t *); |
|
104 |
102 |
105 /*****************************************************************************/ |
103 /*****************************************************************************/ |
106 |
104 |
107 /** Constructor. |
105 /** Constructor. |
108 */ |
106 */ |
109 void ec_fsm_foe_init(ec_fsm_foe_t *fsm, /**< finite state machine */ |
107 void ec_fsm_foe_init( |
110 ec_datagram_t *datagram /**< datagram */ |
108 ec_fsm_foe_t *fsm /**< finite state machine */ |
111 ) |
109 ) |
112 { |
110 { |
113 fsm->state = NULL; |
111 fsm->state = NULL; |
114 fsm->datagram = datagram; |
112 fsm->datagram = NULL; |
115 } |
113 } |
116 |
114 |
117 /*****************************************************************************/ |
115 /*****************************************************************************/ |
118 |
116 |
119 /** Destructor. |
117 /** Destructor. |
123 } |
121 } |
124 |
122 |
125 /*****************************************************************************/ |
123 /*****************************************************************************/ |
126 |
124 |
127 /** Executes the current state of the state machine. |
125 /** Executes the current state of the state machine. |
128 * \return false, if state machine has terminated |
126 * |
129 */ |
127 * \return 1, if the datagram was used, else 0. |
130 int ec_fsm_foe_exec(ec_fsm_foe_t *fsm /**< finite state machine */) |
128 */ |
131 { |
129 int ec_fsm_foe_exec( |
132 fsm->state(fsm); |
130 ec_fsm_foe_t *fsm, /**< finite state machine */ |
133 |
131 ec_datagram_t *datagram /**< Datagram to use. */ |
134 return fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error; |
132 ) |
|
133 { |
|
134 int datagram_used = 0; |
|
135 |
|
136 if (fsm->datagram && |
|
137 (fsm->datagram->state == EC_DATAGRAM_INIT || |
|
138 fsm->datagram->state == EC_DATAGRAM_QUEUED || |
|
139 fsm->datagram->state == EC_DATAGRAM_SENT)) { |
|
140 // datagram not received yet |
|
141 return datagram_used; |
|
142 } |
|
143 |
|
144 fsm->state(fsm, datagram); |
|
145 |
|
146 datagram_used = |
|
147 fsm->state != ec_fsm_foe_end && fsm->state != ec_fsm_foe_error; |
|
148 |
|
149 if (datagram_used) { |
|
150 fsm->datagram = datagram; |
|
151 } else { |
|
152 fsm->datagram = NULL; |
|
153 } |
|
154 |
|
155 return datagram_used; |
135 } |
156 } |
136 |
157 |
137 /*****************************************************************************/ |
158 /*****************************************************************************/ |
138 |
159 |
139 /** Returns, if the state machine terminated with success. |
160 /** Returns, if the state machine terminated with success. |
140 * \return non-zero if successful. |
161 * \return non-zero if successful. |
141 */ |
162 */ |
142 int ec_fsm_foe_success(ec_fsm_foe_t *fsm /**< Finite state machine */) |
163 int ec_fsm_foe_success(const ec_fsm_foe_t *fsm /**< Finite state machine */) |
143 { |
164 { |
144 return fsm->state == ec_fsm_foe_end; |
165 return fsm->state == ec_fsm_foe_end; |
145 } |
166 } |
146 |
167 |
147 /*****************************************************************************/ |
168 /*****************************************************************************/ |
154 ec_foe_request_t *request /**< Sdo request. */ |
175 ec_foe_request_t *request /**< Sdo request. */ |
155 ) |
176 ) |
156 { |
177 { |
157 fsm->slave = slave; |
178 fsm->slave = slave; |
158 fsm->request = request; |
179 fsm->request = request; |
|
180 |
159 if (request->dir == EC_DIR_OUTPUT) { |
181 if (request->dir == EC_DIR_OUTPUT) { |
160 fsm->state = ec_fsm_foe_write; |
182 fsm->tx_buffer = fsm->request->buffer; |
|
183 fsm->tx_buffer_size = fsm->request->data_size; |
|
184 fsm->tx_buffer_offset = 0; |
|
185 |
|
186 fsm->tx_filename = fsm->request->file_name; |
|
187 fsm->tx_filename_len = strlen(fsm->tx_filename); |
|
188 |
|
189 fsm->state = ec_fsm_foe_write_start; |
161 } |
190 } |
162 else { |
191 else { |
163 fsm->state = ec_fsm_foe_read; |
192 fsm->rx_buffer = fsm->request->buffer; |
|
193 fsm->rx_buffer_size = fsm->request->buffer_size; |
|
194 |
|
195 fsm->rx_filename = fsm->request->file_name; |
|
196 fsm->rx_filename_len = strlen(fsm->rx_filename); |
|
197 |
|
198 fsm->state = ec_fsm_foe_read_start; |
164 } |
199 } |
165 } |
200 } |
166 |
201 |
167 /*****************************************************************************/ |
202 /*****************************************************************************/ |
168 |
203 |
169 /** State: ERROR. |
204 /** State: ERROR. |
170 */ |
205 */ |
171 void ec_fsm_foe_error(ec_fsm_foe_t *fsm /**< finite state machine */) |
206 void ec_fsm_foe_error( |
|
207 ec_fsm_foe_t *fsm, /**< finite state machine */ |
|
208 ec_datagram_t *datagram /**< Datagram to use. */ |
|
209 ) |
172 { |
210 { |
173 #ifdef DEBUG_FOE |
211 #ifdef DEBUG_FOE |
174 printk("ec_fsm_foe_error()\n"); |
212 printk("ec_fsm_foe_error()\n"); |
175 #endif |
213 #endif |
176 } |
214 } |
177 |
215 |
178 /*****************************************************************************/ |
216 /*****************************************************************************/ |
179 |
217 |
180 /** State: END. |
218 /** State: END. |
181 */ |
219 */ |
182 void ec_fsm_foe_end(ec_fsm_foe_t *fsm /**< finite state machine */) |
220 void ec_fsm_foe_end( |
|
221 ec_fsm_foe_t *fsm, /**< finite state machine */ |
|
222 ec_datagram_t *datagram /**< Datagram to use. */ |
|
223 ) |
183 { |
224 { |
184 #ifdef DEBUG_FOE |
225 #ifdef DEBUG_FOE |
185 printk("ec_fsm_foe_end\n"); |
226 printk("ec_fsm_foe_end\n"); |
186 #endif |
227 #endif |
187 } |
228 } |
188 |
229 |
189 /*****************************************************************************/ |
230 /*****************************************************************************/ |
190 |
231 |
191 /** Sends a file or the next fragment. |
232 /** Sends a file or the next fragment. |
192 */ |
233 */ |
193 int ec_foe_prepare_data_send(ec_fsm_foe_t *fsm) |
234 int ec_foe_prepare_data_send( |
|
235 ec_fsm_foe_t *fsm, |
|
236 ec_datagram_t *datagram /**< Datagram to use. */ |
|
237 ) |
194 { |
238 { |
195 size_t remaining_size, current_size; |
239 size_t remaining_size, current_size; |
196 uint8_t *data; |
240 uint8_t *data; |
197 |
241 |
198 remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset; |
242 remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset; |
205 current_size = fsm->slave->configured_tx_mailbox_size |
249 current_size = fsm->slave->configured_tx_mailbox_size |
206 - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE; |
250 - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE; |
207 } |
251 } |
208 |
252 |
209 data = ec_slave_mbox_prepare_send(fsm->slave, |
253 data = ec_slave_mbox_prepare_send(fsm->slave, |
210 fsm->datagram, EC_MBOX_TYPE_FILEACCESS, |
254 datagram, EC_MBOX_TYPE_FILEACCESS, |
211 current_size + EC_FOE_HEADER_SIZE); |
255 current_size + EC_FOE_HEADER_SIZE); |
212 if (IS_ERR(data)) |
256 if (IS_ERR(data)) { |
213 return -1; |
257 return -1; |
214 |
258 } |
215 EC_WRITE_U8 ( data, EC_FOE_OPCODE_DATA ); // OpCode = DataBlock req. |
259 |
216 EC_WRITE_U32( data + 2, fsm->tx_packet_no ); // PacketNo, Password |
260 EC_WRITE_U8 (data, EC_FOE_OPCODE_DATA); // OpCode = DataBlock req. |
|
261 EC_WRITE_U32(data + 2, fsm->tx_packet_no); // PacketNo, Password |
217 |
262 |
218 memcpy(data + EC_FOE_HEADER_SIZE, |
263 memcpy(data + EC_FOE_HEADER_SIZE, |
219 fsm->tx_buffer + fsm->tx_buffer_offset, current_size); |
264 fsm->tx_buffer + fsm->tx_buffer_offset, current_size); |
220 fsm->tx_current_size = current_size; |
265 fsm->tx_current_size = current_size; |
221 |
266 |
236 fsm->tx_packet_no = 0; |
284 fsm->tx_packet_no = 0; |
237 fsm->tx_last_packet = 0; |
285 fsm->tx_last_packet = 0; |
238 |
286 |
239 current_size = fsm->tx_filename_len; |
287 current_size = fsm->tx_filename_len; |
240 |
288 |
241 data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram, |
289 data = ec_slave_mbox_prepare_send(fsm->slave, datagram, |
242 EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE); |
290 EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE); |
243 if (IS_ERR(data)) |
291 if (IS_ERR(data)) { |
244 return -1; |
292 return -1; |
|
293 } |
245 |
294 |
246 EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request |
295 EC_WRITE_U16( data, EC_FOE_OPCODE_WRQ); // fsm write request |
247 EC_WRITE_U32( data + 2, fsm->tx_packet_no ); |
296 EC_WRITE_U32( data + 2, fsm->tx_packet_no ); |
248 |
297 |
249 memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size); |
298 memcpy(data + EC_FOE_HEADER_SIZE, fsm->tx_filename, current_size); |
251 return 0; |
300 return 0; |
252 } |
301 } |
253 |
302 |
254 /*****************************************************************************/ |
303 /*****************************************************************************/ |
255 |
304 |
256 /** Start a write operation. |
|
257 */ |
|
258 void ec_fsm_foe_write( |
|
259 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
|
260 ) |
|
261 { |
|
262 fsm->tx_buffer = fsm->request->buffer; |
|
263 fsm->tx_buffer_size = fsm->request->data_size; |
|
264 fsm->tx_buffer_offset = 0; |
|
265 |
|
266 fsm->tx_filename = fsm->request->file_name; |
|
267 fsm->tx_filename_len = strlen(fsm->tx_filename); |
|
268 |
|
269 fsm->state = ec_fsm_foe_write_start; |
|
270 } |
|
271 |
|
272 /*****************************************************************************/ |
|
273 |
|
274 /** Initializes the FoE write state machine. |
305 /** Initializes the FoE write state machine. |
275 */ |
306 */ |
276 void ec_fsm_foe_write_start(ec_fsm_foe_t *fsm /**< finite state machine */) |
307 void ec_fsm_foe_write_start( |
|
308 ec_fsm_foe_t *fsm, /**< finite state machine */ |
|
309 ec_datagram_t *datagram /**< Datagram to use. */ |
|
310 ) |
277 { |
311 { |
278 ec_slave_t *slave = fsm->slave; |
312 ec_slave_t *slave = fsm->slave; |
279 |
313 |
280 fsm->tx_buffer_offset = 0; |
314 fsm->tx_buffer_offset = 0; |
281 fsm->tx_current_size = 0; |
315 fsm->tx_current_size = 0; |
303 /*****************************************************************************/ |
337 /*****************************************************************************/ |
304 |
338 |
305 /** Check for acknowledge. |
339 /** Check for acknowledge. |
306 */ |
340 */ |
307 void ec_fsm_foe_state_ack_check( |
341 void ec_fsm_foe_state_ack_check( |
308 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
342 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
309 ) |
343 ec_datagram_t *datagram /**< Datagram to use. */ |
310 { |
344 ) |
311 ec_datagram_t *datagram = fsm->datagram; |
345 { |
312 ec_slave_t *slave = fsm->slave; |
346 ec_slave_t *slave = fsm->slave; |
313 |
347 |
314 #ifdef DEBUG_FOE |
348 #ifdef DEBUG_FOE |
315 printk("ec_fsm_foe_ack_check()\n"); |
349 printk("ec_fsm_foe_ack_check()\n"); |
316 #endif |
350 #endif |
317 |
351 |
318 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
352 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
319 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
353 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
320 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: "); |
354 EC_SLAVE_ERR(slave, "Failed to receive FoE mailbox check datagram: "); |
321 ec_datagram_print_state(datagram); |
355 ec_datagram_print_state(fsm->datagram); |
322 return; |
356 return; |
323 } |
357 } |
324 |
358 |
325 if (datagram->working_counter != 1) { |
359 if (fsm->datagram->working_counter != 1) { |
326 // slave did not put anything in the mailbox yet |
|
327 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
360 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
328 EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram" |
361 EC_SLAVE_ERR(slave, "Reception of FoE mailbox check datagram" |
329 " failed: "); |
362 " failed: "); |
330 ec_datagram_print_wc_error(datagram); |
363 ec_datagram_print_wc_error(fsm->datagram); |
331 return; |
364 return; |
332 } |
365 } |
333 |
366 |
334 if (!ec_slave_mbox_check(datagram)) { |
367 if (!ec_slave_mbox_check(fsm->datagram)) { |
|
368 // slave did not put anything in the mailbox yet |
335 unsigned long diff_ms = |
369 unsigned long diff_ms = |
336 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
370 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
337 if (diff_ms >= EC_FSM_FOE_TIMEOUT) { |
371 if (diff_ms >= EC_FSM_FOE_TIMEOUT) { |
338 ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR); |
372 ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR); |
339 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n"); |
373 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n"); |
355 /*****************************************************************************/ |
389 /*****************************************************************************/ |
356 |
390 |
357 /** Acknowledge a read operation. |
391 /** Acknowledge a read operation. |
358 */ |
392 */ |
359 void ec_fsm_foe_state_ack_read( |
393 void ec_fsm_foe_state_ack_read( |
360 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
394 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
361 ) |
395 ec_datagram_t *datagram /**< Datagram to use. */ |
362 { |
396 ) |
363 ec_datagram_t *datagram = fsm->datagram; |
397 { |
364 ec_slave_t *slave = fsm->slave; |
398 ec_slave_t *slave = fsm->slave; |
365 uint8_t *data, mbox_prot; |
399 uint8_t *data, mbox_prot; |
366 uint8_t opCode; |
400 uint8_t opCode; |
367 size_t rec_size; |
401 size_t rec_size; |
368 |
402 |
369 #ifdef DEBUG_FOE |
403 #ifdef DEBUG_FOE |
370 printk("ec_fsm_foe_ack_read()\n"); |
404 printk("ec_fsm_foe_ack_read()\n"); |
371 #endif |
405 #endif |
372 |
406 |
373 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
407 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
374 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
408 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
375 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
409 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
376 ec_datagram_print_state(datagram); |
410 ec_datagram_print_state(fsm->datagram); |
377 return; |
411 return; |
378 } |
412 } |
379 |
413 |
380 if (datagram->working_counter != 1) { |
414 if (fsm->datagram->working_counter != 1) { |
381 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
415 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
382 EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: "); |
416 EC_SLAVE_ERR(slave, "Reception of FoE ack response failed: "); |
383 ec_datagram_print_wc_error(datagram); |
417 ec_datagram_print_wc_error(fsm->datagram); |
384 return; |
418 return; |
385 } |
419 } |
386 |
420 |
387 if (!(data = ec_slave_mbox_fetch(fsm->slave, datagram, |
421 data = ec_slave_mbox_fetch(fsm->slave, datagram, &mbox_prot, &rec_size); |
388 &mbox_prot, &rec_size))) { |
422 if (IS_ERR(data)) { |
389 ec_foe_set_tx_error(fsm, FOE_PROT_ERROR); |
423 ec_foe_set_tx_error(fsm, FOE_PROT_ERROR); |
390 return; |
424 return; |
391 } |
425 } |
392 |
426 |
393 if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE |
427 if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE |
435 * |
469 * |
436 * Checks is the previous transmit datagram succeded and sends the next |
470 * Checks is the previous transmit datagram succeded and sends the next |
437 * fragment, if necessary. |
471 * fragment, if necessary. |
438 */ |
472 */ |
439 void ec_fsm_foe_state_wrq_sent( |
473 void ec_fsm_foe_state_wrq_sent( |
440 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
474 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
441 ) |
475 ec_datagram_t *datagram /**< Datagram to use. */ |
442 { |
476 ) |
443 ec_datagram_t *datagram = fsm->datagram; |
477 { |
444 ec_slave_t *slave = fsm->slave; |
478 ec_slave_t *slave = fsm->slave; |
445 |
479 |
446 #ifdef DEBUG_FOE |
480 #ifdef DEBUG_FOE |
447 printk("ec_foe_state_sent_wrq()\n"); |
481 printk("ec_foe_state_sent_wrq()\n"); |
448 #endif |
482 #endif |
449 |
483 |
450 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
484 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
451 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
485 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
452 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: "); |
486 EC_SLAVE_ERR(slave, "Failed to send FoE WRQ: "); |
453 ec_datagram_print_state(datagram); |
487 ec_datagram_print_state(fsm->datagram); |
454 return; |
488 return; |
455 } |
489 } |
456 |
490 |
457 if (datagram->working_counter != 1) { |
491 if (fsm->datagram->working_counter != 1) { |
458 // slave did not put anything in the mailbox yet |
492 // slave did not put anything in the mailbox yet |
459 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
493 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
460 EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: "); |
494 EC_SLAVE_ERR(slave, "Reception of FoE WRQ failed: "); |
461 ec_datagram_print_wc_error(datagram); |
495 ec_datagram_print_wc_error(fsm->datagram); |
462 return; |
496 return; |
463 } |
497 } |
464 |
498 |
465 fsm->jiffies_start = datagram->jiffies_sent; |
499 fsm->jiffies_start = fsm->datagram->jiffies_sent; |
466 |
500 |
467 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
501 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
468 |
502 |
469 fsm->retries = EC_FSM_RETRIES; |
503 fsm->retries = EC_FSM_RETRIES; |
470 fsm->state = ec_fsm_foe_state_ack_check; |
504 fsm->state = ec_fsm_foe_state_ack_check; |
476 * |
510 * |
477 * Checks is the previous transmit datagram succeded and sends the next |
511 * Checks is the previous transmit datagram succeded and sends the next |
478 * fragment, if necessary. |
512 * fragment, if necessary. |
479 */ |
513 */ |
480 void ec_fsm_foe_state_data_sent( |
514 void ec_fsm_foe_state_data_sent( |
481 ec_fsm_foe_t *fsm /**< Foe statemachine. */ |
515 ec_fsm_foe_t *fsm, /**< Foe statemachine. */ |
482 ) |
516 ec_datagram_t *datagram /**< Datagram to use. */ |
483 { |
517 ) |
484 ec_datagram_t *datagram = fsm->datagram; |
518 { |
485 ec_slave_t *slave = fsm->slave; |
519 ec_slave_t *slave = fsm->slave; |
486 |
520 |
487 #ifdef DEBUG_FOE |
521 #ifdef DEBUG_FOE |
488 printk("ec_fsm_foe_state_data_sent()\n"); |
522 printk("ec_fsm_foe_state_data_sent()\n"); |
489 #endif |
523 #endif |
490 |
524 |
491 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
525 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
492 ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR); |
526 ec_foe_set_tx_error(fsm, FOE_RECEIVE_ERROR); |
493 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
527 EC_SLAVE_ERR(slave, "Failed to receive FoE ack response datagram: "); |
494 ec_datagram_print_state(datagram); |
528 ec_datagram_print_state(fsm->datagram); |
495 return; |
529 return; |
496 } |
530 } |
497 |
531 |
498 if (fsm->datagram->working_counter != 1) { |
532 if (fsm->datagram->working_counter != 1) { |
499 ec_foe_set_tx_error(fsm, FOE_WC_ERROR); |
533 ec_foe_set_tx_error(fsm, FOE_WC_ERROR); |
500 EC_SLAVE_ERR(slave, "Reception of FoE data send failed: "); |
534 EC_SLAVE_ERR(slave, "Reception of FoE data send failed: "); |
501 ec_datagram_print_wc_error(datagram); |
535 ec_datagram_print_wc_error(fsm->datagram); |
502 return; |
536 return; |
503 } |
537 } |
504 |
538 |
505 ec_slave_mbox_prepare_check(fsm->slave, fsm->datagram); |
539 ec_slave_mbox_prepare_check(fsm->slave, datagram); |
506 fsm->jiffies_start = jiffies; |
540 fsm->jiffies_start = jiffies; |
507 fsm->retries = EC_FSM_RETRIES; |
541 fsm->retries = EC_FSM_RETRIES; |
508 fsm->state = ec_fsm_foe_state_ack_check; |
542 fsm->state = ec_fsm_foe_state_ack_check; |
509 } |
543 } |
510 |
544 |
511 /*****************************************************************************/ |
545 /*****************************************************************************/ |
512 |
546 |
513 /** Prepare a read request (RRQ) with filename |
547 /** Prepare a read request (RRQ) with filename |
514 */ |
548 */ |
515 int ec_foe_prepare_rrq_send(ec_fsm_foe_t *fsm) |
549 int ec_foe_prepare_rrq_send( |
|
550 ec_fsm_foe_t *fsm, /**< Finite state machine. */ |
|
551 ec_datagram_t *datagram /**< Datagram to use. */ |
|
552 ) |
516 { |
553 { |
517 size_t current_size; |
554 size_t current_size; |
518 uint8_t *data; |
555 uint8_t *data; |
519 |
556 |
520 current_size = fsm->rx_filename_len; |
557 current_size = fsm->rx_filename_len; |
521 |
558 |
522 data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram, |
559 data = ec_slave_mbox_prepare_send(fsm->slave, datagram, |
523 EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE); |
560 EC_MBOX_TYPE_FILEACCESS, current_size + EC_FOE_HEADER_SIZE); |
524 if (IS_ERR(data)) |
561 if (IS_ERR(data)) { |
525 return -1; |
562 return -1; |
|
563 } |
526 |
564 |
527 EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request |
565 EC_WRITE_U16(data, EC_FOE_OPCODE_RRQ); // fsm read request |
528 EC_WRITE_U32(data + 2, 0x00000000); // no passwd |
566 EC_WRITE_U32(data + 2, 0x00000000); // no passwd |
529 memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size); |
567 memcpy(data + EC_FOE_HEADER_SIZE, fsm->rx_filename, current_size); |
530 |
568 |
539 /*****************************************************************************/ |
577 /*****************************************************************************/ |
540 |
578 |
541 /** Prepare to send an acknowledge. |
579 /** Prepare to send an acknowledge. |
542 */ |
580 */ |
543 int ec_foe_prepare_send_ack( |
581 int ec_foe_prepare_send_ack( |
544 ec_fsm_foe_t *foe /**< FoE statemachine. */ |
582 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
|
583 ec_datagram_t *datagram /**< Datagram to use. */ |
545 ) |
584 ) |
546 { |
585 { |
547 uint8_t *data; |
586 uint8_t *data; |
548 |
587 |
549 data = ec_slave_mbox_prepare_send(foe->slave, foe->datagram, |
588 data = ec_slave_mbox_prepare_send(fsm->slave, datagram, |
550 EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE); |
589 EC_MBOX_TYPE_FILEACCESS, EC_FOE_HEADER_SIZE); |
551 if (IS_ERR(data)) |
590 if (IS_ERR(data)) { |
552 return -1; |
591 return -1; |
|
592 } |
553 |
593 |
554 EC_WRITE_U16(data, EC_FOE_OPCODE_ACK); |
594 EC_WRITE_U16(data, EC_FOE_OPCODE_ACK); |
555 EC_WRITE_U32(data + 2, foe->rx_expected_packet_no); |
595 EC_WRITE_U32(data + 2, fsm->rx_expected_packet_no); |
556 |
596 |
557 return 0; |
597 return 0; |
558 } |
598 } |
559 |
599 |
560 /*****************************************************************************/ |
600 /*****************************************************************************/ |
561 |
601 |
562 /** State: RRQ SENT. |
602 /** State: RRQ SENT. |
563 * |
603 * |
564 * Checks is the previous transmit datagram succeded and sends the next |
604 * Checks is the previous transmit datagram succeeded and sends the next |
565 * fragment, if necessary. |
605 * fragment, if necessary. |
566 */ |
606 */ |
567 void ec_fsm_foe_state_rrq_sent( |
607 void ec_fsm_foe_state_rrq_sent( |
568 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
608 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
569 ) |
609 ec_datagram_t *datagram /**< Datagram to use. */ |
570 { |
610 ) |
571 ec_datagram_t *datagram = fsm->datagram; |
611 { |
572 ec_slave_t *slave = fsm->slave; |
612 ec_slave_t *slave = fsm->slave; |
573 |
613 |
574 #ifdef DEBUG_FOE |
614 #ifdef DEBUG_FOE |
575 printk("ec_foe_state_rrq_sent()\n"); |
615 printk("ec_foe_state_rrq_sent()\n"); |
576 #endif |
616 #endif |
577 |
617 |
578 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
618 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
579 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
619 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
580 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: "); |
620 EC_SLAVE_ERR(slave, "Failed to send FoE RRQ: "); |
581 ec_datagram_print_state(datagram); |
621 ec_datagram_print_state(fsm->datagram); |
582 return; |
622 return; |
583 } |
623 } |
584 |
624 |
585 if (datagram->working_counter != 1) { |
625 if (fsm->datagram->working_counter != 1) { |
586 // slave did not put anything in the mailbox yet |
626 // slave did not put anything in the mailbox yet |
587 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
627 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
588 EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: "); |
628 EC_SLAVE_ERR(slave, "Reception of FoE RRQ failed: "); |
589 ec_datagram_print_wc_error(datagram); |
629 ec_datagram_print_wc_error(fsm->datagram); |
590 return; |
630 return; |
591 } |
631 } |
592 |
632 |
593 fsm->jiffies_start = datagram->jiffies_sent; |
633 fsm->jiffies_start = fsm->datagram->jiffies_sent; |
594 |
634 |
595 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
635 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
596 |
636 |
597 fsm->retries = EC_FSM_RETRIES; |
637 fsm->retries = EC_FSM_RETRIES; |
598 fsm->state = ec_fsm_foe_state_data_check; |
638 fsm->state = ec_fsm_foe_state_data_check; |
599 } |
639 } |
600 |
640 |
601 /*****************************************************************************/ |
641 /*****************************************************************************/ |
602 |
642 |
603 /** Start a read operation. |
|
604 */ |
|
605 void ec_fsm_foe_read( |
|
606 ec_fsm_foe_t *fsm /**< FoE state machine. */ |
|
607 ) |
|
608 { |
|
609 fsm->state = ec_fsm_foe_read_start; |
|
610 fsm->rx_filename = fsm->request->file_name; |
|
611 fsm->rx_filename_len = strlen(fsm->rx_filename); |
|
612 |
|
613 fsm->rx_buffer = fsm->request->buffer; |
|
614 fsm->rx_buffer_size = fsm->request->buffer_size; |
|
615 } |
|
616 |
|
617 /*****************************************************************************/ |
|
618 |
|
619 /** Starting state for read operations. |
643 /** Starting state for read operations. |
620 */ |
644 */ |
621 void ec_fsm_foe_read_start( |
645 void ec_fsm_foe_read_start( |
622 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
646 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
|
647 ec_datagram_t *datagram /**< Datagram to use. */ |
623 ) |
648 ) |
624 { |
649 { |
625 ec_slave_t *slave = fsm->slave; |
650 ec_slave_t *slave = fsm->slave; |
626 |
651 |
627 fsm->rx_buffer_offset = 0; |
652 fsm->rx_buffer_offset = 0; |
649 /*****************************************************************************/ |
674 /*****************************************************************************/ |
650 |
675 |
651 /** Check for data. |
676 /** Check for data. |
652 */ |
677 */ |
653 void ec_fsm_foe_state_data_check( |
678 void ec_fsm_foe_state_data_check( |
654 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
679 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
655 ) |
680 ec_datagram_t *datagram /**< Datagram to use. */ |
656 { |
681 ) |
657 ec_datagram_t *datagram = fsm->datagram; |
682 { |
658 ec_slave_t *slave = fsm->slave; |
683 ec_slave_t *slave = fsm->slave; |
659 |
684 |
660 #ifdef DEBUG_FOE |
685 #ifdef DEBUG_FOE |
661 printk("ec_fsm_foe_state_data_check()\n"); |
686 printk("ec_fsm_foe_state_data_check()\n"); |
662 #endif |
687 #endif |
663 |
688 |
664 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
689 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
665 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
690 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
666 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: "); |
691 EC_SLAVE_ERR(slave, "Failed to send FoE DATA READ: "); |
667 ec_datagram_print_state(datagram); |
692 ec_datagram_print_state(fsm->datagram); |
668 return; |
693 return; |
669 } |
694 } |
670 |
695 |
671 if (datagram->working_counter != 1) { |
696 if (fsm->datagram->working_counter != 1) { |
672 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
697 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
673 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: "); |
698 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ: "); |
674 ec_datagram_print_wc_error(datagram); |
699 ec_datagram_print_wc_error(fsm->datagram); |
675 return; |
700 return; |
676 } |
701 } |
677 |
702 |
678 if (!ec_slave_mbox_check(datagram)) { |
703 if (!ec_slave_mbox_check(fsm->datagram)) { |
679 unsigned long diff_ms = |
704 unsigned long diff_ms = |
680 (datagram->jiffies_received - fsm->jiffies_start) * 1000 / HZ; |
705 (fsm->datagram->jiffies_received - fsm->jiffies_start) * |
|
706 1000 / HZ; |
681 if (diff_ms >= EC_FSM_FOE_TIMEOUT) { |
707 if (diff_ms >= EC_FSM_FOE_TIMEOUT) { |
682 ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR); |
708 ec_foe_set_tx_error(fsm, FOE_TIMEOUT_ERROR); |
683 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n"); |
709 EC_SLAVE_ERR(slave, "Timeout while waiting for ack response.\n"); |
684 return; |
710 return; |
685 } |
711 } |
700 /*****************************************************************************/ |
726 /*****************************************************************************/ |
701 |
727 |
702 /** Start reading data. |
728 /** Start reading data. |
703 */ |
729 */ |
704 void ec_fsm_foe_state_data_read( |
730 void ec_fsm_foe_state_data_read( |
705 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
731 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
|
732 ec_datagram_t *datagram /**< Datagram to use. */ |
706 ) |
733 ) |
707 { |
734 { |
708 size_t rec_size; |
735 size_t rec_size; |
709 uint8_t *data, opCode, packet_no, mbox_prot; |
736 uint8_t *data, opCode, packet_no, mbox_prot; |
710 |
737 |
711 ec_datagram_t *datagram = fsm->datagram; |
|
712 ec_slave_t *slave = fsm->slave; |
738 ec_slave_t *slave = fsm->slave; |
713 |
739 |
714 #ifdef DEBUG_FOE |
740 #ifdef DEBUG_FOE |
715 printk("ec_fsm_foe_state_data_read()\n"); |
741 printk("ec_fsm_foe_state_data_read()\n"); |
716 #endif |
742 #endif |
717 |
743 |
718 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
744 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
719 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
745 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
720 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: "); |
746 EC_SLAVE_ERR(slave, "Failed to receive FoE DATA READ datagram: "); |
721 ec_datagram_print_state(datagram); |
747 ec_datagram_print_state(fsm->datagram); |
722 return; |
748 return; |
723 } |
749 } |
724 |
750 |
725 if (datagram->working_counter != 1) { |
751 if (fsm->datagram->working_counter != 1) { |
726 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
752 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
727 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: "); |
753 EC_SLAVE_ERR(slave, "Reception of FoE DATA READ failed: "); |
728 ec_datagram_print_wc_error(datagram); |
754 ec_datagram_print_wc_error(fsm->datagram); |
729 return; |
755 return; |
730 } |
756 } |
731 |
757 |
732 if (!(data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, |
758 data = ec_slave_mbox_fetch(slave, datagram, &mbox_prot, &rec_size); |
733 &rec_size))) { |
759 if (IS_ERR(data)) { |
734 ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR); |
760 ec_foe_set_rx_error(fsm, FOE_MBOX_FETCH_ERROR); |
735 return; |
761 return; |
736 } |
762 } |
737 |
763 |
738 if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE |
764 if (mbox_prot != EC_MBOX_TYPE_FILEACCESS) { // FoE |
824 /*****************************************************************************/ |
850 /*****************************************************************************/ |
825 |
851 |
826 /** Sent an acknowledge. |
852 /** Sent an acknowledge. |
827 */ |
853 */ |
828 void ec_fsm_foe_state_sent_ack( |
854 void ec_fsm_foe_state_sent_ack( |
829 ec_fsm_foe_t *fsm /**< FoE statemachine. */ |
855 ec_fsm_foe_t *fsm, /**< FoE statemachine. */ |
830 ) |
856 ec_datagram_t *datagram /**< Datagram to use. */ |
831 { |
857 ) |
832 ec_datagram_t *datagram = fsm->datagram; |
858 { |
833 ec_slave_t *slave = fsm->slave; |
859 ec_slave_t *slave = fsm->slave; |
834 |
860 |
835 #ifdef DEBUG_FOE |
861 #ifdef DEBUG_FOE |
836 printk("ec_foe_state_sent_ack()\n"); |
862 printk("ec_foe_state_sent_ack()\n"); |
837 #endif |
863 #endif |
838 |
864 |
839 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
865 if (fsm->datagram->state != EC_DATAGRAM_RECEIVED) { |
840 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
866 ec_foe_set_rx_error(fsm, FOE_RECEIVE_ERROR); |
841 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: "); |
867 EC_SLAVE_ERR(slave, "Failed to send FoE ACK: "); |
842 ec_datagram_print_state(datagram); |
868 ec_datagram_print_state(fsm->datagram); |
843 return; |
869 return; |
844 } |
870 } |
845 |
871 |
846 if (datagram->working_counter != 1) { |
872 if (fsm->datagram->working_counter != 1) { |
847 // slave did not put anything into the mailbox yet |
873 // slave did not put anything into the mailbox yet |
848 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
874 ec_foe_set_rx_error(fsm, FOE_WC_ERROR); |
849 EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: "); |
875 EC_SLAVE_ERR(slave, "Reception of FoE ACK failed: "); |
850 ec_datagram_print_wc_error(datagram); |
876 ec_datagram_print_wc_error(fsm->datagram); |
851 return; |
877 return; |
852 } |
878 } |
853 |
879 |
854 fsm->jiffies_start = datagram->jiffies_sent; |
880 fsm->jiffies_start = fsm->datagram->jiffies_sent; |
855 |
881 |
856 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
882 ec_slave_mbox_prepare_check(fsm->slave, datagram); // can not fail. |
857 |
883 |
858 if (fsm->rx_last_packet) { |
884 if (fsm->rx_last_packet) { |
859 fsm->rx_expected_packet_no = 0; |
885 fsm->rx_expected_packet_no = 0; |