[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 11/11] cdi/storage: Auf LIOv2 umstellen



* cdi/storage: Das alte RPC-Interface durch einen LIOv2-Userspace-
  Service ersetzt.

  FIXME: CD-ROM ist jetzt kaputt.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/cdi/ata/device.c          |    1 +
 src/modules/cdi/floppy/device.c       |    1 +
 src/modules/cdi/include/cdi-osdep.h   |    5 +
 src/modules/cdi/include/cdi/storage.h |    7 +
 src/modules/cdi/lib/cdi.c             |    9 ++-
 src/modules/cdi/lib/scsi/disk.c       |   13 ++
 src/modules/cdi/lib/storage.c         |  225 ++++++++++++++++-----------------
 7 files changed, 144 insertions(+), 117 deletions(-)

diff --git a/src/modules/cdi/ata/device.c b/src/modules/cdi/ata/device.c
index 9afa102..baedd72 100644
--- a/src/modules/cdi/ata/device.c
+++ b/src/modules/cdi/ata/device.c
@@ -234,6 +234,7 @@ void ata_init_controller(struct ata_controller* controller)
             if (dev->atapi == 0) {
 #endif
                 dev->dev.storage.block_size = ATA_SECTOR_SIZE;
+                dev->dev.storage.optimal_count = 128;
 
                 // Handler setzen
                 dev->read_sectors = ata_drv_read_sectors;
diff --git a/src/modules/cdi/floppy/device.c b/src/modules/cdi/floppy/device.c
index c5c75a5..5c17a38 100755
--- a/src/modules/cdi/floppy/device.c
+++ b/src/modules/cdi/floppy/device.c
@@ -801,6 +801,7 @@ void floppy_init_device(struct cdi_device* device)
 
     dev->dev.block_size = FLOPPY_SECTOR_SIZE(dev);
     dev->dev.block_count = FLOPPY_SECTOR_COUNT(dev);
+    dev->dev.optimal_count = 1;
 
     cdi_storage_device_init(&dev->dev);
 }
diff --git a/src/modules/cdi/include/cdi-osdep.h b/src/modules/cdi/include/cdi-osdep.h
index 5bb3827..ed8cc5d 100644
--- a/src/modules/cdi/include/cdi-osdep.h
+++ b/src/modules/cdi/include/cdi-osdep.h
@@ -12,6 +12,7 @@
 #define _CDI_OSDEP_H_
 
 #include <stdio.h>
+#include <lostio.h>
 
 #define CDI_STANDALONE
 #define TYNDUR
@@ -92,4 +93,8 @@ typedef struct {
     FILE* device;
 } cdi_fs_osdep;
 
+struct storage_drv_osdep {
+    struct lio_resource* root;
+};
+
 #endif
diff --git a/src/modules/cdi/include/cdi/storage.h b/src/modules/cdi/include/cdi/storage.h
index c60e43c..46f2355 100644
--- a/src/modules/cdi/include/cdi/storage.h
+++ b/src/modules/cdi/include/cdi/storage.h
@@ -77,6 +77,11 @@ struct cdi_storage_device {
      * \endenglish
      */
     uint64_t            block_count;
+
+    /**
+     * Beste Request-Groesse beim Lesen und Schreiben (Anzahl Blocks).
+     */
+    size_t              optimal_count;
 };
 
 /**
@@ -140,6 +145,8 @@ struct cdi_storage_driver {
      */
     int (*write_blocks)(struct cdi_storage_device* device, uint64_t start,
         uint64_t count, void* buffer);
+
+    struct storage_drv_osdep osdep;
 };
 
 #ifdef __cplusplus
diff --git a/src/modules/cdi/lib/cdi.c b/src/modules/cdi/lib/cdi.c
index dd6e144..42a5ef0 100644
--- a/src/modules/cdi/lib/cdi.c
+++ b/src/modules/cdi/lib/cdi.c
@@ -185,7 +185,8 @@ static void cdi_tyndur_run_drivers(void)
 
     // Warten auf Ereignisse
     while (1) {
-        wait_for_rpc();
+        lio_dispatch();
+        lio_srv_wait();
     }
 }
 
