Annotation of Gnu-Mach/device/ds_routines.c, revision 1.1.1.6

1.1.1.2   root        1: /*
1.1       root        2:  * Mach Operating System
                      3:  * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
1.1.1.2   root       11:  *
1.1       root       12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
1.1.1.2   root       15:  *
1.1       root       16:  * Carnegie Mellon requests users of this software to return to
1.1.1.2   root       17:  *
1.1       root       18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
1.1.1.2   root       22:  *
1.1       root       23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Author: David B. Golub, Carnegie Mellon University
                     28:  *     Date:   3/89
                     29:  */
                     30: 
1.1.1.4   root       31: /*
                     32:  * Mach device server routines (i386at version).
                     33:  *
                     34:  * Copyright (c) 1996 The University of Utah and
                     35:  * the Computer Systems Laboratory at the University of Utah (CSL).
                     36:  * All rights reserved.
                     37:  *
                     38:  * Permission to use, copy, modify and distribute this software is hereby
                     39:  * granted provided that (1) source code retains these copyright, permission,
                     40:  * and disclaimer notices, and (2) redistributions including binaries
                     41:  * reproduce the notices in supporting documentation, and (3) all advertising
                     42:  * materials mentioning features or use of this software display the following
                     43:  * acknowledgement: ``This product includes software developed by the
                     44:  * Computer Systems Laboratory at the University of Utah.''
                     45:  *
                     46:  * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
                     47:  * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
                     48:  * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     49:  *
                     50:  * CSL requests users of this software to return to [email protected] any
                     51:  * improvements that they make and grant CSL redistribution rights.
                     52:  *
                     53:  *      Author: Shantanu Goel, University of Utah CSL
                     54:  */
                     55: 
                     56: #include <kern/printf.h>
                     57: #include <string.h>
1.1       root       58: 
                     59: #include <mach/boolean.h>
                     60: #include <mach/kern_return.h>
                     61: #include <mach/mig_errors.h>
                     62: #include <mach/port.h>
                     63: #include <mach/vm_param.h>
                     64: #include <mach/notify.h>
1.1.1.4   root       65: #include <machine/locore.h>
1.1       root       66: #include <machine/machspl.h>           /* spl definitions */
                     67: 
                     68: #include <ipc/ipc_port.h>
                     69: #include <ipc/ipc_space.h>
                     70: 
                     71: #include <kern/ast.h>
                     72: #include <kern/counters.h>
1.1.1.4   root       73: #include <kern/debug.h>
                     74: #include <kern/printf.h>
1.1       root       75: #include <kern/queue.h>
1.1.1.4   root       76: #include <kern/slab.h>
1.1       root       77: #include <kern/thread.h>
                     78: #include <kern/task.h>
                     79: #include <kern/sched_prim.h>
                     80: 
                     81: #include <vm/memory_object.h>
                     82: #include <vm/vm_map.h>
                     83: #include <vm/vm_kern.h>
1.1.1.4   root       84: #include <vm/vm_user.h>
1.1       root       85: 
                     86: #include <device/device_types.h>
                     87: #include <device/dev_hdr.h>
                     88: #include <device/conf.h>
                     89: #include <device/io_req.h>
                     90: #include <device/ds_routines.h>
                     91: #include <device/net_status.h>
                     92: #include <device/device_port.h>
1.1.1.4   root       93: #include <device/device_reply.user.h>
                     94: #include <device/device_emul.h>
1.1       root       95: 
                     96: #include <machine/machspl.h>
1.1.1.4   root       97: 
                     98: #ifdef LINUX_DEV
                     99: extern struct device_emulation_ops linux_block_emulation_ops;
                    100: #ifdef CONFIG_INET
                    101: extern struct device_emulation_ops linux_net_emulation_ops;
1.1.1.5   root      102: extern void free_skbuffs (void);
1.1.1.4   root      103: #ifdef CONFIG_PCMCIA
                    104: extern struct device_emulation_ops linux_pcmcia_emulation_ops;
                    105: #endif /* CONFIG_PCMCIA */
                    106: #endif /* CONFIG_INET */
                    107: #endif /* LINUX_DEV */
                    108: #ifdef MACH_HYP
                    109: extern struct device_emulation_ops hyp_block_emulation_ops;
                    110: extern struct device_emulation_ops hyp_net_emulation_ops;
                    111: #endif /* MACH_HYP */
                    112: extern struct device_emulation_ops mach_device_emulation_ops;
