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@93
|
43 bdev->ptype = get_part_type(plist);
|
nuclear@90
|
44
|
nuclear@90
|
45 free_part_list(plist);
|
nuclear@90
|
46 } else {
|
nuclear@90
|
47 bdev->offset = 0;
|
nuclear@90
|
48 bdev->size = SECT_TO_BLK(ata_num_sectors(devno));
|
nuclear@93
|
49 bdev->ptype = 0;
|
nuclear@90
|
50 }
|
nuclear@90
|
51
|
nuclear@90
|
52 return bdev;
|
nuclear@90
|
53 }
|
nuclear@90
|
54
|
nuclear@90
|
55 void blk_close(struct block_device *bdev)
|
nuclear@90
|
56 {
|
nuclear@90
|
57 free(bdev);
|
nuclear@90
|
58 }
|
nuclear@90
|
59
|
nuclear@90
|
60 #define NSECT (BLKSZ / 512)
|
nuclear@90
|
61
|
nuclear@93
|
62 int blk_read(struct block_device *bdev, uint32_t blk, int count, void *buf)
|
nuclear@90
|
63 {
|
nuclear@90
|
64 int i;
|
nuclear@90
|
65 char *ptr = buf;
|
nuclear@93
|
66 uint32_t sect = blk * NSECT + bdev->offset;
|
nuclear@90
|
67
|
nuclear@93
|
68 for(i=0; i<NSECT * count; i++) {
|
nuclear@90
|
69 if(ata_read_pio(bdev->ata_dev, sect++, ptr) == -1) {
|
nuclear@90
|
70 return -1;
|
nuclear@90
|
71 }
|
nuclear@90
|
72 ptr += 512;
|
nuclear@90
|
73 }
|
nuclear@90
|
74 return 0;
|
nuclear@90
|
75 }
|
nuclear@90
|
76
|
nuclear@93
|
77 int blk_write(struct block_device *bdev, uint32_t blk, int count, void *buf)
|
nuclear@90
|
78 {
|
nuclear@90
|
79 int i;
|
nuclear@90
|
80 char *ptr = buf;
|
nuclear@93
|
81 uint32_t sect = blk * NSECT + bdev->offset;
|
nuclear@90
|
82
|
nuclear@93
|
83 for(i=0; i<NSECT * count; i++) {
|
nuclear@90
|
84 if(ata_write_pio(bdev->ata_dev, sect++, ptr) == -1) {
|
nuclear@90
|
85 return -1;
|
nuclear@90
|
86 }
|
nuclear@90
|
87 ptr += 512;
|
nuclear@90
|
88 }
|
nuclear@90
|
89 return 0;
|
nuclear@90
|
90 }
|
nuclear@91
|
91
|
nuclear@91
|
92 dev_t bdev_by_name(const char *name)
|
nuclear@91
|
93 {
|
nuclear@91
|
94 int minor;
|
nuclear@91
|
95 int atadev, part = 0;
|
nuclear@91
|
96
|
nuclear@91
|
97 char *tmp = strrchr(name, '/');
|
nuclear@91
|
98 if(tmp) {
|
nuclear@91
|
99 name = tmp + 1;
|
nuclear@91
|
100 }
|
nuclear@91
|
101
|
nuclear@91
|
102 if(strstr(name, "ata") != name) {
|
nuclear@91
|
103 return 0;
|
nuclear@91
|
104 }
|
nuclear@91
|
105 name += 3;
|
nuclear@91
|
106
|
nuclear@91
|
107 atadev = strtol(name, &tmp, 10);
|
nuclear@91
|
108 if(tmp == name) {
|
nuclear@91
|
109 return 0;
|
nuclear@91
|
110 }
|
nuclear@91
|
111 name = tmp;
|
nuclear@91
|
112
|
nuclear@91
|
113 if(*name++ == 'p') {
|
nuclear@91
|
114 part = strtol(name, &tmp, 10) + 1;
|
nuclear@91
|
115 if(tmp == name) {
|
nuclear@91
|
116 return 0;
|
nuclear@91
|
117 }
|
nuclear@91
|
118 }
|
nuclear@91
|
119
|
nuclear@91
|
120 minor = MKMINOR(atadev, part);
|
nuclear@93
|
121 return DEVNO(1, minor);
|
nuclear@91
|
122 }
|