/*------------------------------------------------------------------------* * usb_alloc_mbufs - allocate mbufs to an usbd interface queue * * Returns: * A pointer that should be passed to "free()" when the buffer(s) * should be released. *------------------------------------------------------------------------*/ void * usb_alloc_mbufs(struct malloc_type *type, struct usb_ifqueue *ifq, usb_size_t block_size, uint16_t nblocks) { struct usb_mbuf *m_ptr; uint8_t *data_ptr; void *free_ptr = NULL; usb_size_t alloc_size; /* align data */ block_size += ((-block_size) & (USB_HOST_ALIGN - 1)); if (nblocks && block_size) { alloc_size = (block_size + sizeof(struct usb_mbuf)) * nblocks; free_ptr = malloc(alloc_size, type, M_WAITOK | M_ZERO); if (free_ptr == NULL) { goto done; } m_ptr = free_ptr; data_ptr = (void *)(m_ptr + nblocks); while (nblocks--) { m_ptr->cur_data_ptr = m_ptr->min_data_ptr = data_ptr; m_ptr->cur_data_len = m_ptr->max_data_len = block_size; USB_IF_ENQUEUE(ifq, m_ptr); m_ptr++; data_ptr += block_size; } } done: return (free_ptr); }
static uint8_t ugen_fs_get_complete(struct usb_fifo *f, uint8_t *pindex) { struct usb_mbuf *m; USB_IF_DEQUEUE(&f->used_q, m); if (m) { *pindex = *((uint8_t *)(m->cur_data_ptr)); USB_IF_ENQUEUE(&f->free_q, m); return (0); /* success */ } else { *pindex = 0; /* fix compiler warning */ f->flag_iscomplete = 0; } return (1); /* failure */ }
static void ugen_fs_set_complete(struct usb_fifo *f, uint8_t index) { struct usb_mbuf *m; USB_IF_DEQUEUE(&f->free_q, m); if (m == NULL) { /* can happen during close */ DPRINTF("out of buffers\n"); return; } USB_MBUF_RESET(m); *((uint8_t *)(m->cur_data_ptr)) = index; USB_IF_ENQUEUE(&f->used_q, m); f->flag_iscomplete = 1; usb_fifo_wakeup(f); }