1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

Merge branch 'internal'

This commit is contained in:
internal 2023-05-11 14:25:51 +02:00
commit 2c75179530
33 changed files with 436 additions and 1197 deletions

View File

@ -1,4 +1,4 @@
TARGETS = cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig ddinfo getiq modtest TARGETS = cit ddtest setmod1 setmod2 modconfig ddinfo getiq modtest
all: $(TARGETS) all: $(TARGETS)
@ -19,32 +19,14 @@ endif
cit: cit.c cit: cit.c
$(CC) -o cit cit.c -lpthread $(CC) -o cit cit.c -lpthread
modt: modt.c
$(CC) -o modt modt.c -lpthread
setmod: setmod.c
$(CC) -o setmod setmod.c -I../include/
setmod2: setmod2.c
$(CC) -o setmod2 setmod2.c -I../include/
setmod3: setmod3.c
$(CC) -o setmod3 setmod3.c -I../include/
modconfig: modconfig.c
$(CC) -o modconfig modconfig.c -I../include/
clean:
rm cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig ddinfo getiq
%: %.c %: %.c
$(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@ $(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@
%.o: %.c %.o: %.c
$(CC) $(CFLAGS) -I../ddbridge -o $@ $< $(CC) $(CFLAGS) -I../ddbridge -o $@ $<
clean: clean:
rm test.ts -f
for f in $(TARGETS) *.o *~ ; do \ for f in $(TARGETS) *.o *~ ; do \
if [ -e "$$f" ]; then \ if [ -e "$$f" ]; then \
rm "$$f" || exit 1; \ rm "$$f" || exit 1; \

View File

@ -1,60 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
void proc_ts(int i, uint8_t *buf)
{
uint16_t pid=0x1fff&((buf[1]<<8)|buf[2]);
if (buf[3]&0xc0) /* only descrambled packets */
return;
/* only ORF */
if (pid==160 || pid==161 || pid==1001||pid==13001 || pid==0)
write(1, buf, 188);
}
#define TSBUFSIZE (100*188)
void citest()
{
uint8_t *buf;
uint8_t id;
int i, nts;
int len;
int ts=open("/dev/dvb/adapter4/ci0", O_RDONLY);
buf=(uint8_t *)malloc(TSBUFSIZE);
while(1) {
len=read(ts, buf, TSBUFSIZE);
if (len<0) {
continue;
}
if (buf[0]!=0x47) {
read(ts, buf, 1);
continue;
}
if (len%188) { /* should not happen */
printf("blah\n");
continue;
}
nts=len/188;
for (i=0; i<nts; i++)
proc_ts(i, buf+i*188);
}
}
int main()
{
citest();
}

View File

@ -1,55 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/video.h>
#define TSBUFSIZE (100*188)
void citest()
{
uint8_t *buf;
uint8_t id;
int i, nts;
int len;
int ts0=open("/dev/dvb/adapter0/dvr0", O_RDONLY);
int ts1=open("/dev/dvb/adapter4/sec0", O_WRONLY);
int demux0=open("/dev/dvb/adapter0/demux0", O_RDWR);
struct dmx_pes_filter_params pesFilterParams;
pesFilterParams.input = DMX_IN_FRONTEND;
pesFilterParams.output = DMX_OUT_TS_TAP;
pesFilterParams.pes_type = DMX_PES_OTHER;
pesFilterParams.flags = DMX_IMMEDIATE_START;
pesFilterParams.pid = 8192;
if (ioctl(demux0, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
printf("Could not set PES filter\n");
return;
}
buf=(uint8_t *)malloc(TSBUFSIZE);
while(1) {
len=read(ts0, buf, TSBUFSIZE);
if (len<=0)
break;
if (buf[0]!=0x47)
printf("oops\n");
write(ts1, buf, len);
}
}
int main()
{
citest();
}

View File

@ -1 +0,0 @@
octonet/ddflash.c

View File

@ -1,290 +0,0 @@
/*
/* flashprog - Programmer for flash on Digital Devices Octopus
*
* Copyright (C) 2010-2011 Digital Devices GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <errno.h>
#include "flash.h"
#include "flash.c"
void get_ddid(int ddb, struct ddb_id *ddbid) {
uint8_t id[4];
if (ioctl(ddb, IOCTL_DDB_ID, ddbid)>=0)
return;
memset(ddbid, 0, sizeof(*ddbid));
flashread(ddb, linknr, id, 0, 4);
printf("%02x %02x %02x %02x\n",
id[0], id[1], id[2], id[3]);
ddbid->subvendor=(id[0] << 8) | id[1];
ddbid->subdevice=(id[2] << 8) | id[3];
}
int sure()
{
char c;
printf("\n\nWARNING! Flashing a new FPGA image might make your card unusable!\n");
printf("\n\nWARNUNG! Das Flashen eines neuen FPGA-Images kann Ihre Karte unbrauchbar machen.\n");
printf("\n\nAre you sure? y/n?");
printf("\n\nSind Sie sicher? y/n?");
fflush(0);
c = getchar();
if (c!='y') {
printf("\nFlashing aborted.\n\n");
return -1;
}
printf("\nStarting to flash\n\n");
return 0;
}
int main(int argc, char **argv)
{
char ddbname[80];
char *flashname;
int type = 0;
struct ddb_id ddbid;
uint8_t *buffer;
int BufferSize = 0;
int BlockErase = 0;
uint32_t FlashOffset = 0x10000;
int ddb;
int i, err;
uint32_t SectorSize=0;
uint32_t FlashSize=0;
int Flash;
uint32_t svid=0, jump=0, dump=0;
int bin;
int ddbnum = 0;
int force = 0;
char *fname = NULL;
while (1) {
int option_index = 0;
int c;
static struct option long_options[] = {
{"svid", required_argument, NULL, 's'},
{"help", no_argument , NULL, 'h'},
{"force", no_argument , NULL, 'f'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"d:n:s:o:l:dfhjb:",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'b':
fname = optarg;
break;
case 'd':
dump = strtoul(optarg, NULL, 16);
break;
case 's':
svid = strtoul(optarg, NULL, 16);
break;
case 'o':
FlashOffset = strtoul(optarg, NULL, 16);
break;
case 'n':
ddbnum = strtol(optarg, NULL, 0);
break;
case 'l':
linknr = strtol(optarg, NULL, 0);
break;
case 'f':
force = 1;
break;
case 'j':
jump = 1;
break;
case 'h':
default:
break;
}
}
if (optind<argc) {
printf("Warning: unused arguments\n");
}
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
ddb=open(ddbname, O_RDWR);
if (ddb < 0) {
printf("Could not open device\n");
return -1;
}
Flash = flashdetect(ddb, &SectorSize, &FlashSize, &flashname);
get_ddid(ddb, &ddbid);
#if 0
printf("%04x %04x %04x %04x %08x %08x\n",
ddbid.vendor, ddbid.device,
ddbid.subvendor, ddbid.subdevice,
ddbid.hw, ddbid.regmap);
#endif
if (dump) {
flashdump(ddb, linknr, dump, 128);
return 0;
}
if (!SectorSize)
return 0;
if (jump) {
uint32_t Jump = 0x200000;
BufferSize = SectorSize;
FlashOffset = FlashSize - SectorSize;
buffer = malloc(BufferSize);
if (!buffer) {
printf("out of memory\n");
return 0;
}
memset(buffer, 0xFF, BufferSize);
memset(&buffer[BufferSize - 256 + 0x10], 0x00, 16);
buffer[BufferSize - 256 + 0x10] = 0xbd;
buffer[BufferSize - 256 + 0x11] = 0xb3;
buffer[BufferSize - 256 + 0x12] = 0xc4;
buffer[BufferSize - 256 + 0x1a] = 0xfe;
buffer[BufferSize - 256 + 0x1e] = 0x03;
buffer[BufferSize - 256 + 0x1f] = ( ( Jump >> 16 ) & 0xFF );
buffer[BufferSize - 256 + 0x20] = ( ( Jump >> 8 ) & 0xFF );
buffer[BufferSize - 256 + 0x21] = ( ( Jump ) & 0xFF );
} else if (svid) {
BufferSize = SectorSize;
FlashOffset = 0;
buffer = malloc(BufferSize);
if (!buffer) {
printf("out of memory\n");
return 0;
}
memset(buffer,0xFF,BufferSize);
buffer[0] = ((svid >> 24 ) & 0xFF);
buffer[1] = ((svid >> 16 ) & 0xFF);
buffer[2] = ((svid >> 8 ) & 0xFF);
buffer[3] = ((svid ) & 0xFF);
} else {
int fh, i;
int fsize;
char *name;
if (!fname)
fname = devid2fname(ddbid.device, &name);
if (name)
printf("Card: %s\n", name);
fh = open(fname, O_RDONLY);
if (fh < 0 ) {
printf("File %s not found \n", fname);
return 0;
}
printf("Using bitstream %s\n", fname);
fsize = lseek(fh,0,SEEK_END);
if( fsize > FlashSize/2 - 0x10000 || fsize < SectorSize )
{
close(fh);
printf("Invalid File Size \n");
return 0;
}
if( Flash == ATMEL_AT45DB642D ) {
BlockErase = fsize >= 8192;
if( BlockErase )
BufferSize = (fsize + 8191) & ~8191;
else
BufferSize = (fsize + 1023) & ~1023;
} else {
BufferSize = (fsize + SectorSize - 1 ) & ~(SectorSize - 1);
}
printf(" Size %08x, target %08x\n", BufferSize, FlashOffset);
buffer = malloc(BufferSize);
if( buffer == NULL ) {
close(fh);
printf("out of memory\n");
return 0;
}
memset(buffer, 0xFF, BufferSize);
lseek(fh, 0, SEEK_SET);
read(fh, buffer, fsize);
close(fh);
if (BufferSize >= 0x10000) {
for(i = 0; i < 0x200; i += 1 ) {
if ( *(uint16_t *) (&buffer[i]) == 0xFFFF )
break;
buffer[i] = 0xFF;
}
}
}
if (!force && sure()<0)
return 0;
switch(Flash) {
case ATMEL_AT45DB642D:
err = FlashWriteAtmel(ddb,FlashOffset,buffer,BufferSize);
break;
case SSTI_SST25VF016B:
case SSTI_SST25VF032B:
err = FlashWriteSSTI_B(ddb,FlashOffset,buffer,BufferSize);
break;
case SSTI_SST25VF064C:
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
break;
case SPANSION_S25FL116K:
case SPANSION_S25FL164K:
case WINBOND_W25Q16JV:
case WINBOND_W25Q32JV:
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
break;
}
if (err < 0)
printf("Programming Error\n");
else
printf("Programming Done\n");
free(buffer);
return 0;
}

View File

@ -310,16 +310,10 @@ struct mci_command msg_channels = {
struct mci_command msg_stream = { struct mci_command msg_stream = {
.mod_command = MOD_SETUP_STREAM, .mod_command = MOD_SETUP_STREAM,
.mod_channel = 1, .mod_channel = 0,
.mod_stream = 0, .mod_stream = 0,
.mod_setup_stream = { .mod_setup_stream = {
.standard = MOD_STANDARD_DVBC_8, .standard = MOD_STANDARD_DVBC_8,
#if 0
.ofdm = {
.fft_size = 1,
.guard_interval = 0,
}
#endif
}, },
}; };
@ -381,6 +375,7 @@ void channels_cb(void *priv, char *par, char *val)
printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency); printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency);
} else if (!strcasecmp(par, "channels")) { } else if (!strcasecmp(par, "channels")) {
mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10); mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10);
printf("channels = %u\n", mc->channels.mod_setup_channels[0].num_channels);
} else if (!strcasecmp(par, "standard")) { } else if (!strcasecmp(par, "standard")) {
if (!parse_param(val,mod_standard_table, &value)) if (!parse_param(val,mod_standard_table, &value))
mc->channels.mod_setup_channels[0].standard = value; mc->channels.mod_setup_channels[0].standard = value;
@ -434,6 +429,15 @@ void streams_cb(void *priv, char *par, char *val)
} else if (!strcasecmp(par, "stream")) { } else if (!strcasecmp(par, "stream")) {
mc->stream.mod_stream = strtol(val, NULL, 10); mc->stream.mod_stream = strtol(val, NULL, 10);
printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel); printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel);
printf("%u %u %u %u %u %u %u %u\n",
mc->stream.mod_command,
mc->stream.mod_channel,
mc->stream.mod_stream,
mc->stream.mod_setup_stream.standard,
mc->stream.mod_setup_stream.symbol_rate,
mc->stream.mod_setup_stream.stream_format,
mc->stream.mod_setup_stream.qam.modulation,
mc->stream.mod_setup_stream.qam.rolloff);
mci_cmd(mc->fd, &mc->stream); mci_cmd(mc->fd, &mc->stream);
} else } else
printf("invalid streams parameter: %s = %s\n", par, val); printf("invalid streams parameter: %s = %s\n", par, val);

View File

@ -1,36 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#define SNUM 1000
//671
void send(void)
{
uint8_t buf[188*SNUM], *cts;
int i;
uint32_t c=0;
int fdo;
fdo=open("/dev/dvb/adapter0/mod0", O_WRONLY);
while (1) {
read(0, buf, sizeof(buf));
write(fdo, buf, 188*SNUM);
}
}
int main()
{
send();
}

View File

@ -1,167 +0,0 @@
/*
* pls.c: Convert between Gold and Root Codes for DVB-S2 PLS
*
* Copyright (C) 2017 Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <stdint.h>
/* According to ETSI EN 302 307 5.5.4 the PLS (Physical Layer
Scrambling) for DVB-S2 consists of a complex randomization
sequence which is ultimately derived from two recursively
defined m-sequences (=MLS or maximum length sequences)
x(i) and y(i) of polynomials over GF(2) with m=18
(thus their length is 2^18 - 1).
These m-sequences with sequence y starting from y(0) and
sequence x starting from x(n) are combined to form a set
of 2^18 - 1 different Gold code sequences.
This starting number n of sequence x selects which
of those 2^18 - 1 Gold code sequences to use.
As a DVB-S2 tuning parameter n is called the scrambling sequence index
(cf. ETSI EN 300 468 table 41) or Gold sequence index,
commonly also just called "Gold code".
The 18 values of the sequence x starting from x(n)
(x(n) ... x(n+17)) are also called the "Root code".
So, Gold and Root codes are not different ways of PLS, they are
just different ways to select the same sequence start point.
The initial values for x(i), i=0..18 are x(0)=1, x(1)=0, .., x(17)=0 .
The polynomial used for the x sequence recursion is 1+x^7+x^18.
If the lower 18 bits of a variable "uint32_t X" contain x(n) ... x(n+17),
then we can simply calculate x(n+1) ... x(n+18) by doing:
X = (((X ^ (X >> 7)) & 1) << 17) | (X >> 1);
So, if X contained the "Root code" corresponding to "Gold code" n,
it will now contain the "Root code" corresponding to "Gold code" (n+1).
Note that X=0 and n=2^18 - 1 do not exist (or rather the lattter is the same
as n = 0) and for n=0 to 2^18 - 2 and X=1 to 2^18 - 1 there is a
one-to-one correspondence (bijection).
Note that PLS has nothing to do with encryption for DRM purposes. It is used
to minimize interference between transponders.
"Combo code":
There is no such thing as a combo code. It is the result of a bug in older
STV090x drivers which resulted in a crazy race condition between a Gold->Root
conversion in the STV and an ongoing I2C write.
Better forget about it and determine the proper Root or Gold code.
*/
static uint32_t gold2root(uint32_t gold)
{
uint32_t x, g;
for (g = 0, x = 1; g < gold; g++)
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
return x;
}
static uint32_t root2gold(uint32_t root)
{
uint32_t x, g;
for (g = 0, x = 1; g < 0x3ffff; g++) {
if (root == x)
return g;
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
}
return 0xffffffff;
}
int main(int argc, char **argv)
{
uint32_t gold = 0xffffffff, root = 0xffffffff;
while (1) {
int option_index = 0;
int c;
static struct option long_options[] = {
{"gold", required_argument, 0, 'g'},
{"root", required_argument, 0, 'r'},
{"help", no_argument , 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"r:g:h",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'g':
gold = strtoul(optarg, NULL, 0);
break;
case 'r':
root = strtoul(optarg, NULL, 0);
break;
case 'h':
printf("pls -g gold_code\n");
printf("or\n");
printf("pls -r root_code\n");
exit(-1);
default:
break;
}
}
if (optind < argc) {
printf("Warning: unused arguments\n");
}
if (gold != 0xffffffff && root != 0xffffffff) {
printf("Only specify root or gold code\n");
exit(-1);
};
if (gold != 0xffffffff) {
if (gold < 0x3ffff) {
root = gold2root(gold);
printf("gold = %u (0x%05x) root = %u (0x%05x)\n",
gold, gold, root, root);
} else
printf("Invalid gold code specified.\n");
exit(0);
}
if (root != 0xffffffff) {
if (root > 0 && root < 0x40000)
gold = root2gold(root);
if (gold != 0xffffffff)
printf("gold = %llu (0x%05x) root = %llu (0x%05x)\n",
gold, gold, root, root);
else
printf("Invalid root code specified.\n");
exit(0);
}
printf("Specify either root or gold code with -r or -g.\n");
}

View File

@ -1,33 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/dvb/mod.h>
int main()
{
int fd;
struct dvb_mod_params mp;
struct dvb_mod_channel_params mc;
fd = open("/dev/dvb/adapter1/mod0", O_RDONLY);
mp.base_frequency = 722000000;
mp.attenuator = 0;
ioctl(fd, DVB_MOD_SET, &mp);
mc.modulation = QAM_256;
mc.input_bitrate = 40000000ULL << 32;
mc.pcr_correction = 0;
ioctl(fd, DVB_MOD_CHANNEL_SET, &mc);
close(fd);
}

View File

@ -10,6 +10,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <pthread.h> #include <pthread.h>
#include <getopt.h>
#include <linux/dvb/mod.h> #include <linux/dvb/mod.h>
@ -31,17 +32,134 @@ static int set_property(int fd, uint32_t cmd, uint32_t data)
return 0; return 0;
} }
int main() static int get_property(int fd, uint32_t cmd, uint32_t *data)
{
struct dtv_property p;
struct dtv_properties c;
int ret;
p.cmd = cmd;
c.num = 1;
c.props = &p;
ret = ioctl(fd, FE_GET_PROPERTY, &c);
if (ret < 0) {
fprintf(stderr, "FE_GET_PROPERTY returned %d\n", ret);
return -1;
}
*data = p.u.data;
return 0;
}
int main(int argc, char*argv[])
{ {
int fd; int fd;
struct dvb_mod_params mp; struct dvb_mod_params mp;
struct dvb_mod_channel_params mc; struct dvb_mod_channel_params mc;
uint32_t data;
int32_t adapter = 0, channel = 0, gain = -1, att=-1, mod=-1;
int32_t base = -1, freq = -1, rate = -1, srate = -1;
char mod_name[128];
fd = open("/dev/dvb/adapter0/mod0", O_RDONLY); while (1) {
int cur_optind = optind ? optind : 1;
int option_index = 0;
int c;
static struct option long_options[] = {
{"adapter", required_argument, 0, 'a'},
{"channel", required_argument, 0, 'c'},
{"att", required_argument, 0, 't'},
{"gain", required_argument, 0, 'g'},
{"base", required_argument, 0, 'b'},
{"frequency", required_argument, 0, 'f'},
{"rate", required_argument, 0, 'r'},
{"modulation", required_argument, 0, 'm'},
{"symbolrate", required_argument, 0, 's'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"a:c:g:b:f:r:t:m:s:",
long_options, &option_index);
if (c==-1)
break;
set_property(fd, MODULATOR_MODULATION, QAM_256); switch (c) {
set_property(fd, MODULATOR_SYMBOL_RATE, 6900000); case 'a':
set_property(fd, MODULATOR_FREQUENCY, 114000000); adapter = strtoul(optarg, NULL, 0);
break;
case 'c':
channel = strtoul(optarg, NULL, 0);
break;
case 'g':
gain = strtoul(optarg, NULL, 0);
break;
case 't':
att = strtoul(optarg, NULL, 0);
break;
case 'b':
base = strtoul(optarg, NULL, 0);
break;
case 'f':
freq = strtoul(optarg, NULL, 0);
break;
case 'm':
mod = strtoul(optarg, NULL, 0);
break;
case 's':
srate = strtoul(optarg, NULL, 0);
break;
case 'r':
if (!strcmp(optarg, "DVBT_8"))
rate = SYS_DVBT_8;
else if (!strcmp(optarg, "DVBT_7"))
rate = SYS_DVBT_7;
else if (!strcmp(optarg, "DVBT_6"))
rate = SYS_DVBT_6;
else if (!strcmp(optarg, "ISDBT_6"))
rate = SYS_ISDBT_6;
else rate = strtoul(optarg, NULL, 0);
break;
default:
break;
}
}
if (optind < argc) {
printf("too many arguments\n");
exit(1);
}
snprintf(mod_name, 127, "/dev/dvb/adapter%d/mod%d", adapter, channel);
fd = open(mod_name, O_RDONLY);
if (fd < 0) {
printf("Could not open modulator device.\n");
exit(1);
}
/* gain 0-255 */
//get_property(fd, MODULATOR_GAIN, &data);
//printf("Modulator gain = %u\n", data);
//set_property(fd, MODULATOR_GAIN, 100);
//get_property(fd, MODULATOR_ATTENUATOR, &data);
//printf("Modulator attenuator = %u\n", data);
if (att >= 0)
set_property(fd, MODULATOR_ATTENUATOR, att);
if (gain >= 0)
set_property(fd, MODULATOR_GAIN, gain);
if (base > 0)
set_property(fd, MODULATOR_BASE_FREQUENCY, base);
if (freq > 0)
set_property(fd, MODULATOR_FREQUENCY, freq);
if (rate > 0)
set_property(fd, MODULATOR_OUTPUT_RATE, rate);
if (mod >= 0)
set_property(fd, MODULATOR_MODULATION, mod);
if (srate > 0)
set_property(fd, MODULATOR_SYMBOL_RATE, srate);
close(fd); close(fd);
} }

View File

@ -1,149 +0,0 @@
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <getopt.h>
#include <linux/dvb/mod.h>
static int set_property(int fd, uint32_t cmd, uint32_t data)
{
struct dtv_property p;
struct dtv_properties c;
int ret;
p.cmd = cmd;
c.num = 1;
c.props = &p;
p.u.data = data;
ret = ioctl(fd, FE_SET_PROPERTY, &c);
if (ret < 0) {
fprintf(stderr, "FE_SET_PROPERTY returned %d\n", errno);
return -1;
}
return 0;
}
static int get_property(int fd, uint32_t cmd, uint32_t *data)
{
struct dtv_property p;
struct dtv_properties c;
int ret;
p.cmd = cmd;
c.num = 1;
c.props = &p;
ret = ioctl(fd, FE_GET_PROPERTY, &c);
if (ret < 0) {
fprintf(stderr, "FE_GET_PROPERTY returned %d\n", ret);
return -1;
}
*data = p.u.data;
return 0;
}
int main(int argc, char*argv[])
{
int fd;
struct dvb_mod_params mp;
struct dvb_mod_channel_params mc;
uint32_t data;
int32_t adapter = 0, channel = 0, gain = -1;
int32_t base = -1, freq = -1, rate = -1;
char mod_name[128];
while (1) {
int cur_optind = optind ? optind : 1;
int option_index = 0;
int c;
static struct option long_options[] = {
{"adapter", required_argument, 0, 'a'},
{"channel", required_argument, 0, 'c'},
{"gain", required_argument, 0, 'g'},
{"base", required_argument, 0, 'b'},
{"frequency", required_argument, 0, 'f'},
{"rate", required_argument, 0, 'r'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"a:c:g:b:f:r:",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'a':
adapter = strtoul(optarg, NULL, 0);
break;
case 'c':
channel = strtoul(optarg, NULL, 0);
break;
case 'g':
gain = strtoul(optarg, NULL, 0);
break;
case 'b':
base = strtoul(optarg, NULL, 0);
break;
case 'f':
freq = strtoul(optarg, NULL, 0);
break;
case 'r':
if (!strcmp(optarg, "DVBT_8"))
rate = SYS_DVBT_8;
else if (!strcmp(optarg, "DVBT_7"))
rate = SYS_DVBT_7;
else if (!strcmp(optarg, "DVBT_6"))
rate = SYS_DVBT_6;
else if (!strcmp(optarg, "ISDBT_6"))
rate = SYS_ISDBT_6;
else rate = strtoul(optarg, NULL, 0);
break;
default:
break;
}
}
if (optind < argc) {
printf("too many arguments\n");
exit(1);
}
snprintf(mod_name, 127, "/dev/dvb/adapter%d/mod%d", adapter, channel);
fd = open(mod_name, O_RDONLY);
if (fd < 0) {
printf("Could not open modulator device.\n");
exit(1);
}
/* gain 0-255 */
//get_property(fd, MODULATOR_GAIN, &data);
//printf("Modulator gain = %u\n", data);
//set_property(fd, MODULATOR_GAIN, 100);
//get_property(fd, MODULATOR_ATTENUATOR, &data);
//printf("Modulator attenuator = %u\n", data);
if (gain > 0)
set_property(fd, MODULATOR_GAIN, gain);
if (base > 0)
set_property(fd, MODULATOR_BASE_FREQUENCY, base);
if (freq > 0)
set_property(fd, MODULATOR_FREQUENCY, freq);
if (rate > 0)
set_property(fd, MODULATOR_OUTPUT_RATE, rate);
close(fd);
}

View File

@ -1,105 +0,0 @@
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
#include <linux/dvb/video.h>
char line_start[16] = "";
char line_end[16] = "\r";
uint32_t cc_errors = 0;
uint32_t packets = 0;
uint32_t payload_packets = 0;
uint32_t packet_errors = 0;
uint8_t cc[8192] = { 0 };
void proc_ts(int i, uint8_t *buf)
{
uint16_t pid= 0x1fff& ((buf[1] << 8) | buf[2]);
uint8_t ccin = buf[3] & 0x1f;
if( buf[0] == 0x47 && (buf[1] & 0x80) == 0) {
if( pid != 8191 ) {
if (ccin & 0x10) {
if( cc[pid] != 0 ) {
// TODO: 1 repetition allowed
if ((((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)) ) {
cc_errors += 1;
printf("%04x: %u != %u\n", pid, (cc[pid] + 1) & 0x0F, ccin & 0x0F);
}
}
cc[pid] = ccin;
}
payload_packets += 1;
}
} else
packet_errors += 1;
if( (packets & 0x3FFF ) == 0) {
printf("%s Packets: %12u non null %12u, errors: %12u, CC errors: %12u%s",
line_start, packets, payload_packets, packet_errors, cc_errors, line_end);
fflush(stdout);
}
packets += 1;
}
#define TSBUFSIZE (100*188)
void citest(char* n)
{
uint8_t *buf;
uint8_t id;
int i, nts;
int len;
int ts=open(n, O_RDONLY);
buf=(uint8_t *)malloc(TSBUFSIZE);
while(1) {
len=read(ts, buf, TSBUFSIZE);
if (len<0) {
continue;
}
if (buf[0]!=0x47) {
read(ts, buf, 1);
continue;
}
if (len%188) { /* should not happen */
printf("blah\n");
continue;
}
nts=len/188;
for (i=0; i<nts; i++)
proc_ts(i, buf+i*188);
}
}
int main(int argc, char* argv[])
{
if( argc < 2 )
{
printf("tscheck <file>|<device> [<display line>]\n");
exit(0);
}
if( argc > 2 )
{
int line = atoi(argv[2]);
if( line >= 0 && line < 64 )
{
snprintf(line_start,sizeof(line_start)-1,"\0337\033[%d;0H",line);
strncpy(line_end,"\0338",sizeof(line_end)-1);
}
}
citest(argv[1]);
}

View File

@ -3469,7 +3469,11 @@ static const struct file_operations ddb_fops = {
#if (KERNEL_VERSION(3, 4, 0) > LINUX_VERSION_CODE) #if (KERNEL_VERSION(3, 4, 0) > LINUX_VERSION_CODE)
static char *ddb_devnode(struct device *device, mode_t *mode) static char *ddb_devnode(struct device *device, mode_t *mode)
#else #else
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
static char *ddb_devnode(struct device *device, umode_t *mode) static char *ddb_devnode(struct device *device, umode_t *mode)
#else
static char *ddb_devnode(const struct device *device, umode_t *mode)
#endif
#endif #endif
{ {
struct ddb *dev = dev_get_drvdata(device); struct ddb *dev = dev_get_drvdata(device);

View File

@ -1,19 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/* /*
* dmxdev.c - DVB demultiplexer device * dmxdev.c - DVB demultiplexer device
* *
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler * Copyright (C) 2000 Ralph Metzler & Marcus Metzler
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/ */
#define pr_fmt(fmt) "dmxdev: " fmt #define pr_fmt(fmt) "dmxdev: " fmt
@ -369,13 +359,13 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0)) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
static void dvb_dmxdev_filter_timeout(struct timer_list *t) static void dvb_dmxdev_filter_timeout(struct timer_list *t)
{ {
struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer); struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);
dmxdevfilter->buffer.error = -ETIMEDOUT; dmxdevfilter->buffer.error = -ETIMEDOUT;
spin_lock_irq(&dmxdevfilter->dev->lock); spin_lock_irq(&dmxdevfilter->dev->lock);
dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT; dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
spin_unlock_irq(&dmxdevfilter->dev->lock); spin_unlock_irq(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue); wake_up(&dmxdevfilter->buffer.queue);
} }
static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter) static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
@ -384,8 +374,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
del_timer(&dmxdevfilter->timer); del_timer(&dmxdevfilter->timer);
if (para->timeout) { if (para->timeout) {
dmxdevfilter->timer.expires = dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000; jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
add_timer(&dmxdevfilter->timer); add_timer(&dmxdevfilter->timer);
} }
} }
@ -415,6 +405,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
} }
} }
#endif #endif
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_section_filter *filter, struct dmx_section_filter *filter,
@ -475,14 +466,14 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len, const u8 *buffer2, size_t buffer2_len,
struct dmx_ts_feed *feed, struct dmx_ts_feed *feed,
u32 *buffer_flags) u32 *buffer_flags)
{ {
struct dmxdev_filter *dmxdevfilter = feed->priv; struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
#ifdef CONFIG_DVB_MMAP #ifdef CONFIG_DVB_MMAP
struct dvb_vb2_ctx *ctx; struct dvb_vb2_ctx *ctx;
#endif #endif
struct dvb_ringbuffer *buffer;
int ret; int ret;
spin_lock(&dmxdevfilter->dev->lock); spin_lock(&dmxdevfilter->dev->lock);
@ -849,6 +840,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex)) if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
for (i = 0; i < dmxdev->filternum; i++) for (i = 0; i < dmxdev->filternum; i++)
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE) if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
break; break;
@ -1485,7 +1481,7 @@ static const struct dvb_device dvbdev_dvr = {
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
{ {
int i; int i, ret;
if (dmxdev->demux->open(dmxdev->demux) < 0) if (dmxdev->demux->open(dmxdev->demux) < 0)
return -EUSERS; return -EUSERS;
@ -1508,21 +1504,36 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
DMXDEV_STATE_FREE); DMXDEV_STATE_FREE);
} }
dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
DVB_DEVICE_DEMUX, dmxdev->filternum); DVB_DEVICE_DEMUX, dmxdev->filternum);
dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, if (ret < 0)
goto err_register_dvbdev;
ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum); dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
if (ret < 0)
goto err_register_dvr_dvbdev;
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
return 0; return 0;
err_register_dvr_dvbdev:
dvb_unregister_device(dmxdev->dvbdev);
err_register_dvbdev:
vfree(dmxdev->filter);
dmxdev->filter = NULL;
return ret;
} }
EXPORT_SYMBOL(dvb_dmxdev_init); EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev) void dvb_dmxdev_release(struct dmxdev *dmxdev)
{ {
mutex_lock(&dmxdev->mutex);
dmxdev->exit = 1; dmxdev->exit = 1;
mutex_unlock(&dmxdev->mutex);
if (dmxdev->dvbdev->users > 1) { if (dmxdev->dvbdev->users > 1) {
wait_event(dmxdev->dvbdev->wait_queue, wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1); dmxdev->dvbdev->users == 1);

View File

@ -1,4 +1,4 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
/* /*
* dvb_ca.c: generic DVB functions for EN50221 CAM interfaces * dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
* *
@ -164,7 +164,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
{ {
unsigned int i; unsigned int i;
dvb_free_device(ca->dvbdev); dvb_device_put(ca->dvbdev);
for (i = 0; i < ca->slot_count; i++) for (i = 0; i < ca->slot_count; i++)
vfree(ca->slot_info[i].rx_buffer.data); vfree(ca->slot_info[i].rx_buffer.data);

View File

@ -1,20 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/* /*
* dvb_demux.c - DVB kernel demux API * dvb_demux.c - DVB kernel demux API
* *
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de> * Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de> * & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/ */
#define pr_fmt(fmt) "dvb_demux: " fmt #define pr_fmt(fmt) "dvb_demux: " fmt
@ -256,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct dmx_section_feed *sec = &feed->feed.sec; struct dmx_section_feed *sec = &feed->feed.sec;
u16 limit, seclen, n; u16 limit, seclen;
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE) if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
return 0; return 0;
@ -285,7 +275,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
/* to be sure always set secbuf */ /* to be sure always set secbuf */
sec->secbuf = sec->secbuf_base + sec->secbufp; sec->secbuf = sec->secbuf_base + sec->secbufp;
for (n = 0; sec->secbufp + 2 < limit; n++) { while (sec->secbufp + 2 < limit) {
seclen = section_length(sec->secbuf); seclen = section_length(sec->secbuf);
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|| seclen + sec->secbufp > limit) || seclen + sec->secbufp > limit)
@ -489,8 +479,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
} }
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
pid, demux->cnt_storage[pid], pid, demux->cnt_storage[pid],
buf[3] & 0xf); buf[3] & 0xf);
demux->cnt_storage[pid] = buf[3] & 0xf; demux->cnt_storage[pid] = buf[3] & 0xf;
} }
} }