@@ -232,6 +233,12 @@ void cdi_driver_register(struct cdi_driver* driver)
     }
 }
 
+/** Gibt eine Liste aller Treiber zurueck */
+list_t* cdi_tyndur_get_drivers(void)
+{
+    return drivers;
+}
+
 /**
  * Wenn main nicht von einem Treiber ueberschrieben wird, ist hier der
  * Einsprungspunkt. Die Standardfunktion ruft nur cdi_init() auf. Treiber, die
diff --git a/src/modules/cdi/lib/scsi/disk.c b/src/modules/cdi/lib/scsi/disk.c
index e0eca2e..0e2534e 100644
--- a/src/modules/cdi/lib/scsi/disk.c
+++ b/src/modules/cdi/lib/scsi/disk.c
@@ -42,6 +42,7 @@ static int cdi_scsi_disk_write(struct cdi_storage_device* device,
 
 struct cdi_storage_driver cdi_scsi_disk_driver = {
     .drv = {
+        .name       = "scsidisk",
         .type       = CDI_STORAGE,
     },
     .read_blocks    = cdi_scsi_disk_read,
@@ -226,11 +227,23 @@ static int cdi_scsi_disk_write(struct cdi_storage_device* device,
     return -1;
 }
 
+static void driver_init(void)
+{
+    static int initialised = 0;
+
+    if (!initialised) {
+        cdi_driver_register(&cdi_scsi_disk_driver.drv);
+        cdi_storage_driver_init(&cdi_scsi_disk_driver);
+    }
+}
+
 int cdi_scsi_disk_init(struct cdi_scsi_device* device)
 {
     struct cdi_storage_device* frontdev;
     uint32_t num_sectors = 0, sector_size = 0;
 
+    driver_init();
+
     if (cdrom_init(device)) {
         return -1;
     }
diff --git a/src/modules/cdi/lib/storage.c b/src/modules/cdi/lib/storage.c
index fbf2edc..15d51d3 100644
--- a/src/modules/cdi/lib/storage.c
+++ b/src/modules/cdi/lib/storage.c
@@ -17,37 +17,45 @@
 #include "cdi/storage.h"
 #include "libpartition.h"
 
-static void lostio_mst_if_init(void);
 int lostio_mst_if_newdev(struct partition* part);
 
-static size_t lostio_mst_read_handler(lostio_filehandle_t* fh,
-    void* buf, size_t blocksize, size_t blockcount);
-static size_t lostio_mst_write_handler(lostio_filehandle_t* fh,
-    size_t blocksize, size_t blockcount, void* data);
-static int lostio_mst_seek_handler(lostio_filehandle_t* fh, uint64_t offset,
-    int origin);
-
-#define CDI_LOSTIO_TYPE_MST 255
-static typehandle_t lostio_mst_typehandle = {
-    .id = CDI_LOSTIO_TYPE_MST,
-
-    .pre_open = NULL,
-    .post_open = NULL,
-    .not_found = NULL,
-    .close = NULL,
-
-    .read = lostio_mst_read_handler,
-    .write = lostio_mst_write_handler,
-    .seek = lostio_mst_seek_handler
-};
+static int read(struct lio_resource* res, uint64_t offset,
+    size_t size, void* buf);
+static int write(struct lio_resource* res, uint64_t offset,
+    size_t size, void* buf);
+static struct lio_resource* load_root(struct lio_tree* tree);
+static int load_children(struct lio_resource* res);
+int cdi_storage_read(struct cdi_storage_device* device, uint64_t pos,
+    size_t size, void* dest);
 
 /**
  * Initialisiert die Datenstrukturen fuer einen Massenspeichertreiber
  */
 void cdi_storage_driver_init(struct cdi_storage_driver* driver)
 {
+    struct lio_resource* res;
+    struct lio_service* service;
+
     driver->drv.type = CDI_STORAGE;
     cdi_driver_init((struct cdi_driver*) driver);
+
+    res = lio_resource_create(NULL);
+    res->browsable = 1;
+    res->blocksize = 1024;
+    driver->osdep.root = res;
+
+    service = malloc(sizeof(*service));
+    *service = (struct lio_service) {
+        .name               = driver->drv.name,
+        .lio_ops = {
+            .load_root      = load_root,
+            .load_children  = load_children,
+            .read           = read,
+            .write          = write,
+        },
+    };
+
+    lio_add_service(service);
 }
 
 /**
@@ -63,12 +71,6 @@ void cdi_storage_driver_destroy(struct cdi_storage_driver* driver)
  */
 void cdi_storage_driver_register(struct cdi_storage_driver* driver)
 {
-    static int initialized = 0;
-
-    if (initialized == 0) {
-        lostio_mst_if_init();
-        initialized = 1;
-    }
 }
 
 /**
@@ -212,140 +214,131 @@ int cdi_storage_write(struct cdi_storage_device* device, uint64_t pos,
     return 0;
 }
 
-
-/**
- * Initialisiert die Massenspeichernschnittstelle fuer LostIO
- */
-static void lostio_mst_if_init()
-{
-    lostio_register_typehandle(&lostio_mst_typehandle);
-}
-
 /**
  * Erstellt den Dateisystemknoten fuer ein Geraet.
  */
 int lostio_mst_if_newdev(struct partition* part)
 {
-    static int has_cdrom = 0;
+//    static int has_cdrom = 0;
     struct cdi_storage_device* device = part->dev;
+    struct cdi_storage_driver* driver = (void*) device->dev.driver;
+    struct lio_resource* res;
 
-    // Slash vor Pfad anhaengen
+    // Dateinamen erzeugen
     char* path;
     if (part->number == (uint16_t) -1) {
-        asprintf(&path, "/%s", device->dev.name);
+        asprintf(&path, "%s", device->dev.name);
     } else {
-        asprintf(&path, "/%s_p%d", device->dev.name, part->number);
+        asprintf(&path, "%s_p%d", device->dev.name, part->number);
     }
 
-    if (vfstree_create_node(path, CDI_LOSTIO_TYPE_MST, device->block_size *
-        device->block_count, (void*) part, 0) == false)
-    {
-        free(path);
-        return -1;
-    }
+    // Neue Ressource anlegen
+    res = lio_resource_create(NULL);
+    res->readable = 1;
+    res->writable = 1;
+    res->seekable = 1;
+    res->blocksize = device->block_size;
+    res->size = part->size;
+    res->opaque = part;
 
+    lio_node_create(driver->osdep.root, res, path);
+    free(path);
+
+#if 0
+    // TODO
     if (!has_cdrom && !strncmp(device->dev.name, "atapi", strlen("atapi"))) {
         has_cdrom = 1;
         vfstree_create_node("/cdrom", CDI_LOSTIO_TYPE_MST, device->block_size *
             device->block_count, (void*) part, 0);
     }
+#endif
 
-    free(path);
     return 0;
 }
 