1.1       root      113: 
1.1.1.4   root      114: /* List of emulations.  */
                    115: static struct device_emulation_ops *emulation_list[] =
                    116: {
1.1.1.2   root      117: #ifdef LINUX_DEV
1.1.1.4   root      118:   &linux_block_emulation_ops,
                    119: #ifdef CONFIG_INET
                    120:   &linux_net_emulation_ops,
                    121: #ifdef CONFIG_PCMCIA
                    122:   &linux_pcmcia_emulation_ops,
                    123: #endif /* CONFIG_PCMCIA */
                    124: #endif /* CONFIG_INET */
                    125: #endif /* LINUX_DEV */
                    126: #ifdef MACH_HYP
                    127:   &hyp_block_emulation_ops,
                    128:   &hyp_net_emulation_ops,
                    129: #endif /* MACH_HYP */
                    130:   &mach_device_emulation_ops,
                    131: };
                    132: 
                    133: static struct vm_map   device_io_map_store;
                    134: vm_map_t               device_io_map = &device_io_map_store;
                    135: 
                    136: #define NUM_EMULATION (sizeof (emulation_list) / sizeof (emulation_list[0]))
                    137: 
                    138: io_return_t
                    139: ds_device_open (ipc_port_t open_port, ipc_port_t reply_port,
                    140:                mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                    141:                char *name, device_t *devp)
                    142: {
                    143:   int i;
                    144:   io_return_t err;
                    145: 
                    146:   /* Open must be called on the master device port.  */
                    147:   if (open_port != master_device_port)
                    148:     return D_INVALID_OPERATION;
                    149: 
                    150:   /* There must be a reply port.  */
                    151:   if (! IP_VALID (reply_port))
                    152:     {
                    153:       printf ("ds_* invalid reply port\n");
                    154:       SoftDebugger ("ds_* reply_port");
                    155:       return MIG_NO_REPLY;
                    156:     }
                    157: 
                    158:   /* Call each emulation's open routine to find the device.  */
                    159:   for (i = 0; i < NUM_EMULATION; i++)
                    160:     {
                    161:       err = (*emulation_list[i]->open) (reply_port, reply_port_type,
                    162:                                        mode, name, devp);
                    163:       if (err != D_NO_SUCH_DEVICE)
                    164:        break;
                    165:     }
                    166: 
                    167:   return err;
                    168: }
                    169: 
                    170: io_return_t
                    171: ds_device_close (device_t dev)
                    172: {
                    173:   /* Refuse if device is dead or not completely open.  */
                    174:   if (dev == DEVICE_NULL)
                    175:     return D_NO_SUCH_DEVICE;
                    176: 
                    177:   return (dev->emul_ops->close
                    178:          ? (*dev->emul_ops->close) (dev->emul_data)
                    179:          : D_SUCCESS);
                    180: }
                    181: 
                    182: io_return_t
                    183: ds_device_write (device_t dev, ipc_port_t reply_port,
                    184:                 mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                    185:                 recnum_t recnum, io_buf_ptr_t data, unsigned int count,
                    186:                 int *bytes_written)
                    187: {
                    188:   /* Refuse if device is dead or not completely open.  */
                    189:   if (dev == DEVICE_NULL)
                    190:     return D_NO_SUCH_DEVICE;
                    191: 
                    192:   if (data == 0)
                    193:     return D_INVALID_SIZE;
                    194: 
                    195:   if (! dev->emul_ops->write)
                    196:     return D_INVALID_OPERATION;
                    197: 
                    198:   return (*dev->emul_ops->write) (dev->emul_data, reply_port,
                    199:                                  reply_port_type, mode, recnum,
                    200:                                  data, count, bytes_written);
                    201: }
                    202: 
                    203: io_return_t
                    204: ds_device_write_inband (device_t dev, ipc_port_t reply_port,
                    205:                        mach_msg_type_name_t reply_port_type,
                    206:                        dev_mode_t mode, recnum_t recnum,
                    207:                        io_buf_ptr_inband_t data, unsigned count,
                    208:                        int *bytes_written)
                    209: {
                    210:   /* Refuse if device is dead or not completely open.  */
                    211:   if (dev == DEVICE_NULL)
                    212:     return D_NO_SUCH_DEVICE;
                    213: 
                    214:   if (data == 0)
                    215:     return D_INVALID_SIZE;
                    216: 
                    217:   if (! dev->emul_ops->write_inband)
                    218:     return D_INVALID_OPERATION;
                    219: 
                    220:   return (*dev->emul_ops->write_inband) (dev->emul_data, reply_port,
                    221:                                         reply_port_type, mode, recnum,
                    222:                                         data, count, bytes_written);
                    223: }
                    224: 
                    225: io_return_t
                    226: ds_device_read (device_t dev, ipc_port_t reply_port,
                    227:                mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                    228:                recnum_t recnum, int count, io_buf_ptr_t *data,
                    229:                unsigned *bytes_read)
                    230: {
                    231:   /* Refuse if device is dead or not completely open.  */
                    232:   if (dev == DEVICE_NULL)
                    233:     return D_NO_SUCH_DEVICE;
                    234: 
                    235:   if (! dev->emul_ops->read)
                    236:     return D_INVALID_OPERATION;
                    237: 
                    238:   return (*dev->emul_ops->read) (dev->emul_data, reply_port,
                    239:                                 reply_port_type, mode, recnum,
                    240:                                 count, data, bytes_read);
                    241: }
                    242: 
                    243: io_return_t
                    244: ds_device_read_inband (device_t dev, ipc_port_t reply_port,
                    245:                       mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                    246:                       recnum_t recnum, int count, char *data,
                    247:                       unsigned *bytes_read)
                    248: {
                    249:   /* Refuse if device is dead or not completely open.  */
                    250:   if (dev == DEVICE_NULL)
                    251:     return D_NO_SUCH_DEVICE;
                    252: 
                    253:   if (! dev->emul_ops->read_inband)
                    254:     return D_INVALID_OPERATION;
                    255: 
                    256:   return (*dev->emul_ops->read_inband) (dev->emul_data, reply_port,
                    257:                                        reply_port_type, mode, recnum,
                    258:                                        count, data, bytes_read);
                    259: }
                    260: 
                    261: io_return_t
                    262: ds_device_set_status (device_t dev, dev_flavor_t flavor,
                    263:                      dev_status_t status, mach_msg_type_number_t status_count)
                    264: {
                    265:   /* Refuse if device is dead or not completely open.  */
                    266:   if (dev == DEVICE_NULL)
                    267:     return D_NO_SUCH_DEVICE;
                    268: 
                    269:   if (! dev->emul_ops->set_status)
                    270:     return D_INVALID_OPERATION;
                    271: 
                    272:   return (*dev->emul_ops->set_status) (dev->emul_data, flavor, status,
                    273:                                       status_count);
                    274: }
                    275: 
                    276: io_return_t
                    277: ds_device_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status,
                    278:                      mach_msg_type_number_t *status_count)
                    279: {
                    280:   /* Refuse if device is dead or not completely open.  */
                    281:   if (dev == DEVICE_NULL)
                    282:     return D_NO_SUCH_DEVICE;
                    283: 
                    284:   if (! dev->emul_ops->get_status)
                    285:     return D_INVALID_OPERATION;
                    286: 
                    287:   return (*dev->emul_ops->get_status) (dev->emul_data, flavor, status,
                    288:                                       status_count);
                    289: }
                    290: 
                    291: io_return_t
                    292: ds_device_set_filter (device_t dev, ipc_port_t receive_port, int priority,
                    293:                      filter_t *filter, unsigned filter_count)
                    294: {
                    295:   /* Refuse if device is dead or not completely open.  */
                    296:   if (dev == DEVICE_NULL)
                    297:     return D_NO_SUCH_DEVICE;
                    298: 
                    299:   if (! dev->emul_ops->set_filter)
                    300:     return D_INVALID_OPERATION;
                    301: 
                    302:   return (*dev->emul_ops->set_filter) (dev->emul_data, receive_port,
                    303:                                       priority, filter, filter_count);
                    304: }
                    305: 
                    306: io_return_t
                    307: ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset,
                    308:               vm_size_t size, ipc_port_t *pager, boolean_t unmap)
                    309: {
                    310:   /* Refuse if device is dead or not completely open.  */
                    311:   if (dev == DEVICE_NULL)
                    312:     return D_NO_SUCH_DEVICE;
                    313: 
                    314:   if (! dev->emul_ops->map)
                    315:     return D_INVALID_OPERATION;
                    316: 
                    317:   return (*dev->emul_ops->map) (dev->emul_data, prot,
                    318:                                offset, size, pager, unmap);
                    319: }
                    320: 
                    321: boolean_t
                    322: ds_notify (mach_msg_header_t *msg)
                    323: {
                    324:   if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS)
                    325:     {
                    326:       device_t dev;
                    327:       mach_no_senders_notification_t *ns;
                    328: 
                    329:       ns = (mach_no_senders_notification_t *) msg;
                    330:       dev = dev_port_lookup((ipc_port_t) ns->not_header.msgh_remote_port);
                    331:       assert(dev);
                    332:       if (dev->emul_ops->no_senders)
                    333:        (*dev->emul_ops->no_senders) (ns);
                    334:       return TRUE;
                    335:     }
                    336: 
                    337:   printf ("ds_notify: strange notification %d\n", msg->msgh_id);
                    338:   return FALSE;
                    339: }
                    340: 
                    341: io_return_t
                    342: ds_device_write_trap (device_t dev, dev_mode_t mode,
                    343:                      recnum_t recnum, vm_offset_t data, vm_size_t count)
                    344: {
                    345:   /* Refuse if device is dead or not completely open.  */
                    346:   if (dev == DEVICE_NULL)
                    347:     return D_NO_SUCH_DEVICE;
                    348: 
                    349:   if (! dev->emul_ops->write_trap)
                    350:     return D_INVALID_OPERATION;
                    351: 
                    352:   return (*dev->emul_ops->write_trap) (dev->emul_data,
                    353:                                       mode, recnum, data, count);
                    354: }
                    355: 
                    356: io_return_t
                    357: ds_device_writev_trap (device_t dev, dev_mode_t mode,
                    358:                       recnum_t recnum, io_buf_vec_t *iovec, vm_size_t count)
                    359: {
                    360:   /* Refuse if device is dead or not completely open.  */
                    361:   if (dev == DEVICE_NULL)
                    362:     return D_NO_SUCH_DEVICE;
                    363: 
                    364:   if (! dev->emul_ops->writev_trap)
                    365:     return D_INVALID_OPERATION;
                    366: 
                    367:   return (*dev->emul_ops->writev_trap) (dev->emul_data,
                    368:                                        mode, recnum, iovec, count);
                    369: }
                    370: 
                    371: void
                    372: device_reference (device_t dev)
                    373: {
                    374:   /* Refuse if device is dead or not completely open.  */
                    375:   if (dev == DEVICE_NULL)
                    376:     return;
                    377: 
                    378:   if (dev->emul_ops->reference)
                    379:     (*dev->emul_ops->reference) (dev->emul_data);
                    380: }
                    381: 
                    382: void
                    383: device_deallocate (device_t dev)
                    384: {
                    385:   /* Refuse if device is dead or not completely open.  */
                    386:   if (dev == DEVICE_NULL)
                    387:     return;
                    388: 
                    389:   if (dev->emul_ops->dealloc)
                    390:     (*dev->emul_ops->dealloc) (dev->emul_data);
                    391: }
                    392: 
                    393: /*
                    394:  * What follows is the interface for the native Mach devices.
                    395:  */
1.1       root      396: 
                    397: ipc_port_t
1.1.1.4   root      398: mach_convert_device_to_port (mach_device_t device)
1.1       root      399: {
                    400:   ipc_port_t port;
                    401: 
                    402:   if (! device)
                    403:     return IP_NULL;
1.1.1.4   root      404: 
1.1       root      405:   device_lock(device);
1.1.1.4   root      406: 
1.1       root      407:   if (device->state == DEV_STATE_OPEN)
                    408:     port = ipc_port_make_send(device->port);
                    409:   else
                    410:     port = IP_NULL;
1.1.1.4   root      411: 
1.1       root      412:   device_unlock(device);
1.1.1.4   root      413: 
1.1       root      414:   mach_device_deallocate(device);
1.1.1.4   root      415: 
1.1       root      416:   return port;
                    417: }
                    418: 
                    419: static io_return_t
1.1.1.6 ! root      420: device_open(const ipc_port_t   reply_port,
        !           421:            mach_msg_type_name_t reply_port_type,
        !           422:            dev_mode_t          mode,
        !           423:            char *              name,
        !           424:            device_t            *device_p)
