Annotation of sys/dev/sbus/vigra.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: vigra.c,v 1.10 2006/12/17 22:18:16 miod Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 2002, 2003, Miodrag Vallat.
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
! 18: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
! 19: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
! 20: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 21: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 22: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 23: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 24: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
! 25: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 26: * POSSIBILITY OF SUCH DAMAGE.
! 27: *
! 28: */
! 29:
! 30: /*
! 31: * Driver for the Vigra VS series of SBus framebuffers.
! 32: *
! 33: * The VS10, VS11 and VS12 models are supported. VS10-EK is handled by the
! 34: * regular cgthree driver.
! 35: *
! 36: * The monochrome VS14, 16 grays VS15, and color VS18 are not supported.
! 37: */
! 38:
! 39: #include <sys/param.h>
! 40: #include <sys/systm.h>
! 41: #include <sys/buf.h>
! 42: #include <sys/device.h>
! 43: #include <sys/ioctl.h>
! 44: #include <sys/malloc.h>
! 45: #include <sys/mman.h>
! 46: #include <sys/tty.h>
! 47: #include <sys/conf.h>
! 48:
! 49: #include <uvm/uvm_extern.h>
! 50:
! 51: #include <machine/autoconf.h>
! 52: #include <machine/bus.h>
! 53: #include <machine/pmap.h>
! 54: #include <machine/cpu.h>
! 55: #include <machine/conf.h>
! 56:
! 57: #include <dev/wscons/wsconsio.h>
! 58: #include <dev/wscons/wsdisplayvar.h>
! 59: #include <dev/rasops/rasops.h>
! 60: #include <machine/fbvar.h>
! 61:
! 62: #include <dev/sbus/sbusvar.h>
! 63:
! 64: /*
! 65: * The hardware information below has been gathered through experiments, as
! 66: * well as the debug information of the SunOS 4.x vigfb driver.
! 67: */
! 68:
! 69: /*
! 70: * Control and status registers
! 71: */
! 72:
! 73: struct csregs {
! 74: u_int32_t sosr;
! 75: u_int32_t g3rr;
! 76: u_int32_t bcr; /* board control register */
! 77: u_int32_t spr;
! 78: u_int32_t g3sr; /* ramdac status register */
! 79: #define STATUS_INTR 0x0001
! 80: u_int32_t imr; /* interrupt mode register */
! 81: u_int32_t ewcr;
! 82: u_int32_t ssr;
! 83: };
! 84:
! 85: /*
! 86: * G300 layout
! 87: */
! 88:
! 89: struct g300dac {
! 90: u_int32_t cmap[256];
! 91: u_int32_t g3null;
! 92: u_int32_t unused1[32];
! 93: u_int32_t half_sync;
! 94: u_int32_t back_porch;
! 95: u_int32_t display;
! 96: u_int32_t short_display;
! 97: u_int32_t broad_pulse;
! 98: u_int32_t vsync;
! 99: u_int32_t vblank;
! 100: u_int32_t vdisplay;
! 101: u_int32_t line_time;
! 102: u_int32_t tos1;
! 103: u_int32_t mem_init;
! 104: u_int32_t transfer_delay;
! 105: u_int32_t unused2[19];
! 106: u_int32_t mask;
! 107: u_int32_t unused3[31];
! 108: u_int32_t cr;
! 109: u_int32_t unused4[31];
! 110: u_int32_t tos2;
! 111: u_int32_t unused5[31];
! 112: u_int32_t boot_location;
! 113: };
! 114:
! 115: /*
! 116: * G335 layout
! 117: */
! 118:
! 119: struct g335dac {
! 120: u_int32_t boot_location;
! 121: u_int32_t unused1[32];
! 122: u_int32_t half_sync;
! 123: u_int32_t back_porch;
! 124: u_int32_t display;
! 125: u_int32_t short_display;
! 126: u_int32_t broad_pulse;
! 127: u_int32_t vsync;
! 128: u_int32_t vpre_equalize;
! 129: u_int32_t vpost_equalize;
! 130: u_int32_t vblank;
! 131: u_int32_t vdisplay;
! 132: u_int32_t line_time;
! 133: u_int32_t tos1;
! 134: u_int32_t mem_init;
! 135: u_int32_t transfer_delay;
! 136: u_int32_t unused2[17];
! 137: u_int32_t mask;
! 138: u_int32_t unused3[31];
! 139: u_int32_t cra;
! 140: u_int32_t unused4[15];
! 141: u_int32_t crb;
! 142: u_int32_t unused5[15];
! 143: u_int32_t tos2;
! 144: u_int32_t unused6[32];
! 145: u_int32_t cursor_palette[3];
! 146: u_int32_t unused7[28];
! 147: u_int32_t checksum[3];
! 148: u_int32_t unused8[4];
! 149: u_int32_t cursor_position;
! 150: u_int32_t unused9[56];
! 151: u_int32_t cmap[256];
! 152: u_int32_t cursor_store[512];
! 153: };
! 154:
! 155: union dac {
! 156: struct g300dac g300;
! 157: struct g335dac g335;
! 158: };
! 159:
! 160: /*
! 161: * SBUS register mappings
! 162: */
! 163: #define VIGRA_REG_RAMDAC 1 /* either G300 or G335 */
! 164: #define VIGRA_REG_CSR 2
! 165: #define VIGRA_REG_VRAM 3
! 166:
! 167: #define VIGRA_NREG 4
! 168:
! 169: union vigracmap {
! 170: u_char cm_map[256][4]; /* 256 R/G/B entries plus pad */
! 171: u_int32_t cm_chip[256]; /* the way the chip gets loaded */
! 172: };
! 173:
! 174: /* per-display variables */
! 175: struct vigra_softc {
! 176: struct sunfb sc_sunfb; /* common base part */
! 177: bus_space_tag_t sc_bustag;
! 178: bus_addr_t sc_paddr;
! 179: volatile struct csregs *sc_regs;/* control registers */
! 180: volatile union dac *sc_ramdac; /* ramdac registers */
! 181: union vigracmap sc_cmap; /* current colormap */
! 182: int sc_g300;
! 183: void *sc_ih;
! 184: int sc_nscreens;
! 185: };
! 186:
! 187: int vigra_ioctl(void *, u_long, caddr_t, int, struct proc *);
! 188: int vigra_alloc_screen(void *, const struct wsscreen_descr *, void **,
! 189: int *, int *, long *);
! 190: void vigra_free_screen(void *, void *);
! 191: int vigra_show_screen(void *, void *, int, void (*cb)(void *, int, int),
! 192: void *);
! 193: paddr_t vigra_mmap(void *, off_t, int);
! 194: void vigra_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t);
! 195: int vigra_getcmap(union vigracmap *, struct wsdisplay_cmap *, int);
! 196: int vigra_putcmap(union vigracmap *, struct wsdisplay_cmap *, int);
! 197: void vigra_loadcmap_immediate(struct vigra_softc *, int, int);
! 198: static __inline__ void vigra_loadcmap_deferred(struct vigra_softc *,
! 199: u_int, u_int);
! 200: void vigra_burner(void *, u_int, u_int);
! 201: int vigra_intr(void *);
! 202:
! 203: struct wsdisplay_accessops vigra_accessops = {
! 204: vigra_ioctl,
! 205: vigra_mmap,
! 206: vigra_alloc_screen,
! 207: vigra_free_screen,
! 208: vigra_show_screen,
! 209: NULL, /* load_font */
! 210: NULL, /* scrollback */
! 211: NULL, /* getchar */
! 212: vigra_burner,
! 213: };
! 214:
! 215: int vigramatch(struct device *, void *, void *);
! 216: void vigraattach(struct device *, struct device *, void *);
! 217:
! 218: struct cfattach vigra_ca = {
! 219: sizeof (struct vigra_softc), vigramatch, vigraattach
! 220: };
! 221:
! 222: struct cfdriver vigra_cd = {
! 223: NULL, "vigra", DV_DULL
! 224: };
! 225:
! 226: /*
! 227: * Match a supported vigra card.
! 228: */
! 229: int
! 230: vigramatch(struct device *parent, void *vcf, void *aux)
! 231: {
! 232: struct sbus_attach_args *sa = aux;
! 233:
! 234: if (strcmp("vs10", sa->sa_name) != 0 &&
! 235: strcmp("vs11", sa->sa_name) != 0 &&
! 236: strcmp("vs12", sa->sa_name) != 0)
! 237: return (0);
! 238:
! 239: return (1);
! 240: }
! 241:
! 242: /*
! 243: * Attach and initialize a vigra display, as well as a child wsdisplay.
! 244: */
! 245: void
! 246: vigraattach(struct device *parent, struct device *self, void *args)
! 247: {
! 248: struct vigra_softc *sc = (struct vigra_softc *)self;
! 249: struct sbus_attach_args *sa = args;
! 250: bus_space_tag_t bt;
! 251: bus_space_handle_t bh;
! 252: int node, row, isconsole = 0;
! 253: char *nam;
! 254:
! 255: bt = sa->sa_bustag;
! 256: node = sa->sa_node;
! 257: nam = getpropstring(node, "model");
! 258: if (*nam == '\0')
! 259: nam = (char *)sa->sa_name;
! 260: printf(": %s", nam);
! 261:
! 262: isconsole = node == fbnode;
! 263:
! 264: if (sa->sa_nreg < VIGRA_NREG) {
! 265: printf("\n%s: expected %d registers, got %d",
! 266: self->dv_xname, VIGRA_NREG, sa->sa_nreg);
! 267: return;
! 268: }
! 269:
! 270: /*
! 271: * Check whether we are using an G300 or an G335 chip.
! 272: * The VS10 and VS12 use the G300, while the VS11 uses a G335.
! 273: */
! 274: sc->sc_g300 = strncmp(nam, "VIGRA,vs11", strlen("VIGRA,vs11"));
! 275:
! 276: sc->sc_bustag = bt;
! 277: if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_CSR].sbr_slot,
! 278: sa->sa_reg[VIGRA_REG_CSR].sbr_offset,
! 279: sa->sa_reg[VIGRA_REG_CSR].sbr_size, BUS_SPACE_MAP_LINEAR, 0,
! 280: &bh) != 0) {
! 281: printf("\n%s: can't map control registers\n", self->dv_xname);
! 282: return;
! 283: }
! 284: sc->sc_regs = bus_space_vaddr(bt, bh);
! 285: if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_RAMDAC].sbr_slot,
! 286: sa->sa_reg[VIGRA_REG_RAMDAC].sbr_offset,
! 287: sa->sa_reg[VIGRA_REG_RAMDAC].sbr_size, BUS_SPACE_MAP_LINEAR, 0,
! 288: &bh) != 0) {
! 289: printf("\n%s: can't map ramdac registers\n", self->dv_xname);
! 290: return;
! 291: }
! 292: sc->sc_ramdac = bus_space_vaddr(bt, bh);
! 293:
! 294: /* enable video */
! 295: vigra_burner(sc, 1, 0);
! 296:
! 297: fb_setsize(&sc->sc_sunfb, 8, 1152, 900, node, 0);
! 298: if (sbus_bus_map(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot,
! 299: sa->sa_reg[VIGRA_REG_VRAM].sbr_offset,
! 300: round_page(sc->sc_sunfb.sf_fbsize), BUS_SPACE_MAP_LINEAR, 0,
! 301: &bh) != 0) {
! 302: printf("\n%s: can't map video memory\n", self->dv_xname);
! 303: return;
! 304: }
! 305: sc->sc_sunfb.sf_ro.ri_bits = bus_space_vaddr(bt, bh);
! 306: sc->sc_sunfb.sf_ro.ri_hw = sc;
! 307: sc->sc_paddr = sbus_bus_addr(bt, sa->sa_reg[VIGRA_REG_VRAM].sbr_slot,
! 308: sa->sa_reg[VIGRA_REG_VRAM].sbr_offset);
! 309:
! 310: printf(", %dx%d\n", sc->sc_sunfb.sf_width, sc->sc_sunfb.sf_height);
! 311:
! 312: if ((sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri,
! 313: IPL_TTY, 0, vigra_intr, sc, self->dv_xname)) == NULL) {
! 314: printf("%s: couldn't establish interrupt, pri %d\n",
! 315: self->dv_xname, INTLEV(sa->sa_pri));
! 316: }
! 317:
! 318: /*
! 319: * If the framebuffer width is under 1024x768, we will switch from the
! 320: * PROM font to the more adequate 8x16 font here.
! 321: * However, we need to adjust two things in this case:
! 322: * - the display row should be overrided from the current PROM metrics,
! 323: * to prevent us from overwriting the last few lines of text.
! 324: * - if the 80x34 screen would make a large margin appear around it,
! 325: * choose to clear the screen rather than keeping old prom output in
! 326: * the margins.
! 327: * XXX there should be a rasops "clear margins" feature
! 328: *
! 329: * Also, in 1280x1024 resolution, the PROM display is not centered
! 330: * vertically (why? no other frame buffer does this in such a mode!),
! 331: * so be lazy and clear the screen here too anyways...
! 332: */
! 333: fbwscons_init(&sc->sc_sunfb, isconsole && (sc->sc_sunfb.sf_width != 800
! 334: && sc->sc_sunfb.sf_width != 1280) ? 0 : RI_CLEAR);
! 335: fbwscons_setcolormap(&sc->sc_sunfb, vigra_setcolor);
! 336:
! 337: if (isconsole) {
! 338: switch (sc->sc_sunfb.sf_width) {
! 339: case 640:
! 340: row = sc->sc_sunfb.sf_ro.ri_rows - 1;
! 341: break;
! 342: case 800:
! 343: case 1280:
! 344: row = 0; /* screen has been cleared above */
! 345: break;
! 346: default:
! 347: row = -1;
! 348: break;
! 349: }
! 350:
! 351: fbwscons_console_init(&sc->sc_sunfb, row);
! 352: }
! 353:
! 354: fbwscons_attach(&sc->sc_sunfb, &vigra_accessops, isconsole);
! 355: }
! 356:
! 357: int
! 358: vigra_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p)
! 359: {
! 360: struct vigra_softc *sc = v;
! 361: struct wsdisplay_cmap *cm;
! 362: struct wsdisplay_fbinfo *wdf;
! 363: int error;
! 364:
! 365: switch (cmd) {
! 366: case WSDISPLAYIO_GTYPE:
! 367: *(u_int *)data = WSDISPLAY_TYPE_UNKNOWN;
! 368: break;
! 369: case WSDISPLAYIO_GINFO:
! 370: wdf = (struct wsdisplay_fbinfo *)data;
! 371: wdf->height = sc->sc_sunfb.sf_height;
! 372: wdf->width = sc->sc_sunfb.sf_width;
! 373: wdf->depth = sc->sc_sunfb.sf_depth;
! 374: wdf->cmsize = 256;
! 375: break;
! 376: case WSDISPLAYIO_LINEBYTES:
! 377: *(u_int *)data = sc->sc_sunfb.sf_linebytes;
! 378: break;
! 379:
! 380: case WSDISPLAYIO_GETCMAP:
! 381: cm = (struct wsdisplay_cmap *)data;
! 382: error = vigra_getcmap(&sc->sc_cmap, cm, sc->sc_g300);
! 383: if (error)
! 384: return (error);
! 385: break;
! 386: case WSDISPLAYIO_PUTCMAP:
! 387: cm = (struct wsdisplay_cmap *)data;
! 388: error = vigra_putcmap(&sc->sc_cmap, cm, sc->sc_g300);
! 389: if (error)
! 390: return (error);
! 391: /* if we can handle interrupts, defer the update */
! 392: if (sc->sc_ih != NULL)
! 393: vigra_loadcmap_deferred(sc, cm->index, cm->count);
! 394: else
! 395: vigra_loadcmap_immediate(sc, cm->index, cm->count);
! 396: break;
! 397:
! 398: case WSDISPLAYIO_SVIDEO:
! 399: case WSDISPLAYIO_GVIDEO:
! 400: break;
! 401:
! 402: case WSDISPLAYIO_GCURPOS:
! 403: case WSDISPLAYIO_SCURPOS:
! 404: case WSDISPLAYIO_GCURMAX:
! 405: case WSDISPLAYIO_GCURSOR:
! 406: case WSDISPLAYIO_SCURSOR:
! 407: default:
! 408: return (-1); /* not supported yet */
! 409: }
! 410:
! 411: return (0);
! 412: }
! 413:
! 414: int
! 415: vigra_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep,
! 416: int *curxp, int *curyp, long *attrp)
! 417: {
! 418: struct vigra_softc *sc = v;
! 419:
! 420: if (sc->sc_nscreens > 0)
! 421: return (ENOMEM);
! 422:
! 423: *cookiep = &sc->sc_sunfb.sf_ro;
! 424: *curyp = 0;
! 425: *curxp = 0;
! 426: sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro,
! 427: WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp);
! 428: sc->sc_nscreens++;
! 429: return (0);
! 430: }
! 431:
! 432: void
! 433: vigra_free_screen(void *v, void *cookie)
! 434: {
! 435: struct vigra_softc *sc = v;
! 436:
! 437: sc->sc_nscreens--;
! 438: }
! 439:
! 440: int
! 441: vigra_show_screen(void *v, void *cookie, int waitok,
! 442: void (*cb)(void *, int, int), void *cbarg)
! 443: {
! 444: return (0);
! 445: }
! 446:
! 447: /*
! 448: * Return the address that would map the given device at the given
! 449: * offset, allowing for the given protection, or return -1 for error.
! 450: */
! 451: paddr_t
! 452: vigra_mmap(void *v, off_t offset, int prot)
! 453: {
! 454: struct vigra_softc *sc = v;
! 455:
! 456: if (offset & PGOFSET)
! 457: return (-1);
! 458:
! 459: if (offset >= 0 && offset < sc->sc_sunfb.sf_fbsize) {
! 460: return (bus_space_mmap(sc->sc_bustag, sc->sc_paddr,
! 461: offset, prot, BUS_SPACE_MAP_LINEAR));
! 462: }
! 463:
! 464: return (-1);
! 465: }
! 466:
! 467: void
! 468: vigra_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b)
! 469: {
! 470: struct vigra_softc *sc = v;
! 471:
! 472: if (sc->sc_g300) {
! 473: sc->sc_cmap.cm_map[index][3] = r;
! 474: sc->sc_cmap.cm_map[index][2] = g;
! 475: sc->sc_cmap.cm_map[index][1] = b;
! 476: } else {
! 477: sc->sc_cmap.cm_map[index][3] = b;
! 478: sc->sc_cmap.cm_map[index][2] = g;
! 479: sc->sc_cmap.cm_map[index][1] = r;
! 480: }
! 481: sc->sc_cmap.cm_map[index][0] = 0; /* no alpha channel */
! 482:
! 483: vigra_loadcmap_immediate(sc, index, 1);
! 484: }
! 485:
! 486: int
! 487: vigra_getcmap(union vigracmap *cm, struct wsdisplay_cmap *rcm, int g300)
! 488: {
! 489: u_int index = rcm->index, count = rcm->count, i;
! 490: int error;
! 491:
! 492: if (index >= 256 || count > 256 - index)
! 493: return (EINVAL);
! 494:
! 495: if (g300) {
! 496: for (i = 0; i < count; i++) {
! 497: if ((error = copyout(&cm->cm_map[index + i][3],
! 498: &rcm->red[i], 1)) != 0)
! 499: return (error);
! 500: if ((error = copyout(&cm->cm_map[index + i][1],
! 501: &rcm->blue[i], 1)) != 0)
! 502: return (error);
! 503: }
! 504: } else {
! 505: for (i = 0; i < count; i++) {
! 506: if ((error = copyout(&cm->cm_map[index + i][1],
! 507: &rcm->red[i], 1)) != 0)
! 508: return (error);
! 509: if ((error = copyout(&cm->cm_map[index + i][3],
! 510: &rcm->blue[i], 1)) != 0)
! 511: return (error);
! 512: }
! 513: }
! 514:
! 515: for (i = 0; i < count; i++) {
! 516: if ((error = copyout(&cm->cm_map[index + i][2],
! 517: &rcm->green[i], 1)) != 0)
! 518: return (error);
! 519: }
! 520: return (0);
! 521: }
! 522:
! 523: int
! 524: vigra_putcmap(union vigracmap *cm, struct wsdisplay_cmap *rcm, int g300)
! 525: {
! 526: u_int index = rcm->index, count = rcm->count, i;
! 527: int error;
! 528:
! 529: if (index >= 256 || count > 256 - index)
! 530: return (EINVAL);
! 531:
! 532: if (g300) {
! 533: for (i = 0; i < count; i++) {
! 534: if ((error = copyin(&rcm->red[i],
! 535: &cm->cm_map[index + i][3], 1)) != 0)
! 536: return (error);
! 537: if ((error = copyin(&rcm->blue[i],
! 538: &cm->cm_map[index + i][1], 1)) != 0)
! 539: return (error);
! 540: }
! 541: } else {
! 542: for (i = 0; i < count; i++) {
! 543: if ((error = copyin(&rcm->red[i],
! 544: &cm->cm_map[index + i][1], 1)) != 0)
! 545: return (error);
! 546: if ((error = copyin(&rcm->blue[i],
! 547: &cm->cm_map[index + i][3], 1)) != 0)
! 548: return (error);
! 549: }
! 550: }
! 551:
! 552: for (i = 0; i < count; i++) {
! 553: if ((error = copyin(&rcm->green[i],
! 554: &cm->cm_map[index + i][2], 1)) != 0)
! 555: return (error);
! 556: cm->cm_map[index + i][0] = 0; /* no alpha channel */
! 557: }
! 558: return (0);
! 559: }
! 560:
! 561: void
! 562: vigra_loadcmap_immediate(struct vigra_softc *sc, int start, int ncolors)
! 563: {
! 564: u_int32_t *colp = &sc->sc_cmap.cm_chip[start];
! 565: volatile u_int32_t *lutp;
! 566:
! 567: if (sc->sc_g300)
! 568: lutp = &(sc->sc_ramdac->g300.cmap[start]);
! 569: else
! 570: lutp = &(sc->sc_ramdac->g335.cmap[start]);
! 571:
! 572: while (--ncolors >= 0)
! 573: *lutp++ = *colp++;
! 574: }
! 575:
! 576: static __inline__ void
! 577: vigra_loadcmap_deferred(struct vigra_softc *sc, u_int start, u_int ncolors)
! 578: {
! 579:
! 580: sc->sc_regs->imr = 1;
! 581: }
! 582:
! 583: void
! 584: vigra_burner(void *v, u_int on, u_int flags)
! 585: {
! 586: struct vigra_softc *sc = v;
! 587:
! 588: if (on) {
! 589: sc->sc_regs->bcr = 0;
! 590: } else {
! 591: sc->sc_regs->bcr = 1;
! 592: }
! 593: }
! 594:
! 595: int
! 596: vigra_intr(void *v)
! 597: {
! 598: struct vigra_softc *sc = v;
! 599:
! 600: if (sc->sc_regs->imr == 0 ||
! 601: !ISSET(sc->sc_regs->g3sr, STATUS_INTR)) {
! 602: /* Not expecting an interrupt, it's not for us. */
! 603: return (0);
! 604: }
! 605:
! 606: /* Acknowledge the interrupt and disable it. */
! 607: sc->sc_regs->imr = 0;
! 608:
! 609: vigra_loadcmap_immediate(sc, 0, 256);
! 610:
! 611: return (1);
! 612: }
CVSweb