mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-26 22:05:24 +07:00
42bc47b353
The vmalloc() function has no 2-factor argument form, so multiplication factors need to be wrapped in array_size(). This patch replaces cases of: vmalloc(a * b) with: vmalloc(array_size(a, b)) as well as handling cases of: vmalloc(a * b * c) with: vmalloc(array3_size(a, b, c)) This does, however, attempt to ignore constant size factors like: vmalloc(4 * 1024) though any constants defined via macros get caught up in the conversion. Any factors with a sizeof() of "unsigned char", "char", and "u8" were dropped, since they're redundant. The Coccinelle script used for this was: // Fix redundant parens around sizeof(). @@ type TYPE; expression THING, E; @@ ( vmalloc( - (sizeof(TYPE)) * E + sizeof(TYPE) * E , ...) | vmalloc( - (sizeof(THING)) * E + sizeof(THING) * E , ...) ) // Drop single-byte sizes and redundant parens. @@ expression COUNT; typedef u8; typedef __u8; @@ ( vmalloc( - sizeof(u8) * (COUNT) + COUNT , ...) | vmalloc( - sizeof(__u8) * (COUNT) + COUNT , ...) | vmalloc( - sizeof(char) * (COUNT) + COUNT , ...) | vmalloc( - sizeof(unsigned char) * (COUNT) + COUNT , ...) | vmalloc( - sizeof(u8) * COUNT + COUNT , ...) | vmalloc( - sizeof(__u8) * COUNT + COUNT , ...) | vmalloc( - sizeof(char) * COUNT + COUNT , ...) | vmalloc( - sizeof(unsigned char) * COUNT + COUNT , ...) ) // 2-factor product with sizeof(type/expression) and identifier or constant. @@ type TYPE; expression THING; identifier COUNT_ID; constant COUNT_CONST; @@ ( vmalloc( - sizeof(TYPE) * (COUNT_ID) + array_size(COUNT_ID, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * COUNT_ID + array_size(COUNT_ID, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * (COUNT_CONST) + array_size(COUNT_CONST, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * COUNT_CONST + array_size(COUNT_CONST, sizeof(TYPE)) , ...) | vmalloc( - sizeof(THING) * (COUNT_ID) + array_size(COUNT_ID, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * COUNT_ID + array_size(COUNT_ID, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * (COUNT_CONST) + array_size(COUNT_CONST, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * COUNT_CONST + array_size(COUNT_CONST, sizeof(THING)) , ...) ) // 2-factor product, only identifiers. @@ identifier SIZE, COUNT; @@ vmalloc( - SIZE * COUNT + array_size(COUNT, SIZE) , ...) // 3-factor product with 1 sizeof(type) or sizeof(expression), with // redundant parens removed. @@ expression THING; identifier STRIDE, COUNT; type TYPE; @@ ( vmalloc( - sizeof(TYPE) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | vmalloc( - sizeof(TYPE) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(TYPE)) , ...) | vmalloc( - sizeof(THING) * (COUNT) * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * (COUNT) * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * COUNT * (STRIDE) + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) | vmalloc( - sizeof(THING) * COUNT * STRIDE + array3_size(COUNT, STRIDE, sizeof(THING)) , ...) ) // 3-factor product with 2 sizeof(variable), with redundant parens removed. @@ expression THING1, THING2; identifier COUNT; type TYPE1, TYPE2; @@ ( vmalloc( - sizeof(TYPE1) * sizeof(TYPE2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | vmalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2)) , ...) | vmalloc( - sizeof(THING1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | vmalloc( - sizeof(THING1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(THING1), sizeof(THING2)) , ...) | vmalloc( - sizeof(TYPE1) * sizeof(THING2) * COUNT + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) | vmalloc( - sizeof(TYPE1) * sizeof(THING2) * (COUNT) + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2)) , ...) ) // 3-factor product, only identifiers, with redundant parens removed. @@ identifier STRIDE, SIZE, COUNT; @@ ( vmalloc( - (COUNT) * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - COUNT * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - COUNT * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - (COUNT) * (STRIDE) * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - COUNT * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - (COUNT) * STRIDE * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - (COUNT) * (STRIDE) * (SIZE) + array3_size(COUNT, STRIDE, SIZE) , ...) | vmalloc( - COUNT * STRIDE * SIZE + array3_size(COUNT, STRIDE, SIZE) , ...) ) // Any remaining multi-factor products, first at least 3-factor products // when they're not all constants... @@ expression E1, E2, E3; constant C1, C2, C3; @@ ( vmalloc(C1 * C2 * C3, ...) | vmalloc( - E1 * E2 * E3 + array3_size(E1, E2, E3) , ...) ) // And then all remaining 2 factors products when they're not all constants. @@ expression E1, E2; constant C1, C2; @@ ( vmalloc(C1 * C2, ...) | vmalloc( - E1 * E2 + array_size(E1, E2) , ...) ) Signed-off-by: Kees Cook <keescook@chromium.org>
405 lines
7.8 KiB
C
405 lines
7.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include "dvb_filter.h"
|
|
#include "av7110_ipack.h"
|
|
#include <linux/string.h> /* for memcpy() */
|
|
#include <linux/vmalloc.h>
|
|
|
|
|
|
void av7110_ipack_reset(struct ipack *p)
|
|
{
|
|
p->found = 0;
|
|
p->cid = 0;
|
|
p->plength = 0;
|
|
p->flag1 = 0;
|
|
p->flag2 = 0;
|
|
p->hlength = 0;
|
|
p->mpeg = 0;
|
|
p->check = 0;
|
|
p->which = 0;
|
|
p->done = 0;
|
|
p->count = 0;
|
|
}
|
|
|
|
|
|
int av7110_ipack_init(struct ipack *p, int size,
|
|
void (*func)(u8 *buf, int size, void *priv))
|
|
{
|
|
if (!(p->buf = vmalloc(size))) {
|
|
printk(KERN_WARNING "Couldn't allocate memory for ipack\n");
|
|
return -ENOMEM;
|
|
}
|
|
p->size = size;
|
|
p->func = func;
|
|
p->repack_subids = 0;
|
|
av7110_ipack_reset(p);
|
|
return 0;
|
|
}
|
|
|
|
|
|
void av7110_ipack_free(struct ipack *p)
|
|
{
|
|
vfree(p->buf);
|
|
}
|
|
|
|
|
|
static void send_ipack(struct ipack *p)
|
|
{
|
|
int off;
|
|
struct dvb_audio_info ai;
|
|
int ac3_off = 0;
|
|
int streamid = 0;
|
|
int nframes = 0;
|
|
int f = 0;
|
|
|
|
switch (p->mpeg) {
|
|
case 2:
|
|
if (p->count < 10)
|
|
return;
|
|
p->buf[3] = p->cid;
|
|
p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
|
|
p->buf[5] = (u8)((p->count - 6) & 0x00ff);
|
|
if (p->repack_subids && p->cid == PRIVATE_STREAM1) {
|
|
off = 9 + p->buf[8];
|
|
streamid = p->buf[off];
|
|
if ((streamid & 0xf8) == 0x80) {
|
|
ai.off = 0;
|
|
ac3_off = ((p->buf[off + 2] << 8)|
|
|
p->buf[off + 3]);
|
|
if (ac3_off < p->count)
|
|
f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off,
|
|
p->count - ac3_off, &ai, 0);
|
|
if (!f) {
|
|
nframes = (p->count - off - 3 - ac3_off) /
|
|
ai.framesize + 1;
|
|
p->buf[off + 2] = (ac3_off >> 8) & 0xff;
|
|
p->buf[off + 3] = (ac3_off) & 0xff;
|
|
p->buf[off + 1] = nframes;
|
|
ac3_off += nframes * ai.framesize - p->count;
|
|
}
|
|
}
|
|
}
|
|
p->func(p->buf, p->count, p->data);
|
|
|
|
p->buf[6] = 0x80;
|
|
p->buf[7] = 0x00;
|
|
p->buf[8] = 0x00;
|
|
p->count = 9;
|
|
if (p->repack_subids && p->cid == PRIVATE_STREAM1
|
|
&& (streamid & 0xf8) == 0x80) {
|
|
p->count += 4;
|
|
p->buf[9] = streamid;
|
|
p->buf[10] = (ac3_off >> 8) & 0xff;
|
|
p->buf[11] = (ac3_off) & 0xff;
|
|
p->buf[12] = 0;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (p->count < 8)
|
|
return;
|
|
p->buf[3] = p->cid;
|
|
p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8);
|
|
p->buf[5] = (u8)((p->count - 6) & 0x00ff);
|
|
p->func(p->buf, p->count, p->data);
|
|
|
|
p->buf[6] = 0x0f;
|
|
p->count = 7;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void av7110_ipack_flush(struct ipack *p)
|
|
{
|
|
if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6)
|
|
return;
|
|
p->plength = p->found - 6;
|
|
p->found = 0;
|
|
send_ipack(p);
|
|
av7110_ipack_reset(p);
|
|
}
|
|
|
|
|
|
static void write_ipack(struct ipack *p, const u8 *data, int count)
|
|
{
|
|
u8 headr[3] = { 0x00, 0x00, 0x01 };
|
|
|
|
if (p->count < 6) {
|
|
memcpy(p->buf, headr, 3);
|
|
p->count = 6;
|
|
}
|
|
|
|
if (p->count + count < p->size){
|
|
memcpy(p->buf+p->count, data, count);
|
|
p->count += count;
|
|
} else {
|
|
int rest = p->size - p->count;
|
|
memcpy(p->buf+p->count, data, rest);
|
|
p->count += rest;
|
|
send_ipack(p);
|
|
if (count - rest > 0)
|
|
write_ipack(p, data + rest, count - rest);
|
|
}
|
|
}
|
|
|
|
|
|
int av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p)
|
|
{
|
|
int l;
|
|
int c = 0;
|
|
|
|
while (c < count && (p->mpeg == 0 ||
|
|
(p->mpeg == 1 && p->found < 7) ||
|
|
(p->mpeg == 2 && p->found < 9))
|
|
&& (p->found < 5 || !p->done)) {
|
|
switch (p->found) {
|
|
case 0:
|
|
case 1:
|
|
if (buf[c] == 0x00)
|
|
p->found++;
|
|
else
|
|
p->found = 0;
|
|
c++;
|
|
break;
|
|
case 2:
|
|
if (buf[c] == 0x01)
|
|
p->found++;
|
|
else if (buf[c] == 0)
|
|
p->found = 2;
|
|
else
|
|
p->found = 0;
|
|
c++;
|
|
break;
|
|
case 3:
|
|
p->cid = 0;
|
|
switch (buf[c]) {
|
|
case PROG_STREAM_MAP:
|
|
case PRIVATE_STREAM2:
|
|
case PROG_STREAM_DIR:
|
|
case ECM_STREAM :
|
|
case EMM_STREAM :
|
|
case PADDING_STREAM :
|
|
case DSM_CC_STREAM :
|
|
case ISO13522_STREAM:
|
|
p->done = 1;
|
|
/* fall through */
|
|
case PRIVATE_STREAM1:
|
|
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
p->found++;
|
|
p->cid = buf[c];
|
|
c++;
|
|
break;
|
|
default:
|
|
p->found = 0;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 4:
|
|
if (count-c > 1) {
|
|
p->plen[0] = buf[c];
|
|
c++;
|
|
p->plen[1] = buf[c];
|
|
c++;
|
|
p->found += 2;
|
|
p->plength = (p->plen[0] << 8) | p->plen[1];
|
|
} else {
|
|
p->plen[0] = buf[c];
|
|
p->found++;
|
|
return count;
|
|
}
|
|
break;
|
|
case 5:
|
|
p->plen[1] = buf[c];
|
|
c++;
|
|
p->found++;
|
|
p->plength = (p->plen[0] << 8) | p->plen[1];
|
|
break;
|
|
case 6:
|
|
if (!p->done) {
|
|
p->flag1 = buf[c];
|
|
c++;
|
|
p->found++;
|
|
if ((p->flag1 & 0xc0) == 0x80)
|
|
p->mpeg = 2;
|
|
else {
|
|
p->hlength = 0;
|
|
p->which = 0;
|
|
p->mpeg = 1;
|
|
p->flag2 = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 7:
|
|
if (!p->done && p->mpeg == 2) {
|
|
p->flag2 = buf[c];
|
|
c++;
|
|
p->found++;
|
|
}
|
|
break;
|
|
|
|
case 8:
|
|
if (!p->done && p->mpeg == 2) {
|
|
p->hlength = buf[c];
|
|
c++;
|
|
p->found++;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (c == count)
|
|
return count;
|
|
|
|
if (!p->plength)
|
|
p->plength = MMAX_PLENGTH - 6;
|
|
|
|
if (p->done || ((p->mpeg == 2 && p->found >= 9) ||
|
|
(p->mpeg == 1 && p->found >= 7))) {
|
|
switch (p->cid) {
|
|
case AUDIO_STREAM_S ... AUDIO_STREAM_E:
|
|
case VIDEO_STREAM_S ... VIDEO_STREAM_E:
|
|
case PRIVATE_STREAM1:
|
|
if (p->mpeg == 2 && p->found == 9) {
|
|
write_ipack(p, &p->flag1, 1);
|
|
write_ipack(p, &p->flag2, 1);
|
|
write_ipack(p, &p->hlength, 1);
|
|
}
|
|
|
|
if (p->mpeg == 1 && p->found == 7)
|
|
write_ipack(p, &p->flag1, 1);
|
|
|
|
if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&
|
|
p->found < 14) {
|
|
while (c < count && p->found < 14) {
|
|
p->pts[p->found - 9] = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
}
|
|
if (c == count)
|
|
return count;
|
|
}
|
|
|
|
if (p->mpeg == 1 && p->which < 2000) {
|
|
|
|
if (p->found == 7) {
|
|
p->check = p->flag1;
|
|
p->hlength = 1;
|
|
}
|
|
|
|
while (!p->which && c < count &&
|
|
p->check == 0xff){
|
|
p->check = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->hlength++;
|
|
}
|
|
|
|
if (c == count)
|
|
return count;
|
|
|
|
if ((p->check & 0xc0) == 0x40 && !p->which) {
|
|
p->check = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->hlength++;
|
|
|
|
p->which = 1;
|
|
if (c == count)
|
|
return count;
|
|
p->check = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->hlength++;
|
|
p->which = 2;
|
|
if (c == count)
|
|
return count;
|
|
}
|
|
|
|
if (p->which == 1) {
|
|
p->check = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->hlength++;
|
|
p->which = 2;
|
|
if (c == count)
|
|
return count;
|
|
}
|
|
|
|
if ((p->check & 0x30) && p->check != 0xff) {
|
|
p->flag2 = (p->check & 0xf0) << 2;
|
|
p->pts[0] = p->check;
|
|
p->which = 3;
|
|
}
|
|
|
|
if (c == count)
|
|
return count;
|
|
if (p->which > 2){
|
|
if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) {
|
|
while (c < count && p->which < 7) {
|
|
p->pts[p->which - 2] = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->which++;
|
|
p->hlength++;
|
|
}
|
|
if (c == count)
|
|
return count;
|
|
} else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) {
|
|
while (c < count && p->which < 12) {
|
|
if (p->which < 7)
|
|
p->pts[p->which - 2] = buf[c];
|
|
write_ipack(p, buf + c, 1);
|
|
c++;
|
|
p->found++;
|
|
p->which++;
|
|
p->hlength++;
|
|
}
|
|
if (c == count)
|
|
return count;
|
|
}
|
|
p->which = 2000;
|
|
}
|
|
|
|
}
|
|
|
|
while (c < count && p->found < p->plength + 6) {
|
|
l = count - c;
|
|
if (l + p->found > p->plength + 6)
|
|
l = p->plength + 6 - p->found;
|
|
write_ipack(p, buf + c, l);
|
|
p->found += l;
|
|
c += l;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if (p->done) {
|
|
if (p->found + count - c < p->plength + 6) {
|
|
p->found += count - c;
|
|
c = count;
|
|
} else {
|
|
c += p->plength + 6 - p->found;
|
|
p->found = p->plength + 6;
|
|
}
|
|
}
|
|
|
|
if (p->plength && p->found == p->plength + 6) {
|
|
send_ipack(p);
|
|
av7110_ipack_reset(p);
|
|
if (c < count)
|
|
av7110_ipack_instant_repack(buf + c, count - c, p);
|
|
}
|
|
}
|
|
return count;
|
|
}
|