A first attempt at providing access to our device tree through the IOKit.
Darwin's ioreg is able to display the tree.
This commit is contained in:
parent
82ece76c41
commit
80a30f1a31
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_errno.c,v 1.11 2002/12/27 19:57:47 manu Exp $ */
|
||||
/* $NetBSD: mach_errno.c,v 1.12 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_errno.c,v 1.11 2002/12/27 19:57:47 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_errno.c,v 1.12 2003/02/09 22:13:46 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -162,3 +162,25 @@ mach_msg_error(args, error)
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mach_iokit_error(args, error)
|
||||
struct mach_trap_args *args;
|
||||
int error;
|
||||
{
|
||||
mach_msg_header_t *req = args->smsg;
|
||||
mach_error_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
rep->rep_msgh.msgh_size = sizeof(*rep) - sizeof(rep->rep_trailer);
|
||||
rep->rep_msgh.msgh_local_port = req->msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->msgh_id + 100;
|
||||
rep->rep_retval = error;
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_errno.h,v 1.6 2002/12/24 15:53:46 manu Exp $ */
|
||||
/* $NetBSD: mach_errno.h,v 1.7 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
|
@ -92,6 +92,12 @@ extern int native_to_mach_errno[];
|
|||
#define MACH_KERN_NOT_WAITING 48
|
||||
#define MACH_KERN_OPERATION_TIMED_OUT 49
|
||||
|
||||
/* IOKit errors */
|
||||
#define MACH_IOKIT_ENOMEM 0xe00002bd
|
||||
#define MACH_IOKIT_ENODEV 0xe00002c0
|
||||
#define MACH_IOKIT_EAGAIN 0xe00002be
|
||||
#define MACH_IOKIT_EPERM 0xe00002c1
|
||||
#define MACH_IOKIT_EINVAL 0xe00002c2
|
||||
|
||||
typedef struct {
|
||||
mach_msg_header_t rep_msgh;
|
||||
|
@ -101,5 +107,6 @@ typedef struct {
|
|||
} mach_error_reply_t;
|
||||
|
||||
int mach_msg_error(struct mach_trap_args *, int);
|
||||
int mach_iokit_error(struct mach_trap_args *, int);
|
||||
|
||||
#endif /* _MACH_ERRNO_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_iokit.c,v 1.4 2003/02/07 20:40:37 manu Exp $ */
|
||||
/* $NetBSD: mach_iokit.c,v 1.5 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.4 2003/02/07 20:40:37 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.5 2003/02/09 22:13:46 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -46,11 +46,12 @@ __KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.4 2003/02/07 20:40:37 manu Exp $");
|
|||
#include <sys/signal.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <compat/mach/mach_types.h>
|
||||
#include <compat/mach/mach_message.h>
|
||||
#include <compat/mach/mach_port.h>
|
||||
|
||||
#include <compat/mach/mach_errno.h>
|
||||
#include <compat/mach/mach_iokit.h>
|
||||
|
||||
|
||||
|
@ -94,9 +95,49 @@ mach_io_iterator_next(args)
|
|||
struct lwp *l = args->l;
|
||||
struct mach_port *mp;
|
||||
struct mach_right *mr;
|
||||
struct device *dev;
|
||||
struct mach_device_iterator *mdi;
|
||||
mach_port_t mn;
|
||||
|
||||
mn = req->req_msgh.msgh_remote_port;
|
||||
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EPERM);
|
||||
if (mr->mr_port->mp_datatype != MACH_MP_DEVICE_ITERATOR)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EINVAL);
|
||||
mdi = mr->mr_port->mp_data;
|
||||
|
||||
/* XXX No lock for the device list? */
|
||||
/* Check that mdi->mdi_parent still exists, else give up */
|
||||
TAILQ_FOREACH(dev, &alldevs, dv_list)
|
||||
if (dev == mdi->mdi_parent)
|
||||
break;
|
||||
if (dev == NULL)
|
||||
return mach_iokit_error(args, MACH_IOKIT_ENODEV);
|
||||
|
||||
/* Check that mdi->mdi_current still exists, else reset it */
|
||||
TAILQ_FOREACH(dev, &alldevs, dv_list)
|
||||
if (dev == mdi->mdi_current)
|
||||
break;
|
||||
if (dev == NULL)
|
||||
mdi->mdi_current = TAILQ_FIRST(&alldevs);
|
||||
|
||||
/* And now, find the next child of mdi->mdi_parrent. */
|
||||
do {
|
||||
if (dev->dv_parent == mdi->mdi_parent) {
|
||||
mdi->mdi_current = dev;
|
||||
break;
|
||||
}
|
||||
} while ((dev = TAILQ_NEXT(dev, dv_list)) != NULL);
|
||||
|
||||
if (dev == NULL)
|
||||
return mach_iokit_error(args, MACH_IOKIT_ENODEV);
|
||||
|
||||
mp = mach_port_get();
|
||||
mp->mp_flags |= MACH_MP_INKERNEL;
|
||||
mp->mp_datatype = MACH_MP_DEVICE;
|
||||
mp->mp_data = mdi->mdi_current;
|
||||
mdi->mdi_current = TAILQ_NEXT(mdi->mdi_current, dv_list);
|
||||
|
||||
mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
|
@ -337,6 +378,9 @@ mach_io_registry_get_root_entry(args)
|
|||
|
||||
mp = mach_port_get();
|
||||
mp->mp_flags |= MACH_MP_INKERNEL;
|
||||
mp->mp_datatype = MACH_MP_DEVICE;
|
||||
mp->mp_data = TAILQ_FIRST(&alldevs);
|
||||
|
||||
mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
|
@ -364,9 +408,24 @@ mach_io_registry_entry_get_child_iterator(args)
|
|||
struct lwp *l = args->l;
|
||||
struct mach_port *mp;
|
||||
struct mach_right *mr;
|
||||
mach_port_t mn;
|
||||
struct mach_device_iterator *mdi;
|
||||
|
||||
mn = req->req_msgh.msgh_remote_port;
|
||||
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EPERM);
|
||||
if (mr->mr_port->mp_datatype != MACH_MP_DEVICE)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EINVAL);
|
||||
|
||||
mp = mach_port_get();
|
||||
mp->mp_flags |= MACH_MP_INKERNEL;
|
||||
mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
|
||||
mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
|
||||
|
||||
mdi = malloc(sizeof(*mdi), M_EMULDATA, M_WAITOK);
|
||||
mdi->mdi_parent = mr->mr_port->mp_data;
|
||||
mdi->mdi_current = TAILQ_FIRST(&alldevs);
|
||||
mp->mp_data = mdi;
|
||||
|
||||
mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
|
@ -391,7 +450,17 @@ mach_io_registry_entry_get_name_in_plane(args)
|
|||
mach_io_registry_entry_get_name_in_plane_request_t *req = args->smsg;
|
||||
mach_io_registry_entry_get_name_in_plane_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
char foobarbuz[] = "foobarbuz";
|
||||
struct lwp *l = args->l;
|
||||
struct mach_right *mr;
|
||||
mach_port_t mn;
|
||||
struct device *dev;
|
||||
|
||||
mn = req->req_msgh.msgh_remote_port;
|
||||
if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EPERM);
|
||||
if (mr->mr_port->mp_datatype != MACH_MP_DEVICE)
|
||||
return mach_iokit_error(args, MACH_IOKIT_EINVAL);
|
||||
dev = mr->mr_port->mp_data;
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
|
@ -399,8 +468,8 @@ mach_io_registry_entry_get_name_in_plane(args)
|
|||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
/* XXX Just return a dummy name for now */
|
||||
rep->rep_namecount = sizeof(foobarbuz);
|
||||
memcpy(&rep->rep_name, foobarbuz, sizeof(foobarbuz));
|
||||
rep->rep_namecount = sizeof(dev->dv_xname);
|
||||
memcpy(&rep->rep_name, dev->dv_xname, sizeof(dev->dv_xname));
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
@ -414,7 +483,7 @@ mach_io_object_get_class(args)
|
|||
mach_io_object_get_class_request_t *req = args->smsg;
|
||||
mach_io_object_get_class_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
char foobarbuz[] = "FoobarClass";
|
||||
char classname[] = "unknownClass";
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
|
@ -422,8 +491,8 @@ mach_io_object_get_class(args)
|
|||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
/* XXX Just return a dummy name for now */
|
||||
rep->rep_namecount = sizeof(foobarbuz);
|
||||
memcpy(&rep->rep_name, foobarbuz, sizeof(foobarbuz));
|
||||
rep->rep_namecount = sizeof(classname);
|
||||
memcpy(&rep->rep_name, classname, sizeof(classname));
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
@ -438,7 +507,7 @@ mach_io_registry_entry_get_location_in_plane(args)
|
|||
args->smsg;
|
||||
mach_io_registry_entry_get_location_in_plane_reply_t *rep = args->rmsg;
|
||||
size_t *msglen = args->rsize;
|
||||
char foobarbuz[] = "/";
|
||||
char location[] = "";
|
||||
|
||||
rep->rep_msgh.msgh_bits =
|
||||
MACH_MSGH_REPLY_LOCAL_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE);
|
||||
|
@ -446,8 +515,8 @@ mach_io_registry_entry_get_location_in_plane(args)
|
|||
rep->rep_msgh.msgh_local_port = req->req_msgh.msgh_local_port;
|
||||
rep->rep_msgh.msgh_id = req->req_msgh.msgh_id + 100;
|
||||
/* XXX Just return a dummy name for now */
|
||||
rep->rep_locationcount = sizeof(foobarbuz);
|
||||
memcpy(&rep->rep_location, foobarbuz, sizeof(foobarbuz));
|
||||
rep->rep_locationcount = sizeof(location);
|
||||
memcpy(&rep->rep_location, location, sizeof(location));
|
||||
rep->rep_trailer.msgh_trailer_size = 8;
|
||||
|
||||
*msglen = sizeof(*rep);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_iokit.h,v 1.4 2003/02/07 20:40:37 manu Exp $ */
|
||||
/* $NetBSD: mach_iokit.h,v 1.5 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -321,5 +321,9 @@ int mach_io_registry_entry_get_name_in_plane(struct mach_trap_args *);
|
|||
int mach_io_object_get_class(struct mach_trap_args *);
|
||||
int mach_io_registry_entry_get_location_in_plane(struct mach_trap_args *);
|
||||
|
||||
#endif /* _MACH_IOKIT_H_ */
|
||||
struct mach_device_iterator {
|
||||
struct device *mdi_parent;
|
||||
struct device *mdi_current;
|
||||
};
|
||||
|
||||
#endif /* _MACH_IOKIT_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_port.c,v 1.34 2003/02/05 23:58:10 manu Exp $ */
|
||||
/* $NetBSD: mach_port.c,v 1.35 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
|
@ -39,7 +39,7 @@
|
|||
#include "opt_compat_darwin.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.34 2003/02/05 23:58:10 manu Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.35 2003/02/09 22:13:46 manu Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -445,6 +445,8 @@ mach_port_get(void)
|
|||
mp->mp_recv = NULL;
|
||||
mp->mp_count = 0;
|
||||
mp->mp_flags = 0;
|
||||
mp->mp_datatype = MACH_MP_NONE;
|
||||
mp->mp_data = NULL;
|
||||
TAILQ_INIT(&mp->mp_msglist);
|
||||
lockinit(&mp->mp_msglock, PZERO|PCATCH, "mach_port", 0, 0);
|
||||
|
||||
|
@ -468,6 +470,9 @@ mach_port_put(mp)
|
|||
lockmgr(&mp->mp_msglock, LK_RELEASE, NULL);
|
||||
lockmgr(&mp->mp_msglock, LK_DRAIN, NULL);
|
||||
|
||||
if (mp->mp_flags & MACH_MP_DATA_ALLOCATED)
|
||||
free(mp->mp_data, M_EMULDATA);
|
||||
|
||||
pool_put(&mach_port_pool, mp);
|
||||
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mach_port.h,v 1.19 2003/02/05 23:58:10 manu Exp $ */
|
||||
/* $NetBSD: mach_port.h,v 1.20 2003/02/09 22:13:46 manu Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
|
||||
|
@ -267,11 +267,19 @@ struct mach_port {
|
|||
mach_message) mp_msglist;
|
||||
struct lock mp_msglock; /* Lock for the queue */
|
||||
int mp_refcount; /* Reference count */
|
||||
int mp_flags;
|
||||
int mp_flags; /* Flags, see below */
|
||||
int mp_datatype; /* Type of field mp_data, see below */
|
||||
void *mp_data; /* Data attached to the port */
|
||||
};
|
||||
|
||||
/* mp_flags for struct mach_port */
|
||||
#define MACH_MP_INKERNEL 0x1 /* Receiver is inside the kernel */
|
||||
#define MACH_MP_DATA_ALLOCATED 0x2 /* mp_data was malloc'ed */
|
||||
|
||||
/* mp_datatype for struct mach_port */
|
||||
#define MACH_MP_NONE 0x0 /* No data */
|
||||
#define MACH_MP_DEVICE 0x1 /* struct device */
|
||||
#define MACH_MP_DEVICE_ITERATOR 0x2 /* struct mach_device_iterator */
|
||||
|
||||
void mach_port_init(void);
|
||||
struct mach_port *mach_port_get(void);
|
||||
|
|
Loading…
Reference in New Issue