1.1       root      425: {
1.1.1.4   root      426:        mach_device_t           device;
                    427:        kern_return_t           result;
                    428:        io_req_t                ior;
1.1       root      429:        ipc_port_t              notify;
                    430: 
                    431:        /*
                    432:         * Find the device.
                    433:         */
                    434:        device = device_lookup(name);
                    435:        if (device == MACH_DEVICE_NULL)
                    436:            return (D_NO_SUCH_DEVICE);
                    437: 
                    438:        /*
                    439:         * If the device is being opened or closed,
                    440:         * wait for that operation to finish.
                    441:         */
                    442:        device_lock(device);
                    443:        while (device->state == DEV_STATE_OPENING ||
                    444:                device->state == DEV_STATE_CLOSING) {
                    445:            device->io_wait = TRUE;
                    446:            thread_sleep((event_t)device, simple_lock_addr(device->lock), TRUE);
                    447:            device_lock(device);
                    448:        }
                    449: 
                    450:        /*
                    451:         * If the device is already open, increment the open count
                    452:         * and return.
                    453:         */
                    454:        if (device->state == DEV_STATE_OPEN) {
                    455: 
                    456:            if (device->flag & D_EXCL_OPEN) {
                    457:                /*
                    458:                 * Cannot open a second time.
                    459:                 */
                    460:                device_unlock(device);
                    461:                mach_device_deallocate(device);
                    462:                return (D_ALREADY_OPEN);
                    463:            }
                    464: 
                    465:            device->open_count++;
                    466:            device_unlock(device);
                    467:            *device_p = &device->dev;
                    468:            return (D_SUCCESS);
                    469:            /*
                    470:             * Return deallocates device reference while acquiring
                    471:             * port.
                    472:             */
                    473:        }
                    474: 
                    475:        /*
                    476:         * Allocate the device port and register the device before
                    477:         * opening it.
                    478:         */
                    479:        device->state = DEV_STATE_OPENING;
                    480:        device_unlock(device);
                    481: 
                    482:        /*
                    483:         * Allocate port, keeping a reference for it.
                    484:         */
                    485:        device->port = ipc_port_alloc_kernel();
                    486:        if (device->port == IP_NULL) {
                    487:            device_lock(device);
                    488:            device->state = DEV_STATE_INIT;
                    489:            device->port = IP_NULL;
                    490:            if (device->io_wait) {
                    491:                device->io_wait = FALSE;
                    492:                thread_wakeup((event_t)device);
                    493:            }
                    494:            device_unlock(device);
                    495:            mach_device_deallocate(device);
                    496:            return (KERN_RESOURCE_SHORTAGE);
                    497:        }
                    498: 
                    499:        dev_port_enter(device);
                    500: 
                    501:        /*
                    502:         * Request no-senders notifications on device port.
                    503:         */
                    504:        notify = ipc_port_make_sonce(device->port);
                    505:        ip_lock(device->port);
                    506:        ipc_port_nsrequest(device->port, 1, notify, &notify);
                    507:        assert(notify == IP_NULL);
                    508: 
                    509:        /*
                    510:         * Open the device.
                    511:         */
                    512:        io_req_alloc(ior, 0);
                    513: 
                    514:        ior->io_device  = device;
                    515:        ior->io_unit    = device->dev_number;
                    516:        ior->io_op      = IO_OPEN | IO_CALL;
                    517:        ior->io_mode    = mode;
                    518:        ior->io_error   = 0;
                    519:        ior->io_done    = ds_open_done;
                    520:        ior->io_reply_port = reply_port;
                    521:        ior->io_reply_port_type = reply_port_type;
                    522: 
                    523:        result = (*device->dev_ops->d_open)(device->dev_number, (int)mode, ior);
                    524:        if (result == D_IO_QUEUED)
                    525:            return (MIG_NO_REPLY);
                    526: 
                    527:        /*
                    528:         * Return result via ds_open_done.
                    529:         */
                    530:        ior->io_error = result;
                    531:        (void) ds_open_done(ior);
                    532: 
                    533:        io_req_free(ior);
                    534: 
                    535:        return (MIG_NO_REPLY);  /* reply already sent */
                    536: }
                    537: 
                    538: boolean_t
1.1.1.6 ! root      539: ds_open_done(const io_req_t ior)
1.1       root      540: {
                    541:        kern_return_t           result;
1.1.1.4   root      542:        mach_device_t           device;
1.1       root      543: 
                    544:        device = ior->io_device;
                    545:        result = ior->io_error;
                    546: 
                    547:        if (result != D_SUCCESS) {
                    548:            /*
                    549:             * Open failed.  Deallocate port and device.
                    550:             */
                    551:            dev_port_remove(device);
                    552:            ipc_port_dealloc_kernel(device->port);
                    553:            device->port = IP_NULL;
                    554: 
                    555:            device_lock(device);
                    556:            device->state = DEV_STATE_INIT;
                    557:            if (device->io_wait) {
                    558:                device->io_wait = FALSE;
                    559:                thread_wakeup((event_t)device);
                    560:            }
                    561:            device_unlock(device);
                    562: 
                    563:            mach_device_deallocate(device);
                    564:            device = MACH_DEVICE_NULL;
                    565:        }
                    566:        else {
                    567:            /*
                    568:             * Open succeeded.
                    569:             */
                    570:            device_lock(device);
                    571:            device->state = DEV_STATE_OPEN;
                    572:            device->open_count = 1;
                    573:            if (device->io_wait) {
                    574:                device->io_wait = FALSE;
                    575:                thread_wakeup((event_t)device);
                    576:            }
                    577:            device_unlock(device);
                    578: 
                    579:            /* donate device reference to get port */
                    580:        }
                    581:        /*
                    582:         * Must explicitly convert device to port, since
                    583:         * device_reply interface is built as 'user' side
                    584:         * (thus cannot get translation).
                    585:         */
                    586:        if (IP_VALID(ior->io_reply_port)) {
                    587:                (void) ds_device_open_reply(ior->io_reply_port,
                    588:                                            ior->io_reply_port_type,
                    589:                                            result,
1.1.1.4   root      590:                                            mach_convert_device_to_port(device));
1.1       root      591:        } else
                    592:                mach_device_deallocate(device);
                    593: 
                    594:        return (TRUE);
                    595: }
                    596: 
                    597: static io_return_t
1.1.1.6 ! root      598: device_close(void *dev)
1.1       root      599: {
1.1.1.6 ! root      600:        mach_device_t device = dev;
        !           601: 
1.1       root      602:        device_lock(device);
                    603: 
                    604:        /*
                    605:         * If device will remain open, do nothing.
                    606:         */
                    607:        if (--device->open_count > 0) {
                    608:            device_unlock(device);
                    609:            return (D_SUCCESS);
                    610:        }
                    611: 
                    612:        /*
                    613:         * If device is being closed, do nothing.
                    614:         */
                    615:        if (device->state == DEV_STATE_CLOSING) {
                    616:            device_unlock(device);
                    617:            return (D_SUCCESS);
                    618:        }
                    619: 
                    620:        /*
                    621:         * Mark device as closing, to prevent new IO.
                    622:         * Outstanding IO will still be in progress.
                    623:         */
                    624:        device->state = DEV_STATE_CLOSING;
                    625:        device_unlock(device);
                    626: 
                    627:        /*
                    628:         * ? wait for IO to end ?
                    629:         *   only if device wants to
                    630:         */
                    631: 
                    632:        /*
                    633:         * Remove the device-port association.
                    634:         */
                    635:        dev_port_remove(device);
                    636:        ipc_port_dealloc_kernel(device->port);
                    637: 
                    638:        /*
                    639:         * Close the device
                    640:         */
1.1.1.5   root      641:        (*device->dev_ops->d_close)(device->dev_number, 0);
1.1       root      642: 
                    643:        /*
                    644:         * Finally mark it closed.  If someone else is trying
                    645:         * to open it, the open can now proceed.
                    646:         */
                    647:        device_lock(device);
                    648:        device->state = DEV_STATE_INIT;
                    649:        if (device->io_wait) {
                    650:            device->io_wait = FALSE;
                    651:            thread_wakeup((event_t)device);
                    652:        }
                    653:        device_unlock(device);
                    654: 
                    655:        return (D_SUCCESS);
                    656: }
                    657: 
                    658: /*
                    659:  * Write to a device.
                    660:  */
                    661: static io_return_t
1.1.1.6 ! root      662: device_write(void *dev,
        !           663:             const ipc_port_t   reply_port,
        !           664:             mach_msg_type_name_t       reply_port_type,
        !           665:             dev_mode_t         mode,
        !           666:             recnum_t           recnum,
        !           667:             const io_buf_ptr_t data,
        !           668:             unsigned int       data_count,
        !           669:             int                *bytes_written)
1.1       root      670: {
1.1.1.6 ! root      671:        mach_device_t           device = dev;
1.1.1.4   root      672:        io_req_t                ior;
                    673:        io_return_t             result;
1.1       root      674: 
                    675:        if (device->state != DEV_STATE_OPEN)
                    676:            return (D_NO_SUCH_DEVICE);
                    677: 
                    678:        /*
                    679:         * XXX Need logic to reject ridiculously big requests.
                    680:         */
                    681: 
                    682:        /* XXX note that a CLOSE may proceed at any point */
                    683: 
                    684:        /*
                    685:         * Package the write request for the device driver
                    686:         */
                    687:        io_req_alloc(ior, data_count);
                    688: 
                    689:        ior->io_device          = device;
                    690:        ior->io_unit            = device->dev_number;
                    691:        ior->io_op              = IO_WRITE | IO_CALL;
                    692:        ior->io_mode            = mode;
                    693:        ior->io_recnum          = recnum;
                    694:        ior->io_data            = data;
                    695:        ior->io_count           = data_count;
                    696:        ior->io_total           = data_count;
                    697:        ior->io_alloc_size      = 0;
                    698:        ior->io_residual        = 0;
                    699:        ior->io_error           = 0;
                    700:        ior->io_done            = ds_write_done;
                    701:        ior->io_reply_port      = reply_port;
                    702:        ior->io_reply_port_type = reply_port_type;
                    703:        ior->io_copy            = VM_MAP_COPY_NULL;
                    704: 
                    705:        /*
                    706:         * The ior keeps an extra reference for the device.
                    707:         */
                    708:        mach_device_reference(device);
                    709: 
                    710:        /*
                    711:         * And do the write ...
                    712:         *
                    713:         * device_write_dealoc returns false if there's more
                    714:         * to do; it has updated the ior appropriately and expects
                    715:         * its caller to reinvoke it on the device.
                    716:         */
                    717: 
                    718:        do {
                    719: 
                    720:                result = (*device->dev_ops->d_write)(device->dev_number, ior);
                    721: 
                    722:                /*
                    723:                 * If the IO was queued, delay reply until it is finished.
                    724:                 */
                    725:                if (result == D_IO_QUEUED)
                    726:                    return (MIG_NO_REPLY);
                    727: 
                    728:                /*
                    729:                 * Discard the local mapping of the data.
                    730:                 */
                    731: 
                    732:        } while (!device_write_dealloc(ior));
                    733: 
                    734:        /*
                    735:         * Return the number of bytes actually written.
                    736:         */
                    737:        *bytes_written = ior->io_total - ior->io_residual;
                    738: 
                    739:        /*
                    740:         * Remove the extra reference.
                    741:         */
                    742:        mach_device_deallocate(device);
                    743: 
                    744:        io_req_free(ior);
                    745:        return (result);
                    746: }
                    747: 
                    748: /*
                    749:  * Write to a device, but memory is in message.
                    750:  */
                    751: static io_return_t
