2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/statvfs.h>
24 #include <tzplatform_config.h>
30 #define SDCARD_NODE "sdcard"
32 #ifndef __USE_FILE_OFFSET64
33 int __WEAK__ storage_get_external_memory_size(struct statvfs *buf);
35 int __WEAK__ storage_get_external_memory_size64(struct statvfs *buf);
38 static dd_list *cb_list[STORAGE_CALLBACK_MAX];
40 static int sdcard_get_state(void)
44 ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &val);
49 case VCONFKEY_SYSMAN_MMC_MOUNTED:
50 return STORAGE_STATE_MOUNTED;
51 case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED:
52 return STORAGE_STATE_UNMOUNTABLE;
53 case VCONFKEY_SYSMAN_MMC_REMOVED:
58 return STORAGE_STATE_REMOVED;
61 static int sdcard_get_space(unsigned long long *total, unsigned long long *available)
63 storage_state_e state;
66 unsigned long long t = 0, a = 0;
68 state = sdcard_get_state();
69 if (state >= STORAGE_STATE_MOUNTED) {
70 #ifndef __USE_FILE_OFFSET64
71 ret = storage_get_external_memory_size(&s);
73 ret = storage_get_external_memory_size64(&s);
78 t = (unsigned long long)s.f_frsize*s.f_blocks;
79 a = (unsigned long long)s.f_bsize*s.f_bavail;
90 static const char *sdcard_get_root(void)
92 return tzplatform_mkpath(TZ_SYS_STORAGE, SDCARD_NODE);
95 static void sdcard_state_cb(keynode_t *key, void *data)
97 struct storage_cb_info *cb_info;
99 storage_state_e state;
101 state = sdcard_get_state();
103 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info)
104 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
107 static int register_request(enum storage_cb_type type)
110 case STORAGE_CALLBACK_STATE:
111 return vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
112 sdcard_state_cb, NULL);
120 static int release_request(enum storage_cb_type type)
123 case STORAGE_CALLBACK_STATE:
124 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
133 static int sdcard_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
135 struct storage_cb_info *cb_info;
139 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
145 /* check if it is the first request */
146 n = DD_LIST_LENGTH(cb_list[type]);
148 ret = register_request(type);
153 /* check for the same request */
154 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
155 if (cb_info->id == info->id &&
156 cb_info->state_cb == info->state_cb)
160 /* add device changed callback to list (local) */
161 cb_info = malloc(sizeof(struct storage_cb_info));
165 memcpy(cb_info, info, sizeof(struct storage_cb_info));
166 DD_LIST_APPEND(cb_list[type], cb_info);
171 static int sdcard_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
173 struct storage_cb_info *cb_info;
177 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
183 /* search for the same element with callback */
184 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
185 if (cb_info->id == info->id &&
186 cb_info->state_cb == info->state_cb)
193 /* remove device callback from list (local) */
194 DD_LIST_REMOVE(cb_list[type], cb_info);
197 /* check if this callback is last element */
198 n = DD_LIST_LENGTH(cb_list[type]);
200 ret = release_request(type);
208 const struct storage_ops sdcard = {
209 .type = STORAGE_TYPE_EXTERNAL,
210 .root = sdcard_get_root,
211 .get_state = sdcard_get_state,
212 .get_space = sdcard_get_space,
213 .register_cb = sdcard_register_cb,
214 .unregister_cb = sdcard_unregister_cb,
217 STORAGE_OPS_REGISTER(&sdcard)