| .. | .. | 
|---|
| 361 | 361 | break; | 
|---|
| 362 | 362 |  | 
|---|
| 363 | 363 | case KBUFFER_TYPE_TIME_EXTEND: | 
|---|
|  | 364 | +	case KBUFFER_TYPE_TIME_STAMP: | 
|---|
| 364 | 365 | extend = read_4(kbuf, data); | 
|---|
| 365 | 366 | data += 4; | 
|---|
| 366 | 367 | extend <<= TS_SHIFT; | 
|---|
| .. | .. | 
|---|
| 369 | 370 | *length = 0; | 
|---|
| 370 | 371 | break; | 
|---|
| 371 | 372 |  | 
|---|
| 372 |  | -	case KBUFFER_TYPE_TIME_STAMP: | 
|---|
| 373 |  | -		data += 12; | 
|---|
| 374 |  | -		*length = 0; | 
|---|
| 375 |  | -		break; | 
|---|
| 376 | 373 | case 0: | 
|---|
| 377 | 374 | *length = read_4(kbuf, data) - 4; | 
|---|
| 378 | 375 | *length = (*length + 3) & ~3; | 
|---|
| .. | .. | 
|---|
| 397 | 394 |  | 
|---|
| 398 | 395 | type_len = translate_data(kbuf, ptr, &ptr, &delta, &length); | 
|---|
| 399 | 396 |  | 
|---|
| 400 |  | -	kbuf->timestamp += delta; | 
|---|
|  | 397 | +	if (type_len == KBUFFER_TYPE_TIME_STAMP) | 
|---|
|  | 398 | +		kbuf->timestamp = delta; | 
|---|
|  | 399 | +	else | 
|---|
|  | 400 | +		kbuf->timestamp += delta; | 
|---|
|  | 401 | + | 
|---|
| 401 | 402 | kbuf->index = calc_index(kbuf, ptr); | 
|---|
| 402 | 403 | kbuf->next = kbuf->index + length; | 
|---|
| 403 | 404 |  | 
|---|
| .. | .. | 
|---|
| 438 | 439 | case KBUFFER_TYPE_TIME_EXTEND: | 
|---|
| 439 | 440 | case KBUFFER_TYPE_TIME_STAMP: | 
|---|
| 440 | 441 | return NULL; | 
|---|
| 441 |  | -	}; | 
|---|
|  | 442 | +	} | 
|---|
| 442 | 443 |  | 
|---|
| 443 | 444 | *size = length; | 
|---|
| 444 | 445 |  | 
|---|
| .. | .. | 
|---|
| 454 | 455 | if (kbuf->next >= kbuf->size) | 
|---|
| 455 | 456 | return -1; | 
|---|
| 456 | 457 | type = update_pointers(kbuf); | 
|---|
| 457 |  | -	} while (type == KBUFFER_TYPE_TIME_EXTEND || type == KBUFFER_TYPE_PADDING); | 
|---|
|  | 458 | +	} while (type == KBUFFER_TYPE_TIME_EXTEND || | 
|---|
|  | 459 | +		 type == KBUFFER_TYPE_TIME_STAMP || | 
|---|
|  | 460 | +		 type == KBUFFER_TYPE_PADDING); | 
|---|
| 458 | 461 |  | 
|---|
| 459 | 462 | return 0; | 
|---|
| 460 | 463 | } | 
|---|
| .. | .. | 
|---|
| 545 | 548 |  | 
|---|
| 546 | 549 | return 0; | 
|---|
| 547 | 550 | } | 
|---|
|  | 551 | + | 
|---|
|  | 552 | +/** | 
|---|
|  | 553 | + * kbuffer_subbuf_timestamp - read the timestamp from a sub buffer | 
|---|
|  | 554 | + * @kbuf:      The kbuffer to load | 
|---|
|  | 555 | + * @subbuf:    The subbuffer to read from. | 
|---|
|  | 556 | + * | 
|---|
|  | 557 | + * Return the timestamp from a subbuffer. | 
|---|
|  | 558 | + */ | 
|---|
|  | 559 | +unsigned long long kbuffer_subbuf_timestamp(struct kbuffer *kbuf, void *subbuf) | 
|---|
|  | 560 | +{ | 
|---|
|  | 561 | +	return kbuf->read_8(subbuf); | 
|---|
|  | 562 | +} | 
|---|
|  | 563 | + | 
|---|
|  | 564 | +/** | 
|---|
|  | 565 | + * kbuffer_ptr_delta - read the delta field from a record | 
|---|
|  | 566 | + * @kbuf:      The kbuffer to load | 
|---|
|  | 567 | + * @ptr:       The record in the buffe. | 
|---|
|  | 568 | + * | 
|---|
|  | 569 | + * Return the timestamp delta from a record | 
|---|
|  | 570 | + */ | 
|---|
|  | 571 | +unsigned int kbuffer_ptr_delta(struct kbuffer *kbuf, void *ptr) | 
|---|
|  | 572 | +{ | 
|---|
|  | 573 | +	unsigned int type_len_ts; | 
|---|
|  | 574 | + | 
|---|
|  | 575 | +	type_len_ts = read_4(kbuf, ptr); | 
|---|
|  | 576 | +	return ts4host(kbuf, type_len_ts); | 
|---|
|  | 577 | +} | 
|---|
|  | 578 | + | 
|---|
| 548 | 579 |  | 
|---|
| 549 | 580 | /** | 
|---|
| 550 | 581 | * kbuffer_read_event - read the next event in the kbuffer subbuffer | 
|---|
| .. | .. | 
|---|
| 727 | 758 | { | 
|---|
| 728 | 759 | return kbuf->start; | 
|---|
| 729 | 760 | } | 
|---|
|  | 761 | + | 
|---|
|  | 762 | +/** | 
|---|
|  | 763 | + * kbuffer_raw_get - get raw buffer info | 
|---|
|  | 764 | + * @kbuf:	The kbuffer | 
|---|
|  | 765 | + * @subbuf:	Start of mapped subbuffer | 
|---|
|  | 766 | + * @info:	Info descriptor to fill in | 
|---|
|  | 767 | + * | 
|---|
|  | 768 | + * For debugging. This can return internals of the ring buffer. | 
|---|
|  | 769 | + * Expects to have info->next set to what it will read. | 
|---|
|  | 770 | + * The type, length and timestamp delta will be filled in, and | 
|---|
|  | 771 | + * @info->next will be updated to the next element. | 
|---|
|  | 772 | + * The @subbuf is used to know if the info is passed the end of | 
|---|
|  | 773 | + * data and NULL will be returned if it is. | 
|---|
|  | 774 | + */ | 
|---|
|  | 775 | +struct kbuffer_raw_info * | 
|---|
|  | 776 | +kbuffer_raw_get(struct kbuffer *kbuf, void *subbuf, struct kbuffer_raw_info *info) | 
|---|
|  | 777 | +{ | 
|---|
|  | 778 | +	unsigned long long flags; | 
|---|
|  | 779 | +	unsigned long long delta; | 
|---|
|  | 780 | +	unsigned int type_len; | 
|---|
|  | 781 | +	unsigned int size; | 
|---|
|  | 782 | +	int start; | 
|---|
|  | 783 | +	int length; | 
|---|
|  | 784 | +	void *ptr = info->next; | 
|---|
|  | 785 | + | 
|---|
|  | 786 | +	if (!kbuf || !subbuf) | 
|---|
|  | 787 | +		return NULL; | 
|---|
|  | 788 | + | 
|---|
|  | 789 | +	if (kbuf->flags & KBUFFER_FL_LONG_8) | 
|---|
|  | 790 | +		start = 16; | 
|---|
|  | 791 | +	else | 
|---|
|  | 792 | +		start = 12; | 
|---|
|  | 793 | + | 
|---|
|  | 794 | +	flags = read_long(kbuf, subbuf + 8); | 
|---|
|  | 795 | +	size = (unsigned int)flags & COMMIT_MASK; | 
|---|
|  | 796 | + | 
|---|
|  | 797 | +	if (ptr < subbuf || ptr >= subbuf + start + size) | 
|---|
|  | 798 | +		return NULL; | 
|---|
|  | 799 | + | 
|---|
|  | 800 | +	type_len = translate_data(kbuf, ptr, &ptr, &delta, &length); | 
|---|
|  | 801 | + | 
|---|
|  | 802 | +	info->next = ptr + length; | 
|---|
|  | 803 | + | 
|---|
|  | 804 | +	info->type = type_len; | 
|---|
|  | 805 | +	info->delta = delta; | 
|---|
|  | 806 | +	info->length = length; | 
|---|
|  | 807 | + | 
|---|
|  | 808 | +	return info; | 
|---|
|  | 809 | +} | 
|---|