1.1.1.6 ! root      752: device_write_inband(void               *dev,
        !           753:                    const ipc_port_t    reply_port,
        !           754:                    mach_msg_type_name_t        reply_port_type,
        !           755:                    dev_mode_t          mode,
        !           756:                    recnum_t            recnum,
        !           757:                    io_buf_ptr_inband_t data,
        !           758:                    unsigned int        data_count,
        !           759:                    int                 *bytes_written)
1.1       root      760: {
1.1.1.6 ! root      761:        mach_device_t           device = dev;
1.1.1.4   root      762:        io_req_t                ior;
                    763:        io_return_t             result;
1.1       root      764: 
                    765:        if (device->state != DEV_STATE_OPEN)
                    766:            return (D_NO_SUCH_DEVICE);
                    767: 
                    768:        /* XXX note that a CLOSE may proceed at any point */
                    769: 
                    770:        /*
                    771:         * Package the write request for the device driver.
                    772:         */
                    773:        io_req_alloc(ior, 0);
                    774: 
                    775:        ior->io_device          = device;
                    776:        ior->io_unit            = device->dev_number;
                    777:        ior->io_op              = IO_WRITE | IO_CALL | IO_INBAND;
                    778:        ior->io_mode            = mode;
                    779:        ior->io_recnum          = recnum;
                    780:        ior->io_data            = data;
                    781:        ior->io_count           = data_count;
                    782:        ior->io_total           = data_count;
                    783:        ior->io_alloc_size      = 0;
                    784:        ior->io_residual        = 0;
                    785:        ior->io_error           = 0;
                    786:        ior->io_done            = ds_write_done;
                    787:        ior->io_reply_port      = reply_port;
                    788:        ior->io_reply_port_type = reply_port_type;
                    789: 
                    790:        /*
                    791:         * The ior keeps an extra reference for the device.
                    792:         */
                    793:        mach_device_reference(device);
                    794: 
                    795:        /*
                    796:         * And do the write.
                    797:         */
                    798:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
                    799: 
                    800:        /*
                    801:         * If the IO was queued, delay reply until it is finished.
                    802:         */
                    803:        if (result == D_IO_QUEUED)
                    804:            return (MIG_NO_REPLY);
                    805: 
                    806:        /*
                    807:         * Return the number of bytes actually written.
                    808:         */
                    809:        *bytes_written = ior->io_total - ior->io_residual;
                    810: 
                    811:        /*
                    812:         * Remove the extra reference.
                    813:         */
                    814:        mach_device_deallocate(device);
                    815: 
                    816:        io_req_free(ior);
                    817:        return (result);
                    818: }
                    819: 
                    820: /*
                    821:  * Wire down incoming memory to give to device.
                    822:  */
                    823: kern_return_t
1.1.1.5   root      824: device_write_get(
                    825:        io_req_t                ior,
                    826:        boolean_t               *wait)
1.1       root      827: {
                    828:        vm_map_copy_t           io_copy;
                    829:        vm_offset_t             new_addr;
1.1.1.4   root      830:        kern_return_t           result;
1.1       root      831:        int                     bsize;
                    832:        vm_size_t               min_size;
                    833: 
                    834:        /*
                    835:         * By default, caller does not have to wait.
                    836:         */
                    837:        *wait = FALSE;
                    838: 
                    839:        /*
                    840:         * Nothing to do if no data.
                    841:         */
                    842:        if (ior->io_count == 0)
                    843:            return (KERN_SUCCESS);
                    844: 
                    845:        /*
                    846:         * Loaned iors already have valid data.
                    847:         */
                    848:        if (ior->io_op & IO_LOANED)
                    849:            return (KERN_SUCCESS);
                    850: 
                    851:        /*
                    852:         * Inband case.
                    853:         */
                    854:        if (ior->io_op & IO_INBAND) {
                    855:            assert(ior->io_count <= sizeof (io_buf_ptr_inband_t));
1.1.1.4   root      856:            new_addr = kmem_cache_alloc(&io_inband_cache);
                    857:            memcpy((void*)new_addr, ior->io_data, ior->io_count);
1.1       root      858:            ior->io_data = (io_buf_ptr_t)new_addr;
                    859:            ior->io_alloc_size = sizeof (io_buf_ptr_inband_t);
                    860: 
                    861:            return (KERN_SUCCESS);
                    862:        }
                    863: 
                    864:        /*
                    865:         *      Figure out how much data to move this time.  If the device
                    866:         *      won't return a block size, then we have to do the whole
                    867:         *      request in one shot (ditto if this is a block fragment),
                    868:         *      otherwise, move at least one block's worth.
                    869:         */
                    870:        result = (*ior->io_device->dev_ops->d_dev_info)(
                    871:                                        ior->io_device->dev_number,
                    872:                                        D_INFO_BLOCK_SIZE,
                    873:                                        &bsize);
                    874: 
                    875:        if (result != KERN_SUCCESS || ior->io_count < (vm_size_t) bsize)
                    876:                min_size = (vm_size_t) ior->io_count;
                    877:        else
                    878:                min_size = (vm_size_t) bsize;
                    879: 
                    880:        /*
                    881:         *      Map the pages from this page list into memory.
                    882:         *      io_data records location of data.
                    883:         *      io_alloc_size is the vm size of the region to deallocate.
                    884:         */
                    885:        io_copy = (vm_map_copy_t) ior->io_data;
                    886:        result = kmem_io_map_copyout(device_io_map,
                    887:                        (vm_offset_t*)&ior->io_data, &new_addr,
                    888:                        &ior->io_alloc_size, io_copy, min_size);
                    889:        if (result != KERN_SUCCESS)
                    890:            return (result);
                    891: 
1.1.1.2   root      892:        if ((ior->io_data + ior->io_count) >
1.1       root      893:            (((char *)new_addr) + ior->io_alloc_size)) {
                    894: 
                    895:                /*
                    896:                 *      Operation has to be split.  Reset io_count for how
                    897:                 *      much we can do this time.
                    898:                 */
                    899:                assert(vm_map_copy_has_cont(io_copy));
                    900:                assert(ior->io_count == io_copy->size);
                    901:                ior->io_count = ior->io_alloc_size -
                    902:                        (ior->io_data - ((char *)new_addr));
                    903: 
                    904:                /*
                    905:                 *      Caller must wait synchronously.
                    906:                 */
                    907:                ior->io_op &= ~IO_CALL;
1.1.1.2   root      908:                *wait = TRUE;
1.1       root      909:        }
                    910: 
                    911:        ior->io_copy = io_copy;                 /* vm_map_copy to discard */
                    912:        return (KERN_SUCCESS);
                    913: }
                    914: 
                    915: /*
                    916:  * Clean up memory allocated for IO.
                    917:  */
                    918: boolean_t
1.1.1.5   root      919: device_write_dealloc(io_req_t ior)
1.1       root      920: {
                    921:        vm_map_copy_t   new_copy = VM_MAP_COPY_NULL;
                    922:        vm_map_copy_t   io_copy;
                    923:        kern_return_t   result;
                    924:        vm_offset_t     size_to_do;
1.1.1.2   root      925:        int             bsize;
1.1       root      926: 
                    927:        if (ior->io_alloc_size == 0)
                    928:            return (TRUE);
                    929: 
                    930:        /*
                    931:         * Inband case.
                    932:         */
                    933:        if (ior->io_op & IO_INBAND) {
1.1.1.4   root      934:            kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data);
1.1       root      935: 
                    936:            return (TRUE);
                    937:        }
