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>
29 #define SDCARD_PATH "/opt/storage/sdcard"
31 #ifndef __USE_FILE_OFFSET64
32 int __WEAK__ storage_get_external_memory_size(struct statvfs *buf);
34 int __WEAK__ storage_get_external_memory_size64(struct statvfs *buf);
37 static dd_list *cb_list[STORAGE_CALLBACK_MAX];
39 static int sdcard_get_state(void)
43 ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &val);
48 case VCONFKEY_SYSMAN_MMC_MOUNTED:
49 return STORAGE_STATE_MOUNTED;
50 case VCONFKEY_SYSMAN_MMC_INSERTED_NOT_MOUNTED:
51 return STORAGE_STATE_UNMOUNTABLE;
52 case VCONFKEY_SYSMAN_MMC_REMOVED:
57 return STORAGE_STATE_REMOVED;
60 static int sdcard_get_space(unsigned long long *total, unsigned long long *available)
62 storage_state_e state;
65 unsigned long long t = 0, a = 0;
67 state = sdcard_get_state();
68 if (state >= STORAGE_STATE_MOUNTED) {
69 #ifndef __USE_FILE_OFFSET64
70 ret = storage_get_external_memory_size(&s);
72 ret = storage_get_external_memory_size64(&s);
77 t = (unsigned long long)s.f_frsize*s.f_blocks;
78 a = (unsigned long long)s.f_bsize*s.f_bavail;
89 static const char *sdcard_get_root(void)
94 static void sdcard_state_cb(keynode_t *key, void *data)
96 struct storage_cb_info *cb_info;
98 storage_state_e state;
100 state = sdcard_get_state();
102 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info)
103 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
106 static int register_request(enum storage_cb_type type)
109 case STORAGE_CALLBACK_STATE:
110 return vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
111 sdcard_state_cb, NULL);
119 static int release_request(enum storage_cb_type type)
122 case STORAGE_CALLBACK_STATE:
123 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
132 static int sdcard_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
134 struct storage_cb_info *cb_info;
138 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
144 /* check if it is the first request */
145 n = DD_LIST_LENGTH(cb_list[type]);
147 ret = register_request(type);
152 /* check for the same request */
153 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
154 if (cb_info->id == info->id &&
155 cb_info->state_cb == info->state_cb)
159 /* add device changed callback to list (local) */
160 cb_info = malloc(sizeof(struct storage_cb_info));
164 memcpy(cb_info, info, sizeof(struct storage_cb_info));
165 DD_LIST_APPEND(cb_list[type], cb_info);
170 static int sdcard_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
172 struct storage_cb_info *cb_info;
176 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
182 /* search for the same element with callback */
183 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
184 if (cb_info->id == info->id &&
185 cb_info->state_cb == info->state_cb)
192 /* remove device callback from list (local) */
193 DD_LIST_REMOVE(cb_list[type], cb_info);
196 /* check if this callback is last element */
197 n = DD_LIST_LENGTH(cb_list[type]);
199 ret = release_request(type);
207 const struct storage_ops sdcard = {
208 .type = STORAGE_TYPE_EXTERNAL,
209 .root = sdcard_get_root,
210 .get_state = sdcard_get_state,
211 .get_space = sdcard_get_space,
212 .register_cb = sdcard_register_cb,
213 .unregister_cb = sdcard_unregister_cb,
216 STORAGE_OPS_REGISTER(&sdcard)