Annotation of OSKit-Mach/oskit/ds_bus.c, revision 1.1.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.