1.1.1.2   root      938: 
1.1       root      939:        if ((io_copy = ior->io_copy) == VM_MAP_COPY_NULL)
                    940:            return (TRUE);
                    941: 
                    942:        /*
                    943:         *      To prevent a possible deadlock with the default pager,
                    944:         *      we have to release space in the device_io_map before
                    945:         *      we allocate any memory.  (Which vm_map_copy_invoke_cont
1.1.1.4   root      946:         *      might do.)  See the discussion in mach_device_init.
1.1       root      947:         */
                    948: 
                    949:        kmem_io_map_deallocate(device_io_map,
                    950:                         trunc_page(ior->io_data),
1.1.1.4   root      951:                         ior->io_alloc_size);
1.1       root      952: 
                    953:        if (vm_map_copy_has_cont(io_copy)) {
                    954: 
                    955:                /*
1.1.1.2   root      956:                 *      Remember how much is left, then
1.1       root      957:                 *      invoke or abort the continuation.
                    958:                 */
                    959:                size_to_do = io_copy->size - ior->io_count;
                    960:                if (ior->io_error == 0) {
                    961:                        vm_map_copy_invoke_cont(io_copy, &new_copy, &result);
                    962:                }
                    963:                else {
                    964:                        vm_map_copy_abort_cont(io_copy);
                    965:                        result = KERN_FAILURE;
                    966:                }
                    967: 
                    968:                if (result == KERN_SUCCESS && new_copy != VM_MAP_COPY_NULL) {
1.1.1.4   root      969:                        int             res;
1.1       root      970: 
                    971:                        /*
                    972:                         *      We have a new continuation, reset the ior to
                    973:                         *      represent the remainder of the request.  Must
                    974:                         *      adjust the recnum because drivers assume
                    975:                         *      that the residual is zero.
                    976:                         */
                    977:                        ior->io_op &= ~IO_DONE;
                    978:                        ior->io_op |= IO_CALL;
                    979: 
                    980:                        res = (*ior->io_device->dev_ops->d_dev_info)(
                    981:                                        ior->io_device->dev_number,
                    982:                                        D_INFO_BLOCK_SIZE,
                    983:                                        &bsize);
                    984: 
                    985:                        if (res != D_SUCCESS)
                    986:                                panic("device_write_dealloc: No block size");
1.1.1.2   root      987: 
1.1       root      988:                        ior->io_recnum += ior->io_count/bsize;
                    989:                        ior->io_count = new_copy->size;
                    990:                }
                    991:                else {
                    992: 
                    993:                        /*
                    994:                         *      No continuation.  Add amount we didn't get
                    995:                         *      to into residual.
                    996:                         */
                    997:                        ior->io_residual += size_to_do;
                    998:                }
                    999:        }
                   1000: 
                   1001:        /*
                   1002:         *      Clean up the state for the IO that just completed.
                   1003:         */
                   1004:         vm_map_copy_discard(ior->io_copy);
                   1005:        ior->io_copy = VM_MAP_COPY_NULL;
                   1006:        ior->io_data = (char *) new_copy;
                   1007: 
                   1008:        /*
                   1009:         *      Return FALSE if there's more IO to do.
                   1010:         */
                   1011: 
                   1012:        return(new_copy == VM_MAP_COPY_NULL);
                   1013: }
                   1014: 
                   1015: /*
                   1016:  * Send write completion message to client, and discard the data.
                   1017:  */
                   1018: boolean_t
1.1.1.6 ! root     1019: ds_write_done(const io_req_t ior)
1.1       root     1020: {
                   1021:        /*
                   1022:         *      device_write_dealloc discards the data that has been
                   1023:         *      written, but may decide that there is more to write.
                   1024:         */
                   1025:        while (!device_write_dealloc(ior)) {
1.1.1.4   root     1026:                io_return_t             result;
                   1027:                mach_device_t           device;
1.1       root     1028: 
                   1029:                /*
                   1030:                 *     More IO to do -- invoke it.
                   1031:                 */
                   1032:                device = ior->io_device;
                   1033:                result = (*device->dev_ops->d_write)(device->dev_number, ior);
                   1034: 
                   1035:                /*
                   1036:                 * If the IO was queued, return FALSE -- not done yet.
                   1037:                 */
                   1038:                if (result == D_IO_QUEUED)
                   1039:                    return (FALSE);
                   1040:        }
                   1041: 
                   1042:        /*
                   1043:         *      Now the write is really complete.  Send reply.
                   1044:         */
                   1045: 
                   1046:        if (IP_VALID(ior->io_reply_port)) {
                   1047:            (void) (*((ior->io_op & IO_INBAND) ?
                   1048:                      ds_device_write_reply_inband :
                   1049:                      ds_device_write_reply))(ior->io_reply_port,
                   1050:                                              ior->io_reply_port_type,
                   1051:                                              ior->io_error,
                   1052:                                              (int) (ior->io_total -
                   1053:                                                     ior->io_residual));
                   1054:        }
                   1055:        mach_device_deallocate(ior->io_device);
                   1056: 
                   1057:        return (TRUE);
                   1058: }
                   1059: 
                   1060: /*
                   1061:  * Read from a device.
                   1062:  */
                   1063: static io_return_t
1.1.1.6 ! root     1064: device_read(void *dev,
        !          1065:            const ipc_port_t    reply_port,
        !          1066:            mach_msg_type_name_t        reply_port_type,
        !          1067:            dev_mode_t          mode,
        !          1068:            recnum_t            recnum,
        !          1069:            int                 bytes_wanted,
        !          1070:            io_buf_ptr_t        *data,
        !          1071:            unsigned int        *data_count)
1.1       root     1072: {
1.1.1.6 ! root     1073:        mach_device_t           device = dev;
1.1.1.4   root     1074:        io_req_t                ior;
                   1075:        io_return_t             result;
1.1       root     1076: 
                   1077:        if (device->state != DEV_STATE_OPEN)
                   1078:            return (D_NO_SUCH_DEVICE);
                   1079: 
                   1080:        /* XXX note that a CLOSE may proceed at any point */
                   1081: 
                   1082:        /*
                   1083:         * There must be a reply port.
                   1084:         */
                   1085:        if (!IP_VALID(reply_port)) {
                   1086:            printf("ds_* invalid reply port\n");
1.1.1.4   root     1087:            SoftDebugger("ds_* reply_port");
1.1       root     1088:            return (MIG_NO_REPLY);      /* no sense in doing anything */
                   1089:        }
                   1090: 
                   1091:        /*
                   1092:         * Package the read request for the device driver
                   1093:         */
                   1094:        io_req_alloc(ior, 0);
                   1095: 
                   1096:        ior->io_device          = device;
                   1097:        ior->io_unit            = device->dev_number;
                   1098:        ior->io_op              = IO_READ | IO_CALL;
                   1099:        ior->io_mode            = mode;
                   1100:        ior->io_recnum          = recnum;
                   1101:        ior->io_data            = 0;            /* driver must allocate data */
                   1102:        ior->io_count           = bytes_wanted;
                   1103:        ior->io_alloc_size      = 0;            /* no data allocated yet */
                   1104:        ior->io_residual        = 0;
                   1105:        ior->io_error           = 0;
                   1106:        ior->io_done            = ds_read_done;
                   1107:        ior->io_reply_port      = reply_port;
                   1108:        ior->io_reply_port_type = reply_port_type;
                   1109: 
                   1110:        /*
                   1111:         * The ior keeps an extra reference for the device.
                   1112:         */
                   1113:        mach_device_reference(device);
                   1114: 
                   1115:        /*
                   1116:         * And do the read.
                   1117:         */
                   1118:        result = (*device->dev_ops->d_read)(device->dev_number, ior);
                   1119: 
                   1120:        /*
                   1121:         * If the IO was queued, delay reply until it is finished.
                   1122:         */
                   1123:        if (result == D_IO_QUEUED)
                   1124:            return (MIG_NO_REPLY);
                   1125: 
                   1126:        /*
                   1127:         * Return result via ds_read_done.
                   1128:         */
                   1129:        ior->io_error = result;
                   1130:        (void) ds_read_done(ior);
                   1131:        io_req_free(ior);
                   1132: 
                   1133:        return (MIG_NO_REPLY);  /* reply has already been sent. */
                   1134: }
                   1135: 
                   1136: /*
                   1137:  * Read from a device, but return the data 'inband.'
                   1138:  */
                   1139: static io_return_t
1.1.1.6 ! root     1140: device_read_inband(void                        *dev,
        !          1141:                   const ipc_port_t     reply_port,
        !          1142:                   mach_msg_type_name_t reply_port_type,
        !          1143:                   dev_mode_t           mode,
        !          1144:                   recnum_t             recnum,
        !          1145:                   int                  bytes_wanted,
        !          1146:                   char                 *data,
        !          1147:                   unsigned int         *data_count)
