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

Cache object: 0025aea3b54bcc9456934457e1b62f17


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