summaryrefslogtreecommitdiff
path: root/libdde-linux26/lib/src/mach_glue/block.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdde-linux26/lib/src/mach_glue/block.c')
-rw-r--r--libdde-linux26/lib/src/mach_glue/block.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/libdde-linux26/lib/src/mach_glue/block.c b/libdde-linux26/lib/src/mach_glue/block.c
new file mode 100644
index 00000000..3820712c
--- /dev/null
+++ b/libdde-linux26/lib/src/mach_glue/block.c
@@ -0,0 +1,81 @@
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/bio.h>
+#include <ddekit/assert.h>
+
+struct gendisk *find_disk_by_name (char *);
+void dde_page_cache_add (struct page *);
+
+struct block_device *open_block_dev (char *name, int part, fmode_t mode)
+{
+ struct gendisk *disk = find_disk_by_name (name);
+ if (disk)
+ {
+ dev_t devid = MKDEV (disk->major, disk->first_minor + part);
+ return open_by_devnum (devid, mode);
+ }
+ return ERR_PTR(-ENXIO);
+}
+
+/* read or write a piece of data to a block device.
+ * DATA must be in one page.
+ * SECTORNR: the writing location in sectors. */
+int block_dev_rw (struct block_device *dev, int sectornr,
+ char *data, int count, int rw, void (*done (int err)))
+{
+ int err = 0;
+ struct bio *bio;
+ struct page *page;
+ int i;
+
+ void end_bio (struct bio *bio, int err)
+ {
+ done (err);
+ }
+
+ assert (count <= PAGE_SIZE);
+ bio = bio_alloc (GFP_NOIO, 1);
+ if (bio == NULL)
+ {
+ err = ENOMEM;
+ goto out;
+ }
+
+ page = kmalloc (sizeof (*page), GFP_KERNEL);
+ if (page == NULL)
+ {
+ err = ENOMEM;
+ goto out;
+ }
+
+ bio->bi_sector = sectornr;
+ bio->bi_bdev = dev;
+ page->virtual = data;
+ dde_page_cache_add (page);
+ bio->bi_io_vec[0].bv_page = page;
+ bio->bi_io_vec[0].bv_len = count;
+ bio->bi_io_vec[0].bv_offset = (int) data & ~PAGE_MASK;
+
+ bio->bi_vcnt = 1;
+ bio->bi_idx = 0;
+ bio->bi_size = count;
+
+ bio->bi_end_io = end_bio;
+ bio->bi_private = NULL;
+ bio_get (bio);
+ submit_bio (rw, bio);
+ if (bio_flagged (bio, BIO_EOPNOTSUPP))
+ {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+ bio_put (bio);
+out:
+ if (err)
+ {
+ if (bio)
+ bio_put (bio);
+ kfree (page);
+ }
+ return err;
+}