static int dsm_register_extern_client(struct dsm_extern_client* ext_client)
{
    static int ext_client_cnt = 0;

    ext_dev[ext_client_cnt].buff_size = ext_client->buf_size;
    ext_dev[ext_client_cnt].name = ext_client->client_name;

    if (0 >= ext_dev[ext_client_cnt].buff_size || NULL == ext_dev[ext_client_cnt].name
            || ext_client_cnt >= EXTERN_DSM_CLIENT_MAX) {
        DSM_LOG_ERR("[dsm_register_extern_client]client name or buf_size is fault."
                    "don't register!\n");
        return -ENOENT;
    } else if (NULL != dsm_find_client(ext_dev[ext_client_cnt].name)) {
        DSM_LOG_ERR("[dsm_register_extern_client]register %s has exist, dont register again!\n",
                    ext_dev[ext_client_cnt].name);
        return -EEXIST;
    }

    ext_dsm_client[ext_client_cnt] = dsm_register_client(&ext_dev[ext_client_cnt]);
    if (!ext_dsm_client[ext_client_cnt]) {
        DSM_LOG_ERR("[dsm_register_extern_client]register %s failed!\n",
                    ext_dev[ext_client_cnt].name);
        return -ENOMEM;
    }

    ext_client_cnt++;
    return 0;
}
//cnotify format: |client name|,|error no|,|contents|
static ssize_t dsm_cnotify_store(struct device *dev,
                                 struct device_attribute *attr, const char *buf, size_t count)
{
    char client_name[CLIENT_NAME_LEN]= {0};
    int size;
    int error_no = 0;
    struct dsm_client *client = NULL;
    char *strings = NULL;
    char *ptr;

    DSM_LOG_DEBUG("%s enter\n",__func__);
    strings = (char *)kzalloc(count, GFP_KERNEL);
    if(!strings) {
        DSM_LOG_ERR("dsm write malloc failed\n");
        goto out;
    }

    memcpy(strings, buf, count);
    /*get client name*/
    ptr = dsm_strtok(strings, ",");
    if(ptr) {
        size = strlen(ptr);
        size = (size < CLIENT_NAME_LEN) ? size : (CLIENT_NAME_LEN - 1);
        memcpy(client_name, ptr, size);
    }
    /*get error no*/
    ptr = dsm_strtok(NULL, ",");
    if(ptr)
        error_no = dsm_atoi(ptr);
    /*get notify content*/
    ptr = dsm_strtok(NULL, NULL);

    DSM_LOG_INFO("client name - %s, error no - %d\n", client_name, error_no);
    if(ptr)
        DSM_LOG_INFO("content - %s\n", ptr);

    client = dsm_find_client(client_name);
    if(client && (!dsm_client_ocuppy(client))) {
        DSM_LOG_DEBUG("dsm write find client - %s\n", client_name);
        if(ptr)
            dsm_client_copy(client, ptr, strlen(ptr));
        dsm_client_notify(client, error_no);
    } else
        DSM_LOG_INFO("dsm notify can't find client - %s\n", client_name);

out:
    if(strings)
        kfree(strings);
    DSM_LOG_DEBUG("%s exit\n",__func__);
    return count;
}
Exemplo n.º 3
0
static ssize_t dsm_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	char client_name[CLIENT_NAME_LEN]={0};
	int size;
	struct dsm_client *client = NULL;
	char *buff = NULL;
	char *ptr;

	DSM_LOG_DEBUG("%s enter\n",__func__);
	buff = (char *)kzalloc(count, GFP_KERNEL);
	if(!buff){
		DSM_LOG_ERR("dsm write malloc failed\n");
		goto out;
	}

	if(copy_from_user(buff, buf, count)){
		DSM_LOG_ERR("dsm write copy failed\n");
		goto out;
	}

	ptr = buff;
	while(*ptr){
		if(*ptr == '\n')
			break;
		ptr++;
	}

	if(*ptr == '\n'){
		size = ptr - buff;
		size = (size < CLIENT_NAME_LEN) ? size : (CLIENT_NAME_LEN - 1);
		memcpy(client_name, buff, size);
		client = dsm_find_client(client_name);
		if(client && (!dsm_client_ocuppy(client))){
			DSM_LOG_DEBUG("dsm write find client - %s\n", client_name);
			ptr++;//ignore '/n'
			size = count - (ptr - buff);
			dsm_client_copy(client, ptr, size);
			dsm_client_notify(client, 20203);
		}else
			DSM_LOG_INFO("dsm write can't find client - %s\n", client_name);
	}else
		DSM_LOG_ERR("dsm write can't find client name\n");

