4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyoungyoup Park <gynaru.park@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
27 #include <sys/utsname.h>
35 #include <user_request.h>
47 struct vnet_channel ipc0;
50 typedef gboolean(*cb_func)(GIOChannel *channel, GIOCondition condition, gpointer data);
52 static gboolean on_recv_ipc_message(GIOChannel *channel, GIOCondition condition, gpointer data);
54 static guint register_gio_watch(TcoreHal *p, int fd, void *callback);
56 static TReturn hal_power(TcoreHal *h, gboolean flag);
58 static void hex_dump(char *pad, int size, const void *data)
60 char buf[255] = {0, };
66 msg("%sno data", pad);
70 p = (unsigned char *)data;
72 snprintf(buf, 255, "%s%04X: ", pad, 0);
73 for (i = 0; i<size; i++) {
74 snprintf(hex, 4, "%02X ", p[i]);
77 if ((i + 1) % 8 == 0) {
78 if ((i + 1) % 16 == 0) {
81 snprintf(buf, 255, "%s%04X: ", pad, i + 1);
92 static void print_dump(unsigned short data_len, void *data)
98 msg(" \tlen=%d\t%s", data_len, (char *)data);
99 hex_dump(" ", data_len, data);
104 static gboolean _ipc0_init( TcoreHal *h, struct vnet_channel *ch, cb_func recv_message )
107 g_source_remove( ch->watch_id );
111 ch->fd = vnet_ipc0_open();
113 dbg("[ error ] vnet_ipc0_open()");
117 ch->watch_id = register_gio_watch(h, ch->fd, recv_message);
124 static void _ipc0_deinit( struct vnet_channel *ch )
126 g_source_remove( ch->watch_id );
135 static gboolean _silent_reset( TcoreHal *h )
137 dbg("[ error ] cp crash : strat silent reset");
138 tcore_hal_set_power_state(h, FALSE);
140 dbg("[ error ] do nothing.");
141 #if 0 // this is not applicable code, now silent reset is not guaranteed ( 2012, 04, 19 )
143 vnet_start_cp_reset();
145 if ( !hal_power( h, TRUE ) ) {
146 dbg("[ check ] cp crash : silent reset done");
155 static gboolean _do_exception_operation( TcoreHal *h, int fd, GIOCondition con )
158 struct custom_data *user_data = tcore_hal_ref_user_data( h );
164 state = vnet_get_cp_state( fd );
166 dbg("[ error ] vnet_get_cp_state()");
170 switch ( (enum vnet_cp_state)state ) {
171 case VNET_CP_STATE_CRASH_EXIT: {
172 dbg("[ error ] cp crash : strat ramdump");
173 _ipc0_deinit( &user_data->ipc0 );
174 vnet_start_cp_ramdump();
176 state = VNET_CP_STATE_CRASH_RESET;
181 case VNET_CP_STATE_CRASH_RESET: {
183 _ipc0_deinit( &user_data->ipc0 );
185 if (tcore_hal_get_power_state( h )) {
187 state = VNET_CP_STATE_CRASH_RESET;
189 if ( !_silent_reset( h ) ) {
190 dbg("[ error ] _silent_reset()");
196 * if current hal power state is FALSE, 'cp_reset' mean normal power off
197 * ( it's because of kernel concept )
199 state = VNET_CP_STATE_OFFLINE;
204 dbg("useless state, state : (0x%x)", state);
215 dbg("[ error ] unknown problem, con : (0x%x)", con);
220 tcore_hal_emit_recv_callback(h, sizeof(int), &state);
227 static gboolean _power_on( gpointer data )
229 struct custom_data *user_data = 0;
230 TcoreHal *h = (TcoreHal*)data;
232 static int count = 0;
234 user_data = tcore_hal_ref_user_data(h);
236 dbg("[ error ] tcore_hal_ref_user_data()");
242 ret = _ipc0_init( h, &user_data->ipc0, on_recv_ipc_message );
244 dbg("[ error ] _ipc0_init()");
247 dbg("[ error ] _ipc0_init() timeout");
254 tcore_hal_set_power_state(h, TRUE);
259 static TReturn hal_power(TcoreHal *h, gboolean flag)
262 /* power off not support */
263 return TCORE_RETURN_FAILURE;
266 g_timeout_add_full( G_PRIORITY_HIGH, 500, _power_on, h, 0 );
268 return TCORE_RETURN_SUCCESS;
271 static TReturn hal_send(TcoreHal *h, unsigned int data_len, void *data)
274 struct custom_data *user_data;
276 if (tcore_hal_get_power_state(h) == FALSE)
277 return TCORE_RETURN_FAILURE;
279 user_data = tcore_hal_ref_user_data(h);
281 return TCORE_RETURN_FAILURE;
283 dbg("write (fd=%d, len=%d)", user_data->ipc0.fd, data_len);
285 ret = write( user_data->ipc0.fd, (guchar *) data, data_len );
287 return TCORE_RETURN_FAILURE;
289 return TCORE_RETURN_SUCCESS;;
292 static struct tcore_hal_operations hops =
298 static gboolean on_recv_ipc_message(GIOChannel *channel, GIOCondition condition, gpointer data)
301 struct custom_data *custom;
303 #define BUF_LEN_MAX 4096
304 char buf[BUF_LEN_MAX];
307 custom = tcore_hal_ref_user_data(h);
309 if ( condition != G_IO_IN ) {
310 dbg("[ error ] svnet has a problem");
311 return _do_exception_operation( h, custom->ipc0.fd, condition );
314 memset(buf, 0, BUF_LEN_MAX);
316 n = read(custom->ipc0.fd, (guchar *) buf, BUF_LEN_MAX);
318 err("read error. return_valute = %d", n);
322 msg("--[RECV]-------------------------");
323 dbg("recv (len = %d)", n);
325 tcore_hal_emit_recv_callback(h, n, buf);
326 msg("--[RECV FINISH]------------------\n");
328 /* Notice: Mode of any HAL is TCORE_HAL_MODE_AT as default. */
329 tcore_hal_dispatch_response_data(h, 0, n, buf);
334 static guint register_gio_watch(TcoreHal *h, int fd, void *callback)
336 GIOChannel *channel = NULL;
339 if (fd < 0 || !callback)
342 channel = g_io_channel_unix_new(fd);
343 source = g_io_add_watch(channel, G_IO_IN | G_IO_HUP, (GIOFunc) callback, h);
344 g_io_channel_unref(channel);
350 static gboolean on_load()
353 char *vnet_models[] = { "SMDK4410", "SMDK4212", "SLP_PQ", "SLP_PQ_LTE", "SLP_NAPLES", "REDWOOD", "TRATS", NULL };
356 memset(&u, 0, sizeof(struct utsname));
359 dbg("u.nodename: [%s]", u.nodename);
361 for (i = 0; vnet_models[i]; i++ ) {
362 if (!g_strcmp0(u.nodename, vnet_models[i])) {
368 * Not supported model
369 * - unload this plugin.
375 static gboolean on_init(TcorePlugin *p)
378 struct custom_data *data;
385 data = calloc(sizeof(struct custom_data), 1);
386 memset(data, 0, sizeof(struct custom_data));
392 h = tcore_hal_new(p, "6262", &hops, TCORE_HAL_MODE_AT);
394 tcore_hal_set_power_state(h, FALSE);
395 tcore_hal_link_user_data(h, data);
400 static void on_unload(TcorePlugin *p)
408 struct tcore_plugin_define_desc plugin_define_desc =
411 .priority = TCORE_PLUGIN_PRIORITY_HIGH,