static ssize_t cmos_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct cmos_rtc *cmos; int retval; cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); if (unlikely(off >= attr->size)) return -EFBIG; if (unlikely(off < 0)) return -EINVAL; if ((off + count) > attr->size) count = attr->size - off; off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); for (retval = 0; count; count--, off++, retval++) { if (off == cmos->day_alrm || off == cmos->mon_alrm || off == cmos->century) buf++; else if (off < 128) CMOS_WRITE(*buf++, off); else if (can_bank2) cmos_write_bank2(*buf++, off); else break; } spin_unlock_irq(&rtc_lock); return retval; }
static ssize_t cmos_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { struct cmos_rtc *cmos; int retval; cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); /* NOTE: on at least PCs and Ataris, the boot firmware uses a * checksum on part of the NVRAM data. That's currently ignored * here. If userspace is smart enough to know what fields of * NVRAM to update, updating checksums is also part of its job. */ off += NVRAM_OFFSET; spin_lock_irq(&rtc_lock); for (retval = 0; count; count--, off++, retval++) { /* don't trash RTC registers */ if (off == cmos->day_alrm || off == cmos->mon_alrm || off == cmos->century) buf++; else if (off < 128) CMOS_WRITE(*buf++, off); else if (can_bank2) cmos_write_bank2(*buf++, off); else break; } spin_unlock_irq(&rtc_lock); return retval; }