Exemplo n.º 1
0
static int smsdvb_hotplug(struct smscore_device_t *coredev,
			  struct device *device, int arrival)
{
	struct smsclient_params_t params;
	struct smsdvb_client_t *client;
	int rc;

	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;
	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
	if (!client)
		return -ENOMEM;

	/* register dvb adapter */
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(
					smscore_get_board_id(coredev))->name,
				  THIS_MODULE, device, adapter_nr);
	if (rc < 0) {
		pr_err("dvb_register_adapter() failed %d\n", rc);
		goto adapter_error;
	}
	dvb_register_media_controller(&client->adapter, coredev->media_dev);

	/* init dvb demux */
	client->demux.dmx.capabilities = DMX_TS_FILTERING;
	client->demux.filternum = 32; /* todo: nova ??? */
	client->demux.feednum = 32;
	client->demux.start_feed = smsdvb_start_feed;
	client->demux.stop_feed = smsdvb_stop_feed;

	rc = dvb_dmx_init(&client->demux);
	if (rc < 0) {
		pr_err("dvb_dmx_init failed %d\n", rc);
		goto dvbdmx_error;
	}

	/* init dmxdev */
	client->dmxdev.filternum = 32;
	client->dmxdev.demux = &client->demux.dmx;
	client->dmxdev.capabilities = 0;

	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
	if (rc < 0) {
		pr_err("dvb_dmxdev_init failed %d\n", rc);
		goto dmxdev_error;
	}

	/* init and register frontend */
	memcpy(&client->frontend.ops, &smsdvb_fe_ops,
	       sizeof(struct dvb_frontend_ops));

	switch (smscore_get_device_mode(coredev)) {
	case DEVICE_MODE_DVBT:
	case DEVICE_MODE_DVBT_BDA:
		client->frontend.ops.delsys[0] = SYS_DVBT;
		break;
	case DEVICE_MODE_ISDBT:
	case DEVICE_MODE_ISDBT_BDA:
		client->frontend.ops.delsys[0] = SYS_ISDBT;
		break;
	}

	rc = dvb_register_frontend(&client->adapter, &client->frontend);
	if (rc < 0) {
		pr_err("frontend registration failed %d\n", rc);
		goto frontend_error;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DVBT_BDA_DATA;
	params.onresponse_handler = smsdvb_onresponse;
	params.onremove_handler = smsdvb_onremove;
	params.context = client;

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		pr_err("smscore_register_client() failed %d\n", rc);
		goto client_error;
	}

	client->coredev = coredev;

	init_completion(&client->tune_done);
	init_completion(&client->stats_done);

	kmutex_lock(&g_smsdvb_clientslock);

	list_add(&client->entry, &g_smsdvb_clients);

	kmutex_unlock(&g_smsdvb_clientslock);

	client->event_fe_state = -1;
	client->event_unc_state = -1;
	sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);

	sms_board_setup(coredev);

	if (smsdvb_debugfs_create(client) < 0)
		pr_info("failed to create debugfs node\n");

	dvb_create_media_graph(&client->adapter);

	pr_info("DVB interface registered.\n");
	return 0;

client_error:
	dvb_unregister_frontend(&client->frontend);

frontend_error:
	dvb_dmxdev_release(&client->dmxdev);

dmxdev_error:
	dvb_dmx_release(&client->demux);

dvbdmx_error:
	smsdvb_media_device_unregister(client);
	dvb_unregister_adapter(&client->adapter);

adapter_error:
	kfree(client);
	return rc;
}
Exemplo n.º 2
0
/*
 * s5fs_rmdir:
 * s5fs_rmdir removes the directory called name from dir. the directory
 * to be removed must be empty (except for . and .. of course).
 * param *parent: the pointer to the parent dir of the name specified
 * param *name: name string
 * param namelen: the length of the name string
 * return: 0 on success; negative numbers on a variety of errors
 */
