/* * Generate some output and apply a statistical RNG test to it. */ static void cprng_strong_rngtest(struct cprng_strong *cprng) { KASSERT(mutex_owned(&cprng->cs_lock)); /* XXX Switch to a pool cache instead? */ rngtest_t *const rt = kmem_intr_alloc(sizeof(*rt), KM_NOSLEEP); if (rt == NULL) /* XXX Warn? */ return; (void)strlcpy(rt->rt_name, cprng->cs_name, sizeof(rt->rt_name)); if (nist_ctr_drbg_generate(&cprng->cs_drbg, rt->rt_b, sizeof(rt->rt_b), NULL, 0)) panic("cprng %s: NIST CTR_DRBG failed after reseed", cprng->cs_name); if (rngtest(rt)) { printf("cprng %s: failed statistical RNG test\n", cprng->cs_name); /* XXX Not clear that this does any good... */ cprng->cs_ready = false; rndsink_schedule(cprng->cs_rndsink); } explicit_memset(rt, 0, sizeof(*rt)); /* paranoia */ kmem_intr_free(rt, sizeof(*rt)); }
/* * Common function for DMA map destruction. May be called by bus-specific * DMA map destruction functions. */ void bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map) { size_t mapsize = sizeof(*map) + sizeof(bus_dma_segment_t [map->_dm_segcnt - 1]); kmem_intr_free(map, mapsize); }
static void feedrandom(size_t bytes, void *arg) { uint8_t *rnddata; size_t dsize; rnddata = kmem_intr_alloc(MAXGET, KM_SLEEP); if (rumpuser_getrandom(rnddata, MIN(MAXGET, bytes), RUMPUSER_RANDOM_HARD|RUMPUSER_RANDOM_NOWAIT, &dsize) == 0) rnd_add_data(&rndsrc, rnddata, dsize, NBBY*dsize); kmem_intr_free(rnddata, MAXGET); }
/* * Deregister an interrupt handler. */ void intr_disestablish(void *arg) { struct intrhand * const ih = arg; const int virq = ih->ih_virq; struct intr_source * const is = &intrsources[virq]; struct intrhand **p, **q; int maxipl = IPL_NONE; if (!PIC_VIRQ_LEGAL_P(virq)) panic("intr_disestablish: bogus virq %d", virq); /* * Remove the handler from the chain. * This is O(n^2), too. */ for (p = &is->is_hand, q = NULL; (*p) != NULL; p = &(*p)->ih_next) { struct intrhand * const tmp_ih = *p; if (tmp_ih == ih) { q = p; } else { maxipl = max(maxipl, tmp_ih->ih_ipl); } } if (q) *q = ih->ih_next; else panic("intr_disestablish: handler not registered"); kmem_intr_free((void *)ih, sizeof(*ih)); /* * Reset the IPL for this source now that we've removed a handler. */ is->is_ipl = maxipl; intr_calculatemasks(); if (is->is_hand == NULL) { is->is_type = IST_NONE; evcnt_detach(&is->is_ev); /* * Make the virutal IRQ available again. */ virq_map[virq] = 0; virq_mask |= PIC_VIRQ_TO_MASK(virq); } }
usbd_status usbd_setup_pipe_flags(struct usbd_device *dev, struct usbd_interface *iface, struct usbd_endpoint *ep, int ival, struct usbd_pipe **pipe, uint8_t flags) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); struct usbd_pipe *p; usbd_status err; p = kmem_alloc(dev->ud_bus->ub_pipesize, KM_SLEEP); DPRINTFN(1, "dev=%p addr=%d iface=%p ep=%p pipe=%p", dev, dev->ud_addr, iface, ep); if (p == NULL) { DPRINTFN(1, "(nomem)", 0, 0, 0, 0); return USBD_NOMEM; } p->up_dev = dev; p->up_iface = iface; p->up_endpoint = ep; ep->ue_refcnt++; p->up_intrxfer = NULL; p->up_running = 0; p->up_aborting = 0; p->up_serialise = true; p->up_repeat = 0; p->up_interval = ival; p->up_flags = flags; p->up_serialise = true; SIMPLEQ_INIT(&p->up_queue); err = dev->ud_bus->ub_methods->ubm_open(p); if (err) { DPRINTF("endpoint=0x%x failed, error=%d", ep->ue_edesc->bEndpointAddress, err, 0, 0); kmem_intr_free(p, dev->ud_bus->ub_pipesize); return err; } KASSERT(p->up_methods->upm_start || p->up_serialise == false); usb_init_task(&p->up_async_task, usbd_clear_endpoint_stall_task, p, USB_TASKQ_MPSAFE); DPRINTFN(1, "pipe=%p", p, 0, 0, 0); *pipe = p; return USBD_NORMAL_COMPLETION; }
void npcb_free(struct natmpcb *npcb, int op) { int s = splnet(); if ((npcb->npcb_flags & NPCB_FREE) == 0) { LIST_REMOVE(npcb, pcblist); npcb->npcb_flags = NPCB_FREE; } if (op == NPCB_DESTROY) { if (npcb->npcb_inq) { npcb->npcb_flags = NPCB_DRAIN; /* flag for destruction */ } else { kmem_intr_free(npcb, sizeof(*npcb)); } } splx(s); }