static int
netmap_mmap_single(struct dev_mmap_single_args *ap)
{
    int error;
    struct cdev *cdev = ap->a_head.a_dev;
    vm_ooffset_t *foff = ap->a_offset;
    vm_object_t *objp = ap->a_object;
    vm_size_t objsize = ap->a_size;
    struct netmap_vm_handle_t *vmh;
    struct netmap_priv_d *priv;
    int prot = ap->a_nprot;
    vm_object_t obj;

    D("cdev %p foff %jd size %jd objp %p prot %d", cdev,
      (intmax_t )*foff, (intmax_t )objsize, objp, prot);

    vmh = kmalloc(sizeof(struct netmap_vm_handle_t), M_DEVBUF,
                  M_NOWAIT | M_ZERO);
    if (vmh == NULL)
        return ENOMEM;
    vmh->dev = cdev;

    NMG_LOCK();
    error = devfs_get_cdevpriv(ap->a_fp, (void**)&priv);
    if (error)
        goto err_unlock;
    vmh->priv = priv;
    priv->np_refcount++;
    NMG_UNLOCK();

    error = netmap_get_memory(priv);
    if (error)
        goto err_deref;

    obj = cdev_pager_allocate(vmh, OBJT_DEVICE,
                              &netmap_cdev_pager_ops, objsize, prot,
                              *foff, NULL);
    if (obj == NULL) {
        D("cdev_pager_allocate failed");
        error = EINVAL;
        goto err_deref;
    }

    *objp = obj;
    return 0;

err_deref:
    NMG_LOCK();
    priv->np_refcount--;
err_unlock:
    NMG_UNLOCK();
// err:
    kfree(vmh, M_DEVBUF);
    return error;
}
Exemple #2
0
/*
 * XXX this is the open call for the device
 */
NTSTATUS
ioctlCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    NTSTATUS status = STATUS_SUCCESS;
    // As stated in https://support.microsoft.com/en-us/kb/120170
    // irpSp->FileObject is the same for every call from a certain
    // handle so we can use it
    // We can use the structure itself to keep the data
    // [EXTRACT] { Because I/O requests with the same handle have the same file object, 
    // a driver can use the file-object pointer to identify the I/O operations that belong 
    // to one open instantiation of a device or file. }

    struct netmap_priv_d *priv;
    PIO_STACK_LOCATION  irpSp;

    irpSp = IoGetCurrentIrpStackLocation(Irp);
    NMG_LOCK();
    priv = irpSp->FileObject->FsContext;
    if (priv == NULL) {
	priv = malloc(sizeof (*priv), M_DEVBUF, M_NOWAIT | M_ZERO); // could wait
	if (priv == NULL) {
	    status = STATUS_INSUFFICIENT_RESOURCES;
	} else {
	    priv->np_refs = 1;
	    D("Netmap.sys: ioctlCreate::priv->np_refcount = %i", priv->np_refs);
	    irpSp->FileObject->FsContext = priv;
	}
    } else {
	priv->np_refs += 1;
	D("Netmap.sys: ioctlCreate::priv->np_refcount = %i", priv->np_refs);
    }
    NMG_UNLOCK();

    //--------------------------------------------------------
    //D("Netmap.sys: Pid %i attached: memory allocated @%p", currentProcId, priv);

    Irp->IoStatus.Status = status;
    IoCompleteRequest( Irp, IO_NO_INCREMENT );
    return Irp->IoStatus.Status;	
}