VirtualBox

Changeset 63339 in vbox for trunk/src/VBox/Additions


Ignore:
Timestamp:
Aug 11, 2016 1:02:31 PM (8 years ago)
Author:
vboxsync
Message:

Additions/common/VBoxGuest: NetBSD support, based on FreeBSD version.

From Haomai Wang GSoC project with additional changes by Arto Huusko.
Adapted to catch up on changes in the VirtualBox tree.

TODO: Needs more stylistic changes to conform to our style and the
diff to the FreeBSD can be further reduced.

Location:
trunk/src/VBox/Additions/common/VBoxGuest
Files:
1 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk

    r63108 r63339  
    2020
    2121
    22 if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
     22if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) netbsd os2 solaris win)
    2323 #
    2424 # VBoxGuest - The Guest Additions Driver.
     
    2929 VBoxGuest_NAME.haiku    = vboxguest
    3030 VBoxGuest_NAME.linux    = vboxguest
     31 VBoxGuest_NAME.netbsd   = vboxguest
    3132 VBoxGuest_NAME.solaris  = vboxguest
    3233 VBoxGuest_INST.darwin   = $(INST_ADDITIONS)VBoxGuest.kext/Contents/MacOS/
     
    5556 VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
    5657 VBoxGuest_DEPS.freebsd += $(VBOX_SVN_REV_HEADER)
     58 VBoxGuest_DEPS.netbsd  += $(VBOX_SVN_REV_HEADER)
    5759 VBoxGuest_DEPS.darwin  += $(VBOX_SVN_REV_HEADER)
    5860 VBoxGuest_DEFS          = VBGL_VBOXGUEST VBOX_WITH_HGCM
    5961 VBoxGuest_INCS          = .
    6062 VBoxGuest_INCS.freebsd  = $(VBoxGuest_0_OUTDIR) $(PATH_STAGE)/gen-sys-hdrs
     63 VBoxGuest_INCS.netbsd   = $(VBoxGuest_0_OUTDIR)
    6164 VBoxGuest_INCS.linux    = ../../../Runtime/r0drv/linux
    6265 ifeq ($(KBUILD_HOST),solaris)
     
    8184   endif
    8285  endif # win
    83   ifn1of ($(KBUILD_TARGET), linux freebsd solaris haiku)
     86  ifn1of ($(KBUILD_TARGET), linux freebsd netbsd solaris haiku)
    8487   VBoxGuest_SOURCES    = VBoxGuest-$(KBUILD_TARGET).cpp
    8588  else
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-netbsd.c

    r63291 r63339  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Guest Additions Driver for FreeBSD.
     3 * VirtualBox Guest Additions Driver for NetBSD.
    44 */
    55
     
    1616 */
    1717
    18 /** @todo r=bird: This must merge with SUPDrv-freebsd.c before long. The two
     18/** @todo r=bird: This must merge with SUPDrv-netbsd.c before long. The two
    1919 * source files should only differ on prefixes and the extra bits wrt to the
    2020 * pci device. I.e. it should be diffable so that fixes to one can easily be
     
    2626*********************************************************************************************************************************/
    2727#include <sys/param.h>
    28 #undef PVM
    29 #include <sys/types.h>
     28#include <sys/systm.h>
     29#include <sys/select.h>
     30#include <sys/conf.h>
     31#include <sys/kernel.h>
     32#include <sys/kmem.h>
    3033#include <sys/module.h>
    31 #include <sys/systm.h>
    32 #include <sys/errno.h>
    33 #include <sys/kernel.h>
    34 #include <sys/fcntl.h>
    35 #include <sys/conf.h>
    36 #include <sys/uio.h>
     34#include <sys/device.h>
    3735#include <sys/bus.h>
    3836#include <sys/poll.h>
     37#include <sys/proc.h>
     38#include <sys/stat.h>
    3939#include <sys/selinfo.h>
    4040#include <sys/queue.h>
    4141#include <sys/lock.h>
    42 #include <sys/lockmgr.h>
     42#include <sys/types.h>
     43#include <sys/conf.h>
    4344#include <sys/malloc.h>
     45#include <sys/uio.h>
    4446#include <sys/file.h>
    45 #include <sys/rman.h>
    46 #include <machine/bus.h>
    47 #include <machine/resource.h>
     47#include <sys/filedesc.h>
     48#include <sys/vfs_syscalls.h>
    4849#include <dev/pci/pcivar.h>
    4950#include <dev/pci/pcireg.h>
    50 
     51#include <dev/pci/pcidevs.h>
     52
     53#ifdef PVM
     54#  undef PVM
     55#endif
    5156#include "VBoxGuestInternal.h"
    52 #include <VBox/version.h>
    5357#include <VBox/log.h>
    5458#include <iprt/assert.h>
     
    6973*   Structures and Typedefs                                                                                                      *
    7074*********************************************************************************************************************************/
    71 struct VBoxGuestDeviceState
    72 {
    73     /** Resource ID of the I/O port */
    74     int                iIOPortResId;
    75     /** Pointer to the I/O port resource. */
    76     struct resource   *pIOPortRes;
    77     /** Start address of the IO Port. */
    78     uint16_t           uIOPortBase;
    79     /** Resource ID of the MMIO area */
    80     int                iVMMDevMemResId;
    81     /** Pointer to the MMIO resource. */
    82     struct resource   *pVMMDevMemRes;
    83     /** Handle of the MMIO resource. */
     75typedef struct VBoxGuestDeviceState
     76{
     77    device_t sc_dev;
     78    struct pci_attach_args *pa;
     79    bus_space_tag_t io_tag;
     80    bus_space_handle_t io_handle;
     81    bus_addr_t uIOPortBase;
     82    bus_size_t io_regsize;
     83    bus_space_tag_t iVMMDevMemResId;
    8484    bus_space_handle_t VMMDevMemHandle;
     85
    8586    /** Size of the memory area. */
    8687    bus_size_t         VMMDevMemSize;
    8788    /** Mapping of the register space */
    88     void              *pMMIOBase;
    89     /** IRQ number */
    90     int                iIrqResId;
     89    bus_addr_t         pMMIOBase;
     90
    9191    /** IRQ resource handle. */
    92     struct resource   *pIrqRes;
     92    pci_intr_handle_t  ih;
    9393    /** Pointer to the IRQ handler. */
    9494    void              *pfnIrqHandler;
    95     /** VMMDev version */
    96     uint32_t           u32Version;
     95
     96    /** Controller features, limits and status. */
     97    u_int              vboxguest_state;
     98} vboxguest_softc;
     99
     100
     101struct vboxguest_session
     102{
     103    vboxguest_softc *sc;
     104    PVBOXGUESTSESSION session;
    97105};
    98106
     107#define VBOXGUEST_STATE_INITOK 1 << 0
    99108
    100109/*********************************************************************************************************************************
     
    104113 * Character device file handlers.
    105114 */
    106 static d_fdopen_t vgdrvFreeBSDOpen;
    107 static d_close_t  vgdrvFreeBSDClose;
    108 static d_ioctl_t  vgdrvFreeBSDIOCtl;
    109 static d_write_t  vgdrvFreeBSDWrite;
    110 static d_read_t   vgdrvFreeBSDRead;
    111 static d_poll_t   vgdrvFreeBSDPoll;
     115static int VBoxGuestNetBSDOpen(dev_t device, int flags, int fmt, struct lwp *process);
     116static int VBoxGuestNetBSDClose(struct file *fp);
     117static int VBoxGuestNetBSDIOCtl(struct file *fp, u_long cmd, void *addr);
     118static int VBoxGuestNetBSDPoll(struct file *fp, int events);
     119static void VBoxGuestNetBSDAttach(device_t, device_t, void*);
     120static int VBoxGuestNetBSDDetach(device_t pDevice, int flags);
    112121
    113122/*
    114123 * IRQ related functions.
    115124 */
    116 static void vgdrvFreeBSDRemoveIRQ(device_t pDevice, void *pvState);
    117 static int  vgdrvFreeBSDAddIRQ(device_t pDevice, void *pvState);
    118 static int  vgdrvFreeBSDISR(void *pvState);
     125static void VBoxGuestNetBSDRemoveIRQ(vboxguest_softc *sc);
     126static int  VBoxGuestNetBSDAddIRQ(vboxguest_softc *pvState);
     127static int  VBoxGuestNetBSDISR(void *pvState);
    119128
    120129
     
    122131*   Global Variables                                                                                                             *
    123132*********************************************************************************************************************************/
    124 static MALLOC_DEFINE(M_VBOXGUEST, "vboxguest", "VirtualBox Guest Device Driver");
    125 
    126 #ifndef D_NEEDMINOR
    127 # define D_NEEDMINOR 0
    128 #endif
    129 
    130133/*
    131134 * The /dev/vboxguest character device entry points.
    132135 */
    133 static struct cdevsw    g_vgdrvFreeBSDChrDevSW =
    134 {
    135     .d_version =        D_VERSION,
    136     .d_flags =          D_TRACKCLOSE | D_NEEDMINOR,
    137     .d_fdopen =         vgdrvFreeBSDOpen,
    138     .d_close =          vgdrvFreeBSDClose,
    139     .d_ioctl =          vgdrvFreeBSDIOCtl,
    140     .d_read =           vgdrvFreeBSDRead,
    141     .d_write =          vgdrvFreeBSDWrite,
    142     .d_poll =           vgdrvFreeBSDPoll,
    143     .d_name =           "vboxguest"
     136static struct cdevsw g_VBoxGuestNetBSDChrDevSW =
     137{
     138    VBoxGuestNetBSDOpen,
     139    noclose,
     140    noread,
     141    nowrite,
     142    noioctl,
     143    nostop,
     144    notty,
     145    nopoll,
     146    nommap,
     147    nokqfilter,
     148};
     149
     150static const struct fileops vboxguest_fileops = {
     151        .fo_read = fbadop_read,
     152        .fo_write = fbadop_write,
     153        .fo_ioctl = VBoxGuestNetBSDIOCtl,
     154        .fo_fcntl = fnullop_fcntl,
     155        .fo_poll = VBoxGuestNetBSDPoll,
     156        .fo_stat = fbadop_stat,
     157        .fo_close = VBoxGuestNetBSDClose,
     158        .fo_kqfilter = fnullop_kqfilter,
     159        .fo_restart = fnullop_restart
    144160};
    145161
    146162/** Device extention & session data association structure. */
    147163static VBOXGUESTDEVEXT      g_DevExt;
    148 
    149 /** List of cloned device. Managed by the kernel. */
    150 static struct clonedevs    *g_pvgdrvFreeBSDClones;
    151 /** The dev_clone event handler tag. */
    152 static eventhandler_tag     g_vgdrvFreeBSDEHTag;
    153164/** Reference counter */
    154165static volatile uint32_t    cUsers;
     
    156167static struct selinfo       g_SelInfo;
    157168
    158 /**
    159  * DEVFS event handler.
    160  */
    161 static void vgdrvFreeBSDClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
    162 {
    163     int iUnit;
    164     int rc;
    165 
    166     Log(("vgdrvFreeBSDClone: pszName=%s ppDev=%p\n", pszName, ppDev));
    167 
    168     /*
    169      * One device node per user, si_drv1 points to the session.
    170      * /dev/vboxguest<N> where N = {0...255}.
    171      */
    172     if (!ppDev)
    173         return;
    174     if (strcmp(pszName, "vboxguest") == 0)
    175         iUnit =  -1;
    176     else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)
    177         return;
    178     if (iUnit >= 256)
    179     {
    180         Log(("vgdrvFreeBSDClone: iUnit=%d >= 256 - rejected\n", iUnit));
    181         return;
    182     }
    183 
    184     Log(("vgdrvFreeBSDClone: pszName=%s iUnit=%d\n", pszName, iUnit));
    185 
    186     rc = clone_create(&g_pvgdrvFreeBSDClones, &g_vgdrvFreeBSDChrDevSW, &iUnit, ppDev, 0);
    187     Log(("vgdrvFreeBSDClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
    188     if (rc)
    189     {
    190         *ppDev = make_dev(&g_vgdrvFreeBSDChrDevSW,
    191                           iUnit,
    192                           UID_ROOT,
    193                           GID_WHEEL,
    194                           0664,
    195                           "vboxguest%d", iUnit);
    196         if (*ppDev)
    197         {
    198             dev_ref(*ppDev);
    199             (*ppDev)->si_flags |= SI_CHEAPCLONE;
    200             Log(("vgdrvFreeBSDClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
    201                      *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
    202             (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
    203         }
    204         else
    205             Log(("vgdrvFreeBSDClone: make_dev iUnit=%d failed\n", iUnit));
    206     }
    207     else
    208         Log(("vgdrvFreeBSDClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
    209              *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
    210 }
     169CFDRIVER_DECL(vboxguest, DV_DULL, NULL);
     170extern struct cfdriver vboxguest_cd;
    211171
    212172/**
     
    214174 *
    215175 */
    216 #if __FreeBSD_version >= 700000
    217 static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd, struct file *pFd)
    218 #else
    219 static int vgdrvFreeBSDOpen(struct cdev *pDev, int fOpen, struct thread *pTd)
    220 #endif
    221 {
    222     int                 rc;
    223     PVBOXGUESTSESSION   pSession;
    224 
    225     LogFlow(("vgdrvFreeBSDOpen:\n"));
    226 
    227     /*
    228      * Try grab it (we don't grab the giant, remember).
    229      */
    230     if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, (void *)0x42, NULL))
    231         return EBUSY;
     176static int VBoxGuestNetBSDOpen(dev_t device, int flags, int fmt, struct lwp *process)
     177{
     178    int rc;
     179    vboxguest_softc *vboxguest;
     180    struct vboxguest_session *session;
     181    file_t *fp;
     182    int fd, error;
     183
     184    LogFlow((DEVICE_NAME ":VBoxGuestNetBSDOpen\n"));
     185
     186    if ((vboxguest = device_lookup_private(&vboxguest_cd, minor(device))) == NULL) {
     187        printf("device_lookup_private failed\n");
     188        return (ENXIO);
     189    }
     190    if ((vboxguest->vboxguest_state & VBOXGUEST_STATE_INITOK) == 0) {
     191        aprint_error_dev(vboxguest->sc_dev, "device not configured\n");
     192        return (ENXIO);
     193    }
     194
     195    session = kmem_alloc(sizeof(*session), KM_SLEEP);
     196    if (session == NULL) {
     197        return (ENOMEM);
     198    }
     199
     200    session->sc = vboxguest;
     201
     202    if ((error = fd_allocfile(&fp, &fd)) != 0) {
     203        kmem_free(session, sizeof(*session));
     204        return error;
     205    }
    232206
    233207    /*
    234208     * Create a new session.
    235209     */
    236     rc = VGDrvCommonCreateUserSession(&g_DevExt, &pSession);
    237     if (RT_SUCCESS(rc))
    238     {
    239         if (ASMAtomicCmpXchgPtr(&pDev->si_drv1, pSession, (void *)0x42))
    240         {
    241             Log(("vgdrvFreeBSDOpen: success - g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
    242             ASMAtomicIncU32(&cUsers);
    243             return 0;
    244         }
    245 
    246         VGDrvCommonCloseSession(&g_DevExt, pSession);
    247     }
    248 
    249     LogRel(("vgdrvFreeBSDOpen: failed. rc=%d\n", rc));
    250     return RTErrConvertToErrno(rc);
     210    rc = VGDrvCommonCreateUserSession(&g_DevExt, &session->session);
     211    if (! RT_SUCCESS(rc))
     212    {
     213        aprint_error_dev(vboxguest->sc_dev, "VBox session creation failed\n");
     214        closef(fp); /* ??? */
     215        kmem_free(session, sizeof(*session));
     216        return RTErrConvertToErrno(rc);
     217    }
     218    ASMAtomicIncU32(&cUsers);
     219    return fd_clone(fp, fd, flags, &vboxguest_fileops, session);
     220
    251221}
    252222
     
    255225 *
    256226 */
    257 static int vgdrvFreeBSDClose(struct cdev *pDev, int fFile, int DevType, struct thread *pTd)
    258 {
    259     PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;
    260     Log(("vgdrvFreeBSDClose: fFile=%#x pSession=%p\n", fFile, pSession));
    261 
    262     /*
    263      * Close the session if it's still hanging on to the device...
    264      */
    265     if (VALID_PTR(pSession))
    266     {
    267         VGDrvCommonCloseSession(&g_DevExt, pSession);
    268         if (!ASMAtomicCmpXchgPtr(&pDev->si_drv1, NULL, pSession))
    269             Log(("vgdrvFreeBSDClose: si_drv1=%p expected %p!\n", pDev->si_drv1, pSession));
    270         ASMAtomicDecU32(&cUsers);
    271         /* Don't use destroy_dev here because it may sleep resulting in a hanging user process. */
    272         destroy_dev_sched(pDev);
    273     }
    274     else
    275         Log(("vgdrvFreeBSDClose: si_drv1=%p!\n", pSession));
     227static int VBoxGuestNetBSDClose(struct file *fp)
     228{
     229    struct vboxguest_session *session = fp->f_data;
     230    vboxguest_softc *vboxguest = session->sc;
     231
     232    VGDrvCommonCloseSession(&g_DevExt, session->session);
     233    ASMAtomicDecU32(&cUsers);
     234
     235    kmem_free(session, sizeof(*session));
     236
    276237    return 0;
    277238}
     
    281242 *
    282243 */
    283 static int vgdrvFreeBSDIOCtl(struct cdev *pDev, u_long ulCmd, caddr_t pvData, int fFile, struct thread *pTd)
    284 {
    285     LogFlow(("vgdrvFreeBSDIOCtl\n"));
     244static int VBoxGuestNetBSDIOCtl(struct file *fp, u_long command, void *data)
     245{
     246    struct vboxguest_session *session = fp->f_data;
     247    vboxguest_softc *vboxguest = session->sc;
    286248
    287249    int rc = 0;
    288250
    289251    /*
    290      * Validate the input.
    291      */
    292     PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;
    293     if (RT_UNLIKELY(!VALID_PTR(pSession)))
    294         return EINVAL;
    295 
    296     /*
    297252     * Validate the request wrapper.
    298253     */
    299     if (IOCPARM_LEN(ulCmd) != sizeof(VBGLBIGREQ))
    300     {
    301         Log(("vgdrvFreeBSDIOCtl: bad request %lu size=%lu expected=%d\n", ulCmd, IOCPARM_LEN(ulCmd), sizeof(VBGLBIGREQ)));
     254    if (IOCPARM_LEN(command) != sizeof(VBGLBIGREQ)) {
     255        Log((DEVICE_NAME ": VBoxGuestFreeBSDIOCtl: bad request %lu size=%lu expected=%d\n", command, IOCPARM_LEN(command), sizeof(VBGLBIGREQ)));
    302256        return ENOTTY;
    303257    }
    304258
    305     PVBGLBIGREQ ReqWrap = (PVBGLBIGREQ)pvData;
     259    PVBGLBIGREQ ReqWrap = (PVBGLBIGREQ)data;
    306260    if (ReqWrap->u32Magic != VBGLBIGREQ_MAGIC)
    307261    {
    308         Log(("vgdrvFreeBSDIOCtl: bad magic %#x; pArg=%p Cmd=%lu.\n", ReqWrap->u32Magic, pvData, ulCmd));
     262        Log((DEVICE_NAME ": VBoxGuestNetBSDIOCtl: bad magic %#x; pArg=%p Cmd=%lu.\n", ReqWrap->u32Magic, data, command));
    309263        return EINVAL;
    310264    }
     
    312266                    || ReqWrap->cbData > _1M*16))
    313267    {
    314         printf("vgdrvFreeBSDIOCtl: bad size %#x; pArg=%p Cmd=%lu.\n", ReqWrap->cbData, pvData, ulCmd);
     268        printf(DEVICE_NAME ": VBoxGuestNetBSDIOCtl: bad size %#x; pArg=%p Cmd=%lu.\n", ReqWrap->cbData, data, command);
    315269        return EINVAL;
    316270    }
     
    322276    if (RT_UNLIKELY(!pvBuf))
    323277    {
    324         Log(("vgdrvFreeBSDIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap->cbData));
     278        Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", ReqWrap->cbData));
    325279        return ENOMEM;
    326280    }
     
    330284    {
    331285        RTMemTmpFree(pvBuf);
    332         Log(("vgdrvFreeBSDIOCtl: copyin failed; pvBuf=%p pArg=%p Cmd=%lu. rc=%d\n", pvBuf, pvData, ulCmd, rc));
     286        Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: copyin failed; pvBuf=%p pArg=%p Cmd=%lu. rc=%d\n", pvBuf, data, command, rc));
     287aprint_error_dev(vboxguest->sc_dev, "copyin failed\n");
    333288        return EFAULT;
    334289    }
     
    337292    {
    338293        RTMemTmpFree(pvBuf);
    339         Log(("vgdrvFreeBSDIOCtl: pvBuf invalid pointer %p\n", pvBuf));
     294        Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: pvBuf invalid pointer %p\n", pvBuf));
    340295        return EINVAL;
    341296    }
    342     Log(("vgdrvFreeBSDIOCtl: pSession=%p pid=%d.\n", pSession, (int)RTProcSelf()));
    343297
    344298    /*
     
    346300     */
    347301    size_t cbDataReturned;
    348     rc = VGDrvCommonIoCtl(ulCmd, &g_DevExt, pSession, pvBuf, ReqWrap->cbData, &cbDataReturned);
    349     if (RT_SUCCESS(rc))
    350     {
     302    rc = VGDrvCommonIoCtl(command, &g_DevExt, session->session, pvBuf, ReqWrap->cbData, &cbDataReturned);
     303    if (RT_SUCCESS(rc)) {
    351304        rc = 0;
    352305        if (RT_UNLIKELY(cbDataReturned > ReqWrap->cbData))
    353306        {
    354             Log(("vgdrvFreeBSDIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap->cbData));
     307            Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: too much output data %d expected %d\n", cbDataReturned, ReqWrap->cbData));
    355308            cbDataReturned = ReqWrap->cbData;
    356309        }
     
    360313            if (RT_UNLIKELY(rc))
    361314            {
    362                 Log(("vgdrvFreeBSDIOCtl: copyout failed; pvBuf=%p pArg=%p Cmd=%lu. rc=%d\n", pvBuf, pvData, ulCmd, rc));
    363                 rc = EFAULT;
     315                Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: copyout failed; pvBuf=%p pArg=%p. rc=%d\n", pvBuf, data, rc));
    364316            }
    365317        }
    366     }
    367     else
    368     {
    369         Log(("vgdrvFreeBSDIOCtl: VGDrvCommonIoCtl failed. rc=%d\n", rc));
    370         rc = EFAULT;
     318    } else {
     319        Log((DEVICE_NAME ":VBoxGuestNetBSDIOCtl: VGDrvCommonIoCtl failed. rc=%d\n", rc));
     320        rc = -rc;
    371321    }
    372322    RTMemTmpFree(pvBuf);
     
    374324}
    375325
    376 static int vgdrvFreeBSDPoll(struct cdev *pDev, int fEvents, struct thread *td)
    377 {
    378     int fEventsProcessed;
    379 
    380     LogFlow(("vgdrvFreeBSDPoll: fEvents=%d\n", fEvents));
    381 
    382     PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pDev->si_drv1;
    383     if (RT_UNLIKELY(!VALID_PTR(pSession))) {
    384         Log(("vgdrvFreeBSDPoll: no state data for %s\n", devtoname(pDev)));
    385         return (fEvents & (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
    386     }
     326static int VBoxGuestNetBSDPoll(struct file *fp, int events)
     327{
     328    struct vboxguest_session *session = fp->f_data;
     329    vboxguest_softc *vboxguest = session->sc;
     330
     331    int rc = 0;
     332    int events_processed;
    387333
    388334    uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
    389     if (pSession->u32MousePosChangedSeq != u32CurSeq)
    390     {
    391         fEventsProcessed = fEvents & (POLLIN | POLLRDNORM);
    392         pSession->u32MousePosChangedSeq = u32CurSeq;
    393     }
    394     else
    395     {
    396         fEventsProcessed = 0;
    397 
    398         selrecord(td, &g_SelInfo);
    399     }
    400 
    401     return fEventsProcessed;
    402 }
    403 
    404 static int vgdrvFreeBSDWrite(struct cdev *pDev, struct uio *pUio, int fIo)
    405 {
    406     return 0;
    407 }
    408 
    409 static int vgdrvFreeBSDRead(struct cdev *pDev, struct uio *pUio, int fIo)
    410 {
    411     return 0;
    412 }
    413 
    414 static int vgdrvFreeBSDDetach(device_t pDevice)
    415 {
    416     struct VBoxGuestDeviceState *pState = device_get_softc(pDevice);
     335    if (session->session->u32MousePosChangedSeq != u32CurSeq) {
     336        events_processed = events & (POLLIN | POLLRDNORM);
     337        session->session->u32MousePosChangedSeq = u32CurSeq;
     338    } else {
     339        events_processed = 0;
     340
     341        selrecord(curlwp, &g_SelInfo);
     342    }
     343
     344    return events_processed;
     345}
     346
     347static int VBoxGuestNetBSDDetach(device_t self, int flags)
     348{
     349    vboxguest_softc *vboxguest;
     350    vboxguest = device_private(self);
    417351
    418352    if (cUsers > 0)
    419353        return EBUSY;
    420354
    421     /*
    422      * Reverse what we did in vgdrvFreeBSDAttach.
    423      */
    424     if (g_vgdrvFreeBSDEHTag != NULL)
    425         EVENTHANDLER_DEREGISTER(dev_clone, g_vgdrvFreeBSDEHTag);
    426 
    427     clone_cleanup(&g_pvgdrvFreeBSDClones);
    428 
    429     vgdrvFreeBSDRemoveIRQ(pDevice, pState);
    430 
    431     if (pState->pVMMDevMemRes)
    432         bus_release_resource(pDevice, SYS_RES_MEMORY, pState->iVMMDevMemResId, pState->pVMMDevMemRes);
    433     if (pState->pIOPortRes)
    434         bus_release_resource(pDevice, SYS_RES_IOPORT, pState->iIOPortResId, pState->pIOPortRes);
     355    if ((vboxguest->vboxguest_state & VBOXGUEST_STATE_INITOK) == 0) {
     356        return 0;
     357    }
     358
     359    /*
     360     * Reverse what we did in VBoxGuestNetBSDAttach.
     361     */
     362
     363    VBoxGuestNetBSDRemoveIRQ(vboxguest);
    435364
    436365    VGDrvCommonDeleteDevExt(&g_DevExt);
     
    447376 * @param   pvState Opaque pointer to the device state.
    448377 */
    449 static int vgdrvFreeBSDISR(void *pvState)
    450 {
    451     LogFlow(("vgdrvFreeBSDISR: pvState=%p\n", pvState));
     378static int VBoxGuestNetBSDISR(void *pvState)
     379{
     380    LogFlow((DEVICE_NAME ":VBoxGuestNetBSDISR pvState=%p\n", pvState));
    452381
    453382    bool fOurIRQ = VGDrvCommonISR(&g_DevExt);
     
    456385}
    457386
    458 void VGDrvNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
    459 {
    460     LogFlow(("VGDrvNativeISRMousePollEvent:\n"));
     387void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
     388{
     389    LogFlow((DEVICE_NAME "::NativeISRMousePollEvent:\n"));
    461390
    462391    /*
    463392     * Wake up poll waiters.
    464393     */
    465     selwakeup(&g_SelInfo);
     394    selnotify(&g_SelInfo, 0, 0);
    466395}
    467396
     
    469398 * Sets IRQ for VMMDev.
    470399 *
    471  * @returns FreeBSD error code.
     400 * @returns NetBSD error code.
    472401 * @param   pDevice  Pointer to the device info structure.
    473402 * @param   pvState  Pointer to the state info structure.
    474403 */
    475 static int vgdrvFreeBSDAddIRQ(device_t pDevice, void *pvState)
     404static int VBoxGuestNetBSDAddIRQ(vboxguest_softc *vboxguest)
    476405{
    477406    int iResId = 0;
    478407    int rc = 0;
    479     struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
    480 
    481     pState->pIrqRes = bus_alloc_resource_any(pDevice, SYS_RES_IRQ, &iResId, RF_SHAREABLE | RF_ACTIVE);
    482 
    483 #if __FreeBSD_version >= 700000
    484     rc = bus_setup_intr(pDevice, pState->pIrqRes, INTR_TYPE_BIO | INTR_MPSAFE, NULL, (driver_intr_t *)vgdrvFreeBSDISR, pState,
    485                         &pState->pfnIrqHandler);
    486 #else
    487     rc = bus_setup_intr(pDevice, pState->pIrqRes, INTR_TYPE_BIO, (driver_intr_t *)vgdrvFreeBSDISR, pState, &pState->pfnIrqHandler);
    488 #endif
    489 
    490     if (rc)
    491     {
    492         pState->pfnIrqHandler = NULL;
     408    struct pci_attach_args *pa = vboxguest->pa;
     409    const char *intrstr;
     410    char intstrbuf[100];
     411
     412    if (pci_intr_map(pa, &vboxguest->ih)) {
     413        aprint_error_dev(vboxguest->sc_dev, "couldn't map interrupt.\n");
    493414        return VERR_DEV_IO_ERROR;
    494415    }
    495 
    496     pState->iIrqResId = iResId;
     416    intrstr = pci_intr_string(vboxguest->pa->pa_pc, vboxguest->ih,
     417            intstrbuf, sizeof(intstrbuf));
     418    aprint_normal_dev(vboxguest->sc_dev, "interrupting at %s\n", intrstr);
     419    vboxguest->pfnIrqHandler = pci_intr_establish(vboxguest->pa->pa_pc, vboxguest->ih, IPL_BIO, VBoxGuestNetBSDISR, vboxguest);
     420    if (vboxguest->pfnIrqHandler == NULL) {
     421        aprint_error_dev(vboxguest->sc_dev, "couldn't establish interrupt\n");
     422        return VERR_DEV_IO_ERROR;
     423    }
    497424
    498425    return VINF_SUCCESS;
     
    505432 * @param   pvState  Opaque pointer to the state info structure.
    506433 */
    507 static void vgdrvFreeBSDRemoveIRQ(device_t pDevice, void *pvState)
    508 {
    509     struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
    510 
    511     if (pState->pIrqRes)
    512     {
    513         bus_teardown_intr(pDevice, pState->pIrqRes, pState->pfnIrqHandler);
    514         bus_release_resource(pDevice, SYS_RES_IRQ, 0, pState->pIrqRes);
    515     }
    516 }
    517 
    518 static int vgdrvFreeBSDAttach(device_t pDevice)
    519 {
    520     int rc;
    521     int iResId;
    522     struct VBoxGuestDeviceState *pState;
     434static void VBoxGuestNetBSDRemoveIRQ(vboxguest_softc *vboxguest)
     435{
     436    if (vboxguest->pfnIrqHandler)
     437    {
     438        pci_intr_disestablish(vboxguest->pa->pa_pc, vboxguest->pfnIrqHandler);
     439    }
     440}
     441
     442static void VBoxGuestNetBSDAttach(device_t parent, device_t self, void *aux)
     443{
     444    int rc = VINF_SUCCESS;
     445    int iResId = 0;
     446    vboxguest_softc *vboxguest;
     447    struct pci_attach_args *pa = aux;
     448    bus_space_tag_t iot, memt;
     449    bus_space_handle_t ioh, memh;
     450    bus_dma_segment_t seg;
     451    int ioh_valid, memh_valid;
    523452
    524453    cUsers = 0;
     454
     455    aprint_normal(": VirtualBox Guest\n");
     456
     457    vboxguest = device_private(self);
     458    vboxguest->sc_dev = self;
    525459
    526460    /*
     
    531465    {
    532466        LogFunc(("RTR0Init failed.\n"));
    533         return ENXIO;
    534     }
    535 
    536     pState = device_get_softc(pDevice);
     467        aprint_error_dev(vboxguest->sc_dev, "RTR0Init failed\n");
     468        return ;
     469    }
     470
     471    vboxguest->pa = pa;
    537472
    538473    /*
    539474     * Allocate I/O port resource.
    540475     */
    541     iResId                 = PCIR_BAR(0);
    542     pState->pIOPortRes     = bus_alloc_resource_any(pDevice, SYS_RES_IOPORT, &iResId, RF_ACTIVE);
    543     pState->uIOPortBase    = rman_get_start(pState->pIOPortRes);
    544     pState->iIOPortResId   = iResId;
    545     if (pState->uIOPortBase)
    546     {
     476    ioh_valid = (pci_mapreg_map(pa, PCI_MAPREG_START, PCI_MAPREG_TYPE_IO, 0, &vboxguest->io_tag, &vboxguest->io_handle, &vboxguest->uIOPortBase, &vboxguest->io_regsize) == 0);
     477
     478    if (ioh_valid)
     479    {
     480
    547481        /*
    548482         * Map the MMIO region.
    549483         */
    550         iResId                   = PCIR_BAR(1);
    551         pState->pVMMDevMemRes    = bus_alloc_resource_any(pDevice, SYS_RES_MEMORY, &iResId, RF_ACTIVE);
    552         pState->VMMDevMemHandle  = rman_get_bushandle(pState->pVMMDevMemRes);
    553         pState->VMMDevMemSize    = rman_get_size(pState->pVMMDevMemRes);
    554 
    555         pState->pMMIOBase        = rman_get_virtual(pState->pVMMDevMemRes);
    556         pState->iVMMDevMemResId  = iResId;
    557         if (pState->pMMIOBase)
     484        memh_valid = (pci_mapreg_map(pa, PCI_MAPREG_START+4, PCI_MAPREG_TYPE_MEM, BUS_SPACE_MAP_LINEAR, &vboxguest->iVMMDevMemResId, &vboxguest->VMMDevMemHandle, &vboxguest->pMMIOBase, &vboxguest->VMMDevMemSize) == 0);
     485        if (memh_valid)
    558486        {
    559487            /*
    560488             * Call the common device extension initializer.
    561489             */
    562             rc = VGDrvCommonInitDevExt(&g_DevExt, pState->uIOPortBase,
    563                                        pState->pMMIOBase, pState->VMMDevMemSize,
     490            rc = VGDrvCommonInitDevExt(&g_DevExt, vboxguest->uIOPortBase,
     491                    bus_space_vaddr(vboxguest->iVMMDevMemResId,
     492                            vboxguest->VMMDevMemHandle),
     493                                       vboxguest->VMMDevMemSize,
    564494#if ARCH_BITS == 64
    565                                        VBOXOSTYPE_FreeBSD_x64,
     495                                       VBOXOSTYPE_NetBSD_x64,
    566496#else
    567                                        VBOXOSTYPE_FreeBSD,
     497                                       VBOXOSTYPE_NetBSD,
    568498#endif
    569499                                       VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
     
    573503                 * Add IRQ of VMMDev.
    574504                 */
    575                 rc = vgdrvFreeBSDAddIRQ(pDevice, pState);
     505                rc = VBoxGuestNetBSDAddIRQ(vboxguest);
    576506                if (RT_SUCCESS(rc))
    577507                {
    578                     /*
    579                      * Configure device cloning.
    580                      */
    581                     clone_setup(&g_pvgdrvFreeBSDClones);
    582                     g_vgdrvFreeBSDEHTag = EVENTHANDLER_REGISTER(dev_clone, vgdrvFreeBSDClone, 0, 1000);
    583                     if (g_vgdrvFreeBSDEHTag)
    584                     {
    585                         printf(DEVICE_NAME ": loaded successfully\n");
    586                         return 0;
    587                     }
    588 
    589                     printf(DEVICE_NAME ": EVENTHANDLER_REGISTER(dev_clone,,,) failed\n");
    590                     clone_cleanup(&g_pvgdrvFreeBSDClones);
    591                     vgdrvFreeBSDRemoveIRQ(pDevice, pState);
     508                    vboxguest->vboxguest_state |= VBOXGUEST_STATE_INITOK;
     509                    return ;
    592510                }
    593                 else
    594                     printf((DEVICE_NAME ": VGDrvCommonInitDevExt failed.\n"));
    595511                VGDrvCommonDeleteDevExt(&g_DevExt);
     512            } else {
     513                aprint_error_dev(vboxguest->sc_dev, "init failed\n");
    596514            }
    597             else
    598                 printf((DEVICE_NAME ": vgdrvFreeBSDAddIRQ failed.\n"));
     515        } else {
     516            aprint_error_dev(vboxguest->sc_dev, "MMIO mapping failed\n");
    599517        }
    600         else
    601             printf((DEVICE_NAME ": MMIO region setup failed.\n"));
    602     }
    603     else
    604         printf((DEVICE_NAME ": IOport setup failed.\n"));
     518    } else {
     519        aprint_error_dev(vboxguest->sc_dev, "IO mapping failed\n");
     520    }
    605521
    606522    RTR0Term();
    607     return ENXIO;
    608 }
    609 
    610 static int vgdrvFreeBSDProbe(device_t pDevice)
    611 {
    612     if ((pci_get_vendor(pDevice) == VMMDEV_VENDORID) && (pci_get_device(pDevice) == VMMDEV_DEVICEID))
    613         return 0;
    614 
    615     return ENXIO;
    616 }
    617 
    618 static device_method_t vgdrvFreeBSDMethods[] =
    619 {
    620     /* Device interface. */
    621     DEVMETHOD(device_probe,  vgdrvFreeBSDProbe),
    622     DEVMETHOD(device_attach, vgdrvFreeBSDAttach),
    623     DEVMETHOD(device_detach, vgdrvFreeBSDDetach),
    624     {0,0}
    625 };
    626 
    627 static driver_t vgdrvFreeBSDDriver =
    628 {
    629     DEVICE_NAME,
    630     vgdrvFreeBSDMethods,
    631     sizeof(struct VBoxGuestDeviceState),
    632 };
    633 
    634 static devclass_t vgdrvFreeBSDClass;
    635 
    636 DRIVER_MODULE(vboxguest, pci, vgdrvFreeBSDDriver, vgdrvFreeBSDClass, 0, 0);
    637 MODULE_VERSION(vboxguest, 1);
     523    return ;
     524}
     525
     526static int
     527VBoxGuestNetBSDMatch(device_t parent, cfdata_t match, void *aux)
     528{
     529    const struct pci_attach_args *pa = aux;
     530    if ((PCI_VENDOR(pa->pa_id) == VMMDEV_VENDORID)
     531            && (PCI_PRODUCT(pa->pa_id) == VMMDEV_DEVICEID)) {
     532        return 1;
     533    } else {
     534        return 2;
     535    }
     536}
    638537
    639538/* Common code that depend on g_DevExt. */
    640539#include "VBoxGuestIDC-unix.c.h"
    641540
     541CFATTACH_DECL_NEW(vboxguest, sizeof(vboxguest_softc),
     542    VBoxGuestNetBSDMatch, VBoxGuestNetBSDAttach, VBoxGuestNetBSDDetach, NULL);
     543
     544MODULE(MODULE_CLASS_DRIVER, vboxguest, "pci");
     545
     546static int loc[2] = {-1, -1};
     547
     548static const struct cfparent pspec = {
     549        "pci", "pci", DVUNIT_ANY
     550};
     551
     552static struct cfdata vboxguest_cfdata[] = {
     553        {
     554                .cf_name = "vboxguest",
     555                .cf_atname = "vboxguest",
     556                .cf_unit = 0,           /* Only unit 0 is ever used  */
     557                .cf_fstate = FSTATE_STAR,
     558                .cf_loc = loc,
     559                .cf_flags = 0,
     560                .cf_pspec = &pspec,
     561        },
     562        { NULL, NULL, 0, 0, NULL, 0, NULL }
     563};
     564
     565static int
     566vboxguest_modcmd(modcmd_t cmd, void *opaque)
     567{
     568    devmajor_t bmajor, cmajor;
     569    int error;
     570    register_t retval;
     571
     572    bmajor = cmajor = NODEVMAJOR;
     573    switch (cmd) {
     574        case MODULE_CMD_INIT:
     575                error = config_cfdriver_attach(&vboxguest_cd);
     576                if (error) {
     577                    printf("config_cfdriver_attach failed: %d", error);
     578                    break;
     579                }
     580                error = config_cfattach_attach(vboxguest_cd.cd_name, &vboxguest_ca);
     581                if (error) {
     582                    config_cfdriver_detach(&vboxguest_cd);
     583                    printf("%s: unable to register cfattach\n", vboxguest_cd.cd_name);
     584                    break;
     585                }
     586
     587                error = config_cfdata_attach(vboxguest_cfdata, 1);
     588                if (error) {
     589                        printf("%s: unable to attach cfdata\n", vboxguest_cd.cd_name);
     590                        config_cfattach_detach(vboxguest_cd.cd_name, &vboxguest_ca);
     591                        config_cfdriver_detach(&vboxguest_cd);
     592                        break;
     593                }
     594
     595                error = devsw_attach("vboxguest", NULL, &bmajor, &g_VBoxGuestNetBSDChrDevSW, &cmajor);
     596               
     597                if (error == EEXIST)
     598                        error = 0; /* maybe built-in ... improve eventually */
     599                if (error)
     600                        break;
     601
     602                error = do_sys_mknod(curlwp, "/dev/vboxguest", 0666|S_IFCHR, makedev(cmajor, 0), &retval, UIO_SYSSPACE);
     603                if (error == EEXIST)
     604                        error = 0;
     605                break;
     606        case MODULE_CMD_FINI:
     607                error = config_cfdata_detach(vboxguest_cfdata);
     608                if (error)
     609                    break;
     610                error = config_cfattach_detach(vboxguest_cd.cd_name, &vboxguest_ca);
     611                if (error)
     612                    break;
     613                config_cfdriver_detach(&vboxguest_cd);
     614                error = devsw_detach(NULL, &g_VBoxGuestNetBSDChrDevSW);
     615                break;
     616        default:
     617                return ENOTTY;
     618    }
     619    return error;
     620}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette