src/devices/bin/driver_manager/coordinator.cc
// send message to driver_host, requesting the binding of a driver to a device
send message to driver_host, requesting the binding of a driver to a device
send message to driver_host requesting the binding of a driver to a device
static zx_status_t dh_bind_driver(const fbl::RefPtr<Device>& dev, const char* libname) {
  zx::vmo vmo;
  zx_status_t status = dev->coordinator->LibnameToVmo(libname, &vmo);
  if (status != ZX_OK) {
    return status;
  }
  status = dh_send_bind_driver(
      dev.get(), libname, std::move(vmo), [dev](zx_status_t status, zx::channel test_output) {
        if (status != ZX_OK) {
          LOGF(ERROR, "Failed to bind driver '%s': %s", dev->name().data(),
               zx_status_get_string(status));
          return;
        }
        fbl::RefPtr<Device> real_parent;
        if (dev->flags & DEV_CTX_PROXY) {
          real_parent = dev->parent();
        } else {
          real_parent = dev;
        }
        for (auto& child : real_parent->children()) {
          const char* drivername =
              dev->coordinator->LibnameToDriver(child.libname().data())->name.data();
          auto bootarg = fbl::StringPrintf("driver.%s.compatibility-tests-enable", drivername);
          auto compat_test_enabled =
              dev->coordinator->boot_args()->GetBool(fidl::unowned_str(bootarg), false);
          if (compat_test_enabled.ok() && compat_test_enabled->value &&
              (real_parent->test_state() == Device::TestStateMachine::kTestNotStarted)) {
            bootarg = fbl::StringPrintf("driver.%s.compatibility-tests-wait-time", drivername);
            auto test_wait_time =
                dev->coordinator->boot_args()->GetString(fidl::unowned_str(bootarg));
            zx::duration test_time = kDefaultTestTimeout;
            if (test_wait_time.ok() && !test_wait_time->value.is_null()) {
              auto test_timeout =
                  std::string{test_wait_time->value.data(), test_wait_time->value.size()};
              test_time = zx::msec(atoi(test_timeout.data()));
            }
            real_parent->set_test_time(test_time);
            real_parent->DriverCompatibiltyTest();
            break;
          } else if (real_parent->test_state() == Device::TestStateMachine::kTestBindSent) {
            real_parent->test_event().signal(0, TEST_BIND_DONE_SIGNAL);
            break;
          }
        }
        if (test_output.is_valid()) {
          LOGF(INFO, "Setting test channel for driver '%s'", dev->name().data());
          status = dev->set_test_output(std::move(test_output), dev->coordinator->dispatcher());
          if (status != ZX_OK) {
            LOGF(ERROR, "Failed to wait on test output for driver '%s': %s", dev->name().data(),
                 zx_status_get_string(status));
          }
        }
      });
  if (status != ZX_OK) {
    return status;
  }
  dev->flags |= DEV_CTX_BOUND;
  return ZX_OK;
}
static zx_status_t dh_bind_driver ( const fbl :: RefPtr < Device > & dev , const char * libname ) { zx :: vmo vmo ; zx_status_t status = dev -> coordinator -> LibnameToVmo ( libname , & vmo ) ; if ( status != ZX_OK ) { return status ; } status = dh_send_bind_driver ( dev . get ( ) , libname , std :: move ( vmo ) , [ dev ] ( zx_status_t status , zx :: channel test_output ) { if ( status != ZX_OK ) { LOGF ( ERROR , " " , dev -> name ( ) . data ( ) , zx_status_get_string ( status ) ) ; return ; } fbl :: RefPtr < Device > real_parent ; if ( dev -> flags & DEV_CTX_PROXY ) { real_parent = dev -> parent ( ) ; } else { real_parent = dev ; } for ( auto & child : real_parent -> children ( ) ) { const char * drivername = dev -> coordinator -> LibnameToDriver ( child . libname ( ) . data ( ) ) -> name . data ( ) ; auto bootarg = fbl :: StringPrintf ( " " , drivername ) ; auto compat_test_enabled = dev -> coordinator -> boot_args ( ) -> GetBool ( fidl :: unowned_str ( bootarg ) , false ) ; if ( compat_test_enabled . ok ( ) && compat_test_enabled -> value && ( real_parent -> test_state ( ) == Device :: TestStateMachine :: kTestNotStarted ) ) { bootarg = fbl :: StringPrintf ( " " , drivername ) ; auto test_wait_time = dev -> coordinator -> boot_args ( ) -> GetString ( fidl :: unowned_str ( bootarg ) ) ; zx :: duration test_time = kDefaultTestTimeout ; if ( test_wait_time . ok ( ) && ! test_wait_time -> value . is_null ( ) ) { auto test_timeout = std :: string { test_wait_time -> value . data ( ) , test_wait_time -> value . size ( ) } ; test_time = zx :: msec ( atoi ( test_timeout . data ( ) ) ) ; } real_parent -> set_test_time ( test_time ) ; real_parent -> DriverCompatibiltyTest ( ) ; break ; } else if ( real_parent -> test_state ( ) == Device :: TestStateMachine :: kTestBindSent ) { real_parent -> test_event ( ) . signal ( 0 , TEST_BIND_DONE_SIGNAL ) ; break ; } } if ( test_output . is_valid ( ) ) { LOGF ( INFO , " " , dev -> name ( ) . data ( ) ) ; status = dev -> set_test_output ( std :: move ( test_output ) , dev -> coordinator -> dispatcher ( ) ) ; if ( status != ZX_OK ) { LOGF ( ERROR , " " , dev -> name ( ) . data ( ) , zx_status_get_string ( status ) ) ; } } } ) ; if ( status != ZX_OK ) { return status ; } dev -> flags |= DEV_CTX_BOUND ; return ZX_OK ; }
send message to driver_host, requesting the binding of a driver to a device
send message to driver_host requesting the binding of a driver to a device