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