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;
66 state = sdcard_get_state();
67 if (state < STORAGE_STATE_MOUNTED) {
70 } else { /* if sdcard is mounted */
71 #ifndef __USE_FILE_OFFSET64
72 ret = storage_get_external_memory_size(&s);
74 ret = storage_get_external_memory_size64(&s);
79 t = (unsigned long long)s.f_frsize*s.f_blocks;
80 a = (unsigned long long)s.f_bsize*s.f_bavail;
91 static const char *sdcard_get_root(void)
96 static void sdcard_state_cb(keynode_t *key, void *data)
98 struct storage_cb_info *cb_info;
100 storage_state_e state;
102 state = sdcard_get_state();
104 DD_LIST_FOREACH(cb_list[STORAGE_CALLBACK_STATE], elem, cb_info)
105 cb_info->state_cb(cb_info->id, state, cb_info->user_data);
108 static int register_request(enum storage_cb_type type)
111 case STORAGE_CALLBACK_STATE:
112 return vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
113 sdcard_state_cb, NULL);
121 static int release_request(enum storage_cb_type type)
124 case STORAGE_CALLBACK_STATE:
125 return vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
134 static int sdcard_register_cb(enum storage_cb_type type, struct storage_cb_info *info)
136 struct storage_cb_info *cb_info;
140 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
146 /* check if it is the first request */
147 n = DD_LIST_LENGTH(cb_list[type]);
149 ret = register_request(type);
154 /* check for the same request */
155 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
156 if (cb_info->id == info->id &&
157 cb_info->state_cb == info->state_cb)
161 /* add device changed callback to list (local) */
162 cb_info = malloc(sizeof(struct storage_cb_info));
166 memcpy(cb_info, info, sizeof(struct storage_cb_info));
167 DD_LIST_APPEND(cb_list[type], cb_info);
172 static int sdcard_unregister_cb(enum storage_cb_type type, struct storage_cb_info *info)
174 struct storage_cb_info *cb_info;
178 if (type < 0 || type >= STORAGE_CALLBACK_MAX)
184 /* search for the same element with callback */
185 DD_LIST_FOREACH(cb_list[type], elem, cb_info) {
186 if (cb_info->id == info->id &&
187 cb_info->state_cb == info->state_cb)
194 /* remove device callback from list (local) */
195 DD_LIST_REMOVE(cb_list[type], cb_info);
198 /* check if this callback is last element */
199 n = DD_LIST_LENGTH(cb_list[type]);
201 ret = release_request(type);
209 const struct storage_ops sdcard = {
210 .type = STORAGE_TYPE_EXTERNAL,
211 .root = sdcard_get_root,
212 .get_state = sdcard_get_state,
213 .get_space = sdcard_get_space,
214 .register_cb = sdcard_register_cb,
215 .unregister_cb = sdcard_unregister_cb,
218 STORAGE_OPS_REGISTER(&sdcard)