b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | /****************************************************************************** |
| 2 | *(C) Copyright 2013 Marvell International Ltd. |
| 3 | * All Rights Reserved |
| 4 | ******************************************************************************/ |
| 5 | /*-------------------------------------------------------------------------------------------------------------------- |
| 6 | * ------------------------------------------------------------------------------------------------------------------- |
| 7 | * |
| 8 | * Filename: iml_api.c |
| 9 | * |
| 10 | * Description: The APIs to handle IML log. |
| 11 | * |
| 12 | * History: |
| 13 | * Dec, 13 2013 - Zhongmin Wu(zmwu@marvell.com) Creation of file |
| 14 | * |
| 15 | * Notes: |
| 16 | * |
| 17 | ******************************************************************************/ |
| 18 | |
| 19 | #include <unistd.h> |
| 20 | #include <stdlib.h> |
| 21 | #include <fcntl.h> |
| 22 | #include <pthread.h> |
| 23 | #include <errno.h> |
| 24 | #include <termios.h> |
| 25 | #include <sys/mman.h> |
| 26 | #include <string.h> |
| 27 | |
| 28 | #include "utlEventHandler.h" |
| 29 | #include "pxa_dbg.h" |
| 30 | |
| 31 | |
| 32 | #include "iml_config.h" |
| 33 | #include "iml_api.h" |
| 34 | #include "iml_state_machine.h" |
| 35 | #include "media_manager.h" |
| 36 | |
| 37 | #define IML_DEV_PATH "/dev/imldev0" |
| 38 | |
| 39 | #define BLOCK_SIZE 8192 |
| 40 | #define SEGMENT_NUM 512 |
| 41 | |
| 42 | struct ring_ctl_head{ |
| 43 | int block_number; |
| 44 | int read_index; |
| 45 | int write_index; |
| 46 | int u_write_index; |
| 47 | int signature; |
| 48 | char stuff[BLOCK_SIZE - 5 * sizeof(int)]; |
| 49 | char data[0]; |
| 50 | }; |
| 51 | |
| 52 | |
| 53 | |
| 54 | static utlEventHandlerId_T IMLDevHandler; |
| 55 | static int IMLDevfd = -1; |
| 56 | |
| 57 | static char * iml_ring_buff; |
| 58 | |
| 59 | |
| 60 | static int get_next_read_block(struct ring_ctl_head *head) |
| 61 | { |
| 62 | return head->read_index + 1 == head->block_number ? 0 |
| 63 | : head->read_index + 1; |
| 64 | } |
| 65 | |
| 66 | |
| 67 | static int get_free_read_blocks(struct ring_ctl_head *head) |
| 68 | { |
| 69 | int free = head->read_index - head->u_write_index; |
| 70 | if(free < 0) |
| 71 | { |
| 72 | free += head->block_number; |
| 73 | } |
| 74 | return free; |
| 75 | } |
| 76 | |
| 77 | static void * block_to_addr(int block) |
| 78 | { |
| 79 | struct ring_ctl_head * head = (struct ring_ctl_head * )iml_ring_buff; |
| 80 | return block * BLOCK_SIZE + head->data; |
| 81 | } |
| 82 | |
| 83 | static int read_data(void) |
| 84 | { |
| 85 | struct ring_ctl_head * head = (struct ring_ctl_head * )iml_ring_buff; |
| 86 | int ret; |
| 87 | int block; |
| 88 | int count = 0; |
| 89 | while(get_free_read_blocks(head) > 0) |
| 90 | { |
| 91 | block = get_next_read_block(head); |
| 92 | //DBGMSG("Send block %d to Meida\n", block); |
| 93 | ret = SendMediadata(block_to_addr(block),BLOCK_SIZE); |
| 94 | |
| 95 | if(ret != BLOCK_SIZE) |
| 96 | ERRMSG("Data Send to Media error"); |
| 97 | else if(ret > 0) |
| 98 | count += ret; |
| 99 | head->read_index = block; |
| 100 | } |
| 101 | return count; |
| 102 | } |
| 103 | static utlReturnCode_T ReceiveDataFromMSA(const utlEventHandlerType_T handler_type UNUSED, |
| 104 | const utlEventHandlerType_T event_type UNUSED, |
| 105 | const int fd UNUSED, |
| 106 | const utlRelativeTime_P2c period_p UNUSED, |
| 107 | void *arg_p UNUSED) |
| 108 | { |
| 109 | int ret = 0; |
| 110 | unsigned long total = 0; |
| 111 | total = read_data(); |
| 112 | // DBGMSG("Read %d bytes this time\n", total); |
| 113 | return utlSUCCESS; |
| 114 | } |
| 115 | |
| 116 | |
| 117 | int openIMLPort(int ddr) |
| 118 | { |
| 119 | F_ENTER(); |
| 120 | int fd, flag; |
| 121 | if(ddr) |
| 122 | flag = O_WRONLY; |
| 123 | else |
| 124 | flag = O_RDWR; |
| 125 | fd = open(imlConfig.sys_settings.diag_port, flag); |
| 126 | if(fd < 0) |
| 127 | { |
| 128 | ERRMSG("open %s error %s\n", IML_DEV_PATH, strerror(errno)); |
| 129 | return fd; |
| 130 | } |
| 131 | |
| 132 | IMLDevfd = fd; |
| 133 | if(!ddr) |
| 134 | { |
| 135 | iml_ring_buff = mmap(NULL,BLOCK_SIZE*SEGMENT_NUM,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); |
| 136 | if(MAP_FAILED == iml_ring_buff) |
| 137 | { |
| 138 | iml_ring_buff = NULL; |
| 139 | ERRMSG("mmap %s error %s\n", IML_DEV_PATH, strerror(errno)); |
| 140 | } |
| 141 | else |
| 142 | { |
| 143 | struct ring_ctl_head * head = (struct ring_ctl_head *)iml_ring_buff; |
| 144 | DBGMSG("iml ring head (%d): signature:%x, block number : %d, rang %p -> %p", |
| 145 | sizeof(struct ring_ctl_head), head->signature, head->block_number, |
| 146 | iml_ring_buff, iml_ring_buff + BLOCK_SIZE*SEGMENT_NUM); |
| 147 | IMLDevHandler = utlSetFdEventHandler(utlEVENT_HANDLER_TYPE_READ, utlEVENT_HANDLER_PRIORITY_LOW, IMLDevfd, ReceiveDataFromMSA, NULL); |
| 148 | } |
| 149 | } |
| 150 | F_LEAVE(); |
| 151 | return 0; |
| 152 | } |
| 153 | |
| 154 | int closeIMLPort(void) |
| 155 | { |
| 156 | F_ENTER(); |
| 157 | if(iml_ring_buff) |
| 158 | { |
| 159 | utlDeleteEventHandler(IMLDevHandler); |
| 160 | munmap(iml_ring_buff, BLOCK_SIZE*SEGMENT_NUM); |
| 161 | iml_ring_buff = NULL; |
| 162 | } |
| 163 | close(IMLDevfd); |
| 164 | IMLDevfd = -1; |
| 165 | F_LEAVE(); |
| 166 | return 0; |
| 167 | } |
| 168 | |
| 169 | void InitIML(void) |
| 170 | { |
| 171 | F_ENTER(); |
| 172 | InitIMLMachine(); |
| 173 | F_LEAVE(); |
| 174 | } |
| 175 | |
| 176 | |