mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 02:35:03 +01:00
random: always use the PRNG, and use entropy sources to feed it
remove the yarrow module. the hardware modules can push entropy with queue_randomness(). virtio_rng will now push entropy every 300 seconds. helps with #14937 Change-Id: If76c5deabf61dc616a0e051332f44b89deb6b8a1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5824 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
0843085384
commit
34e9243872
@ -14,18 +14,12 @@
|
||||
|
||||
typedef struct {
|
||||
driver_module_info info;
|
||||
|
||||
status_t (*queue_randomness)(uint64 value);
|
||||
} random_for_controller_interface;
|
||||
|
||||
|
||||
#define RANDOM_FOR_CONTROLLER_MODULE_NAME "bus_managers/random/controller/driver_v1"
|
||||
|
||||
// Bus manager interface used by Random controller drivers.
|
||||
typedef struct random_module_info {
|
||||
driver_module_info info;
|
||||
|
||||
status_t (*read)(void* cookie, void *_buffer, size_t *_numBytes);
|
||||
status_t (*write)(void* cookie, const void *_buffer, size_t *_numBytes);
|
||||
} random_module_info;
|
||||
|
||||
|
||||
#endif /* _RANDOM_H */
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
|
||||
static mutex sRandomLock;
|
||||
static random_module_info *sRandomModule;
|
||||
static void *sRandomCookie;
|
||||
device_manager_info* gDeviceManager;
|
||||
|
||||
@ -44,6 +43,15 @@ typedef struct {
|
||||
} random_driver_info;
|
||||
|
||||
|
||||
static status_t
|
||||
random_queue_randomness(uint64 value)
|
||||
{
|
||||
MutexLocker locker(&sRandomLock);
|
||||
RANDOM_ENQUEUE(value);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - device module API
|
||||
|
||||
|
||||
@ -74,7 +82,7 @@ random_read(void *cookie, off_t position, void *_buffer, size_t *_numBytes)
|
||||
TRACE("read(%Ld,, %ld)\n", position, *_numBytes);
|
||||
|
||||
MutexLocker locker(&sRandomLock);
|
||||
return sRandomModule->read(sRandomCookie, _buffer, _numBytes);
|
||||
return RANDOM_READ(sRandomCookie, _buffer, _numBytes);
|
||||
}
|
||||
|
||||
|
||||
@ -83,11 +91,7 @@ random_write(void *cookie, off_t position, const void *buffer, size_t *_numBytes
|
||||
{
|
||||
TRACE("write(%Ld,, %ld)\n", position, *_numBytes);
|
||||
MutexLocker locker(&sRandomLock);
|
||||
if (sRandomModule->write == NULL) {
|
||||
*_numBytes = 0;
|
||||
return EINVAL;
|
||||
}
|
||||
return sRandomModule->write(sRandomCookie, buffer, _numBytes);
|
||||
return RANDOM_WRITE(sRandomCookie, buffer, _numBytes);
|
||||
}
|
||||
|
||||
|
||||
@ -187,6 +191,7 @@ random_init_driver(device_node *node, void **cookie)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
mutex_init(&sRandomLock, "/dev/random lock");
|
||||
RANDOM_INIT();
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
@ -202,6 +207,8 @@ random_uninit_driver(void *_cookie)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
RANDOM_UNINIT();
|
||||
|
||||
mutex_destroy(&sRandomLock);
|
||||
|
||||
random_driver_info* info = (random_driver_info*)_cookie;
|
||||
@ -220,38 +227,10 @@ random_register_child_devices(void* _cookie)
|
||||
gDeviceManager->publish_device(info->node, "urandom",
|
||||
RANDOM_DEVICE_MODULE_NAME);
|
||||
}
|
||||
|
||||
// add the default Yarrow RNG
|
||||
device_attr attrs[] = {
|
||||
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
|
||||
{ string: "Yarrow RNG" }},
|
||||
{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
|
||||
{ string: RANDOM_FOR_CONTROLLER_MODULE_NAME }},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
device_node* node;
|
||||
return gDeviceManager->register_node(info->node,
|
||||
YARROW_RNG_SIM_MODULE_NAME, attrs, NULL, &node);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
status_t
|
||||
random_added_device(device_node *node)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
status_t status = gDeviceManager->get_driver(node,
|
||||
(driver_module_info **)&sRandomModule, &sRandomCookie);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@ -311,11 +290,13 @@ random_for_controller_interface sRandomForControllerModule = {
|
||||
},
|
||||
|
||||
NULL, // supported devices
|
||||
random_added_device,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
|
||||
random_queue_randomness,
|
||||
};
|
||||
|
||||
|
||||
@ -323,6 +304,5 @@ module_info* modules[] = {
|
||||
(module_info*)&sRandomDriver,
|
||||
(module_info*)&sRandomDevice,
|
||||
(module_info*)&sRandomForControllerModule,
|
||||
(module_info*)&gYarrowRandomModule,
|
||||
NULL
|
||||
};
|
||||
|
@ -286,10 +286,28 @@ kill_chrand(ch_randgen *randgen)
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// Random interface
|
||||
|
||||
|
||||
static status_t
|
||||
status_t
|
||||
yarrow_init()
|
||||
{
|
||||
CALLED();
|
||||
sRandomEnv = new_chrand(8);
|
||||
if (sRandomEnv == NULL)
|
||||
return B_NO_MEMORY;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
yarrow_uninit()
|
||||
{
|
||||
CALLED();
|
||||
kill_chrand(sRandomEnv);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
yarrow_rng_read(void* cookie, void *_buffer, size_t *_numBytes)
|
||||
{
|
||||
if (!IS_USER_ADDRESS(_buffer))
|
||||
@ -323,7 +341,7 @@ yarrow_rng_read(void* cookie, void *_buffer, size_t *_numBytes)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
status_t
|
||||
yarrow_rng_write(void* cookie, const void *_buffer, size_t *_numBytes)
|
||||
{
|
||||
OCTET *buffer = (OCTET*)_buffer;
|
||||
@ -342,54 +360,9 @@ yarrow_rng_write(void* cookie, const void *_buffer, size_t *_numBytes)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
static status_t
|
||||
yarrow_init_bus(device_node* node, void** bus_cookie)
|
||||
void
|
||||
yarrow_enqueue_randomness(const uint64 value)
|
||||
{
|
||||
CALLED();
|
||||
sRandomEnv = new_chrand(8);
|
||||
if (sRandomEnv == NULL)
|
||||
return B_NO_MEMORY;
|
||||
return B_OK;
|
||||
chseed(sRandomEnv, value);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
yarrow_uninit_bus(void* bus_cookie)
|
||||
{
|
||||
CALLED();
|
||||
kill_chrand(sRandomEnv);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
yarrow_bus_removed(void* bus_cookie)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
random_module_info gYarrowRandomModule = {
|
||||
{
|
||||
{
|
||||
YARROW_RNG_SIM_MODULE_NAME,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
|
||||
NULL, // supports_device,
|
||||
NULL, // register_device,
|
||||
yarrow_init_bus,
|
||||
yarrow_uninit_bus,
|
||||
NULL, // register child devices
|
||||
NULL, // rescan
|
||||
yarrow_bus_removed,
|
||||
},
|
||||
yarrow_rng_read,
|
||||
yarrow_rng_write
|
||||
};
|
||||
|
@ -14,15 +14,23 @@
|
||||
#include "random.h"
|
||||
|
||||
|
||||
#define YARROW_RNG_SIM_MODULE_NAME "bus_managers/random/yarrow_rng/device/v1"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t yarrow_init();
|
||||
void yarrow_uninit();
|
||||
void yarrow_enqueue_randomness(const uint64 value);
|
||||
|
||||
extern random_module_info gYarrowRandomModule;
|
||||
status_t yarrow_rng_read(void* cookie, void *_buffer, size_t *_numBytes);
|
||||
status_t yarrow_rng_write(void* cookie, const void *_buffer, size_t *_numBytes);
|
||||
|
||||
|
||||
#define RANDOM_INIT yarrow_init
|
||||
#define RANDOM_UNINIT yarrow_uninit
|
||||
#define RANDOM_ENQUEUE yarrow_enqueue_randomness
|
||||
#define RANDOM_READ yarrow_rng_read
|
||||
#define RANDOM_WRITE yarrow_rng_write
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -24,24 +24,19 @@ get_feature_name(uint32 feature)
|
||||
|
||||
VirtioRNGDevice::VirtioRNGDevice(device_node *node)
|
||||
:
|
||||
fNode(node),
|
||||
fVirtio(NULL),
|
||||
fVirtioDevice(NULL),
|
||||
fStatus(B_NO_INIT),
|
||||
fOffset(BUFFER_SIZE),
|
||||
fExpectsInterrupt(false)
|
||||
fExpectsInterrupt(false),
|
||||
fDPCHandle(NULL)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
B_INITIALIZE_SPINLOCK(&fInterruptLock);
|
||||
fInterruptCondition.Init(this, "virtio rng transfer");
|
||||
|
||||
get_memory_map(fBuffer, BUFFER_SIZE, &fEntry, 1);
|
||||
|
||||
// get the Virtio device from our parent's parent
|
||||
device_node *parent = gDeviceManager->get_parent_node(node);
|
||||
device_node *virtioParent = gDeviceManager->get_parent_node(parent);
|
||||
gDeviceManager->put_node(parent);
|
||||
device_node *virtioParent = gDeviceManager->get_parent_node(node);
|
||||
|
||||
gDeviceManager->get_driver(virtioParent, (driver_module_info **)&fVirtio,
|
||||
(void **)&fVirtioDevice);
|
||||
@ -68,11 +63,31 @@ VirtioRNGDevice::VirtioRNGDevice(device_node *node)
|
||||
ERROR("queue interrupt setup failed (%s)\n", strerror(fStatus));
|
||||
return;
|
||||
}
|
||||
|
||||
fStatus = gDPC->new_dpc_queue(&fDPCHandle, "virtio_rng timer",
|
||||
B_LOW_PRIORITY);
|
||||
if (fStatus != B_OK) {
|
||||
ERROR("dpc setup failed (%s)\n", strerror(fStatus));
|
||||
return;
|
||||
}
|
||||
|
||||
if (fStatus == B_OK) {
|
||||
fTimer.user_data = this;
|
||||
fStatus = add_timer(&fTimer, &HandleTimerHook, 300 * 1000 * 1000, B_PERIODIC_TIMER);
|
||||
if (fStatus != B_OK)
|
||||
ERROR("timer setup failed (%s)\n", strerror(fStatus));
|
||||
}
|
||||
|
||||
// trigger also now
|
||||
gDPC->queue_dpc(fDPCHandle, HandleDPC, this);
|
||||
}
|
||||
|
||||
|
||||
VirtioRNGDevice::~VirtioRNGDevice()
|
||||
{
|
||||
cancel_timer(&fTimer);
|
||||
gDPC->delete_dpc_queue(fDPCHandle);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -84,46 +99,42 @@ VirtioRNGDevice::InitCheck()
|
||||
|
||||
|
||||
status_t
|
||||
VirtioRNGDevice::Read(void* _buffer, size_t* _numBytes)
|
||||
VirtioRNGDevice::_Enqueue()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (fOffset >= BUFFER_SIZE) {
|
||||
{
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = true;
|
||||
fInterruptCondition.Add(&fInterruptConditionEntry);
|
||||
}
|
||||
status_t result = fVirtio->queue_request(fVirtioQueue, NULL, &fEntry,
|
||||
NULL);
|
||||
if (result != B_OK) {
|
||||
ERROR("queueing failed (%s)\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
uint64 value = 0;
|
||||
physical_entry entry;
|
||||
get_memory_map(&value, sizeof(value), &entry, 1);
|
||||
|
||||
result = fInterruptConditionEntry.Wait(B_CAN_INTERRUPT);
|
||||
|
||||
{
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = false;
|
||||
}
|
||||
|
||||
if (result == B_OK) {
|
||||
fOffset = 0;
|
||||
} else if (result != B_INTERRUPTED) {
|
||||
ERROR("request failed (%s)\n", strerror(result));
|
||||
}
|
||||
{
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = true;
|
||||
fInterruptCondition.Add(&fInterruptConditionEntry);
|
||||
}
|
||||
status_t result = fVirtio->queue_request(fVirtioQueue, NULL, &entry, NULL);
|
||||
if (result != B_OK) {
|
||||
ERROR("queueing failed (%s)\n", strerror(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
if (fOffset < BUFFER_SIZE) {
|
||||
size_t size = min_c(BUFFER_SIZE - fOffset, *_numBytes);
|
||||
if (user_memcpy(_buffer, fBuffer + fOffset, size) != B_OK)
|
||||
return B_BAD_ADDRESS;
|
||||
fOffset += size;
|
||||
*_numBytes = size;
|
||||
} else
|
||||
*_numBytes = 0;
|
||||
return B_OK;
|
||||
result = fInterruptConditionEntry.Wait(B_CAN_INTERRUPT);
|
||||
|
||||
{
|
||||
InterruptsSpinLocker locker(fInterruptLock);
|
||||
fExpectsInterrupt = false;
|
||||
}
|
||||
|
||||
if (result == B_OK) {
|
||||
if (value != 0) {
|
||||
gRandom->queue_randomness(value);
|
||||
TRACE("enqueue %" B_PRIx64 "\n", value);
|
||||
}
|
||||
} else if (result != B_OK && result != B_INTERRUPTED) {
|
||||
ERROR("request failed (%s)\n", strerror(result));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -145,3 +156,22 @@ VirtioRNGDevice::_RequestInterrupt()
|
||||
SpinLocker locker(fInterruptLock);
|
||||
fInterruptCondition.NotifyAll();
|
||||
}
|
||||
|
||||
|
||||
/*static*/ int32
|
||||
VirtioRNGDevice::HandleTimerHook(struct timer* timer)
|
||||
{
|
||||
VirtioRNGDevice* device = reinterpret_cast<VirtioRNGDevice*>(timer->user_data);
|
||||
|
||||
gDPC->queue_dpc(device->fDPCHandle, HandleDPC, device);
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
VirtioRNGDevice::HandleDPC(void *arg)
|
||||
{
|
||||
VirtioRNGDevice* device = reinterpret_cast<VirtioRNGDevice*>(arg);
|
||||
device->_Enqueue();
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
|
||||
#include <condition_variable.h>
|
||||
#include <dpc.h>
|
||||
#include <lock.h>
|
||||
#include "random.h"
|
||||
#include <virtio.h>
|
||||
@ -24,9 +25,7 @@
|
||||
|
||||
extern device_manager_info* gDeviceManager;
|
||||
extern random_for_controller_interface *gRandom;
|
||||
|
||||
|
||||
#define BUFFER_SIZE 16
|
||||
extern dpc_module_info *gDPC;
|
||||
|
||||
|
||||
class VirtioRNGDevice {
|
||||
@ -36,15 +35,15 @@ public:
|
||||
|
||||
status_t InitCheck();
|
||||
|
||||
status_t Read(void* buffer, size_t* numBytes);
|
||||
|
||||
protected:
|
||||
static int32 HandleTimerHook(struct timer* timer);
|
||||
static void HandleDPC(void* arg);
|
||||
|
||||
private:
|
||||
static void _RequestCallback(void* driverCookie,
|
||||
void *cookie);
|
||||
void _RequestInterrupt();
|
||||
|
||||
device_node* fNode;
|
||||
status_t _Enqueue();
|
||||
|
||||
virtio_device_interface* fVirtio;
|
||||
virtio_device* fVirtioDevice;
|
||||
@ -53,14 +52,13 @@ private:
|
||||
uint32 fFeatures;
|
||||
::virtio_queue fVirtioQueue;
|
||||
|
||||
physical_entry fEntry;
|
||||
uint8 fBuffer[BUFFER_SIZE];
|
||||
uint32 fOffset;
|
||||
|
||||
spinlock fInterruptLock;
|
||||
ConditionVariable fInterruptCondition;
|
||||
ConditionVariableEntry fInterruptConditionEntry;
|
||||
bool fExpectsInterrupt;
|
||||
|
||||
timer fTimer;
|
||||
void* fDPCHandle;
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,47 +19,7 @@
|
||||
|
||||
device_manager_info *gDeviceManager;
|
||||
random_for_controller_interface *gRandom;
|
||||
|
||||
|
||||
// #pragma mark - Random module interface
|
||||
|
||||
|
||||
static status_t
|
||||
sim_init_bus(device_node *node, void **_cookie)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
VirtioRNGDevice *device = new(std::nothrow)
|
||||
VirtioRNGDevice(node);
|
||||
if (device == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t status = device->InitCheck();
|
||||
if (status < B_OK) {
|
||||
delete device;
|
||||
return status;
|
||||
}
|
||||
|
||||
*_cookie = device;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sim_uninit_bus(void *cookie)
|
||||
{
|
||||
CALLED();
|
||||
VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
|
||||
|
||||
delete device;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
sim_read(void* cookie, void *_buffer, size_t *_numBytes)
|
||||
{
|
||||
VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
|
||||
return device->Read(_buffer, _numBytes);
|
||||
}
|
||||
dpc_module_info *gDPC;
|
||||
|
||||
|
||||
// #pragma mark - Driver module interface
|
||||
@ -107,77 +67,39 @@ static status_t
|
||||
virtio_rng_init_driver(device_node *node, void **_cookie)
|
||||
{
|
||||
CALLED();
|
||||
*_cookie = node;
|
||||
VirtioRNGDevice *device = new(std::nothrow) VirtioRNGDevice(node);
|
||||
if (device == NULL)
|
||||
return B_NO_MEMORY;
|
||||
status_t status = device->InitCheck();
|
||||
if (status < B_OK) {
|
||||
delete device;
|
||||
return status;
|
||||
}
|
||||
*_cookie = device;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
virtio_rng_register_child_devices(void *cookie)
|
||||
static void
|
||||
virtio_rng_uninit_driver(void *cookie)
|
||||
{
|
||||
CALLED();
|
||||
device_node *node = (device_node *)cookie;
|
||||
|
||||
device_attr attrs[] = {
|
||||
{ B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
|
||||
{ string: RANDOM_FOR_CONTROLLER_MODULE_NAME }},
|
||||
{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
|
||||
{ string: VIRTIO_RNG_CONTROLLER_PRETTY_NAME }},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
return gDeviceManager->register_node(node,
|
||||
VIRTIO_RNG_DEVICE_MODULE_NAME, attrs, NULL, NULL);
|
||||
VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
|
||||
delete device;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
case B_MODULE_UNINIT:
|
||||
return B_OK;
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static random_module_info sVirtioRNGDeviceInterface = {
|
||||
{
|
||||
{
|
||||
VIRTIO_RNG_DEVICE_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
},
|
||||
NULL, // supported devices
|
||||
NULL, // register node
|
||||
sim_init_bus,
|
||||
sim_uninit_bus,
|
||||
NULL, // register child devices
|
||||
NULL, // rescan
|
||||
NULL // bus_removed
|
||||
},
|
||||
|
||||
sim_read,
|
||||
NULL // write
|
||||
|
||||
};
|
||||
|
||||
|
||||
static driver_module_info sVirtioRNGDriver = {
|
||||
{
|
||||
VIRTIO_RNG_DRIVER_MODULE_NAME,
|
||||
0,
|
||||
std_ops
|
||||
NULL
|
||||
},
|
||||
virtio_rng_supports_device,
|
||||
virtio_rng_register_device,
|
||||
virtio_rng_init_driver,
|
||||
NULL, // uninit_driver,
|
||||
virtio_rng_register_child_devices,
|
||||
virtio_rng_uninit_driver,
|
||||
NULL,
|
||||
NULL, // rescan
|
||||
NULL, // device_removed
|
||||
};
|
||||
@ -186,12 +108,12 @@ static driver_module_info sVirtioRNGDriver = {
|
||||
module_dependency module_dependencies[] = {
|
||||
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
|
||||
{ RANDOM_FOR_CONTROLLER_MODULE_NAME, (module_info **)&gRandom },
|
||||
{ B_DPC_MODULE_NAME, (module_info **)&gDPC },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&sVirtioRNGDriver,
|
||||
(module_info *)&sVirtioRNGDeviceInterface,
|
||||
NULL
|
||||
};
|
||||
|
@ -1743,6 +1743,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
||||
_AddPath(*stack, "bus_managers");
|
||||
} else if (!generic) {
|
||||
_AddPath(*stack, "drivers");
|
||||
_AddPath(*stack, "busses/virtio");
|
||||
} else {
|
||||
// For generic drivers, we only allow busses when the
|
||||
// request is more specified
|
||||
@ -1756,7 +1757,6 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
||||
_AddPath(*stack, "busses/i2c");
|
||||
_AddPath(*stack, "busses/scsi");
|
||||
_AddPath(*stack, "busses/random");
|
||||
_AddPath(*stack, "busses/virtio");
|
||||
_AddPath(*stack, "bus_managers/pci");
|
||||
}
|
||||
break;
|
||||
|
Loading…
x
Reference in New Issue
Block a user