Example #1
0
int
flash_erase_region(kdev_t dev, __u32 offset, __u32 size)
{
	int minor;
	struct flashpartition *part;
	unsigned char *erase_start;
	short retries = 5;
	short success;

	minor = MINOR(dev);
	if (minor < FLASH_MINOR) {
		return -EINVAL;
	}

	part = &partitions[minor - FLASH_MINOR];
	if (!part->start) {
		return -EINVAL;
	}

	/* Start the erasure, then sleep and wake up now and then to see
	 * if it's done.
	 */

	erase_start = part->start + offset;

	flash_safe_acquire(part);
	do {
		flash_init_erase(erase_start, size);

		while (flash_is_busy((flashptr)erase_start)) {
			current->state = TASK_INTERRUPTIBLE;
			current->timeout = jiffies + HZ / 2;
			schedule();
		}

		success = ((flashptr)erase_start)[0] == FLASH_ERASE_STATE
			  && ((flashptr)erase_start)[1] == FLASH_ERASE_STATE
			  && ((flashptr)erase_start)[2] == FLASH_ERASE_STATE
			  && ((flashptr)erase_start)[3] == FLASH_ERASE_STATE;

		if (!success) {
			printk(KERN_NOTICE "flash: erase of region "
			       "[0x%p, 0x%p] failed once\n",
			       erase_start, erase_start + size);
		}

	} while (retries-- && !success);

	flash_safe_release(part);

	if (retries == 0 && !success) {
		printk(KERN_WARNING "flash: erase of region "
			       "[0x%p, 0x%p] totally failed\n",
			       erase_start, erase_start + size);
		return -1;
	}

	return 0;
}
Example #2
0
static void flash_wait_for_write_complete()
{
    int ii;
    for (ii = 0;flash_is_busy(); ii++)
    {
	// TODO check for timeout
	vTaskDelay(1);
    }
    //shell_printf("waited %d", ii);
}
Example #3
0
static int32_t flash_status_check_orig(flash_info_t * info, cfiptr_t cptr, cfiword_t * cword,
                                   uint32_t tout, char *prompt)
{
    uint32_t start;

    /* Wait for command completion */
    start = get_timer(0);

    while (flash_is_busy(info, cptr, cword)) {
        if ((flash_time_out(info, cptr)) || ((get_timer(start)) > tout * CFG_HZ)) {
            if (flash_is_busy(info, cptr, cword)) {
                printf("Flash %s timeout at address %x data %x\n",
                       prompt, (uint32_t) cptr.cp, cword->l);
                flash_write_cmd(info, 0, 0, info->cmd_reset);
                return ERR_TIMOUT;
            }
        }
    }

    return ERR_OK;
}
Example #4
0
void
flash_busy_wait_erase(unsigned char *ptr)
{
	flashptr flashStart;

	ptr = (unsigned char *)((unsigned long)ptr | MEM_NON_CACHEABLE);
	flashStart = (flashptr)getchip(ptr)->start;

	/* busy-wait for flash completion - when D6 stops toggling between
	 * reads.
	 */
	while (flash_is_busy(flashStart))
		/* nothing */;
}
Example #5
0
static int
flash_ioctl(struct inode *inode, struct file *file,
	    unsigned int cmd, unsigned long arg)
{
	int minor;
	struct flashpartition *part;
	struct flashchipinfo *finfo;

	if (!inode || !inode->i_rdev)
		return -EINVAL;

	minor = MINOR(inode->i_rdev);

	if(minor < FLASH_MINOR)
		return -EINVAL; /* only ioctl's for flash devices */

	part = &partitions[minor - FLASH_MINOR];

	switch(cmd) {
	case FLASHIO_CHIPINFO:

		if(!suser())
			return -EACCES;

		if(arg == 0)
			return -EINVAL;

		finfo = (struct flashchipinfo *)arg;

		/* TODO: verify arg */

		finfo->isValid = chips[0].isValid;
		finfo->manufacturer_id = chips[0].manufacturer_id;
		finfo->device_id = chips[0].device_id;
		finfo->size = chips[0].size;
		finfo->sectorsize = chips[0].sectorsize;

		return 0;

	case FLASHIO_ERASEALL:
		FDEBUG(printk("flash_ioctl(): Got FLASHIO_ERASEALL request.\n"));

		if(!part->start)
			return -EINVAL;

		if(!suser())
			return -EACCES;

		/* Invalidate all pages and buffers */

		invalidate_inodes(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);

		/*
		 * Start the erasure, then sleep and wake up now and
		 * then to see if it's done. We use the waitqueue to
		 * make sure we don't start erasing in the middle of
		 * a write, or that nobody start using the flash while
		 * we're erasing.
		 *
		 * TODO: break up partition erases that spans more than one
		 *       chip.
		 */

		flash_safe_acquire(part);

		flash_init_erase(part->start, part->size);
#if 1
		flash_finalize_erase(part->start, part->size);
#else
		while (flash_is_busy(part->start)
		       || !flash_pos_is_clean(part->start)) {
			current->state = TASK_INTERRUPTIBLE;
			current->timeout = jiffies + HZ / 2;
			schedule();
		}
#endif

		flash_safe_release(part);

		return 0;

	default:
		return -EPERM;
	}

	return -EPERM;
}