out:
	if(buff)
		kfree(buff);
	DSM_LOG_DEBUG("%s exit\n",__func__);
	return count;
}
static long dsm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    void __user *argp = (void __user *)arg;
    struct dsm_client *client = (struct dsm_client *)file->private_data;
    long ret = 0;
    int error = 0;
    char buff[CLIENT_NAME_LEN]= {0};
    struct dsm_extern_client tmp_ext_client;

    DSM_LOG_DEBUG("%s enter,\n",__func__);

    switch (cmd) {
    case DSM_IOCTL_GET_CLIENT_COUNT:
        mutex_lock(&g_dsm_server.mtx_lock);
        error = g_dsm_server.client_count;
        mutex_unlock(&g_dsm_server.mtx_lock);
        DSM_LOG_INFO("client count :%d\n", error);
        ret = copy_int_to_user(argp, error);
        break;
    case DSM_IOCTL_BIND:
        if (copy_from_user(buff, argp, CLIENT_NAME_LEN)) {
            DSM_LOG_ERR("copy from user failed\n");
            ret = -EFAULT;
        } else {
            DSM_LOG_DEBUG("try bind client %s\n", buff);
            client = dsm_find_client(buff);
            if(client) {
                dsm_bind_client(client);
                file->private_data = (void *)client;
            } else {
                ret = -ENXIO;
            }
        }
        break;
    case DSM_IOCTL_POLL_CLIENT_STATE:
        if(client && client->cops && client->cops->poll_state) {
            error = client->cops->poll_state();
            DSM_LOG_INFO("poll %s state result :%d\n", client->client_name, error);
            ret = copy_int_to_user(argp, error);
        }
        else {
            DSM_LOG_ERR("dsm client not bound or poll not support\n");
            ret = -ENXIO;
        }
        break;
    case DSM_IOCTL_FORCE_DUMP:
        if (copy_from_user(buff, argp, UINT_BUF_MAX)) {
            DSM_LOG_ERR("copy from user failed\n");
            ret = -EFAULT;
        } else {
            if(client && client->cops && client->cops->dump_func) {
                if(!dsm_client_ocuppy(client)) {
                    client->error_no = dsm_atoi(buff);
                    client->used_size = client->cops->dump_func(client->error_no,
                                        (void *)client->dump_buff, (int)client->buff_size);
                    set_bit(CBUFF_READY_BIT, &client->buff_flag);
                }
                else {
                    DSM_LOG_INFO("client %s's buff ocuppy failed\n", client->client_name);
                    ret = -EBUSY;
                }
            }
            else {
                DSM_LOG_ERR("dsm client not bound or dump not support\n");
                ret = -ENXIO;
            }
        }
        break;
    case DSM_IOCTL_GET_CLIENT_ERROR:
        if(client)
            ret = copy_int_to_user(argp, client->error_no);
        else {
            DSM_LOG_ERR("dsm find client failed\n");
            ret = -ENXIO;
        }
        break;
    case DSM_IOCTL_GET_DEVICE_NAME:
        if (client && client->device_name) {
            ret = copy_to_user(argp, client->device_name, DSM_MAX_DEVICE_NAME_LEN);
        } else {
            ret = -ENXIO;
        }
        break;
    case DSM_IOCTL_GET_IC_NAME:
        if (client && client->ic_name) {
            ret = copy_to_user(argp, client->ic_name, DSM_MAX_IC_NAME_LEN);
        } else {
            ret = -ENXIO;
        }
        break;
    case DSM_IOCTL_GET_MODULE_NAME:
        if (client && client->module_name) {
            ret = copy_to_user(argp, client->module_name, DSM_MAX_MODULE_NAME_LEN);
        } else {
            ret = -ENXIO;
        }
        break;
    case DSM_IOCTL_REGISTER_EXTERN_CLIENT:
        if (copy_from_user(&tmp_ext_client, (struct dsm_extern_client *)arg,
                           sizeof(struct dsm_extern_client))) {
            ret = -EFAULT;
        } else {
            dsm_register_extern_client(&tmp_ext_client);
        }
        break;
    default:
        DSM_LOG_ERR("unknown ioctl command :%d\n", cmd);
        ret = -EINVAL;
        break;
    }

    DSM_LOG_DEBUG("%s exit\n",__func__);
    return ret;
}
static ssize_t dsm_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
    char client_name[CLIENT_NAME_LEN]= {'\0'};
    int size, error_no = 0;
    struct dsm_client *client = NULL;
    char *buff = NULL;
    char *ptr = NULL;
