84 fsm->master = master; |
84 fsm->master = master; |
85 fsm->datagram = datagram; |
85 fsm->datagram = datagram; |
86 fsm->state = ec_fsm_master_state_start; |
86 fsm->state = ec_fsm_master_state_start; |
87 fsm->idle = 0; |
87 fsm->idle = 0; |
88 fsm->dev_idx = EC_DEVICE_MAIN; |
88 fsm->dev_idx = EC_DEVICE_MAIN; |
89 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) { |
89 for (dev_idx = EC_DEVICE_MAIN; dev_idx < ec_master_num_devices(master); |
|
90 dev_idx++) { |
90 fsm->link_state[dev_idx] = 0; |
91 fsm->link_state[dev_idx] = 0; |
91 fsm->slaves_responding[dev_idx] = 0; |
92 fsm->slaves_responding[dev_idx] = 0; |
92 fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN; |
93 fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN; |
93 } |
94 } |
94 fsm->rescan_required = 0; |
95 fsm->rescan_required = 0; |
207 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
208 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
208 fsm->rescan_required = 1; |
209 fsm->rescan_required = 1; |
209 fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter; |
210 fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter; |
210 EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n", |
211 EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n", |
211 fsm->slaves_responding[fsm->dev_idx], |
212 fsm->slaves_responding[fsm->dev_idx], |
212 ec_device_names[fsm->dev_idx]); |
213 ec_device_names[fsm->dev_idx != 0]); |
213 } |
214 } |
214 |
215 |
215 if (fsm->link_state[fsm->dev_idx] && |
216 if (fsm->link_state[fsm->dev_idx] && |
216 !master->devices[fsm->dev_idx].link_state) { |
217 !master->devices[fsm->dev_idx].link_state) { |
217 ec_device_index_t dev_idx; |
218 ec_device_index_t dev_idx; |
218 |
219 |
219 EC_MASTER_DBG(master, 1, "Master state machine detected " |
220 EC_MASTER_DBG(master, 1, "Master state machine detected " |
220 "link down on %s device. Clearing slave list.\n", |
221 "link down on %s device. Clearing slave list.\n", |
221 ec_device_names[fsm->dev_idx]); |
222 ec_device_names[fsm->dev_idx != 0]); |
222 |
223 |
223 #ifdef EC_EOE |
224 #ifdef EC_EOE |
224 ec_master_eoe_stop(master); |
225 ec_master_eoe_stop(master); |
225 ec_master_clear_eoe_handlers(master); |
226 ec_master_clear_eoe_handlers(master); |
226 #endif |
227 #endif |
227 ec_master_clear_slaves(master); |
228 ec_master_clear_slaves(master); |
228 |
229 |
229 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) { |
230 for (dev_idx = EC_DEVICE_MAIN; |
|
231 dev_idx < ec_master_num_devices(master); dev_idx++) { |
230 fsm->slave_states[dev_idx] = 0x00; |
232 fsm->slave_states[dev_idx] = 0x00; |
231 fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on |
233 fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on |
232 next link up. */ |
234 next link up. */ |
233 } |
235 } |
234 } |
236 } |
241 // slave states changed |
243 // slave states changed |
242 char state_str[EC_STATE_STRING_SIZE]; |
244 char state_str[EC_STATE_STRING_SIZE]; |
243 fsm->slave_states[fsm->dev_idx] = states; |
245 fsm->slave_states[fsm->dev_idx] = states; |
244 ec_state_string(states, state_str, 1); |
246 ec_state_string(states, state_str, 1); |
245 EC_MASTER_INFO(master, "Slave states on %s device: %s.\n", |
247 EC_MASTER_INFO(master, "Slave states on %s device: %s.\n", |
246 ec_device_names[fsm->dev_idx], state_str); |
248 ec_device_names[fsm->dev_idx != 0], state_str); |
247 } |
249 } |
248 } else { |
250 } else { |
249 fsm->slave_states[fsm->dev_idx] = 0x00; |
251 fsm->slave_states[fsm->dev_idx] = 0x00; |
250 } |
252 } |
251 |
253 |
252 fsm->dev_idx++; |
254 fsm->dev_idx++; |
253 if (fsm->dev_idx < EC_NUM_DEVICES) { |
255 if (fsm->dev_idx < ec_master_num_devices(master)) { |
254 // check number of responding slaves on next device |
256 // check number of responding slaves on next device |
255 fsm->state = ec_fsm_master_state_start; |
257 fsm->state = ec_fsm_master_state_start; |
256 fsm->state(fsm); // execute immediately |
258 fsm->state(fsm); // execute immediately |
257 return; |
259 return; |
258 } |
260 } |
277 ec_master_eoe_stop(master); |
279 ec_master_eoe_stop(master); |
278 ec_master_clear_eoe_handlers(master); |
280 ec_master_clear_eoe_handlers(master); |
279 #endif |
281 #endif |
280 ec_master_clear_slaves(master); |
282 ec_master_clear_slaves(master); |
281 |
283 |
282 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; |
284 for (dev_idx = EC_DEVICE_MAIN; |
283 dev_idx++) { |
285 dev_idx < ec_master_num_devices(master); dev_idx++) { |
284 count += fsm->slaves_responding[dev_idx]; |
286 count += fsm->slaves_responding[dev_idx]; |
285 } |
287 } |
286 |
288 |
287 if (!count) { |
289 if (!count) { |
288 // no slaves present -> finish state machine. |
290 // no slaves present -> finish state machine. |
706 } |
708 } |
707 |
709 |
708 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
710 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
709 EC_MASTER_ERR(master, "Failed to receive address" |
711 EC_MASTER_ERR(master, "Failed to receive address" |
710 " clearing datagram on %s link: ", |
712 " clearing datagram on %s link: ", |
711 ec_device_names[fsm->dev_idx]); |
713 ec_device_names[fsm->dev_idx != 0]); |
712 ec_datagram_print_state(datagram); |
714 ec_datagram_print_state(datagram); |
713 master->scan_busy = 0; |
715 master->scan_busy = 0; |
714 wake_up_interruptible(&master->scan_queue); |
716 wake_up_interruptible(&master->scan_queue); |
715 ec_fsm_master_restart(fsm); |
717 ec_fsm_master_restart(fsm); |
716 return; |
718 return; |
717 } |
719 } |
718 |
720 |
719 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
721 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
720 EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:" |
722 EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:" |
721 " Cleared %u of %u", |
723 " Cleared %u of %u", |
722 ec_device_names[fsm->dev_idx], datagram->working_counter, |
724 ec_device_names[fsm->dev_idx != 0], datagram->working_counter, |
723 fsm->slaves_responding[fsm->dev_idx]); |
725 fsm->slaves_responding[fsm->dev_idx]); |
724 } |
726 } |
725 |
727 |
726 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
728 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
727 " to measure transmission delays on %s link.\n", |
729 " to measure transmission delays on %s link.\n", |
728 ec_device_names[fsm->dev_idx]); |
730 ec_device_names[fsm->dev_idx != 0]); |
729 |
731 |
730 ec_datagram_bwr(datagram, 0x0900, 1); |
732 ec_datagram_bwr(datagram, 0x0900, 1); |
731 ec_datagram_zero(datagram); |
733 ec_datagram_zero(datagram); |
732 fsm->datagram->device_index = fsm->dev_idx; |
734 fsm->datagram->device_index = fsm->dev_idx; |
733 fsm->retries = EC_FSM_RETRIES; |
735 fsm->retries = EC_FSM_RETRIES; |
748 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
750 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
749 return; |
751 return; |
750 |
752 |
751 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
753 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
752 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram" |
754 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram" |
753 " on %s link: ", ec_device_names[fsm->dev_idx]); |
755 " on %s link: ", ec_device_names[fsm->dev_idx != 0]); |
754 ec_datagram_print_state(datagram); |
756 ec_datagram_print_state(datagram); |
755 master->scan_busy = 0; |
757 master->scan_busy = 0; |
756 wake_up_interruptible(&master->scan_queue); |
758 wake_up_interruptible(&master->scan_queue); |
757 ec_fsm_master_restart(fsm); |
759 ec_fsm_master_restart(fsm); |
758 return; |
760 return; |
759 } |
761 } |
760 |
762 |
761 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring" |
763 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring" |
762 " on %s link.\n", |
764 " on %s link.\n", |
763 datagram->working_counter, ec_device_names[fsm->dev_idx]); |
765 datagram->working_counter, ec_device_names[fsm->dev_idx != 0]); |
764 |
766 |
765 do { |
767 do { |
766 fsm->dev_idx++; |
768 fsm->dev_idx++; |
767 } while (fsm->dev_idx < EC_NUM_DEVICES && |
769 } while (fsm->dev_idx < ec_master_num_devices(master) && |
768 !fsm->slaves_responding[fsm->dev_idx]); |
770 !fsm->slaves_responding[fsm->dev_idx]); |
769 if (fsm->dev_idx < EC_NUM_DEVICES) { |
771 if (fsm->dev_idx < ec_master_num_devices(master)) { |
770 ec_fsm_master_enter_clear_addresses(fsm); |
772 ec_fsm_master_enter_clear_addresses(fsm); |
771 return; |
773 return; |
772 } |
774 } |
773 |
775 |
774 EC_MASTER_INFO(master, "Scanning bus.\n"); |
776 EC_MASTER_INFO(master, "Scanning bus.\n"); |
775 |
777 |
776 // begin scanning of slaves |
778 // begin scanning of slaves |
777 fsm->slave = master->slaves; |
779 fsm->slave = master->slaves; |
778 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
780 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
779 fsm->slave->ring_position, |
781 fsm->slave->ring_position, |
780 ec_device_names[fsm->slave->device_index]); |
782 ec_device_names[fsm->slave->device_index != 0]); |
781 fsm->state = ec_fsm_master_state_scan_slave; |
783 fsm->state = ec_fsm_master_state_scan_slave; |
782 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
784 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
783 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
785 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
784 fsm->datagram->device_index = fsm->slave->device_index; |
786 fsm->datagram->device_index = fsm->slave->device_index; |
785 } |
787 } |
821 // another slave to fetch? |
823 // another slave to fetch? |
822 fsm->slave++; |
824 fsm->slave++; |
823 if (fsm->slave < master->slaves + master->slave_count) { |
825 if (fsm->slave < master->slaves + master->slave_count) { |
824 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
826 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
825 fsm->slave->ring_position, |
827 fsm->slave->ring_position, |
826 ec_device_names[fsm->slave->device_index]); |
828 ec_device_names[fsm->slave->device_index != 0]); |
827 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
829 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
828 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
830 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
829 fsm->datagram->device_index = fsm->slave->device_index; |
831 fsm->datagram->device_index = fsm->slave->device_index; |
830 return; |
832 return; |
831 } |
833 } |