Exemplo n.º 1
0
void setDeviceList(JNIEnv* env, libusb_device** list, int size, jobject object)
{
    SET_POINTER(env, list, object, "deviceListPointer");

    jclass cls = (*env)->GetObjectClass(env, object);
    jfieldID field = (*env)->GetFieldID(env, cls, "size", "I");
    (*env)->SetIntField(env, object, field, size);
}
Exemplo n.º 2
0
void setDeviceList(JNIEnv* env, libusb_device* const *list, jint size, jobject object)
{
    SET_POINTER(env, list, object, "deviceListPointer");

    // We already have the class from the previous call.
    field = (*env)->GetFieldID(env, cls, "size", "I");
    (*env)->SetIntField(env, object, field, size);
}
Exemplo n.º 3
0
/*
 * Break up ADDR_ALL into ADDR_P and ADDR_COUNT_P
 */
void	_dmalloc_address_break(const char *addr_all, DMALLOC_PNT *addr_p,
			       unsigned long *addr_count_p)
{
  char	*colon_p;
  
  SET_POINTER(addr_p, (DMALLOC_PNT)hex_to_long(addr_all));
  if (addr_count_p != NULL) {
    colon_p = strchr(addr_all, ':');
    if (colon_p != NULL) {
      *addr_count_p = loc_atoul(colon_p + 1);
    }
  }
}
Exemplo n.º 4
0
/*
 * Read in a rc file from PATH and process it looking for the
 * specified DEBUG_VALUE or TAG_FIND token.  It passes back the
 * returned debug value in DEBUG_P.  Passes back the matching TOKEN of
 * TOKEN_SIZE.
 *
 * Returns FILE_NOT_FOUND, FILE_FOUND, or TOKEN_FOUND.
 */
static	int	read_rc_file(const char *path, const long debug_value,
			     const char *tag_find, long *debug_p,
			     char *token, const int token_size)
{
  FILE	*infile;
  int	found_b = 0;
  char	next_token[64];
  long	new_debug;
  
  /* open the path */
  infile = fopen(path, "r");
  if (infile == NULL) {
    return FILE_NOT_FOUND;
  }
  
  /* run through the tokens, looking for a match */
  while (read_next_token(infile, &new_debug, next_token,
			 sizeof(next_token)) == 1) {
    
    /* are we looking for a tag? */
    if (tag_find != NULL && strcmp(tag_find, next_token) == 0) {
      found_b = 1;
      break;
    }
    
    /* are we looking for a debug-value? */
    if (debug_value > 0 && debug_value == new_debug) {
      found_b = 1;
      break;
    }
  }
  
  (void)fclose(infile);
  
  SET_POINTER(debug_p, new_debug);
  if (token != NULL) {
    (void)loc_snprintf(token, token_size, "config file token: %s",
		       next_token);
  }
  
  if (found_b) {
    return TOKEN_FOUND;
  }
  else {
    return FILE_FOUND;
  }
}
Exemplo n.º 5
0
/*
 * static void *alloc_mem
 *
 * DESCRIPTION:
 *
 * Allocate space for bytes inside of an already open memory pool.
 *
 * RETURNS:
 *
 * Success - Pointer to the address to use.
 *
 * Failure - NULL
 *
 * ARGUMENTS:
 *
 * mp_p <-> Pointer to the memory pool.  If NULL then it will do a
 * normal malloc.
 *
 * byte_size -> Number of bytes to allocate in the pool.  Must be >0.
 *
 * error_p <- Pointer to integer which, if not NULL, will be set with
 * a mpool error code.
 */
