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
+4 -2
View File
@@ -17,9 +17,11 @@
#define DM_GET_NEXT_CHILD 3 #define DM_GET_NEXT_CHILD 3
#define DM_GET_NEXT_ATTRIBUTE 4 #define DM_GET_NEXT_ATTRIBUTE 4
typedef addr_t device_node_cookie;
struct device_attr_info { struct device_attr_info {
uint32 node_cookie; device_node_cookie node_cookie;
uint32 cookie; device_node_cookie cookie;
char name[255]; char name[255];
type_code type; type_code type;
union { union {
+9 -8
View File
@@ -4,6 +4,7 @@
#include <unistd.h> #include <unistd.h>
#include <drivers/device_manager.h> #include <drivers/device_manager.h>
#include <device_manager_defs.h>
#include <generic_syscall_defs.h> #include <generic_syscall_defs.h>
#include <string.h> #include <string.h>
#include <syscalls.h> #include <syscalls.h>
@@ -23,26 +24,26 @@ status_t uninit_dm_wrapper(void)
} }
status_t 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 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 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 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));
} }
+5 -5
View File
@@ -1,14 +1,14 @@
#ifndef _DM_WRAPPER_H_ #ifndef _DM_WRAPPER_H_
#define _DM_WRAPPER_H_ #define _DM_WRAPPER_H_
#include "kdevice_manager.h" #include "device_manager_defs.h"
status_t init_dm_wrapper(void); status_t init_dm_wrapper(void);
status_t uninit_dm_wrapper(void); status_t uninit_dm_wrapper(void);
status_t get_root(uint32 *cookie); status_t get_root(device_node_cookie *cookie);
status_t get_child(uint32 *cookie); status_t get_child(device_node_cookie *cookie);
status_t get_next_child(uint32 *cookie); status_t get_next_child(device_node_cookie *cookie);
status_t dm_get_next_attr(struct dev_attr *attr); status_t dm_get_next_attr(struct device_attr_info *attr);
#endif #endif
+61 -78
View File
@@ -74,7 +74,7 @@ put_level(int32 level)
static void static void
dump_attribute(struct dev_attr *attr, int32 level) dump_attribute(struct device_attr_info *attr, int32 level)
{ {
if (attr == NULL) if (attr == NULL)
return; return;
@@ -105,10 +105,10 @@ dump_attribute(struct dev_attr *attr, int32 level)
static void static void
dump_device(uint32 *node, uint8 level) dump_device(device_node_cookie *node, uint8 level)
{ {
char data[256]; char data[256];
struct dev_attr attr; struct device_attr_info attr;
attr.cookie = 0; attr.cookie = 0;
attr.node_cookie = *node; attr.node_cookie = *node;
attr.value.raw.data = data; attr.value.raw.data = data;
@@ -121,14 +121,12 @@ dump_device(uint32 *node, uint8 level)
static void static void
dump_nodes(uint32 *node, uint8 level) dump_nodes(device_node_cookie *node, uint8 level)
{ {
status_t err; status_t err;
uint32 child = *node; device_node_cookie child = *node;
dump_device(node, level); dump_device(node, level);
printf("node %lu\n", *node);
if (get_child(&child) != B_OK) if (get_child(&child) != B_OK)
return; return;
@@ -140,17 +138,17 @@ dump_nodes(uint32 *node, uint8 level)
static int32 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; uint8 new_level = level;
char data[256]; char data[256];
struct dev_attr attr; struct device_attr_info attr;
// BUS attributes // BUS attributes
uint8 is_bus = 0; char device_bus[64];
char connection[64];
uint8 scsi_path_id = 255; uint8 scsi_path_id = 255;
int bus = 0;
// PCI attributes // PCI attributes
uint8 pci_class_base_id = 0; 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); attr.value.raw.length = sizeof(data);
while (dm_get_next_attr(&attr) == B_OK) { while (dm_get_next_attr(&attr) == B_OK) {
if (!strcmp(attr.name, PNP_BUS_IS_BUS) if (!strcmp(attr.name, B_DEVICE_BUS)
&& attr.type == B_UINT8_TYPE) {
is_bus = attr.value.ui8;
} else if (!strcmp(attr.name, PNP_DRIVER_CONNECTION)
&& attr.type == B_STRING_TYPE) { && 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") } else if (!strcmp(attr.name, "scsi/path_id")
&& attr.type == B_UINT8_TYPE) { && attr.type == B_UINT8_TYPE) {
scsi_path_id = attr.value.ui8; 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) { if (!strcmp(device_bus, "isa"))
case BUS_ISA: bus = BUS_ISA;
break; else if (!strcmp(device_bus, "pci"))
case BUS_PCI: bus = BUS_PCI;
if (!strcmp(attr.name, PCI_DEVICE_BASE_CLASS_ID_ITEM) else if (scsi_path_id < 255)
&& attr.type == B_UINT8_TYPE) bus = BUS_SCSI;
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;
};
/*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.data = data;
attr.value.raw.length = sizeof(data); attr.value.raw.length = sizeof(data);
} }
if (is_bus) { switch (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) {
case BUS_ISA: case BUS_ISA:
new_level=level+1; new_level=level+1;
break; break;
@@ -303,18 +287,17 @@ display_device(uint32 *node, uint8 level, int parent_bus, int *bus)
static void static void
display_nodes(uint32 *node, uint8 level, int parent_bus) display_nodes(device_node_cookie *node, uint8 level)
{ {
status_t err; status_t err;
uint32 child = *node; device_node_cookie child = *node;
int bus = 0; level = display_device(node, level);
level = display_device(node, level, parent_bus, &bus);
if (get_child(&child) != B_OK) if (get_child(&child) != B_OK)
return; return;
do { do {
display_nodes(&child, level, bus); display_nodes(&child, level);
} while ((err = get_next_child(&child)) == B_OK); } while ((err = get_next_child(&child)) == B_OK);
} }
@@ -323,7 +306,7 @@ int
main(int argc, char **argv) main(int argc, char **argv)
{ {
status_t error; status_t error;
uint32 root; device_node_cookie root;
if ((error = init_dm_wrapper()) < 0) { if ((error = init_dm_wrapper()) < 0) {
printf("Error initializing device manager (%s)\n", strerror(error)); printf("Error initializing device manager (%s)\n", strerror(error));
@@ -346,7 +329,7 @@ main(int argc, char **argv)
dump_nodes(&root, 0); dump_nodes(&root, 0);
} else { } else {
get_root(&root); get_root(&root);
display_nodes(&root, 0, 0); display_nodes(&root, 0);
} }
uninit_dm_wrapper(); uninit_dm_wrapper();
@@ -21,6 +21,7 @@
#include <device_manager_defs.h> #include <device_manager_defs.h>
#include <fs/devfs.h> #include <fs/devfs.h>
#include <fs/KPath.h> #include <fs/KPath.h>
#include <kernel.h>
#include <generic_syscall.h> #include <generic_syscall.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
@@ -323,134 +324,115 @@ control_device_manager(const char* subsystem, uint32 function, void* buffer,
switch (function) { switch (function) {
case DM_GET_ROOT: case DM_GET_ROOT:
{ {
return B_ERROR; device_node_cookie cookie;
#if 0
uint32 cookie;
if (!IS_USER_ADDRESS(buffer)) if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32)) if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE; return B_BAD_VALUE;
cookie = sRootNode->ID(); cookie = (device_node_cookie)sRootNode;
// copy back to user space // copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32)); return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
#endif
} }
case DM_GET_CHILD: case DM_GET_CHILD:
{ {
return B_ERROR;
#if 0
device_node_info* node;
device_node_info* child;
if (!IS_USER_ADDRESS(buffer)) if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32)) if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE; return B_BAD_VALUE;
uint32 cookie; device_node_cookie cookie;
if (user_memcpy(&cookie, buffer, sizeof(uint32)) < B_OK) if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
mutex_lock(&gNodeLock); device_node* node = (device_node*)cookie;
node = device_manager_find_device(gRootNode, cookie); NodeList::ConstIterator iterator = node->Children().GetIterator();
if (!node) {
mutex_unlock(&gNodeLock); if (!iterator.HasNext()) {
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)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
}
node = iterator.Next();
cookie = (device_node_cookie)node;
// copy back to user space // copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32)); return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
#endif
} }
case DM_GET_NEXT_CHILD: case DM_GET_NEXT_CHILD:
{ {
return B_ERROR;
#if 0
device_node_info* node;
device_node_info* child;
if (!IS_USER_ADDRESS(buffer)) if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (bufferSize < sizeof(uint32)) if (bufferSize < sizeof(device_node_cookie))
return B_BAD_VALUE; return B_BAD_VALUE;
uint32 cookie; device_node_cookie cookie;
if (user_memcpy(&cookie, buffer, sizeof(uint32)) < B_OK) if (user_memcpy(&cookie, buffer, sizeof(device_node_cookie)) < B_OK)
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
mutex_lock(&gNodeLock); device_node* last = (device_node*)cookie;
node = device_manager_find_device(gRootNode, cookie); if (!last->Parent())
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)
return B_ENTRY_NOT_FOUND; 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 // copy back to user space
return user_memcpy(buffer, &cookie, sizeof(uint32)); return user_memcpy(buffer, &cookie, sizeof(device_node_cookie));
#endif
} }
case DM_GET_NEXT_ATTRIBUTE: case DM_GET_NEXT_ATTRIBUTE:
{ {
return B_ERROR; struct device_attr_info attr_info;
#if 0
struct dev_attr attr;
device_node_info* node;
uint32 i = 0;
device_attr_info *attr_info;
if (!IS_USER_ADDRESS(buffer)) if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
if (bufferSize < sizeof(struct dev_attr)) if (bufferSize < sizeof(struct device_attr_info))
return B_BAD_VALUE; 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; return B_BAD_ADDRESS;
mutex_lock(&gNodeLock); device_node* node = (device_node*)attr_info.node_cookie;
node = device_manager_find_device(gRootNode, attr.node_cookie); device_attr* last = (device_attr*)attr_info.cookie;
if (!node) { AttributeList::Iterator iterator = node->Attributes().GetIterator();
mutex_unlock(&gNodeLock); // skip those we already traversed
return B_BAD_VALUE; while (iterator.HasNext() && last != NULL) {
} device_attr* attr = iterator.Next();
for (attr_info = node->attributes; attr.cookie > i && attr_info != NULL; attr_info = attr_info->next) {
i++; if (attr == last)
break;
} }
if (!attr_info) { if (!iterator.HasNext()) {
mutex_unlock(&gNodeLock); attr_info.cookie = 0;
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
} }
attr.cookie++; device_attr* attr = iterator.Next();
attr_info.cookie = (device_node_cookie)attr;
strlcpy(attr.name, attr_info->attr.name, 254); strlcpy(attr_info.name, attr->name, 254);
attr.type = attr_info->attr.type; attr_info.type = attr->type;
switch (attr_info->attr.type) { switch (attr_info.type) {
case B_UINT8_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: 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: 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: 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: 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: /*case B_RAW_TYPE:
if (attr.value.raw.length > attr_info->attr.value.raw.length) if (attr.value.raw.length > attr_info->attr.value.raw.length)
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;*/ break;*/
} }
mutex_unlock(&gNodeLock);
// copy back to user space // copy back to user space
return user_memcpy(buffer, &attr, sizeof(struct dev_attr)); return user_memcpy(buffer, &attr_info, sizeof(struct device_attr_info));
#endif
} }
} }