fixed listdev and device_manager syscalls

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@25833 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2008-06-06 22:23:25 +00:00
parent bf319ba31d
commit 75d2085651
5 changed files with 142 additions and 177 deletions

View File

@ -17,9 +17,11 @@
#define DM_GET_NEXT_CHILD 3
#define DM_GET_NEXT_ATTRIBUTE 4
typedef addr_t device_node_cookie;
struct device_attr_info {
uint32 node_cookie;
uint32 cookie;
device_node_cookie node_cookie;
device_node_cookie cookie;
char name[255];
type_code type;
union {

View File

@ -4,6 +4,7 @@
#include <unistd.h>
#include <drivers/device_manager.h>
#include <device_manager_defs.h>
#include <generic_syscall_defs.h>
#include <string.h>
#include <syscalls.h>
@ -23,26 +24,26 @@ status_t uninit_dm_wrapper(void)
}
status_t
get_root(uint32 *cookie)
get_root(device_node_cookie *cookie)
{
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_ROOT, cookie, sizeof(uint32));
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_ROOT, cookie, sizeof(device_node_cookie));
}
status_t
get_child(uint32 *device)
get_child(device_node_cookie *device)
{
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_CHILD, device, sizeof(uint32));
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_CHILD, device, sizeof(device_node_cookie));
}
status_t
get_next_child(uint32 *device)
get_next_child(device_node_cookie *device)
{
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_NEXT_CHILD, device, sizeof(uint32));
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_NEXT_CHILD, device, sizeof(device_node_cookie));
}
status_t
dm_get_next_attr(struct dev_attr *attr)
dm_get_next_attr(struct device_attr_info *attr)
{
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_NEXT_ATTRIBUTE, attr, sizeof(struct dev_attr));
return _kern_generic_syscall(DEVICE_MANAGER_SYSCALLS, DM_GET_NEXT_ATTRIBUTE, attr, sizeof(struct device_attr_info));
}

View File

@ -1,14 +1,14 @@
#ifndef _DM_WRAPPER_H_
#define _DM_WRAPPER_H_
#include "kdevice_manager.h"
#include "device_manager_defs.h"
status_t init_dm_wrapper(void);
status_t uninit_dm_wrapper(void);
status_t get_root(uint32 *cookie);
status_t get_child(uint32 *cookie);
status_t get_next_child(uint32 *cookie);
status_t dm_get_next_attr(struct dev_attr *attr);
status_t get_root(device_node_cookie *cookie);
status_t get_child(device_node_cookie *cookie);
status_t get_next_child(device_node_cookie *cookie);
status_t dm_get_next_attr(struct device_attr_info *attr);
#endif

View File

@ -74,7 +74,7 @@ put_level(int32 level)
static void
dump_attribute(struct dev_attr *attr, int32 level)
dump_attribute(struct device_attr_info *attr, int32 level)
{
if (attr == NULL)
return;
@ -105,10 +105,10 @@ dump_attribute(struct dev_attr *attr, int32 level)
static void
dump_device(uint32 *node, uint8 level)
dump_device(device_node_cookie *node, uint8 level)
{
char data[256];
struct dev_attr attr;
struct device_attr_info attr;
attr.cookie = 0;
attr.node_cookie = *node;
attr.value.raw.data = data;
@ -121,14 +121,12 @@ dump_device(uint32 *node, uint8 level)
static void
dump_nodes(uint32 *node, uint8 level)
dump_nodes(device_node_cookie *node, uint8 level)
{
status_t err;
uint32 child = *node;
device_node_cookie child = *node;
dump_device(node, level);
printf("node %lu\n", *node);
if (get_child(&child) != B_OK)
return;
@ -140,17 +138,17 @@ dump_nodes(uint32 *node, uint8 level)
static int32
display_device(uint32 *node, uint8 level, int parent_bus, int *bus)
display_device(device_node_cookie *node, uint8 level)
{
uint8 new_level = level;
char data[256];
struct dev_attr attr;
struct device_attr_info attr;
// BUS attributes
uint8 is_bus = 0;
char connection[64];
char device_bus[64];
uint8 scsi_path_id = 255;
int bus = 0;
// PCI attributes
uint8 pci_class_base_id = 0;
@ -179,76 +177,62 @@ display_device(uint32 *node, uint8 level, int parent_bus, int *bus)
attr.value.raw.length = sizeof(data);
while (dm_get_next_attr(&attr) == B_OK) {
if (!strcmp(attr.name, PNP_BUS_IS_BUS)
&& attr.type == B_UINT8_TYPE) {
is_bus = attr.value.ui8;
} else if (!strcmp(attr.name, PNP_DRIVER_CONNECTION)
if (!strcmp(attr.name, B_DEVICE_BUS)
&& attr.type == B_STRING_TYPE) {
strlcpy(connection, attr.value.string, 64);
strlcpy(device_bus, attr.value.string, 64);
} else if (!strcmp(attr.name, "scsi/path_id")
&& attr.type == B_UINT8_TYPE) {
scsi_path_id = attr.value.ui8;
}
} else if (!strcmp(attr.name, B_DEVICE_TYPE)
&& attr.type == B_UINT8_TYPE)
pci_class_base_id = attr.value.ui8;
else if (!strcmp(attr.name, B_DEVICE_SUB_TYPE)
&& attr.type == B_UINT8_TYPE)
pci_class_sub_id = attr.value.ui8;
else if (!strcmp(attr.name, B_DEVICE_INTERFACE)
&& attr.type == B_UINT8_TYPE)
pci_class_api_id = attr.value.ui8;
else if (!strcmp(attr.name, B_DEVICE_VENDOR_ID)
&& attr.type == B_UINT16_TYPE)
pci_vendor_id = attr.value.ui16;
else if (!strcmp(attr.name, B_DEVICE_ID)
&& attr.type == B_UINT16_TYPE)
pci_device_id = attr.value.ui16;
else if (!strcmp(attr.name, SCSI_DEVICE_TARGET_LUN_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_target_lun = attr.value.ui8;
else if (!strcmp(attr.name, SCSI_DEVICE_TARGET_ID_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_target_id = attr.value.ui8;
else if (!strcmp(attr.name, SCSI_DEVICE_TYPE_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_type = attr.value.ui8;
else if (!strcmp(attr.name, SCSI_DEVICE_VENDOR_ITEM)
&& attr.type == B_STRING_TYPE)
strlcpy(scsi_vendor, attr.value.string, 64);
else if (!strcmp(attr.name, SCSI_DEVICE_PRODUCT_ITEM)
&& attr.type == B_STRING_TYPE)
strlcpy(scsi_product, attr.value.string, 64);
switch (parent_bus) {
case BUS_ISA:
break;
case BUS_PCI:
if (!strcmp(attr.name, PCI_DEVICE_BASE_CLASS_ID_ITEM)
&& attr.type == B_UINT8_TYPE)
pci_class_base_id = attr.value.ui8;
else if (!strcmp(attr.name, PCI_DEVICE_SUB_CLASS_ID_ITEM)
&& attr.type == B_UINT8_TYPE)
pci_class_sub_id = attr.value.ui8;
else if (!strcmp(attr.name, PCI_DEVICE_API_ID_ITEM)
&& attr.type == B_UINT8_TYPE)
pci_class_api_id = attr.value.ui8;
else if (!strcmp(attr.name, PCI_DEVICE_VENDOR_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_vendor_id = attr.value.ui16;
else if (!strcmp(attr.name, PCI_DEVICE_DEVICE_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_device_id = attr.value.ui16;
else if (!strcmp(attr.name, PCI_DEVICE_SUBVENDOR_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_subsystem_vendor_id = attr.value.ui16;
else if (!strcmp(attr.name, PCI_DEVICE_SUBSYSTEM_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_subsystem_id = attr.value.ui16;
break;
case BUS_SCSI:
if (!strcmp(attr.name, SCSI_DEVICE_TARGET_LUN_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_target_lun = attr.value.ui8;
if (!strcmp(attr.name, SCSI_DEVICE_TARGET_ID_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_target_id = attr.value.ui8;
if (!strcmp(attr.name, SCSI_DEVICE_TYPE_ITEM)
&& attr.type == B_UINT8_TYPE)
scsi_type = attr.value.ui8;
if (!strcmp(attr.name, SCSI_DEVICE_VENDOR_ITEM)
&& attr.type == B_STRING_TYPE)
strlcpy(scsi_vendor, attr.value.string, 64);
if (!strcmp(attr.name, SCSI_DEVICE_PRODUCT_ITEM)
&& attr.type == B_STRING_TYPE)
strlcpy(scsi_product, attr.value.string, 64);
break;
};
if (!strcmp(device_bus, "isa"))
bus = BUS_ISA;
else if (!strcmp(device_bus, "pci"))
bus = BUS_PCI;
else if (scsi_path_id < 255)
bus = BUS_SCSI;
/*else if (!strcmp(attr.name, PCI_DEVICE_SUBVENDOR_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_subsystem_vendor_id = attr.value.ui16;
else if (!strcmp(attr.name, PCI_DEVICE_SUBSYSTEM_ID_ITEM)
&& attr.type == B_UINT16_TYPE)
pci_subsystem_id = attr.value.ui16;*/
attr.value.raw.data = data;
attr.value.raw.length = sizeof(data);
}
if (is_bus) {
if (!strcmp(connection, "ISA"))
*bus = BUS_ISA;
else if (!strcmp(connection, "PCI"))
*bus = BUS_PCI;
else if (scsi_path_id < 255)
*bus = BUS_SCSI;
}
switch (parent_bus) {
switch (bus) {
case BUS_ISA:
new_level=level+1;
break;
@ -303,18 +287,17 @@ display_device(uint32 *node, uint8 level, int parent_bus, int *bus)
static void
display_nodes(uint32 *node, uint8 level, int parent_bus)
display_nodes(device_node_cookie *node, uint8 level)
{
status_t err;
uint32 child = *node;
int bus = 0;
level = display_device(node, level, parent_bus, &bus);
device_node_cookie child = *node;
level = display_device(node, level);
if (get_child(&child) != B_OK)
return;
do {
display_nodes(&child, level, bus);
display_nodes(&child, level);
} while ((err = get_next_child(&child)) == B_OK);
}
@ -323,7 +306,7 @@ int
main(int argc, char **argv)
{
status_t error;
uint32 root;
device_node_cookie root;
if ((error = init_dm_wrapper()) < 0) {
printf("Error initializing device manager (%s)\n", strerror(error));
@ -346,7 +329,7 @@ main(int argc, char **argv)
dump_nodes(&root, 0);
} else {
get_root(&root);
display_nodes(&root, 0, 0);
display_nodes(&root, 0);
}
uninit_dm_wrapper();

View File

@ -21,6 +21,7 @@
#include <device_manager_defs.h>
#include <fs/devfs.h>
#include <fs/KPath.h>
#include <kernel.h>
#include <generic_syscall.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
@ -323,134 +324,115 @@ control_device_manager(const char* subsystem, uint32 function, void* buffer,
switch (function) {
case DM_GET_ROOT:
{
return B_ERROR;
#if 0
uint32 cookie;
device_node_cookie cookie;
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32))
if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE;
cookie = sRootNode->ID();
cookie = (device_node_cookie)sRootNode;
// copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32));
#endif
return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
}
case DM_GET_CHILD:
{
return B_ERROR;
#if 0
device_node_info* node;
device_node_info* child;
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32))
if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE;
uint32 cookie;
if (user_memcpy(&cookie, buffer, sizeof(uint32)) < B_OK)
device_node_cookie cookie;
if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK)
return B_BAD_ADDRESS;
mutex_lock(&gNodeLock);
node = device_manager_find_device(gRootNode, cookie);
if (!node) {
mutex_unlock(&gNodeLock);
return B_BAD_VALUE;
}
child = (device_node_info *)list_get_next_item(&node->children, NULL);
if (child)
cookie = child->internal_id;
mutex_unlock(&gNodeLock);
if (!child)
device_node* node = (device_node*)cookie;
NodeList::ConstIterator iterator = node->Children().GetIterator();
if (!iterator.HasNext()) {
return B_ENTRY_NOT_FOUND;
}
node = iterator.Next();
cookie = (device_node_cookie)node;
// copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32));
#endif
return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
}
case DM_GET_NEXT_CHILD:
{
return B_ERROR;
#if 0
device_node_info* node;
device_node_info* child;
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32))
if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE;
uint32 cookie;
if (user_memcpy(&cookie, buffer, sizeof(uint32)) < B_OK)
device_node_cookie cookie;
if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK)
return B_BAD_ADDRESS;
mutex_lock(&gNodeLock);
node = device_manager_find_device(gRootNode, cookie);
if (!node) {
mutex_unlock(&gNodeLock);
return B_BAD_VALUE;
}
child = (device_node_info *)list_get_next_item(&node->parent->children, node);
if (child)
cookie = child->internal_id;
mutex_unlock(&gNodeLock);
if (!child)
device_node* last = (device_node*)cookie;
if (!last->Parent())
return B_ENTRY_NOT_FOUND;
NodeList::ConstIterator iterator = last->Parent()->Children().GetIterator();
// skip those we already traversed
while (iterator.HasNext() && last != NULL) {
device_node* node = iterator.Next();
if (node == last)
break;
}
if (!iterator.HasNext())
return B_ENTRY_NOT_FOUND;
device_node* node = iterator.Next();
cookie = (device_node_cookie)node;
// copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32));
#endif
return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
}
case DM_GET_NEXT_ATTRIBUTE:
{
return B_ERROR;
#if 0
struct dev_attr attr;
device_node_info* node;
uint32 i = 0;
device_attr_info *attr_info;
struct device_attr_info attr_info;
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (bufferSize < sizeof(struct dev_attr))
if (bufferSize < sizeof(struct device_attr_info))
return B_BAD_VALUE;
if (user_memcpy(&attr, buffer, sizeof(struct dev_attr)) < B_OK)
if (user_memcpy(&attr_info, buffer, sizeof(struct device_attr_info)) < B_OK)
return B_BAD_ADDRESS;
mutex_lock(&gNodeLock);
node = device_manager_find_device(gRootNode, attr.node_cookie);
if (!node) {
mutex_unlock(&gNodeLock);
return B_BAD_VALUE;
}
for (attr_info = node->attributes; attr.cookie > i && attr_info != NULL; attr_info = attr_info->next) {
i++;
device_node* node = (device_node*)attr_info.node_cookie;
device_attr* last = (device_attr*)attr_info.cookie;
AttributeList::Iterator iterator = node->Attributes().GetIterator();
// skip those we already traversed
while (iterator.HasNext() && last != NULL) {
device_attr* attr = iterator.Next();
if (attr == last)
break;
}
if (!attr_info) {
mutex_unlock(&gNodeLock);
if (!iterator.HasNext()) {
attr_info.cookie = 0;
return B_ENTRY_NOT_FOUND;
}
attr.cookie++;
strlcpy(attr.name, attr_info->attr.name, 254);
attr.type = attr_info->attr.type;
switch (attr_info->attr.type) {
device_attr* attr = iterator.Next();
attr_info.cookie = (device_node_cookie)attr;
strlcpy(attr_info.name, attr->name, 254);
attr_info.type = attr->type;
switch (attr_info.type) {
case B_UINT8_TYPE:
attr.value.ui8 = attr_info->attr.value.ui8; break;
attr_info.value.ui8 = attr->value.ui8; break;
case B_UINT16_TYPE:
attr.value.ui16 = attr_info->attr.value.ui16; break;
attr_info.value.ui16 = attr->value.ui16; break;
case B_UINT32_TYPE:
attr.value.ui32 = attr_info->attr.value.ui32; break;
attr_info.value.ui32 = attr->value.ui32; break;
case B_UINT64_TYPE:
attr.value.ui64 = attr_info->attr.value.ui64; break;
attr_info.value.ui64 = attr->value.ui64; break;
case B_STRING_TYPE:
strlcpy(attr.value.string, attr_info->attr.value.string, 254); break;
strlcpy(attr_info.value.string, attr->value.string, 254); break;
/*case B_RAW_TYPE:
if (attr.value.raw.length > attr_info->attr.value.raw.length)
attr.value.raw.length = attr_info->attr.value.raw.length;
@ -459,11 +441,8 @@ control_device_manager(const char* subsystem, uint32 function, void* buffer,
break;*/
}
mutex_unlock(&gNodeLock);
// copy back to user space
return user_memcpy(buffer, &attr, sizeof(struct dev_attr));
#endif
return user_memcpy(buffer, &attr_info, sizeof(struct device_attr_info));
}
}