drivers/mtd/inftlcore.c

Source file repositories/reference/linux-study-clean/drivers/mtd/inftlcore.c

File Facts

System
Linux kernel
Corpus path
drivers/mtd/inftlcore.c
Extension
.c
Size
24253 bytes
Lines
946
Domain
Driver Families
Bucket
drivers/mtd
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (inftl->mbd.size % temp) {
			inftl->heads++;
			temp = inftl->heads * inftl->sectors;
			inftl->cylinders = inftl->mbd.size / temp;
		}
	}

	if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
		/*
		  Oh no we don't have
		   mbd.size == heads * cylinders * sectors
		*/
		printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
		       "match size of 0x%lx.\n", inftl->mbd.size);
		printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
			"(== 0x%lx sects)\n",
			inftl->cylinders, inftl->heads , inftl->sectors,
			(long)inftl->cylinders * (long)inftl->heads *
			(long)inftl->sectors );
	}

	if (add_mtd_blktrans_dev(&inftl->mbd)) {
		kfree(inftl->PUtable);
		kfree(inftl->VUtable);
		kfree(inftl);
		return;
	}
#ifdef PSYCHO_DEBUG
	printk(KERN_INFO "INFTL: Found new inftl%c\n", inftl->mbd.devnum + 'a');
#endif
	return;
}

static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
{
	struct INFTLrecord *inftl = (void *)dev;

	pr_debug("INFTL: remove_dev (i=%d)\n", dev->devnum);

	del_mtd_blktrans_dev(dev);

	kfree(inftl->PUtable);
	kfree(inftl->VUtable);
}

/*
 * Actual INFTL access routines.
 */

/*
 * Read oob data from flash
 */
int inftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
		   size_t *retlen, uint8_t *buf)
{
	struct mtd_oob_ops ops = { };
	int res;

	ops.mode = MTD_OPS_PLACE_OOB;
	ops.ooboffs = offs & (mtd->writesize - 1);
	ops.ooblen = len;
	ops.oobbuf = buf;
	ops.datbuf = NULL;

	res = mtd_read_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
	*retlen = ops.oobretlen;
	return res;
}

/*
 * Write oob data to flash
 */
int inftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
		    size_t *retlen, uint8_t *buf)
{
	struct mtd_oob_ops ops = { };
	int res;

	ops.mode = MTD_OPS_PLACE_OOB;
	ops.ooboffs = offs & (mtd->writesize - 1);
	ops.ooblen = len;
	ops.oobbuf = buf;
	ops.datbuf = NULL;

	res = mtd_write_oob(mtd, offs & ~(mtd->writesize - 1), &ops);
	*retlen = ops.oobretlen;
	return res;
}

/*

Annotation

Implementation Notes