> On 21/08/12(Tue) 20:58, Mark Kettenis wrote:
> > > Date: Tue, 21 Aug 2012 19:17:08 +0200
> > > From: Martin Pieuchot <[email protected]>
> > > 
> > > Diff below is mostly a rewrite of vgafb_pci_probe() to determine the
> > > memory and mmio regions based on previously initialized BAR structures.
> > > But it also includes the glue to attach drm(4) to vgafb(4).
> > > 
> > > It reuses the following functions from vga(4), the last three are
> > > required by any drm(4) driver:
> > >   - vga_pci_bar_init()
> > >   - vga_pci_bar_info()
> > >   - vga_pci_bar_map()
> > >   - vga_pci_bar_unmap()
> > 
> > Looks like by "reuses" you mean "copies".  That tends to be a bad idea
> > since results in diverging code.  WOuldn't it be better to split out
> > these functions into their own file (vga_pci_common.c) and share them
> > between vga(4) and vgafb(4)?
> 
> Sure, here's a diff that does only this, tested on i386 and macppc.
> I used Owain's copyright because he is the one who commited this code.
> 
> Ok?

Go for it.

(If it wasn't obvious yet, I intend to use this code on sparc64 as well)

> Index: pci/files.pci
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/files.pci,v
> retrieving revision 1.285
> diff -u -p -r1.285 files.pci
> --- pci/files.pci     14 Aug 2012 00:28:23 -0000      1.285
> +++ pci/files.pci     22 Aug 2012 15:03:50 -0000
> @@ -15,6 +15,7 @@ file        dev/pci/pci_subr.c              pci
>  # Generic VGA
>  attach       vga at pci with vga_pci
>  file dev/pci/vga_pci.c               vga_pci
> +file dev/pci/vga_pci_common.c        vga_pci
>  
>  device       tga: wsemuldisplaydev, rasops8, rasops32
>  attach       tga at pci
> Index: pci/vga_pci.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/vga_pci.c,v
> retrieving revision 1.67
> diff -u -p -r1.67 vga_pci.c
> --- pci/vga_pci.c     14 Apr 2011 21:04:29 -0000      1.67
> +++ pci/vga_pci.c     22 Aug 2012 15:03:36 -0000
> @@ -63,6 +63,7 @@
>   */
>  
>  #include "vga.h"
> +#include "drm.h"
>  #if defined(__i386__) || defined(__amd64__)
>  #include "acpi.h"
>  #endif
> @@ -90,7 +91,6 @@
>  #include <dev/ic/vgavar.h>
>  #include <dev/pci/vga_pcivar.h>
>  
> -
>  #include <dev/wscons/wsconsio.h>
>  #include <dev/wscons/wsdisplayvar.h>
>  
> @@ -103,22 +103,16 @@
>  #endif
>  
>  #include "intagp.h"
> -#include "drm.h"
>  
>  int  vga_pci_match(struct device *, void *, void *);
>  void vga_pci_attach(struct device *, struct device *, void *);
>  int  vga_pci_activate(struct device *, int);
>  paddr_t      vga_pci_mmap(void* v, off_t off, int prot);
> -void vga_pci_bar_init(struct vga_pci_softc *, struct pci_attach_args *);
>  
>  #if NINTAGP > 0
>  int  intagpsubmatch(struct device *, void *, void *);
>  int  intagp_print(void *, const char *);
>  #endif 
> -#if NDRM > 0
> -int  drmsubmatch(struct device *, void *, void *);
> -int  vga_drm_print(void *, const char *);
> -#endif
>  
>  #ifdef VESAFB
>  int  vesafb_putcmap(struct vga_pci_softc *, struct wsdisplay_cmap *);
> @@ -138,7 +132,7 @@ void      vga_restore_state(struct vga_pci_so
>   */
>  int  (*ws_get_param)(struct wsdisplay_param *);
>  int  (*ws_set_param)(struct wsdisplay_param *);
> -    
> +
>  
>  struct cfattach vga_pci_ca = {
>       sizeof(struct vga_pci_softc), vga_pci_match, vga_pci_attach,
> @@ -369,27 +363,6 @@ intagp_print(void *vaa, const char *pnp)
>  }
>  #endif
>  
> -#if NDRM > 0
> -int
> -drmsubmatch(struct device *parent, void *match, void *aux)
> -{
> -     struct cfdata *cf = match;
> -     struct cfdriver *cd;
> -     size_t len = 0;
> -     char *sm;
> -
> -     cd = cf->cf_driver;
> -
> -     /* is this a *drm device? */
> -     len = strlen(cd->cd_name);
> -     sm = cd->cd_name + len - 3;
> -     if (strncmp(sm, "drm", 3) == 0)
> -             return ((*cf->cf_attach->ca_match)(parent, match, aux));
> -
> -     return (0);
> -}
> -#endif
> -
>  paddr_t
>  vga_pci_mmap(void *v, off_t off, int prot)
>  {
> @@ -506,116 +479,6 @@ vga_pci_ioctl(void *v, u_long cmd, caddr
>       }
>  
>       return (error);
> -}
> -
> -#ifdef notyet
> -void
> -vga_pci_close(void *v)
> -{
> -}
> -#endif
> -
> -/*
> - * Prepare dev->bars to be used for information. we do this at startup
> - * so we can do the whole array at once, dealing with 64-bit BARs correctly.
> - */
> -void
> -vga_pci_bar_init(struct vga_pci_softc *dev, struct pci_attach_args *pa)
> -{
> -     pcireg_t type;
> -     int addr = PCI_MAPREG_START, i = 0;
> -     memcpy(&dev->pa, pa, sizeof(dev->pa));
> -
> -     while (i < VGA_PCI_MAX_BARS) {
> -             dev->bars[i] = malloc(sizeof((*dev->bars[i])), M_DEVBUF,
> -                 M_NOWAIT | M_ZERO);
> -             if (dev->bars[i] == NULL) {
> -                     return;
> -             }
> -
> -             dev->bars[i]->addr = addr;
> -
> -             type = dev->bars[i]->maptype = pci_mapreg_type(pa->pa_pc,
> -                 pa->pa_tag, addr);
> -             if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, addr,
> -                 dev->bars[i]->maptype, &dev->bars[i]->base,
> -                 &dev->bars[i]->maxsize, &dev->bars[i]->flags) != 0) {
> -                     free(dev->bars[i], M_DEVBUF);
> -                     dev->bars[i] = NULL;
> -             }
> -
> -             if (type == PCI_MAPREG_MEM_TYPE_64BIT) {
> -                     addr += 8;
> -                     i += 2;
> -             } else {
> -                     addr += 4;
> -                     i++;
> -             }
> -     }
> -}
> -
> -/*
> - * Get the vga_pci_bar struct for the address in question. returns NULL if
> - * invalid BAR is passed.
> - */
> -struct vga_pci_bar*
> -vga_pci_bar_info(struct vga_pci_softc *dev, int no)
> -{
> -     if (dev == NULL || no >= VGA_PCI_MAX_BARS)
> -             return (NULL);
> -     return (dev->bars[no]);
> -}
> -
> -/*
> - * map the BAR in question, returning the vga_pci_bar struct in case any more
> - * processing needs to be done. Returns NULL on failure. Can be called 
> multiple
> - * times.
> - */
> -struct vga_pci_bar*
> -vga_pci_bar_map(struct vga_pci_softc *dev, int addr, bus_size_t size,
> -    int busflags)
> -{
> -     struct vga_pci_bar *bar = NULL;
> -     int i;
> -
> -     if (dev == NULL) 
> -             return (NULL);
> -
> -     for (i = 0; i < VGA_PCI_MAX_BARS; i++) {
> -             if (dev->bars[i] && dev->bars[i]->addr == addr) {
> -                     bar = dev->bars[i];
> -                     break;
> -             }
> -     }
> -     if (bar == NULL) {
> -             printf("vga_pci_bar_map: given invalid address 0x%x\n", addr);
> -             return (NULL);
> -     }
> -
> -     if (bar->mapped == 0) {
> -             if (pci_mapreg_map(&dev->pa, bar->addr, bar->maptype,
> -                 bar->flags | busflags, &bar->bst, &bar->bsh, NULL,
> -                 &bar->size, size)) {
> -                     printf("vga_pci_bar_map: can't map bar 0x%x\n", addr);
> -                     return (NULL);
> -             }
> -     }
> -
> -     bar->mapped++;
> -     return (bar);
> -}
> -
> -/*
> - * "unmap" the BAR referred to by argument. If more than one place has 
> mapped it
> - * we just decrement the reference counter so nothing untoward happens.
> - */
> -void
> -vga_pci_bar_unmap(struct vga_pci_bar *bar)
> -{
> -     if (bar != NULL && bar->mapped != 0) {
> -             if (--bar->mapped == 0)
> -                     bus_space_unmap(bar->bst, bar->bsh, bar->size);
> -     }
>  }
>  
>  #if !defined(SMALL_KERNEL) && NACPI > 0
> Index: pci/vga_pci_common.c
> ===================================================================
> RCS file: pci/vga_pci_common.c
> diff -N pci/vga_pci_common.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ pci/vga_pci_common.c      22 Aug 2012 15:08:27 -0000
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (c) 2008 Owain G. Ainsworth <[email protected]>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#include "drm.h"
> +
> +#include <sys/param.h>
> +#include <sys/systm.h>
> +#include <sys/malloc.h>
> +
> +#include <machine/bus.h>
> +
> +#include <dev/pci/pcireg.h>
> +#include <dev/pci/pcivar.h>
> +#include <dev/pci/vga_pcivar.h>
> +
> +
> +#if NDRM > 0
> +int
> +drmsubmatch(struct device *parent, void *match, void *aux)
> +{
> +     struct cfdata *cf = match;
> +     struct cfdriver *cd;
> +     size_t len = 0;
> +     char *sm;
> +
> +     cd = cf->cf_driver;
> +
> +     /* is this a *drm device? */
> +     len = strlen(cd->cd_name);
> +     sm = cd->cd_name + len - 3;
> +     if (strncmp(sm, "drm", 3) == 0)
> +             return ((*cf->cf_attach->ca_match)(parent, match, aux));
> +
> +     return (0);
> +}
> +#endif
> +
> +/*
> + * Prepare dev->bars to be used for information. we do this at startup
> + * so we can do the whole array at once, dealing with 64-bit BARs correctly.
> + */
> +void
> +vga_pci_bar_init(struct vga_pci_softc *dev, struct pci_attach_args *pa)
> +{
> +     pcireg_t type;
> +     int addr = PCI_MAPREG_START, i = 0;
> +     memcpy(&dev->pa, pa, sizeof(dev->pa));
> +
> +     while (i < VGA_PCI_MAX_BARS) {
> +             dev->bars[i] = malloc(sizeof((*dev->bars[i])), M_DEVBUF,
> +                 M_NOWAIT | M_ZERO);
> +             if (dev->bars[i] == NULL) {
> +                     return;
> +             }
> +
> +             dev->bars[i]->addr = addr;
> +
> +             type = dev->bars[i]->maptype = pci_mapreg_type(pa->pa_pc,
> +                 pa->pa_tag, addr);
> +             if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, addr,
> +                 dev->bars[i]->maptype, &dev->bars[i]->base,
> +                 &dev->bars[i]->maxsize, &dev->bars[i]->flags) != 0) {
> +                     free(dev->bars[i], M_DEVBUF);
> +                     dev->bars[i] = NULL;
> +             }
> +
> +             if (type == PCI_MAPREG_MEM_TYPE_64BIT) {
> +                     addr += 8;
> +                     i += 2;
> +             } else {
> +                     addr += 4;
> +                     i++;
> +             }
> +     }
> +}
> +
> +/*
> + * Get the vga_pci_bar struct for the address in question. returns NULL if
> + * invalid BAR is passed.
> + */
> +struct vga_pci_bar*
> +vga_pci_bar_info(struct vga_pci_softc *dev, int no)
> +{
> +     if (dev == NULL || no >= VGA_PCI_MAX_BARS)
> +             return (NULL);
> +     return (dev->bars[no]);
> +}
> +
> +/*
> + * map the BAR in question, returning the vga_pci_bar struct in case any more
> + * processing needs to be done. Returns NULL on failure. Can be called 
> multiple
> + * times.
> + */
> +struct vga_pci_bar*
> +vga_pci_bar_map(struct vga_pci_softc *dev, int addr, bus_size_t size,
> +    int busflags)
> +{
> +     struct vga_pci_bar *bar = NULL;
> +     int i;
> +
> +     if (dev == NULL)
> +             return (NULL);
> +
> +     for (i = 0; i < VGA_PCI_MAX_BARS; i++) {
> +             if (dev->bars[i] && dev->bars[i]->addr == addr) {
> +                     bar = dev->bars[i];
> +                     break;
> +             }
> +     }
> +     if (bar == NULL) {
> +             printf("vga_pci_bar_map: given invalid address 0x%x\n", addr);
> +             return (NULL);
> +     }
> +
> +     if (bar->mapped == 0) {
> +             if (pci_mapreg_map(&dev->pa, bar->addr, bar->maptype,
> +                 bar->flags | busflags, &bar->bst, &bar->bsh, NULL,
> +                 &bar->size, size)) {
> +                     printf("vga_pci_bar_map: can't map bar 0x%x\n", addr);
> +                     return (NULL);
> +             }
> +     }
> +
> +     bar->mapped++;
> +     return (bar);
> +}
> +
> +/*
> + * "unmap" the BAR referred to by argument. If more than one place has 
> mapped it
> + * we just decrement the reference counter so nothing untoward happens.
> + */
> +void
> +vga_pci_bar_unmap(struct vga_pci_bar *bar)
> +{
> +     if (bar != NULL && bar->mapped != 0) {
> +             if (--bar->mapped == 0)
> +                     bus_space_unmap(bar->bst, bar->bsh, bar->size);
> +     }
> +}
> Index: pci/vga_pcivar.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/vga_pcivar.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 vga_pcivar.h
> --- pci/vga_pcivar.h  8 Aug 2010 17:21:07 -0000       1.14
> +++ pci/vga_pcivar.h  22 Aug 2012 15:03:36 -0000
> @@ -85,10 +85,15 @@ struct vga_pci_softc {
>  
>  int  vga_pci_cnattach(bus_space_tag_t, bus_space_tag_t,
>           pci_chipset_tag_t, int, int, int);
> +void vga_pci_bar_init(struct vga_pci_softc *, struct pci_attach_args *);
>  struct       vga_pci_bar *vga_pci_bar_info(struct vga_pci_softc *, int);
>  struct       vga_pci_bar *vga_pci_bar_map(struct vga_pci_softc *, int,
>           bus_size_t, int);
>  void vga_pci_bar_unmap(struct vga_pci_bar*);
> +
> +#if NDRM > 0
> +int  drmsubmatch(struct device *, void *, void *);
> +#endif
>  
>  #ifdef VESAFB
>  int  vesafb_find_mode(struct vga_pci_softc *, int, int, int);

Reply via email to