e5e7e6b99aefa6e83ec4e2a7037bcb046dca5b39
[akaros.git] / kern / src / blockdev.c
1 /* Copyright (c) 2010 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Block devices and generic blockdev infrastructure */
6
7 #include <devfs.h>
8 #include <blockdev.h>
9 #include <kmalloc.h>
10 #include <slab.h>
11
12 struct file_operations block_f_op;
13 struct kmem_cache *breq_kcache;
14
15 void block_init(void)
16 {
17         breq_kcache = kmem_cache_create("block_reqs", sizeof(struct block_request),
18                                         __alignof__(struct block_request), 0, 0, 0);
19
20         #ifdef __CONFIG_EXT2FS__
21         /* Now probe for and init the block device for the ext2 ram disk */
22         extern uint8_t _binary_mnt_ext2fs_img_size[];
23         extern uint8_t _binary_mnt_ext2fs_img_start[];
24         /* Build and init the block device */
25         struct block_device *ram_bd = kmalloc(sizeof(struct block_device), 0);
26         memset(ram_bd, 0, sizeof(struct block_device));
27         ram_bd->b_id = 31337;
28         ram_bd->b_sector_size = 512;
29         ram_bd->b_num_sectors = (unsigned int)_binary_mnt_ext2fs_img_size / 512;
30         kref_init(&ram_bd->b_kref, fake_release, 1);
31         ram_bd->b_data = _binary_mnt_ext2fs_img_start;
32         strncpy(ram_bd->b_name, "RAMDISK", BDEV_INLINE_NAME);
33         ram_bd->b_name[BDEV_INLINE_NAME - 1] = '\0';
34         /* Connect it to the file system */
35         struct file *ram_bf = make_device("/dev/ramdisk", S_IRUSR | S_IWUSR,
36                                           __S_IFBLK, &block_f_op);
37         ram_bf->f_dentry->d_inode->i_bdev = ram_bd;     /* this holds the bd kref */
38         kref_put(&ram_bf->f_kref);
39         #endif /* __CONFIG_EXT2FS__ */
40 }
41
42 int make_request(struct block_device *bdev, struct block_request *req)
43 {
44         /* Sectors are indexed starting with 0, for now. */
45         if (req->first_sector + req->amount > bdev->b_num_sectors)
46                 return -1;
47         if (req->flags & BREQ_READ)
48                 memcpy(req->buffer, bdev->b_data + req->first_sector * SECTOR_SIZE,
49                        req->amount * SECTOR_SIZE);
50         else if (req->flags & BREQ_WRITE)
51                 memcpy(bdev->b_data + req->first_sector * SECTOR_SIZE, req->buffer,
52                        req->amount * SECTOR_SIZE);
53         else
54                 panic("Need a request type!\n");
55         return 0;
56 }
57
58 /* Block device file ops: for now, we don't let you do much of anything */
59 struct file_operations block_f_op = {
60         dev_c_llseek,
61         0,
62         0,
63         kfs_readdir,    /* this will fail gracefully */
64         dev_mmap,
65         kfs_open,
66         kfs_flush,
67         kfs_release,
68         0,      /* fsync - makes no sense */
69         kfs_poll,
70         0,      /* readv */
71         0,      /* writev */
72         kfs_sendpage,
73         kfs_check_flags,
74 };