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:
manu 2003-02-09 22:13:46 +00:00
parent 82ece76c41
commit 80a30f1a31
6 changed files with 137 additions and 22 deletions

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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);

View File

@ -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_ */

View File

@ -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;

View File

@ -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);