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; }
/* * 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; }