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 <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
0843085384
commit
34e9243872
@@ -14,18 +14,12 @@
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
driver_module_info info;
|
driver_module_info info;
|
||||||
|
|
||||||
|
status_t (*queue_randomness)(uint64 value);
|
||||||
} random_for_controller_interface;
|
} random_for_controller_interface;
|
||||||
|
|
||||||
|
|
||||||
#define RANDOM_FOR_CONTROLLER_MODULE_NAME "bus_managers/random/controller/driver_v1"
|
#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 */
|
#endif /* _RANDOM_H */
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
|
|
||||||
static mutex sRandomLock;
|
static mutex sRandomLock;
|
||||||
static random_module_info *sRandomModule;
|
|
||||||
static void *sRandomCookie;
|
static void *sRandomCookie;
|
||||||
device_manager_info* gDeviceManager;
|
device_manager_info* gDeviceManager;
|
||||||
|
|
||||||
@@ -44,6 +43,15 @@ typedef struct {
|
|||||||
} random_driver_info;
|
} 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
|
// #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);
|
TRACE("read(%Ld,, %ld)\n", position, *_numBytes);
|
||||||
|
|
||||||
MutexLocker locker(&sRandomLock);
|
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);
|
TRACE("write(%Ld,, %ld)\n", position, *_numBytes);
|
||||||
MutexLocker locker(&sRandomLock);
|
MutexLocker locker(&sRandomLock);
|
||||||
if (sRandomModule->write == NULL) {
|
return RANDOM_WRITE(sRandomCookie, buffer, _numBytes);
|
||||||
*_numBytes = 0;
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
return sRandomModule->write(sRandomCookie, buffer, _numBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -187,6 +191,7 @@ random_init_driver(device_node *node, void **cookie)
|
|||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
mutex_init(&sRandomLock, "/dev/random lock");
|
mutex_init(&sRandomLock, "/dev/random lock");
|
||||||
|
RANDOM_INIT();
|
||||||
|
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
|
|
||||||
@@ -202,6 +207,8 @@ random_uninit_driver(void *_cookie)
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
|
RANDOM_UNINIT();
|
||||||
|
|
||||||
mutex_destroy(&sRandomLock);
|
mutex_destroy(&sRandomLock);
|
||||||
|
|
||||||
random_driver_info* info = (random_driver_info*)_cookie;
|
random_driver_info* info = (random_driver_info*)_cookie;
|
||||||
@@ -220,38 +227,10 @@ random_register_child_devices(void* _cookie)
|
|||||||
gDeviceManager->publish_device(info->node, "urandom",
|
gDeviceManager->publish_device(info->node, "urandom",
|
||||||
RANDOM_DEVICE_MODULE_NAME);
|
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;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -311,11 +290,13 @@ random_for_controller_interface sRandomForControllerModule = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
NULL, // supported devices
|
NULL, // supported devices
|
||||||
random_added_device,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
}
|
},
|
||||||
|
|
||||||
|
random_queue_randomness,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -323,6 +304,5 @@ module_info* modules[] = {
|
|||||||
(module_info*)&sRandomDriver,
|
(module_info*)&sRandomDriver,
|
||||||
(module_info*)&sRandomDevice,
|
(module_info*)&sRandomDevice,
|
||||||
(module_info*)&sRandomForControllerModule,
|
(module_info*)&sRandomForControllerModule,
|
||||||
(module_info*)&gYarrowRandomModule,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -286,10 +286,28 @@ kill_chrand(ch_randgen *randgen)
|
|||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #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)
|
yarrow_rng_read(void* cookie, void *_buffer, size_t *_numBytes)
|
||||||
{
|
{
|
||||||
if (!IS_USER_ADDRESS(_buffer))
|
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)
|
yarrow_rng_write(void* cookie, const void *_buffer, size_t *_numBytes)
|
||||||
{
|
{
|
||||||
OCTET *buffer = (OCTET*)_buffer;
|
OCTET *buffer = (OCTET*)_buffer;
|
||||||
@@ -342,54 +360,9 @@ yarrow_rng_write(void* cookie, const void *_buffer, size_t *_numBytes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
void
|
||||||
|
yarrow_enqueue_randomness(const uint64 value)
|
||||||
|
|
||||||
static status_t
|
|
||||||
yarrow_init_bus(device_node* node, void** bus_cookie)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
sRandomEnv = new_chrand(8);
|
chseed(sRandomEnv, value);
|
||||||
if (sRandomEnv == NULL)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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"
|
#include "random.h"
|
||||||
|
|
||||||
|
|
||||||
#define YARROW_RNG_SIM_MODULE_NAME "bus_managers/random/yarrow_rng/device/v1"
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -24,24 +24,19 @@ get_feature_name(uint32 feature)
|
|||||||
|
|
||||||
VirtioRNGDevice::VirtioRNGDevice(device_node *node)
|
VirtioRNGDevice::VirtioRNGDevice(device_node *node)
|
||||||
:
|
:
|
||||||
fNode(node),
|
|
||||||
fVirtio(NULL),
|
fVirtio(NULL),
|
||||||
fVirtioDevice(NULL),
|
fVirtioDevice(NULL),
|
||||||
fStatus(B_NO_INIT),
|
fStatus(B_NO_INIT),
|
||||||
fOffset(BUFFER_SIZE),
|
fExpectsInterrupt(false),
|
||||||
fExpectsInterrupt(false)
|
fDPCHandle(NULL)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
B_INITIALIZE_SPINLOCK(&fInterruptLock);
|
B_INITIALIZE_SPINLOCK(&fInterruptLock);
|
||||||
fInterruptCondition.Init(this, "virtio rng transfer");
|
fInterruptCondition.Init(this, "virtio rng transfer");
|
||||||
|
|
||||||
get_memory_map(fBuffer, BUFFER_SIZE, &fEntry, 1);
|
|
||||||
|
|
||||||
// get the Virtio device from our parent's parent
|
// get the Virtio device from our parent's parent
|
||||||
device_node *parent = gDeviceManager->get_parent_node(node);
|
device_node *virtioParent = gDeviceManager->get_parent_node(node);
|
||||||
device_node *virtioParent = gDeviceManager->get_parent_node(parent);
|
|
||||||
gDeviceManager->put_node(parent);
|
|
||||||
|
|
||||||
gDeviceManager->get_driver(virtioParent, (driver_module_info **)&fVirtio,
|
gDeviceManager->get_driver(virtioParent, (driver_module_info **)&fVirtio,
|
||||||
(void **)&fVirtioDevice);
|
(void **)&fVirtioDevice);
|
||||||
@@ -68,11 +63,31 @@ VirtioRNGDevice::VirtioRNGDevice(device_node *node)
|
|||||||
ERROR("queue interrupt setup failed (%s)\n", strerror(fStatus));
|
ERROR("queue interrupt setup failed (%s)\n", strerror(fStatus));
|
||||||
return;
|
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()
|
VirtioRNGDevice::~VirtioRNGDevice()
|
||||||
{
|
{
|
||||||
|
cancel_timer(&fTimer);
|
||||||
|
gDPC->delete_dpc_queue(fDPCHandle);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -84,46 +99,42 @@ VirtioRNGDevice::InitCheck()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
VirtioRNGDevice::Read(void* _buffer, size_t* _numBytes)
|
VirtioRNGDevice::_Enqueue()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (fOffset >= BUFFER_SIZE) {
|
uint64 value = 0;
|
||||||
{
|
physical_entry entry;
|
||||||
InterruptsSpinLocker locker(fInterruptLock);
|
get_memory_map(&value, sizeof(value), &entry, 1);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = fInterruptConditionEntry.Wait(B_CAN_INTERRUPT);
|
{
|
||||||
|
InterruptsSpinLocker locker(fInterruptLock);
|
||||||
{
|
fExpectsInterrupt = true;
|
||||||
InterruptsSpinLocker locker(fInterruptLock);
|
fInterruptCondition.Add(&fInterruptConditionEntry);
|
||||||
fExpectsInterrupt = false;
|
}
|
||||||
}
|
status_t result = fVirtio->queue_request(fVirtioQueue, NULL, &entry, NULL);
|
||||||
|
if (result != B_OK) {
|
||||||
if (result == B_OK) {
|
ERROR("queueing failed (%s)\n", strerror(result));
|
||||||
fOffset = 0;
|
return result;
|
||||||
} else if (result != B_INTERRUPTED) {
|
|
||||||
ERROR("request failed (%s)\n", strerror(result));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fOffset < BUFFER_SIZE) {
|
result = fInterruptConditionEntry.Wait(B_CAN_INTERRUPT);
|
||||||
size_t size = min_c(BUFFER_SIZE - fOffset, *_numBytes);
|
|
||||||
if (user_memcpy(_buffer, fBuffer + fOffset, size) != B_OK)
|
{
|
||||||
return B_BAD_ADDRESS;
|
InterruptsSpinLocker locker(fInterruptLock);
|
||||||
fOffset += size;
|
fExpectsInterrupt = false;
|
||||||
*_numBytes = size;
|
}
|
||||||
} else
|
|
||||||
*_numBytes = 0;
|
if (result == B_OK) {
|
||||||
return 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);
|
SpinLocker locker(fInterruptLock);
|
||||||
fInterruptCondition.NotifyAll();
|
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 <condition_variable.h>
|
||||||
|
#include <dpc.h>
|
||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
#include <virtio.h>
|
#include <virtio.h>
|
||||||
@@ -24,9 +25,7 @@
|
|||||||
|
|
||||||
extern device_manager_info* gDeviceManager;
|
extern device_manager_info* gDeviceManager;
|
||||||
extern random_for_controller_interface *gRandom;
|
extern random_for_controller_interface *gRandom;
|
||||||
|
extern dpc_module_info *gDPC;
|
||||||
|
|
||||||
#define BUFFER_SIZE 16
|
|
||||||
|
|
||||||
|
|
||||||
class VirtioRNGDevice {
|
class VirtioRNGDevice {
|
||||||
@@ -36,15 +35,15 @@ public:
|
|||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
status_t Read(void* buffer, size_t* numBytes);
|
protected:
|
||||||
|
static int32 HandleTimerHook(struct timer* timer);
|
||||||
|
static void HandleDPC(void* arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _RequestCallback(void* driverCookie,
|
static void _RequestCallback(void* driverCookie,
|
||||||
void *cookie);
|
void *cookie);
|
||||||
void _RequestInterrupt();
|
void _RequestInterrupt();
|
||||||
|
status_t _Enqueue();
|
||||||
device_node* fNode;
|
|
||||||
|
|
||||||
virtio_device_interface* fVirtio;
|
virtio_device_interface* fVirtio;
|
||||||
virtio_device* fVirtioDevice;
|
virtio_device* fVirtioDevice;
|
||||||
@@ -53,14 +52,13 @@ private:
|
|||||||
uint32 fFeatures;
|
uint32 fFeatures;
|
||||||
::virtio_queue fVirtioQueue;
|
::virtio_queue fVirtioQueue;
|
||||||
|
|
||||||
physical_entry fEntry;
|
|
||||||
uint8 fBuffer[BUFFER_SIZE];
|
|
||||||
uint32 fOffset;
|
|
||||||
|
|
||||||
spinlock fInterruptLock;
|
spinlock fInterruptLock;
|
||||||
ConditionVariable fInterruptCondition;
|
ConditionVariable fInterruptCondition;
|
||||||
ConditionVariableEntry fInterruptConditionEntry;
|
ConditionVariableEntry fInterruptConditionEntry;
|
||||||
bool fExpectsInterrupt;
|
bool fExpectsInterrupt;
|
||||||
|
|
||||||
|
timer fTimer;
|
||||||
|
void* fDPCHandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,47 +19,7 @@
|
|||||||
|
|
||||||
device_manager_info *gDeviceManager;
|
device_manager_info *gDeviceManager;
|
||||||
random_for_controller_interface *gRandom;
|
random_for_controller_interface *gRandom;
|
||||||
|
dpc_module_info *gDPC;
|
||||||
|
|
||||||
// #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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Driver module interface
|
// #pragma mark - Driver module interface
|
||||||
@@ -107,77 +67,39 @@ static status_t
|
|||||||
virtio_rng_init_driver(device_node *node, void **_cookie)
|
virtio_rng_init_driver(device_node *node, void **_cookie)
|
||||||
{
|
{
|
||||||
CALLED();
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static void
|
||||||
virtio_rng_register_child_devices(void *cookie)
|
virtio_rng_uninit_driver(void *cookie)
|
||||||
{
|
{
|
||||||
CALLED();
|
VirtioRNGDevice *device = (VirtioRNGDevice*)cookie;
|
||||||
device_node *node = (device_node *)cookie;
|
delete device;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 = {
|
static driver_module_info sVirtioRNGDriver = {
|
||||||
{
|
{
|
||||||
VIRTIO_RNG_DRIVER_MODULE_NAME,
|
VIRTIO_RNG_DRIVER_MODULE_NAME,
|
||||||
0,
|
0,
|
||||||
std_ops
|
NULL
|
||||||
},
|
},
|
||||||
virtio_rng_supports_device,
|
virtio_rng_supports_device,
|
||||||
virtio_rng_register_device,
|
virtio_rng_register_device,
|
||||||
virtio_rng_init_driver,
|
virtio_rng_init_driver,
|
||||||
NULL, // uninit_driver,
|
virtio_rng_uninit_driver,
|
||||||
virtio_rng_register_child_devices,
|
NULL,
|
||||||
NULL, // rescan
|
NULL, // rescan
|
||||||
NULL, // device_removed
|
NULL, // device_removed
|
||||||
};
|
};
|
||||||
@@ -186,12 +108,12 @@ static driver_module_info sVirtioRNGDriver = {
|
|||||||
module_dependency module_dependencies[] = {
|
module_dependency module_dependencies[] = {
|
||||||
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
|
{ B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
|
||||||
{ RANDOM_FOR_CONTROLLER_MODULE_NAME, (module_info **)&gRandom },
|
{ RANDOM_FOR_CONTROLLER_MODULE_NAME, (module_info **)&gRandom },
|
||||||
|
{ B_DPC_MODULE_NAME, (module_info **)&gDPC },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
module_info *modules[] = {
|
module_info *modules[] = {
|
||||||
(module_info *)&sVirtioRNGDriver,
|
(module_info *)&sVirtioRNGDriver,
|
||||||
(module_info *)&sVirtioRNGDeviceInterface,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1743,6 +1743,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
|||||||
_AddPath(*stack, "bus_managers");
|
_AddPath(*stack, "bus_managers");
|
||||||
} else if (!generic) {
|
} else if (!generic) {
|
||||||
_AddPath(*stack, "drivers");
|
_AddPath(*stack, "drivers");
|
||||||
|
_AddPath(*stack, "busses/virtio");
|
||||||
} else {
|
} else {
|
||||||
// For generic drivers, we only allow busses when the
|
// For generic drivers, we only allow busses when the
|
||||||
// request is more specified
|
// request is more specified
|
||||||
@@ -1756,7 +1757,6 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
|
|||||||
_AddPath(*stack, "busses/i2c");
|
_AddPath(*stack, "busses/i2c");
|
||||||
_AddPath(*stack, "busses/scsi");
|
_AddPath(*stack, "busses/scsi");
|
||||||
_AddPath(*stack, "busses/random");
|
_AddPath(*stack, "busses/random");
|
||||||
_AddPath(*stack, "busses/virtio");
|
|
||||||
_AddPath(*stack, "bus_managers/pci");
|
_AddPath(*stack, "bus_managers/pci");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user