static int
s5fs_rmdir(vnode_t *parent, const char *name, size_t namelen)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(parent != NULL);
    KASSERT(name != NULL);
    KASSERT(namelen <= NAME_LEN - 1);
    KASSERT((uint32_t)parent->vn_len == VNODE_TO_S5INODE(parent)->s5_size);
    
    kmutex_lock(&parent->vn_mutex);
    
    int inode_number = 0;
    if ((inode_number = s5_find_dirent(parent, name, namelen)) < 0)
    {
        kmutex_unlock(&parent->vn_mutex);
        /* Need vput? */
        return inode_number;
    }
    
    /* May block here */
    vnode_t* vn = vget(parent->vn_fs, inode_number);
    KASSERT(vn != NULL);
    
    if (!S_ISDIR(vn->vn_mode))
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&parent->vn_mutex);
        return -ENOTDIR;
    }
    
    /* Check empty */
    if (VNODE_TO_S5INODE(vn)->s5_size > sizeof(dirent_t)*2)
    {
        vput(vn);
        kmutex_unlock(&parent->vn_mutex);
        return -ENOTEMPTY;
    }
    
    int ret;
    if ((ret = s5_remove_dirent(parent, name, namelen)) < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&parent->vn_mutex);
        return ret;
    }
    /* Decrease the linkcount because .. is removed */
    s5_inode_t* parent_inode = VNODE_TO_S5INODE(parent);
    parent_inode->s5_linkcount--;
    s5_dirty_inode(VNODE_TO_S5FS(parent), parent_inode);
    
    /* May block here */
    vput(vn);
    kmutex_unlock(&parent->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
Exemplo n.º 3
0
/*
 * Unlocks the mutex for the whole file system
 */
static void
unlock_s5(s5fs_t *fs)
{
        kmutex_unlock(&fs->s5f_mutex);
}
Exemplo n.º 4
0
/*
 * s5fs_mknod:
 * s5fs_mknod creates a special file for the device specified by
 * 'devid' and an entry for it in 'dir' of the specified name.
 * param dir: the pointer to the 
 * param name: the name string
 * param namelen: the length of the name string
 * param mode: device mode
 * param devid: device id
 * return: 0 on success; negative number on a variety of errors
 */
static int
s5fs_mknod(vnode_t *dir, const char *name, size_t namelen, int mode, devid_t devid)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(S_ISCHR(mode) || S_ISBLK(mode));
    KASSERT(namelen <= S5_NAME_LEN-1);
    KASSERT(name != NULL);
    KASSERT(dir != NULL);
    
    
    vnode_t* vn = NULL;
    /* Must be non-exist */
    vnode_t* result = NULL;
    
    KASSERT(0 != s5fs_lookup(dir, name, namelen, &result));
    
    /* lock */
    kmutex_lock(&dir->vn_mutex);
    int ino = 0;
    if (S_ISCHR(mode))
    {
        if ((ino = s5_alloc_inode(dir->vn_fs, S5_TYPE_CHR, devid)) < 0)
        {
            /* Unsuccessfull*/
            kmutex_unlock(&dir->vn_mutex);
            return ino;
        }
    }else if (S_ISBLK(mode))
    {
        if ((ino = s5_alloc_inode(dir->vn_fs, S5_TYPE_BLK, devid)) < 0)
        {
            /* Unsuccessfull*/
            kmutex_unlock(&dir->vn_mutex);
            return ino;
        }
    }
    else
    {
        panic("Impossible to get here!");
    }
    
    /* May block here */
    vn = vget(dir->vn_fs, (ino_t)ino);
    KASSERT(vn != NULL);
    KASSERT(vn->vn_vno == (ino_t)ino);
    int ret = 0;
    if ((ret = s5_link(dir, vn, name, namelen)) < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&dir->vn_mutex);
        return ret;
    }
    /* new vnode */
    KASSERT(vn->vn_refcount == 1);
    
    /* May block here */
    vput(vn);
    kmutex_unlock(&dir->vn_mutex);
    dbg(DBG_S5FS, "}\n");
    
    return 0;
}
Exemplo n.º 5
0
/*
 * s5fs_mkdir:
 * s5fs_mkdir creates a directory called name in dir
 * param *dir: the pointer to the vnode object of the parent directory
 * param *name: the name string
 * param namelen: the length of the name
 * return: 0 on success; negative number on a variety of errors
 */
