示例#1
0
static void pvr2_ioread_filter(struct pvr2_ioread *cp)
{
    unsigned int idx;
    if (!cp->enabled) return;
    if (cp->sync_state != 1) return;

    // Search the stream for our synchronization key.  This is made
    // complicated by the fact that in order to be honest with
    // ourselves here we must search across buffer boundaries...
    mutex_lock(&cp->mutex);
    while (1) {
        // Ensure we have a buffer
        if (!pvr2_ioread_get_buffer(cp)) break;
        if (!cp->c_data_len) break;

        // Now walk the buffer contents until we match the key or
        // run out of buffer data.
        for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
            if (cp->sync_buf_offs >= cp->sync_key_len) break;
            if (cp->c_data_ptr[idx] ==
                    cp->sync_key_ptr[cp->sync_buf_offs]) {
                // Found the next key byte
                (cp->sync_buf_offs)++;
            } else {
                // Whoops, mismatched.  Start key over...
                cp->sync_buf_offs = 0;
            }
        }

        // Consume what we've walked through
        cp->c_data_offs += idx;
        cp->sync_trashed_count += idx;

        // If we've found the key, then update state and get out.
        if (cp->sync_buf_offs >= cp->sync_key_len) {
            cp->sync_trashed_count -= cp->sync_key_len;
            pvr2_trace(PVR2_TRACE_DATA_FLOW,
                       "/*---TRACE_READ---*/"
                       " sync_state <== 2 (skipped %u bytes)",
                       cp->sync_trashed_count);
            cp->sync_state = 2;
            cp->sync_buf_offs = 0;
            break;
        }

        if (cp->c_data_offs < cp->c_data_len) {
            // Sanity check - should NEVER get here
            pvr2_trace(PVR2_TRACE_ERROR_LEGS,
                       "ERROR: pvr2_ioread filter sync problem"
                       " len=%u offs=%u",
                       cp->c_data_len,cp->c_data_offs);
            // Get out so we don't get stuck in an infinite
            // loop.
            break;
        }

        continue; // (for clarity)
    }
    mutex_unlock(&cp->mutex);
}
示例#2
0
static void pvr2_ioread_filter(struct pvr2_ioread *cp)
{
	unsigned int idx;
	if (!cp->enabled) return;
	if (cp->sync_state != 1) return;

	
	
	
	mutex_lock(&cp->mutex); while (1) {
		
		if (!pvr2_ioread_get_buffer(cp)) break;
		if (!cp->c_data_len) break;

		
		
		for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) {
			if (cp->sync_buf_offs >= cp->sync_key_len) break;
			if (cp->c_data_ptr[idx] ==
			    cp->sync_key_ptr[cp->sync_buf_offs]) {
				
				(cp->sync_buf_offs)++;
			} else {
				
				cp->sync_buf_offs = 0;
			}
		}

		
		cp->c_data_offs += idx;
		cp->sync_trashed_count += idx;

		
		if (cp->sync_buf_offs >= cp->sync_key_len) {
			cp->sync_trashed_count -= cp->sync_key_len;
			pvr2_trace(PVR2_TRACE_DATA_FLOW,
				   "/*---TRACE_READ---*/"
				   " sync_state <== 2 (skipped %u bytes)",
				   cp->sync_trashed_count);
			cp->sync_state = 2;
			cp->sync_buf_offs = 0;
			break;
		}

		if (cp->c_data_offs < cp->c_data_len) {
			
			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
				   "ERROR: pvr2_ioread filter sync problem"
				   " len=%u offs=%u",
				   cp->c_data_len,cp->c_data_offs);
			
			
			break;
		}

		continue; 
	} mutex_unlock(&cp->mutex);
}
示例#3
0
int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
{
	unsigned int copied_cnt;
	unsigned int bcnt;
	const char *src;
	int stat;
	int ret = 0;
	unsigned int req_cnt = cnt;

	if (!cnt) {
		pvr2_trace(PVR2_TRACE_TRAP,
			   "/*---TRACE_READ---*/ pvr2_ioread_read id=%p ZERO Request? Returning zero.",
cp);
		return 0;
	}

	stat = pvr2_ioread_avail(cp);
	if (stat < 0) return stat;

	cp->stream_running = !0;

	mutex_lock(&cp->mutex);
	do {

		// Suck data out of the buffers and copy to the user
		copied_cnt = 0;
		if (!buf) cnt = 0;
		while (1) {
			if (!pvr2_ioread_get_buffer(cp)) {
				ret = -EIO;
				break;
			}

			if (!cnt) break;

			if (cp->sync_state == 2) {
				// We're repeating the sync key data into
				// the stream.
				src = cp->sync_key_ptr + cp->sync_buf_offs;
				bcnt = cp->sync_key_len - cp->sync_buf_offs;
			} else {
				// Normal buffer copy
				src = cp->c_data_ptr + cp->c_data_offs;
				bcnt = cp->c_data_len - cp->c_data_offs;
			}

			if (!bcnt) break;

			// Don't run past user's buffer
			if (bcnt > cnt) bcnt = cnt;

			if (copy_to_user(buf,src,bcnt)) {
				// User supplied a bad pointer?
				// Give up - this *will* cause data
				// to be lost.
				ret = -EFAULT;
				break;
			}
			cnt -= bcnt;
			buf += bcnt;
			copied_cnt += bcnt;

			if (cp->sync_state == 2) {
				// Update offset inside sync key that we're
				// repeating back out.
				cp->sync_buf_offs += bcnt;
				if (cp->sync_buf_offs >= cp->sync_key_len) {
					// Consumed entire key; switch mode
					// to normal.
					pvr2_trace(PVR2_TRACE_DATA_FLOW,
						   "/*---TRACE_READ---*/ sync_state <== 0");
					cp->sync_state = 0;
				}
			} else {
				// Update buffer offset.
				cp->c_data_offs += bcnt;
			}
		}

	} while (0);
	mutex_unlock(&cp->mutex);

	if (!ret) {
		if (copied_cnt) {
			// If anything was copied, return that count
			ret = copied_cnt;
		} else {
			// Nothing copied; suggest to caller that another
			// attempt should be tried again later
			ret = -EAGAIN;
		}
	}

	pvr2_trace(PVR2_TRACE_DATA_FLOW,
		   "/*---TRACE_READ---*/ pvr2_ioread_read id=%p request=%d result=%d",
		   cp,req_cnt,ret);
	return ret;
}
示例#4
0
int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt)
{
	unsigned int copied_cnt;
	unsigned int bcnt;
	const char *src;
	int stat;
	int ret = 0;
	unsigned int req_cnt = cnt;

	if (!cnt) {
		pvr2_trace(PVR2_TRACE_TRAP,
			   "/*---TRACE_READ---*/ pvr2_ioread_read id=%p"
			   " ZERO Request? Returning zero.",cp);
		return 0;
	}

	stat = pvr2_ioread_avail(cp);
	if (stat < 0) return stat;

	cp->stream_running = !0;

	mutex_lock(&cp->mutex); do {

		
		copied_cnt = 0;
		if (!buf) cnt = 0;
		while (1) {
			if (!pvr2_ioread_get_buffer(cp)) {
				ret = -EIO;
				break;
			}

			if (!cnt) break;

			if (cp->sync_state == 2) {
				
				
				src = cp->sync_key_ptr + cp->sync_buf_offs;
				bcnt = cp->sync_key_len - cp->sync_buf_offs;
			} else {
				
				src = cp->c_data_ptr + cp->c_data_offs;
				bcnt = cp->c_data_len - cp->c_data_offs;
			}

			if (!bcnt) break;

			
			if (bcnt > cnt) bcnt = cnt;

			if (copy_to_user(buf,src,bcnt)) {
				
				
				
				ret = -EFAULT;
				break;
			}
			cnt -= bcnt;
			buf += bcnt;
			copied_cnt += bcnt;

			if (cp->sync_state == 2) {
				
				
				cp->sync_buf_offs += bcnt;
				if (cp->sync_buf_offs >= cp->sync_key_len) {
					
					
					pvr2_trace(PVR2_TRACE_DATA_FLOW,
						   "/*---TRACE_READ---*/"
						   " sync_state <== 0");
					cp->sync_state = 0;
				}
			} else {
				
				cp->c_data_offs += bcnt;
			}
		}

	} while (0); mutex_unlock(&cp->mutex);

	if (!ret) {
		if (copied_cnt) {
			
			ret = copied_cnt;
		} else {
			
			
			ret = -EAGAIN;
		}
	}

	pvr2_trace(PVR2_TRACE_DATA_FLOW,
		   "/*---TRACE_READ---*/ pvr2_ioread_read"
		   " id=%p request=%d result=%d",
		   cp,req_cnt,ret);
	return ret;
}