int ps3_lpm_copy_tb_to_user()

in ps3-lpm.c [972:1020]


int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
			    unsigned long count, unsigned long *bytes_copied)
{
	int result;

	*bytes_copied = 0;

	if (!lpm_priv->tb_cache)
		return -EPERM;

	if (offset >= lpm_priv->tb_count)
		return 0;

	count = min_t(u64, count, lpm_priv->tb_count - offset);

	while (*bytes_copied < count) {
		const unsigned long request = count - *bytes_copied;
		u64 tmp;

		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
						   request, &tmp);
		if (result) {
			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
				__func__, __LINE__, request, offset);
			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
				"failed: %s\n", __func__, __LINE__,
				ps3_result(result));
			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
		}

		result = copy_to_user(buf, lpm_priv->tb_cache, tmp);

		if (result) {
			dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n",
				__func__, __LINE__, tmp, buf);
			dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
				__func__, __LINE__, result);
			return -EFAULT;
		}

		buf += tmp;
		*bytes_copied += tmp;
		offset += tmp;
	}
	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
		*bytes_copied);

	return 0;
}