static int
s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(dir != NULL);
    KASSERT(name != NULL);
    KASSERT(namelen <= NAME_LEN-1);
    
    vnode_t* result = NULL;
    /* Must be non-exist */
    KASSERT(s5fs_lookup(dir, name, namelen, &result) < 0);
    
    /* Lock */
    kmutex_lock(&dir->vn_mutex);
    s5_inode_t* dir_inode = VNODE_TO_S5INODE(dir);
    int parent_link = dir_inode->s5_linkcount;
    int ino = 0;
    /* Allocate an inode */
    if ((ino = s5_alloc_inode(dir->vn_fs, S5_TYPE_DIR, 0)) < 0)
    {
        /* Unsuccess */
        kmutex_unlock(&dir->vn_mutex);
        return ino;
    }
    
    /* May block here */
    vnode_t* vn = vget(dir->vn_fs, ino);
    
    KASSERT(vn != NULL);
    
    int ret = 0;
    ret = s5_link(dir, vn, name, namelen);
    if (ret < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&dir->vn_mutex);
        return -1;
    }
    
    s5_inode_t* inode = VNODE_TO_S5INODE(vn);
    
    ret = s5_link(vn, vn, ".", 1);
    if (ret < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&dir->vn_mutex);
        return -1;
    }
    int a = inode->s5_direct_blocks[0];
    ret = s5_link(vn, dir, "..", 2);
    if (ret < 0)
    {
        /* May block here */
        vput(vn);
        kmutex_unlock(&dir->vn_mutex);
        return -1;
    }
    int b = inode->s5_direct_blocks[0];
    if (a != b)
    {
        KASSERT(0);
        b = a;
    }
    KASSERT(inode->s5_linkcount == 2); /* one is VFS, one is from the parent */
    /* Not clear */
    KASSERT(parent_link + 1 == dir_inode->s5_linkcount);
    
    /* May block here */
    vput(vn);
    kmutex_unlock(&dir->vn_mutex);
    KASSERT(ret == 0);
    
    dbg(DBG_S5FS, "}\n");
    
    return ret;
}
Exemplo n.º 6
0
/*
 * s5fs_read_vnode:
 * s5fs_read_vnode will be passed a vnode_t*, which will have its vn_fs
 * and vn_vno fields initialized.
 * param *vnode: the pointer to the vnode object
 */
