|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.