in adb.c [772:839]
static ssize_t adb_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
int ret/*, i*/;
struct adbdev_state *state = file->private_data;
struct adb_request *req;
if (count < 2 || count > sizeof(req->data))
return -EINVAL;
if (adb_controller == NULL)
return -ENXIO;
req = kmalloc(sizeof(struct adb_request),
GFP_KERNEL);
if (req == NULL)
return -ENOMEM;
req->nbytes = count;
req->done = adb_write_done;
req->arg = (void *) state;
req->complete = 0;
ret = -EFAULT;
if (copy_from_user(req->data, buf, count))
goto out;
atomic_inc(&state->n_pending);
/* If a probe is in progress or we are sleeping, wait for it to complete */
down(&adb_probe_mutex);
/* Queries are special requests sent to the ADB driver itself */
if (req->data[0] == ADB_QUERY) {
if (count > 1)
ret = do_adb_query(req);
else
ret = -EINVAL;
up(&adb_probe_mutex);
}
/* Special case for ADB_BUSRESET request, all others are sent to
the controller */
else if ((req->data[0] == ADB_PACKET) && (count > 1)
&& (req->data[1] == ADB_BUSRESET)) {
ret = do_adb_reset_bus();
up(&adb_probe_mutex);
atomic_dec(&state->n_pending);
if (ret == 0)
ret = count;
goto out;
} else {
req->reply_expected = ((req->data[1] & 0xc) == 0xc);
if (adb_controller && adb_controller->send_request)
ret = adb_controller->send_request(req, 0);
else
ret = -ENXIO;
up(&adb_probe_mutex);
}
if (ret != 0) {
atomic_dec(&state->n_pending);
goto out;
}
return count;
out:
kfree(req);
return ret;
}