Ejemplo n.º 1
0
int procfs_register(FAR const struct procfs_entry_s *entry)
{
  FAR struct procfs_entry_s *newtable;
  unsigned int newcount;
  size_t newsize;
  int ret;

  /* Make sure that we are properly initialized */

  procfs_initialize();

  /* realloc the table of procfs entries.
   *
   * REVISIT:  This reallocation may free memory previously used for the
   * procfs entry table.  If that table were actively in use, then that
   * could cause procfs logic to use a stale memory pointer!  We avoid that
   * problem by requiring that the procfs file be unmounted when the new
   * entry is added.  That requirment, however, is not enforced explicitly.
   *
   * Locking the scheduler as done below is insufficient.  As would be just
   * marking the entries as volatile.
   */

  newcount = g_procfs_entrycount + 1;
  newsize  = newcount * sizeof(struct procfs_entry_s);

  sched_lock();
  newtable = (FAR struct procfs_entry_s *)kmm_realloc(g_procfs_entries, newsize);
  if (newtable == NULL)
    {
      /* Reallocation failed! */

      ret = -ENOMEM;
    }
  else
    {
      /* Copy the new entry at the end of the reallocated table */

      memcpy(&newtable[g_procfs_entrycount], entry, sizeof(struct procfs_entry_s));

      /* Instantiate the reallocated table */

      g_procfs_entries    = newtable;
      g_procfs_entrycount = newcount;
      ret = OK;
    }

  sched_unlock();
  return ret;
}
int elf_reallocbuffer(FAR struct elf_loadinfo_s *loadinfo, size_t increment)
{
  FAR void *buffer;
  size_t newsize;

  /* Get the new size of the allocation */

  newsize = loadinfo->buflen + increment;

  /* And perform the reallocation */

   buffer = kmm_realloc((FAR void *)loadinfo->iobuffer, newsize);
   if (!buffer)
    {
      bdbg("Failed to reallocate the I/O buffer\n");
      return -ENOMEM;
    }

  /* Save the new buffer info */

  loadinfo->iobuffer = buffer;
  loadinfo->buflen   = newsize;
  return OK;
}
Ejemplo n.º 3
0
int usbmsc_bindlun(FAR void *handle, FAR const char *drvrpath, unsigned int lunno, off_t startsector, size_t nsectors, bool readonly)
{
	FAR struct usbmsc_alloc_s *alloc = (FAR struct usbmsc_alloc_s *)handle;
	FAR struct usbmsc_dev_s *priv;
	FAR struct usbmsc_lun_s *lun;
	FAR struct inode *inode;
	struct geometry geo;
	int ret;

#ifdef CONFIG_DEBUG
	if (!alloc || !drvrpath || startsector < 0) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINLUNINVALIDARGS1), 0);
		return -EINVAL;
	}
#endif

	priv = &alloc->dev;

#ifdef CONFIG_DEBUG
	if (!priv->luntab) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_INTERNALCONFUSION1), 0);
		return -EIO;
	}

	if (lunno > priv->nluns) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS2), 0);
		return -EINVAL;
	}
#endif

	lun = &priv->luntab[lunno];

#ifdef CONFIG_DEBUG
	if (lun->inode != NULL) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_LUNALREADYBOUND), 0);
		return -EBUSY;
	}
#endif

	/* Open the block driver */

	ret = open_blockdriver(drvrpath, 0, &inode);
	if (ret < 0) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BLKDRVEOPEN), 0);
		return ret;
	}

	/* Get the drive geometry */

	if (!inode || !inode->u.i_bops || !inode->u.i_bops->geometry || inode->u.i_bops->geometry(inode, &geo) != OK || !geo.geo_available) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_NOGEOMETRY), 0);
		return -ENODEV;
	}

	/* Verify that the partition parameters are valid */

	if (startsector >= geo.geo_nsectors) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS3), 0);
		return -EDOM;
	} else if (nsectors == 0) {
		nsectors = geo.geo_nsectors - startsector;
	} else if (startsector + nsectors >= geo.geo_nsectors) {
		usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_BINDLUNINVALIDARGS4), 0);
		return -EDOM;
	}

	/* Initialize the LUN structure */

	memset(lun, 0, sizeof(struct usbmsc_lun_s *));

	/* Allocate an I/O buffer big enough to hold one hardware sector.  SCSI commands
	 * are processed one at a time so all LUNs may share a single I/O buffer.  The
	 * I/O buffer will be allocated so that is it as large as the largest block
	 * device sector size
	 */

	if (!priv->iobuffer) {
		priv->iobuffer = (FAR uint8_t *)kmm_malloc(geo.geo_sectorsize);
		if (!priv->iobuffer) {
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_ALLOCIOBUFFER), geo.geo_sectorsize);
			return -ENOMEM;
		}

		priv->iosize = geo.geo_sectorsize;
	} else if (priv->iosize < geo.geo_sectorsize) {
		void *tmp;
		tmp = (FAR uint8_t *)kmm_realloc(priv->iobuffer, geo.geo_sectorsize);
		if (!tmp) {
			usbtrace(TRACE_CLSERROR(USBMSC_TRACEERR_REALLOCIOBUFFER), geo.geo_sectorsize);
			return -ENOMEM;
		}

		priv->iobuffer = (FAR uint8_t *)tmp;
		priv->iosize = geo.geo_sectorsize;
	}

	lun->inode = inode;
	lun->startsector = startsector;
	lun->nsectors = nsectors;
	lun->sectorsize = geo.geo_sectorsize;

	/* If the driver does not support the write method, then this is read-only */

	if (!inode->u.i_bops->write) {
		lun->readonly = true;
	}

	return OK;
}