From 21bf6f025d94c2987dfe30a0b327b6dfab7a8bff Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Fri, 4 Jun 2010 16:51:24 +0200 Subject: support block devices in the DDE library. --- libdde_linux26/lib/src/Makefile | 3 +- libdde_linux26/lib/src/arch/l4/mach_glue.c | 87 ------------------------------ libdde_linux26/lib/src/mach_glue/block.c | 77 ++++++++++++++++++++++++++ libdde_linux26/lib/src/mach_glue/net.c | 87 ++++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+), 88 deletions(-) delete mode 100644 libdde_linux26/lib/src/arch/l4/mach_glue.c create mode 100644 libdde_linux26/lib/src/mach_glue/block.c create mode 100644 libdde_linux26/lib/src/mach_glue/net.c (limited to 'libdde_linux26/lib') diff --git a/libdde_linux26/lib/src/Makefile b/libdde_linux26/lib/src/Makefile index 3743f91b..947f11b9 100644 --- a/libdde_linux26/lib/src/Makefile +++ b/libdde_linux26/lib/src/Makefile @@ -150,7 +150,7 @@ SRC_C_libdde_linux26.o.a += \ ################################################################## SRC_C_libdde_linux26_net.a += \ arch/l4/net.c \ - arch/l4/mach_glue.c \ + mach_glue/net.c \ drivers/net/mii.c \ net/core/dev.c \ net/core/dev_mcast.c \ @@ -180,6 +180,7 @@ SRC_C_libdde_linux26_sound.a += \ # SRC_C_libdde_linux26_block.a += \ arch/l4/inodes.c \ + mach_glue/block.c \ block/blk-barrier.c \ block/blk-core.c \ block/blk-exec.c \ diff --git a/libdde_linux26/lib/src/arch/l4/mach_glue.c b/libdde_linux26/lib/src/arch/l4/mach_glue.c deleted file mode 100644 index 48373a90..00000000 --- a/libdde_linux26/lib/src/arch/l4/mach_glue.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include - -/* List of sk_buffs waiting to be freed. */ -static struct sk_buff_head skb_done_list; - -struct net_device *search_netdev (char *name) -{ - struct net_device *dev; - struct net_device *found = NULL; - struct net *net; - - printk("search device %s\n", name); - read_lock(&dev_base_lock); - for_each_net(net) { - for_each_netdev(net, dev) { - printk("there is device %s, base addr: %x\n", - dev->name, dev->base_addr); - if (!strcmp (name, dev->name)) - { - found = dev; - goto end; - } - } - } -end: - read_unlock(&dev_base_lock); - return found; -} - -int linux_pkg_xmit (char *pkg_data, int len, void *del_data, - int (*del_func) (struct sk_buff *, void *), - struct net_device *dev) -{ - struct sk_buff *skb; - - if (len == 0 || len > dev->mtu + dev->hard_header_len) - return EINVAL; - - /* Allocate a sk_buff. */ - skb = dev_alloc_skb (len); - if (!skb) - return ENOMEM; - - skb->del_data = del_data; - skb->pre_del_func = del_func; - - /* Copy user data. This is only required if it spans multiple pages. */ - skb->len = len; - skb->tail = skb->data + len; - - memcpy (skb->data, pkg_data, len); - - skb->dev = dev; - - return dev_queue_xmit(skb); -} - -char *netdev_addr(struct net_device *dev) -{ - return dev->dev_addr; -} - -int netdev_flags(struct net_device *dev) -{ - return dev->flags; -} - -void *skb_reply(struct sk_buff *skb) -{ - return skb->del_data; -} - -void skb_done_head_init() -{ - skb_queue_head_init (&skb_done_list); -} - -struct sk_buff *skb_done_dequeue() -{ - return skb_dequeue (&skb_done_list); -} - -void skb_done_queue(struct sk_buff *skb) -{ - skb_queue_tail (&skb_done_list, skb); -} 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..7eac7e46 --- /dev/null +++ b/libdde_linux26/lib/src/mach_glue/block.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +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); + dev_t devid = MKDEV (disk->major, disk->first_minor + part); + return open_by_devnum (devid, mode); +} + +/* write a piece of data to a block device. + * DATA must be in one page. + * SECTORNR: the writing location in sectors. */ +int block_dev_write (struct block_device *dev, int sectornr, + char *data, int count, void (*write_done (int err))) +{ + int err = 0; + struct bio *bio; + struct page *page; + int i; + + void end_bio (struct bio *bio, int err) + { + write_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 (WRITE, 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; +} diff --git a/libdde_linux26/lib/src/mach_glue/net.c b/libdde_linux26/lib/src/mach_glue/net.c new file mode 100644 index 00000000..48373a90 --- /dev/null +++ b/libdde_linux26/lib/src/mach_glue/net.c @@ -0,0 +1,87 @@ +#include +#include + +/* List of sk_buffs waiting to be freed. */ +static struct sk_buff_head skb_done_list; + +struct net_device *search_netdev (char *name) +{ + struct net_device *dev; + struct net_device *found = NULL; + struct net *net; + + printk("search device %s\n", name); + read_lock(&dev_base_lock); + for_each_net(net) { + for_each_netdev(net, dev) { + printk("there is device %s, base addr: %x\n", + dev->name, dev->base_addr); + if (!strcmp (name, dev->name)) + { + found = dev; + goto end; + } + } + } +end: + read_unlock(&dev_base_lock); + return found; +} + +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev) +{ + struct sk_buff *skb; + + if (len == 0 || len > dev->mtu + dev->hard_header_len) + return EINVAL; + + /* Allocate a sk_buff. */ + skb = dev_alloc_skb (len); + if (!skb) + return ENOMEM; + + skb->del_data = del_data; + skb->pre_del_func = del_func; + + /* Copy user data. This is only required if it spans multiple pages. */ + skb->len = len; + skb->tail = skb->data + len; + + memcpy (skb->data, pkg_data, len); + + skb->dev = dev; + + return dev_queue_xmit(skb); +} + +char *netdev_addr(struct net_device *dev) +{ + return dev->dev_addr; +} + +int netdev_flags(struct net_device *dev) +{ + return dev->flags; +} + +void *skb_reply(struct sk_buff *skb) +{ + return skb->del_data; +} + +void skb_done_head_init() +{ + skb_queue_head_init (&skb_done_list); +} + +struct sk_buff *skb_done_dequeue() +{ + return skb_dequeue (&skb_done_list); +} + +void skb_done_queue(struct sk_buff *skb) +{ + skb_queue_tail (&skb_done_list, skb); +} -- cgit v1.2.3