rev |
line source |
nuclear@90
|
1 #include <stdlib.h>
|
nuclear@91
|
2 #include <string.h>
|
nuclear@90
|
3 #include <assert.h>
|
nuclear@90
|
4 #include "bdev.h"
|
nuclear@90
|
5 #include "ata.h"
|
nuclear@90
|
6 #include "part.h"
|
nuclear@90
|
7
|
nuclear@91
|
8 #define MKMINOR(disk, part) ((((disk) & 0xf) << 4) | ((part) & 0xf))
|
nuclear@91
|
9 #define MINOR_DISK(x) (((x) >> 4) & 0xf)
|
nuclear@91
|
10 #define MINOR_PART(x) ((x) & 0xf)
|
nuclear@90
|
11
|
nuclear@90
|
12 struct block_device *blk_open(dev_t dev)
|
nuclear@90
|
13 {
|
nuclear@90
|
14 struct block_device *bdev;
|
nuclear@90
|
15 int i, minor, devno, part;
|
nuclear@90
|
16
|
nuclear@90
|
17 /* XXX for now ignore the major number as we only have ata devices */
|
nuclear@90
|
18 minor = DEV_MINOR(dev);
|
nuclear@90
|
19 devno = MINOR_DISK(minor);
|
nuclear@90
|
20 part = MINOR_PART(minor);
|
nuclear@90
|
21
|
nuclear@90
|
22 bdev = malloc(sizeof *bdev);
|
nuclear@90
|
23 assert(bdev);
|
nuclear@90
|
24
|
nuclear@90
|
25 bdev->ata_dev = devno;
|
nuclear@90
|
26
|
nuclear@90
|
27 if(part) {
|
nuclear@90
|
28 struct partition *plist = get_part_list(devno);
|
nuclear@90
|
29 assert(plist);
|
nuclear@90
|
30
|
nuclear@90
|
31 for(i=1; i<part; i++) {
|
nuclear@90
|
32 if(!plist) break;
|
nuclear@90
|
33 plist = plist->next;
|
nuclear@90
|
34 }
|
nuclear@90
|
35 if(!plist) {
|
nuclear@90
|
36 free(bdev);
|
nuclear@90
|
37 free_part_list(plist);
|
nuclear@90
|
38 return 0;
|
nuclear@90
|
39 }
|
nuclear@90
|
40
|
nuclear@90
|
41 bdev->offset = SECT_TO_BLK(plist->start_sect);
|
nuclear@90
|
42 bdev->size = SECT_TO_BLK(plist->size_sect);
|
nuclear@90
|
43
|
nuclear@90
|
44 free_part_list(plist);
|
nuclear@90
|
45 } else {
|
nuclear@90
|
46 bdev->offset = 0;
|
nuclear@90
|
47 bdev->size = SECT_TO_BLK(ata_num_sectors(devno));
|
nuclear@90
|
48 }
|
nuclear@90
|
49
|
nuclear@90
|
50 return bdev;
|
nuclear@90
|
51 }
|
nuclear@90
|
52
|
nuclear@90
|
53 void blk_close(struct block_device *bdev)
|
nuclear@90
|
54 {
|
nuclear@90
|
55 free(bdev);
|
nuclear@90
|
56 }
|
nuclear@90
|
57
|
nuclear@90
|
58 #define NSECT (BLKSZ / 512)
|
nuclear@90
|
59
|
nuclear@90
|
60 int blk_read(struct block_device *bdev, uint32_t blk, void *buf)
|
nuclear@90
|
61 {
|
nuclear@90
|
62 int i;
|
nuclear@90
|
63 char *ptr = buf;
|
nuclear@90
|
64 uint32_t sect = blk * NSECT;
|
nuclear@90
|
65
|
nuclear@90
|
66 for(i=0; i<NSECT; i++) {
|
nuclear@90
|
67 if(ata_read_pio(bdev->ata_dev, sect++, ptr) == -1) {
|
nuclear@90
|
68 return -1;
|
nuclear@90
|
69 }
|
nuclear@90
|
70 ptr += 512;
|
nuclear@90
|
71 }
|
nuclear@90
|
72 return 0;
|
nuclear@90
|
73 }
|
nuclear@90
|
74
|
nuclear@90
|
75 int blk_write(struct block_device *bdev, uint32_t blk, void *buf)
|
nuclear@90
|
76 {
|
nuclear@90
|
77 int i;
|
nuclear@90
|
78 char *ptr = buf;
|
nuclear@90
|
79 uint32_t sect = blk * NSECT;
|
nuclear@90
|
80
|
nuclear@90
|
81 for(i=0; i<NSECT; i++) {
|
nuclear@90
|
82 if(ata_write_pio(bdev->ata_dev, sect++, ptr) == -1) {
|
nuclear@90
|
83 return -1;
|
nuclear@90
|
84 }
|
nuclear@90
|
85 ptr += 512;
|
nuclear@90
|
86 }
|
nuclear@90
|
87 return 0;
|
nuclear@90
|
88 }
|
nuclear@91
|
89
|
nuclear@91
|
90 dev_t bdev_by_name(const char *name)
|
nuclear@91
|
91 {
|
nuclear@91
|
92 int minor;
|
nuclear@91
|
93 int atadev, part = 0;
|
nuclear@91
|
94
|
nuclear@91
|
95 char *tmp = strrchr(name, '/');
|
nuclear@91
|
96 if(tmp) {
|
nuclear@91
|
97 name = tmp + 1;
|
nuclear@91
|
98 }
|
nuclear@91
|
99
|
nuclear@91
|
100 if(strstr(name, "ata") != name) {
|
nuclear@91
|
101 return 0;
|
nuclear@91
|
102 }
|
nuclear@91
|
103 name += 3;
|
nuclear@91
|
104
|
nuclear@91
|
105 atadev = strtol(name, &tmp, 10);
|
nuclear@91
|
106 if(tmp == name) {
|
nuclear@91
|
107 return 0;
|
nuclear@91
|
108 }
|
nuclear@91
|
109 name = tmp;
|
nuclear@91
|
110
|
nuclear@91
|
111 if(*name++ == 'p') {
|
nuclear@91
|
112 part = strtol(name, &tmp, 10) + 1;
|
nuclear@91
|
113 if(tmp == name) {
|
nuclear@91
|
114 return 0;
|
nuclear@91
|
115 }
|
nuclear@91
|
116 }
|
nuclear@91
|
117
|
nuclear@91
|
118 minor = MKMINOR(atadev, part);
|
nuclear@91
|
119 return DEVNO(0, minor);
|
nuclear@91
|
120 }
|