Merge commit '1653208bf47b0d44ebc2ba96f07c639049176669' into HEAD

Change-Id: I9c5823d88f65f85c639d97a74eaf041b24876a0e
Signed-off-by: Shreyas Narayan <shrena@codeaurora.org>
This commit is contained in:
Shreyas Narayan 2019-02-01 07:52:47 +05:30
commit a440819fb4
11 changed files with 437 additions and 591 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2015-2017,2019 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -81,6 +81,7 @@
qcom,gpu-qdss-stm = <0x081c0000 0x40000>; // base addr, size
qcom,tsens-name = "tsens_tz_sensor14";
/* Trace bus */
coresight-id = <300>;
coresight-name = "coresight-gfx";

View file

@ -2638,6 +2638,7 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
struct fastrpc_apps *me = &gfa;
struct fastrpc_file *fl = filp->private_data;
struct hlist_node *n;
struct fastrpc_buf *buf = NULL;
struct fastrpc_mmap *map = NULL;
struct fastrpc_mmap *gmaps = NULL;
struct smq_invoke_ctx *ictx = NULL;
@ -2797,6 +2798,22 @@ static ssize_t fastrpc_debugfs_read(struct file *filp, char __user *buffer,
"%-20d|0x%-20lX\n\n",
map->secure, map->attr);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n======%s %s %s======\n", title,
" LIST OF CACHED BUFS ", title);
spin_lock(&fl->hlock);
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%-19s|%-19s|%-19s\n",
"virt", "phys", "size");
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"%s%s%s%s%s\n", single_line, single_line,
single_line, single_line, single_line);
hlist_for_each_entry_safe(buf, n, &fl->cached_bufs, hn) {
len += scnprintf(fileinfo + len,
DEBUGFS_SIZE - len,
"0x%-17p|0x%-17llX|%-19zu\n",
buf->virt, (uint64_t)buf->phys, buf->size);
}
len += scnprintf(fileinfo + len, DEBUGFS_SIZE - len,
"\n%s %s %s\n", title,
" LIST OF PENDING SMQCONTEXTS ", title);
@ -2931,7 +2948,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp)
if (err)
return err;
snprintf(strpid, PID_SIZE, "%d", current->pid);
buf_size = strlen(current->comm) + strlen(strpid) + 1;
buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1;
fl->debug_buf = kzalloc(buf_size, GFP_KERNEL);
snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d",
current->comm, "_", current->pid);

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@ -119,6 +119,17 @@ struct compat_fastrpc_ioctl_perf { /* kernel performance data */
compat_uptr_t keys;
};
#define FASTRPC_CONTROL_LATENCY (1)
struct compat_fastrpc_ctrl_latency {
compat_uint_t enable; /* latency control enable */
compat_uint_t level; /* level of control */
};
#define FASTRPC_CONTROL_SMMU (2)
struct compat_fastrpc_ctrl_smmu {
compat_uint_t sharedcb;
};
#define FASTRPC_CONTROL_KALLOC (3)
struct compat_fastrpc_ctrl_kalloc {
compat_uint_t kalloc_support; /* Remote memory allocation from kernel */
@ -127,6 +138,8 @@ struct compat_fastrpc_ctrl_kalloc {
struct compat_fastrpc_ioctl_control {
compat_uint_t req;
union {
struct compat_fastrpc_ctrl_latency lp;
struct compat_fastrpc_ctrl_smmu smmu;
struct compat_fastrpc_ctrl_kalloc kalloc;
};
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -1359,6 +1359,7 @@ static ssize_t iommu_debug_dma_attach_read(struct file *file, char __user *ubuf,
struct iommu_debug_device *ddev = file->private_data;
struct device *dev = ddev->dev;
char c[2];
size_t buflen = sizeof(c);
if (*offset)
return 0;
@ -1369,13 +1370,14 @@ static ssize_t iommu_debug_dma_attach_read(struct file *file, char __user *ubuf,
c[0] = dev->archdata.mapping->domain ? '1' : '0';
c[1] = '\n';
if (copy_to_user(ubuf, &c, 2)) {
buflen = min(count, buflen);
if (copy_to_user(ubuf, &c, buflen)) {
pr_err("copy_to_user failed\n");
return -EFAULT;
}
*offset = 1; /* non-zero means we're done */
return 2;
return buflen;
}
static const struct file_operations iommu_debug_dma_attach_fops = {
@ -1401,7 +1403,7 @@ static ssize_t iommu_debug_virt_addr_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "0x%pK\n", virt_addr);
buflen = strlen(buf);
buflen = min(count, strlen(buf)+1);
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1432,19 +1434,21 @@ static ssize_t iommu_debug_attach_read(struct file *file, char __user *ubuf,
{
struct iommu_debug_device *ddev = file->private_data;
char c[2];
size_t buflen = sizeof(c);
if (*offset)
return 0;
c[0] = ddev->domain ? '1' : '0';
c[1] = '\n';
if (copy_to_user(ubuf, &c, 2)) {
buflen = min(count, buflen);
if (copy_to_user(ubuf, &c, buflen)) {
pr_err("copy_to_user failed\n");
return -EFAULT;
}
*offset = 1; /* non-zero means we're done */
return 2;
return buflen;
}
static const struct file_operations iommu_debug_attach_fops = {
@ -1523,7 +1527,7 @@ static ssize_t iommu_debug_pte_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "pte=%016llx\n", pte);
buflen = strlen(buf);
buflen = min(count, strlen(buf)+1);
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1592,7 +1596,7 @@ static ssize_t iommu_debug_atos_read(struct file *file, char __user *ubuf,
snprintf(buf, 100, "%pa\n", &phys);
}
buflen = strlen(buf);
buflen = min(count, strlen(buf)+1);
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1645,7 +1649,7 @@ static ssize_t iommu_debug_dma_atos_read(struct file *file, char __user *ubuf,
else
snprintf(buf, 100, "%pa\n", &phys);
buflen = strlen(buf);
buflen = min(count, strlen(buf)+1);
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;
@ -1876,7 +1880,7 @@ static ssize_t iommu_debug_dma_map_read(struct file *file, char __user *ubuf,
iova = ddev->iova;
snprintf(buf, 100, "%pa\n", &iova);
buflen = strlen(buf);
buflen = min(count, strlen(buf)+1);
if (copy_to_user(ubuf, buf, buflen)) {
pr_err("Couldn't copy_to_user\n");
retval = -EFAULT;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -215,32 +215,35 @@ static long msm_ispif_cmd_ext(struct v4l2_subdev *sd,
long rc = 0;
struct ispif_device *ispif =
(struct ispif_device *)v4l2_get_subdevdata(sd);
struct ispif_cfg_data_ext pcdata;
struct ispif_cfg_data_ext pcdata = {0};
struct msm_ispif_param_data_ext *params = NULL;
if (is_compat_task()) {
#ifdef CONFIG_COMPAT
struct ispif_cfg_data_ext_32 *pcdata32 =
(struct ispif_cfg_data_ext_32 *)arg;
struct ispif_cfg_data_ext_32 *pcdata32 =
(struct ispif_cfg_data_ext_32 *)arg;
if (pcdata32 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata32->cfg_type;
pcdata.size = pcdata32->size;
pcdata.data = compat_ptr(pcdata32->data);
if (pcdata32 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata32->cfg_type;
pcdata.size = pcdata32->size;
pcdata.data = compat_ptr(pcdata32->data);
#else
struct ispif_cfg_data_ext *pcdata64 =
(struct ispif_cfg_data_ext *)arg;
if (pcdata64 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata64->cfg_type;
pcdata.size = pcdata64->size;
pcdata.data = pcdata64->data;
#endif
} else {
struct ispif_cfg_data_ext *pcdata64 =
(struct ispif_cfg_data_ext *)arg;
if (pcdata64 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata64->cfg_type;
pcdata.size = pcdata64->size;
pcdata.data = pcdata64->data;
}
if (pcdata.size != sizeof(struct msm_ispif_param_data_ext)) {
pr_err("%s: payload size mismatch\n", __func__);
return -EINVAL;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, 2019 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -230,32 +230,34 @@ static long msm_ispif_cmd_ext(struct v4l2_subdev *sd,
long rc = 0;
struct ispif_device *ispif =
(struct ispif_device *)v4l2_get_subdevdata(sd);
struct ispif_cfg_data_ext pcdata;
struct ispif_cfg_data_ext pcdata = {0};
struct msm_ispif_param_data_ext *params = NULL;
if (is_compat_task()) {
#ifdef CONFIG_COMPAT
struct ispif_cfg_data_ext_32 *pcdata32 =
(struct ispif_cfg_data_ext_32 *)arg;
struct ispif_cfg_data_ext_32 *pcdata32 =
(struct ispif_cfg_data_ext_32 *)arg;
if (pcdata32 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata32->cfg_type;
pcdata.size = pcdata32->size;
pcdata.data = compat_ptr(pcdata32->data);
#else
struct ispif_cfg_data_ext *pcdata64 =
if (pcdata32 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata32->cfg_type;
pcdata.size = pcdata32->size;
pcdata.data = compat_ptr(pcdata32->data);
#endif
} else {
struct ispif_cfg_data_ext *pcdata64 =
(struct ispif_cfg_data_ext *)arg;
if (pcdata64 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
if (pcdata64 == NULL) {
pr_err("Invalid params passed from user\n");
return -EINVAL;
}
pcdata.cfg_type = pcdata64->cfg_type;
pcdata.size = pcdata64->size;
pcdata.data = pcdata64->data;
}
pcdata.cfg_type = pcdata64->cfg_type;
pcdata.size = pcdata64->size;
pcdata.data = pcdata64->data;
#endif
if (pcdata.size != sizeof(struct msm_ispif_param_data_ext)) {
pr_err("%s: payload size mismatch\n", __func__);
return -EINVAL;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -449,6 +449,11 @@ struct rndis_pkt_hdr rndis_template_hdr = {
.zeroes = {0},
};
static void rndis_ipa_msg_free_cb(void *buff, u32 len, u32 type)
{
kfree(buff);
}
/**
* rndis_ipa_init() - create network device and initialize internal
* data structures
@ -648,6 +653,8 @@ int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl,
int next_state;
int result;
unsigned long flags;
struct ipa_ecm_msg *rndis_msg;
struct ipa_msg_meta msg_meta;
RNDIS_IPA_LOG_ENTRY();
@ -718,6 +725,26 @@ int rndis_ipa_pipe_connect_notify(u32 usb_to_ipa_hdl,
}
RNDIS_IPA_DEBUG("netif_carrier_on() was called\n");
rndis_msg = kzalloc(sizeof(*rndis_msg), GFP_KERNEL);
if (!rndis_msg) {
result = -ENOMEM;
goto fail;
}
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = ECM_CONNECT;
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
strlcpy(rndis_msg->name, rndis_ipa_ctx->net->name,
IPA_RESOURCE_NAME_MAX);
rndis_msg->ifindex = rndis_ipa_ctx->net->ifindex;
result = ipa_send_msg(&msg_meta, rndis_msg, rndis_ipa_msg_free_cb);
if (result) {
RNDIS_IPA_ERROR("fail to send ECM_CONNECT for rndis\n");
kfree(rndis_msg);
goto fail;
}
spin_lock_irqsave(&rndis_ipa_ctx->state_lock, flags);
next_state = rndis_ipa_next_state(rndis_ipa_ctx->state,
RNDIS_IPA_CONNECT);
@ -1165,6 +1192,8 @@ int rndis_ipa_pipe_disconnect_notify(void *private)
int outstanding_dropped_pkts;
int retval;
unsigned long flags;
struct ipa_ecm_msg *rndis_msg;
struct ipa_msg_meta msg_meta;
RNDIS_IPA_LOG_ENTRY();
@ -1192,6 +1221,23 @@ int rndis_ipa_pipe_disconnect_notify(void *private)
netif_carrier_off(rndis_ipa_ctx->net);
RNDIS_IPA_DEBUG("carrier_off notification was sent\n");
rndis_msg = kzalloc(sizeof(*rndis_msg), GFP_KERNEL);
if (!rndis_msg)
return -ENOMEM;
memset(&msg_meta, 0, sizeof(struct ipa_msg_meta));
msg_meta.msg_type = ECM_DISCONNECT;
msg_meta.msg_len = sizeof(struct ipa_ecm_msg);
strlcpy(rndis_msg->name, rndis_ipa_ctx->net->name,
IPA_RESOURCE_NAME_MAX);
rndis_msg->ifindex = rndis_ipa_ctx->net->ifindex;
retval = ipa_send_msg(&msg_meta, rndis_msg, rndis_ipa_msg_free_cb);
if (retval) {
RNDIS_IPA_ERROR("fail to send ECM_DISCONNECT for rndis\n");
kfree(rndis_msg);
return -EPERM;
}
netif_stop_queue(rndis_ipa_ctx->net);
RNDIS_IPA_DEBUG("queue stopped\n");

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -89,6 +89,9 @@ struct wdsp_glink_ch {
/* Wait for ch connect state before sending any command */
wait_queue_head_t ch_connect_wait;
/* Wait for ch local and remote disconnect before channel free */
wait_queue_head_t ch_free_wait;
/*
* Glink channel configuration. This has to be the last
* member of the strucuture as it has variable size
@ -338,7 +341,7 @@ static void wdsp_glink_notify_state(void *handle, const void *priv,
mutex_lock(&ch->mutex);
ch->channel_state = event;
if (event == GLINK_CONNECTED) {
dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n",
dev_info(wpriv->dev, "%s: glink channel: %s connected\n",
__func__, ch->ch_cfg.name);
for (i = 0; i < ch->ch_cfg.no_of_intents; i++) {
@ -360,31 +363,29 @@ static void wdsp_glink_notify_state(void *handle, const void *priv,
ch->ch_cfg.name);
wake_up(&ch->ch_connect_wait);
mutex_unlock(&ch->mutex);
} else if (event == GLINK_LOCAL_DISCONNECTED) {
/*
* Don't use dev_dbg here as dev may not be valid if channel
* closed from driver close.
*/
pr_debug("%s: channel: %s disconnected locally\n",
pr_info("%s: channel: %s disconnected locally\n",
__func__, ch->ch_cfg.name);
mutex_unlock(&ch->mutex);
if (ch->free_mem) {
kfree(ch);
ch = NULL;
}
ch->free_mem = true;
wake_up(&ch->ch_free_wait);
return;
} else if (event == GLINK_REMOTE_DISCONNECTED) {
dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n",
pr_info("%s: remote channel: %s disconnected remotely\n",
__func__, ch->ch_cfg.name);
mutex_unlock(&ch->mutex);
/*
* If remote disconnect happens, local side also has
* to close the channel as per glink design in a
* separate work_queue.
*/
queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
if (wpriv && wpriv->work_queue != NULL)
queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
}
mutex_unlock(&ch->mutex);
}
/*
@ -399,11 +400,11 @@ static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch)
mutex_lock(&wpriv->glink_mutex);
if (ch->handle) {
ret = glink_close(ch->handle);
ch->handle = NULL;
if (IS_ERR_VALUE(ret)) {
dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n",
__func__, ret);
} else {
ch->handle = NULL;
dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__,
ch->ch_cfg.name);
}
@ -451,6 +452,7 @@ static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch)
ch->handle = NULL;
ret = -EINVAL;
}
ch->free_mem = false;
} else {
dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__,
ch->ch_cfg.name);
@ -492,7 +494,7 @@ static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv)
err_open:
for (j = 0; j < i; j++)
if (wpriv->ch[i])
if (wpriv->ch[j])
wdsp_glink_close_ch(wpriv->ch[j]);
done:
@ -631,6 +633,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
goto err_ch_mem;
}
ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED;
ch[i]->free_mem = true;
memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size);
payload += ch_cfg_size;
@ -654,6 +657,7 @@ static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk);
INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk);
init_waitqueue_head(&ch[i]->ch_connect_wait);
init_waitqueue_head(&ch[i]->ch_free_wait);
}
INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk);
@ -1060,37 +1064,49 @@ static int wdsp_glink_release(struct inode *inode, struct file *file)
goto done;
}
dev_info(wpriv->dev, "%s: closing wdsp_glink driver\n", __func__);
if (wpriv->glink_state.handle)
glink_unregister_link_state_cb(wpriv->glink_state.handle);
flush_workqueue(wpriv->work_queue);
destroy_workqueue(wpriv->work_queue);
/*
* Clean up glink channel memory in channel state
* callback only if close channels are called from here.
* Wait for channel local and remote disconnect state notifications
* before freeing channel memory.
*/
if (wpriv->ch) {
for (i = 0; i < wpriv->no_of_channels; i++) {
if (wpriv->ch[i]) {
wpriv->ch[i]->free_mem = true;
/*
* Channel handle NULL means channel is already
* closed. Free the channel memory here itself.
*/
if (!wpriv->ch[i]->handle) {
kfree(wpriv->ch[i]);
wpriv->ch[i] = NULL;
} else {
wdsp_glink_close_ch(wpriv->ch[i]);
}
for (i = 0; i < wpriv->no_of_channels; i++) {
if (wpriv->ch && wpriv->ch[i]) {
/*
* Only close glink channel from here if REMOTE has
* not already disconnected it
*/
wdsp_glink_close_ch(wpriv->ch[i]);
ret = wait_event_timeout(wpriv->ch[i]->ch_free_wait,
(wpriv->ch[i]->free_mem == true),
msecs_to_jiffies(TIMEOUT_MS));
if (!ret) {
pr_err("%s: glink ch %s failed to notify states properly %d\n",
__func__, wpriv->ch[i]->ch_cfg.name,
wpriv->ch[i]->channel_state);
ret = -EINVAL;
goto done;
}
}
kfree(wpriv->ch);
wpriv->ch = NULL;
}
flush_workqueue(wpriv->work_queue);
destroy_workqueue(wpriv->work_queue);
wpriv->work_queue = NULL;
for (i = 0; i < wpriv->no_of_channels; i++) {
if (wpriv->ch && wpriv->ch[i]) {
kfree(wpriv->ch[i]);
wpriv->ch[i] = NULL;
}
}
kfree(wpriv->ch);
wpriv->ch = NULL;
mutex_destroy(&wpriv->glink_mutex);
mutex_destroy(&wpriv->rsp_mutex);
kfree(wpriv);

View file

@ -1113,8 +1113,6 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SRC_NEGOTIATE_CAPABILITY:
if (PD_RDO_OBJ_POS(pd->rdo) != 1 ||
PD_RDO_FIXED_CURR(pd->rdo) >
PD_SRC_PDO_FIXED_MAX_CURR(*default_src_caps) ||
PD_RDO_FIXED_CURR_MINMAX(pd->rdo) >
PD_SRC_PDO_FIXED_MAX_CURR(*default_src_caps)) {
/* send Reject */
ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG);

View file

@ -454,10 +454,10 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
}
bio_set_op_attrs(bio, fio->op, fio->op_flags);
__submit_bio(fio->sbi, bio, fio->type);
if (!is_read_io(fio->op))
inc_page_count(fio->sbi, WB_DATA_TYPE(fio->page));
__submit_bio(fio->sbi, bio, fio->type);
return 0;
}

File diff suppressed because it is too large Load diff