-/**
- * Lesehandler fuer LostIO
- */
-static size_t lostio_mst_read_handler(lostio_filehandle_t* fh,
-    void* buf, size_t blocksize, size_t blockcount)
+
+extern list_t* cdi_tyndur_get_drivers(void);
+static struct lio_resource* load_root(struct lio_tree* tree)
 {
-    struct partition* part = (struct partition*) fh->node->data;
-    struct cdi_storage_device* device = part->dev;
-    size_t size = blocksize * blockcount;
+    list_t* drivers = cdi_tyndur_get_drivers();
+    struct cdi_driver* drv;
+    int i;
 
-    // Groesse anpassen, wenn ueber das Medium hinaus gelesen werden soll
-    if (size > (part->size - fh->pos)) {
-        size = part->size - fh->pos;
-        if (size == 0) {
-            fh->flags |= LOSTIO_FLAG_EOF;
-            return 0;
-        }
+    if (tree->source != -1) {
+        return NULL;
     }
 
-    // In den uebergebenen Buffer einlesen
-    if (cdi_storage_read(device, fh->pos + part->start, size, buf) != 0) {
-        return 0;
+    for (i = 0; (drv = list_get_element_at(drivers, i)); i++) {
+        if (drv->type == CDI_STORAGE) {
+            struct cdi_storage_driver* sdrv = (void*) drv;
+            if (!strcmp(tree->service->name, drv->name)) {
+                struct lio_resource* root = sdrv->osdep.root;
+                root->tree = tree;
+                lio_resource_modified(root);
+                return root;
+            }
+        }
     }
 
-    fh->pos += size;
+    return NULL;
+}
+
+static int load_children(struct lio_resource* root)
+{
+    struct lio_node* it;
+    int j;
+
+    for (j = 0; (it = list_get_element_at(root->children, j)); j++)
+    {
+        it->res->tree = root->tree;
+        lio_resource_modified(it->res);
+        lio_srv_node_add(root->server.id, it->res->server.id,
+            it->name);
+    }
 
-    return size;
+    return 0;
 }
 
+#define NUM_BLOCKS(x) (((x) + res->blocksize - 1) / res->blocksize)
+
 /**
- * Schreibhandler fuer LostIO
+ * Lesehandler fuer LostIO
  */
-static size_t lostio_mst_write_handler(lostio_filehandle_t* fh,
-    size_t blocksize, size_t blockcount, void* data)
+static int read(struct lio_resource* res, uint64_t offset,
+    size_t size, void* buf)
 {
-    struct partition* part = (struct partition*) fh->node->data;
+    struct partition* part = res->opaque;
     struct cdi_storage_device* device = part->dev;
-    size_t size = blocksize * blockcount;
-    size_t result = size;
+    int result;
 
-    // Groesse anpassen, wenn ueber das Medium hinaus geschrieben werden soll
-    if (size > (part->size - fh->pos)) {
-        size = part->size - fh->pos;
+    // Groesse anpassen, wenn ueber das Medium hinaus gelesen werden soll
+    if (size > (part->size - offset)) {
+        size = part->size - offset;
     }
 
-    // Daten schreiben
-    if (cdi_storage_write(device, fh->pos + part->start, size, data) != 0) {
-        result = 0;
-    } else {
-        fh->pos += size;
-    }
+    // In den uebergebenen Buffer einlesen
+    result = cdi_storage_read(device, offset + part->start, size, buf);
 
-    return result;
+    return (result ? -1 : 0);
 }
 
 /**
- * Seek-Handler fuer LostIO
+ * Schreibhandler fuer LostIO
  */
-static int lostio_mst_seek_handler(lostio_filehandle_t* fh, uint64_t offset,
-    int origin)
+static int write(struct lio_resource* res, uint64_t offset,
+    size_t size, void* buf)
 {
-    struct partition* part = (struct partition*) fh->node->data;
-    uint64_t new_pos = fh->pos;
-    uint64_t size = part->size;
-
-    switch (origin)  {
-        case SEEK_SET:
-            new_pos = offset;
-            break;
-
-        case SEEK_CUR:
-            new_pos += offset;
-            break;
-
-        case SEEK_END:
-            new_pos = size;
-            break;
-    }
+    struct partition* part = res->opaque;
+    struct cdi_storage_device* device = part->dev;
+    int result;
 
-    // Position nur aktualisieren, wenn sie nicht ausserhalb des Datentraegers
-    // liegt.
-    if (new_pos > size) {
-        return -1;
-    } else if (new_pos == size) {
-        // Gegebenen Falles noch EOF setzen
-        fh->flags |= LOSTIO_FLAG_EOF;
-    } else {
-        // Sonst EOF loeschen
-        fh->flags &= ~LOSTIO_FLAG_EOF;
+    // Groesse anpassen, wenn ueber das Medium hinaus geschrieben werden soll
+    if (size > (part->size - offset)) {
+        size = part->size - offset;
     }
-    fh->pos = new_pos;
-    return 0;
-}
 
+    // Daten schreiben
+    result = cdi_storage_write(device, offset + part->start, size, buf);
 
+    return (result ? -1 : 0);
+}
-- 
1.7.7