54 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
54 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
55 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
55 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
56 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
56 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
57 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
57 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
58 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
58 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
59 void ec_fsm_master_state_phy_request(ec_fsm_master_t *); |
59 void ec_fsm_master_state_reg_request(ec_fsm_master_t *); |
60 void ec_fsm_master_state_foe_request(ec_fsm_master_t *); |
60 void ec_fsm_master_state_foe_request(ec_fsm_master_t *); |
61 |
61 |
62 /*****************************************************************************/ |
62 /*****************************************************************************/ |
63 |
63 |
64 /** Constructor. |
64 /** Constructor. |
325 return 0; |
325 return 0; |
326 } |
326 } |
327 |
327 |
328 /*****************************************************************************/ |
328 /*****************************************************************************/ |
329 |
329 |
330 /** Check for pending phy requests and process one. |
330 /** Check for pending register requests and process one. |
331 * |
331 * |
332 * \return non-zero, if a phy request is processed. |
332 * \return non-zero, if a register request is processed. |
333 */ |
333 */ |
334 int ec_fsm_master_action_process_phy( |
334 int ec_fsm_master_action_process_register( |
335 ec_fsm_master_t *fsm /**< Master state machine. */ |
335 ec_fsm_master_t *fsm /**< Master state machine. */ |
336 ) |
336 ) |
337 { |
337 { |
338 ec_master_t *master = fsm->master; |
338 ec_master_t *master = fsm->master; |
339 ec_phy_request_t *request; |
339 ec_reg_request_t *request; |
340 |
340 |
341 // search the first request to be processed |
341 // search the first request to be processed |
342 while (!list_empty(&master->phy_requests)) { |
342 while (!list_empty(&master->reg_requests)) { |
343 |
343 |
344 // get first request |
344 // get first request |
345 request = list_entry(master->phy_requests.next, |
345 request = list_entry(master->reg_requests.next, |
346 ec_phy_request_t, list); |
346 ec_reg_request_t, list); |
347 list_del_init(&request->list); // dequeue |
347 list_del_init(&request->list); // dequeue |
348 request->state = EC_INT_REQUEST_BUSY; |
348 request->state = EC_INT_REQUEST_BUSY; |
349 |
349 |
350 // found pending request; process it! |
350 // found pending request; process it! |
351 if (master->debug_level) |
351 if (master->debug_level) |
352 EC_DBG("Processing phy request for slave %u, " |
352 EC_DBG("Processing register request for slave %u, " |
353 "offset 0x%04x, length %u...\n", |
353 "offset 0x%04x, length %u...\n", |
354 request->slave->ring_position, |
354 request->slave->ring_position, |
355 request->offset, request->length); |
355 request->offset, request->length); |
356 |
356 |
357 if (request->length > fsm->datagram->mem_size) { |
357 if (request->length > fsm->datagram->mem_size) { |
358 EC_ERR("Request length (%u) exceeds maximum " |
358 EC_ERR("Request length (%u) exceeds maximum " |
359 "datagram size (%u)!\n", request->length, |
359 "datagram size (%u)!\n", request->length, |
360 fsm->datagram->mem_size); |
360 fsm->datagram->mem_size); |
361 request->state = EC_INT_REQUEST_FAILURE; |
361 request->state = EC_INT_REQUEST_FAILURE; |
362 wake_up(&master->phy_queue); |
362 wake_up(&master->reg_queue); |
363 continue; |
363 continue; |
364 } |
364 } |
365 |
365 |
366 fsm->phy_request = request; |
366 fsm->reg_request = request; |
367 |
367 |
368 if (request->dir == EC_DIR_INPUT) { |
368 if (request->dir == EC_DIR_INPUT) { |
369 ec_datagram_fprd(fsm->datagram, request->slave->station_address, |
369 ec_datagram_fprd(fsm->datagram, request->slave->station_address, |
370 request->offset, request->length); |
370 request->offset, request->length); |
371 ec_datagram_zero(fsm->datagram); |
371 ec_datagram_zero(fsm->datagram); |
373 ec_datagram_fpwr(fsm->datagram, request->slave->station_address, |
373 ec_datagram_fpwr(fsm->datagram, request->slave->station_address, |
374 request->offset, request->length); |
374 request->offset, request->length); |
375 memcpy(fsm->datagram->data, request->data, request->length); |
375 memcpy(fsm->datagram->data, request->data, request->length); |
376 } |
376 } |
377 fsm->retries = EC_FSM_RETRIES; |
377 fsm->retries = EC_FSM_RETRIES; |
378 fsm->state = ec_fsm_master_state_phy_request; |
378 fsm->state = ec_fsm_master_state_reg_request; |
379 return 1; |
379 return 1; |
380 } |
380 } |
381 |
381 |
382 return 0; |
382 return 0; |
383 } |
383 } |
566 |
566 |
567 // check for pending SII write operations. |
567 // check for pending SII write operations. |
568 if (ec_fsm_master_action_process_sii(fsm)) |
568 if (ec_fsm_master_action_process_sii(fsm)) |
569 return; // SII write request found |
569 return; // SII write request found |
570 |
570 |
571 // check for pending phy requests. |
571 // check for pending register requests. |
572 if (ec_fsm_master_action_process_phy(fsm)) |
572 if (ec_fsm_master_action_process_register(fsm)) |
573 return; // phy request processing |
573 return; // register request processing |
574 |
574 |
575 ec_fsm_master_restart(fsm); |
575 ec_fsm_master_restart(fsm); |
576 } |
576 } |
577 |
577 |
578 /*****************************************************************************/ |
578 /*****************************************************************************/ |
1012 ec_fsm_master_restart(fsm); |
1012 ec_fsm_master_restart(fsm); |
1013 } |
1013 } |
1014 |
1014 |
1015 /*****************************************************************************/ |
1015 /*****************************************************************************/ |
1016 |
1016 |
1017 /** Master state: PHY. |
1017 /** Master state: REG REQUEST. |
1018 */ |
1018 */ |
1019 void ec_fsm_master_state_phy_request( |
1019 void ec_fsm_master_state_reg_request( |
1020 ec_fsm_master_t *fsm /**< Master state machine. */ |
1020 ec_fsm_master_t *fsm /**< Master state machine. */ |
1021 ) |
1021 ) |
1022 { |
1022 { |
1023 ec_master_t *master = fsm->master; |
1023 ec_master_t *master = fsm->master; |
1024 ec_datagram_t *datagram = fsm->datagram; |
1024 ec_datagram_t *datagram = fsm->datagram; |
1025 ec_phy_request_t *request = fsm->phy_request; |
1025 ec_reg_request_t *request = fsm->reg_request; |
1026 |
1026 |
1027 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1027 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1028 EC_ERR("Failed to receive phy request datagram (state %u).\n", |
1028 EC_ERR("Failed to receive register request datagram (state %u).\n", |
1029 datagram->state); |
1029 datagram->state); |
1030 request->state = EC_INT_REQUEST_FAILURE; |
1030 request->state = EC_INT_REQUEST_FAILURE; |
1031 wake_up(&master->phy_queue); |
1031 wake_up(&master->reg_queue); |
1032 ec_fsm_master_restart(fsm); |
1032 ec_fsm_master_restart(fsm); |
1033 return; |
1033 return; |
1034 } |
1034 } |
1035 |
1035 |
1036 if (datagram->working_counter == 1) { |
1036 if (datagram->working_counter == 1) { |
1037 if (request->dir == EC_DIR_INPUT) { // read request |
1037 if (request->dir == EC_DIR_INPUT) { // read request |
1038 if (request->data) |
1038 if (request->data) |
1039 kfree(request->data); |
1039 kfree(request->data); |
1040 request->data = kmalloc(request->length, GFP_KERNEL); |
1040 request->data = kmalloc(request->length, GFP_KERNEL); |
1041 if (!request->data) { |
1041 if (!request->data) { |
1042 EC_ERR("Failed to allocate %u bytes of memory for phy request.\n", |
1042 EC_ERR("Failed to allocate %u bytes of memory for" |
1043 request->length); |
1043 " register data.\n", request->length); |
1044 request->state = EC_INT_REQUEST_FAILURE; |
1044 request->state = EC_INT_REQUEST_FAILURE; |
1045 wake_up(&master->phy_queue); |
1045 wake_up(&master->reg_queue); |
1046 ec_fsm_master_restart(fsm); |
1046 ec_fsm_master_restart(fsm); |
1047 return; |
1047 return; |
1048 } |
1048 } |
1049 memcpy(request->data, datagram->data, request->length); |
1049 memcpy(request->data, datagram->data, request->length); |
1050 } |
1050 } |