diff --git a/Kbuild b/Kbuild index 2ce2955..b4e7482 100644 --- a/Kbuild +++ b/Kbuild @@ -2,6 +2,12 @@ # Makefile for the kernel multimedia device drivers. # +ifeq ($(KERNEL_DVB_CORE),y) +obj-y := ddbridge/ \ + frontends/ + +else obj-y := dvb-core/ \ ddbridge/ \ frontends/ +endif \ No newline at end of file diff --git a/ddbridge/Kbuild b/ddbridge/Kbuild index bc9c7c5..cec6ff1 100644 --- a/ddbridge/Kbuild +++ b/ddbridge/Kbuild @@ -1,12 +1,16 @@ EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX -DCONFIG_DVB_CXD2099 -DCONFIG_DVB_NET ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o + octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o #mci-objs = ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o ddbridge-io.o obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o #mci.o + +ifneq ($(KERNEL_DVB_CORE),y) obj-$(CONFIG_DVB_OCTONET) += octonet.o +endif #EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends #EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 2fa5a74..590946a 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -95,6 +95,70 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); /****************************************************************************/ /****************************************************************************/ +/* copied from dvb-core/dvbdev.c because kernel version does not export it */ + +int ddb_dvb_usercopy(struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, + unsigned int cmd, void *arg)) +{ + char sbuf[128]; + void *mbuf = NULL; + void *parg = NULL; + int err = -EINVAL; + + /* Copy arguments into temp kernel buffer */ + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: + /* + * For this command, the pointer is actually an integer + * argument. + */ + parg = (void *) arg; + break; + case _IOC_READ: /* some v4l ioctls are marked wrong ... */ + case _IOC_WRITE: + case (_IOC_WRITE | _IOC_READ): + if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { + parg = sbuf; + } else { + /* too big to allocate from stack */ + mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); + if (NULL == mbuf) + return -ENOMEM; + parg = mbuf; + } + + err = -EFAULT; + if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) + goto out; + break; + } + + /* call driver */ + if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) + err = -ENOTTY; + + if (err < 0) + goto out; + + /* Copy results into user buffer */ + switch (_IOC_DIR(cmd)) + { + case _IOC_READ: + case (_IOC_WRITE | _IOC_READ): + if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) + err = -EFAULT; + break; + } + +out: + kfree(mbuf); + return err; +} + +/****************************************************************************/ + struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr, void (*handler)(void *), void *data) { @@ -998,7 +1062,7 @@ static struct dvb_device dvbdev_ci = { static long mod_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl); + return ddb_dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl); } static const struct file_operations mod_fops = { @@ -2971,7 +3035,7 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) static long nsd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(file, cmd, arg, nsd_do_ioctl); + return ddb_dvb_usercopy(file, cmd, arg, nsd_do_ioctl); } static const struct file_operations nsd_fops = { diff --git a/ddbridge/ddbridge-m4.c b/ddbridge/ddbridge-m4.c index 6203c6f..29a3a13 100644 --- a/ddbridge/ddbridge-m4.c +++ b/ddbridge/ddbridge-m4.c @@ -516,7 +516,7 @@ static int base_init(struct mci_base *mci_base) return 0; } -struct mci_cfg ddb_max_m4_cfg = { +static struct mci_cfg ddb_max_m4_cfg = { .type = 0, .fe_ops = &m4_ops, .base_size = sizeof(struct m4_base), @@ -524,3 +524,8 @@ struct mci_cfg ddb_max_m4_cfg = { .init = init, .base_init = base_init, }; + +struct dvb_frontend *ddb_m4_attach(struct ddb_input *input, int nr, int tuner) +{ + return ddb_mci_attach(input, &ddb_max_m4_cfg, nr, tuner); +} diff --git a/ddbridge/ddbridge-max.c b/ddbridge/ddbridge-max.c index 3cab4ff..b79a479 100644 --- a/ddbridge/ddbridge-max.c +++ b/ddbridge/ddbridge-max.c @@ -472,7 +472,8 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input) tuner = demod & 3; if (fmode >= 3) tuner = 0; - dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner); + dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, + demod, tuner, &dvb->set_input); if (!dvb->fe) { dev_err(dev->dev, "No MXL5XX found!\n"); return -ENODEV; @@ -490,13 +491,17 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input) dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd; dvb->fe->ops.diseqc_send_burst = max_send_burst; dvb->fe->sec_priv = input; - dvb->set_input = dvb->fe->ops.set_input; +#ifndef KERNEL_DVB_CORE dvb->fe->ops.set_input = max_set_input; +#endif dvb->input = tuner; return 0; } /* MAX MCI related functions */ +struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner, + int (**fn_set_input)(struct dvb_frontend *fe, int input)); +struct dvb_frontend *ddb_m4_attach(struct ddb_input *input, int nr, int tuner); int ddb_fe_attach_mci(struct ddb_input *input, u32 type) { @@ -505,25 +510,23 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type) struct ddb_port *port = input->port; struct ddb_link *link = &dev->link[port->lnr]; int demod, tuner; - struct mci_cfg cfg; int fm = fmode; demod = input->nr; tuner = demod & 3; switch (type) { case DDB_TUNER_MCI_SX8: - cfg = ddb_max_sx8_cfg; if (fm >= 3) tuner = 0; + dvb->fe = ddb_sx8_attach(input, demod, tuner, &dvb->set_input); break; case DDB_TUNER_MCI_M4: fm = 0; - cfg = ddb_max_m4_cfg; + dvb->fe = ddb_m4_attach(input, demod, tuner); break; default: return -EINVAL; } - dvb->fe = ddb_mci_attach(input, &cfg, demod, tuner); if (!dvb->fe) { dev_err(dev->dev, "No MCI card found!\n"); return -ENODEV; @@ -545,8 +548,9 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type) case DDB_TUNER_MCI_M4: break; default: - dvb->set_input = dvb->fe->ops.set_input; +#ifndef KERNEL_DVB_CORE dvb->fe->ops.set_input = max_set_input; +#endif break; } dvb->input = tuner; diff --git a/ddbridge/ddbridge-modulator.c b/ddbridge/ddbridge-modulator.c index e99064d..18fddde 100644 --- a/ddbridge/ddbridge-modulator.c +++ b/ddbridge/ddbridge-modulator.c @@ -23,8 +23,13 @@ #include "ddbridge.h" #include "ddbridge-io.h" +#include "ddbridge-ioctl.h" +#ifdef KERNEL_DVB_CORE +#include "../include/linux/dvb/mod.h" +#else #include +#endif #include /****************************************************************************/ diff --git a/ddbridge/ddbridge-sx8.c b/ddbridge/ddbridge-sx8.c index 406c31e..84f7a3d 100644 --- a/ddbridge/ddbridge-sx8.c +++ b/ddbridge/ddbridge-sx8.c @@ -23,7 +23,6 @@ #include "ddbridge.h" #include "ddbridge-io.h" -#include "ddbridge-i2c.h" #include "ddbridge-mci.h" static int default_mod = 3; @@ -556,7 +555,10 @@ static int set_input(struct dvb_frontend *fe, int input) mutex_lock(&state->lock); stop_iq(fe); stop(fe); - state->mci.tuner = p->input = input; + state->mci.tuner = input; +#ifndef KERNEL_DVB_CORE + p->input = input; +#endif mutex_unlock(&state->lock); return 0; } @@ -582,7 +584,6 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties static struct dvb_frontend_ops sx8_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, - .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ .info = { .name = "DVB-S/S2X", .frequency_min_hz = 950000000, @@ -602,7 +603,10 @@ static struct dvb_frontend_ops sx8_ops = { .tune = tune, .release = release, .read_status = read_status, +#ifndef KERNEL_DVB_CORE + .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ .set_input = set_input, +#endif .set_lna = set_lna, .sleep = sleep, }; @@ -612,8 +616,10 @@ static int init(struct mci *mci) struct sx8 *state = (struct sx8 *) mci; state->mci.demod = SX8_DEMOD_NONE; +#ifndef KERNEL_DVB_CORE mci->fe.ops.xbar[1] = mci->nr; mci->fe.dtv_property_cache.input = mci->tuner; +#endif mutex_init(&state->lock); return 0; } @@ -625,7 +631,7 @@ static int base_init(struct mci_base *mci_base) return 0; } -struct mci_cfg ddb_max_sx8_cfg = { +static struct mci_cfg ddb_max_sx8_cfg = { .type = 0, .fe_ops = &sx8_ops, .base_size = sizeof(struct sx8_base), @@ -633,3 +639,10 @@ struct mci_cfg ddb_max_sx8_cfg = { .init = init, .base_init = base_init, }; + +struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner, + int (**fn_set_input)(struct dvb_frontend *fe, int input)) +{ + *fn_set_input = set_input; + return ddb_mci_attach(input, &ddb_max_sx8_cfg, nr, tuner); +} diff --git a/ddbridge/dvb_netstream.c b/ddbridge/dvb_netstream.c index f49fc96..ee1188b 100644 --- a/ddbridge/dvb_netstream.c +++ b/ddbridge/dvb_netstream.c @@ -26,6 +26,9 @@ #include #include "dvb_netstream.h" +int ddb_dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, unsigned int cmd, void *arg)); + static ssize_t ns_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { @@ -211,7 +214,7 @@ static int do_ioctl(struct file *file, unsigned int cmd, void *parg) static long ns_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return dvb_usercopy(file, cmd, arg, do_ioctl); + return ddb_dvb_usercopy(file, cmd, arg, do_ioctl); } static const struct file_operations ns_fops = { diff --git a/dvb-core/Makefile b/dvb-core/Makefile index 28e3437..c9ff666 100644 --- a/dvb-core/Makefile +++ b/dvb-core/Makefile @@ -13,4 +13,3 @@ dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ obj-$(CONFIG_DVB_CORE) += dvb-core.o EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET -#NOSTDINC_FLAGS += -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux diff --git a/frontends/mxl5xx.c b/frontends/mxl5xx.c index ab40793..ef5e9ac 100644 --- a/frontends/mxl5xx.c +++ b/frontends/mxl5xx.c @@ -825,13 +825,15 @@ static int set_input(struct dvb_frontend *fe, int input) struct mxl *state = fe->demodulator_priv; struct dtv_frontend_properties *p = &fe->dtv_property_cache; - state->tuner = p->input = input; + state->tuner = input; +#ifndef KERNEL_DVB_CORE + p->input = input; +#endif return 0; } static struct dvb_frontend_ops mxl_ops = { .delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS }, - .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ .info = { .name = "MXL5XX", .frequency_min_hz = 300000000, @@ -856,7 +858,10 @@ static struct dvb_frontend_ops mxl_ops = { .read_signal_strength = read_signal_strength, .read_ucblocks = read_ucblocks, .get_frontend = get_frontend, +#ifndef KERNEL_DVB_CORE .set_input = set_input, + .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ +#endif .diseqc_send_master_cmd = send_master_cmd, }; @@ -1873,7 +1878,8 @@ static int probe(struct mxl *state, struct mxl5xx_cfg *cfg) struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, struct mxl5xx_cfg *cfg, - u32 demod, u32 tuner) + u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)) { struct mxl *state; struct mxl_base *base; @@ -1913,9 +1919,12 @@ struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, list_add(&base->mxllist, &mxllist); } state->fe.ops = mxl_ops; +#ifndef KERNEL_DVB_CORE state->fe.ops.xbar[1] = demod; - state->fe.demodulator_priv = state; state->fe.dtv_property_cache.input = tuner; +#endif + state->fe.demodulator_priv = state; + *fn_set_input = set_input; list_add(&state->mxl, &base->mxls); return &state->fe; diff --git a/frontends/mxl5xx.h b/frontends/mxl5xx.h index 24ac1fa..1a3f5e7 100644 --- a/frontends/mxl5xx.h +++ b/frontends/mxl5xx.h @@ -23,12 +23,15 @@ struct mxl5xx_cfg { extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, struct mxl5xx_cfg *cfg, - u32 demod, u32 tuner); + u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)); + #else static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, struct mxl5xx_cfg *cfg, - u32 demod, u32 tuner) + u32 demod, u32 tuner, + int (**fn_set_input)(struct dvb_frontend *, int)) { pr_warn("%s: driver disabled by Kconfig\n", __func__); return NULL;