예제 #1
0
파일: sflash.c 프로젝트: janfj/dd-wrt
static int
sflash_mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
{
    struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
    int bytes, ret = 0;

    /* Check address range */
    if (!len)
        return 0;
    if ((to + len) > mtd->size)
        return -EINVAL;

    down(&sflash->lock);

    *retlen = 0;
    while (len) {
        if ((bytes = sflash_write(sflash->sbh, sflash->cc, (uint) to, len, buf)) < 0) {
            ret = bytes;
            break;
        }
        if ((ret = sflash_mtd_poll(sflash, (unsigned int) to, HZ / 10)))
            break;
        to += (loff_t) bytes;
        len -= bytes;
        buf += bytes;
        *retlen += bytes;
    }

    up(&sflash->lock);

    return ret;
}
예제 #2
0
파일: sflash.c 프로젝트: Cribstone/linino
static int
sflash_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
{
	struct sflash_mtd *sflash = (struct sflash_mtd *) mtd->priv;
	int i, j, ret = 0;
	unsigned int addr, len;

	/* Check address range */
	if (!erase->len)
		return 0;
	if ((erase->addr + erase->len) > mtd->size)
		return -EINVAL;

	addr = erase->addr;
	len = erase->len;

	down(&sflash->lock);

	/* Ensure that requested region is aligned */
	for (i = 0; i < mtd->numeraseregions; i++) {
		for (j = 0; j < mtd->eraseregions[i].numblocks; j++) {
			if (addr == mtd->eraseregions[i].offset + mtd->eraseregions[i].erasesize * j &&
			    len >= mtd->eraseregions[i].erasesize) {
				if ((ret = sflash_erase(sflash->sbh, sflash->cc, addr)) < 0)
					break;
				if ((ret = sflash_mtd_poll(sflash, addr, 10 * HZ)))
					break;
				addr += mtd->eraseregions[i].erasesize;
				len -= mtd->eraseregions[i].erasesize;
			}
		}
		if (ret)
			break;
	}

	up(&sflash->lock);

	/* Set erase status */
	if (ret)
		erase->state = MTD_ERASE_FAILED;
	else 
		erase->state = MTD_ERASE_DONE;

	/* Call erase callback */
	if (erase->callback)
		erase->callback(erase);

	return ret;
}