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;
+}