1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer as 10 * the first lines of this file unmodified. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 *
| 1/*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer as 10 * the first lines of this file unmodified. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 *
|
97/* 98 * Low-level frame buffer driver functions 99 * frame buffer subdrivers, such as the VGA driver, call these functions 100 * to initialize the video_adapter structure and register it to the virtual 101 * frame buffer driver `fb'. 102 */ 103 104/* initialize the video_adapter_t structure */ 105void 106vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) 107{ 108 adp->va_flags = 0; 109 adp->va_name = name; 110 adp->va_type = type; 111 adp->va_unit = unit; 112} 113 114/* Register a video adapter */ 115int 116vid_register(video_adapter_t *adp) 117{ 118 video_driver_t **list; 119 video_driver_t *p; 120 int index; 121 122 for (index = 0; index < adapters; ++index) { 123 if (adapter[index] == NULL) 124 break; 125 } 126 if (index >= adapters) 127 return -1; 128 129 adp->va_index = index; 130 adp->va_token = NULL; 131 list = (video_driver_t **)videodriver_set.ls_items; 132 while ((p = *list++) != NULL) { 133 if (strcmp(p->name, adp->va_name) == 0) { 134 adapter[index] = adp; 135 vidsw[index] = p->vidsw; 136 return index; 137 } 138 } 139 140 return -1; 141} 142 143int 144vid_unregister(video_adapter_t *adp) 145{ 146 if ((adp->va_index < 0) || (adp->va_index >= adapters)) 147 return ENOENT; 148 if (adapter[adp->va_index] != adp) 149 return ENOENT; 150 151 adapter[adp->va_index] = NULL; 152 vidsw[adp->va_index] = NULL; 153 return 0; 154} 155 156/* Get video I/O function table */ 157video_switch_t 158*vid_get_switch(char *name) 159{ 160 video_driver_t **list; 161 video_driver_t *p; 162 163 list = (video_driver_t **)videodriver_set.ls_items; 164 while ((p = *list++) != NULL) { 165 if (strcmp(p->name, name) == 0) 166 return p->vidsw; 167 } 168 169 return NULL; 170} 171 172/* 173 * Video card client functions 174 * Video card clients, such as the console driver `syscons' and the frame 175 * buffer cdev driver, use these functions to claim and release a card for 176 * exclusive use. 177 */ 178 179/* find the video card specified by a driver name and a unit number */ 180int 181vid_find_adapter(char *driver, int unit) 182{ 183 int i; 184 185 for (i = 0; i < adapters; ++i) { 186 if (adapter[i] == NULL) 187 continue; 188 if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver)) 189 continue; 190 if ((unit != -1) && (adapter[i]->va_unit != unit)) 191 continue; 192 return i; 193 } 194 return -1; 195} 196 197/* allocate a video card */ 198int 199vid_allocate(char *driver, int unit, void *id) 200{ 201 int index; 202 int s; 203 204 s = spltty(); 205 index = vid_find_adapter(driver, unit); 206 if (index >= 0) { 207 if (adapter[index]->va_token) { 208 splx(s); 209 return -1; 210 } 211 adapter[index]->va_token = id; 212 } 213 splx(s); 214 return index; 215} 216 217int 218vid_release(video_adapter_t *adp, void *id) 219{ 220 int error; 221 int s; 222 223 s = spltty(); 224 if (adp->va_token == NULL) { 225 error = EINVAL; 226 } else if (adp->va_token != id) { 227 error = EPERM; 228 } else { 229 adp->va_token = NULL; 230 error = 0; 231 } 232 splx(s); 233 return error; 234} 235 236/* Get a video adapter structure */ 237video_adapter_t 238*vid_get_adapter(int index) 239{ 240 if ((index < 0) || (index >= adapters)) 241 return NULL; 242 return adapter[index]; 243} 244 245/* Configure drivers: this is a backdoor for the console driver XXX */ 246int 247vid_configure(int flags) 248{ 249 video_driver_t **list; 250 video_driver_t *p; 251 252 list = (video_driver_t **)videodriver_set.ls_items; 253 while ((p = *list++) != NULL) { 254 if (p->configure != NULL) 255 (*p->configure)(flags); 256 } 257 258 return 0; 259} 260 261/* 262 * Virtual frame buffer cdev driver functions 263 * The virtual frame buffer driver dispatches driver functions to 264 * appropriate subdrivers. 265 */ 266 267#define DRIVER_NAME "fb" 268 269#ifdef FB_INSTALL_CDEV 270 271#define FB_UNIT(dev) minor(dev) 272#define FB_MKMINOR(unit) (u) 273 274#if notyet 275 276static d_open_t fbopen; 277static d_close_t fbclose; 278static d_ioctl_t fbioctl; 279static d_mmap_t fbmmap; 280 281#define CDEV_MAJOR 141 /* XXX */ 282 283static struct cdevsw fb_cdevsw = { 284 fbopen, fbclose, noread, nowrite, /* ??? */ 285 fbioctl, nostop, nullreset, nodevtotty, 286 seltrue, fbmmap, NULL, DRIVER_NAME, 287 NULL, -1, nodump, nopsize, 288}; 289 290static void 291vfbattach(void *arg) 292{ 293 static int fb_devsw_installed = FALSE; 294 dev_t dev; 295 296 if (!fb_devsw_installed) { 297 dev = makedev(CDEV_MAJOR, 0); 298 cdevsw_add(&dev, &fb_cdevsw, NULL); 299 fb_devsw_installed = TRUE; 300 } 301} 302 303PSEUDO_SET(vfbattach, fb); 304 305#endif /* notyet */ 306 307int 308fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) 309{ 310 int s; 311 312 if (adp->va_index >= adapters) 313 return EINVAL; 314 if (adapter[adp->va_index] != adp) 315 return EINVAL; 316 317 s = spltty(); 318 adp->va_minor = minor(dev); 319 vidcdevsw[adp->va_index] = cdevsw; 320 splx(s); 321 322 /* XXX: DEVFS? */ 323 324 if (adp->va_index + 1 >= adapters) 325 vid_realloc_array(); 326 327 printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); 328 return 0; 329} 330 331int 332fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) 333{ 334 int s; 335 336 if (adp->va_index >= adapters) 337 return EINVAL; 338 if (adapter[adp->va_index] != adp) 339 return EINVAL; 340 if (vidcdevsw[adp->va_index] != cdevsw) 341 return EINVAL; 342 343 s = spltty(); 344 vidcdevsw[adp->va_index] = NULL; 345 splx(s); 346 return 0; 347} 348 349#endif /* FB_INSTALL_CDEV */ 350 351static char 352*adapter_name(int type) 353{ 354 static struct { 355 int type; 356 char *name; 357 } names[] = { 358 { KD_MONO, "MDA" }, 359 { KD_HERCULES, "Hercules" }, 360 { KD_CGA, "CGA" }, 361 { KD_EGA, "EGA" }, 362 { KD_VGA, "VGA" }, 363 { KD_PC98, "PC-98x1" }, 364 { -1, "Unknown" }, 365 }; 366 int i; 367 368 for (i = 0; names[i].type != -1; ++i) 369 if (names[i].type == type) 370 break; 371 return names[i].name; 372} 373 374void 375fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) 376{ 377 if (level <= 0) 378 return; 379 380 printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 381 DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, 382 adapter_name(adp->va_type), adp->va_type, adp->va_flags); 383 printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n", 384 DRIVER_NAME, adp->va_index, 385 adp->va_io_base, adp->va_io_base + adp->va_io_size - 1, 386 adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size); 387 printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n", 388 DRIVER_NAME, adp->va_index, 389 adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); 390 printf("%s%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n", 391 DRIVER_NAME, adp->va_index, 392 adp->va_window, adp->va_window_size/1024, adp->va_window_gran/1024, 393 adp->va_buffer, adp->va_buffer_size/1024); 394} 395 396void 397fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, 398 int level) 399{ 400 if (level <= 0) 401 return; 402 403 printf("%s%d: %s, mode:%d, flags:0x%x ", 404 driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags); 405 if (info->vi_flags & V_INFO_GRAPHICS) 406 printf("G %dx%dx%d, %d plane(s), font:%dx%d, ", 407 info->vi_width, info->vi_height, 408 info->vi_depth, info->vi_planes, 409 info->vi_cwidth, info->vi_cheight); 410 else 411 printf("T %dx%d, font:%dx%d, ", 412 info->vi_width, info->vi_height, 413 info->vi_cwidth, info->vi_cheight); 414 printf("win:0x%x\n", info->vi_window); 415}
| 102/* 103 * Low-level frame buffer driver functions 104 * frame buffer subdrivers, such as the VGA driver, call these functions 105 * to initialize the video_adapter structure and register it to the virtual 106 * frame buffer driver `fb'. 107 */ 108 109/* initialize the video_adapter_t structure */ 110void 111vid_init_struct(video_adapter_t *adp, char *name, int type, int unit) 112{ 113 adp->va_flags = 0; 114 adp->va_name = name; 115 adp->va_type = type; 116 adp->va_unit = unit; 117} 118 119/* Register a video adapter */ 120int 121vid_register(video_adapter_t *adp) 122{ 123 video_driver_t **list; 124 video_driver_t *p; 125 int index; 126 127 for (index = 0; index < adapters; ++index) { 128 if (adapter[index] == NULL) 129 break; 130 } 131 if (index >= adapters) 132 return -1; 133 134 adp->va_index = index; 135 adp->va_token = NULL; 136 list = (video_driver_t **)videodriver_set.ls_items; 137 while ((p = *list++) != NULL) { 138 if (strcmp(p->name, adp->va_name) == 0) { 139 adapter[index] = adp; 140 vidsw[index] = p->vidsw; 141 return index; 142 } 143 } 144 145 return -1; 146} 147 148int 149vid_unregister(video_adapter_t *adp) 150{ 151 if ((adp->va_index < 0) || (adp->va_index >= adapters)) 152 return ENOENT; 153 if (adapter[adp->va_index] != adp) 154 return ENOENT; 155 156 adapter[adp->va_index] = NULL; 157 vidsw[adp->va_index] = NULL; 158 return 0; 159} 160 161/* Get video I/O function table */ 162video_switch_t 163*vid_get_switch(char *name) 164{ 165 video_driver_t **list; 166 video_driver_t *p; 167 168 list = (video_driver_t **)videodriver_set.ls_items; 169 while ((p = *list++) != NULL) { 170 if (strcmp(p->name, name) == 0) 171 return p->vidsw; 172 } 173 174 return NULL; 175} 176 177/* 178 * Video card client functions 179 * Video card clients, such as the console driver `syscons' and the frame 180 * buffer cdev driver, use these functions to claim and release a card for 181 * exclusive use. 182 */ 183 184/* find the video card specified by a driver name and a unit number */ 185int 186vid_find_adapter(char *driver, int unit) 187{ 188 int i; 189 190 for (i = 0; i < adapters; ++i) { 191 if (adapter[i] == NULL) 192 continue; 193 if (strcmp("*", driver) && strcmp(adapter[i]->va_name, driver)) 194 continue; 195 if ((unit != -1) && (adapter[i]->va_unit != unit)) 196 continue; 197 return i; 198 } 199 return -1; 200} 201 202/* allocate a video card */ 203int 204vid_allocate(char *driver, int unit, void *id) 205{ 206 int index; 207 int s; 208 209 s = spltty(); 210 index = vid_find_adapter(driver, unit); 211 if (index >= 0) { 212 if (adapter[index]->va_token) { 213 splx(s); 214 return -1; 215 } 216 adapter[index]->va_token = id; 217 } 218 splx(s); 219 return index; 220} 221 222int 223vid_release(video_adapter_t *adp, void *id) 224{ 225 int error; 226 int s; 227 228 s = spltty(); 229 if (adp->va_token == NULL) { 230 error = EINVAL; 231 } else if (adp->va_token != id) { 232 error = EPERM; 233 } else { 234 adp->va_token = NULL; 235 error = 0; 236 } 237 splx(s); 238 return error; 239} 240 241/* Get a video adapter structure */ 242video_adapter_t 243*vid_get_adapter(int index) 244{ 245 if ((index < 0) || (index >= adapters)) 246 return NULL; 247 return adapter[index]; 248} 249 250/* Configure drivers: this is a backdoor for the console driver XXX */ 251int 252vid_configure(int flags) 253{ 254 video_driver_t **list; 255 video_driver_t *p; 256 257 list = (video_driver_t **)videodriver_set.ls_items; 258 while ((p = *list++) != NULL) { 259 if (p->configure != NULL) 260 (*p->configure)(flags); 261 } 262 263 return 0; 264} 265 266/* 267 * Virtual frame buffer cdev driver functions 268 * The virtual frame buffer driver dispatches driver functions to 269 * appropriate subdrivers. 270 */ 271 272#define DRIVER_NAME "fb" 273 274#ifdef FB_INSTALL_CDEV 275 276#define FB_UNIT(dev) minor(dev) 277#define FB_MKMINOR(unit) (u) 278 279#if notyet 280 281static d_open_t fbopen; 282static d_close_t fbclose; 283static d_ioctl_t fbioctl; 284static d_mmap_t fbmmap; 285 286#define CDEV_MAJOR 141 /* XXX */ 287 288static struct cdevsw fb_cdevsw = { 289 fbopen, fbclose, noread, nowrite, /* ??? */ 290 fbioctl, nostop, nullreset, nodevtotty, 291 seltrue, fbmmap, NULL, DRIVER_NAME, 292 NULL, -1, nodump, nopsize, 293}; 294 295static void 296vfbattach(void *arg) 297{ 298 static int fb_devsw_installed = FALSE; 299 dev_t dev; 300 301 if (!fb_devsw_installed) { 302 dev = makedev(CDEV_MAJOR, 0); 303 cdevsw_add(&dev, &fb_cdevsw, NULL); 304 fb_devsw_installed = TRUE; 305 } 306} 307 308PSEUDO_SET(vfbattach, fb); 309 310#endif /* notyet */ 311 312int 313fb_attach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) 314{ 315 int s; 316 317 if (adp->va_index >= adapters) 318 return EINVAL; 319 if (adapter[adp->va_index] != adp) 320 return EINVAL; 321 322 s = spltty(); 323 adp->va_minor = minor(dev); 324 vidcdevsw[adp->va_index] = cdevsw; 325 splx(s); 326 327 /* XXX: DEVFS? */ 328 329 if (adp->va_index + 1 >= adapters) 330 vid_realloc_array(); 331 332 printf("fb%d at %s%d\n", adp->va_index, adp->va_name, adp->va_unit); 333 return 0; 334} 335 336int 337fb_detach(dev_t dev, video_adapter *adp, struct cdevsw *cdevsw) 338{ 339 int s; 340 341 if (adp->va_index >= adapters) 342 return EINVAL; 343 if (adapter[adp->va_index] != adp) 344 return EINVAL; 345 if (vidcdevsw[adp->va_index] != cdevsw) 346 return EINVAL; 347 348 s = spltty(); 349 vidcdevsw[adp->va_index] = NULL; 350 splx(s); 351 return 0; 352} 353 354#endif /* FB_INSTALL_CDEV */ 355 356static char 357*adapter_name(int type) 358{ 359 static struct { 360 int type; 361 char *name; 362 } names[] = { 363 { KD_MONO, "MDA" }, 364 { KD_HERCULES, "Hercules" }, 365 { KD_CGA, "CGA" }, 366 { KD_EGA, "EGA" }, 367 { KD_VGA, "VGA" }, 368 { KD_PC98, "PC-98x1" }, 369 { -1, "Unknown" }, 370 }; 371 int i; 372 373 for (i = 0; names[i].type != -1; ++i) 374 if (names[i].type == type) 375 break; 376 return names[i].name; 377} 378 379void 380fb_dump_adp_info(char *driver, video_adapter_t *adp, int level) 381{ 382 if (level <= 0) 383 return; 384 385 printf("%s%d: %s%d, %s, type:%s (%d), flags:0x%x\n", 386 DRIVER_NAME, adp->va_index, driver, adp->va_unit, adp->va_name, 387 adapter_name(adp->va_type), adp->va_type, adp->va_flags); 388 printf("%s%d: port:0x%x-0x%x, crtc:0x%x, mem:0x%x 0x%x\n", 389 DRIVER_NAME, adp->va_index, 390 adp->va_io_base, adp->va_io_base + adp->va_io_size - 1, 391 adp->va_crtc_addr, adp->va_mem_base, adp->va_mem_size); 392 printf("%s%d: init mode:%d, bios mode:%d, current mode:%d\n", 393 DRIVER_NAME, adp->va_index, 394 adp->va_initial_mode, adp->va_initial_bios_mode, adp->va_mode); 395 printf("%s%d: window:0x%x size:%dk gran:%dk, buf:0x%x size:%dk\n", 396 DRIVER_NAME, adp->va_index, 397 adp->va_window, adp->va_window_size/1024, adp->va_window_gran/1024, 398 adp->va_buffer, adp->va_buffer_size/1024); 399} 400 401void 402fb_dump_mode_info(char *driver, video_adapter_t *adp, video_info_t *info, 403 int level) 404{ 405 if (level <= 0) 406 return; 407 408 printf("%s%d: %s, mode:%d, flags:0x%x ", 409 driver, adp->va_unit, adp->va_name, info->vi_mode, info->vi_flags); 410 if (info->vi_flags & V_INFO_GRAPHICS) 411 printf("G %dx%dx%d, %d plane(s), font:%dx%d, ", 412 info->vi_width, info->vi_height, 413 info->vi_depth, info->vi_planes, 414 info->vi_cwidth, info->vi_cheight); 415 else 416 printf("T %dx%d, font:%dx%d, ", 417 info->vi_width, info->vi_height, 418 info->vi_cwidth, info->vi_cheight); 419 printf("win:0x%x\n", info->vi_window); 420}
|