static void
s5fs_read_vnode(vnode_t *vnode)
{
    dbg(DBG_S5FS, "{\n");
    
    KASSERT(vnode != NULL);
    KASSERT(vnode->vn_fs != NULL);
    
    kmutex_lock(&vnode->vn_mutex);
    pframe_t* page = NULL;
    
    int ret = pframe_get(S5FS_TO_VMOBJ(FS_TO_S5FS(vnode->vn_fs)),
                         S5_INODE_BLOCK(vnode->vn_vno), &page);
    
    KASSERT(ret == 0);
    KASSERT(page != NULL);
    
    pframe_pin(page);
    s5_inode_t* inode = ((s5_inode_t*)page->pf_addr) +
                        S5_INODE_OFFSET(vnode->vn_vno);
    
    inode->s5_linkcount++;
    s5_dirty_inode(VNODE_TO_S5FS(vnode), inode);
    vnode->vn_i   = inode;
    vnode->vn_len = inode->s5_size;
    
    switch(inode->s5_type)
    {
        case S5_TYPE_DIR:
        {
            vnode->vn_mode  = S_IFDIR;
            vnode->vn_ops   = &s5fs_dir_vops;
            break;
        }
        case S5_TYPE_DATA:
        {
            vnode->vn_mode  = S_IFREG;
            vnode->vn_ops   = &s5fs_file_vops;
            break;
        }
        case S5_TYPE_CHR:
        {
            vnode->vn_mode  = S_IFCHR;
            vnode->vn_ops   = NULL;
            vnode->vn_devid = (devid_t)(inode->s5_indirect_block);
            vnode->vn_cdev  = bytedev_lookup(vnode->vn_devid);
            break;
        }
        case S5_TYPE_BLK:
        {
            vnode->vn_mode  = S_IFBLK;
            vnode->vn_ops   = NULL;
            vnode->vn_devid = (devid_t)(inode->s5_indirect_block);
            vnode->vn_bdev  = blockdev_lookup(vnode->vn_devid);
            break;
        }
        default:
        {
            panic("inode %d has unknown/invalid type %d!!\n",
                  (int)vnode->vn_vno, (int)inode->s5_type);
        }
    }
    
    kmutex_unlock(&vnode->vn_mutex);
    
    dbg(DBG_S5FS, "}\n");
}
Exemplo n.º 7
0
STATIC int
fat_getdents64(fs_handle h, struct linux_dirent64 *dirp, u32 buf_size)
{
   fat_file_handle *fh = h;
   int rc;

   if (!fh->e->directory && !fh->e->volume_id)
      return -ENOTDIR;

   fat_fs_device_data *dd = fh->fs->device_data;
   fat_walk_dir_ctx walk_ctx = {0};

   getdents64_walk_ctx ctx = {
      .dirp = dirp,
      .buf_size = buf_size,
      .fh = fh,
      .offset = 0,
      .curr_file_index = 0,
      .rc = 0,
   };

   u32 cluster_to_use = 0;

   if (fh->e == dd->root_entry) {
      cluster_to_use = dd->root_cluster;
   } else {
      cluster_to_use = fat_get_first_cluster(fh->e);
   }

   rc = fat_walk_directory(&walk_ctx,
                           dd->hdr,
                           dd->type,
                           NULL,
                           cluster_to_use,
                           fat_getdents64_cb,
                           &ctx, /* arg */
                           0 /* depth level */);

   if (rc != 0)
      return rc;

   if (ctx.rc != 0)
      return (int)ctx.rc;

   return (int) ctx.offset;
}

STATIC void fat_exclusive_lock(filesystem *fs)
{
   if (!(fs->flags & VFS_FS_RW))
      return; /* read-only: no lock is needed */

   fat_fs_device_data *d = fs->device_data;
   kmutex_lock(&d->ex_mutex);
}

STATIC void fat_exclusive_unlock(filesystem *fs)
{
   if (!(fs->flags & VFS_FS_RW))
      return; /* read-only: no lock is needed */

   fat_fs_device_data *d = fs->device_data;
   kmutex_unlock(&d->ex_mutex);
}

STATIC void fat_shared_lock(filesystem *fs)
{
   if (!(fs->flags & VFS_FS_RW))
      return; /* read-only: no lock is needed */

   NOT_IMPLEMENTED();
}

STATIC void fat_shared_unlock(filesystem *fs)
{
   if (!(fs->flags & VFS_FS_RW))
      return; /* read-only: no lock is needed */

   NOT_IMPLEMENTED();
}

STATIC void fat_file_exlock(fs_handle h)
{
   // TODO: introduce a real per-file lock
   fat_exclusive_lock(get_fs(h));
}
Exemplo n.º 8
0
/*
 * See the comment in vnode.h for what is expected of this function.
 *
 * You need to create the "." and ".." directory entries in the new
 * directory. These are simply links to the new directory and its
 * parent.
 *
 * When this function returns, the inode refcount on the parent should
 * be incremented, and the inode refcount on the new directory should be
 * 1. It might make more sense for the inode refcount on the new
 * directory to be 2 (since "." refers to it as well as its entry in the
 * parent dir), but convention is that empty directories have only 1
 * link.
 *
 * You probably want to use s5_alloc_inode, and s5_link().
 *
 * Assert, a lot.
 */
