The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/mach/mach_iokit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: mach_iokit.c,v 1.34 2006/03/07 03:32:06 thorpej Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2003 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include "opt_compat_darwin.h"
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: mach_iokit.c,v 1.34 2006/03/07 03:32:06 thorpej Exp $");
   42 
   43 #include <sys/types.h>
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/malloc.h>
   47 #include <sys/signal.h>
   48 #include <sys/mount.h>
   49 #include <sys/proc.h>
   50 #include <sys/ktrace.h>
   51 #include <sys/device.h>
   52 #include <compat/mach/mach_types.h>
   53 #include <compat/mach/mach_message.h>
   54 #include <compat/mach/mach_port.h>
   55 #include <compat/mach/mach_errno.h>
   56 #include <compat/mach/mach_iokit.h>
   57 #include <compat/mach/mach_services.h>
   58 
   59 #ifdef COMPAT_DARWIN
   60 #include <compat/darwin/darwin_iokit.h>
   61 #endif
   62 
   63 struct mach_iokit_devclass mach_ioroot_devclass = {
   64         "(unknwon)",
   65         { NULL },
   66         "<dict ID=\"\"></dict>",
   67         NULL,
   68         NULL,
   69         NULL,
   70         NULL,
   71         NULL,
   72         NULL,
   73         "Root",
   74         NULL,
   75 };
   76 
   77 struct mach_iokit_devclass *mach_iokit_devclasses[] = {
   78         &mach_ioroot_devclass,
   79 #ifdef COMPAT_DARWIN
   80         DARWIN_IOKIT_DEVCLASSES
   81 #endif
   82         NULL,
   83 };
   84 
   85 
   86 static int mach_fill_child_iterator(struct mach_device_iterator *, int, int,
   87     struct mach_iokit_devclass *);
   88 static int mach_fill_parent_iterator(struct mach_device_iterator *, int, int,
   89     struct mach_iokit_devclass *);
   90 
   91 int
   92 mach_io_service_get_matching_services(args)
   93         struct mach_trap_args *args;
   94 {
   95         mach_io_service_get_matching_services_request_t *req = args->smsg;
   96         mach_io_service_get_matching_services_reply_t *rep = args->rmsg;
   97         size_t *msglen = args->rsize;
   98         struct lwp *l = args->l;
   99         struct mach_port *mp;
  100         struct mach_right *mr;
  101         struct mach_iokit_devclass *mid;
  102         struct mach_device_iterator *mdi;
  103         size_t size;
  104         int end_offset;
  105         int i;
  106 
  107         /* Sanity check req_size */
  108         end_offset = req->req_size;
  109         if (MACH_REQMSG_OVERFLOW(args, req->req_string[end_offset]))
  110                 return mach_msg_error(args, EINVAL);
  111 
  112         mp = mach_port_get();
  113         mp->mp_flags |= MACH_MP_INKERNEL;
  114         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  115 
  116         mp->mp_data = NULL;
  117         i = 0;
  118         while ((mid = mach_iokit_devclasses[i++]) != NULL) {
  119                 if (memcmp(req->req_string, mid->mid_string,
  120                     req->req_size) == 0) {
  121                         mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
  122 
  123                         size = sizeof(*mdi)
  124                             + sizeof(struct mach_device_iterator *);
  125                         mdi = malloc(size, M_EMULDATA, M_WAITOK);
  126                         mdi->mdi_devices[0] = mid;
  127                         mdi->mdi_devices[1] = NULL;
  128                         mdi->mdi_current = 0;
  129 
  130                         mp->mp_data = mdi;
  131                         break;
  132                 }
  133         }
  134 
  135         if (mp->mp_data == NULL)
  136                 return mach_iokit_error(args, MACH_IOKIT_ENOENT);
  137 
  138         *msglen = sizeof(*rep);
  139         mach_set_header(rep, req, *msglen);
  140         mach_add_port_desc(rep, mr->mr_name);
  141         mach_set_trailer(rep, *msglen);
  142 
  143         return 0;
  144 }
  145 
  146 int
  147 mach_io_iterator_next(args)
  148         struct mach_trap_args *args;
  149 {
  150         mach_io_iterator_next_request_t *req = args->smsg;
  151         mach_io_iterator_next_reply_t *rep = args->rmsg;
  152         size_t *msglen = args->rsize;
  153         struct lwp *l = args->l;
  154         struct mach_port *mp;
  155         struct mach_right *mr;
  156         struct mach_device_iterator *mdi;
  157         mach_port_t mn;
  158 
  159         mn = req->req_msgh.msgh_remote_port;
  160         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  161                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  162 
  163         if (mr->mr_port->mp_datatype != MACH_MP_DEVICE_ITERATOR)
  164                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  165 
  166         mdi = mr->mr_port->mp_data;
  167 
  168         /* Is there something coming next? */
  169         if (mdi->mdi_devices[mdi->mdi_current] == NULL)
  170                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  171 
  172         mp = mach_port_get();
  173         mp->mp_flags |= MACH_MP_INKERNEL;
  174         mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
  175         mp->mp_data = mdi->mdi_devices[mdi->mdi_current++];
  176 
  177         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  178 
  179         *msglen = sizeof(*rep);
  180         mach_set_header(rep, req, *msglen);
  181         mach_add_port_desc(rep, mr->mr_name);
  182         mach_set_trailer(rep, *msglen);
  183 
  184         return 0;
  185 }
  186 
  187 int
  188 mach_io_service_open(args)
  189         struct mach_trap_args *args;
  190 {
  191         mach_io_service_open_request_t *req = args->smsg;
  192         mach_io_service_open_reply_t *rep = args->rmsg;
  193         size_t *msglen = args->rsize;
  194         struct lwp *l = args->l;
  195         struct mach_port *mp;
  196         struct mach_right *mr;
  197         mach_port_t mn;
  198 
  199         mn = req->req_msgh.msgh_remote_port;
  200         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  201                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  202 
  203         mp = mach_port_get();
  204         mp->mp_flags |= MACH_MP_INKERNEL;
  205         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  206                 mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
  207                 mp->mp_data = mr->mr_port->mp_data;
  208         }
  209         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  210 
  211         *msglen = sizeof(*rep);
  212         mach_set_header(rep, req, *msglen);
  213         mach_add_port_desc(rep, mr->mr_name);
  214         mach_set_trailer(rep, *msglen);
  215 
  216         return 0;
  217 }
  218 
  219 int
  220 mach_io_connect_method_scalari_scalaro(args)
  221         struct mach_trap_args *args;
  222 {
  223         mach_io_connect_method_scalari_scalaro_request_t *req = args->smsg;
  224         struct lwp *l = args->l;
  225         mach_port_t mn;
  226         struct mach_right *mr;
  227         struct mach_iokit_devclass *mid;
  228         int end_offset, outcount;
  229 
  230         /*
  231          * Sanity check req_incount
  232          * the +1 gives us the last field of the message, req_outcount
  233          */
  234         end_offset = req->req_incount +
  235                      (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
  236         if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
  237                 return mach_msg_error(args, EINVAL);
  238 
  239         /* Sanity check req->req_outcount */
  240         outcount = req->req_in[req->req_incount];
  241         if (outcount > 16)
  242                 return mach_msg_error(args, EINVAL);
  243 
  244         mn = req->req_msgh.msgh_remote_port;
  245         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  246                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  247 
  248         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  249                 mid = mr->mr_port->mp_data;
  250                 if (mid->mid_connect_method_scalari_scalaro == NULL)
  251                         printf("no connect_method_scalari_scalaro method "
  252                             "for darwin_iokit_class %s\n", mid->mid_name);
  253                 else
  254                         return (mid->mid_connect_method_scalari_scalaro)(args);
  255         }
  256 
  257         return mach_iokit_error(args, MACH_IOKIT_ENODEV);
  258 }
  259 
  260 int
  261 mach_io_connect_get_service(args)
  262         struct mach_trap_args *args;
  263 {
  264         mach_io_connect_get_service_request_t *req = args->smsg;
  265         mach_io_connect_get_service_reply_t *rep = args->rmsg;
  266         size_t *msglen = args->rsize;
  267         struct lwp *l = args->l;
  268         struct mach_port *mp;
  269         struct mach_right *mr;
  270         mach_port_t mn;
  271 
  272         mn = req->req_msgh.msgh_remote_port;
  273         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  274                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  275 
  276         mp = mach_port_get();
  277         mp->mp_flags |= MACH_MP_INKERNEL;
  278         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  279                 mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
  280                 mp->mp_data = mr->mr_port->mp_data;
  281         }
  282         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  283 
  284         /*
  285          * XXX Bump the refcount to workaround an emulation bug
  286          * that causes Windowserver to release the port too early.
  287          */
  288         mr->mr_refcount++;
  289 
  290         *msglen = sizeof(*rep);
  291         mach_set_header(rep, req, *msglen);
  292         mach_add_port_desc(rep, mr->mr_name);
  293         mach_set_trailer(rep, *msglen);
  294 
  295         return 0;
  296 }
  297 
  298 int
  299 mach_io_registry_entry_create_iterator(args)
  300         struct mach_trap_args *args;
  301 {
  302         mach_io_registry_entry_create_iterator_request_t *req = args->smsg;
  303         mach_io_registry_entry_create_iterator_reply_t *rep = args->rmsg;
  304         size_t *msglen = args->rsize;
  305         struct lwp *l = args->l;
  306         struct mach_port *mp;
  307         mach_port_t mn;
  308         struct mach_right *mr;
  309         struct mach_iokit_devclass *mid;
  310         struct mach_device_iterator *mdi;
  311         struct mach_iokit_devclass **midp;
  312         int maxdev, index;
  313         size_t size;
  314         int end_offset;
  315 
  316         /*
  317          * req_planeoffset is not used.
  318          * Sanity check req_planecount
  319          */
  320         end_offset = req->req_planecount +
  321                      (sizeof(req->req_options) / sizeof(req->req_plane[0]));
  322         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
  323                 return mach_msg_error(args, EINVAL);
  324 
  325         mn = req->req_msgh.msgh_remote_port;
  326         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  327                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  328         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  329                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  330         mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
  331 
  332         mp = mach_port_get();
  333         mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
  334         mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
  335 
  336         maxdev = sizeof(mach_iokit_devclasses);
  337         size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
  338         mdi = malloc(size, M_EMULDATA, M_WAITOK);
  339         mp->mp_data = mdi;
  340 
  341         if (req->req_options & MACH_IOKIT_PARENT_ITERATOR)
  342                 index = mach_fill_parent_iterator(mdi, maxdev, 0, mid);
  343         else
  344                 index = mach_fill_child_iterator(mdi, maxdev, 0, mid);
  345 
  346         /* XXX This is untested */
  347         if (req->req_options & MACH_IOKIT_RECURSIVE_ITERATOR) {
  348                 for (midp = mdi->mdi_devices; *midp != NULL; midp++) {
  349                         if (req->req_options & MACH_IOKIT_PARENT_ITERATOR)
  350                                 index = mach_fill_parent_iterator(mdi,
  351                                     maxdev, index, *midp);
  352                         else
  353                                 index = mach_fill_child_iterator(mdi,
  354                                     maxdev, index, *midp);
  355                 }
  356         }
  357 
  358         mdi->mdi_current = 0;
  359 
  360         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  361 
  362 #ifdef DEBUG_MACH
  363         printf("io_registry_entry_create_iterator\n");
  364 #endif
  365 
  366         *msglen = sizeof(*rep);
  367         mach_set_header(rep, req, *msglen);
  368         mach_add_port_desc(rep, mr->mr_name);
  369         mach_set_trailer(rep, *msglen);
  370 
  371         return 0;
  372 }
  373 
  374 int
  375 mach_io_object_conforms_to(args)
  376         struct mach_trap_args *args;
  377 {
  378         mach_io_object_conforms_to_request_t *req = args->smsg;
  379         mach_io_object_conforms_to_reply_t *rep = args->rmsg;
  380         size_t *msglen = args->rsize;
  381         int end_offset;
  382 
  383         /*
  384          * req_classnameoffset is not used.
  385          * Sanity check req_classnamecount.
  386          */
  387         end_offset = req->req_classnamecount;
  388         if (MACH_REQMSG_OVERFLOW(args, req->req_classname[end_offset]))
  389                 return mach_msg_error(args, EINVAL);
  390 
  391 #ifdef DEBUG_DARWIN
  392         uprintf("Unimplemented mach_io_object_conforms_to\n");
  393 #endif
  394 
  395         *msglen = sizeof(*rep);
  396         mach_set_header(rep, req, *msglen);
  397 
  398         rep->rep_conforms = 1; /* XXX */
  399 
  400         mach_set_trailer(rep, *msglen);
  401 
  402         return 0;
  403 }
  404 
  405 int
  406 mach_io_service_add_interest_notification(args)
  407         struct mach_trap_args *args;
  408 {
  409         mach_io_service_add_interest_notification_request_t *req = args->smsg;
  410         mach_io_service_add_interest_notification_reply_t *rep = args->rmsg;
  411         size_t *msglen = args->rsize;
  412         struct lwp *l = args->l;
  413         struct mach_port *mp;
  414         struct mach_right *mr;
  415         int end_offset, refcount_offset;
  416         int item_size, refitem_size, refcount;
  417 
  418         /*
  419          * req_typeofinterestoffset is not used.
  420          * Sanity checks: first check refcount is not
  421          * outside the message. NB: it is word aligned
  422          */
  423         refcount_offset = (req->req_typeofinterestcount & ~0x3UL) + 4;
  424         if (MACH_REQMSG_OVERFLOW(args,
  425             req->req_typeofinterest[refcount_offset]))
  426                 return mach_msg_error(args, EINVAL);
  427         refcount = req->req_typeofinterest[refcount_offset];
  428 
  429         /*
  430          * Sanity check typeofinterestcount and refcount
  431          */
  432         item_size = sizeof(req->req_typeofinterest[0]);
  433         refitem_size = sizeof(req->req_ref[0]);
  434         end_offset = req->req_typeofinterestcount +
  435                      (sizeof(refcount) / item_size) +
  436                      (refcount * refitem_size / item_size);
  437         if (MACH_REQMSG_OVERFLOW(args, req->req_typeofinterest[end_offset]))
  438                 return mach_msg_error(args, EINVAL);
  439 
  440         mp = mach_port_get();
  441         mp->mp_flags |= MACH_MP_INKERNEL;
  442         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  443 
  444 #ifdef DEBUG_DARWIN
  445         uprintf("Unimplemented mach_io_service_add_interest_notification\n");
  446 #endif
  447         *msglen = sizeof(*rep);
  448         mach_set_header(rep, req, *msglen);
  449         mach_add_port_desc(rep, mr->mr_name);
  450         mach_set_trailer(rep, *msglen);
  451 
  452         return 0;
  453 }
  454 
  455 int
  456 mach_io_connect_set_notification_port(args)
  457         struct mach_trap_args *args;
  458 {
  459         mach_io_connect_set_notification_port_request_t *req = args->smsg;
  460         mach_io_connect_set_notification_port_reply_t *rep = args->rmsg;
  461         struct lwp *l = args->l;
  462         size_t *msglen = args->rsize;
  463         mach_port_t mnn, mn;
  464         struct mach_right *mrn;
  465         struct mach_right *mr;
  466         struct mach_iokit_devclass *mid;
  467 
  468 #ifdef DEBUG_DARWIN
  469         printf("mach_io_connect_set_notification_port\n");
  470 #endif
  471         mnn = req->req_port.name;
  472         if ((mrn = mach_right_check(mnn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  473                 return mach_msg_error(args, EINVAL);
  474 
  475         mn = req->req_msgh.msgh_remote_port;
  476         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  477                 return mach_msg_error(args, EINVAL);
  478 
  479         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  480                 return mach_msg_error(args, EINVAL);
  481 
  482 #ifdef DEBUG_DARWIN
  483         printf("notification on right %p, name %x\n", mrn, mrn->mr_name);
  484 #endif
  485         mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
  486         mid->mid_notify = mrn;
  487 
  488         *msglen = sizeof(*rep);
  489         mach_set_header(rep, req, *msglen);
  490 
  491         rep->rep_retval = 0;
  492 
  493         mach_set_trailer(rep, *msglen);
  494 
  495         return 0;
  496 }
  497 
  498 int
  499 mach_io_registry_get_root_entry(args)
  500         struct mach_trap_args *args;
  501 {
  502         mach_io_registry_get_root_entry_request_t *req = args->smsg;
  503         mach_io_registry_get_root_entry_reply_t *rep = args->rmsg;
  504         size_t *msglen = args->rsize;
  505         struct lwp *l = args->l;
  506         struct mach_port *mp;
  507         struct mach_right *mr;
  508 
  509         mp = mach_port_get();
  510         mp->mp_flags |= MACH_MP_INKERNEL;
  511         mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
  512         mp->mp_data = &mach_ioroot_devclass;
  513 
  514         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  515 
  516         *msglen = sizeof(*rep);
  517         mach_set_header(rep, req, *msglen);
  518         mach_add_port_desc(rep, mr->mr_name);
  519         mach_set_trailer(rep, *msglen);
  520 
  521         return 0;
  522 }
  523 
  524 int
  525 mach_io_registry_entry_get_child_iterator(args)
  526         struct mach_trap_args *args;
  527 {
  528         mach_io_registry_entry_get_child_iterator_request_t *req = args->smsg;
  529         mach_io_registry_entry_get_child_iterator_reply_t *rep = args->rmsg;
  530         size_t *msglen = args->rsize;
  531         struct lwp *l = args->l;
  532         struct mach_port *mp;
  533         struct mach_right *mr;
  534         mach_port_t mn;
  535         struct mach_iokit_devclass *mid;
  536         struct mach_device_iterator *mdi;
  537         int maxdev;
  538         size_t size;
  539         int end_offset;
  540 
  541         /*
  542          * req_planeoffset is not used.
  543          * Sanity check req_planecount.
  544          */
  545         end_offset = req->req_planecount;
  546         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
  547                 return mach_msg_error(args, EINVAL);
  548 
  549         mn = req->req_msgh.msgh_remote_port;
  550         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  551                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  552         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  553                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  554         mid = (struct mach_iokit_devclass *)mr->mr_port->mp_data;
  555 
  556         mp = mach_port_get();
  557         mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
  558         mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
  559 
  560         maxdev = sizeof(mach_iokit_devclasses);
  561         size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
  562         mdi = malloc(size, M_EMULDATA, M_WAITOK);
  563         mp->mp_data = mdi;
  564 
  565         (void)mach_fill_child_iterator(mdi, maxdev, 0, mid);
  566         mdi->mdi_current = 0;
  567 
  568         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
  569 
  570         *msglen = sizeof(*rep);
  571         mach_set_header(rep, req, *msglen);
  572         mach_add_port_desc(rep, mr->mr_name);
  573         mach_set_trailer(rep, *msglen);
  574 
  575         return 0;
  576 }
  577 
  578 int
  579 mach_io_registry_entry_get_name_in_plane(args)
  580         struct mach_trap_args *args;
  581 {
  582         mach_io_registry_entry_get_name_in_plane_request_t *req = args->smsg;
  583         mach_io_registry_entry_get_name_in_plane_reply_t *rep = args->rmsg;
  584         size_t *msglen = args->rsize;
  585         struct lwp *l = args->l;
  586         struct mach_right *mr;
  587         mach_port_t mn;
  588         struct mach_iokit_devclass *mid;
  589         int end_offset;
  590 
  591         /*
  592          * req_planeoffset is not used.
  593          * Sanity check req_planecount.
  594          */
  595         end_offset = req->req_planecount;
  596         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
  597                 return mach_msg_error(args, EINVAL);
  598 
  599         mn = req->req_msgh.msgh_remote_port;
  600         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  601                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  602         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  603                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  604         mid = mr->mr_port->mp_data;
  605 
  606         *msglen = sizeof(*rep);
  607         mach_set_header(rep, req, *msglen);
  608 
  609         rep->rep_namecount = strlen(mid->mid_name);
  610         if (rep->rep_namecount >= 128)
  611                 rep->rep_namecount = 128;
  612         memcpy(&rep->rep_name, mid->mid_name, rep->rep_namecount);
  613 
  614         mach_set_trailer(rep, *msglen);
  615 
  616         return 0;
  617 }
  618 
  619 int
  620 mach_io_object_get_class(args)
  621         struct mach_trap_args *args;
  622 {
  623         mach_io_object_get_class_request_t *req = args->smsg;
  624         mach_io_object_get_class_reply_t *rep = args->rmsg;
  625         size_t *msglen = args->rsize;
  626         char classname[] = "unknownClass";
  627 
  628         *msglen = sizeof(*rep);
  629         mach_set_header(rep, req, *msglen);
  630 
  631         /* XXX Just return a dummy name for now */
  632         rep->rep_namecount = strlen(classname);
  633         if (rep->rep_namecount >= 128)
  634                 rep->rep_namecount = 128;
  635         memcpy(&rep->rep_name, classname, rep->rep_namecount);
  636 
  637         mach_set_trailer(rep, *msglen);
  638 
  639         return 0;
  640 }
  641 
  642 int
  643 mach_io_registry_entry_get_location_in_plane(args)
  644         struct mach_trap_args *args;
  645 {
  646         mach_io_registry_entry_get_location_in_plane_request_t *req =
  647             args->smsg;
  648         mach_io_registry_entry_get_location_in_plane_reply_t *rep = args->rmsg;
  649         size_t *msglen = args->rsize;
  650         char location[] = "";
  651         int end_offset;
  652 
  653         /*
  654          * req_nameoffset is not used.
  655          * Sanity check req_namecount.
  656          */
  657         end_offset = req->req_namecount;
  658         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
  659                 return mach_msg_error(args, EINVAL);
  660 
  661         *msglen = sizeof(*rep);
  662         mach_set_header(rep, req, *msglen);
  663 
  664         /* XXX Just return a dummy name for now */
  665         rep->rep_locationcount = sizeof(location);
  666         memcpy(&rep->rep_location, location, sizeof(location));
  667 
  668         mach_set_trailer(rep, *msglen);
  669 
  670         return 0;
  671 }
  672 
  673 int
  674 mach_io_registry_entry_get_properties(args)
  675         struct mach_trap_args *args;
  676 {
  677         mach_io_registry_entry_get_properties_request_t *req = args->smsg;
  678         mach_io_registry_entry_get_properties_reply_t *rep = args->rmsg;
  679         size_t *msglen = args->rsize;
  680         struct lwp *l = args->l;
  681         int error;
  682         void *uaddr;
  683         size_t size;
  684         mach_port_t mn;
  685         struct mach_right *mr;
  686         struct mach_iokit_devclass *mid;
  687 
  688         mn = req->req_msgh.msgh_remote_port;
  689         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  690                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  691 
  692         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  693                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  694 
  695         mid = mr->mr_port->mp_data;
  696         if (mid->mid_properties == NULL)
  697                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  698         size = strlen(mid->mid_properties) + 1; /* Include trailing zero */
  699 
  700         if ((error = mach_ool_copyout(l,
  701             mid->mid_properties, &uaddr, size, MACH_OOL_TRACE)) != 0) {
  702 #ifdef DEBUG_MACH
  703                 printf("pid %d.%d: copyout iokit properties failed\n",
  704                     l->l_proc->p_pid, l->l_lid);
  705 #endif
  706         }
  707 
  708         *msglen = sizeof(*rep);
  709         mach_set_header(rep, req, *msglen);
  710         mach_add_ool_desc(rep, uaddr, size);
  711 
  712         rep->rep_count = size;
  713 
  714         mach_set_trailer(rep, *msglen);
  715 
  716         return 0;
  717 }
  718 
  719 int
  720 mach_io_registry_entry_get_property(args)
  721         struct mach_trap_args *args;
  722 {
  723         mach_io_registry_entry_get_property_request_t *req = args->smsg;
  724         mach_io_registry_entry_get_property_reply_t *rep = args->rmsg;
  725         size_t *msglen = args->rsize;
  726         struct lwp *l = args->l;
  727         int error;
  728         void *uaddr;
  729         size_t size;
  730         mach_port_t mn;
  731         struct mach_right *mr;
  732         struct mach_iokit_devclass *mid;
  733         struct mach_iokit_property *mip;
  734         int end_offset;
  735 
  736         /*
  737          * req_property_nameoffset is not used.
  738          * Sanity check req_property_namecount.
  739          */
  740         end_offset = req->req_property_namecount;
  741         if (MACH_REQMSG_OVERFLOW(args, req->req_property_name[end_offset]))
  742                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  743 
  744         /* Find the port */
  745         mn = req->req_msgh.msgh_remote_port;
  746         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  747                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  748 
  749         /* Find the devclass information */
  750         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
  751                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  752 
  753         mid = mr->mr_port->mp_data;
  754         if (mid->mid_properties_array == NULL)
  755                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  756 
  757         /* Lookup the property name */
  758         for (mip = mid->mid_properties_array; mip->mip_name; mip++)
  759                 if (memcmp(mip->mip_name, req->req_property_name,
  760                     req->req_property_namecount) == 0)
  761                         break;
  762 
  763         if (mip->mip_value == NULL)
  764                 return mach_iokit_error(args, MACH_IOKIT_ENOENT);
  765         size = strlen(mip->mip_value) + 1; /* Include trailing zero */
  766 
  767         /* And copyout its associated value */
  768         if ((error = mach_ool_copyout(l,
  769             mip->mip_value, &uaddr, size, MACH_OOL_TRACE)) != 0) {
  770 #ifdef DEBUG_MACH
  771                 printf("pid %d.%d: copyout iokit property failed\n",
  772                     l->l_proc->p_pid, l->l_lid);
  773 #endif
  774         }
  775 
  776         *msglen = sizeof(*rep);
  777         mach_set_header(rep, req, *msglen);
  778         mach_add_ool_desc(rep, uaddr, size);
  779 
  780         rep->rep_properties_count = size;
  781 
  782         mach_set_trailer(rep, *msglen);
  783 
  784         return 0;
  785 }
  786 
  787 int
  788 mach_io_registry_entry_get_path(args)
  789         struct mach_trap_args *args;
  790 {
  791         mach_io_registry_entry_get_path_request_t *req = args->smsg;
  792         mach_io_registry_entry_get_path_reply_t *rep = args->rmsg;
  793         size_t *msglen = args->rsize;
  794         char location[] = ":/GossamerPE/pci@80000000/AppleGracklePCI/"
  795             "ATY,264LT-G@11/.Display_Video_ATI_mach64-01018002/"
  796             "display0/AppleBacklightDisplay";
  797         char *cp;
  798         size_t len, plen;
  799         int end_offset;
  800 
  801         /*
  802          * req_offset is not used.
  803          * Sanity check req_count.
  804          */
  805         end_offset = req->req_count;
  806         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
  807                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  808 
  809         /* XXX Just return a dummy name for now */
  810         len = req->req_count + strlen(location) - 1;
  811 
  812         /* Sanity check for len */
  813         if (len > 512)
  814                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  815         plen = (len & ~0x3UL) + 4;      /* Round to an int */
  816 
  817         *msglen = sizeof(*rep) + (plen - 512);
  818         mach_set_header(rep, req, *msglen);
  819 
  820         rep->rep_retval = 0;
  821         rep->rep_count = len;
  822 
  823         cp = &rep->rep_path[0];
  824         memcpy(cp, &req->req_plane, req->req_count);
  825         cp += (req->req_count - 1);     /* overwrite trailing \0 */
  826         memcpy(cp, location, strlen(location));
  827         cp += strlen(location);
  828         *cp = '\0';
  829 
  830         mach_set_trailer(rep, *msglen);
  831 
  832         return 0;
  833 }
  834 
  835 int
  836 mach_io_connect_map_memory(args)
  837         struct mach_trap_args *args;
  838 {
  839         mach_io_connect_map_memory_request_t *req = args->smsg;
  840         struct lwp *l = args->l;
  841         mach_port_t mn;
  842         struct mach_right *mr;
  843         struct mach_iokit_devclass *mid;
  844 
  845         mn = req->req_msgh.msgh_remote_port;
  846         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  847                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  848 
  849         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  850                 mid = mr->mr_port->mp_data;
  851                 if (mid->mid_connect_map_memory == NULL)
  852                         printf("no connect_map_memory method "
  853                             "for darwin_iokit_class %s\n", mid->mid_name);
  854                 else
  855                         return (mid->mid_connect_map_memory)(args);
  856         }
  857 
  858         return mach_iokit_error(args, MACH_IOKIT_ENODEV);
  859 }
  860 
  861 int
  862 mach_io_iterator_reset(args)
  863         struct mach_trap_args *args;
  864 {
  865         mach_io_iterator_reset_request_t *req = args->smsg;
  866         mach_io_iterator_reset_reply_t *rep = args->rmsg;
  867         size_t *msglen = args->rsize;
  868         struct lwp *l = args->l;
  869         mach_port_t mn;
  870         struct mach_right *mr;
  871         struct mach_device_iterator *mdi;
  872 
  873         mn = req->req_msgh.msgh_remote_port;
  874         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  875                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  876 
  877         if (mr->mr_port->mp_datatype != MACH_MP_DEVICE_ITERATOR)
  878                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
  879 
  880         mdi = mr->mr_port->mp_data;
  881         mdi->mdi_current = 0;
  882 
  883         *msglen = sizeof(*rep);
  884         mach_set_header(rep, req, *msglen);
  885 
  886         rep->rep_retval = 0;
  887 
  888         mach_set_trailer(rep, *msglen);
  889 
  890         return 0;
  891 }
  892 
  893 int
  894 mach_io_connect_method_scalari_structo(args)
  895         struct mach_trap_args *args;
  896 {
  897         mach_io_connect_method_scalari_structo_request_t *req = args->smsg;
  898         struct lwp *l = args->l;
  899         mach_port_t mn;
  900         struct mach_right *mr;
  901         struct mach_iokit_devclass *mid;
  902         int end_offset;
  903 
  904         /* Sanity check req_incount */
  905         end_offset = req->req_incount +
  906                      (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
  907         if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
  908                 return mach_msg_error(args, EINVAL);
  909 
  910         /* Sanity check req_outcount */
  911         if (req->req_outcount > 4096)
  912                 return mach_msg_error(args, EINVAL);
  913 
  914         mn = req->req_msgh.msgh_remote_port;
  915         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  916                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  917 
  918         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  919                 mid = mr->mr_port->mp_data;
  920                 if (mid->mid_connect_method_scalari_structo == NULL)
  921                         printf("no connect_method_scalari_structo method "
  922                             "for darwin_iokit_class %s\n", mid->mid_name);
  923                 else
  924                         return (mid->mid_connect_method_scalari_structo)(args);
  925         }
  926 
  927         return mach_iokit_error(args, MACH_IOKIT_ENODEV);
  928 }
  929 
  930 int
  931 mach_io_connect_method_structi_structo(args)
  932         struct mach_trap_args *args;
  933 {
  934         mach_io_connect_method_structi_structo_request_t *req = args->smsg;
  935         struct lwp *l = args->l;
  936         mach_port_t mn;
  937         struct mach_right *mr;
  938         struct mach_iokit_devclass *mid;
  939         int end_offset;
  940         int outcount;
  941 
  942         /* Sanity check req_incount */
  943         end_offset = req->req_incount +
  944                      (sizeof(req->req_outcount) / sizeof(req->req_in[0]));
  945         if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
  946                 return mach_msg_error(args, EINVAL);
  947 
  948         /* Sanity check outcount. It is word aligned */
  949         outcount = req->req_in[(req->req_incount & ~0x3UL) + 4];
  950         if (outcount > 4096)
  951                 return mach_msg_error(args, EINVAL);
  952 
  953         mn = req->req_msgh.msgh_remote_port;
  954         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  955                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
  956 
  957         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
  958                 mid = mr->mr_port->mp_data;
  959                 if (mid->mid_connect_method_structi_structo == NULL)
  960                         printf("no connect_method_structi_structo method "
  961                             "for darwin_iokit_class %s\n", mid->mid_name);
  962                 else
  963                         return (mid->mid_connect_method_structi_structo)(args);
  964         }
  965 
  966         return mach_iokit_error(args, MACH_IOKIT_ENODEV);
  967 }
  968 
  969 int
  970 mach_io_connect_set_properties(args)
  971         struct mach_trap_args *args;
  972 {
  973         mach_io_connect_set_properties_request_t *req = args->smsg;
  974         mach_io_connect_set_properties_reply_t *rep = args->rmsg;
  975         size_t *msglen = args->rsize;
  976 
  977 #ifdef DEBUG_MACH
  978         uprintf("Unimplemented mach_io_connect_set_properties\n");
  979 #endif
  980 
  981         *msglen = sizeof(*rep);
  982         mach_set_header(rep, req, *msglen);
  983 
  984         mach_set_trailer(rep, *msglen);
  985 
  986         return 0;
  987 }
  988 
  989 int
  990 mach_io_service_close(args)
  991         struct mach_trap_args *args;
  992 {
  993         mach_io_service_close_request_t *req = args->smsg;
  994         mach_io_service_close_reply_t *rep = args->rmsg;
  995         size_t *msglen = args->rsize;
  996 
  997 #ifdef DEBUG_MACH
  998         uprintf("Unimplemented mach_io_service_close\n");
  999 #endif
 1000 
 1001         *msglen = sizeof(*rep);
 1002         mach_set_header(rep, req, *msglen);
 1003 
 1004         rep->rep_retval = 0;
 1005 
 1006         mach_set_trailer(rep, *msglen);
 1007 
 1008         return 0;
 1009 }
 1010 
 1011 int
 1012 mach_io_connect_add_client(args)
 1013         struct mach_trap_args *args;
 1014 {
 1015         mach_io_connect_add_client_request_t *req = args->smsg;
 1016         mach_io_connect_add_client_reply_t *rep = args->rmsg;
 1017         size_t *msglen = args->rsize;
 1018 
 1019 #ifdef DEBUG_MACH
 1020         uprintf("Unimplemented mach_io_connect_add_client\n");
 1021 #endif
 1022 
 1023         *msglen = sizeof(*rep);
 1024         mach_set_header(rep, req, *msglen);
 1025 
 1026         rep->rep_retval = 0;
 1027 
 1028         mach_set_trailer(rep, *msglen);
 1029 
 1030         return 0;
 1031 }
 1032 
 1033 int
 1034 mach_io_connect_method_scalari_structi(args)
 1035         struct mach_trap_args *args;
 1036 {
 1037         mach_io_connect_method_scalari_structi_request_t *req = args->smsg;
 1038         struct lwp *l = args->l;
 1039         mach_port_t mn;
 1040         struct mach_right *mr;
 1041         struct mach_iokit_devclass *mid;
 1042         int end_offset;
 1043         int scalar_size, struct_size, instructcount;
 1044 
 1045         /* Sanity check req_incount and get instructcount */
 1046         if (MACH_REQMSG_OVERFLOW(args, req->req_in[req->req_incount]))
 1047                 return mach_msg_error(args, EINVAL);
 1048         instructcount = req->req_in[req->req_incount];
 1049 
 1050         /* Sanity check instructcount */
 1051         scalar_size = sizeof(req->req_in[0]);
 1052         struct_size = sizeof(req->req_instruct[0]);
 1053         end_offset = req->req_incount +
 1054                      (sizeof(instructcount) / scalar_size) +
 1055                      (instructcount * struct_size / scalar_size);
 1056         if (MACH_REQMSG_OVERFLOW(args, req->req_in[end_offset]))
 1057                 return mach_msg_error(args, EINVAL);
 1058 
 1059         mn = req->req_msgh.msgh_remote_port;
 1060         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
 1061                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
 1062 
 1063         if (mr->mr_port->mp_datatype == MACH_MP_IOKIT_DEVCLASS) {
 1064                 mid = mr->mr_port->mp_data;
 1065                 if (mid->mid_connect_method_scalari_structi == NULL)
 1066                         printf("no connect_method_scalari_structi method "
 1067                             "for darwin_iokit_class %s\n", mid->mid_name);
 1068                 else
 1069                         return (mid->mid_connect_method_scalari_structi)(args);
 1070         }
 1071 
 1072         return mach_iokit_error(args, MACH_IOKIT_ENODEV);
 1073 }
 1074 
 1075 int
 1076 mach_io_registry_entry_from_path(args)
 1077         struct mach_trap_args *args;
 1078 {
 1079         mach_io_registry_entry_from_path_request_t *req = args->smsg;
 1080         mach_io_registry_entry_from_path_reply_t *rep = args->rmsg;
 1081         size_t *msglen = args->rsize;
 1082         struct lwp *l = args->l;
 1083         struct mach_port *mp;
 1084         struct mach_right *mr;
 1085         struct mach_iokit_devclass *mid;
 1086         int i, len;
 1087         int end_offset;
 1088 
 1089         /*
 1090          * req_pathoffset is not used.
 1091          * Sanity check req_pathcount.
 1092          */
 1093         end_offset = req->req_pathcount;
 1094         if (MACH_REQMSG_OVERFLOW(args, req->req_path[end_offset]))
 1095                 return mach_msg_error(args, EINVAL);
 1096 
 1097 #ifdef DEBUG_MACH
 1098         printf("mach_io_registry_entry_from_path: path = %s\n", req->req_path);
 1099 #endif
 1100 
 1101         mp = mach_port_get();
 1102         mp->mp_flags |= MACH_MP_INKERNEL;
 1103         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
 1104 
 1105         i = 0;
 1106         while ((mid = mach_iokit_devclasses[i++]) != NULL) {
 1107                 len = strlen(mid->mid_name);
 1108 #ifdef DEBUG_MACH
 1109                 printf("trying \"%s\" vs \"%s\"\n",
 1110                     &req->req_path[req->req_pathcount - 1 - len],
 1111                     mid->mid_name);
 1112 #endif
 1113                 if (memcmp(&req->req_path[req->req_pathcount - 1 - len],
 1114                     mid->mid_name, len) == 0) {
 1115                         mp->mp_datatype = MACH_MP_IOKIT_DEVCLASS;
 1116                         mp->mp_data = mid;
 1117                         break;
 1118                 }
 1119         }
 1120 
 1121         *msglen = sizeof(*rep);
 1122         mach_set_header(rep, req, *msglen);
 1123         mach_add_port_desc(rep, mr->mr_name);
 1124         mach_set_trailer(rep, *msglen);
 1125 
 1126         return 0;
 1127 }
 1128 
 1129 int
 1130 mach_io_registry_entry_get_parent_iterator(args)
 1131         struct mach_trap_args *args;
 1132 {
 1133         mach_io_registry_entry_get_parent_iterator_request_t *req = args->smsg;
 1134         mach_io_registry_entry_get_parent_iterator_reply_t *rep = args->rmsg;
 1135         size_t *msglen = args->rsize;
 1136         struct lwp *l = args->l;
 1137         struct mach_port *mp;
 1138         struct mach_right *mr;
 1139         struct mach_iokit_devclass *mid;
 1140         struct mach_device_iterator *mdi;
 1141         mach_port_t mn;
 1142         int maxdev;
 1143         size_t size;
 1144         int end_offset;
 1145 
 1146         /*
 1147          * req_offset is unused
 1148          * Sanity check req_count
 1149          */
 1150         end_offset = req->req_count;
 1151         if (MACH_REQMSG_OVERFLOW(args, req->req_plane[end_offset]))
 1152                 return mach_msg_error(args, EINVAL);
 1153 
 1154 #ifdef DEBUG_MACH
 1155         printf("mach_io_registry_entry_get_parent_iterator: plane = %s\n",
 1156             req->req_plane);
 1157 #endif
 1158 
 1159         mn = req->req_msgh.msgh_remote_port;
 1160         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
 1161                 return mach_iokit_error(args, MACH_IOKIT_EPERM);
 1162 
 1163         if (mr->mr_port->mp_datatype != MACH_MP_IOKIT_DEVCLASS)
 1164                 return mach_iokit_error(args, MACH_IOKIT_EINVAL);
 1165         mid = mr->mr_port->mp_data;
 1166 
 1167         mp = mach_port_get();
 1168         mp->mp_flags |= (MACH_MP_INKERNEL | MACH_MP_DATA_ALLOCATED);
 1169         mp->mp_datatype = MACH_MP_DEVICE_ITERATOR;
 1170 
 1171         maxdev = sizeof(mach_iokit_devclasses);
 1172         size = sizeof(*mdi) + (maxdev * sizeof(struct mach_iokit_devclass *));
 1173         mdi = malloc(size, M_EMULDATA, M_WAITOK);
 1174         mp->mp_data = mdi;
 1175 
 1176         (void)mach_fill_parent_iterator(mdi, maxdev, 0, mid);
 1177         mdi->mdi_current = 0;
 1178 
 1179         mr = mach_right_get(mp, l, MACH_PORT_TYPE_SEND, 0);
 1180 
 1181         *msglen = sizeof(*rep);
 1182         mach_set_header(rep, req, *msglen);
 1183         mach_add_port_desc(rep, mr->mr_name);
 1184         mach_set_trailer(rep, *msglen);
 1185 
 1186         return 0;
 1187 }
 1188 
 1189 void
 1190 mach_iokit_cleanup_notify(mr)
 1191         struct mach_right *mr;
 1192 {
 1193         int i;
 1194         struct mach_iokit_devclass *mid;
 1195 
 1196         i = 0;
 1197         while ((mid = mach_iokit_devclasses[i++]) != NULL)
 1198                 if (mid->mid_notify == mr)
 1199                         mid->mid_notify = NULL;
 1200 
 1201         return;
 1202 }
 1203 
 1204 static int
 1205 mach_fill_child_iterator(mdi, size, index, mid)
 1206         struct mach_device_iterator *mdi;
 1207         int size;
 1208         int index;
 1209         struct mach_iokit_devclass *mid;
 1210 {
 1211         struct mach_iokit_devclass **midp;
 1212         struct mach_iokit_devclass **midq;
 1213 
 1214         for (midp = mach_iokit_devclasses; *midp != NULL; midp++) {
 1215                 for (midq = (*midp)->mid_parent; *midq != NULL; midq++) {
 1216                         if (*midq == mid) {
 1217                                 mdi->mdi_devices[index++] = *midp;
 1218                                 break;
 1219                         }
 1220                 }
 1221 #ifdef DIAGNOSTIC
 1222                 if (index >= size) {
 1223                         printf("mach_device_iterator overflow\n");
 1224                         break;
 1225                 }
 1226 #endif
 1227         }
 1228         mdi->mdi_devices[index] = NULL;
 1229 
 1230         return index;
 1231 }
 1232 
 1233 static int
 1234 mach_fill_parent_iterator(mdi, size, index, mid)
 1235         struct mach_device_iterator *mdi;
 1236         int size;
 1237         int index;
 1238         struct mach_iokit_devclass *mid;
 1239 {
 1240         struct mach_iokit_devclass **midp;
 1241 
 1242         for (midp = mid->mid_parent; *midp != NULL; midp++) {
 1243                 mdi->mdi_devices[index++] = *midp;
 1244 #ifdef DIAGNOSTIC
 1245                 if (index >= size) {
 1246                         printf("mach_device_iterator overflow\n");
 1247                         break;
 1248                 }
 1249 #endif
 1250         }
 1251         mdi->mdi_devices[index] = NULL;
 1252 
 1253         return index;
 1254 }

Cache object: f6925a0e3836493148de051e64a9273a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.