static int i2c_slave_open(struct inode *inode, struct file *fd) { int ret; unsigned int id; i2c_slave_device_t *dev; id = iminor(inode); if (id >= I2C_SLAVE_DEVICE_MAX) { ret = -ENODEV; goto error; } dev = i2c_slave_device_find(id); if (!dev) { ret = -ENODEV; goto error; } i2c_slave_rb_clear(dev->receive_buffer); i2c_slave_rb_clear(dev->send_buffer); if (i2c_slave_device_start(dev)) { ret = -EBUSY; goto error; } fd->private_data = (void *)dev; ret = 0; error: return ret; }
int i2c_slave_device_write(i2c_slave_device_t *device, int num, u8 *data) { int write_num, write_total = 0; int step = 1000; u8 *buf_index = data; write_num = i2c_slave_rb_produce(device->send_buffer, num, buf_index); write_total += write_num; buf_index += write_num; step--; while (write_total < num && step) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); if (!signal_pending(current)) { } else { /*TODO*/ step = 0; break; } write_num = i2c_slave_rb_produce(device->send_buffer, num - write_total, buf_index); write_total += write_num; buf_index += write_num; step--; } while (step && i2c_slave_rb_num(device->send_buffer)) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); if (!signal_pending(current)) { step--; } else { /*TODO*/ step = 0; break; } } if (!step) { write_total -= i2c_slave_rb_num(device->send_buffer); i2c_slave_rb_clear(device->send_buffer); } return write_total; }