static int
s5fs_mkdir(vnode_t *dir, const char *name, size_t namelen)
{
    static const char *dotstring = ".";
    static const char *dotdotstring = "..";

    KASSERT(namelen < NAME_LEN);
    KASSERT(dir->vn_ops->mkdir != NULL);

    kmutex_lock(&dir->vn_mutex);

    fs_t *fs = VNODE_TO_S5FS(dir)->s5f_fs;

    int ino = s5_alloc_inode(fs, S5_TYPE_DIR, NULL);

    if (ino < 0){
        dbg(DBG_S5FS, "unable to alloc a new inode\n");
        kmutex_unlock(&dir->vn_mutex);
        return ino;
    }

    vnode_t *child = vget(fs, ino);

    kmutex_lock(&child->vn_mutex);

    /* make sure the state of the new vnode is correct */
    assert_new_vnode_state(child, ino, S5_TYPE_DIR, 0);

    int link_res = s5_link(child, child, dotstring, 1); 

    if (link_res < 0){
        dbg(DBG_S5FS, "error creating entry for \'.\' in new directory\n");
        /* TODO make sure we should be vputting */
        /*s5_free_inode(child);*/
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&dir->vn_mutex);
        return link_res;
    }

    KASSERT(VNODE_TO_S5INODE(child)->s5_linkcount == 1);

    link_res = s5_link(child, dir, dotdotstring, 2);

    if (link_res < 0){
        dbg(DBG_S5FS, "error creating entry for \'..\' in new directory\n");
        /*s5_free_inode(child);*/
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&dir->vn_mutex);
        return link_res;
    }

    link_res = s5_link(dir, child, name, namelen);

    if (link_res < 0){
        dbg(DBG_S5FS, "error creating entry for new directory in parent dir\n");
        /*s5_free_inode(child);*/
        vput(child);
        kmutex_unlock(&child->vn_mutex);
        kmutex_unlock(&dir->vn_mutex);
        return link_res;
    }

    KASSERT(VNODE_TO_S5INODE(child)->s5_linkcount == 2);

    vput(child);

    KASSERT(child->vn_refcount - child->vn_nrespages == 0);

    kmutex_unlock(&child->vn_mutex);
    kmutex_unlock(&dir->vn_mutex);
    return 0;
}
Exemplo n.º 9
0
Arquivo: smsdvb.c Projeto: E-LLP/n900
static int smsdvb_hotplug(struct smscore_device_t *coredev,
			  struct device *device, int arrival)
{
	struct smsclient_params_t params;
	struct smsdvb_client_t *client;
	int rc;

	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	if (smscore_get_device_mode(coredev) != 4) {
		sms_err("SMS Device mode is not set for "
			"DVB operation.");
		return 0;
	}

	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	/* register dvb adapter */
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(
					smscore_get_board_id(coredev))->name,
				  THIS_MODULE, device, adapter_nr);
	if (rc < 0) {
		sms_err("dvb_register_adapter() failed %d", rc);
		goto adapter_error;
	}

	/* init dvb demux */
	client->demux.dmx.capabilities = DMX_TS_FILTERING;
	client->demux.filternum = 32; /* todo: nova ??? */
	client->demux.feednum = 32;
	client->demux.start_feed = smsdvb_start_feed;
	client->demux.stop_feed = smsdvb_stop_feed;

	rc = dvb_dmx_init(&client->demux);
	if (rc < 0) {
		sms_err("dvb_dmx_init failed %d", rc);
		goto dvbdmx_error;
	}

	/* init dmxdev */
	client->dmxdev.filternum = 32;
	client->dmxdev.demux = &client->demux.dmx;
	client->dmxdev.capabilities = 0;

	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
	if (rc < 0) {
		sms_err("dvb_dmxdev_init failed %d", rc);
		goto dmxdev_error;
	}

	/* init and register frontend */
	memcpy(&client->frontend.ops, &smsdvb_fe_ops,
	       sizeof(struct dvb_frontend_ops));

	rc = dvb_register_frontend(&client->adapter, &client->frontend);
	if (rc < 0) {
		sms_err("frontend registration failed %d", rc);
		goto frontend_error;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DVBT_BDA_DATA;
	params.onresponse_handler = smsdvb_onresponse;
	params.onremove_handler = smsdvb_onremove;
	params.context = client;

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		goto client_error;
	}

	client->coredev = coredev;

	init_completion(&client->tune_done);
	init_completion(&client->stat_done);

	kmutex_lock(&g_smsdvb_clientslock);

	list_add(&client->entry, &g_smsdvb_clients);

	kmutex_unlock(&g_smsdvb_clientslock);

	sms_info("success");

	return 0;

