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

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
                    420: device_open(reply_port, reply_port_type, mode, name, device_p)
1.1.1.5 ! root      421:        const ipc_port_t reply_port;
1.1       root      422:        mach_msg_type_name_t reply_port_type;
                    423:        dev_mode_t      mode;
                    424:        char *          name;
                    425:        device_t        *device_p;      /* out */
                    426: {
1.1.1.4   root      427:        mach_device_t           device;
                    428:        kern_return_t           result;
                    429:        io_req_t                ior;
1.1       root      430:        ipc_port_t              notify;
                    431: 
                    432:        /*
                    433:         * Find the device.
                    434:         */
                    435:        device = device_lookup(name);
                    436:        if (device == MACH_DEVICE_NULL)
                    437:            return (D_NO_SUCH_DEVICE);
                    438: 
                    439:        /*
                    440:         * If the device is being opened or closed,
                    441:         * wait for that operation to finish.
                    442:         */
                    443:        device_lock(device);
                    444:        while (device->state == DEV_STATE_OPENING ||
                    445:                device->state == DEV_STATE_CLOSING) {
                    446:            device->io_wait = TRUE;
                    447:            thread_sleep((event_t)device, simple_lock_addr(device->lock), TRUE);
                    448:            device_lock(device);
                    449:        }
                    450: 
                    451:        /*
                    452:         * If the device is already open, increment the open count
                    453:         * and return.
                    454:         */
                    455:        if (device->state == DEV_STATE_OPEN) {
                    456: 
                    457:            if (device->flag & D_EXCL_OPEN) {
                    458:                /*
                    459:                 * Cannot open a second time.
                    460:                 */
                    461:                device_unlock(device);
                    462:                mach_device_deallocate(device);
                    463:                return (D_ALREADY_OPEN);
                    464:            }
                    465: 
                    466:            device->open_count++;
                    467:            device_unlock(device);
                    468:            *device_p = &device->dev;
                    469:            return (D_SUCCESS);
                    470:            /*
                    471:             * Return deallocates device reference while acquiring
                    472:             * port.
                    473:             */
                    474:        }
                    475: 
                    476:        /*
                    477:         * Allocate the device port and register the device before
                    478:         * opening it.
                    479:         */
                    480:        device->state = DEV_STATE_OPENING;
                    481:        device_unlock(device);
                    482: 
                    483:        /*
                    484:         * Allocate port, keeping a reference for it.
                    485:         */
                    486:        device->port = ipc_port_alloc_kernel();
                    487:        if (device->port == IP_NULL) {
                    488:            device_lock(device);
                    489:            device->state = DEV_STATE_INIT;
                    490:            device->port = IP_NULL;
                    491:            if (device->io_wait) {
                    492:                device->io_wait = FALSE;
                    493:                thread_wakeup((event_t)device);
                    494:            }
                    495:            device_unlock(device);
                    496:            mach_device_deallocate(device);
                    497:            return (KERN_RESOURCE_SHORTAGE);
                    498:        }
                    499: 
                    500:        dev_port_enter(device);
                    501: 
                    502:        /*
                    503:         * Request no-senders notifications on device port.
                    504:         */
                    505:        notify = ipc_port_make_sonce(device->port);
                    506:        ip_lock(device->port);
                    507:        ipc_port_nsrequest(device->port, 1, notify, &notify);
                    508:        assert(notify == IP_NULL);
                    509: 
                    510:        /*
                    511:         * Open the device.
                    512:         */
                    513:        io_req_alloc(ior, 0);
                    514: 
                    515:        ior->io_device  = device;
                    516:        ior->io_unit    = device->dev_number;
                    517:        ior->io_op      = IO_OPEN | IO_CALL;
                    518:        ior->io_mode    = mode;
                    519:        ior->io_error   = 0;
                    520:        ior->io_done    = ds_open_done;
                    521:        ior->io_reply_port = reply_port;
                    522:        ior->io_reply_port_type = reply_port_type;
                    523: 
                    524:        result = (*device->dev_ops->d_open)(device->dev_number, (int)mode, ior);
                    525:        if (result == D_IO_QUEUED)
                    526:            return (MIG_NO_REPLY);
                    527: 
                    528:        /*
                    529:         * Return result via ds_open_done.
                    530:         */
                    531:        ior->io_error = result;
                    532:        (void) ds_open_done(ior);
                    533: 
                    534:        io_req_free(ior);
                    535: 
                    536:        return (MIG_NO_REPLY);  /* reply already sent */
                    537: }
                    538: 
                    539: boolean_t
                    540: ds_open_done(ior)
1.1.1.5 ! root      541:        const io_req_t          ior;
1.1       root      542: {
                    543:        kern_return_t           result;
1.1.1.4   root      544:        mach_device_t           device;
1.1       root      545: 
                    546:        device = ior->io_device;
                    547:        result = ior->io_error;
                    548: 
                    549:        if (result != D_SUCCESS) {
                    550:            /*
                    551:             * Open failed.  Deallocate port and device.
                    552:             */
                    553:            dev_port_remove(device);
                    554:            ipc_port_dealloc_kernel(device->port);
                    555:            device->port = IP_NULL;
                    556: 
                    557:            device_lock(device);
                    558:            device->state = DEV_STATE_INIT;
                    559:            if (device->io_wait) {
                    560:                device->io_wait = FALSE;
                    561:                thread_wakeup((event_t)device);
                    562:            }
                    563:            device_unlock(device);
                    564: 
                    565:            mach_device_deallocate(device);
                    566:            device = MACH_DEVICE_NULL;
                    567:        }
                    568:        else {
                    569:            /*
                    570:             * Open succeeded.
                    571:             */
                    572:            device_lock(device);
                    573:            device->state = DEV_STATE_OPEN;
                    574:            device->open_count = 1;
                    575:            if (device->io_wait) {
                    576:                device->io_wait = FALSE;
                    577:                thread_wakeup((event_t)device);
                    578:            }
                    579:            device_unlock(device);
                    580: 
                    581:            /* donate device reference to get port */
                    582:        }
                    583:        /*
                    584:         * Must explicitly convert device to port, since
                    585:         * device_reply interface is built as 'user' side
                    586:         * (thus cannot get translation).
                    587:         */
                    588:        if (IP_VALID(ior->io_reply_port)) {
                    589:                (void) ds_device_open_reply(ior->io_reply_port,
                    590:                                            ior->io_reply_port_type,
                    591:                                            result,
1.1.1.4   root      592:                                            mach_convert_device_to_port(device));
1.1       root      593:        } else
                    594:                mach_device_deallocate(device);
                    595: 
                    596:        return (TRUE);
                    597: }
                    598: 
                    599: static io_return_t
1.1.1.5 ! root      600: device_close(mach_device_t device)
1.1       root      601: {
                    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.4   root      662: device_write(device, reply_port, reply_port_type, mode, recnum,
1.1       root      663:             data, data_count, bytes_written)
1.1.1.4   root      664:        mach_device_t           device;
1.1.1.5 ! root      665:        const ipc_port_t        reply_port;
1.1       root      666:        mach_msg_type_name_t    reply_port_type;
                    667:        dev_mode_t              mode;
                    668:        recnum_t                recnum;
1.1.1.5 ! root      669:        const io_buf_ptr_t      data;
1.1       root      670:        unsigned int            data_count;
                    671:        int                     *bytes_written; /* out */
                    672: {
1.1.1.4   root      673:        io_req_t                ior;
                    674:        io_return_t             result;
1.1       root      675: 
                    676:        if (device->state != DEV_STATE_OPEN)
                    677:            return (D_NO_SUCH_DEVICE);
                    678: 
                    679:        /*
                    680:         * XXX Need logic to reject ridiculously big requests.
                    681:         */
                    682: 
                    683:        /* XXX note that a CLOSE may proceed at any point */
                    684: 
                    685:        /*
                    686:         * Package the write request for the device driver
                    687:         */
                    688:        io_req_alloc(ior, data_count);
                    689: 
                    690:        ior->io_device          = device;
                    691:        ior->io_unit            = device->dev_number;
                    692:        ior->io_op              = IO_WRITE | IO_CALL;
                    693:        ior->io_mode            = mode;
                    694:        ior->io_recnum          = recnum;
                    695:        ior->io_data            = data;
                    696:        ior->io_count           = data_count;
                    697:        ior->io_total           = data_count;
                    698:        ior->io_alloc_size      = 0;
                    699:        ior->io_residual        = 0;
                    700:        ior->io_error           = 0;
                    701:        ior->io_done            = ds_write_done;
                    702:        ior->io_reply_port      = reply_port;
                    703:        ior->io_reply_port_type = reply_port_type;
                    704:        ior->io_copy            = VM_MAP_COPY_NULL;
                    705: 
                    706:        /*
                    707:         * The ior keeps an extra reference for the device.
                    708:         */
                    709:        mach_device_reference(device);
                    710: 
                    711:        /*
                    712:         * And do the write ...
                    713:         *
                    714:         * device_write_dealoc returns false if there's more
                    715:         * to do; it has updated the ior appropriately and expects
                    716:         * its caller to reinvoke it on the device.
                    717:         */
                    718: 
                    719:        do {
                    720: 
                    721:                result = (*device->dev_ops->d_write)(device->dev_number, ior);
                    722: 
                    723:                /*
                    724:                 * If the IO was queued, delay reply until it is finished.
                    725:                 */
                    726:                if (result == D_IO_QUEUED)
                    727:                    return (MIG_NO_REPLY);
                    728: 
                    729:                /*
                    730:                 * Discard the local mapping of the data.
                    731:                 */
                    732: 
                    733:        } while (!device_write_dealloc(ior));
                    734: 
                    735:        /*
                    736:         * Return the number of bytes actually written.
                    737:         */
                    738:        *bytes_written = ior->io_total - ior->io_residual;
                    739: 
                    740:        /*
                    741:         * Remove the extra reference.
                    742:         */
                    743:        mach_device_deallocate(device);
                    744: 
                    745:        io_req_free(ior);
                    746:        return (result);
                    747: }
                    748: 
                    749: /*
                    750:  * Write to a device, but memory is in message.
                    751:  */
                    752: static io_return_t
1.1.1.4   root      753: device_write_inband(device, reply_port, reply_port_type, mode, recnum,
1.1       root      754:                    data, data_count, bytes_written)
1.1.1.4   root      755:        mach_device_t           device;
1.1.1.5 ! root      756:        const ipc_port_t        reply_port;
1.1       root      757:        mach_msg_type_name_t    reply_port_type;
                    758:        dev_mode_t              mode;
                    759:        recnum_t                recnum;
                    760:        io_buf_ptr_inband_t     data;
                    761:        unsigned int            data_count;
                    762:        int                     *bytes_written; /* out */
                    763: {
1.1.1.4   root      764:        io_req_t                ior;
                    765:        io_return_t             result;
1.1       root      766: 
                    767:        if (device->state != DEV_STATE_OPEN)
                    768:            return (D_NO_SUCH_DEVICE);
                    769: 
                    770:        /* XXX note that a CLOSE may proceed at any point */
                    771: 
                    772:        /*
                    773:         * Package the write request for the device driver.
                    774:         */
                    775:        io_req_alloc(ior, 0);
                    776: 
                    777:        ior->io_device          = device;
                    778:        ior->io_unit            = device->dev_number;
                    779:        ior->io_op              = IO_WRITE | IO_CALL | IO_INBAND;
                    780:        ior->io_mode            = mode;
                    781:        ior->io_recnum          = recnum;
                    782:        ior->io_data            = data;
                    783:        ior->io_count           = data_count;
                    784:        ior->io_total           = data_count;
                    785:        ior->io_alloc_size      = 0;
                    786:        ior->io_residual        = 0;
                    787:        ior->io_error           = 0;
                    788:        ior->io_done            = ds_write_done;
                    789:        ior->io_reply_port      = reply_port;
                    790:        ior->io_reply_port_type = reply_port_type;
                    791: 
                    792:        /*
                    793:         * The ior keeps an extra reference for the device.
                    794:         */
                    795:        mach_device_reference(device);
                    796: 
                    797:        /*
                    798:         * And do the write.
                    799:         */
                    800:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
                    801: 
                    802:        /*
                    803:         * If the IO was queued, delay reply until it is finished.
                    804:         */
                    805:        if (result == D_IO_QUEUED)
                    806:            return (MIG_NO_REPLY);
                    807: 
                    808:        /*
                    809:         * Return the number of bytes actually written.
                    810:         */
                    811:        *bytes_written = ior->io_total - ior->io_residual;
                    812: 
                    813:        /*
                    814:         * Remove the extra reference.
                    815:         */
                    816:        mach_device_deallocate(device);
                    817: 
                    818:        io_req_free(ior);
                    819:        return (result);
                    820: }
                    821: 
                    822: /*
                    823:  * Wire down incoming memory to give to device.
                    824:  */
                    825: kern_return_t
1.1.1.5 ! root      826: device_write_get(
        !           827:        io_req_t                ior,
        !           828:        boolean_t               *wait)
1.1       root      829: {
                    830:        vm_map_copy_t           io_copy;
                    831:        vm_offset_t             new_addr;
1.1.1.4   root      832:        kern_return_t           result;
1.1       root      833:        int                     bsize;
                    834:        vm_size_t               min_size;
                    835: 
                    836:        /*
                    837:         * By default, caller does not have to wait.
                    838:         */
                    839:        *wait = FALSE;
                    840: 
                    841:        /*
                    842:         * Nothing to do if no data.
                    843:         */
                    844:        if (ior->io_count == 0)
                    845:            return (KERN_SUCCESS);
                    846: 
                    847:        /*
                    848:         * Loaned iors already have valid data.
                    849:         */
                    850:        if (ior->io_op & IO_LOANED)
                    851:            return (KERN_SUCCESS);
                    852: 
                    853:        /*
                    854:         * Inband case.
                    855:         */
                    856:        if (ior->io_op & IO_INBAND) {
                    857:            assert(ior->io_count <= sizeof (io_buf_ptr_inband_t));
1.1.1.4   root      858:            new_addr = kmem_cache_alloc(&io_inband_cache);
                    859:            memcpy((void*)new_addr, ior->io_data, ior->io_count);
1.1       root      860:            ior->io_data = (io_buf_ptr_t)new_addr;
                    861:            ior->io_alloc_size = sizeof (io_buf_ptr_inband_t);
                    862: 
                    863:            return (KERN_SUCCESS);
                    864:        }
                    865: 
                    866:        /*
                    867:         *      Figure out how much data to move this time.  If the device
                    868:         *      won't return a block size, then we have to do the whole
                    869:         *      request in one shot (ditto if this is a block fragment),
                    870:         *      otherwise, move at least one block's worth.
                    871:         */
                    872:        result = (*ior->io_device->dev_ops->d_dev_info)(
                    873:                                        ior->io_device->dev_number,
                    874:                                        D_INFO_BLOCK_SIZE,
                    875:                                        &bsize);
                    876: 
                    877:        if (result != KERN_SUCCESS || ior->io_count < (vm_size_t) bsize)
                    878:                min_size = (vm_size_t) ior->io_count;
                    879:        else
                    880:                min_size = (vm_size_t) bsize;
                    881: 
                    882:        /*
                    883:         *      Map the pages from this page list into memory.
                    884:         *      io_data records location of data.
                    885:         *      io_alloc_size is the vm size of the region to deallocate.
                    886:         */
                    887:        io_copy = (vm_map_copy_t) ior->io_data;
                    888:        result = kmem_io_map_copyout(device_io_map,
                    889:                        (vm_offset_t*)&ior->io_data, &new_addr,
                    890:                        &ior->io_alloc_size, io_copy, min_size);
                    891:        if (result != KERN_SUCCESS)
                    892:            return (result);
                    893: 
1.1.1.2   root      894:        if ((ior->io_data + ior->io_count) >
1.1       root      895:            (((char *)new_addr) + ior->io_alloc_size)) {
                    896: 
                    897:                /*
                    898:                 *      Operation has to be split.  Reset io_count for how
                    899:                 *      much we can do this time.
                    900:                 */
                    901:                assert(vm_map_copy_has_cont(io_copy));
                    902:                assert(ior->io_count == io_copy->size);
                    903:                ior->io_count = ior->io_alloc_size -
                    904:                        (ior->io_data - ((char *)new_addr));
                    905: 
                    906:                /*
                    907:                 *      Caller must wait synchronously.
                    908:                 */
                    909:                ior->io_op &= ~IO_CALL;
1.1.1.2   root      910:                *wait = TRUE;
1.1       root      911:        }
                    912: 
                    913:        ior->io_copy = io_copy;                 /* vm_map_copy to discard */
                    914:        return (KERN_SUCCESS);
                    915: }
                    916: 
                    917: /*
                    918:  * Clean up memory allocated for IO.
                    919:  */
                    920: boolean_t
1.1.1.5 ! root      921: device_write_dealloc(io_req_t ior)
1.1       root      922: {
                    923:        vm_map_copy_t   new_copy = VM_MAP_COPY_NULL;
                    924:        vm_map_copy_t   io_copy;
                    925:        kern_return_t   result;
                    926:        vm_offset_t     size_to_do;
1.1.1.2   root      927:        int             bsize;
1.1       root      928: 
                    929:        if (ior->io_alloc_size == 0)
                    930:            return (TRUE);
                    931: 
                    932:        /*
                    933:         * Inband case.
                    934:         */
                    935:        if (ior->io_op & IO_INBAND) {
1.1.1.4   root      936:            kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data);
1.1       root      937: 
                    938:            return (TRUE);
                    939:        }
1.1.1.2   root      940: 
1.1       root      941:        if ((io_copy = ior->io_copy) == VM_MAP_COPY_NULL)
                    942:            return (TRUE);
                    943: 
                    944:        /*
                    945:         *      To prevent a possible deadlock with the default pager,
                    946:         *      we have to release space in the device_io_map before
                    947:         *      we allocate any memory.  (Which vm_map_copy_invoke_cont
1.1.1.4   root      948:         *      might do.)  See the discussion in mach_device_init.
1.1       root      949:         */
                    950: 
                    951:        kmem_io_map_deallocate(device_io_map,
                    952:                         trunc_page(ior->io_data),
1.1.1.4   root      953:                         ior->io_alloc_size);
1.1       root      954: 
                    955:        if (vm_map_copy_has_cont(io_copy)) {
                    956: 
                    957:                /*
1.1.1.2   root      958:                 *      Remember how much is left, then
1.1       root      959:                 *      invoke or abort the continuation.
                    960:                 */
                    961:                size_to_do = io_copy->size - ior->io_count;
                    962:                if (ior->io_error == 0) {
                    963:                        vm_map_copy_invoke_cont(io_copy, &new_copy, &result);
                    964:                }
                    965:                else {
                    966:                        vm_map_copy_abort_cont(io_copy);
                    967:                        result = KERN_FAILURE;
                    968:                }
                    969: 
                    970:                if (result == KERN_SUCCESS && new_copy != VM_MAP_COPY_NULL) {
1.1.1.4   root      971:                        int             res;
1.1       root      972: 
                    973:                        /*
                    974:                         *      We have a new continuation, reset the ior to
                    975:                         *      represent the remainder of the request.  Must
                    976:                         *      adjust the recnum because drivers assume
                    977:                         *      that the residual is zero.
                    978:                         */
                    979:                        ior->io_op &= ~IO_DONE;
                    980:                        ior->io_op |= IO_CALL;
                    981: 
                    982:                        res = (*ior->io_device->dev_ops->d_dev_info)(
                    983:                                        ior->io_device->dev_number,
                    984:                                        D_INFO_BLOCK_SIZE,
                    985:                                        &bsize);
                    986: 
                    987:                        if (res != D_SUCCESS)
                    988:                                panic("device_write_dealloc: No block size");
1.1.1.2   root      989: 
1.1       root      990:                        ior->io_recnum += ior->io_count/bsize;
                    991:                        ior->io_count = new_copy->size;
                    992:                }
                    993:                else {
                    994: 
                    995:                        /*
                    996:                         *      No continuation.  Add amount we didn't get
                    997:                         *      to into residual.
                    998:                         */
                    999:                        ior->io_residual += size_to_do;
                   1000:                }
                   1001:        }
                   1002: 
                   1003:        /*
                   1004:         *      Clean up the state for the IO that just completed.
                   1005:         */
                   1006:         vm_map_copy_discard(ior->io_copy);
                   1007:        ior->io_copy = VM_MAP_COPY_NULL;
                   1008:        ior->io_data = (char *) new_copy;
                   1009: 
                   1010:        /*
                   1011:         *      Return FALSE if there's more IO to do.
                   1012:         */
                   1013: 
                   1014:        return(new_copy == VM_MAP_COPY_NULL);
                   1015: }
                   1016: 
                   1017: /*
                   1018:  * Send write completion message to client, and discard the data.
                   1019:  */
                   1020: boolean_t
                   1021: ds_write_done(ior)
1.1.1.5 ! root     1022:        const io_req_t          ior;
1.1       root     1023: {
                   1024:        /*
                   1025:         *      device_write_dealloc discards the data that has been
                   1026:         *      written, but may decide that there is more to write.
                   1027:         */
                   1028:        while (!device_write_dealloc(ior)) {
1.1.1.4   root     1029:                io_return_t             result;
                   1030:                mach_device_t           device;
1.1       root     1031: 
                   1032:                /*
                   1033:                 *     More IO to do -- invoke it.
                   1034:                 */
                   1035:                device = ior->io_device;
                   1036:                result = (*device->dev_ops->d_write)(device->dev_number, ior);
                   1037: 
                   1038:                /*
                   1039:                 * If the IO was queued, return FALSE -- not done yet.
                   1040:                 */
                   1041:                if (result == D_IO_QUEUED)
                   1042:                    return (FALSE);
                   1043:        }
                   1044: 
                   1045:        /*
                   1046:         *      Now the write is really complete.  Send reply.
                   1047:         */
                   1048: 
                   1049:        if (IP_VALID(ior->io_reply_port)) {
                   1050:            (void) (*((ior->io_op & IO_INBAND) ?
                   1051:                      ds_device_write_reply_inband :
                   1052:                      ds_device_write_reply))(ior->io_reply_port,
                   1053:                                              ior->io_reply_port_type,
                   1054:                                              ior->io_error,
                   1055:                                              (int) (ior->io_total -
                   1056:                                                     ior->io_residual));
                   1057:        }
                   1058:        mach_device_deallocate(ior->io_device);
                   1059: 
                   1060:        return (TRUE);
                   1061: }
                   1062: 
                   1063: /*
                   1064:  * Read from a device.
                   1065:  */
                   1066: static io_return_t
1.1.1.4   root     1067: device_read(device, reply_port, reply_port_type, mode, recnum,
1.1       root     1068:            bytes_wanted, data, data_count)
1.1.1.4   root     1069:        mach_device_t           device;
1.1.1.5 ! root     1070:        const ipc_port_t        reply_port;
1.1       root     1071:        mach_msg_type_name_t    reply_port_type;
                   1072:        dev_mode_t              mode;
                   1073:        recnum_t                recnum;
                   1074:        int                     bytes_wanted;
                   1075:        io_buf_ptr_t            *data;          /* out */
                   1076:        unsigned int            *data_count;    /* out */
                   1077: {
1.1.1.4   root     1078:        io_req_t                ior;
                   1079:        io_return_t             result;
1.1       root     1080: 
                   1081:        if (device->state != DEV_STATE_OPEN)
                   1082:            return (D_NO_SUCH_DEVICE);
                   1083: 
                   1084:        /* XXX note that a CLOSE may proceed at any point */
                   1085: 
                   1086:        /*
                   1087:         * There must be a reply port.
                   1088:         */
                   1089:        if (!IP_VALID(reply_port)) {
                   1090:            printf("ds_* invalid reply port\n");
1.1.1.4   root     1091:            SoftDebugger("ds_* reply_port");
1.1       root     1092:            return (MIG_NO_REPLY);      /* no sense in doing anything */
                   1093:        }
                   1094: 
                   1095:        /*
                   1096:         * Package the read request for the device driver
                   1097:         */
                   1098:        io_req_alloc(ior, 0);
                   1099: 
                   1100:        ior->io_device          = device;
                   1101:        ior->io_unit            = device->dev_number;
                   1102:        ior->io_op              = IO_READ | IO_CALL;
                   1103:        ior->io_mode            = mode;
                   1104:        ior->io_recnum          = recnum;
                   1105:        ior->io_data            = 0;            /* driver must allocate data */
                   1106:        ior->io_count           = bytes_wanted;
                   1107:        ior->io_alloc_size      = 0;            /* no data allocated yet */
                   1108:        ior->io_residual        = 0;
                   1109:        ior->io_error           = 0;
                   1110:        ior->io_done            = ds_read_done;
                   1111:        ior->io_reply_port      = reply_port;
                   1112:        ior->io_reply_port_type = reply_port_type;
                   1113: 
                   1114:        /*
                   1115:         * The ior keeps an extra reference for the device.
                   1116:         */
                   1117:        mach_device_reference(device);
                   1118: 
                   1119:        /*
                   1120:         * And do the read.
                   1121:         */
                   1122:        result = (*device->dev_ops->d_read)(device->dev_number, ior);
                   1123: 
                   1124:        /*
                   1125:         * If the IO was queued, delay reply until it is finished.
                   1126:         */
                   1127:        if (result == D_IO_QUEUED)
                   1128:            return (MIG_NO_REPLY);
                   1129: 
                   1130:        /*
                   1131:         * Return result via ds_read_done.
                   1132:         */
                   1133:        ior->io_error = result;
                   1134:        (void) ds_read_done(ior);
                   1135:        io_req_free(ior);
                   1136: 
                   1137:        return (MIG_NO_REPLY);  /* reply has already been sent. */
                   1138: }
                   1139: 
                   1140: /*
                   1141:  * Read from a device, but return the data 'inband.'
                   1142:  */
                   1143: static io_return_t
1.1.1.4   root     1144: device_read_inband(device, reply_port, reply_port_type, mode, recnum,
1.1       root     1145:                   bytes_wanted, data, data_count)
1.1.1.4   root     1146:        mach_device_t           device;
1.1.1.5 ! root     1147:        const ipc_port_t        reply_port;
1.1       root     1148:        mach_msg_type_name_t    reply_port_type;
                   1149:        dev_mode_t              mode;
                   1150:        recnum_t                recnum;
                   1151:        int                     bytes_wanted;
                   1152:        char                    *data;          /* pointer to OUT array */
                   1153:        unsigned int            *data_count;    /* out */
                   1154: {
1.1.1.4   root     1155:        io_req_t                ior;
                   1156:        io_return_t             result;
1.1       root     1157: 
                   1158:        if (device->state != DEV_STATE_OPEN)
                   1159:            return (D_NO_SUCH_DEVICE);
                   1160: 
                   1161:        /* XXX note that a CLOSE may proceed at any point */
                   1162: 
                   1163:        /*
                   1164:         * There must be a reply port.
                   1165:         */
                   1166:        if (!IP_VALID(reply_port)) {
                   1167:            printf("ds_* invalid reply port\n");
1.1.1.4   root     1168:            SoftDebugger("ds_* reply_port");
1.1       root     1169:            return (MIG_NO_REPLY);      /* no sense in doing anything */
                   1170:        }
                   1171: 
                   1172:        /*
                   1173:         * Package the read for the device driver
                   1174:         */
                   1175:        io_req_alloc(ior, 0);
                   1176: 
                   1177:        ior->io_device          = device;
                   1178:        ior->io_unit            = device->dev_number;
                   1179:        ior->io_op              = IO_READ | IO_CALL | IO_INBAND;
                   1180:        ior->io_mode            = mode;
                   1181:        ior->io_recnum          = recnum;
                   1182:        ior->io_data            = 0;            /* driver must allocate data */
1.1.1.2   root     1183:        ior->io_count           =
1.1       root     1184:            ((bytes_wanted < sizeof(io_buf_ptr_inband_t)) ?
                   1185:                bytes_wanted : sizeof(io_buf_ptr_inband_t));
                   1186:        ior->io_alloc_size      = 0;            /* no data allocated yet */
                   1187:        ior->io_residual        = 0;
                   1188:        ior->io_error           = 0;
                   1189:        ior->io_done            = ds_read_done;
                   1190:        ior->io_reply_port      = reply_port;
                   1191:        ior->io_reply_port_type = reply_port_type;
                   1192: 
                   1193:        /*
                   1194:         * The ior keeps an extra reference for the device.
                   1195:         */
                   1196:        mach_device_reference(device);
                   1197: 
                   1198:        /*
                   1199:         * Do the read.
                   1200:         */
                   1201:        result = (*device->dev_ops->d_read)(device->dev_number, ior);
                   1202: 
                   1203:        /*
                   1204:         * If the io was queued, delay reply until it is finished.
                   1205:         */
                   1206:        if (result == D_IO_QUEUED)
                   1207:            return (MIG_NO_REPLY);
                   1208: 
                   1209:        /*
                   1210:         * Return result, via ds_read_done.
                   1211:         */
                   1212:        ior->io_error = result;
                   1213:        (void) ds_read_done(ior);
                   1214:        io_req_free(ior);
                   1215: 
                   1216:        return (MIG_NO_REPLY);  /* reply has already been sent. */
                   1217: }
                   1218: 
                   1219: /*
                   1220:  * Allocate wired-down memory for device read.
                   1221:  */
