in slaves/w1_ds2805.c [202:262]
static ssize_t w1_f0d_write_bin(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
struct w1_slave *sl = kobj_to_w1_slave(kobj);
int addr, len;
int copy;
count = w1_f0d_fix_count(off, count, W1_F0D_EEPROM_SIZE);
if (count == 0)
return 0;
mutex_lock(&sl->master->mutex);
/* Can only write data in blocks of the size of the scratchpad */
addr = off;
len = count;
while (len > 0) {
/* if len too short or addr not aligned */
if (len < W1_F0D_SCRATCH_SIZE || addr & W1_F0D_SCRATCH_MASK) {
char tmp[W1_F0D_SCRATCH_SIZE];
/* read the block and update the parts to be written */
if (w1_f0d_readblock(sl, addr & ~W1_F0D_SCRATCH_MASK,
W1_F0D_SCRATCH_SIZE, tmp)) {
count = -EIO;
goto out_up;
}
/* copy at most to the boundary of the PAGE or len */
copy = W1_F0D_SCRATCH_SIZE -
(addr & W1_F0D_SCRATCH_MASK);
if (copy > len)
copy = len;
memcpy(&tmp[addr & W1_F0D_SCRATCH_MASK], buf, copy);
if (w1_f0d_write(sl, addr & ~W1_F0D_SCRATCH_MASK,
W1_F0D_SCRATCH_SIZE, tmp) < 0) {
count = -EIO;
goto out_up;
}
} else {
copy = W1_F0D_SCRATCH_SIZE;
if (w1_f0d_write(sl, addr, copy, buf) < 0) {
count = -EIO;
goto out_up;
}
}
buf += copy;
addr += copy;
len -= copy;
}
out_up:
mutex_unlock(&sl->master->mutex);
return count;
}