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, ¶ms, &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"); sms_board_setup(coredev); 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; }
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, ¶ms, &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"); rc = dvb_create_media_graph(&client->adapter, true); if (rc < 0) { pr_err("dvb_create_media_graph failed %d\n", rc); goto client_error; } 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; }