1.1.1.5 ! root     1222: kern_return_t device_read_alloc(
        !          1223:        io_req_t                ior,
        !          1224:        vm_size_t               size)
1.1       root     1225: {
                   1226:        vm_offset_t             addr;
                   1227:        kern_return_t           kr;
                   1228: 
                   1229:        /*
                   1230:         * Nothing to do if no data.
                   1231:         */
                   1232:        if (ior->io_count == 0)
                   1233:            return (KERN_SUCCESS);
                   1234: 
                   1235:        if (ior->io_op & IO_INBAND) {
1.1.1.4   root     1236:            ior->io_data = (io_buf_ptr_t) kmem_cache_alloc(&io_inband_cache);
1.1       root     1237:            ior->io_alloc_size = sizeof(io_buf_ptr_inband_t);
                   1238:        } else {
                   1239:            size = round_page(size);
                   1240:            kr = kmem_alloc(kernel_map, &addr, size);
                   1241:            if (kr != KERN_SUCCESS)
                   1242:                return (kr);
                   1243: 
                   1244:            ior->io_data = (io_buf_ptr_t) addr;
                   1245:            ior->io_alloc_size = size;
                   1246:        }
                   1247: 
                   1248:        return (KERN_SUCCESS);
                   1249: }
                   1250: 
                   1251: boolean_t ds_read_done(ior)
1.1.1.5 ! root     1252:        const io_req_t  ior;
1.1       root     1253: {
                   1254:        vm_offset_t             start_data, end_data;
                   1255:        vm_offset_t             start_sent, end_sent;
1.1.1.4   root     1256:        vm_size_t               size_read;
1.1       root     1257: 
                   1258:        if (ior->io_error)
                   1259:            size_read = 0;
                   1260:        else
                   1261:            size_read = ior->io_count - ior->io_residual;
                   1262: 
                   1263:        start_data  = (vm_offset_t)ior->io_data;
                   1264:        end_data    = start_data + size_read;
                   1265: 
                   1266:        start_sent  = (ior->io_op & IO_INBAND) ? start_data :
                   1267:                                                trunc_page(start_data);
1.1.1.2   root     1268:        end_sent    = (ior->io_op & IO_INBAND) ?
1.1       root     1269:                start_data + ior->io_alloc_size : round_page(end_data);
                   1270: 
                   1271:        /*
                   1272:         * Zero memory that the device did not fill.
                   1273:         */
                   1274:        if (start_sent < start_data)
1.1.1.5 ! root     1275:            memset((void *)start_sent, 0, start_data - start_sent);
1.1       root     1276:        if (end_sent > end_data)
1.1.1.5 ! root     1277:            memset((void *)end_data, 0, end_sent - end_data);
1.1       root     1278: 
                   1279: 
                   1280:        /*
                   1281:         * Touch the data being returned, to mark it dirty.
                   1282:         * If the pages were filled by DMA, the pmap module
                   1283:         * may think that they are clean.
                   1284:         */
                   1285:        {
1.1.1.4   root     1286:            vm_offset_t                 touch;
                   1287:            int                         c;
1.1       root     1288: 
                   1289:            for (touch = start_sent; touch < end_sent; touch += PAGE_SIZE) {
1.1.1.2   root     1290:                c = *(volatile char *)touch;
                   1291:                *(volatile char *)touch = c;
1.1       root     1292:            }
                   1293:        }
                   1294: 
                   1295:        /*
                   1296:         * Send the data to the reply port - this
                   1297:         * unwires and deallocates it.
                   1298:         */
                   1299:        if (ior->io_op & IO_INBAND) {
                   1300:            (void)ds_device_read_reply_inband(ior->io_reply_port,
                   1301:                                              ior->io_reply_port_type,
                   1302:                                              ior->io_error,
                   1303:                                              (char *) start_data,
                   1304:                                              size_read);
                   1305:        } else {
                   1306:            vm_map_copy_t copy;
                   1307:            kern_return_t kr;
                   1308: 
                   1309:            kr = vm_map_copyin_page_list(kernel_map, start_data,
                   1310:                                                 size_read, TRUE, TRUE,
                   1311:                                                 &copy, FALSE);
                   1312: 
                   1313:            if (kr != KERN_SUCCESS)
                   1314:                panic("read_done: vm_map_copyin_page_list failed");
                   1315: 
                   1316:            (void)ds_device_read_reply(ior->io_reply_port,
                   1317:                                       ior->io_reply_port_type,
                   1318:                                       ior->io_error,
                   1319:                                       (char *) copy,
                   1320:                                       size_read);
                   1321:        }
                   1322: 
                   1323:        /*
                   1324:         * Free any memory that was allocated but not sent.
                   1325:         */
                   1326:        if (ior->io_count != 0) {
                   1327:            if (ior->io_op & IO_INBAND) {
                   1328:                if (ior->io_alloc_size > 0)
1.1.1.4   root     1329:                    kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data);
1.1       root     1330:            } else {
1.1.1.4   root     1331:                vm_offset_t             end_alloc;
1.1       root     1332: 
                   1333:                end_alloc = start_sent + round_page(ior->io_alloc_size);
                   1334:                if (end_alloc > end_sent)
                   1335:                    (void) vm_deallocate(kernel_map,
                   1336:                                         end_sent,
                   1337:                                         end_alloc - end_sent);
                   1338:            }
                   1339:        }
                   1340: 
                   1341:        mach_device_deallocate(ior->io_device);
                   1342: 
                   1343:        return (TRUE);
                   1344: }
                   1345: 
                   1346: static io_return_t