client_error:
	dvb_unregister_frontend(&client->frontend);

frontend_error:
	dvb_dmxdev_release(&client->dmxdev);

dmxdev_error:
	dvb_dmx_release(&client->demux);

dvbdmx_error:
	dvb_unregister_adapter(&client->adapter);

adapter_error:
	kfree(client);
	return rc;
}
Exemplo n.º 10
0
static int smsdvb_hotplug(struct smscore_device_t *coredev,
			  struct device *device, int arrival)
{
	struct smsclient_params_t params;
	struct smsdvb_client_t *client;
	int rc;
	int mode = smscore_get_device_mode(coredev);
	//mode = 6;
	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	if ( (mode != DEVICE_MODE_DVBT_BDA) &&
	     (mode != DEVICE_MODE_ISDBT_BDA) ) {
		sms_err("SMS Device mode is not set for "
			"DVB operation.");
		return 0;
	}

	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	/* register dvb adapter */
#ifdef SMS_DVB_OLD_DVB_REGISTER_ADAPTER
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(smscore_get_board_id(coredev))->
				  name, THIS_MODULE, device);
#else
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(smscore_get_board_id(coredev))->
				  name, THIS_MODULE, device, adapter_nr);
#endif
	if (rc < 0) {
		sms_err("dvb_register_adapter() failed %d", rc);
		goto adapter_error;
	}

	/* init dvb demux */
	client->demux.dmx.capabilities = DMX_TS_FILTERING;
	client->demux.filternum = 32; /* todo: nova ??? */
	client->demux.feednum = 32;
	client->demux.start_feed = smsdvb_start_feed;
	client->demux.stop_feed = smsdvb_stop_feed;

	rc = dvb_dmx_init(&client->demux);
	if (rc < 0) {
		sms_err("dvb_dmx_init failed %d", rc);
		goto dvbdmx_error;
	}

	/* init dmxdev */
	client->dmxdev.filternum = 32;
	client->dmxdev.demux = &client->demux.dmx;
	client->dmxdev.capabilities = 0;

	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
	if (rc < 0) {
		sms_err("dvb_dmxdev_init failed %d", rc);
		goto dmxdev_error;
	}
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	/* init and register frontend */
	memcpy(&client->frontend.ops, &smsdvb_fe_ops,
	       sizeof(struct dvb_frontend_ops));
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	rc = dvb_register_frontend(&client->adapter, &client->frontend);
	if (rc < 0) {
		sms_err("frontend registration failed %d", rc);
		goto frontend_error;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DVBT_BDA_DATA;
	params.onresponse_handler = smsdvb_onresponse;
	params.onremove_handler = smsdvb_onremove;
	params.context = client;
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		goto client_error;
	}

	client->coredev = coredev;

	init_completion(&client->tune_done);
	init_completion(&client->get_stats_done);

	kmutex_lock(&g_smsdvb_clientslock);

	list_add(&client->entry, &g_smsdvb_clients);

	kmutex_unlock(&g_smsdvb_clientslock);

	client->event_fe_state = -1;
	client->event_unc_state = -1;
	sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	sms_info("success");
	return 0;

client_error:
	dvb_unregister_frontend(&client->frontend);

frontend_error:
	dvb_dmxdev_release(&client->dmxdev);

dmxdev_error:
	dvb_dmx_release(&client->demux);

dvbdmx_error:
	dvb_unregister_adapter(&client->adapter);

adapter_error:
	kfree(client);
	return rc;
}