Fix the MGA driver on BSD by passing in the proper chipset flags to the
driver's preinit routine, and by using DRM_COPY_TO_USER_IOCTL when copying out to an ioctl's data pointer. Pulled from the latest version of my drm-hook-rename.diff and only compile-tested after that.main
parent
49bbb6d861
commit
b0da5df90a
|
@ -653,6 +653,8 @@ struct drm_device {
|
||||||
void (*irq_handler)(DRM_IRQ_ARGS);
|
void (*irq_handler)(DRM_IRQ_ARGS);
|
||||||
int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence);
|
int (*vblank_wait)(drm_device_t *dev, unsigned int *sequence);
|
||||||
|
|
||||||
|
drm_pci_id_list_t *id_entry; /* PCI ID, name, and chipset private */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by \c drm_device_is_agp. Typically used to determine if a
|
* Called by \c drm_device_is_agp. Typically used to determine if a
|
||||||
* card is really attached to AGP or not.
|
* card is really attached to AGP or not.
|
||||||
|
|
|
@ -36,8 +36,10 @@
|
||||||
|
|
||||||
int drm_debug_flag = 0;
|
int drm_debug_flag = 0;
|
||||||
|
|
||||||
static int drm_init(device_t nbdev);
|
static int drm_init(drm_device_t *dev);
|
||||||
static void drm_cleanup(drm_device_t *dev);
|
static void drm_cleanup(drm_device_t *dev);
|
||||||
|
static drm_pci_id_list_t *drm_find_description(int vendor, int device,
|
||||||
|
drm_pci_id_list_t *idlist);
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#define DRIVER_SOFTC(unit) \
|
#define DRIVER_SOFTC(unit) \
|
||||||
|
@ -116,8 +118,6 @@ static drm_ioctl_desc_t drm_ioctls[256] = {
|
||||||
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 },
|
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = { drm_wait_vblank, 0, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist);
|
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
static struct cdevsw drm_cdevsw = {
|
static struct cdevsw drm_cdevsw = {
|
||||||
#if __FreeBSD_version >= 502103
|
#if __FreeBSD_version >= 502103
|
||||||
|
@ -143,23 +143,49 @@ static struct cdevsw drm_cdevsw = {
|
||||||
|
|
||||||
int drm_probe(device_t dev, drm_pci_id_list_t *idlist)
|
int drm_probe(device_t dev, drm_pci_id_list_t *idlist)
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
drm_pci_id_list_t *id_entry;
|
||||||
int vendor, device;
|
int vendor, device;
|
||||||
|
|
||||||
vendor = pci_get_vendor(dev);
|
vendor = pci_get_vendor(dev);
|
||||||
device = pci_get_device(dev);
|
device = pci_get_device(dev);
|
||||||
|
|
||||||
s = drm_find_description(vendor, device, idlist);
|
id_entry = drm_find_description(vendor, device, idlist);
|
||||||
if (s != NULL) {
|
if (id_entry != NULL) {
|
||||||
device_set_desc(dev, s);
|
device_set_desc(dev, id_entry->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int drm_attach(device_t dev, drm_pci_id_list_t *idlist)
|
int drm_attach(device_t nbdev, drm_pci_id_list_t *idlist)
|
||||||
{
|
{
|
||||||
|
drm_device_t *dev;
|
||||||
|
drm_pci_id_list_t *id_entry;
|
||||||
|
int unit;
|
||||||
|
|
||||||
|
unit = device_get_unit(nbdev);
|
||||||
|
dev = device_get_softc(nbdev);
|
||||||
|
|
||||||
|
if (!strcmp(device_get_name(nbdev), "drmsub"))
|
||||||
|
dev->device = device_get_parent(nbdev);
|
||||||
|
else
|
||||||
|
dev->device = nbdev;
|
||||||
|
|
||||||
|
dev->devnode = make_dev(&drm_cdevsw,
|
||||||
|
unit,
|
||||||
|
DRM_DEV_UID,
|
||||||
|
DRM_DEV_GID,
|
||||||
|
DRM_DEV_MODE,
|
||||||
|
"dri/card%d", unit);
|
||||||
|
#if __FreeBSD_version >= 500000
|
||||||
|
mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
id_entry = drm_find_description(pci_get_vendor(nbdev),
|
||||||
|
pci_get_device(nbdev), idlist);
|
||||||
|
dev->id_entry = id_entry;
|
||||||
|
|
||||||
return drm_init(dev);
|
return drm_init(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,10 +280,11 @@ int drm_modprobe(void)
|
||||||
int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t idlist)
|
int drm_probe(struct pci_attach_args *pa, drm_pci_id_list_t idlist)
|
||||||
{
|
{
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
drm_pci_id_list_t *id_entry;
|
||||||
|
|
||||||
desc = drm_find_description(PCI_VENDOR(pa->pa_id),
|
id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
|
||||||
PCI_PRODUCT(pa->pa_id), idlist);
|
PCI_PRODUCT(pa->pa_id), idlist);
|
||||||
if (desc != NULL) {
|
if (id_entry != NULL) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,6 +311,10 @@ void drm_attach(struct pci_attach_args *pa, dev_t kdev,
|
||||||
dev->pci_func = pa->pa_function;
|
dev->pci_func = pa->pa_function;
|
||||||
dev->dma_tag = pa->pa_dmat;
|
dev->dma_tag = pa->pa_dmat;
|
||||||
|
|
||||||
|
id_entry = drm_find_description(PCI_VENDOR(pa->pa_id),
|
||||||
|
PCI_PRODUCT(pa->pa_id), idlist);
|
||||||
|
dev->driver.pci_id_entry = id_entry;
|
||||||
|
|
||||||
DRM_INFO("%s", drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist));
|
DRM_INFO("%s", drm_find_description(PCI_VENDOR(pa->pa_id), PCI_PRODUCT(pa->pa_id), idlist));
|
||||||
drm_init(dev);
|
drm_init(dev);
|
||||||
}
|
}
|
||||||
|
@ -309,13 +340,15 @@ int drm_activate(struct device *self, enum devact act)
|
||||||
}
|
}
|
||||||
#endif /* __NetBSD__ || __OpenBSD__ */
|
#endif /* __NetBSD__ || __OpenBSD__ */
|
||||||
|
|
||||||
const char *drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist) {
|
drm_pci_id_list_t *drm_find_description(int vendor, int device,
|
||||||
|
drm_pci_id_list_t *idlist)
|
||||||
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (i = 0; idlist[i].vendor != 0; i++) {
|
for (i = 0; idlist[i].vendor != 0; i++) {
|
||||||
if ((idlist[i].vendor == vendor) &&
|
if ((idlist[i].vendor == vendor) &&
|
||||||
(idlist[i].device == device)) {
|
(idlist[i].device == device)) {
|
||||||
return idlist[i].name;
|
return &idlist[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -452,36 +485,11 @@ static int drm_takedown(drm_device_t *dev)
|
||||||
* linux/init/main.c (this is not currently supported).
|
* linux/init/main.c (this is not currently supported).
|
||||||
* bsd: drm_init is called via the attach function per device.
|
* bsd: drm_init is called via the attach function per device.
|
||||||
*/
|
*/
|
||||||
static int drm_init(device_t nbdev)
|
static int drm_init(drm_device_t *dev)
|
||||||
{
|
{
|
||||||
int unit;
|
|
||||||
drm_device_t *dev;
|
|
||||||
int retcode;
|
int retcode;
|
||||||
DRM_DEBUG( "\n" );
|
DRM_DEBUG( "\n" );
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
|
||||||
unit = device_get_unit(nbdev);
|
|
||||||
dev = device_get_softc(nbdev);
|
|
||||||
|
|
||||||
if (!strcmp(device_get_name(nbdev), "drmsub"))
|
|
||||||
dev->device = device_get_parent(nbdev);
|
|
||||||
else
|
|
||||||
dev->device = nbdev;
|
|
||||||
|
|
||||||
dev->devnode = make_dev(&drm_cdevsw,
|
|
||||||
unit,
|
|
||||||
DRM_DEV_UID,
|
|
||||||
DRM_DEV_GID,
|
|
||||||
DRM_DEV_MODE,
|
|
||||||
"dri/card%d", unit);
|
|
||||||
#if __FreeBSD_version >= 500000
|
|
||||||
mtx_init(&dev->dev_lock, "drm device", NULL, MTX_DEF);
|
|
||||||
#endif
|
|
||||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
|
||||||
dev = nbdev;
|
|
||||||
unit = minor(dev->device.dv_unit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dev->irq = pci_get_irq(dev->device);
|
dev->irq = pci_get_irq(dev->device);
|
||||||
/* XXX Fix domain number (alpha hoses) */
|
/* XXX Fix domain number (alpha hoses) */
|
||||||
dev->pci_domain = 0;
|
dev->pci_domain = 0;
|
||||||
|
@ -498,7 +506,7 @@ static int drm_init(device_t nbdev)
|
||||||
TAILQ_INIT(&dev->files);
|
TAILQ_INIT(&dev->files);
|
||||||
|
|
||||||
if (dev->preinit != NULL) {
|
if (dev->preinit != NULL) {
|
||||||
retcode = dev->preinit(dev, 0);
|
retcode = dev->preinit(dev, dev->id_entry->driver_private);
|
||||||
if (retcode != 0)
|
if (retcode != 0)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
@ -525,13 +533,12 @@ static int drm_init(device_t nbdev)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
DRM_INFO( "Initialized %s %d.%d.%d %s on minor %d\n",
|
DRM_INFO("Initialized %s %d.%d.%d %s\n",
|
||||||
dev->driver_name,
|
dev->driver_name,
|
||||||
dev->driver_major,
|
dev->driver_major,
|
||||||
dev->driver_minor,
|
dev->driver_minor,
|
||||||
dev->driver_patchlevel,
|
dev->driver_patchlevel,
|
||||||
dev->driver_date,
|
dev->driver_date);
|
||||||
unit );
|
|
||||||
|
|
||||||
if (dev->postinit != NULL)
|
if (dev->postinit != NULL)
|
||||||
dev->postinit(dev, 0);
|
dev->postinit(dev, 0);
|
||||||
|
|
|
@ -723,6 +723,9 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
|
||||||
DRM_DEVICE;
|
DRM_DEVICE;
|
||||||
drm_mga_dma_bootstrap_t bootstrap;
|
drm_mga_dma_bootstrap_t bootstrap;
|
||||||
int err;
|
int err;
|
||||||
|
static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
|
||||||
|
const drm_mga_private_t * const dev_priv =
|
||||||
|
(drm_mga_private_t *) dev->dev_private;
|
||||||
|
|
||||||
|
|
||||||
DRM_COPY_FROM_USER_IOCTL(bootstrap,
|
DRM_COPY_FROM_USER_IOCTL(bootstrap,
|
||||||
|
@ -730,31 +733,26 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
|
||||||
sizeof(bootstrap));
|
sizeof(bootstrap));
|
||||||
|
|
||||||
err = mga_do_dma_bootstrap(dev, & bootstrap);
|
err = mga_do_dma_bootstrap(dev, & bootstrap);
|
||||||
if (! err) {
|
if (err) {
|
||||||
static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
|
mga_do_cleanup_dma(dev);
|
||||||
const drm_mga_private_t * const dev_priv =
|
return err;
|
||||||
(drm_mga_private_t *) dev->dev_private;
|
}
|
||||||
|
|
||||||
if (dev_priv->agp_textures != NULL) {
|
if (dev_priv->agp_textures != NULL) {
|
||||||
bootstrap.texture_handle = dev_priv->agp_textures->offset;
|
bootstrap.texture_handle = dev_priv->agp_textures->offset;
|
||||||
bootstrap.texture_size = dev_priv->agp_textures->size;
|
bootstrap.texture_size = dev_priv->agp_textures->size;
|
||||||
}
|
|
||||||
else {
|
|
||||||
bootstrap.texture_handle = 0;
|
|
||||||
bootstrap.texture_size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bootstrap.agp_mode = modes[ bootstrap.agp_mode & 0x07 ];
|
|
||||||
if (DRM_COPY_TO_USER( (void __user *) data, & bootstrap,
|
|
||||||
sizeof(bootstrap))) {
|
|
||||||
err = DRM_ERR(EFAULT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mga_do_cleanup_dma(dev);
|
bootstrap.texture_handle = 0;
|
||||||
|
bootstrap.texture_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
|
||||||
|
|
||||||
|
DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data,
|
||||||
|
bootstrap, sizeof(bootstrap));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1130,10 +1130,7 @@ static int mga_set_fence(DRM_IOCTL_ARGS)
|
||||||
MGA_SOFTRAP, 0x00000000);
|
MGA_SOFTRAP, 0x00000000);
|
||||||
ADVANCE_DMA();
|
ADVANCE_DMA();
|
||||||
|
|
||||||
if (DRM_COPY_TO_USER( (u32 __user *) data, & temp, sizeof(u32))) {
|
DRM_COPY_TO_USER_IOCTL((u32 __user *)data, temp, sizeof(u32));
|
||||||
DRM_ERROR("copy_to_user\n");
|
|
||||||
return DRM_ERR(EFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1155,10 +1152,7 @@ static int mga_wait_fence(DRM_IOCTL_ARGS)
|
||||||
|
|
||||||
mga_driver_fence_wait(dev, & fence);
|
mga_driver_fence_wait(dev, & fence);
|
||||||
|
|
||||||
if (DRM_COPY_TO_USER( (u32 __user *) data, & fence, sizeof(u32))) {
|
DRM_COPY_TO_USER_IOCTL((u32 __user *)data, fence, sizeof(u32));
|
||||||
DRM_ERROR("copy_to_user\n");
|
|
||||||
return DRM_ERR(EFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue