Reputation: 65
I am have code:
static unsigned char buffer[512];
static struct mtd_info *mtd_ptr = NULL;
static unsigned int *counter = NULL;
static void mtdblock_read(void)
{
int readed = 0;
int ret = 0;
const unsigned int mtd_device_num = 12;
counter = (unsigned int *)buffer;
mtd_ptr = get_mtd_device(NULL, mtd_device_num);
if(IS_ERR(mtd_ptr)){
printk("Can't get mtd partition...");
mtd_ptr = NULL;
return;
}
printk("Found partition '%s'\n", mtd_ptr->name);
if(mtd_ptr->read)
{
ret = mtd_ptr->read(mtd_ptr, 0, sizeof(buffer), &readed, buffer);
printk("%s:%d - %d, readed: %d\n", __func__, __LINE__, ret, readed);
}
else
printk("Not have 'read' ops\n");
printk("current counter = 0x%08X\n", *counter);
}
static void mtdblock_write(void)
{
int writed = 0;
int ret = 0;
(*counter) = 111;
printk("Write counter (%d) to mtd\n", *counter);
if(mtd_ptr && mtd_ptr->write)
{
ret = mtd_ptr->write(mtd_ptr, 0, sizeof(buffer), &writed, buffer);
printk("%s:%d - %d, writed: %d\n", __func__, __LINE__, ret, writed);
if(mtd_ptr->sync)
mtd_ptr->sync(mtd_ptr);
}
else
printk("Not have 'write' ops or mtd is not available\n");
}
void test()
{
mtdblock_read();
mtdblock_write();
mtdblock_read();
}
mtdblock_read must read 512 bytes from mtdblock and display int value placed into first 4 bytes of buffer.
mtdblock_write puts 4-byte value at start of 512-byte buffer and write it to mtdblock.
test() executes test sequence:
1st mtdblock_read() - for read current value from mtdblock.
mtdblock_write() - for write new value
2nd mtdblock_read() - for re-read writed value.
Problem in mtdblock_read (as my opinion) because I have trace output:
Found 13 partition 'dying_gasp'
mtdblock_read:303 - 0, readed: 512
current counter = 0x00000000
Write counter (1953719668) to mtd
mtdblock_write:322 - 0, writed: 512
Found 13 partition 'dying_gasp'
mtdblock_read:303 - 0, readed: 512
current counter = 0x00000000
From this I can see that mtd_ptr->read() have return value -74, but reports into readed that it have 512 bytes readed from mtdblock. But really it is not read data from mtdblock. Additionally I am check mtd_ptr->write() but it correctly report 512 bytes writed and have zero return value.
Can you help me for solve this problem? It is internal mtdblock driver error or I am skip major operations at read or write from/to mtdlock?
Upvotes: 0
Views: 1716
Reputation: 16
This is a little late for the person asking the question, but perhaps someone else can benefit.
Found out that you cannot read into a buffer declared static if your mtd device is backed by the SPI driver. There is a section of code in spi_map_buf() in spi.c that checks for this:
if (vmalloced_buf || kmap_buf) {
desc_len = min_t(int, max_seg_size, PAGE_SIZE);
sgs = DIV_ROUND_UP(len + offset_in_page(buf), desc_len);
} else if (virt_addr_valid(buf)) {
desc_len = min_t(int, max_seg_size, ctlr->max_dma_len);
sgs = DIV_ROUND_UP(len, desc_len);
} else {
dev_err(&ctlr->dev,"Not vmalloced, not kmap, va not valid\n");
return -EINVAL;
}
So, if you go ahead and kmalloc the buffer, everything goes fine. Found this while trying to create a kernel mod that uses the MTD SPI SRAM on the i.MX6UL chip, and calling mtd_read directly.
Upvotes: 0