1.1.1.5 ! root     1347: device_set_status(
        !          1348:        mach_device_t           device,
        !          1349:        dev_flavor_t            flavor,
        !          1350:        dev_status_t            status,
        !          1351:        mach_msg_type_number_t  status_count)
1.1       root     1352: {
                   1353:        if (device->state != DEV_STATE_OPEN)
                   1354:            return (D_NO_SUCH_DEVICE);
                   1355: 
                   1356:        /* XXX note that a CLOSE may proceed at any point */
                   1357: 
                   1358:        return ((*device->dev_ops->d_setstat)(device->dev_number,
                   1359:                                              flavor,
                   1360:                                              status,
                   1361:                                              status_count));
                   1362: }
                   1363: 
                   1364: io_return_t
1.1.1.5 ! root     1365: mach_device_get_status(
        !          1366:        mach_device_t           device,
        !          1367:        dev_flavor_t            flavor,
        !          1368:        dev_status_t            status,         /* pointer to OUT array */
        !          1369:        mach_msg_type_number_t  *status_count)  /* out */
1.1       root     1370: {
                   1371:        if (device->state != DEV_STATE_OPEN)
                   1372:            return (D_NO_SUCH_DEVICE);
                   1373: 
                   1374:        /* XXX note that a CLOSE may proceed at any point */
                   1375: 
                   1376:        return ((*device->dev_ops->d_getstat)(device->dev_number,
                   1377:                                              flavor,
                   1378:                                              status,
                   1379:                                              status_count));
                   1380: }
                   1381: 
                   1382: static io_return_t
1.1.1.4   root     1383: device_set_filter(device, receive_port, priority, filter, filter_count)
                   1384:        mach_device_t           device;
1.1.1.5 ! root     1385:        const ipc_port_t        receive_port;
1.1       root     1386:        int                     priority;
                   1387:        filter_t                filter[];       /* pointer to IN array */
                   1388:        unsigned int            filter_count;
                   1389: {
                   1390:        if (device->state != DEV_STATE_OPEN)
                   1391:            return (D_NO_SUCH_DEVICE);
                   1392: 
                   1393:        /* XXX note that a CLOSE may proceed at any point */
                   1394: 
                   1395:        /*
                   1396:         * Request is absurd if no receive port is specified.
                   1397:         */
                   1398:        if (!IP_VALID(receive_port))
                   1399:            return (D_INVALID_OPERATION);
                   1400: 
                   1401:        return ((*device->dev_ops->d_async_in)(device->dev_number,
                   1402:                                               receive_port,
                   1403:                                               priority,
                   1404:                                               filter,
                   1405:                                               filter_count));
                   1406: }
                   1407: 
                   1408: static io_return_t
1.1.1.5 ! root     1409: device_map(
        !          1410:        mach_device_t           device,
        !          1411:        vm_prot_t               protection,
        !          1412:        vm_offset_t             offset,
        !          1413:        vm_size_t               size,
        !          1414:        ipc_port_t              *pager, /* out */
        !          1415:        boolean_t               unmap)  /* ? */
1.1       root     1416: {
                   1417:        if (protection & ~VM_PROT_ALL)
                   1418:                return (KERN_INVALID_ARGUMENT);
                   1419: 
                   1420:        if (device->state != DEV_STATE_OPEN)
                   1421:            return (D_NO_SUCH_DEVICE);
                   1422: 
                   1423:        /* XXX note that a CLOSE may proceed at any point */
                   1424: 
                   1425:        return (device_pager_setup(device, protection, offset, size,
                   1426:                                    (mach_port_t*)pager));
                   1427: }
                   1428: 
                   1429: /*
                   1430:  * Doesn't do anything (yet).
                   1431:  */
                   1432: static void
                   1433: ds_no_senders(notification)
1.1.1.5 ! root     1434:        const mach_no_senders_notification_t *notification;
1.1       root     1435: {
1.1.1.4   root     1436:        printf("ds_no_senders called! device_port=0x%lx count=%d\n",
1.1       root     1437:               notification->not_header.msgh_remote_port,
                   1438:               notification->not_count);
                   1439: }
                   1440: 
                   1441: queue_head_t           io_done_list;
                   1442: decl_simple_lock_data(,        io_done_list_lock)
                   1443: 
                   1444: #define        splio   splsched        /* XXX must block ALL io devices */
                   1445: 
1.1.1.5 ! root     1446: void iodone(io_req_t ior)
1.1       root     1447: {
1.1.1.4   root     1448:        spl_t                   s;
1.1       root     1449: 
                   1450:        /*
                   1451:         * If this ior was loaned to us, return it directly.
                   1452:         */
                   1453:        if (ior->io_op & IO_LOANED) {
                   1454:                (*ior->io_done)(ior);
                   1455:                return;
                   1456:        }
                   1457:        /*
                   1458:         * If !IO_CALL, some thread is waiting for this.  Must lock
                   1459:         * structure to interlock correctly with iowait().  Else can
                   1460:         * toss on queue for io_done thread to call completion.
                   1461:         */
                   1462:        s = splio();
                   1463:        if ((ior->io_op & IO_CALL) == 0) {
                   1464:            ior_lock(ior);
                   1465:            ior->io_op |= IO_DONE;
                   1466:            ior->io_op &= ~IO_WANTED;
                   1467:            ior_unlock(ior);
                   1468:            thread_wakeup((event_t)ior);
                   1469:        } else {
                   1470:            ior->io_op |= IO_DONE;
                   1471:            simple_lock(&io_done_list_lock);
                   1472:            enqueue_tail(&io_done_list, (queue_entry_t)ior);
                   1473:            thread_wakeup((event_t)&io_done_list);
                   1474:            simple_unlock(&io_done_list_lock);
                   1475:        }
                   1476:        splx(s);
                   1477: }
                   1478: 
1.1.1.5 ! root     1479: void  __attribute__ ((noreturn)) io_done_thread_continue(void)
1.1       root     1480: {
                   1481:        for (;;) {
1.1.1.4   root     1482:            spl_t               s;
                   1483:            io_req_t            ior;
1.1       root     1484: 
1.1.1.4   root     1485: #if defined (LINUX_DEV) && defined (CONFIG_INET)
1.1       root     1486:            free_skbuffs ();
                   1487: #endif
                   1488:            s = splio();
                   1489:            simple_lock(&io_done_list_lock);
                   1490:            while ((ior = (io_req_t)dequeue_head(&io_done_list)) != 0) {
                   1491:                simple_unlock(&io_done_list_lock);
                   1492:                (void) splx(s);
                   1493: 
                   1494:                if ((*ior->io_done)(ior)) {
                   1495:                    /*
                   1496:                     * IO done - free io_req_elt
                   1497:                     */
                   1498:                    io_req_free(ior);
                   1499:                }
                   1500:                /* else routine has re-queued it somewhere */
                   1501: 
                   1502:                s = splio();
                   1503:                simple_lock(&io_done_list_lock);
                   1504:            }
                   1505: 
                   1506:            assert_wait(&io_done_list, FALSE);
                   1507:            simple_unlock(&io_done_list_lock);
                   1508:            (void) splx(s);
                   1509:            counter(c_io_done_thread_block++);
                   1510:            thread_block(io_done_thread_continue);
                   1511:        }
                   1512: }
                   1513: 
