static ssize_t w1_f0d_write_bin()

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;
}