#ifdef CONFIG_HUAWEI_SDCARD_VOLD
    char  err_string[20] = {0};
    int   err;
#endif
    DSM_LOG_DEBUG("%s enter\n",__func__);
    buff = (char *)kzalloc(count, GFP_KERNEL);
    if(!buff) {
        DSM_LOG_ERR("dsm write malloc failed\n");
        goto out;
    }

    if(copy_from_user(buff, buf, count)) {
        DSM_LOG_ERR("dsm write copy failed\n");
        goto out;
    }

    /*get client name*/
    ptr = dsm_strtok(buff, ",");
    if(ptr) {
        size = strlen(ptr);
        size = (size < CLIENT_NAME_LEN) ? size : (CLIENT_NAME_LEN - 1);
        memcpy(client_name, ptr, size);
    }
    /*get error no*/
    ptr = dsm_strtok(NULL, ",");
    if(ptr) {
        error_no = dsm_atoi(ptr);
    }

    /*get notify content*/
    ptr = dsm_strtok(NULL, NULL);
    DSM_LOG_INFO("client name - %s, error no - %d\n", client_name, error_no);
    if(ptr) {
        DSM_LOG_INFO("content - %s\n", ptr);
    }

    client = dsm_find_client(client_name);
#ifdef CONFIG_HUAWEI_SDCARD_VOLD
    if(client && !strncasecmp("sdcard_vold",client_name,size)&&(!dsm_client_ocuppy(client)))
    {
        DSM_LOG_DEBUG("dsm write find sdcard_vold\n");
        ptr++;
        while(*ptr) {
            if(*ptr == '\n')
                break;
            ptr++;
        }

        if(*ptr == '\n')
        {

            memcpy(err_string,ptr-SDCARD_ERR_LEN,SDCARD_ERR_LEN);
            err_string[SDCARD_ERR_LEN] = '\0';
            sscanf(err_string,"%d",&err);
            dsm_client_copy(client, ptr+1, (count - (ptr+1-buff)));
            dsm_client_notify(client, err);
        }

    }
    else if(client && (!dsm_client_ocuppy(client))) {
#else
    if(client && (!dsm_client_ocuppy(client))) {
#endif
        DSM_LOG_DEBUG("dsm write find client - %s\n", client_name);
        if(ptr)
            dsm_client_copy(client, ptr, strlen(ptr));
        dsm_client_notify(client, error_no);
    } else {
        DSM_LOG_INFO("dsm notify can't find client - %s\n", client_name);
    }

out:
    if(buff)
        kfree(buff);

    DSM_LOG_DEBUG("%s exit\n",__func__);
    return count;
}