1.1.1.5 ! root     1514: void io_done_thread(void)
1.1       root     1515: {
                   1516:        /*
                   1517:         * Set thread privileges and highest priority.
                   1518:         */
                   1519:        current_thread()->vm_privilege = TRUE;
                   1520:        stack_privilege(current_thread());
                   1521:        thread_set_own_priority(0);
                   1522: 
                   1523:        io_done_thread_continue();
                   1524:        /*NOTREACHED*/
                   1525: }
                   1526: 
1.1.1.4   root     1527: #define        DEVICE_IO_MAP_SIZE      (16 * 1024 * 1024)
1.1       root     1528: 
1.1.1.4   root     1529: static void mach_device_trap_init(void);               /* forward */
1.1       root     1530: 
1.1.1.5 ! root     1531: void mach_device_init(void)
1.1       root     1532: {
                   1533:        vm_offset_t     device_io_min, device_io_max;
                   1534: 
                   1535:        queue_init(&io_done_list);
                   1536:        simple_lock_init(&io_done_list_lock);
                   1537: 
1.1.1.4   root     1538:        kmem_submap(device_io_map, kernel_map, &device_io_min, &device_io_max,
                   1539:                    DEVICE_IO_MAP_SIZE, FALSE);
                   1540: 
1.1       root     1541:        /*
                   1542:         *      If the kernel receives many device_write requests, the
                   1543:         *      device_io_map might run out of space.  To prevent
                   1544:         *      device_write_get from failing in this case, we enable
                   1545:         *      wait_for_space on the map.  This causes kmem_io_map_copyout
                   1546:         *      to block until there is sufficient space.
                   1547:         *      (XXX Large writes may be starved by small writes.)
                   1548:         *
                   1549:         *      There is a potential deadlock problem with this solution,
                   1550:         *      if a device_write from the default pager has to wait
                   1551:         *      for the completion of a device_write which needs to wait
                   1552:         *      for memory allocation.  Hence, once device_write_get
                   1553:         *      allocates space in device_io_map, no blocking memory
                   1554:         *      allocations should happen until device_write_dealloc
                   1555:         *      frees the space.  (XXX A large write might starve
                   1556:         *      a small write from the default pager.)
                   1557:         */
                   1558:        device_io_map->wait_for_space = TRUE;
                   1559: 
1.1.1.4   root     1560:        kmem_cache_init(&io_inband_cache, "io_buf_ptr_inband",
                   1561:                        sizeof(io_buf_ptr_inband_t), 0, NULL, NULL, NULL, 0);
1.1       root     1562: 
1.1.1.4   root     1563:        mach_device_trap_init();
1.1       root     1564: }
                   1565: 
1.1.1.5 ! root     1566: void iowait(io_req_t ior)
1.1       root     1567: {
                   1568:     spl_t s;
                   1569: 
                   1570:     s = splio();
                   1571:     ior_lock(ior);
                   1572:     while ((ior->io_op&IO_DONE)==0) {
                   1573:        assert_wait((event_t)ior, FALSE);
                   1574:        ior_unlock(ior);
                   1575:        thread_block((void (*)()) 0);
                   1576:         ior_lock(ior);
                   1577:     }
                   1578:     ior_unlock(ior);
                   1579:     splx(s);
                   1580: }
                   1581: 
                   1582: 
                   1583: /*
                   1584:  * Device trap support.
                   1585:  */
                   1586: 
                   1587: /*
                   1588:  * Memory Management
                   1589:  *
                   1590:  * This currently has a single pool of 2k wired buffers
                   1591:  * since we only handle writes to an ethernet device.
                   1592:  * Should be more general.
                   1593:  */
                   1594: #define IOTRAP_REQSIZE 2048
                   1595: 
1.1.1.4   root     1596: struct kmem_cache io_trap_cache;
1.1       root     1597: 
                   1598: /*
1.1.1.4   root     1599:  * Initialization.  Called from mach_device_init().
1.1       root     1600:  */
1.1.1.4   root     1601: static void
                   1602: mach_device_trap_init(void)
1.1       root     1603: {
1.1.1.4   root     1604:        kmem_cache_init(&io_trap_cache, "io_req", IOTRAP_REQSIZE, 0,
                   1605:                        NULL, NULL, NULL, 0);
1.1       root     1606: }
                   1607: 
                   1608: /*
                   1609:  * Allocate an io_req_t.
1.1.1.4   root     1610:  * Currently allocates from io_trap_cache.
1.1       root     1611:  *
1.1.1.4   root     1612:  * Could have lists of different size caches.
1.1       root     1613:  * Could call a device-specific routine.
                   1614:  */
                   1615: io_req_t
1.1.1.5 ! root     1616: ds_trap_req_alloc(const mach_device_t device, vm_size_t data_size)
1.1       root     1617: {
1.1.1.4   root     1618:        return (io_req_t) kmem_cache_alloc(&io_trap_cache);
1.1       root     1619: }
                   1620: 
                   1621: /*
                   1622:  * Called by iodone to release ior.
                   1623:  */
                   1624: boolean_t
1.1.1.5 ! root     1625: ds_trap_write_done(const io_req_t ior)
1.1       root     1626: {
1.1.1.4   root     1627:        mach_device_t   dev;
1.1       root     1628: 
                   1629:        dev = ior->io_device;
                   1630: 
                   1631:        /*
                   1632:         * Should look at reply port and maybe send a message.
                   1633:         */
1.1.1.4   root     1634:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1.1.2   root     1635: 
1.1       root     1636:        /*
                   1637:         * Give up device reference from ds_write_trap.
                   1638:         */
                   1639:        mach_device_deallocate(dev);
                   1640:        return TRUE;
                   1641: }
                   1642: 
                   1643: /*
                   1644:  * Like device_write except that data is in user space.
                   1645:  */
                   1646: static io_return_t
