auto import from //depot/cupcake/@135843
diff --git a/vold/media.c b/vold/media.c
new file mode 100644
index 0000000..40637ff
--- /dev/null
+++ b/vold/media.c
@@ -0,0 +1,165 @@
+
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include <sys/types.h>
+
+#include "vold.h"
+#include "media.h"
+
+static media_list_t *list_root = NULL;
+
+media_t *media_create(char *devpath, char *name, char *serial, media_type_t type)
+{
+ media_list_t *list_entry;
+ media_t *new;
+
+ if (!(new = malloc(sizeof(media_t))))
+ return NULL;
+
+ memset(new, 0, sizeof(media_t));
+
+ if (!(list_entry = malloc(sizeof(media_list_t)))) {
+ free(new);
+ return NULL;
+ }
+ list_entry->media = new;
+ list_entry->next = NULL;
+
+ if (!list_root)
+ list_root = list_entry;
+ else {
+ media_list_t *list_scan = list_root;
+ while(list_scan->next)
+ list_scan = list_scan->next;
+ list_scan->next = list_entry;
+ }
+
+ new->devpath = strdup(devpath);
+ new->name = strdup(name);
+ if (!serial)
+ new->serial = 0;
+ else
+ new->serial = strtoul(serial, NULL, 0);
+
+ new->media_type = type;
+
+ return new;
+}
+
+void media_destroy(media_t *media)
+{
+ media_list_t *list_next;
+
+ if (list_root->media == media) {
+ list_next = list_root->next;
+ free(list_root);
+ list_root = list_next;
+ } else {
+ media_list_t *list_scan = list_root;
+ while (list_scan->next->media != media)
+ list_scan = list_scan -> next;
+ list_next = list_scan->next->next;
+ free(list_scan->next);
+ list_scan->next = list_next;
+ }
+
+ free(media->devpath);
+ free(media->name);
+
+ while(media->devs)
+ media_remove_blkdev(media, media->devs->dev);
+ free(media);
+}
+
+media_t *media_lookup_by_path(char *devpath, boolean fuzzy_match)
+{
+ media_list_t *list_scan = list_root;
+
+ while (list_scan) {
+ if (fuzzy_match) {
+ if (!strncmp(list_scan->media->devpath, devpath, strlen(devpath)))
+ return list_scan->media;
+ } else {
+ if (!strcmp(list_scan->media->devpath, devpath))
+ return list_scan->media;
+ }
+ list_scan = list_scan->next;
+ }
+#if DEBUG_MEDIA
+ LOG_VOL("media_lookup_by_path(): No media found @ %s", devpath);
+#endif
+ return NULL;
+}
+
+int media_add_blkdev(media_t *card, blkdev_t *dev)
+{
+ blkdev_list_t *list_entry;
+
+ if (!(list_entry = malloc(sizeof(blkdev_list_t)))) {
+ LOGE("Out of memory");
+ return -ENOMEM;
+ }
+
+ list_entry->next = NULL;
+ list_entry->dev = dev;
+ if (!card->devs)
+ card->devs = list_entry;
+ else {
+ blkdev_list_t *scan = card->devs;
+
+ while(scan->next)
+ scan = scan->next;
+
+ scan->next = list_entry;
+ }
+ return 0;
+}
+
+void media_remove_blkdev(media_t *card, blkdev_t *dev)
+{
+ if (card->devs->dev == dev)
+ card->devs = card->devs->next;
+ else {
+ blkdev_list_t *scan = card->devs;
+ while (scan->next->dev != dev)
+ scan = scan -> next;
+ blkdev_list_t *next = scan->next->next;
+ free(scan->next);
+ scan->next = next;
+ }
+}
+
+media_t *media_lookup_by_dev(blkdev_t *dev)
+{
+ media_list_t *media_scan = list_root;
+
+ while (media_scan) {
+ blkdev_list_t *blk_scan = media_scan->media->devs;
+ while (blk_scan) {
+ if (blk_scan->dev == dev)
+ return media_scan->media;
+ blk_scan = blk_scan->next;
+ }
+ media_scan = media_scan->next;
+ }
+ return NULL;
+}