static	void	*alloc_mem(mpool_t *mp_p, const unsigned long byte_size,
			   int *error_p)
{
  unsigned long	size, fence;
  void		*addr;
  
  /* make sure we have enough bytes */
  if (byte_size < MIN_ALLOCATION) {
    size = MIN_ALLOCATION;
  }
  else {
    size = byte_size;
  }
  
  if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
    fence = 0;
  }
  else {
    fence = FENCE_SIZE;
  }
  
  /* get our free space + the space for the fence post */
  addr = get_space(mp_p, size + fence, error_p);
  if (addr == NULL) {
    /* error_p set in get_space */
    return NULL;
  }
  
  if (! BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_NO_FREE)) {
    write_magic((char *)addr + size);
  }
  
  /* maintain our stats */
  mp_p->mp_alloc_c++;
  mp_p->mp_user_alloc += size;
  if (mp_p->mp_user_alloc > mp_p->mp_max_alloc) {
    mp_p->mp_max_alloc = mp_p->mp_user_alloc;
  }
  
  SET_POINTER(error_p, MPOOL_ERROR_NONE);
  return addr;
}
Exemplo n.º 6
0
/*
 * Process the values of dmalloc environ variable(s) from ENVIRON
 * string.
 */
void	_dmalloc_environ_process(const char *env_str, DMALLOC_PNT *addr_p,
				 unsigned long *addr_count_p,
				 unsigned int *debug_p,
				 unsigned long *interval_p, int *lock_on_p,
				 char **logpath_p, char **start_file_p,
				 int *start_line_p,
				 unsigned long *start_iter_p,
				 unsigned long *start_size_p,
				 unsigned long *limit_p)
{
  char		*env_p, *this_p;
  char		buf[1024];
  int		len, done_b = 0;
  unsigned int	flags = 0;
  attr_t	*attr_p;
  
  SET_POINTER(addr_p, NULL);
  SET_POINTER(addr_count_p, 0);
  SET_POINTER(debug_p, 0);
  SET_POINTER(interval_p, 0);
  SET_POINTER(lock_on_p, 0);
  SET_POINTER(logpath_p, NULL);
  SET_POINTER(start_file_p, NULL);
  SET_POINTER(start_line_p, 0);
  SET_POINTER(start_iter_p, 0);
  SET_POINTER(start_size_p, 0);
  SET_POINTER(limit_p, 0);
  
  /* make a copy */
  (void)strncpy(buf, env_str, sizeof(buf));
  buf[sizeof(buf) - 1] = '\0';
  
  /* handle each of tokens, in turn */
  for (env_p = buf, this_p = buf; ! done_b; env_p++, this_p = env_p) {
    
    /* find the comma of end */
    for (;; env_p++) {
      if (*env_p == '\0') {
	done_b = 1;
	break;
      }
      if (*env_p == ',' && (env_p == buf || *(env_p - 1) != '\\')) {
	break;
      }
    }
    
    /* should we strip ' ' or '\t' here? */
    
    if (this_p == env_p) {
      continue;
    }
    
    *env_p = '\0';
    
    len = strlen(ADDRESS_LABEL);
    if (strncmp(this_p, ADDRESS_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      _dmalloc_address_break(this_p, addr_p, addr_count_p);
      continue;
    }
    
    len = strlen(DEBUG_LABEL);
    if (strncmp(this_p, DEBUG_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      SET_POINTER(debug_p, hex_to_long(this_p));
      continue;
    }
    
    len = strlen(INTERVAL_LABEL);
    if (strncmp(this_p, INTERVAL_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      SET_POINTER(interval_p, loc_atoul(this_p));
      continue;
    }
    
    len = strlen(LOCK_ON_LABEL);
    if (strncmp(this_p, LOCK_ON_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      SET_POINTER(lock_on_p, atoi(this_p));
      continue;
    }
    
    /* get the dmalloc logfile name into a holding variable */
    len = strlen(LOGFILE_LABEL);
    if (strncmp(this_p, LOGFILE_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      (void)strncpy(log_path, this_p, sizeof(log_path));
      log_path[sizeof(log_path) - 1] = '\0';
      SET_POINTER(logpath_p, log_path);
      continue;
    }
    
    /*
     * start checking the heap after X iterations OR
     * start at a file:line combination
     */
    len = strlen(START_LABEL);
    if (strncmp(this_p, START_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      _dmalloc_start_break(this_p, start_file_p, start_line_p, start_iter_p,
			   start_size_p);
      continue;
    }
    
    /* set the memory limit to the library */
    len = strlen(LIMIT_LABEL);
    if (strncmp(this_p, LIMIT_LABEL, len) == 0
	&& *(this_p + len) == ASSIGNMENT_CHAR) {
      this_p += len + 1;
      SET_POINTER(limit_p, loc_atoul(this_p));
      continue;
    }
    
    /* need to check the short/long debug options */
    for (attr_p = attributes; attr_p->at_string != NULL; attr_p++) {
      if (strcmp(this_p, attr_p->at_string) == 0) {
	flags |= attr_p->at_value;
	break;
      }
    }
    if (attr_p->at_string != NULL) {
      continue;
    }
  }
  
  /* append the token settings to the debug setting */
  if (debug_p != NULL) {
    if (*debug_p == 0) {
      *debug_p = flags;
    }
    else {
      *debug_p |= flags;
    }
  }
}
Exemplo n.º 7
0
/*
 * Break up START_ALL into SFILE_P, SLINE_P, and SCOUNT_P
 */
void	_dmalloc_start_break(char *start_all, char **start_file_p,
			     int *start_line_p, unsigned long *start_iter_p,
			     unsigned long *start_size_p)
{
  char	*start_p;
  
  start_p = strchr(start_all, ':');
  if (start_p != NULL) {
    (void)strncpy(start_file, start_all, sizeof(start_file));
    start_file[sizeof(start_file) - 1] = '\0';
    SET_POINTER(start_file_p, start_file);
    start_p = start_file + (start_p - start_all);
    *start_p = '\0';
    SET_POINTER(start_line_p, atoi(start_p + 1));
    SET_POINTER(start_iter_p, 0);
    SET_POINTER(start_size_p, 0);
  }
  else if (start_all[0] == 's') {
    SET_POINTER(start_file_p, NULL);
    SET_POINTER(start_line_p, 0);
    SET_POINTER(start_iter_p, 0);
    SET_POINTER(start_size_p, loc_atoul(start_all + 1));
  }
  else {
    SET_POINTER(start_file_p, NULL);
    SET_POINTER(start_line_p, 0);
    if (start_all[0] == 'c') {
      SET_POINTER(start_iter_p, loc_atoul(start_all + 1));
    }
    else {
      SET_POINTER(start_iter_p, loc_atoul(start_all));
    }
    SET_POINTER(start_size_p, 0);
  }
}
Exemplo n.º 8
0
void setContext(JNIEnv* env, const libusb_context* context, jobject object)
{
    SET_POINTER(env, context, object, "contextPointer");
}
Exemplo n.º 9
0
void setContainerIdDescriptor(JNIEnv* env,
    const struct libusb_container_id_descriptor* descriptor, jobject object)
{
    SET_POINTER(env, descriptor, object, "containerIdDescriptorPointer");
}
Exemplo n.º 10
0
void setHotplugCallbackHandle(JNIEnv* env, const libusb_hotplug_callback_handle hotplugHandle,
    jobject object)
{
    SET_POINTER(env, hotplugHandle, object, "hotplugCallbackHandleValue");
}
void setSsEndpointCompanionDescriptor(JNIEnv* env,
    const struct libusb_ss_endpoint_companion_descriptor* descriptor, jobject object)
{
    SET_POINTER(env, descriptor, object, "ssEndpointCompanionDescriptorPointer");
}
Exemplo n.º 12
0
void setBosDescriptor(JNIEnv* env,
    struct libusb_bos_descriptor* descriptor, jobject object)
{
    SET_POINTER(env, descriptor, object, "bosDescriptorPointer");
}
Exemplo n.º 13
0
/*
 * Read in the next token from INFILE.  It passes back the returned
 * debug value in DEBUG_P.  Passes back the matching TOKEN of
 * TOKEN_SIZE.  Returns 1 if there was a next else 0.
 */
static	int	read_next_token(FILE *infile, long *debug_p,
				char *token, const int token_size)
{
  int	cont_b = 0, found_b = 0;
  long	new_debug = 0;
  char	buf[1024], *tok_p, *buf_p;
  
  while (fgets(buf, sizeof(buf), infile) != NULL) {
    
    /* ignore comments and empty lines */
    if (buf[0] == '#' || buf[0] == '\n') {
      continue;
    }
    
    /* chop off the ending \n */
    buf_p = strrchr(buf, '\n');
    SET_POINTER(buf_p, '\0');
    
    buf_p = buf;
    
    /* if we're not continuing then we need to process a tag */
    if (! cont_b) {
      
      /* get the first token on the line */
      tok_p = strsep(&buf_p, TOKENIZE_EQUALS);
      if (tok_p == NULL) {
	continue;
      }
      if (*tok_p == '\0') {
	(void)fprintf(stderr, "Invalid start of line: %s\n", buf_p);
	continue;
      }
      
      /* save the token */
      if (token != NULL) {
	(void)strncpy(token, tok_p, token_size);
	token[token_size - 1] = '\0';
      }
      found_b = 1;
    }
    
    cont_b = 0;
    
    while (1) {
      /* get the next token */
      tok_p = strsep(&buf_p, TOKENIZE_CHARS);
      if (tok_p == NULL) {
	break;
      }
      if (*tok_p == '\0') {
	continue;
      }
      
      /* do we have a continuation character? */
      if (strcmp(tok_p, "\\") == 0) {
	cont_b = 1;
	break;
      }
      
      new_debug |= token_to_value(tok_p);
    }
    
    /* are we done? */
    if (! cont_b) {
      break;
    }
  }
  
  SET_POINTER(debug_p, new_debug);
  
  if (found_b) {
    return 1;
  }
  else {
    return 0;
  }
}
Exemplo n.º 14
0
/*
 * static void *alloc_pages
 *
 * DESCRIPTION:
 *
 * Allocate space for a number of memory pages in the memory pool.
 *
 * RETURNS:
 *
 * Success - New pages of memory
 *
 * Failure - NULL
 *
 * ARGUMENTS:
 *
 * mp_p <-> Pointer to our memory pool.
 *
 * page_n -> Number of pages to alloc.
 *
 * error_p <- Pointer to integer which, if not NULL, will be set with
 * a mpool error code.
 */
static	void	*alloc_pages(mpool_t *mp_p, const unsigned int page_n,
			     int *error_p)
{
  void		*mem, *fill_mem;
  unsigned long	size, fill;
  int		state;
  
  /* are we over our max-pages? */
  if (mp_p->mp_max_pages > 0 && mp_p->mp_page_c >= mp_p->mp_max_pages) {
    SET_POINTER(error_p, MPOOL_ERROR_NO_PAGES);
    return NULL;
  }
  
  size = SIZE_OF_PAGES(mp_p, page_n);
  
#ifdef DEBUG
  (void)printf("allocating %u pages or %lu bytes\n", page_n, size);
#endif
  
  if (BIT_IS_SET(mp_p->mp_flags, MPOOL_FLAG_USE_SBRK)) {
    mem = sbrk(size);
    if (mem == (void *)-1) {
      SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
      return NULL;
    }
    fill = (unsigned long)mem % mp_p->mp_page_size;
    
    if (fill > 0) {
      fill = mp_p->mp_page_size - fill;
      fill_mem = sbrk(fill);
      if (fill_mem == (void *)-1) {
	SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
	return NULL;
      }
      if ((char *)fill_mem != (char *)mem + size) {
	SET_POINTER(error_p, MPOOL_ERROR_SBRK_CONTIG);
	return NULL;
      }
      mem = (char *)mem + fill;
    }
  }
  else {
    state = MAP_PRIVATE;
#ifdef MAP_FILE
    state |= MAP_FILE;
#endif
#ifdef MAP_VARIABLE
    state |= MAP_VARIABLE;
#endif
    
    /* mmap from /dev/zero */
    mem = mmap((caddr_t)mp_p->mp_addr, size, PROT_READ | PROT_WRITE, state,
	       mp_p->mp_fd, mp_p->mp_top);
    if (mem == (void *)MAP_FAILED) {
      if (errno == ENOMEM) {
	SET_POINTER(error_p, MPOOL_ERROR_NO_MEM);
      }
      else {
	SET_POINTER(error_p, MPOOL_ERROR_MMAP);
      }
      return NULL;
    }
    mp_p->mp_top += size;
    if (mp_p->mp_addr != NULL) {
      mp_p->mp_addr = (char *)mp_p->mp_addr + size;
    }
  }
  
  mp_p->mp_page_c += page_n;
  
  SET_POINTER(error_p, MPOOL_ERROR_NONE);
  return mem;
}
Exemplo n.º 15
0
void setConfigDescriptor(JNIEnv* env,
    struct libusb_config_descriptor* descriptor, jobject object)
{
    SET_POINTER(env, descriptor, object, "configDescriptorPointer");
}
Exemplo n.º 16
0
/*
 * static void *get_space
 *
 * DESCRIPTION:
 *
 * Moved a pointer into our free lists.
 *
 * RETURNS:
 *
 * Success - New address that we can use.
 *
 * Failure - NULL
 *
 * ARGUMENTS:
 *
 * mp_p <-> Pointer to the memory pool.
 *
 * byte_size -> Size of the address space that we need.
 *
 * error_p <- Pointer to integer which, if not NULL, will be set with
 * a mpool error code.
 */
static	void	*get_space(mpool_t *mp_p, const unsigned long byte_size,
			   int *error_p)
{
  mpool_block_t	*block_p;
  mpool_free_t	free_pnt;
  int		ret;
  unsigned long	size;
  unsigned int	bit_c, page_n, left;
  void		*free_addr = NULL, *free_end;
  
  size = byte_size;
  while ((size & (sizeof(void *) - 1)) > 0) {
    size++;
  }
  
  /*
   * First we check the free lists looking for something with enough
   * pages.  Maybe we should only look X bits higher in the list.
   *
   * XXX: this is where we'd do the best fit.  We'd look for the
   * closest match.  We then could put the rest of the allocation that
   * we did not use in a lower free list.  Have a define which states
   * how deep in the free list to go to find the closest match.
   */
  for (bit_c = size_to_bits(size); bit_c <= MAX_BITS; bit_c++) {
    if (mp_p->mp_free[bit_c] != NULL) {
      free_addr = mp_p->mp_free[bit_c];
      break;
    }
  }
  
  /*
   * If we haven't allocated any blocks or if the last block doesn't
   * have enough memory then we need a new block.
   */
  if (bit_c > MAX_BITS) {
    
    /* we need to allocate more space */
    
    page_n = PAGES_IN_SIZE(mp_p, size);
    
    /* now we try and get the pages we need/want */
    block_p = alloc_pages(mp_p, page_n, error_p);
    if (block_p == NULL) {
      /* error_p set in alloc_pages */
      return NULL;
    }
    
    /* init the block header */
    block_p->mb_magic = BLOCK_MAGIC;
    block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(mp_p, page_n);
    block_p->mb_next_p = mp_p->mp_first_p;
    block_p->mb_magic2 = BLOCK_MAGIC;
    
    /*
     * We insert it into the front of the queue.  We could add it to
     * the end but there is not much use.
     */
    mp_p->mp_first_p = block_p;
    if (mp_p->mp_last_p == NULL) {
      mp_p->mp_last_p = block_p;
    }
    
    free_addr = FIRST_ADDR_IN_BLOCK(block_p);
    
#ifdef DEBUG
    (void)printf("had to allocate space for %lx of %lu bytes\n",
		 (long)free_addr, size);
#endif

    free_end = (char *)free_addr + size;
    left = (char *)block_p->mb_bounds_p - (char *)free_end;
  }
  else {
    
    if (bit_c < min_bit_free_next) {
      mp_p->mp_free[bit_c] = NULL;
      /* calculate the number of left over bytes */
      left = bits_to_size(bit_c) - size;
    }
    else if (bit_c < min_bit_free_next) {
      /* grab the next pointer from the freed address into our list */
      memcpy(mp_p->mp_free + bit_c, free_addr, sizeof(void *));
      /* calculate the number of left over bytes */
      left = bits_to_size(bit_c) - size;
    }
    else {
      /* grab the free structure from the address */
      memcpy(&free_pnt, free_addr, sizeof(free_pnt));
      mp_p->mp_free[bit_c] = free_pnt.mf_next_p;
      
      /* are we are splitting up a multiblock chunk into fewer blocks? */
      if (PAGES_IN_SIZE(mp_p, free_pnt.mf_size) > PAGES_IN_SIZE(mp_p, size)) {
	ret = split_block(mp_p, free_addr, size);
	if (ret != MPOOL_ERROR_NONE) {
	  SET_POINTER(error_p, ret);
	  return NULL;
	}
	/* left over memory was taken care of in split_block */
	left = 0;
      }
      else {
	/* calculate the number of left over bytes */
	left = free_pnt.mf_size - size;
      }
    }
    
#ifdef DEBUG
    (void)printf("found a free block at %lx of %lu bytes\n",
		 (long)free_addr, left + size);
#endif
    
    free_end = (char *)free_addr + size;
  }
  
  /*
   * If we have memory left over then we free it so someone else can
   * use it.  We do not free the space if we just allocated a
   * multi-block chunk because we need to have every allocation easily
   * find the start of the block.  Every user address % page-size
   * should take us to the start of the block.
   */
  if (left > 0 && size <= MAX_BLOCK_USER_MEMORY(mp_p)) {
    /* free the rest of the block */
    ret = free_pointer(mp_p, free_end, left);
    if (ret != MPOOL_ERROR_NONE) {
      SET_POINTER(error_p, ret);
      return NULL;
    }
  }
  
  /* update our bounds */
  if (free_addr > mp_p->mp_bounds_p) {
    mp_p->mp_bounds_p = free_addr;
  }
  else if (free_addr < mp_p->mp_min_p) {
    mp_p->mp_min_p = free_addr;
  }
  
  return free_addr;
}
Exemplo n.º 17
0
void setDeviceHandle(JNIEnv* env, const libusb_device_handle* deviceHandle,
    jobject object)
{
    SET_POINTER(env, deviceHandle, object, "deviceHandlePointer");
}
Exemplo n.º 18
0
/*
 * mpool_t *mpool_open
 *
 * DESCRIPTION:
 *
 * Open/allocate a new memory pool.
 *
 * RETURNS:
 *
 * Success - Pool pointer which must be passed to mpool_close to
 * deallocate.
 *
 * Failure - NULL
 *
 * ARGUMENTS:
 *
 * flags -> Flags to set attributes of the memory pool.  See the top
 * of mpool.h.
 *
 * page_size -> Set the internal memory page-size.  This must be a
 * multiple of the getpagesize() value.  Set to 0 for the default.
 *
 * start_addr -> Starting address to try and allocate memory pools.
 * This is ignored if the MPOOL_FLAG_USE_SBRK is enabled.
 *
 * error_p <- Pointer to integer which, if not NULL, will be set with
 * a mpool error code.
 */
mpool_t	*mpool_open(const unsigned int flags, const unsigned int page_size,
		    void *start_addr, int *error_p)
{
  mpool_block_t	*block_p;
  int		page_n, ret;
  mpool_t	mp, *mp_p;
  void		*free_addr;
  
  if (! enabled_b) {
    startup();
  }
  
  /* zero our temp struct */
  memset(&mp, 0, sizeof(mp));
  
  mp.mp_magic = MPOOL_MAGIC;
  mp.mp_flags = flags;
  mp.mp_alloc_c = 0;
  mp.mp_user_alloc = 0;
  mp.mp_max_alloc = 0;
  mp.mp_page_c = 0;
  /* mp.mp_page_size set below */
  /* mp.mp_blocks_bit_n set below */
  /* mp.mp_fd set below */
  /* mp.mp_top set below */
  /* mp.mp_addr set below */
  mp.mp_log_func = NULL;
  mp.mp_min_p = NULL;
  mp.mp_bounds_p = NULL;
  mp.mp_first_p = NULL;
  mp.mp_last_p = NULL;
  mp.mp_magic2 = MPOOL_MAGIC;
  
  /* get and sanity check our page size */
  if (page_size > 0) {
    mp.mp_page_size = page_size;
    if (mp.mp_page_size % getpagesize() != 0) {
      SET_POINTER(error_p, MPOOL_ERROR_ARG_INVALID);
      return NULL;
    }
  }
  else {
    mp.mp_page_size = getpagesize() * DEFAULT_PAGE_MULT;
    if (mp.mp_page_size % 1024 != 0) {
      SET_POINTER(error_p, MPOOL_ERROR_PAGE_SIZE);
      return NULL;
    }
  }
  
  if (BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK)) {
    mp.mp_fd = -1;
    mp.mp_addr = NULL;
    mp.mp_top = 0;
  }
  else {
    /* open dev-zero for our mmaping */
    mp.mp_fd = open("/dev/zero", O_RDWR, 0);
    if (mp.mp_fd < 0) {
      SET_POINTER(error_p, MPOOL_ERROR_OPEN_ZERO);
      return NULL;
    }
    mp.mp_addr = start_addr;
    /* we start at the front of the file */
    mp.mp_top = 0;
  }
  
  /*
   * Find out how many pages we need for our mpool structure.
   *
   * NOTE: this adds possibly unneeded space for mpool_block_t which
   * may not be in this block.
   */
  page_n = PAGES_IN_SIZE(&mp, sizeof(mpool_t));
  
  /* now allocate us space for the actual struct */
  mp_p = alloc_pages(&mp, page_n, error_p);
  if (mp_p == NULL) {
    if (mp.mp_fd >= 0) {
      (void)close(mp.mp_fd);
      mp.mp_fd = -1;
    }
    return NULL;
  }
  
  /*
   * NOTE: we do not normally free the rest of the block here because
   * we want to lesson the chance of an allocation overwriting the
   * main structure.
   */
  if (BIT_IS_SET(flags, MPOOL_FLAG_HEAVY_PACKING)) {
    
    /* we add a block header to the front of the block */
    block_p = (mpool_block_t *)mp_p;
    
    /* init the block header */
    block_p->mb_magic = BLOCK_MAGIC;
    block_p->mb_bounds_p = (char *)block_p + SIZE_OF_PAGES(&mp, page_n);
    block_p->mb_next_p = NULL;
    block_p->mb_magic2 = BLOCK_MAGIC;
    
    /* the mpool pointer is then the 2nd thing in the block */
    mp_p = FIRST_ADDR_IN_BLOCK(block_p);
    free_addr = (char *)mp_p + sizeof(mpool_t);
    
    /* free the rest of the block */
    ret = free_pointer(&mp, free_addr,
		       (char *)block_p->mb_bounds_p - (char *)free_addr);
    if (ret != MPOOL_ERROR_NONE) {
      if (mp.mp_fd >= 0) {
	(void)close(mp.mp_fd);
	mp.mp_fd = -1;
      }
      /* NOTE: after this line mp_p will be invalid */
      (void)free_pages(block_p, SIZE_OF_PAGES(&mp, page_n),
		       BIT_IS_SET(flags, MPOOL_FLAG_USE_SBRK));
      SET_POINTER(error_p, ret);
      return NULL;
    }
    
    /*
     * NOTE: if we are HEAVY_PACKING then the 1st block with the mpool
     * header is not on the block linked list.
     */
    
    /* now copy our tmp structure into our new memory area */
    memcpy(mp_p, &mp, sizeof(mpool_t));
    
    /* we setup min/max to our current address which is as good as any */
    mp_p->mp_min_p = block_p;
    mp_p->mp_bounds_p = block_p->mb_bounds_p;
  }
  else {
    /* now copy our tmp structure into our new memory area */
    memcpy(mp_p, &mp, sizeof(mpool_t));
    
    /* we setup min/max to our current address which is as good as any */
    mp_p->mp_min_p = mp_p;
    mp_p->mp_bounds_p = (char *)mp_p + SIZE_OF_PAGES(mp_p, page_n);
  }
  
  SET_POINTER(error_p, MPOOL_ERROR_NONE);
  return mp_p;
}
void setSsUsbDeviceCapabilityDescriptor(JNIEnv* env,
    const struct libusb_ss_usb_device_capability_descriptor* descriptor, jobject object)
{
    SET_POINTER(env, descriptor, object, "ssUsbDeviceCapabilityDescriptorPointer");
}