1.1       root     1148: {
1.1.1.6 ! root     1149:        mach_device_t           device = dev;
1.1.1.4   root     1150:        io_req_t                ior;
                   1151:        io_return_t             result;
1.1       root     1152: 
                   1153:        if (device->state != DEV_STATE_OPEN)
                   1154:            return (D_NO_SUCH_DEVICE);
                   1155: 
                   1156:        /* XXX note that a CLOSE may proceed at any point */
                   1157: 
                   1158:        /*
                   1159:         * There must be a reply port.
                   1160:         */
                   1161:        if (!IP_VALID(reply_port)) {
                   1162:            printf("ds_* invalid reply port\n");
1.1.1.4   root     1163:            SoftDebugger("ds_* reply_port");
1.1       root     1164:            return (MIG_NO_REPLY);      /* no sense in doing anything */
                   1165:        }
                   1166: 
                   1167:        /*
                   1168:         * Package the read for the device driver
                   1169:         */
                   1170:        io_req_alloc(ior, 0);
                   1171: 
                   1172:        ior->io_device          = device;
                   1173:        ior->io_unit            = device->dev_number;
                   1174:        ior->io_op              = IO_READ | IO_CALL | IO_INBAND;
                   1175:        ior->io_mode            = mode;
                   1176:        ior->io_recnum          = recnum;
                   1177:        ior->io_data            = 0;            /* driver must allocate data */
1.1.1.2   root     1178:        ior->io_count           =
1.1       root     1179:            ((bytes_wanted < sizeof(io_buf_ptr_inband_t)) ?
                   1180:                bytes_wanted : sizeof(io_buf_ptr_inband_t));
                   1181:        ior->io_alloc_size      = 0;            /* no data allocated yet */
                   1182:        ior->io_residual        = 0;
                   1183:        ior->io_error           = 0;
                   1184:        ior->io_done            = ds_read_done;
                   1185:        ior->io_reply_port      = reply_port;
                   1186:        ior->io_reply_port_type = reply_port_type;
                   1187: 
                   1188:        /*
                   1189:         * The ior keeps an extra reference for the device.
                   1190:         */
                   1191:        mach_device_reference(device);
                   1192: 
                   1193:        /*
                   1194:         * Do the read.
                   1195:         */
                   1196:        result = (*device->dev_ops->d_read)(device->dev_number, ior);
                   1197: 
                   1198:        /*
                   1199:         * If the io was queued, delay reply until it is finished.
                   1200:         */
                   1201:        if (result == D_IO_QUEUED)
                   1202:            return (MIG_NO_REPLY);
                   1203: 
                   1204:        /*
                   1205:         * Return result, via ds_read_done.
                   1206:         */
                   1207:        ior->io_error = result;
                   1208:        (void) ds_read_done(ior);
                   1209:        io_req_free(ior);
                   1210: 
                   1211:        return (MIG_NO_REPLY);  /* reply has already been sent. */
                   1212: }
                   1213: 
                   1214: /*
                   1215:  * Allocate wired-down memory for device read.
                   1216:  */
1.1.1.5   root     1217: kern_return_t device_read_alloc(
                   1218:        io_req_t                ior,
                   1219:        vm_size_t               size)
1.1       root     1220: {
                   1221:        vm_offset_t             addr;
                   1222:        kern_return_t           kr;
                   1223: 
                   1224:        /*
                   1225:         * Nothing to do if no data.
                   1226:         */
                   1227:        if (ior->io_count == 0)
                   1228:            return (KERN_SUCCESS);
                   1229: 
                   1230:        if (ior->io_op & IO_INBAND) {
1.1.1.4   root     1231:            ior->io_data = (io_buf_ptr_t) kmem_cache_alloc(&io_inband_cache);
1.1       root     1232:            ior->io_alloc_size = sizeof(io_buf_ptr_inband_t);
                   1233:        } else {
                   1234:            size = round_page(size);
                   1235:            kr = kmem_alloc(kernel_map, &addr, size);
                   1236:            if (kr != KERN_SUCCESS)
                   1237:                return (kr);
                   1238: 
                   1239:            ior->io_data = (io_buf_ptr_t) addr;
                   1240:            ior->io_alloc_size = size;
                   1241:        }
                   1242: 
                   1243:        return (KERN_SUCCESS);
                   1244: }
                   1245: 
1.1.1.6 ! root     1246: boolean_t ds_read_done(const io_req_t ior)
1.1       root     1247: {
                   1248:        vm_offset_t             start_data, end_data;
                   1249:        vm_offset_t             start_sent, end_sent;
1.1.1.4   root     1250:        vm_size_t               size_read;
1.1       root     1251: 
                   1252:        if (ior->io_error)
                   1253:            size_read = 0;
                   1254:        else
                   1255:            size_read = ior->io_count - ior->io_residual;
                   1256: 
                   1257:        start_data  = (vm_offset_t)ior->io_data;
                   1258:        end_data    = start_data + size_read;
                   1259: 
                   1260:        start_sent  = (ior->io_op & IO_INBAND) ? start_data :
                   1261:                                                trunc_page(start_data);
1.1.1.2   root     1262:        end_sent    = (ior->io_op & IO_INBAND) ?
1.1       root     1263:                start_data + ior->io_alloc_size : round_page(end_data);
                   1264: 
                   1265:        /*
                   1266:         * Zero memory that the device did not fill.
                   1267:         */
                   1268:        if (start_sent < start_data)
1.1.1.5   root     1269:            memset((void *)start_sent, 0, start_data - start_sent);
1.1       root     1270:        if (end_sent > end_data)
1.1.1.5   root     1271:            memset((void *)end_data, 0, end_sent - end_data);
1.1       root     1272: 
                   1273: 
                   1274:        /*
                   1275:         * Touch the data being returned, to mark it dirty.
                   1276:         * If the pages were filled by DMA, the pmap module
                   1277:         * may think that they are clean.
                   1278:         */
                   1279:        {
1.1.1.4   root     1280:            vm_offset_t                 touch;
                   1281:            int                         c;
1.1       root     1282: 
                   1283:            for (touch = start_sent; touch < end_sent; touch += PAGE_SIZE) {
1.1.1.2   root     1284:                c = *(volatile char *)touch;
                   1285:                *(volatile char *)touch = c;
1.1       root     1286:            }
                   1287:        }
                   1288: 
                   1289:        /*
                   1290:         * Send the data to the reply port - this
                   1291:         * unwires and deallocates it.
                   1292:         */
                   1293:        if (ior->io_op & IO_INBAND) {
                   1294:            (void)ds_device_read_reply_inband(ior->io_reply_port,
                   1295:                                              ior->io_reply_port_type,
                   1296:                                              ior->io_error,
                   1297:                                              (char *) start_data,
                   1298:                                              size_read);
                   1299:        } else {
                   1300:            vm_map_copy_t copy;
                   1301:            kern_return_t kr;
                   1302: 
                   1303:            kr = vm_map_copyin_page_list(kernel_map, start_data,
                   1304:                                                 size_read, TRUE, TRUE,
                   1305:                                                 &copy, FALSE);
                   1306: 
                   1307:            if (kr != KERN_SUCCESS)
                   1308:                panic("read_done: vm_map_copyin_page_list failed");
                   1309: 
                   1310:            (void)ds_device_read_reply(ior->io_reply_port,
                   1311:                                       ior->io_reply_port_type,
                   1312:                                       ior->io_error,
                   1313:                                       (char *) copy,
                   1314:                                       size_read);
                   1315:        }
                   1316: 
                   1317:        /*
                   1318:         * Free any memory that was allocated but not sent.
                   1319:         */
                   1320:        if (ior->io_count != 0) {
                   1321:            if (ior->io_op & IO_INBAND) {
                   1322:                if (ior->io_alloc_size > 0)
1.1.1.4   root     1323:                    kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data);
1.1       root     1324:            } else {
1.1.1.4   root     1325:                vm_offset_t             end_alloc;
1.1       root     1326: 
                   1327:                end_alloc = start_sent + round_page(ior->io_alloc_size);
                   1328:                if (end_alloc > end_sent)
                   1329:                    (void) vm_deallocate(kernel_map,
                   1330:                                         end_sent,
                   1331:                                         end_alloc - end_sent);
                   1332:            }
                   1333:        }
                   1334: 
                   1335:        mach_device_deallocate(ior->io_device);
                   1336: 
                   1337:        return (TRUE);
                   1338: }
                   1339: 
                   1340: static io_return_t
1.1.1.5   root     1341: device_set_status(
1.1.1.6 ! root     1342:        void                    *dev,
1.1.1.5   root     1343:        dev_flavor_t            flavor,
                   1344:        dev_status_t            status,
                   1345:        mach_msg_type_number_t  status_count)
1.1       root     1346: {
1.1.1.6 ! root     1347:        mach_device_t           device = dev;
1.1       root     1348:        if (device->state != DEV_STATE_OPEN)
                   1349:            return (D_NO_SUCH_DEVICE);
                   1350: 
                   1351:        /* XXX note that a CLOSE may proceed at any point */
                   1352: 
                   1353:        return ((*device->dev_ops->d_setstat)(device->dev_number,
                   1354:                                              flavor,
                   1355:                                              status,
                   1356:                                              status_count));
                   1357: }
                   1358: 
                   1359: io_return_t
1.1.1.5   root     1360: mach_device_get_status(
1.1.1.6 ! root     1361:        void                    *dev,
1.1.1.5   root     1362:        dev_flavor_t            flavor,
                   1363:        dev_status_t            status,         /* pointer to OUT array */
                   1364:        mach_msg_type_number_t  *status_count)  /* out */
1.1       root     1365: {
1.1.1.6 ! root     1366:        mach_device_t           device = dev;
1.1       root     1367:        if (device->state != DEV_STATE_OPEN)
                   1368:            return (D_NO_SUCH_DEVICE);
                   1369: 
                   1370:        /* XXX note that a CLOSE may proceed at any point */
                   1371: 
                   1372:        return ((*device->dev_ops->d_getstat)(device->dev_number,
                   1373:                                              flavor,
                   1374:                                              status,
                   1375:                                              status_count));
                   1376: }
                   1377: 
                   1378: static io_return_t
1.1.1.6 ! root     1379: device_set_filter(void                 *dev,
        !          1380:                  const ipc_port_t      receive_port,
        !          1381:                  int                   priority,
        !          1382:                  filter_t              filter[],
        !          1383:                  unsigned int          filter_count)
