1 /* 2 * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "device.h" 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <Drivers.h> 13 #include <graphic_driver.h> 14 #include <image.h> 15 #include <KernelExport.h> 16 #include <OS.h> 17 #include <PCI.h> 18 #include <SupportDefs.h> 19 20 #include "driver.h" 21 #include "utility.h" 22 #include "vesa_info.h" 23 #include "vesa_private.h" 24 #include "vga.h" 25 26 27 //#define TRACE_DEVICE 28 #ifdef TRACE_DEVICE 29 # define TRACE(x) dprintf x 30 #else 31 # define TRACE(x) ; 32 #endif 33 34 35 /* device hooks prototypes */ 36 37 static status_t device_open(const char *, uint32, void **); 38 static status_t device_close(void *); 39 static status_t device_free(void *); 40 static status_t device_ioctl(void *, uint32, void *, size_t); 41 static status_t device_read(void *, off_t, void *, size_t *); 42 static status_t device_write(void *, off_t, const void *, size_t *); 43 44 45 device_hooks gDeviceHooks = { 46 device_open, 47 device_close, 48 device_free, 49 device_ioctl, 50 device_read, 51 device_write, 52 NULL, 53 NULL, 54 NULL, 55 NULL 56 }; 57 58 59 // #pragma mark - 60 // the device will be accessed through the following functions (a.k.a. device hooks) 61 62 63 static status_t 64 device_open(const char *name, uint32 flags, void **_cookie) 65 { 66 int id; 67 68 // find accessed device 69 { 70 char *thisName; 71 72 // search for device name 73 for (id = 0; (thisName = gDeviceNames[id]) != NULL; id++) { 74 if (!strcmp(name, thisName)) 75 break; 76 } 77 if (!thisName) 78 return EINVAL; 79 } 80 81 vesa_info *info = gDeviceInfo[id]; 82 *_cookie = info; 83 84 acquire_lock(&gLock); 85 86 status_t status = B_OK; 87 88 if (info->open_count++ == 0) { 89 // this device has been opened for the first time, so 90 // we allocate needed resources and initialize the structure 91 if (status == B_OK) 92 status = vesa_init(*info); 93 if (status == B_OK) 94 info->id = id; 95 } 96 97 release_lock(&gLock); 98 return status; 99 } 100 101 102 static status_t 103 device_close(void *cookie) 104 { 105 return B_OK; 106 } 107 108 109 static status_t 110 device_free(void *cookie) 111 { 112 struct vesa_info *info = (vesa_info *)cookie; 113 114 acquire_lock(&gLock); 115 116 if (info->open_count-- == 1) { 117 // release info structure 118 vesa_uninit(*info); 119 } 120 121 release_lock(&gLock); 122 return B_OK; 123 } 124 125 126 static status_t 127 device_ioctl(void *cookie, uint32 msg, void *buffer, size_t bufferLength) 128 { 129 struct vesa_info *info = (vesa_info *)cookie; 130 131 switch (msg) { 132 case B_GET_ACCELERANT_SIGNATURE: 133 dprintf(DEVICE_NAME ": acc: %s\n", VESA_ACCELERANT_NAME); 134 if (user_strlcpy((char *)buffer, VESA_ACCELERANT_NAME, 135 B_FILE_NAME_LENGTH) < B_OK) 136 return B_BAD_ADDRESS; 137 138 return B_OK; 139 140 // needed to share data between kernel and accelerant 141 case VESA_GET_PRIVATE_DATA: 142 return user_memcpy(buffer, &info->shared_area, sizeof(area_id)); 143 144 // needed for cloning 145 case VESA_GET_DEVICE_NAME: 146 if (user_strlcpy((char *)buffer, gDeviceNames[info->id], 147 B_PATH_NAME_LENGTH) < B_OK) 148 return B_BAD_ADDRESS; 149 150 return B_OK; 151 152 case VGA_SET_INDEXED_COLORS: 153 { 154 vga_set_indexed_colors_args args; 155 if (user_memcpy(&args, buffer, sizeof(args)) < B_OK) 156 return B_BAD_ADDRESS; 157 158 return vga_set_indexed_colors(args.first, args.colors, args.count); 159 } 160 161 case VGA_PLANAR_BLIT: 162 { 163 vga_planar_blit_args args; 164 if (user_memcpy(&args, buffer, sizeof(args)) < B_OK) 165 return B_BAD_ADDRESS; 166 167 return vga_planar_blit(info->shared_info, args.source, 168 args.source_bytes_per_row, args.left, args.top, 169 args.right, args.bottom); 170 } 171 172 default: 173 TRACE((DEVICE_NAME ": ioctl() unknown message %ld (length = %lu)\n", msg, bufferLength)); 174 } 175 176 return B_DEV_INVALID_IOCTL; 177 } 178 179 180 static status_t 181 device_read(void */*cookie*/, off_t /*pos*/, void */*buffer*/, size_t *_length) 182 { 183 *_length = 0; 184 return B_NOT_ALLOWED; 185 } 186 187 188 static status_t 189 device_write(void */*cookie*/, off_t /*pos*/, const void */*buffer*/, size_t *_length) 190 { 191 *_length = 0; 192 return B_NOT_ALLOWED; 193 } 194 195