struct ds2433_config {
size_t eeprom_size; /* eeprom size in bytes */ unsignedint page_count; /* number of 256 bits pages */ unsignedint tprog; /* time in ms for page programming */
};
/* * Check the file size bounds and adjusts count as needed. * This would not be needed if the file size didn't reset to 0 after a write.
*/ staticinline size_t w1_f23_fix_count(loff_t off, size_t count, size_t size)
{ if (off > size) return 0;
if ((off + count) > size) return (size - off);
return count;
}
#ifdef CONFIG_W1_SLAVE_DS2433_CRC staticint w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, int block)
{
u8 wrbuf[3]; int off = block * W1_PAGE_SIZE;
if (test_bit(block, data->validcrc)) return 0;
if (w1_reset_select_slave(sl)) {
bitmap_zero(data->validcrc, data->cfg->page_count); return -EIO;
}
wrbuf[0] = W1_F23_READ_EEPROM;
wrbuf[1] = off & 0xff;
wrbuf[2] = off >> 8;
w1_write_block(sl->master, wrbuf, 3);
w1_read_block(sl->master, &data->memory[off], W1_PAGE_SIZE);
/* cache the block if the CRC is valid */ if (crc16(CRC16_INIT, &data->memory[off], W1_PAGE_SIZE) == CRC16_VALID)
set_bit(block, data->validcrc);
count = w1_f23_fix_count(off, count, bin_attr->size); if (!count) return 0;
mutex_lock(&sl->master->bus_mutex);
#ifdef CONFIG_W1_SLAVE_DS2433_CRC
min_page = (off >> W1_PAGE_BITS);
max_page = (off + count - 1) >> W1_PAGE_BITS; for (i = min_page; i <= max_page; i++) { if (w1_f23_refresh_block(sl, data, i)) {
count = -EIO; goto out_up;
}
}
memcpy(buf, &data->memory[off], count);
#else/* CONFIG_W1_SLAVE_DS2433_CRC */
/* read directly from the EEPROM */ if (w1_reset_select_slave(sl)) {
count = -EIO; goto out_up;
}
wrbuf[0] = W1_F23_READ_EEPROM;
wrbuf[1] = off & 0xff;
wrbuf[2] = off >> 8;
w1_write_block(sl->master, wrbuf, 3);
w1_read_block(sl->master, buf, count);
#endif/* CONFIG_W1_SLAVE_DS2433_CRC */
out_up:
mutex_unlock(&sl->master->bus_mutex);
return count;
}
/** * w1_f23_write() - Writes to the scratchpad and reads it back for verification. * @sl: The slave structure * @addr: Address for the write * @len: length must be <= (W1_PAGE_SIZE - (addr & W1_PAGE_MASK)) * @data: The data to write * * Then copies the scratchpad to EEPROM. * The data must be on one page. * The master must be locked. * * Return: 0=Success, -1=failure
*/ staticint w1_f23_write(struct w1_slave *sl, int addr, int len, const u8 *data)
{ struct w1_f23_data *f23 = sl->family_data;
u8 wrbuf[4];
u8 rdbuf[W1_PAGE_SIZE + 3];
u8 es = (addr + len - 1) & 0x1f;
/* Write the data to the scratchpad */ if (w1_reset_select_slave(sl)) return -1;
/* Read the scratchpad and verify */ if (w1_reset_select_slave(sl)) return -1;
w1_write_8(sl->master, W1_F23_READ_SCRATCH);
w1_read_block(sl->master, rdbuf, len + 3);
/* Compare what was read against the data written */ if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
(rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) return -1;
/* Copy the scratchpad to EEPROM */ if (w1_reset_select_slave(sl)) return -1;
/* Sleep for tprog ms to wait for the write to complete */
msleep(f23->cfg->tprog);
/* Reset the bus to wake up the EEPROM (this may not be needed) */
w1_reset_bus(sl->master); #ifdef CONFIG_W1_SLAVE_DS2433_CRC
clear_bit(addr >> W1_PAGE_BITS, f23->validcrc); #endif return 0;
}
count = w1_f23_fix_count(off, count, bin_attr->size); if (!count) return 0;
#ifdef CONFIG_W1_SLAVE_DS2433_CRC /* can only write full blocks in cached mode */ if ((off & W1_PAGE_MASK) || (count & W1_PAGE_MASK)) {
dev_err(&sl->dev, "invalid offset/count off=%d cnt=%zd\n",
(int)off, count); return -EINVAL;
}
/* make sure the block CRCs are valid */ for (idx = 0; idx < count; idx += W1_PAGE_SIZE) { if (crc16(CRC16_INIT, &buf[idx], W1_PAGE_SIZE) != CRC16_VALID) {
dev_err(&sl->dev, "bad CRC at offset %d\n", (int)off); return -EINVAL;
}
} #endif/* CONFIG_W1_SLAVE_DS2433_CRC */
mutex_lock(&sl->master->bus_mutex);
/* Can only write data to one page at a time */
idx = 0; while (idx < count) {
addr = off + idx;
len = W1_PAGE_SIZE - (addr & W1_PAGE_MASK); if (len > (count - idx))
len = count - idx;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.