1.1       root     1384: {
1.1.1.6 ! root     1385:        mach_device_t           device = dev;
1.1       root     1386:        if (device->state != DEV_STATE_OPEN)
                   1387:            return (D_NO_SUCH_DEVICE);
                   1388: 
                   1389:        /* XXX note that a CLOSE may proceed at any point */
                   1390: 
                   1391:        /*
                   1392:         * Request is absurd if no receive port is specified.
                   1393:         */
                   1394:        if (!IP_VALID(receive_port))
                   1395:            return (D_INVALID_OPERATION);
                   1396: 
                   1397:        return ((*device->dev_ops->d_async_in)(device->dev_number,
                   1398:                                               receive_port,
                   1399:                                               priority,
                   1400:                                               filter,
                   1401:                                               filter_count));
                   1402: }
                   1403: 
                   1404: static io_return_t
1.1.1.5   root     1405: device_map(
1.1.1.6 ! root     1406:        void                    *dev,
1.1.1.5   root     1407:        vm_prot_t               protection,
                   1408:        vm_offset_t             offset,
                   1409:        vm_size_t               size,
                   1410:        ipc_port_t              *pager, /* out */
                   1411:        boolean_t               unmap)  /* ? */
1.1       root     1412: {
1.1.1.6 ! root     1413:        mach_device_t           device = dev;
1.1       root     1414:        if (protection & ~VM_PROT_ALL)
                   1415:                return (KERN_INVALID_ARGUMENT);
                   1416: 
                   1417:        if (device->state != DEV_STATE_OPEN)
                   1418:            return (D_NO_SUCH_DEVICE);
                   1419: 
                   1420:        /* XXX note that a CLOSE may proceed at any point */
                   1421: 
                   1422:        return (device_pager_setup(device, protection, offset, size,
                   1423:                                    (mach_port_t*)pager));
                   1424: }
                   1425: 
                   1426: /*
                   1427:  * Doesn't do anything (yet).
                   1428:  */
                   1429: static void
1.1.1.6 ! root     1430: ds_no_senders(mach_no_senders_notification_t *notification)
1.1       root     1431: {
1.1.1.4   root     1432:        printf("ds_no_senders called! device_port=0x%lx count=%d\n",
1.1       root     1433:               notification->not_header.msgh_remote_port,
                   1434:               notification->not_count);
                   1435: }
                   1436: 
                   1437: queue_head_t           io_done_list;
                   1438: decl_simple_lock_data(,        io_done_list_lock)
                   1439: 
                   1440: #define        splio   splsched        /* XXX must block ALL io devices */
                   1441: 
1.1.1.5   root     1442: void iodone(io_req_t ior)
1.1       root     1443: {
1.1.1.4   root     1444:        spl_t                   s;
1.1       root     1445: 
                   1446:        /*
                   1447:         * If this ior was loaned to us, return it directly.
                   1448:         */
                   1449:        if (ior->io_op & IO_LOANED) {
                   1450:                (*ior->io_done)(ior);
                   1451:                return;
                   1452:        }
                   1453:        /*
                   1454:         * If !IO_CALL, some thread is waiting for this.  Must lock
                   1455:         * structure to interlock correctly with iowait().  Else can
                   1456:         * toss on queue for io_done thread to call completion.
                   1457:         */
                   1458:        s = splio();
                   1459:        if ((ior->io_op & IO_CALL) == 0) {
                   1460:            ior_lock(ior);
                   1461:            ior->io_op |= IO_DONE;
                   1462:            ior->io_op &= ~IO_WANTED;
                   1463:            ior_unlock(ior);
                   1464:            thread_wakeup((event_t)ior);
                   1465:        } else {
                   1466:            ior->io_op |= IO_DONE;
                   1467:            simple_lock(&io_done_list_lock);
                   1468:            enqueue_tail(&io_done_list, (queue_entry_t)ior);
                   1469:            thread_wakeup((event_t)&io_done_list);
                   1470:            simple_unlock(&io_done_list_lock);
                   1471:        }
                   1472:        splx(s);
                   1473: }
                   1474: 
1.1.1.5   root     1475: void  __attribute__ ((noreturn)) io_done_thread_continue(void)
1.1       root     1476: {
                   1477:        for (;;) {
1.1.1.4   root     1478:            spl_t               s;
                   1479:            io_req_t            ior;
1.1       root     1480: 
1.1.1.4   root     1481: #if defined (LINUX_DEV) && defined (CONFIG_INET)
1.1       root     1482:            free_skbuffs ();
                   1483: #endif
                   1484:            s = splio();
                   1485:            simple_lock(&io_done_list_lock);
                   1486:            while ((ior = (io_req_t)dequeue_head(&io_done_list)) != 0) {
                   1487:                simple_unlock(&io_done_list_lock);
                   1488:                (void) splx(s);
                   1489: 
                   1490:                if ((*ior->io_done)(ior)) {
                   1491:                    /*
                   1492:                     * IO done - free io_req_elt
                   1493:                     */
                   1494:                    io_req_free(ior);
                   1495:                }
                   1496:                /* else routine has re-queued it somewhere */
                   1497: 
                   1498:                s = splio();
                   1499:                simple_lock(&io_done_list_lock);
                   1500:            }
                   1501: 
                   1502:            assert_wait(&io_done_list, FALSE);
                   1503:            simple_unlock(&io_done_list_lock);
                   1504:            (void) splx(s);
                   1505:            counter(c_io_done_thread_block++);
                   1506:            thread_block(io_done_thread_continue);
                   1507:        }
                   1508: }
                   1509: 
1.1.1.5   root     1510: void io_done_thread(void)
1.1       root     1511: {
                   1512:        /*
                   1513:         * Set thread privileges and highest priority.
                   1514:         */
                   1515:        current_thread()->vm_privilege = TRUE;
                   1516:        stack_privilege(current_thread());
                   1517:        thread_set_own_priority(0);
                   1518: 
                   1519:        io_done_thread_continue();
                   1520:        /*NOTREACHED*/
                   1521: }
                   1522: 
1.1.1.4   root     1523: #define        DEVICE_IO_MAP_SIZE      (16 * 1024 * 1024)
1.1       root     1524: 
1.1.1.4   root     1525: static void mach_device_trap_init(void);               /* forward */
1.1       root     1526: 
1.1.1.5   root     1527: void mach_device_init(void)
1.1       root     1528: {
                   1529:        vm_offset_t     device_io_min, device_io_max;
                   1530: 
                   1531:        queue_init(&io_done_list);
                   1532:        simple_lock_init(&io_done_list_lock);
                   1533: 
1.1.1.4   root     1534:        kmem_submap(device_io_map, kernel_map, &device_io_min, &device_io_max,
                   1535:                    DEVICE_IO_MAP_SIZE, FALSE);
                   1536: 
1.1       root     1537:        /*
                   1538:         *      If the kernel receives many device_write requests, the
                   1539:         *      device_io_map might run out of space.  To prevent
                   1540:         *      device_write_get from failing in this case, we enable
                   1541:         *      wait_for_space on the map.  This causes kmem_io_map_copyout
                   1542:         *      to block until there is sufficient space.
                   1543:         *      (XXX Large writes may be starved by small writes.)
                   1544:         *
                   1545:         *      There is a potential deadlock problem with this solution,
                   1546:         *      if a device_write from the default pager has to wait
                   1547:         *      for the completion of a device_write which needs to wait
                   1548:         *      for memory allocation.  Hence, once device_write_get
                   1549:         *      allocates space in device_io_map, no blocking memory
                   1550:         *      allocations should happen until device_write_dealloc
                   1551:         *      frees the space.  (XXX A large write might starve
                   1552:         *      a small write from the default pager.)
                   1553:         */
                   1554:        device_io_map->wait_for_space = TRUE;
                   1555: 
1.1.1.4   root     1556:        kmem_cache_init(&io_inband_cache, "io_buf_ptr_inband",
                   1557:                        sizeof(io_buf_ptr_inband_t), 0, NULL, NULL, NULL, 0);
1.1       root     1558: 
1.1.1.4   root     1559:        mach_device_trap_init();
1.1       root     1560: }
                   1561: 
1.1.1.5   root     1562: void iowait(io_req_t ior)
1.1       root     1563: {
                   1564:     spl_t s;
                   1565: 
                   1566:     s = splio();
                   1567:     ior_lock(ior);
                   1568:     while ((ior->io_op&IO_DONE)==0) {
                   1569:        assert_wait((event_t)ior, FALSE);
                   1570:        ior_unlock(ior);
                   1571:        thread_block((void (*)()) 0);
                   1572:         ior_lock(ior);
                   1573:     }
                   1574:     ior_unlock(ior);
                   1575:     splx(s);
                   1576: }
                   1577: 
                   1578: 
                   1579: /*
                   1580:  * Device trap support.
                   1581:  */
                   1582: 
                   1583: /*
                   1584:  * Memory Management
                   1585:  *
                   1586:  * This currently has a single pool of 2k wired buffers
                   1587:  * since we only handle writes to an ethernet device.
                   1588:  * Should be more general.
                   1589:  */
                   1590: #define IOTRAP_REQSIZE 2048
                   1591: 
1.1.1.4   root     1592: struct kmem_cache io_trap_cache;
1.1       root     1593: 
                   1594: /*
1.1.1.4   root     1595:  * Initialization.  Called from mach_device_init().
1.1       root     1596:  */
1.1.1.4   root     1597: static void
                   1598: mach_device_trap_init(void)
