diff --git a/src/libs/compat/freebsd_network/bus.c b/src/libs/compat/freebsd_network/bus.c index 75e4a7f4fa..5ca5c0b139 100644 --- a/src/libs/compat/freebsd_network/bus.c +++ b/src/libs/compat/freebsd_network/bus.c @@ -378,14 +378,6 @@ bus_get_dma_tag(device_t dev) } -int -bus_generic_detach(device_t dev) -{ - UNIMPLEMENTED(); - return B_ERROR; -} - - int bus_generic_suspend(device_t dev) { diff --git a/src/libs/compat/freebsd_network/compat.c b/src/libs/compat/freebsd_network/compat.c index 9c0290860b..80c660e652 100644 --- a/src/libs/compat/freebsd_network/compat.c +++ b/src/libs/compat/freebsd_network/compat.c @@ -329,8 +329,10 @@ device_delete_child(device_t parent, device_t child) if ((atomic_and(&parent->flags, ~DEVICE_ATTACHED) & DEVICE_ATTACHED) != 0 && parent->methods.detach != NULL) { int status = parent->methods.detach(parent); - if (status != 0) + if (status != 0) { + atomic_or(&parent->flags, DEVICE_ATTACHED); return status; + } } if (parent->flags & DEVICE_DESC_ALLOCED) @@ -365,6 +367,24 @@ device_attach(device_t device) } +int +device_detach(device_t device) +{ + if (device->driver == NULL) + return B_ERROR; + + if ((atomic_and(&device->flags, ~DEVICE_ATTACHED) & DEVICE_ATTACHED) != 0) { + int result = device->methods.detach(device); + if (result != 0) { + atomic_or(&device->flags, DEVICE_ATTACHED); + return result; + } + } + + return 0; +} + + int bus_generic_attach(device_t dev) { @@ -394,6 +414,26 @@ bus_generic_attach(device_t dev) } +int +bus_generic_detach(device_t device) +{ + device_t child = NULL; + + if ((device->flags & DEVICE_ATTACHED) == 0) + return B_ERROR; + + while (true) { + child = list_get_next_item(&device->children, child); + if (child == NULL) + break; + + device_detach(child); + } + + return 0; +} + + // #pragma mark - Misc, Malloc diff --git a/src/libs/compat/freebsd_network/compat/sys/bus.h b/src/libs/compat/freebsd_network/compat/sys/bus.h index e6d1f1ffcd..bed127ef11 100644 --- a/src/libs/compat/freebsd_network/compat/sys/bus.h +++ b/src/libs/compat/freebsd_network/compat/sys/bus.h @@ -144,6 +144,7 @@ device_t device_add_child(device_t dev, const char *name, int unit); int device_delete_child(device_t dev, device_t child); int device_is_attached(device_t dev); int device_attach(device_t dev); +int device_detach(device_t dev); int bus_generic_print_child(device_t dev, device_t child); void bus_generic_driver_added(device_t dev, driver_t *driver); int bus_generic_attach(device_t dev);