diff options
| author | elric <elric@NetBSD.org> | 2001-07-16 00:55:16 +0000 |
|---|---|---|
| committer | elric <elric@NetBSD.org> | 2001-07-16 00:55:16 +0000 |
| commit | 99e8b114e0c47067e84ebc73ce397f0e1cae0855 (patch) | |
| tree | 7dc93cabe9e950f09669c14c06e98b5a3f4306b7 /sys/dev | |
| parent | 1d32ca9175bb56469f7f54bc00b961ffd4dc015d (diff) | |
So, the PowerStorm 4d20 a.k.a. 32bit TGA2 w/ IBM RGB561 RAMDAC was causing
the kernel to panic since it is recognised as a TGA and the TGA driver
doesn't [yet] know what to do with it.
This patch fixes that by:
o making tgamatch() try to actually figure out what kind
of TGA card is there, rather than simply relying on the
vendor/product ids.
o creating a tga_cnmatch() so that the console code in
arch/alpha/pci/pci_machdep.c can cause the same to occur.
o breaking up some of tga_getdevconfig() into a few different
functions to re-use code that would have been duplicated.
o changed arch/alpha/pci/pci_machdep.c so that it calls out
to tga_cnmatch() if DEVICE_IS_TGA() matches before it decides
to attach the console as a TGA.
Addresses PR: port-alpha/12923
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/tga.c | 102 | ||||
| -rw-r--r-- | sys/dev/pci/tgavar.h | 4 |
2 files changed, 78 insertions, 28 deletions
diff --git a/sys/dev/pci/tga.c b/sys/dev/pci/tga.c index 9bef494ad97..1b252a78e52 100644 --- a/sys/dev/pci/tga.c +++ b/sys/dev/pci/tga.c @@ -1,4 +1,4 @@ -/* $NetBSD: tga.c,v 1.33 2001/07/07 16:46:35 thorpej Exp $ */ +/* $NetBSD: tga.c,v 1.34 2001/07/16 00:55:16 elric Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -72,9 +72,13 @@ struct cfattach tga_ca = { int tga_identify __P((struct tga_devconfig *)); const struct tga_conf *tga_getconf __P((int)); -static void tga_getdevconfig __P((bus_space_tag_t memt, pci_chipset_tag_t pc, +static void tga_init __P((bus_space_tag_t memt, pci_chipset_tag_t pc, pcitag_t tag, struct tga_devconfig *dc)); +static int tga_matchcommon __P((bus_space_tag_t, pci_chipset_tag_t, pcitag_t)); +static void tga_mapaddrs __P((bus_space_tag_t memt, pci_chipset_tag_t pc, + pcitag_t, bus_size_t *pcisize, struct tga_devconfig *dc)); + struct tga_devconfig tga_console_dc; int tga_ioctl __P((void *, u_long, caddr_t, int, struct proc *)); @@ -154,6 +158,15 @@ static void tga_blank __P((struct tga_devconfig *)); static void tga_unblank __P((struct tga_devconfig *)); int +tga_cnmatch(iot, memt, pc, tag) + bus_space_tag_t iot, memt; + pci_chipset_tag_t pc; + pcitag_t tag; +{ + return tga_matchcommon(memt, pc, tag); +} + +int tgamatch(parent, match, aux) struct device *parent; struct cfdata *match; @@ -167,41 +180,66 @@ tgamatch(parent, match, aux) switch (PCI_PRODUCT(pa->pa_id)) { case PCI_PRODUCT_DEC_21030: case PCI_PRODUCT_DEC_PBXGB: - return 10; + break; default: return 0; } - return (0); + + /* short-circuit the following test, as we + * already have the memory mapped and hence + * cannot perform it---and we are the console + * anyway. + */ + if (pa->pa_tag == tga_console_dc.dc_pcitag) + return 10; + + return tga_matchcommon(pa->pa_memt, pa->pa_pc, pa->pa_tag); +} + +static int +tga_matchcommon(memt, pc, tag) + bus_space_tag_t memt; + pci_chipset_tag_t pc; + pcitag_t tag; +{ + struct tga_devconfig tmp_dc; + struct tga_devconfig *dc = &tmp_dc; + bus_size_t pcisize; + + tga_mapaddrs(memt, pc, tag, &pcisize, dc); + dc->dc_tga_type = tga_identify(dc); + + dc->dc_tgaconf = tga_getconf(dc->dc_tga_type); + bus_space_unmap(memt, dc->dc_memh, pcisize); + if (dc->dc_tgaconf) + return 10; + return 0; } static void -tga_getdevconfig(memt, pc, tag, dc) +tga_mapaddrs(memt, pc, tag, pcisize, dc) bus_space_tag_t memt; pci_chipset_tag_t pc; pcitag_t tag; + bus_size_t *pcisize; struct tga_devconfig *dc; { - const struct tga_conf *tgac; - struct rasops_info *rip; - int cookie; - bus_size_t pcisize; - int i, flags; + int flags; dc->dc_memt = memt; - - dc->dc_pcitag = tag; + dc->dc_tgaconf = NULL; /* XXX magic number */ if (pci_mapreg_info(pc, tag, 0x10, PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, - &dc->dc_pcipaddr, &pcisize, &flags)) - return; + &dc->dc_pcipaddr, pcisize, &flags)) + panic("tga_mapaddrs: pci_mapreg_info() failed"); if ((flags & BUS_SPACE_MAP_PREFETCHABLE) == 0) /* XXX */ panic("tga memory not prefetchable"); - if (bus_space_map(memt, dc->dc_pcipaddr, pcisize, + if (bus_space_map(memt, dc->dc_pcipaddr, *pcisize, BUS_SPACE_MAP_PREFETCHABLE | BUS_SPACE_MAP_LINEAR, &dc->dc_memh)) - return; + panic("tga_mapaddrs: could not map TGA address space"); dc->dc_vaddr = (vaddr_t) bus_space_vaddr(memt, dc->dc_memh); #ifdef __alpha__ dc->dc_paddr = ALPHA_K0SEG_TO_PHYS(dc->dc_vaddr); /* XXX */ @@ -213,16 +251,29 @@ tga_getdevconfig(memt, pc, tag, dc) bus_space_subregion(dc->dc_memt, dc->dc_memh, TGA_MEM_CREGS, TGA_CREGS_SIZE, &dc->dc_regs); - dc->dc_tga_type = tga_identify(dc); +} - tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type); - if (tgac == NULL) - return; +static void +tga_init(memt, pc, tag, dc) + bus_space_tag_t memt; + pci_chipset_tag_t pc; + pcitag_t tag; + struct tga_devconfig *dc; +{ + const struct tga_conf *tgac; + struct rasops_info *rip; + int cookie; + bus_size_t pcisize; + int i; + dc->dc_pcitag = tag; + tga_mapaddrs(memt, pc, tag, &pcisize, dc); + dc->dc_tga_type = tga_identify(dc); + tgac = dc->dc_tgaconf = tga_getconf(dc->dc_tga_type); #if 0 /* XXX on the Alpha, pcisize = 4 * cspace_size. */ if (tgac->tgac_cspace_size != pcisize) /* sanity */ - panic("tga_getdevconfig: memory size mismatch?"); + panic("tga_init: memory size mismatch?"); #endif switch (TGARREG(dc, TGA_REG_GREV) & 0xff) { @@ -238,7 +289,7 @@ tga_getdevconfig(memt, pc, tag, dc) dc->dc_tga2 = 1; break; default: - panic("tga_getdevconfig: TGA Revision not recognized"); + panic("tga_init: TGA Revision not recognized"); } if (dc->dc_tga2) { @@ -377,8 +428,7 @@ tgaattach(parent, self, aux) sc->sc_dc = (struct tga_devconfig *) malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_WAITOK); memset(sc->sc_dc, 0, sizeof(struct tga_devconfig)); - tga_getdevconfig(pa->pa_memt, pa->pa_pc, pa->pa_tag, - sc->sc_dc); + tga_init(pa->pa_memt, pa->pa_pc, pa->pa_tag, sc->sc_dc); } if (sc->sc_dc->dc_vaddr == NULL) { printf(": couldn't map memory space; punt!\n"); @@ -482,7 +532,6 @@ tga_config_interrupts (d) struct tga_softc *sc = (struct tga_softc *)d; sc->sc_dc->dc_intrenabled = 1; } - int tga_ioctl(v, cmd, data, flag, p) @@ -698,8 +747,7 @@ tga_cnattach(iot, memt, pc, bus, device, function) struct tga_devconfig *dcp = &tga_console_dc; long defattr; - tga_getdevconfig(memt, pc, - pci_make_tag(pc, bus, device, function), dcp); + tga_init(memt, pc, pci_make_tag(pc, bus, device, function), dcp); /* sanity checks */ if (dcp->dc_vaddr == NULL) diff --git a/sys/dev/pci/tgavar.h b/sys/dev/pci/tgavar.h index d17684db62b..309387c52e7 100644 --- a/sys/dev/pci/tgavar.h +++ b/sys/dev/pci/tgavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: tgavar.h,v 1.9 2000/04/20 05:25:20 nathanw Exp $ */ +/* $NetBSD: tgavar.h,v 1.10 2001/07/16 00:55:17 elric Exp $ */ /* * Copyright (c) 1995, 1996 Carnegie-Mellon University. @@ -117,6 +117,8 @@ struct tga_softc { PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) || \ PCI_PRODUCT(id) == PCI_PRODUCT_DEC_PBXGB) ? 10 : 0) +int tga_cnmatch __P((bus_space_tag_t, bus_space_tag_t, pci_chipset_tag_t, + pcitag_t)); int tga_cnattach __P((bus_space_tag_t, bus_space_tag_t, pci_chipset_tag_t, int, int, int)); |
