168 lines
3.7 KiB
C
Executable File
168 lines
3.7 KiB
C
Executable File
/*
|
|
* Common interfaces for XRadio drivers
|
|
*
|
|
* Copyright (c) 2013
|
|
* Xradio Technology Co., Ltd. <www.xradiotech.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#ifndef XRADIO_COMMON_C
|
|
#define XRADIO_COMMON_C
|
|
#include <linux/init.h>
|
|
#include <linux/vmalloc.h>
|
|
|
|
#include "xradio.h"
|
|
|
|
struct xr_file *xr_fileopen(const char *path, int open_mode, umode_t mode)
|
|
{
|
|
struct xr_file *xr_fp = NULL;
|
|
if (!path)
|
|
return NULL;
|
|
|
|
xr_fp = xr_kmalloc(sizeof(struct xr_file), false);
|
|
if (!xr_fp) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s:xr_kmalloc failed,size=%lu!\n",
|
|
__func__, (unsigned long)sizeof(struct xr_file));
|
|
return NULL;
|
|
}
|
|
memset(xr_fp, 0, sizeof(struct xr_file));
|
|
|
|
/*open file.*/
|
|
xr_fp->fp = filp_open(path, open_mode, mode);
|
|
if (IS_ERR(xr_fp->fp)) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "filp_open failed(%ld)\n", (long)xr_fp->fp);
|
|
kfree(xr_fp);
|
|
return NULL;
|
|
}
|
|
/*get file size.*/
|
|
if (xr_fp->fp->f_op->llseek != NULL) {
|
|
mm_segment_t old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
xr_fp->size = vfs_llseek(xr_fp->fp, 0, SEEK_END);
|
|
vfs_llseek(xr_fp->fp, 0, SEEK_SET);
|
|
set_fs(old_fs);
|
|
} else {
|
|
xr_fp->size = 0;
|
|
}
|
|
return xr_fp;
|
|
}
|
|
|
|
int xr_fileclose(const struct xr_file *xr_fp)
|
|
{
|
|
if (xr_fp) {
|
|
if (!IS_ERR(xr_fp->fp))
|
|
filp_close(xr_fp->fp, NULL);
|
|
if (xr_fp->data)
|
|
kfree(xr_fp->data);
|
|
kfree(xr_fp);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int xr_fileread(const struct xr_file *xr_fp, char *buffer, int size)
|
|
{
|
|
int ret = -1;
|
|
if (xr_fp && buffer) {
|
|
mm_segment_t old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
ret = vfs_read(xr_fp->fp, buffer, size, &xr_fp->fp->f_pos);
|
|
if (ret < 0) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s failed(%d)\n",
|
|
__func__, ret);
|
|
}
|
|
set_fs(old_fs);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int xr_filewrite(const struct xr_file *xr_fp, char *buffer, int size)
|
|
{
|
|
int ret = -1;
|
|
if (xr_fp && buffer) {
|
|
mm_segment_t old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
ret = vfs_write(xr_fp->fp, buffer, size, &xr_fp->fp->f_pos);
|
|
if (ret < 0) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s failed(%d)\n",
|
|
__func__, ret);
|
|
}
|
|
set_fs(old_fs);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
struct xr_file *xr_request_file(const char *path)
|
|
{
|
|
int ret = -1;
|
|
struct xr_file *xr_fp = xr_fileopen(path, O_RDONLY, 0);
|
|
if (!xr_fp) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s:xr_fileopen failed!\n", __func__);
|
|
return NULL;
|
|
}
|
|
/*get file data.*/
|
|
if (xr_fp->size) {
|
|
xr_fp->data = xr_kmalloc(xr_fp->size, false);
|
|
if (xr_fp->data) {
|
|
mm_segment_t old_fs = get_fs();
|
|
set_fs(KERNEL_DS);
|
|
ret = vfs_read(xr_fp->fp, xr_fp->data, xr_fp->size,
|
|
&xr_fp->fp->f_pos);
|
|
set_fs(old_fs);
|
|
}
|
|
}
|
|
if (ret < 0) {
|
|
xr_fileclose(xr_fp);
|
|
xr_fp = NULL;
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s %s failed(%d)\n",
|
|
__func__, path, ret);
|
|
}
|
|
return xr_fp;
|
|
}
|
|
|
|
/* To use macaddr and ps mode of customers */
|
|
int access_file(char *path, char *buffer, int size, int isRead)
|
|
{
|
|
int ret = 0;
|
|
struct file *fp;
|
|
mm_segment_t old_fs = get_fs();
|
|
|
|
if (isRead)
|
|
fp = filp_open(path, O_RDONLY, S_IRUSR);
|
|
else
|
|
fp = filp_open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
|
|
|
if (IS_ERR(fp)) {
|
|
if ((long)fp != -ENOENT)
|
|
xradio_dbg(XRADIO_DBG_ERROR,
|
|
"can't open %s, failed(%ld)\n", path, (long)fp);
|
|
return -1;
|
|
}
|
|
|
|
if (isRead) {
|
|
fp->f_pos = 0;
|
|
set_fs(KERNEL_DS);
|
|
ret = vfs_read(fp, buffer, size, &fp->f_pos);
|
|
set_fs(old_fs);
|
|
} else {
|
|
fp->f_pos = 0;
|
|
set_fs(KERNEL_DS);
|
|
ret = vfs_write(fp, buffer, size, &fp->f_pos);
|
|
set_fs(old_fs);
|
|
}
|
|
if (ret < 0) {
|
|
xradio_dbg(XRADIO_DBG_ERROR, "%s %s failed(%d)\n",
|
|
isRead?"Read":"Write", path, ret);
|
|
}
|
|
|
|
filp_close(fp, NULL);
|
|
|
|
xradio_dbg(XRADIO_DBG_NIY, "Access_file %s(%d)\n", path, ret);
|
|
return ret;
|
|
}
|
|
|
|
#endif /*XRADIO_COMMON_C*/
|