static unsigned int dsm_poll(struct file *file, poll_table *wait)
{
    struct dsm_client *client = file->private_data;
    unsigned int mask = 0;

    DSM_LOG_DEBUG("%s enter\n",__func__);
    if(!client) {
        DSM_LOG_ERR("dsm can't poll without client\n");
        goto out;
    }
    DSM_LOG_DEBUG("client name :%s\n", client->client_name);
    poll_wait(file, &client->waitq, wait);
    if(test_bit(CBUFF_READY_BIT, &client->buff_flag))
        mask = POLLIN | POLLRDNORM;

out:
    DSM_LOG_DEBUG("%s exit, mask:%d\n",__func__, mask);
    return mask;
}

static int dsm_open(struct inode *inode, struct file *file)
{
    DSM_LOG_DEBUG("%s enter\n",__func__);
    file->private_data = NULL;
    DSM_LOG_DEBUG("%s exit\n",__func__);
    return 0;
}
/* sysfs write function */
static ssize_t dsm_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
	char client_name[CLIENT_NAME_LEN]={0};
	int size;
	struct dsm_client *client = NULL;
	char *buff = NULL;
	char *ptr;
	char  err_string[20] = {0};
	int   err;
	DSM_LOG_INFO("%s enter\n",__func__);


	/* try to get control of the write buffer */
	if (down_trylock(&dsm_wbs)) {
		/* somebody else has it now;
		 * if we're non-blocking, then exit...
		 */
		if (file->f_flags & O_NONBLOCK) {
			return -EAGAIN;
		}
		/* ...or if we want to block, then do so here */
		if (down_interruptible(&dsm_wbs)) {
			/* something went wrong with wait */
			return -ERESTARTSYS;
		}
	}


	buff = (char *)kzalloc(count, GFP_KERNEL);
	if(!buff){
		DSM_LOG_ERR("dsm write malloc failed\n");
		goto out;
	}

	if(copy_from_user(buff, buf, count)){
		DSM_LOG_ERR("dsm write copy failed\n");
		goto out;
	}

	buff[count-1] = '\0';
	ptr = buff;
	while(*ptr){
		if(*ptr == '\n')
			break;
		ptr++;
	}

	/* get the client name */
	if(*ptr == '\n')
	{
		size = ptr - buff;
		size = (size < CLIENT_NAME_LEN) ? size : (CLIENT_NAME_LEN - 1);
		memcpy(client_name, buff, size);
		DSM_LOG_INFO( "%s client name is: %s \n", __func__ ,client_name );
		client = dsm_find_client(client_name);
		if( client )
		{
			/* found client name */
			DSM_LOG_DEBUG("dsm write find client - %s\n", client_name);

			ptr++;
			while(*ptr)
			{
				if(*ptr == '\n')
					break;
				ptr++;
			}

			/* get error number */
			if(*ptr == '\n')
			{
				memcpy(err_string,ptr-DSM_ERR_LEN,DSM_ERR_LEN);
				err_string[DSM_ERR_LEN] = '\0';
				sscanf(err_string,"%d",&err);
				DSM_LOG_INFO( "%s error number is: %d \n", __func__ ,err );
				/* judge if the err number is legal */
				if( (err >= DMS_ERR_NUM_MIN ) && (err < DMS_ERR_NUM_MAX) )
				{
					/* report the error */
					dsm_client_copy(client, ptr+1, (count - (ptr+1-buff)));
					dsm_client_notify(client, err);
				}
				else
				{
					DSM_LOG_ERR("dsm write err number is not legal! err:%d\n", err);
				}
			}
		}
		else
		{
			DSM_LOG_INFO("dsm write can't find client - %s\n", client_name);
		}
	}
	else
	{
		DSM_LOG_ERR("dsm write can't find client name\n");
	}

out:
	if(buff)
		kfree(buff);
	DSM_LOG_DEBUG("%s exit\n", __func__);
	/* release the write buffer and wake anyone who's waiting for it */
	up(&dsm_wbs);
	return count;
}