Annotation of OSKit-Mach/oskit/ds_bus.c, revision 1.1

1.1     ! root        1: /* This is a total crock of shit.  */
        !             2: 
        !             3: #include "ds_oskit.h"
        !             4: 
        !             5: #include <oskit/error.h>
        !             6: #include <oskit/dev/bus.h>
        !             7: 
        !             8: #include <vm/vm_map.h>
        !             9: #include <vm/vm_kern.h>
        !            10: #include <vm/vm_page.h>
        !            11: 
        !            12: #include <string.h>
        !            13: 
        !            14: 
        !            15: oskit_error_t
        !            16: populate_bus (device_t dev, oskit_bus_t *bus)
        !            17: {
        !            18:   kern_return_t kr;
        !            19:   oskit_error_t rc;
        !            20:   unsigned int i;
        !            21:   char *p;
        !            22: 
        !            23:   /* First, we probe the bus so it knows what devices are on it.  */
        !            24:   rc = oskit_bus_probe (bus);
        !            25:   if (OSKIT_FAILED (rc) && rc != OSKIT_E_NOTIMPL)
        !            26:     return rc;
        !            27: 
        !            28:   /* Next, we will get a page of kernel memory to hold our ridiculous
        !            29:      text representation of the bus's device list.  */
        !            30: 
        !            31:   kr = kmem_alloc_pageable (kernel_map, (vm_offset_t *) &dev->com.bus.contents,
        !            32:                            PAGE_SIZE);
        !            33:   if (kr)
        !            34:     return OSKIT_E_OUTOFMEMORY;
        !            35: 
        !            36:   p = dev->com.bus.contents;
        !            37:   i = 0;
        !            38:   do
        !            39:     {
        !            40:       inline void append (char sep, const char *str)
        !            41:        {
        !            42:          extern char *stpcpy (char *, const char *);
        !            43:          if (str)
        !            44:            {
        !            45:              *p++ = sep;
        !            46:              p = stpcpy (p, str);
        !            47:            }
        !            48:        }
        !            49: 
        !            50:       char pos[OSKIT_BUS_POS_MAX];
        !            51:       oskit_device_t *child;
        !            52:       oskit_devinfo_t info;
        !            53: 
        !            54:       rc = oskit_bus_getchild (bus, i++, &child, pos);
        !            55:       if (rc == OSKIT_E_DEV_NOMORE_CHILDREN)
        !            56:        break;
        !            57:       if (OSKIT_SUCCEEDED (rc))
        !            58:        {
        !            59:          rc = oskit_device_getinfo (child, &info);
        !            60:          oskit_device_release (child);
        !            61:        }
        !            62:       if (OSKIT_FAILED (rc))
        !            63:        {
        !            64:          kmem_free (kernel_map,
        !            65:                     (vm_offset_t) dev->com.bus.contents, PAGE_SIZE);
        !            66:          return rc;
        !            67:        }
        !            68: 
        !            69:       append ('@', pos);
        !            70:       append (':', info.name);
        !            71:       append ('=', info.description);
        !            72:       append (';', info.author);
        !            73:       append ('/', info.version);
        !            74:       *p++ = '\n';
        !            75: 
        !            76:       assert (p < dev->com.bus.contents + PAGE_SIZE);
        !            77:     } while (rc == 0);
        !            78: 
        !            79:   dev->com.bus.size = p - dev->com.bus.contents;
        !            80:   memset (p, 0, PAGE_SIZE - dev->com.bus.size);
        !            81: 
        !            82:   return 0;
        !            83: }
        !            84: 
        !            85: void
        !            86: ds_bus_close (device_t dev)
        !            87: {
        !            88:   kmem_free (kernel_map, (vm_offset_t) dev->com.bus.contents, PAGE_SIZE);
        !            89: }
        !            90: 
        !            91: io_return_t
        !            92: ds_bus_read (device_t dev, ipc_port_t reply_port,
        !            93:             mach_msg_type_name_t reply_port_type, dev_mode_t mode,
        !            94:             recnum_t recnum, int count, io_buf_ptr_t *data,
        !            95:             unsigned *bytes_read)
        !            96: {
        !            97:   if (recnum % PAGE_SIZE != 0)
        !            98:     return D_INVALID_OPERATION;        /* let generic code use inband read */
        !            99: 
        !           100:   if (recnum + count > dev->com.bus.size)
        !           101:     INVALREC;
        !           102: 
        !           103:   if (count == 0)
        !           104:     {
        !           105:       *bytes_read = 0;
        !           106:       return D_SUCCESS;
        !           107:     }
        !           108: 
        !           109:   *bytes_read = count;
        !           110:   return vm_map_copyin_page_list (kernel_map,
        !           111:                                  (vm_offset_t) dev->com.bus.contents + recnum,
        !           112:                                  round_page (count),
        !           113:                                  FALSE, FALSE, (vm_map_copy_t *) data,
        !           114:                                  FALSE);
        !           115: }
        !           116: 
        !           117: io_return_t
        !           118: ds_bus_read_inband (device_t dev, ipc_port_t reply_port,
        !           119:                    mach_msg_type_name_t reply_port_type, dev_mode_t mode,
        !           120:                    recnum_t recnum, int count, char *data,
        !           121:                    unsigned *bytes_read)
        !           122: {
        !           123:   if (recnum + count > dev->com.bus.size)
        !           124:     INVALREC;
        !           125:   memcpy (data, dev->com.bus.contents + recnum, count);
        !           126:   *bytes_read = count;
        !           127:   return D_SUCCESS;
        !           128: }
        !           129: 
        !           130: io_return_t
        !           131: ds_bus_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status,
        !           132:                   mach_msg_type_number_t *status_count)
        !           133: {
        !           134:   switch (flavor)
        !           135:     {
        !           136:     case DEV_GET_SIZE:
        !           137:       status[DEV_GET_SIZE_RECORD_SIZE] = 1;
        !           138:       status[DEV_GET_SIZE_DEVICE_SIZE] = dev->com.bus.size;
        !           139:       *status_count = 2;
        !           140:       return D_SUCCESS;
        !           141:     }
        !           142:   INVALOP;
        !           143: }
        !           144: 
        !           145: 
        !           146: const struct device_ops bus_device_ops =
        !           147: {
        !           148:   read_inband: ds_bus_read_inband,
        !           149:   read: ds_bus_read,
        !           150:   get_status: ds_bus_get_status,
        !           151:   close: ds_bus_close
        !           152: };

unix.superglobalmegacorp.com

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