1.1.1.4   root     1647: device_write_trap (mach_device_t device, dev_mode_t mode,
1.1       root     1648:                   recnum_t recnum, vm_offset_t data, vm_size_t data_count)
                   1649: {
                   1650:        io_req_t ior;
                   1651:        io_return_t result;
                   1652: 
                   1653:        if (device->state != DEV_STATE_OPEN)
                   1654:                return (D_NO_SUCH_DEVICE);
1.1.1.2   root     1655: 
1.1       root     1656:        /* XXX note that a CLOSE may proceed at any point */
1.1.1.2   root     1657: 
1.1       root     1658:        /*
                   1659:         * Get a buffer to hold the ioreq.
                   1660:         */
                   1661:        ior = ds_trap_req_alloc(device, data_count);
1.1.1.2   root     1662: 
1.1       root     1663:        /*
                   1664:         * Package the write request for the device driver.
                   1665:         */
                   1666: 
                   1667:        ior->io_device          = device;
                   1668:        ior->io_unit            = device->dev_number;
                   1669:        ior->io_op              = IO_WRITE | IO_CALL | IO_LOANED;
                   1670:        ior->io_mode            = mode;
                   1671:        ior->io_recnum          = recnum;
                   1672:        ior->io_data            = (io_buf_ptr_t)
                   1673:                (vm_offset_t)ior + sizeof(struct io_req);
                   1674:        ior->io_count           = data_count;
                   1675:        ior->io_total           = data_count;
                   1676:        ior->io_alloc_size      = 0;
                   1677:        ior->io_residual        = 0;
                   1678:        ior->io_error           = 0;
                   1679:        ior->io_done            = ds_trap_write_done;
                   1680:        ior->io_reply_port      = IP_NULL;      /* XXX */
                   1681:        ior->io_reply_port_type = 0;            /* XXX */
                   1682: 
                   1683:        /*
                   1684:         * Copy the data from user space.
                   1685:         */
                   1686:        if (data_count > 0)
1.1.1.5 ! root     1687:                copyin((void *)data, ior->io_data, data_count);
1.1.1.2   root     1688: 
1.1       root     1689:        /*
                   1690:         * The ior keeps an extra reference for the device.
                   1691:         */
                   1692:        mach_device_reference(device);
1.1.1.2   root     1693: 
1.1       root     1694:        /*
                   1695:         * And do the write.
                   1696:         */
                   1697:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
1.1.1.2   root     1698: 
1.1       root     1699:        /*
                   1700:         * If the IO was queued, delay reply until it is finished.
                   1701:         */
                   1702:        if (result == D_IO_QUEUED)
                   1703:                return (MIG_NO_REPLY);
1.1.1.2   root     1704: 
1.1       root     1705:        /*
                   1706:         * Remove the extra reference.
                   1707:         */
                   1708:        mach_device_deallocate(device);
1.1.1.2   root     1709: 
1.1.1.4   root     1710:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1       root     1711:        return (result);
                   1712: }
                   1713: 
                   1714: static io_return_t
1.1.1.4   root     1715: device_writev_trap (mach_device_t device, dev_mode_t mode,
1.1       root     1716:                    recnum_t recnum, io_buf_vec_t *iovec, vm_size_t iocount)
                   1717: {
                   1718:        io_req_t ior;
                   1719:        io_return_t result;
                   1720:        io_buf_vec_t    stack_iovec[16]; /* XXX */
                   1721:        vm_size_t data_count;
                   1722:        int i;
                   1723: 
                   1724:        if (device->state != DEV_STATE_OPEN)
                   1725:                return (D_NO_SUCH_DEVICE);
1.1.1.2   root     1726: 
1.1       root     1727:        /* XXX note that a CLOSE may proceed at any point */
1.1.1.2   root     1728: 
1.1       root     1729:        /*
                   1730:         * Copyin user addresses.
                   1731:         */
                   1732:        if (iocount > 16)
                   1733:                return KERN_INVALID_VALUE; /* lame */
1.1.1.5 ! root     1734:        copyin(iovec,
        !          1735:               stack_iovec,
1.1       root     1736:               iocount * sizeof(io_buf_vec_t));
                   1737:        for (data_count = 0, i = 0; i < iocount; i++)
                   1738:                data_count += stack_iovec[i].count;
                   1739: 
                   1740:        /*
                   1741:         * Get a buffer to hold the ioreq.
                   1742:         */
                   1743:        ior = ds_trap_req_alloc(device, data_count);
1.1.1.2   root     1744: 
1.1       root     1745:        /*
                   1746:         * Package the write request for the device driver.
                   1747:         */
                   1748: 
                   1749:        ior->io_device          = device;
                   1750:        ior->io_unit            = device->dev_number;
                   1751:        ior->io_op              = IO_WRITE | IO_CALL | IO_LOANED;
                   1752:        ior->io_mode            = mode;
                   1753:        ior->io_recnum          = recnum;
                   1754:        ior->io_data            = (io_buf_ptr_t)
                   1755:                (vm_offset_t)ior + sizeof(struct io_req);
                   1756:        ior->io_count           = data_count;
                   1757:        ior->io_total           = data_count;
                   1758:        ior->io_alloc_size      = 0;
                   1759:        ior->io_residual        = 0;
                   1760:        ior->io_error           = 0;
                   1761:        ior->io_done            = ds_trap_write_done;
                   1762:        ior->io_reply_port      = IP_NULL;      /* XXX */
                   1763:        ior->io_reply_port_type = 0;            /* XXX */
                   1764: 
                   1765:        /*
                   1766:         * Copy the data from user space.
                   1767:         */
                   1768:        if (data_count > 0) {
                   1769:                vm_offset_t p;
                   1770: 
                   1771:                p = (vm_offset_t) ior->io_data;
                   1772:                for (i = 0; i < iocount; i++) {
1.1.1.5 ! root     1773:                        copyin((void *) stack_iovec[i].data,
        !          1774:                               (void *) p,
1.1       root     1775:                               stack_iovec[i].count);
                   1776:                        p += stack_iovec[i].count;
                   1777:                }
                   1778:        }
1.1.1.2   root     1779: 
1.1       root     1780:        /*
                   1781:         * The ior keeps an extra reference for the device.
                   1782:         */
                   1783:        mach_device_reference(device);
1.1.1.2   root     1784: 
1.1       root     1785:        /*
                   1786:         * And do the write.
                   1787:         */
                   1788:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
1.1.1.2   root     1789: 
1.1       root     1790:        /*
                   1791:         * If the IO was queued, delay reply until it is finished.
                   1792:         */
                   1793:        if (result == D_IO_QUEUED)
                   1794:                return (MIG_NO_REPLY);
1.1.1.2   root     1795: 
1.1       root     1796:        /*
                   1797:         * Remove the extra reference.
                   1798:         */
                   1799:        mach_device_deallocate(device);
1.1.1.2   root     1800: 
1.1.1.4   root     1801:        kmem_cache_free(&io_trap_cache, (vm_offset_t) ior);
1.1       root     1802:        return (result);
                   1803: }
                   1804: 
                   1805: struct device_emulation_ops mach_device_emulation_ops =
                   1806: {
1.1.1.4   root     1807:   (void*) mach_device_reference,
                   1808:   (void*) mach_device_deallocate,
                   1809:   (void*) mach_convert_device_to_port,
1.1       root     1810:   device_open,
                   1811:   device_close,
                   1812:   device_write,
                   1813:   device_write_inband,
                   1814:   device_read,
                   1815:   device_read_inband,
                   1816:   device_set_status,
                   1817:   mach_device_get_status,
                   1818:   device_set_filter,
                   1819:   device_map,
                   1820:   ds_no_senders,
1.1.1.4   root     1821:   (void*) device_write_trap,
                   1822:   (void*) device_writev_trap
1.1       root     1823: };

unix.superglobalmegacorp.com

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