static int tdfx_clrmtrr(device_t dev) { /* This function removes the MTRR set by the attach call, so it can be used * in the future by other drivers. */ int retval, act; struct tdfx_softc *tdfx_info = device_get_softc(dev); act = MEMRANGE_SET_REMOVE; retval = mem_range_attr_set(&tdfx_info->mrdesc, &act); return retval; }
int drm_mtrr_add(unsigned long offset, unsigned long size, unsigned int flags) { int act; struct mem_range_desc mrdesc; mrdesc.mr_base = offset; mrdesc.mr_len = size; mrdesc.mr_flags = flags; act = MEMRANGE_SET_UPDATE; strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); return (-mem_range_attr_set(&mrdesc, &act)); }
int drm_mtrr_del(int __unused handle, unsigned long offset, size_t size, int flags) { int act; struct mem_range_desc mrdesc; mrdesc.mr_base = offset; mrdesc.mr_len = size; mrdesc.mr_flags = flags; act = MEMRANGE_SET_REMOVE; strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); return mem_range_attr_set(&mrdesc, &act); }
/* * Operations for changing memory attributes. * * This is basically just an ioctl shim for mem_range_attr_get * and mem_range_attr_set. */ static int mmioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct thread *td) { int nd, error = 0; struct mem_range_op *mo = (struct mem_range_op *)data; struct mem_range_desc *md; /* is this for us? */ if ((cmd != MEMRANGE_GET) && (cmd != MEMRANGE_SET)) return (ENOTTY); /* any chance we can handle this? */ if (mem_range_softc.mr_op == NULL) return (EOPNOTSUPP); /* do we have any descriptors? */ if (mem_range_softc.mr_ndesc == 0) return (ENXIO); switch (cmd) { case MEMRANGE_GET: nd = imin(mo->mo_arg[0], mem_range_softc.mr_ndesc); if (nd > 0) { md = (struct mem_range_desc *) malloc(nd * sizeof(struct mem_range_desc), M_MEMDESC, M_WAITOK); error = mem_range_attr_get(md, &nd); if (!error) error = copyout(md, mo->mo_desc, nd * sizeof(struct mem_range_desc)); free(md, M_MEMDESC); } else nd = mem_range_softc.mr_ndesc; mo->mo_arg[0] = nd; break; case MEMRANGE_SET: md = (struct mem_range_desc *)malloc(sizeof(struct mem_range_desc), M_MEMDESC, M_WAITOK); error = copyin(mo->mo_desc, md, sizeof(struct mem_range_desc)); /* clamp description string */ md->mr_owner[sizeof(md->mr_owner) - 1] = 0; if (error == 0) error = mem_range_attr_set(md, &mo->mo_arg[0]); free(md, M_MEMDESC); break; } return (error); }
int drm_mtrr_del(int handle, unsigned long offset, size_t size, int flags) { #ifndef DRM_NO_MTRR int act; struct mem_range_desc mrdesc; mrdesc.mr_base = offset; mrdesc.mr_len = size; mrdesc.mr_flags = flags; act = MEMRANGE_SET_REMOVE; strlcpy(mrdesc.mr_owner, "drm", sizeof(mrdesc.mr_owner)); return mem_range_attr_set(&mrdesc, &act); #else return 0; #endif }
static int tdfx_setmtrr(device_t dev) { /* * This is the MTRR setting function for the 3dfx card. It is called from * tdfx_attach. If we can't set the MTRR properly, it's not the end of the * world. We can still continue, just with slightly (very slightly) degraded * performance. */ int retval = 0, act; struct tdfx_softc *tdfx_info = device_get_softc(dev); /* The older Voodoo cards have a shorter memrange than the newer ones */ if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO1) || (pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO2)) { tdfx_info->mrdesc.mr_len = 0x400000; /* The memory descriptor is described as the top 15 bits of the real address */ tdfx_info->mrdesc.mr_base = tdfx_info->addr0 & 0xfffe0000; } else if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO3) || (pci_get_devid(dev) == PCI_DEVICE_3DFX_BANSHEE)) { tdfx_info->mrdesc.mr_len = 0x1000000; /* The Voodoo3 and Banshee LFB is the second memory address */ /* The memory descriptor is described as the top 15 bits of the real address */ tdfx_info->mrdesc.mr_base = tdfx_info->addr1 & 0xfffe0000; } else return 0; /* * The Alliance Pro Motion AT3D was not mentioned in the linux * driver as far as MTRR support goes, so I just won't put the * code in here for it. This is where it should go, though. */ /* Firstly, try to set write combining */ tdfx_info->mrdesc.mr_flags = MDF_WRITECOMBINE; bcopy("tdfx", &tdfx_info->mrdesc.mr_owner, 4); act = MEMRANGE_SET_UPDATE; retval = mem_range_attr_set(&tdfx_info->mrdesc, &act); if(retval == 0) { #ifdef DEBUG device_printf(dev, "MTRR Set Correctly for tdfx\n"); #endif } else if((pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO2) || (pci_get_devid(dev) == PCI_DEVICE_3DFX_VOODOO1)) { /* if, for some reason we can't set the WRCOMB range with the V1/V2, we * can still possibly use the UNCACHEABLE region for it instead, and help * out in a small way */ tdfx_info->mrdesc.mr_flags = MDF_UNCACHEABLE; /* This length of 1000h was taken from the linux device driver... */ tdfx_info->mrdesc.mr_len = 0x1000; /* * If, for some reason, we can't set the MTRR (N/A?) we may still continue */ #ifdef DEBUG device_printf(dev, "MTRR Set Type Uncacheable %x\n", (u_int32_t)tdfx_info->mrdesc.mr_base); #endif } #ifdef DEBUG else { device_printf(dev, "Couldn't Set MTRR\n"); return 0; } #endif return 0; }