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

Cache object: acd43ceed918f660aece58b7fba09b4b


[ 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.