View File

@ -141,7 +141,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
if (fepriv) if (fepriv)
dvb_free_device(fepriv->dvbdev); dvb_device_put(fepriv->dvbdev);
dvb_frontend_invoke_release(fe, fe->ops.release); dvb_frontend_invoke_release(fe, fe->ops.release);
@ -924,6 +924,7 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
/* If the standard is for satellite, convert frequencies to kHz */ /* If the standard is for satellite, convert frequencies to kHz */
switch (c->delivery_system) { switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS: case SYS_DVBS:
case SYS_DVBS2: case SYS_DVBS2:
case SYS_TURBO: case SYS_TURBO:
@ -949,6 +950,7 @@ static u32 dvb_frontend_get_stepsize(struct dvb_frontend *fe)
u32 step = max(fe_step, tuner_step); u32 step = max(fe_step, tuner_step);
switch (c->delivery_system) { switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS: case SYS_DVBS:
case SYS_DVBS2: case SYS_DVBS2:
case SYS_TURBO: case SYS_TURBO:
@ -980,6 +982,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
/* range check: symbol rate */ /* range check: symbol rate */
switch (c->delivery_system) { switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS: case SYS_DVBS:
case SYS_DVBS2: case SYS_DVBS2:
case SYS_TURBO: case SYS_TURBO:
@ -1047,6 +1050,10 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
c->input = NO_INPUT; c->input = NO_INPUT;
switch (c->delivery_system) { switch (c->delivery_system) {
case SYS_DSS:
c->modulation = QPSK;
c->rolloff = ROLLOFF_20;
break;
case SYS_DVBS: case SYS_DVBS:
case SYS_DVBS2: case SYS_DVBS2:
case SYS_TURBO: case SYS_TURBO:
@ -1839,6 +1846,7 @@ static void prepare_tuning_algo_parameters(struct dvb_frontend *fe)
} else { } else {
/* default values */ /* default values */
switch (c->delivery_system) { switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS: case SYS_DVBS:
case SYS_DVBS2: case SYS_DVBS2:
case SYS_ISDBS: case SYS_ISDBS:
@ -2312,6 +2320,9 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_DVBC_ANNEX_C: case SYS_DVBC_ANNEX_C:
rolloff = 113; rolloff = 113;
break; break;
case SYS_DSS:
rolloff = 120;
break;
case SYS_DVBS: case SYS_DVBS:
case SYS_TURBO: case SYS_TURBO:
case SYS_ISDBS: case SYS_ISDBS:
@ -2582,8 +2593,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_DISEQC_SEND_BURST: case FE_DISEQC_SEND_BURST:
if (fe->ops.diseqc_send_burst) { if (fe->ops.diseqc_send_burst) {
err = fe->ops.diseqc_send_burst(fe, err = fe->ops.diseqc_send_burst(fe, (long)parg);
(enum fe_sec_mini_cmd)parg);
fepriv->state = FESTATE_DISEQC; fepriv->state = FESTATE_DISEQC;
fepriv->status = 0; fepriv->status = 0;
} }
@ -2591,9 +2601,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_TONE: case FE_SET_TONE:
if (fe->ops.set_tone) { if (fe->ops.set_tone) {
err = fe->ops.set_tone(fe, fepriv->tone = (long)parg;
(enum fe_sec_tone_mode)parg); err = fe->ops.set_tone(fe, fepriv->tone);
fepriv->tone = (enum fe_sec_tone_mode)parg;
fepriv->state = FESTATE_DISEQC; fepriv->state = FESTATE_DISEQC;
fepriv->status = 0; fepriv->status = 0;
} }
@ -2601,9 +2610,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_VOLTAGE: case FE_SET_VOLTAGE:
if (fe->ops.set_voltage) { if (fe->ops.set_voltage) {
err = fe->ops.set_voltage(fe, fepriv->voltage = (long)parg;
(enum fe_sec_voltage)parg); err = fe->ops.set_voltage(fe, fepriv->voltage);
fepriv->voltage = (enum fe_sec_voltage)parg;
fepriv->state = FESTATE_DISEQC; fepriv->state = FESTATE_DISEQC;
fepriv->status = 0; fepriv->status = 0;
} }
@ -2767,7 +2775,6 @@ typedef unsigned int __poll_t;
#define EPOLLOUT POLLOUT #define EPOLLOUT POLLOUT
#endif #endif
static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait) static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
{ {
struct dvb_device *dvbdev = file->private_data; struct dvb_device *dvbdev = file->private_data;
@ -2796,7 +2803,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (fe->exit == DVB_FE_DEVICE_REMOVED) if (fe->exit == DVB_FE_DEVICE_REMOVED)
return -ENODEV; return -ENODEV;
if (adapter->mfe_shared) { if (adapter->mfe_shared == 2) {
mutex_lock(&adapter->mfe_lock);
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
if (adapter->mfe_dvbdev &&
!adapter->mfe_dvbdev->writers) {
mutex_unlock(&adapter->mfe_lock);
return -EBUSY;
}
adapter->mfe_dvbdev = dvbdev;
}
} else if (adapter->mfe_shared) {
mutex_lock(&adapter->mfe_lock); mutex_lock(&adapter->mfe_lock);
if (!adapter->mfe_dvbdev) if (!adapter->mfe_dvbdev)
@ -2974,7 +2991,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
else if (fe->ops.tuner_ops.sleep) else if (fe->ops.tuner_ops.sleep)
ret = fe->ops.tuner_ops.sleep(fe); ret = fe->ops.tuner_ops.sleep(fe);
if (fe->ops.sleep) if (fe->ops.suspend)
ret = fe->ops.suspend(fe);
else if (fe->ops.sleep)
ret = fe->ops.sleep(fe); ret = fe->ops.sleep(fe);
return ret; return ret;
@ -2990,7 +3009,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
fe->id); fe->id);
fe->exit = DVB_FE_DEVICE_RESUME; fe->exit = DVB_FE_DEVICE_RESUME;
if (fe->ops.init) if (fe->ops.resume)
ret = fe->ops.resume(fe);
else if (fe->ops.init)
ret = fe->ops.init(fe); ret = fe->ops.init(fe);
if (fe->ops.tuner_ops.resume) if (fe->ops.tuner_ops.resume)
@ -3024,6 +3045,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
.name = fe->ops.info.name, .name = fe->ops.info.name,
#endif #endif
}; };
int ret;
dev_dbg(dvb->device, "%s:\n", __func__); dev_dbg(dvb->device, "%s:\n", __func__);
@ -3053,8 +3075,14 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
fe->dvb = dvb; fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF; fepriv->inversion = INVERSION_OFF;
dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template, ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
fe, DVB_DEVICE_FRONTEND, 0); fe, DVB_DEVICE_FRONTEND, 0);
if (ret) {
dvb_frontend_put(fe);
mutex_unlock(&frontend_mutex);
return ret;
}
dev_info(fe->dvb->device, dev_info(fe->dvb->device,
"DVB: registering adapter %i frontend %i (%s)...\n", "DVB: registering adapter %i frontend %i (%s)...\n",

View File

@ -60,6 +60,9 @@
#include <media/dvb_demux.h> #include <media/dvb_demux.h>
#include <media/dvb_net.h> #include <media/dvb_net.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
#include <linux/nospec.h>
#endif
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
{ {
@ -662,7 +665,7 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
h->ts_remain > 2 ? h->ts_remain > 2 ?
*(unsigned short *)h->from_where : 0); *(unsigned short *)h->from_where : 0);
#ifdef DVB_ULE_DEBUG #ifdef DVB_ULE_DEBUG
hexdump(iov[0].iov_base, iov[0].iov_len); hexdump(iov[0].iov_base, iov[0].iov_len);
hexdump(iov[1].iov_base, iov[1].iov_len); hexdump(iov[1].iov_base, iov[1].iov_len);
hexdump(iov[2].iov_base, iov[2].iov_len); hexdump(iov[2].iov_base, iov[2].iov_len);
@ -678,7 +681,7 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
hexdump(ule_where - TS_SZ, TS_SZ); hexdump(ule_where - TS_SZ, TS_SZ);
} }
ule_dump = 1; ule_dump = 1;
#endif #endif
h->dev->stats.rx_errors++; h->dev->stats.rx_errors++;
h->dev->stats.rx_crc_errors++; h->dev->stats.rx_crc_errors++;
@ -1062,7 +1065,7 @@ static int dvb_net_feed_start(struct net_device *dev)
int ret = 0, i; int ret = 0, i;
struct dvb_net_priv *priv = netdev_priv(dev); struct dvb_net_priv *priv = netdev_priv(dev);
struct dmx_demux *demux = priv->demux; struct dmx_demux *demux = priv->demux;
const unsigned char *mac = (unsigned char *) dev->dev_addr; const unsigned char *mac = (const unsigned char *) dev->dev_addr;
netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode); netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
@ -1483,14 +1486,21 @@ static int dvb_net_do_ioctl(struct file *file,
struct net_device *netdev; struct net_device *netdev;
struct dvb_net_priv *priv_data; struct dvb_net_priv *priv_data;
struct dvb_net_if *dvbnetif = parg; struct dvb_net_if *dvbnetif = parg;
int if_num = dvbnetif->if_num;
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || if (if_num >= DVB_NET_DEVICES_MAX) {
!dvbnet->state[dvbnetif->if_num]) { ret = -EINVAL;
goto ioctl_error;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
#endif
if (!dvbnet->state[if_num]) {
ret = -EINVAL; ret = -EINVAL;
goto ioctl_error; goto ioctl_error;
} }
netdev = dvbnet->device[dvbnetif->if_num]; netdev = dvbnet->device[if_num];
priv_data = netdev_priv(netdev); priv_data = netdev_priv(netdev);
dvbnetif->pid=priv_data->pid; dvbnetif->pid=priv_data->pid;
@ -1543,14 +1553,21 @@ static int dvb_net_do_ioctl(struct file *file,
struct net_device *netdev; struct net_device *netdev;
struct dvb_net_priv *priv_data; struct dvb_net_priv *priv_data;
struct __dvb_net_if_old *dvbnetif = parg; struct __dvb_net_if_old *dvbnetif = parg;
int if_num = dvbnetif->if_num;
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || if (if_num >= DVB_NET_DEVICES_MAX) {
!dvbnet->state[dvbnetif->if_num]) { ret = -EINVAL;
goto ioctl_error;
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
#endif
if (!dvbnet->state[if_num]) {
ret = -EINVAL; ret = -EINVAL;
goto ioctl_error; goto ioctl_error;
} }
netdev = dvbnet->device[dvbnetif->if_num]; netdev = dvbnet->device[if_num];
priv_data = netdev_priv(netdev); priv_data = netdev_priv(netdev);
dvbnetif->pid=priv_data->pid; dvbnetif->pid=priv_data->pid;

View File

@ -63,7 +63,7 @@ int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
* this pairs with smp_store_release() in dvb_ringbuffer_write(), * this pairs with smp_store_release() in dvb_ringbuffer_write(),
* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset() * dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
* *
* for memory barriers also see Documentation/core-api/circular-buffers.txt * for memory barriers also see Documentation/core-api/circular-buffers.rst
*/ */
return (rbuf->pread == smp_load_acquire(&rbuf->pwrite)); return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
#endif #endif
@ -75,7 +75,7 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
{ {
ssize_t free; ssize_t free;
/* ACCESS_ONCE() to load read pointer on writer side /* READ_ONCE() to load read pointer on writer side
* this pairs with smp_store_release() in dvb_ringbuffer_read(), * this pairs with smp_store_release() in dvb_ringbuffer_read(),
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(), * dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
* or dvb_ringbuffer_reset() * or dvb_ringbuffer_reset()
@ -171,7 +171,7 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
#else #else
/* smp_store_release() for read pointer update to ensure /* smp_store_release() for read pointer update to ensure
* that buf is not overwritten until read is complete, * that buf is not overwritten until read is complete,
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free() * this pairs with READ_ONCE() in dvb_ringbuffer_free()
*/ */
smp_store_release(&rbuf->pread, 0); smp_store_release(&rbuf->pread, 0);
#endif #endif
@ -203,7 +203,7 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
#else #else
/* smp_store_release() for read pointer update to ensure /* smp_store_release() for read pointer update to ensure
* that buf is not overwritten until read is complete, * that buf is not overwritten until read is complete,
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free() * this pairs with READ_ONCE() in dvb_ringbuffer_free()
*/ */
smp_store_release(&rbuf->pread, 0); smp_store_release(&rbuf->pread, 0);
#endif #endif
@ -391,7 +391,7 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t*
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
} }
consumed = idx - rbuf->pread; consumed = (idx - rbuf->pread);
if (consumed < 0) if (consumed < 0)
consumed += rbuf->size; consumed += rbuf->size;

View File

@ -5,10 +5,6 @@
* Copyright (C) 2015 Samsung Electronics * Copyright (C) 2015 Samsung Electronics
* *
* Author: jh1009.sung@samsung.com * Author: jh1009.sung@samsung.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*/ */
#include <linux/err.h> #include <linux/err.h>
@ -358,6 +354,12 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{ {
struct vb2_queue *q = &ctx->vb_q;
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
return -EINVAL;
}
vb2_core_querybuf(&ctx->vb_q, b->index, b); vb2_core_querybuf(&ctx->vb_q, b->index, b);
dprintk(3, "[%s] index=%d\n", ctx->name, b->index); dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
return 0; return 0;
@ -382,8 +384,13 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{ {
struct vb2_queue *q = &ctx->vb_q;
int ret; int ret;
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
return -EINVAL;
}
ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL); ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
if (ret) { if (ret) {
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name, dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,

View File

@ -1,20 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/* /*
* dvbdev.c * dvbdev.c
* *
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de> * & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/ */
#define pr_fmt(fmt) "dvbdev: " fmt #define pr_fmt(fmt) "dvbdev: " fmt
@ -118,7 +108,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
new_fops = fops_get(dvbdev->fops); new_fops = fops_get(dvbdev->fops);
if (!new_fops) if (!new_fops)
goto fail; goto fail;
file->private_data = dvbdev; file->private_data = dvb_device_get(dvbdev);
replace_fops(file, new_fops); replace_fops(file, new_fops);
if (file->f_op->open) if (file->f_op->open)
err = file->f_op->open(inode, file); err = file->f_op->open(inode, file);
@ -182,6 +172,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
} }
dvbdev->users++; dvbdev->users++;
dvb_device_put(dvbdev);
return 0; return 0;
} }
EXPORT_SYMBOL(dvb_generic_release); EXPORT_SYMBOL(dvb_generic_release);
@ -264,7 +257,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
static int dvb_create_tsout_entity(struct dvb_device *dvbdev, static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
const char *name, int npads) const char *name, int npads)
{ {
int i, ret = 0; int i;
dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
GFP_KERNEL); GFP_KERNEL);
@ -281,6 +274,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
for (i = 0; i < npads; i++) { for (i = 0; i < npads; i++) {
struct media_pad *pads = &dvbdev->tsout_pads[i]; struct media_pad *pads = &dvbdev->tsout_pads[i];
struct media_entity *entity = &dvbdev->tsout_entity[i]; struct media_entity *entity = &dvbdev->tsout_entity[i];
int ret;
entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i); entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
if (!entity->name) if (!entity->name)
@ -353,6 +347,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
GFP_KERNEL); GFP_KERNEL);
if (!dvbdev->pads) { if (!dvbdev->pads) {
kfree(dvbdev->entity); kfree(dvbdev->entity);
dvbdev->entity = NULL;
return -ENOMEM; return -ENOMEM;
} }
} }
@ -499,6 +494,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
} }
memcpy(dvbdev, template, sizeof(struct dvb_device)); memcpy(dvbdev, template, sizeof(struct dvb_device));
kref_init(&dvbdev->ref);
dvbdev->type = type; dvbdev->type = type;
dvbdev->id = id; dvbdev->id = id;
dvbdev->adapter = adap; dvbdev->adapter = adap;
@ -529,7 +525,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
#endif #endif
dvbdev->minor = minor; dvbdev->minor = minor;
dvb_minors[minor] = dvbdev; dvb_minors[minor] = dvb_device_get(dvbdev);
up_write(&minor_rwsem); up_write(&minor_rwsem);
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
@ -574,6 +570,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
down_write(&minor_rwsem); down_write(&minor_rwsem);
dvb_minors[dvbdev->minor] = NULL; dvb_minors[dvbdev->minor] = NULL;
dvb_device_put(dvbdev);
up_write(&minor_rwsem); up_write(&minor_rwsem);
dvb_media_device_free(dvbdev); dvb_media_device_free(dvbdev);
@ -585,21 +582,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
EXPORT_SYMBOL(dvb_remove_device); EXPORT_SYMBOL(dvb_remove_device);
void dvb_free_device(struct dvb_device *dvbdev) static void dvb_free_device(struct kref *ref)
{ {
if (!dvbdev) struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
return;
kfree (dvbdev->fops); kfree (dvbdev->fops);
kfree (dvbdev); kfree (dvbdev);
} }
EXPORT_SYMBOL(dvb_free_device);
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
{
kref_get(&dvbdev->ref);
return dvbdev;
}
EXPORT_SYMBOL(dvb_device_get);
void dvb_device_put(struct dvb_device *dvbdev)
{
if (dvbdev)
kref_put(&dvbdev->ref, dvb_free_device);
}
void dvb_unregister_device(struct dvb_device *dvbdev) void dvb_unregister_device(struct dvb_device *dvbdev)
{ {
dvb_remove_device(dvbdev); dvb_remove_device(dvbdev);
dvb_free_device(dvbdev); dvb_device_put(dvbdev);
} }
EXPORT_SYMBOL(dvb_unregister_device); EXPORT_SYMBOL(dvb_unregister_device);
@ -1041,9 +1051,13 @@ EXPORT_SYMBOL_GPL(dvb_module_release);
#endif #endif
#endif #endif
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
#else
static int dvb_uevent(const struct device *dev, struct kobj_uevent_env *env)
#endif
{ {
struct dvb_device *dvbdev = dev_get_drvdata(dev); const struct dvb_device *dvbdev = dev_get_drvdata(dev);
add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
@ -1051,9 +1065,13 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0; return 0;
} }
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
static char *dvb_devnode(struct device *dev, umode_t *mode) static char *dvb_devnode(struct device *dev, umode_t *mode)
#else
static char *dvb_devnode(const struct device *dev, umode_t *mode)
#endif
{ {
struct dvb_device *dvbdev = dev_get_drvdata(dev); const struct dvb_device *dvbdev = dev_get_drvdata(dev);
return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d", return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);

View File

@ -7,21 +7,6 @@
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de> * & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBAUDIO_H_ #ifndef _DVBAUDIO_H_
@ -54,7 +39,7 @@ typedef enum {
typedef struct audio_mixer { typedef struct audio_mixer {
unsigned int volume_left; unsigned int volume_left;
unsigned int volume_right; unsigned int volume_right;
/* what else do we need? bass, pass-through, ... */ /* what else do we need? bass, pass-through, ... */
} audio_mixer_t; } audio_mixer_t;

View File

@ -5,21 +5,6 @@
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de> * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de> * & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBCA_H_ #ifndef _DVBCA_H_
@ -132,11 +117,6 @@ struct ca_descr {
unsigned char cw[8]; unsigned char cw[8];
}; };
struct ca_pid {
unsigned int pid;
int index;/* -1 == disable*/
};
#define CA_RESET _IO('o', 128) #define CA_RESET _IO('o', 128)
#define CA_GET_CAP _IOR('o', 129, struct ca_caps) #define CA_GET_CAP _IOR('o', 129, struct ca_caps)
#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info) #define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info)
@ -144,7 +124,6 @@ struct ca_pid {
#define CA_GET_MSG _IOR('o', 132, struct ca_msg) #define CA_GET_MSG _IOR('o', 132, struct ca_msg)
#define CA_SEND_MSG _IOW('o', 133, struct ca_msg) #define CA_SEND_MSG _IOW('o', 133, struct ca_msg)
#define CA_SET_DESCR _IOW('o', 134, struct ca_descr) #define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
#define CA_SET_PID _IOW('o', 135, struct ca_pid)
#if !defined(__KERNEL__) #if !defined(__KERNEL__)
@ -154,7 +133,6 @@ typedef struct ca_descr_info ca_descr_info_t;
typedef struct ca_caps ca_caps_t; typedef struct ca_caps ca_caps_t;
typedef struct ca_msg ca_msg_t; typedef struct ca_msg ca_msg_t;
typedef struct ca_descr ca_descr_t; typedef struct ca_descr ca_descr_t;
typedef struct ca_pid ca_pid_t;
#endif #endif

View File

@ -5,21 +5,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de> * & Ralph Metzler <ralph@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _UAPI_DVBDMX_H_ #ifndef _UAPI_DVBDMX_H_

View File

@ -7,21 +7,6 @@
* Holger Waechtler <holger@convergence.de> * Holger Waechtler <holger@convergence.de>
* Andre Draszik <ad@convergence.de> * Andre Draszik <ad@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBFRONTEND_H_ #ifndef _DVBFRONTEND_H_
@ -282,7 +267,6 @@ enum fe_spectral_inversion {
/** /**
* enum fe_code_rate - Type of Forward Error Correction (FEC) * enum fe_code_rate - Type of Forward Error Correction (FEC)
* *
*
* @FEC_NONE: No Forward Error Correction Code * @FEC_NONE: No Forward Error Correction Code
* @FEC_1_2: Forward Error Correction Code 1/2 * @FEC_1_2: Forward Error Correction Code 1/2
* @FEC_2_3: Forward Error Correction Code 2/3 * @FEC_2_3: Forward Error Correction Code 2/3
@ -296,7 +280,28 @@ enum fe_spectral_inversion {
* @FEC_3_5: Forward Error Correction Code 3/5 * @FEC_3_5: Forward Error Correction Code 3/5
* @FEC_9_10: Forward Error Correction Code 9/10 * @FEC_9_10: Forward Error Correction Code 9/10
* @FEC_2_5: Forward Error Correction Code 2/5 * @FEC_2_5: Forward Error Correction Code 2/5
* * @FEC_1_3: Forward Error Correction Code 1/3
* @FEC_1_4: Forward Error Correction Code 1/4
* @FEC_5_9: Forward Error Correction Code 5/9
* @FEC_7_9: Forward Error Correction Code 7/9
* @FEC_8_15: Forward Error Correction Code 8/15
* @FEC_11_15: Forward Error Correction Code 11/15
* @FEC_13_18: Forward Error Correction Code 13/18
* @FEC_9_20: Forward Error Correction Code 9/20
* @FEC_11_20: Forward Error Correction Code 11/20
* @FEC_23_36: Forward Error Correction Code 23/36
* @FEC_25_36: Forward Error Correction Code 25/36
* @FEC_13_45: Forward Error Correction Code 13/45
* @FEC_26_45: Forward Error Correction Code 26/45
* @FEC_28_45: Forward Error Correction Code 28/45
* @FEC_32_45: Forward Error Correction Code 32/45
* @FEC_77_90: Forward Error Correction Code 77/90
* @FEC_11_45: Forward Error Correction Code 11/45
* @FEC_4_15: Forward Error Correction Code 4/15
* @FEC_14_45: Forward Error Correction Code 14/45
* @FEC_7_15: Forward Error Correction Code 7/15
* @FEC_29_45: Forward Error Correction Code 29/45
* @FEC_31_45: Forward Error Correction Code 31/45
* Please note that not all FEC types are supported by a given standard. * Please note that not all FEC types are supported by a given standard.
*/ */
enum fe_code_rate { enum fe_code_rate {
@ -313,8 +318,28 @@ enum fe_code_rate {
FEC_3_5, FEC_3_5,
FEC_9_10, FEC_9_10,
FEC_2_5, FEC_2_5,
FEC_1_4,
FEC_1_3, FEC_1_3,
FEC_1_4,
FEC_5_9,
FEC_7_9,
FEC_8_15,
FEC_11_15,
FEC_13_18,
FEC_9_20,
FEC_11_20,
FEC_23_36,
FEC_25_36,
FEC_13_45,
FEC_26_45,
FEC_28_45,
FEC_32_45,
FEC_77_90,
FEC_11_45,
FEC_4_15,
FEC_14_45,
FEC_7_15,
FEC_29_45,
FEC_31_45,
}; };
/** /**
@ -333,6 +358,16 @@ enum fe_code_rate {
* @APSK_32: 32-APSK modulation * @APSK_32: 32-APSK modulation
* @DQPSK: DQPSK modulation * @DQPSK: DQPSK modulation
* @QAM_4_NR: 4-QAM-NR modulation * @QAM_4_NR: 4-QAM-NR modulation
* @QAM_1024: 1024-QAM modulation
* @QAM_4096: 4096-QAM modulation
* @APSK_8_L: 8APSK-L modulation
* @APSK_16_L: 16APSK-L modulation
* @APSK_32_L: 32APSK-L modulation
* @APSK_64: 64APSK modulation
* @APSK_64_L: 64APSK-L modulation
* @APSK_128: 128APSK modulation
* @APSK_256: 256APSK modulation
* @APSK_256_L: 256APSK-L modulation
* *
* Please note that not all modulations are supported by a given standard. * Please note that not all modulations are supported by a given standard.
* *
@ -352,9 +387,16 @@ enum fe_modulation {
APSK_32, APSK_32,
DQPSK, DQPSK,
QAM_4_NR, QAM_4_NR,
QAM_1024,
QAM_4096,
APSK_8_L,
APSK_16_L,
APSK_32_L,
APSK_64, APSK_64,
APSK_64_L,
APSK_128, APSK_128,
APSK_256, APSK_256,
APSK_256_L,
}; };
/** /**
@ -409,6 +451,7 @@ enum fe_transmit_mode {
* @GUARD_INTERVAL_PN420: PN length 420 (1/4) * @GUARD_INTERVAL_PN420: PN length 420 (1/4)
* @GUARD_INTERVAL_PN595: PN length 595 (1/6) * @GUARD_INTERVAL_PN595: PN length 595 (1/6)
* @GUARD_INTERVAL_PN945: PN length 945 (1/9) * @GUARD_INTERVAL_PN945: PN length 945 (1/9)
* @GUARD_INTERVAL_1_64: Guard interval 1/64
* *
* Please note that not all guard intervals are supported by a given standard. * Please note that not all guard intervals are supported by a given standard.
*/ */
@ -424,6 +467,7 @@ enum fe_guard_interval {
GUARD_INTERVAL_PN420, GUARD_INTERVAL_PN420,
GUARD_INTERVAL_PN595, GUARD_INTERVAL_PN595,
GUARD_INTERVAL_PN945, GUARD_INTERVAL_PN945,
GUARD_INTERVAL_1_64,
}; };
/** /**
@ -577,6 +621,9 @@ enum fe_pilot {
* @ROLLOFF_20: Roloff factor: α=20% * @ROLLOFF_20: Roloff factor: α=20%
* @ROLLOFF_25: Roloff factor: α=25% * @ROLLOFF_25: Roloff factor: α=25%
* @ROLLOFF_AUTO: Auto-detect the roloff factor. * @ROLLOFF_AUTO: Auto-detect the roloff factor.
* @ROLLOFF_15: Rolloff factor: α=15%
* @ROLLOFF_10: Rolloff factor: α=10%
* @ROLLOFF_5: Rolloff factor: α=5%
* *
* .. note: * .. note:
* *
@ -603,6 +650,8 @@ enum fe_rolloff {
* Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM) * Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM)
* @SYS_DVBC_ANNEX_C: * @SYS_DVBC_ANNEX_C:
* Cable TV: DVB-C following ITU-T J.83 Annex C spec * Cable TV: DVB-C following ITU-T J.83 Annex C spec
* @SYS_DVBC2:
* Cable TV: DVB-C2
* @SYS_ISDBC: * @SYS_ISDBC:
* Cable TV: ISDB-C (no drivers yet) * Cable TV: ISDB-C (no drivers yet)
* @SYS_DVBT: * @SYS_DVBT:
@ -620,7 +669,7 @@ enum fe_rolloff {
* @SYS_DVBS: * @SYS_DVBS:
* Satellite TV: DVB-S * Satellite TV: DVB-S
* @SYS_DVBS2: * @SYS_DVBS2:
* Satellite TV: DVB-S2 * Satellite TV: DVB-S2 and DVB-S2X
* @SYS_TURBO: * @SYS_TURBO:
* Satellite TV: DVB-S Turbo * Satellite TV: DVB-S Turbo
* @SYS_ISDBS: * @SYS_ISDBS:
@ -730,7 +779,7 @@ enum atscmh_rs_frame_mode {
}; };
/** /**
* enum atscmh_rs_code_mode * enum atscmh_rs_code_mode - ATSC-M/H Reed Solomon modes
* @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187). * @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187).
* @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187). * @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187).
* @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187). * @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187).
@ -771,8 +820,8 @@ enum fecap_scale_params {
* struct dtv_stats - Used for reading a DTV status property * struct dtv_stats - Used for reading a DTV status property
* *
* @scale: * @scale:
* Filled with enum fecap_scale_params - the scale in usage * Filled with enum fecap_scale_params - the scale in usage
* for that parameter * for that parameter
* *
* @svalue: * @svalue:
* integer value of the measure, for %FE_SCALE_DECIBEL, * integer value of the measure, for %FE_SCALE_DECIBEL,
@ -841,18 +890,18 @@ struct dtv_fe_stats {
/** /**
* struct dtv_property - store one of frontend command and its value * struct dtv_property - store one of frontend command and its value
* *
* @cmd: Digital TV command. * @cmd: Digital TV command.
* @reserved: Not used. * @reserved: Not used.
* @u: Union with the values for the command. * @u: Union with the values for the command.
* @u.data: A unsigned 32 bits integer with command value. * @u.data: A unsigned 32 bits integer with command value.
* @u.buffer: Struct to store bigger properties. * @u.buffer: Struct to store bigger properties.
* Currently unused. * Currently unused.
* @u.buffer.data: an unsigned 32-bits array. * @u.buffer.data: an unsigned 32-bits array.
* @u.buffer.len: number of elements of the buffer. * @u.buffer.len: number of elements of the buffer.
* @u.buffer.reserved1: Reserved. * @u.buffer.reserved1: Reserved.
* @u.buffer.reserved2: Reserved. * @u.buffer.reserved2: Reserved.
* @u.st: a &struct dtv_fe_stats array of statistics. * @u.st: a &struct dtv_fe_stats array of statistics.
* @result: Currently unused. * @result: Currently unused.
* *
*/ */
struct dtv_property { struct dtv_property {

View File

@ -5,21 +5,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de> * & Ralph Metzler <ralph@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBNET_H_ #ifndef _DVBNET_H_

View File

@ -7,21 +7,6 @@
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de> * Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de> * & Marcus Metzler <marcus@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Lesser Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBOSD_H_ #ifndef _DVBOSD_H_

View File

@ -4,21 +4,6 @@
* *
* Copyright (C) 2000 Holger Waechtler <holger@convergence.de> * Copyright (C) 2000 Holger Waechtler <holger@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _DVBVERSION_H_ #ifndef _DVBVERSION_H_

View File

@ -7,21 +7,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de> * & Ralph Metzler <ralph@convergence.de>
* for convergence integrated media GmbH * for convergence integrated media GmbH
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/ */
#ifndef _UAPI_DVBVIDEO_H_ #ifndef _UAPI_DVBVIDEO_H_

View File

@ -369,6 +369,10 @@ struct dvb_frontend_internal_info {
* allocated by the driver. * allocated by the driver.
* @init: callback function used to initialize the tuner device. * @init: callback function used to initialize the tuner device.
* @sleep: callback function used to put the tuner to sleep. * @sleep: callback function used to put the tuner to sleep.
* @suspend: callback function used to inform that the Kernel will
* suspend.
* @resume: callback function used to inform that the Kernel is
* resuming from suspend.
* @write: callback function used by some demod legacy drivers to * @write: callback function used by some demod legacy drivers to
* allow other drivers to write data into their registers. * allow other drivers to write data into their registers.
* Should not be used on new drivers. * Should not be used on new drivers.
@ -438,7 +442,6 @@ struct dvb_frontend_internal_info {
* @analog_ops: pointer to &struct analog_demod_ops * @analog_ops: pointer to &struct analog_demod_ops
*/ */
struct dvb_frontend_ops { struct dvb_frontend_ops {
struct dvb_frontend_internal_info info; struct dvb_frontend_internal_info info;
u8 delsys[MAX_DELSYS]; u8 delsys[MAX_DELSYS];
@ -449,6 +452,8 @@ struct dvb_frontend_ops {
int (*init)(struct dvb_frontend* fe); int (*init)(struct dvb_frontend* fe);
int (*sleep)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe);
int (*suspend)(struct dvb_frontend *fe);
int (*resume)(struct dvb_frontend *fe);
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len); int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
@ -765,7 +770,8 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
* &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise, * &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
* it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available. * it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
* *
* It will also call &dvb_frontend_ops.sleep\(\) to put the demod to suspend. * It will also call &dvb_frontend_ops.suspend\(\) to put the demod to suspend,
* if available. Otherwise it will call &dvb_frontend_ops.sleep\(\).
* *
* The drivers should also call dvb_frontend_suspend\(\) as part of their * The drivers should also call dvb_frontend_suspend\(\) as part of their
* handler for the &device_driver.suspend\(\). * handler for the &device_driver.suspend\(\).
@ -779,7 +785,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
* *
* This function resumes the usual operation of the tuner after resume. * This function resumes the usual operation of the tuner after resume.
* *
* In order to resume the frontend, it calls the demod &dvb_frontend_ops.init\(\). * In order to resume the frontend, it calls the demod
* &dvb_frontend_ops.resume\(\) if available. Otherwise it calls demod
* &dvb_frontend_ops.init\(\).
* *
* If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it. * If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available. * Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.

View File

@ -214,7 +214,7 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
* @buf: Buffer to write. * @buf: Buffer to write.
* @len: Length of buffer (currently limited to 65535 bytes max). * @len: Length of buffer (currently limited to 65535 bytes max).
* *
* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. * Return: Number of bytes written, or -EFAULT, -ENOMEM, -EINVAL.
*/ */
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf, extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,
size_t len); size_t len);

View File

@ -35,7 +35,7 @@
#endif #endif
#endif #endif
#define DVB_MAX_ADAPTERS 64 #define DVB_MAX_ADAPTERS 64
#define DVB_UNSET (-1) #define DVB_UNSET (-1)
@ -96,7 +96,11 @@ struct dvb_frontend;
* @device: pointer to struct device * @device: pointer to struct device
* @module: pointer to struct module * @module: pointer to struct module
* @mfe_shared: indicates mutually exclusive frontends. * @mfe_shared: indicates mutually exclusive frontends.
* Use of this flag is currently deprecated. * 1 = legacy exclusion behavior: blocking any open() call
* 2 = enhanced exclusion behavior, emulating the standard
* behavior of busy frontends: allowing read-only sharing
* and otherwise returning immediately with -EBUSY when any
* of the frontends is already opened with write access.
* @mfe_dvbdev: Frontend device in use, in the case of MFE * @mfe_dvbdev: Frontend device in use, in the case of MFE
* @mfe_lock: Lock to prevent using the other frontends when MFE is * @mfe_lock: Lock to prevent using the other frontends when MFE is
* used. * used.
@ -135,6 +139,7 @@ struct dvb_adapter {
* struct dvb_device - represents a DVB device node * struct dvb_device - represents a DVB device node
* *
* @list_head: List head with all DVB devices * @list_head: List head with all DVB devices
* @ref: reference counter
* @fops: pointer to struct file_operations * @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node * @adapter: pointer to the adapter that holds this device node
* @type: type of the device, as defined by &enum dvb_device_type. * @type: type of the device, as defined by &enum dvb_device_type.
@ -165,6 +170,7 @@ struct dvb_adapter {
*/ */
struct dvb_device { struct dvb_device {
struct list_head list_head; struct list_head list_head;
struct kref ref;
const struct file_operations *fops; const struct file_operations *fops;
struct dvb_adapter *adapter; struct dvb_adapter *adapter;
enum dvb_device_type type; enum dvb_device_type type;
@ -196,6 +202,20 @@ struct dvb_device {
void *priv; void *priv;
}; };
/**
* dvb_device_get - Increase dvb_device reference
*
* @dvbdev: pointer to struct dvb_device
*/
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
/**
* dvb_device_put - Decrease dvb_device reference
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_device_put(struct dvb_device *dvbdev);
/** /**
* dvb_register_adapter - Registers a new DVB adapter * dvb_register_adapter - Registers a new DVB adapter
* *
@ -240,29 +260,16 @@ int dvb_register_device(struct dvb_adapter *adap,
/** /**
* dvb_remove_device - Remove a registered DVB device * dvb_remove_device - Remove a registered DVB device
* *
* This does not free memory. To do that, call dvb_free_device(). * This does not free memory. dvb_free_device() will do that when
* reference counter is empty
* *
* @dvbdev: pointer to struct dvb_device * @dvbdev: pointer to struct dvb_device
*/ */
void dvb_remove_device(struct dvb_device *dvbdev); void dvb_remove_device(struct dvb_device *dvbdev);
/**
* dvb_free_device - Free memory occupied by a DVB device.
*
* Call dvb_unregister_device() before calling this function.
*
* @dvbdev: pointer to struct dvb_device
*/
void dvb_free_device(struct dvb_device *dvbdev);
/** /**
* dvb_unregister_device - Unregisters a DVB device * dvb_unregister_device - Unregisters a DVB device
* *
* This is a combination of dvb_remove_device() and dvb_free_device().
* Using this function is usually a mistake, and is often an indicator
* for a use-after-free bug (when a userspace process keeps a file
* handle to a detached device).
*
* @dvbdev: pointer to struct dvb_device * @dvbdev: pointer to struct dvb_device
*/ */
void dvb_unregister_device(struct dvb_device *dvbdev); void dvb_unregister_device(struct dvb_device *dvbdev);

View File

@ -391,6 +391,10 @@ int main(int argc, char **argv)
printf("unknown mtype %s\n", optarg); printf("unknown mtype %s\n", optarg);
break; break;
case 'd': case 'd':
if (!strcmp(optarg, "C2"))
delsys = SYS_DVBC2;
if (!strcmp(optarg, "DVBC2"))
delsys = SYS_DVBC2;
if (!strcmp(optarg, "C")) if (!strcmp(optarg, "C"))
delsys = SYS_DVBC_ANNEX_A; delsys = SYS_DVBC_ANNEX_A;
if (!strcmp(optarg, "DVBC")) if (!strcmp(optarg, "DVBC"))