1.1       root     1599: {
1.1.1.4   root     1600:        kmem_cache_init(&io_trap_cache, "io_req", IOTRAP_REQSIZE, 0,
                   1601:                        NULL, NULL, NULL, 0);
1.1       root     1602: }
                   1603: 
                   1604: /*
                   1605:  * Allocate an io_req_t.
1.1.1.4   root     1606:  * Currently allocates from io_trap_cache.
1.1       root     1607:  *
1.1.1.4   root     1608:  * Could have lists of different size caches.
1.1       root     1609:  * Could call a device-specific routine.
                   1610:  */
                   1611: io_req_t
1.1.1.5   root     1612: ds_trap_req_alloc(const mach_device_t device, vm_size_t data_size)
1.1       root     1613: {
1.1.1.4   root     1614:        return (io_req_t) kmem_cache_alloc(&io_trap_cache);
1.1       root     1615: }
                   1616: 
                   1617: /*
                   1618:  * Called by iodone to release ior.
                   1619:  */
                   1620: boolean_t
1.1.1.5   root     1621: ds_trap_write_done(const io_req_t ior)
1.1       root     1622: {
1.1.1.4   root     1623:        mach_device_t   dev;
1.1       root     1624: 
                   1625:        dev = ior->io_device;
                   1626: 
                   1627:        /*
                   1628:         * Should look at reply port and maybe send a message.
                   1629:         */
1.1.1.4   root     1630:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1.1.2   root     1631: 
1.1       root     1632:        /*
                   1633:         * Give up device reference from ds_write_trap.
                   1634:         */
                   1635:        mach_device_deallocate(dev);
                   1636:        return TRUE;
                   1637: }
                   1638: 
                   1639: /*
                   1640:  * Like device_write except that data is in user space.
                   1641:  */
                   1642: static io_return_t
1.1.1.4   root     1643: device_write_trap (mach_device_t device, dev_mode_t mode,
1.1       root     1644:                   recnum_t recnum, vm_offset_t data, vm_size_t data_count)
                   1645: {
                   1646:        io_req_t ior;
                   1647:        io_return_t result;
                   1648: 
                   1649:        if (device->state != DEV_STATE_OPEN)
                   1650:                return (D_NO_SUCH_DEVICE);
1.1.1.2   root     1651: 
1.1       root     1652:        /* XXX note that a CLOSE may proceed at any point */
1.1.1.2   root     1653: 
1.1       root     1654:        /*
                   1655:         * Get a buffer to hold the ioreq.
                   1656:         */
                   1657:        ior = ds_trap_req_alloc(device, data_count);
1.1.1.2   root     1658: 
1.1       root     1659:        /*
                   1660:         * Package the write request for the device driver.
                   1661:         */
                   1662: 
                   1663:        ior->io_device          = device;
                   1664:        ior->io_unit            = device->dev_number;
                   1665:        ior->io_op              = IO_WRITE | IO_CALL | IO_LOANED;
                   1666:        ior->io_mode            = mode;
                   1667:        ior->io_recnum          = recnum;
                   1668:        ior->io_data            = (io_buf_ptr_t)
                   1669:                (vm_offset_t)ior + sizeof(struct io_req);
                   1670:        ior->io_count           = data_count;
                   1671:        ior->io_total           = data_count;
                   1672:        ior->io_alloc_size      = 0;
                   1673:        ior->io_residual        = 0;
                   1674:        ior->io_error           = 0;
                   1675:        ior->io_done            = ds_trap_write_done;
                   1676:        ior->io_reply_port      = IP_NULL;      /* XXX */
                   1677:        ior->io_reply_port_type = 0;            /* XXX */
                   1678: 
                   1679:        /*
                   1680:         * Copy the data from user space.
                   1681:         */
                   1682:        if (data_count > 0)
1.1.1.5   root     1683:                copyin((void *)data, ior->io_data, data_count);
1.1.1.2   root     1684: 
1.1       root     1685:        /*
                   1686:         * The ior keeps an extra reference for the device.
                   1687:         */
                   1688:        mach_device_reference(device);
1.1.1.2   root     1689: 
1.1       root     1690:        /*
                   1691:         * And do the write.
                   1692:         */
                   1693:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
1.1.1.2   root     1694: 
1.1       root     1695:        /*
                   1696:         * If the IO was queued, delay reply until it is finished.
                   1697:         */
                   1698:        if (result == D_IO_QUEUED)
                   1699:                return (MIG_NO_REPLY);
1.1.1.2   root     1700: 
1.1       root     1701:        /*
                   1702:         * Remove the extra reference.
                   1703:         */
                   1704:        mach_device_deallocate(device);
1.1.1.2   root     1705: 
1.1.1.4   root     1706:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1       root     1707:        return (result);
                   1708: }
                   1709: 
                   1710: static io_return_t
1.1.1.4   root     1711: device_writev_trap (mach_device_t device, dev_mode_t mode,
1.1       root     1712:                    recnum_t recnum, io_buf_vec_t *iovec, vm_size_t iocount)
                   1713: {
                   1714:        io_req_t ior;
                   1715:        io_return_t result;
                   1716:        io_buf_vec_t    stack_iovec[16]; /* XXX */
                   1717:        vm_size_t data_count;
                   1718:        int i;
                   1719: 
                   1720:        if (device->state != DEV_STATE_OPEN)
                   1721:                return (D_NO_SUCH_DEVICE);
1.1.1.2   root     1722: 
1.1       root     1723:        /* XXX note that a CLOSE may proceed at any point */
1.1.1.2   root     1724: 
1.1       root     1725:        /*
                   1726:         * Copyin user addresses.
                   1727:         */
                   1728:        if (iocount > 16)
                   1729:                return KERN_INVALID_VALUE; /* lame */
1.1.1.5   root     1730:        copyin(iovec,
                   1731:               stack_iovec,
1.1       root     1732:               iocount * sizeof(io_buf_vec_t));
                   1733:        for (data_count = 0, i = 0; i < iocount; i++)
                   1734:                data_count += stack_iovec[i].count;
                   1735: 
                   1736:        /*
                   1737:         * Get a buffer to hold the ioreq.
                   1738:         */
                   1739:        ior = ds_trap_req_alloc(device, data_count);
1.1.1.2   root     1740: 
1.1       root     1741:        /*
                   1742:         * Package the write request for the device driver.
                   1743:         */
                   1744: 
                   1745:        ior->io_device          = device;
                   1746:        ior->io_unit            = device->dev_number;
                   1747:        ior->io_op              = IO_WRITE | IO_CALL | IO_LOANED;
                   1748:        ior->io_mode            = mode;
                   1749:        ior->io_recnum          = recnum;
                   1750:        ior->io_data            = (io_buf_ptr_t)
                   1751:                (vm_offset_t)ior + sizeof(struct io_req);
                   1752:        ior->io_count           = data_count;
                   1753:        ior->io_total           = data_count;
                   1754:        ior->io_alloc_size      = 0;
                   1755:        ior->io_residual        = 0;
                   1756:        ior->io_error           = 0;
                   1757:        ior->io_done            = ds_trap_write_done;
                   1758:        ior->io_reply_port      = IP_NULL;      /* XXX */
                   1759:        ior->io_reply_port_type = 0;            /* XXX */
                   1760: 
                   1761:        /*
                   1762:         * Copy the data from user space.
                   1763:         */
                   1764:        if (data_count > 0) {
                   1765:                vm_offset_t p;
                   1766: 
                   1767:                p = (vm_offset_t) ior->io_data;
                   1768:                for (i = 0; i < iocount; i++) {
1.1.1.5   root     1769:                        copyin((void *) stack_iovec[i].data,
                   1770:                               (void *) p,
1.1       root     1771:                               stack_iovec[i].count);
                   1772:                        p += stack_iovec[i].count;
                   1773:                }
                   1774:        }
1.1.1.2   root     1775: 
1.1       root     1776:        /*
                   1777:         * The ior keeps an extra reference for the device.
                   1778:         */
                   1779:        mach_device_reference(device);
1.1.1.2   root     1780: 
1.1       root     1781:        /*
                   1782:         * And do the write.
                   1783:         */
                   1784:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
1.1.1.2   root     1785: 
1.1       root     1786:        /*
                   1787:         * If the IO was queued, delay reply until it is finished.
                   1788:         */
                   1789:        if (result == D_IO_QUEUED)
                   1790:                return (MIG_NO_REPLY);
1.1.1.2   root     1791: 
1.1       root     1792:        /*
                   1793:         * Remove the extra reference.
                   1794:         */
                   1795:        mach_device_deallocate(device);
1.1.1.2   root     1796: 
1.1.1.4   root     1797:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1       root     1798:        return (result);
                   1799: }
                   1800: 
                   1801: struct device_emulation_ops mach_device_emulation_ops =
                   1802: {
1.1.1.4   root     1803:   (void*) mach_device_reference,
                   1804:   (void*) mach_device_deallocate,
                   1805:   (void*) mach_convert_device_to_port,
1.1       root     1806:   device_open,
                   1807:   device_close,
                   1808:   device_write,
                   1809:   device_write_inband,
                   1810:   device_read,
                   1811:   device_read_inband,
                   1812:   device_set_status,
                   1813:   mach_device_get_status,
                   1814:   device_set_filter,
                   1815:   device_map,
                   1816:   ds_no_senders,
1.1.1.4   root     1817:   (void*) device_write_trap,
                   1818:   (void*) device_writev_trap
1.1       root     1819: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.