453 ec_slave_t *slave, *next; |
453 ec_slave_t *slave, *next; |
454 ec_slave_ident_t *ident; |
454 ec_slave_ident_t *ident; |
455 unsigned int i; |
455 unsigned int i; |
456 ec_command_t *command; |
456 ec_command_t *command; |
457 ec_eoe_t *eoe; |
457 ec_eoe_t *eoe; |
458 uint16_t buscoupler_index, index_after_buscoupler; |
458 uint16_t coupler_index, coupler_subindex; |
|
459 uint16_t reverse_coupler_index, current_coupler_index; |
459 |
460 |
460 if (!list_empty(&master->slaves)) { |
461 if (!list_empty(&master->slaves)) { |
461 EC_ERR("Slave scan already done!\n"); |
462 EC_ERR("Slave scan already done!\n"); |
462 return -1; |
463 return -1; |
463 } |
464 } |
488 } |
489 } |
489 |
490 |
490 list_add_tail(&slave->list, &master->slaves); |
491 list_add_tail(&slave->list, &master->slaves); |
491 } |
492 } |
492 |
493 |
493 buscoupler_index = 0xFFFF; |
494 coupler_index = 0; |
494 index_after_buscoupler = 0; |
495 reverse_coupler_index = 0xFFFF; |
|
496 current_coupler_index = 0x3FFF; |
|
497 coupler_subindex = 0; |
495 |
498 |
496 // For every slave on the bus |
499 // For every slave on the bus |
497 list_for_each_entry(slave, &master->slaves, list) { |
500 list_for_each_entry(slave, &master->slaves, list) { |
498 |
501 |
499 // Write station address |
502 // Write station address |
518 break; |
521 break; |
519 } |
522 } |
520 ident++; |
523 ident++; |
521 } |
524 } |
522 |
525 |
523 if (!slave->type) |
526 if (!slave->type) { |
524 EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at" |
527 EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at" |
525 " position %i.\n", slave->sii_vendor_id, |
528 " position %i.\n", slave->sii_vendor_id, |
526 slave->sii_product_code, i); |
529 slave->sii_product_code, i); |
527 else { |
530 } |
528 if (slave->type->special == EC_TYPE_BUS_COUPLER) { |
531 else if (slave->type->special == EC_TYPE_BUS_COUPLER) { |
529 buscoupler_index++; |
532 if (slave->sii_alias) |
530 index_after_buscoupler = 0; |
533 current_coupler_index = reverse_coupler_index--; |
531 } |
534 else |
532 } |
535 current_coupler_index = coupler_index++; |
533 |
536 coupler_subindex = 0; |
534 slave->buscoupler_index = buscoupler_index; |
537 } |
535 slave->index_after_buscoupler = index_after_buscoupler; |
538 |
536 index_after_buscoupler++; |
539 slave->coupler_index = current_coupler_index; |
|
540 slave->coupler_subindex = coupler_subindex; |
|
541 coupler_subindex++; |
537 |
542 |
538 // Does the slave support EoE? |
543 // Does the slave support EoE? |
539 if (slave->sii_mailbox_protocols & EC_MBOX_EOE) { |
544 if (slave->sii_mailbox_protocols & EC_MBOX_EOE) { |
540 if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
545 if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
541 EC_ERR("Failed to allocate EoE-Object.\n"); |
546 EC_ERR("Failed to allocate EoE-Object.\n"); |
677 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address); |
682 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address); |
678 return NULL; |
683 return NULL; |
679 } |
684 } |
680 |
685 |
681 if (alias_requested) { |
686 if (alias_requested) { |
|
687 if (!alias_slave->type || |
|
688 alias_slave->type->special != EC_TYPE_BUS_COUPLER) { |
|
689 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" |
|
690 " in colon mode.\n", address); |
|
691 return NULL; |
|
692 } |
682 list_for_each_entry(slave, &master->slaves, list) { |
693 list_for_each_entry(slave, &master->slaves, list) { |
683 if (slave->buscoupler_index == alias_slave->buscoupler_index |
694 if (slave->coupler_index == alias_slave->coupler_index |
684 && alias_slave->index_after_buscoupler == 0 |
695 && slave->coupler_subindex == second) |
685 && slave->index_after_buscoupler == second) |
|
686 return slave; |
696 return slave; |
687 } |
697 } |
688 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
698 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
689 " following!\n", address, alias_slave->ring_position, |
699 " following!\n", address, alias_slave->ring_position, |
690 second); |
700 second); |
691 return NULL; |
701 return NULL; |
692 } |
702 } |
693 else { |
703 else { |
694 list_for_each_entry(slave, &master->slaves, list) { |
704 list_for_each_entry(slave, &master->slaves, list) { |
695 if (slave->buscoupler_index == first |
705 if (slave->coupler_index == first |
696 && slave->index_after_buscoupler == second) return slave; |
706 && slave->coupler_subindex == second) return slave; |
697 } |
707 } |
698 } |
708 } |
699 } |
709 } |
700 else |
710 else |
701 EC_ERR("Slave address \"%s\" - Invalid format!\n", address); |
711 EC_ERR("Slave address \"%s\" - Invalid format!\n", address); |