Commit ab1df7b4 authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: fix 32 bytes offset, modify circbuf_valid_ptr to update pointer

parent 3c64c8e0
...@@ -290,13 +290,13 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun ...@@ -290,13 +290,13 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)]; len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)];
if ((len32 & MARKER_FF) != MARKER_FF) { if ((len32 & MARKER_FF) != MARKER_FF) {
printk(KERN_DEBUG "failed to get 0xff marker at offset 0x%x\n", offset); dev_dbg(g_dev_ptr, "failed to get 0xff marker at offset 0x%x\n", offset);
byte_offset = X393_BUFFSUB(byte_offset, 0x20); byte_offset = X393_BUFFSUB(byte_offset, 0x20);
last_image_chunk = X393_BUFFSUB(byte_offset, OFFSET_X40); last_image_chunk = X393_BUFFSUB(byte_offset, OFFSET_X40);
offset = last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH); offset = last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH);
len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)]; len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)];
if ((len32 & MARKER_FF) != MARKER_FF) { if ((len32 & MARKER_FF) != MARKER_FF) {
printk(KERN_DEBUG "failed to get 0xff marker at CORRECTED offset 0x%x\n", offset); dev_dbg(g_dev_ptr, "failed to get 0xff marker at CORRECTED offset 0x%x\n", offset);
return 0; return 0;
} }
} }
...@@ -320,8 +320,9 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun ...@@ -320,8 +320,9 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
* -1 if there is no frame at this index, -2 if the pointer is not 32-bytes aligned * -1 if there is no frame at this index, -2 if the pointer is not 32-bytes aligned
* sets *fpp to the frame header, including signature and length * sets *fpp to the frame header, including signature and length
*/ */
int circbuf_valid_ptr(int rp, struct interframe_params_t **fpp, unsigned int chn) int circbuf_valid_ptr(int *rp_offset, struct interframe_params_t **fpp, unsigned int chn)
{ {
int rp = *rp_offset;
int last_image_chunk; int last_image_chunk;
unsigned int sec; unsigned int sec;
unsigned int usec; unsigned int usec;
...@@ -350,8 +351,9 @@ int circbuf_valid_ptr(int rp, struct interframe_params_t **fpp, unsigned int chn ...@@ -350,8 +351,9 @@ int circbuf_valid_ptr(int rp, struct interframe_params_t **fpp, unsigned int chn
dev_dbg(g_dev_ptr, "interframe signature is overwritten at CORRECTED offset, signffff = 0x%x\n", fp_off->signffff); dev_dbg(g_dev_ptr, "interframe signature is overwritten at CORRECTED offset, signffff = 0x%x\n", fp_off->signffff);
return -1; return -1;
} else { } else {
dev_dbg(g_dev_ptr, "interframe pointer is advanced by 0x20\n"); dev_dbg(g_dev_ptr, "interframe pointer and file ponter is advanced by 0x20\n");
*fpp = fp_off; *fpp = fp_off;
*rp_offset += CHUNK_SIZE;
dump_interframe_params(fp_off, rp); dump_interframe_params(fp_off, rp);
return 2; return 2;
} }
...@@ -449,7 +451,7 @@ void dump_state(unsigned int chn) ...@@ -449,7 +451,7 @@ void dump_state(unsigned int chn)
img_start = get_image_start(last_image_chunk, len32); img_start = get_image_start(last_image_chunk, len32);
read_ptr = img_start; read_ptr = img_start;
// move back in history // move back in history
while ((circbuf_valid_ptr(read_ptr, &fp, chn) >= 0) && (nz >= 0)) { while ((circbuf_valid_ptr(&read_ptr, &fp, chn) >= 0) && (nz >= 0)) {
printk(KERN_DEBUG "analyzing frame starting at 0x%x\n", read_ptr); printk(KERN_DEBUG "analyzing frame starting at 0x%x\n", read_ptr);
//printk(KERN_DEBUG "mem dump of 0x40 bytes at (pointer - 0x20) = 0x%x:\n", read_ptr - OFFSET_X40 / 2); //printk(KERN_DEBUG "mem dump of 0x40 bytes at (pointer - 0x20) = 0x%x:\n", read_ptr - OFFSET_X40 / 2);
//print_hex_dump_bytes("\t\t", DUMP_PREFIX_OFFSET, &circbuf_priv[chn].buf_ptr[BYTE2DW(read_ptr - OFFSET_X40 / 2)], OFFSET_X40); //print_hex_dump_bytes("\t\t", DUMP_PREFIX_OFFSET, &circbuf_priv[chn].buf_ptr[BYTE2DW(read_ptr - OFFSET_X40 / 2)], OFFSET_X40);
...@@ -491,7 +493,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -491,7 +493,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
break; break;
case SEEK_CUR: case SEEK_CUR:
if (offset) file->f_pos += offset; if (offset) file->f_pos += offset;
else if (circbuf_valid_ptr(file->f_pos, &fp, chn) < 0 ) return -EINVAL; //!no frames at the specified location or pointer is not 32-byte aligned else if (circbuf_valid_ptr(&file->f_pos, &fp, chn) < 0 ) return -EINVAL; //!no frames at the specified location or pointer is not 32-byte aligned
break; break;
case SEEK_END: case SEEK_END:
if (offset <= 0) { if (offset <= 0) {
...@@ -508,7 +510,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -508,7 +510,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
case LSEEK_CIRC_READY: case LSEEK_CIRC_READY:
case LSEEK_CIRC_FREE: case LSEEK_CIRC_FREE:
case LSEEK_CIRC_USED: case LSEEK_CIRC_USED:
if ((fvld = circbuf_valid_ptr(file->f_pos, &fp, chn)) < 0) if ((fvld = circbuf_valid_ptr(&file->f_pos, &fp, chn)) < 0)
return -EINVAL; // no frames at the specified location return -EINVAL; // no frames at the specified location
break; break;
/* debug code follows */ /* debug code follows */
...@@ -555,14 +557,14 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -555,14 +557,14 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32); //img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
img_start = get_image_start(last_image_chunk, len32); img_start = get_image_start(last_image_chunk, len32);
dev_dbg(g_dev_ptr, "calculated start address = 0x%x, length = 0x%x\n", img_start, len32); dev_dbg(g_dev_ptr, "calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
if (circbuf_valid_ptr(img_start, &fp, chn) < 0) if (circbuf_valid_ptr(&img_start, &fp, chn) < 0)
return -EOVERFLOW; return -EOVERFLOW;
file->f_pos = img_start; file->f_pos = img_start;
dev_dbg(g_dev_ptr, "LSEEK_CIRC_LAST: moving file->f_pos to 0x%llx\n", file->f_pos); dev_dbg(g_dev_ptr, "LSEEK_CIRC_LAST: moving file->f_pos to 0x%llx\n", file->f_pos);
break; break;
case LSEEK_CIRC_PREV: case LSEEK_CIRC_PREV:
rp = file->f_pos; rp = file->f_pos;
fvld = circbuf_valid_ptr(rp, &fp, chn); fvld = circbuf_valid_ptr(&rp, &fp, chn);
dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: rp = 0x%x, fvld = %d\n", rp, fvld); dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: rp = 0x%x, fvld = %d\n", rp, fvld);
dev_dbg(g_dev_ptr, "mem dump of last 0x40 bytes in buffer number %d\n", chn); dev_dbg(g_dev_ptr, "mem dump of last 0x40 bytes in buffer number %d\n", chn);
...@@ -581,7 +583,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -581,7 +583,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
// move file pointer only if previous frame valid // move file pointer only if previous frame valid
len32 = get_image_length(img_start, chn, NULL); len32 = get_image_length(img_start, chn, NULL);
if (circbuf_valid_ptr(img_start, &fp, chn) < 0) if (circbuf_valid_ptr(&img_start, &fp, chn) < 0)
return -EOVERFLOW; return -EOVERFLOW;
file->f_pos = img_start; file->f_pos = img_start;
break; break;
...@@ -590,7 +592,8 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -590,7 +592,8 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
if (fvld <= 0) { if (fvld <= 0) {
return -EOVERFLOW; //! no frames after current return -EOVERFLOW; //! no frames after current
} else if (fvld == 2) { } else if (fvld == 2) {
file->f_pos += CHUNK_SIZE; //file->f_pos += CHUNK_SIZE;
dev_dbg(g_dev_ptr, "read pointer file->f_pos was advanced by 0x20 bytes\n");
} }
// calculate the full length of current frame and advance file pointer by this value // calculate the full length of current frame and advance file pointer by this value
padded_frame = fp->frame_length + INSERTED_BYTES(fp->frame_length) + CHUNK_SIZE + CCAM_MMAP_META; padded_frame = fp->frame_length + INSERTED_BYTES(fp->frame_length) + CHUNK_SIZE + CCAM_MMAP_META;
...@@ -602,25 +605,27 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -602,25 +605,27 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
{ {
int nf = 0; // number of frames; int nf = 0; // number of frames;
int nz = 1; // number of start crossing of the circular buffer (counter to prevent looping forever) int nz = 1; // number of start crossing of the circular buffer (counter to prevent looping forever)
int rp_b;
int prev_p, preprev_p; int prev_p, preprev_p;
// starting from the write pointer to be able to count all the frames in the buffer // starting from the write pointer to be able to count all the frames in the buffer
rp = camseq_get_jpeg_wp(chn); rp = camseq_get_jpeg_wp(chn);
prev_p = preprev_p = rp; prev_p = preprev_p = DW2BYTE(rp);
file->f_pos = DW2BYTE(rp); file->f_pos = DW2BYTE(rp);
while (((fvld = circbuf_valid_ptr(DW2BYTE(rp), &fp, chn)) >= 0) & (nz >= 0)) { rp_b = DW2BYTE(rp);
while (((fvld = circbuf_valid_ptr(&rp_b, &fp, chn)) >= 0) & (nz >= 0)) {
nf++; nf++;
preprev_p = prev_p; // second known good (at least first one) preprev_p = prev_p; // second known good (at least first one)
prev_p=rp; // now - current, known good prev_p=rp_b; // now - current, known good
len32 = get_image_length(DW2BYTE(rp), chn, &last_image_chunk); len32 = get_image_length(rp_b, chn, &last_image_chunk);
dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32); dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp_b = 0x%x, fvld = %d, len32 = 0x%x", nf, rp_b, fvld, len32);
if ((len32 & MARKER_FF) != MARKER_FF ) break; //! no frames before rp (==prev_p) if ((len32 & MARKER_FF) != MARKER_FF ) break; //! no frames before rp (==prev_p)
//! move rp to the previous frame //! move rp to the previous frame
len32 &= FRAME_LENGTH_MASK; len32 &= FRAME_LENGTH_MASK;
//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32); //img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
img_start = get_image_start(last_image_chunk, len32); img_start = get_image_start(last_image_chunk, len32);
dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: calculated start address = 0x%x, length = 0x%x\n", img_start, len32); dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
rp = BYTE2DW(img_start); rp_b = img_start;
if (rp > prev_p) nz--; // rolled through zero - make sure we'll not stuck in this loop forever if (rp_b > prev_p) nz--; // rolled through zero - make sure we'll not stuck in this loop forever
} }
dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: finish stepping back through frames, number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32); dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: finish stepping back through frames, number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32);
file->f_pos = ((offset == LSEEK_CIRC_SCND) ? preprev_p : prev_p) << 2; file->f_pos = ((offset == LSEEK_CIRC_SCND) ? preprev_p : prev_p) << 2;
...@@ -640,7 +645,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig) ...@@ -640,7 +645,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
break; break;
case LSEEK_CIRC_WAIT: case LSEEK_CIRC_WAIT:
dev_dbg(g_dev_ptr, "LSEEK_CIRC_WAIT\n"); dev_dbg(g_dev_ptr, "LSEEK_CIRC_WAIT\n");
while (((fvld=circbuf_valid_ptr(file->f_pos, &fp, chn)))==0) { // only while not ready, ready or BAD - return while (((fvld=circbuf_valid_ptr(&file->f_pos, &fp, chn)))==0) { // only while not ready, ready or BAD - return
wait_event_interruptible(circbuf_wait_queue, (camseq_get_jpeg_wp(chn) << 2) != file->f_pos); wait_event_interruptible(circbuf_wait_queue, (camseq_get_jpeg_wp(chn) << 2) != file->f_pos);
} }
if (fvld < 0) return -ESPIPE; // invalid seek - have better code? if (fvld < 0) return -ESPIPE; // invalid seek - have better code?
...@@ -802,7 +807,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait) ...@@ -802,7 +807,7 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait)
int rslt; int rslt;
dev_dbg(g_dev_ptr, "minor = 0x%x\n", minor); dev_dbg(g_dev_ptr, "minor = 0x%x\n", minor);
rslt = circbuf_valid_ptr(file->f_pos, &fp, chn); rslt = circbuf_valid_ptr(&file->f_pos, &fp, chn);
if (rslt < 0) { if (rslt < 0) {
// not a valid read pointer, probable buffer overrun // not a valid read pointer, probable buffer overrun
dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%llx\n", file->f_pos); dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%llx\n", file->f_pos);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment