bool V4li_camera::mmap_device() { bool flag = (-1 != device) && (memory == V4L2_MEMORY_MMAP); if (flag && num_buffers > 0) { buffer = new Buffer[num_buffers]; if (0 != buffer) { int i; struct v4l2_buffer buf; for (i = 0; i < (int)num_buffers && flag; ++i) { memset(&buf, 0, sizeof(buf)); buf.index = i; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; flag = flag && ioctl(VIDIOC_QUERYBUF, &buf); buffer[i].length = buf.length; buffer[i].start = (uint8_t *)mmap(0, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, device, buf.m.offset); flag = flag && (!(MAP_FAILED == buffer[i].start)); } if (false == flag) { unmap_device(); } } } return flag; }
static status_t free_hook(void* dev) { device_info *di = (device_info *)dev; shared_info *si = di->si; vuint32 *regs = di->regs; /* lock the driver */ AQUIRE_BEN(pd->kernel); /* if opened multiple times, decrement the open count and exit */ if (di->is_open > 1) goto unlock_and_exit; /* disable and clear any pending interrupts */ //fixme: //distinquish between crtc1/crtc2 once all heads get seperate driver instances! disable_vbi_all(regs); if (si->ps.int_assigned) { /* remove interrupt handler */ remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, nv_interrupt, di); /* delete the semaphores, ignoring any errors ('cause the owning team may have died on us) */ delete_sem(si->vblank); si->vblank = -1; } /* free regs and framebuffer areas */ unmap_device(di); /* clean up our aligned DMA area */ delete_area(si->dma_area); si->dma_area = -1; si->dma_buffer = NULL; /* clean up our unaligned DMA area */ delete_area(si->unaligned_dma_area); si->unaligned_dma_area = -1; si->dma_buffer_pci = NULL; /* clean up our shared area */ delete_area(di->shared_area); di->shared_area = -1; di->si = NULL; unlock_and_exit: /* mark the device available */ di->is_open--; /* unlock the driver */ RELEASE_BEN(pd->kernel); /* all done */ return B_OK; }
/** * Unmap all devices from virtual memory. * * @param ws2811 ws2811 instance pointer. * * @returns None */ static void unmap_registers(ws2811_t *ws2811) { ws2811_device_t *device = ws2811->device; if (device->dma) { unmap_device(device->dma, sizeof(dma_t)); } if (device->pwm) { unmap_device(device->pwm, sizeof(pwm_t)); } if (device->cm_pwm) { unmap_device(device->cm_pwm, sizeof(cm_pwm_t)); } if (device->gpio) { unmap_device(device->gpio, sizeof(gpio_t)); } }
void V4li_camera::close() { stop(); unmap_device(); if (0 != device_name) { delete [] device_name; device_name = 0; } if (device >= 0) { ::close(device); } device = -1; }
/* ----------- free_hook - close down the device ----------- */ static status_t free_hook (void* dev) { device_info *di = (device_info *)dev; shared_info *si = di->si; vuint32 *regs = di->regs; /* lock the driver */ AQUIRE_BEN(pd->kernel); /* if opened multiple times, decrement the open count and exit */ if (di->is_open > 1) goto unlock_and_exit; /* disable and clear any pending interrupts */ disable_vbi(regs); /* remove interrupt handler */ remove_io_interrupt_handler(di->pcii.u.h0.interrupt_line, eng_interrupt, di); /* delete the semaphores, ignoring any errors ('cause the owning team may have died on us) */ delete_sem(si->vblank); si->vblank = -1; /* free regs and framebuffer areas */ unmap_device(di); /* clean up our shared area */ delete_area(di->shared_area); di->shared_area = -1; di->si = NULL; unlock_and_exit: /* mark the device available */ di->is_open--; /* unlock the driver */ RELEASE_BEN(pd->kernel); /* all done */ return B_OK; }
static status_t open_hook (const char* name, uint32 flags, void** cookie) { int32 index = 0; device_info *di; shared_info *si; thread_id thid; thread_info thinfo; status_t result = B_OK; vuint32 *regs; char shared_name[B_OS_NAME_LENGTH]; /* find the device name in the list of devices */ /* we're never passed a name we didn't publish */ while (pd->device_names[index] && (strcmp(name, pd->device_names[index]) != 0)) index++; /* for convienience */ di = &(pd->di[index]); /* make sure no one else has write access to the common data */ AQUIRE_BEN(pd->kernel); /* if it's already open for writing */ if (di->is_open) { /* mark it open another time */ goto mark_as_open; } /* create the shared area */ sprintf(shared_name, DEVICE_FORMAT " shared", di->pcii.vendor_id, di->pcii.device_id, di->pcii.bus, di->pcii.device, di->pcii.function); /* create this area with NO user-space read or write permissions, to prevent accidental dammage */ di->shared_area = create_area(shared_name, (void **)&(di->si), B_ANY_KERNEL_ADDRESS, ((sizeof(shared_info) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1)), B_FULL_LOCK, 0); if (di->shared_area < 0) { /* return the error */ result = di->shared_area; goto done; } /* save a few dereferences */ si = di->si; /* save the vendor and device IDs */ si->vendor_id = di->pcii.vendor_id; si->device_id = di->pcii.device_id; si->revision = di->pcii.revision; si->bus = di->pcii.bus; si->device = di->pcii.device; si->function = di->pcii.function; /* device at bus #0, device #0, function #0 holds byte value at byte-index 0xf6 */ si->ps.chip_rev = ((*pci_bus->read_pci_config)(0, 0, 0, 0xf6, 1)); /* map the device */ result = map_device(di); if (result < 0) goto free_shared; result = B_OK; /* create a semaphore for vertical blank management */ si->vblank = create_sem(0, di->name); if (si->vblank < 0) { result = si->vblank; goto unmap; } /* change the owner of the semaphores to the opener's team */ /* this is required because apps can't aquire kernel semaphores */ thid = find_thread(NULL); get_thread_info(thid, &thinfo); set_sem_owner(si->vblank, thinfo.team); /* assign local regs pointer for SAMPLExx() macros */ regs = di->regs; /* disable and clear any pending interrupts */ disable_vbi(regs); /* If there is a valid interrupt line assigned then set up interrupts */ if ((di->pcii.u.h0.interrupt_pin == 0x00) || (di->pcii.u.h0.interrupt_line == 0xff) || /* no IRQ assigned */ (di->pcii.u.h0.interrupt_line <= 0x02)) /* system IRQ assigned */ { /* we are aborting! */ /* Note: the R4 graphics driver kit lacks this statement!! */ result = B_ERROR; /* interrupt does not exist so exit without installing our handler */ goto delete_the_sem; } else { /* otherwise install our interrupt handler */ result = install_io_interrupt_handler(di->pcii.u.h0.interrupt_line, eng_interrupt, (void *)di, 0); /* bail if we couldn't install the handler */ if (result != B_OK) goto delete_the_sem; } mark_as_open: /* mark the device open */ di->is_open++; /* send the cookie to the opener */ *cookie = di; goto done; delete_the_sem: delete_sem(si->vblank); unmap: unmap_device(di); free_shared: /* clean up our shared area */ delete_area(di->shared_area); di->shared_area = -1; di->si = NULL; done: /* end of critical section */ RELEASE_BEN(pd->kernel); /* all done, return the status */ return result; }