blob: 90bfc1155e4faf1f65dc834ba0ef2db3c5129509 [file] [log] [blame]
Travis Geiselbrecht52486732010-05-06 14:04:14 -07001/*
2 * Copyright (c) 2009 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <debug.h>
24#include <stdlib.h>
25#include <string.h>
26#include <lib/console.h>
27#include <lib/bio.h>
28#include <lib/partition.h>
29#include <platform.h>
30
31#if defined(WITH_LIB_CONSOLE)
32
33#if DEBUGLEVEL > 0
34static int cmd_bio(int argc, const cmd_args *argv);
35
36STATIC_COMMAND_START
37STATIC_COMMAND("bio", "block io debug commands", &cmd_bio)
38STATIC_COMMAND_END(bio);
39
40static int cmd_bio(int argc, const cmd_args *argv)
41{
42 int rc = 0;
43
44 if (argc < 2) {
45 printf("not enough arguments:\n");
46usage:
47 printf("%s list\n", argv[0].str);
48 printf("%s read <device> <address> <offset> <len>\n", argv[0].str);
49 printf("%s write <device> <address> <offset> <len>\n", argv[0].str);
50 printf("%s erase <device> <offset> <len>\n", argv[0].str);
51 printf("%s ioctl <device> <request> <arg>\n", argv[0].str);
52 printf("%s remove <device>\n", argv[0].str);
53#if WITH_LIB_PARTITION
54 printf("%s partscan <device> [offset]\n", argv[0].str);
55#endif
56 return -1;
57 }
58
59 if (!strcmp(argv[1].str, "list")) {
60 bio_dump_devices();
61 } else if (!strcmp(argv[1].str, "read")) {
62 if (argc < 6) {
63 printf("not enough arguments:\n");
64 goto usage;
65 }
66
67 addr_t address = argv[3].u;
68 off_t offset = argv[4].u; // XXX use long
69 size_t len = argv[5].u;
70
71 bdev_t *dev = bio_open(argv[2].str);
72 if (!dev) {
73 printf("error opening block device\n");
74 return -1;
75 }
76
77 time_t t = current_time();
78 ssize_t err = bio_read(dev, (void *)address, offset, len);
79 t = current_time() - t;
80 dprintf(INFO, "bio_read returns %d, took %u msecs (%d bytes/sec)\n", (int)err, (uint)t, (uint32_t)((uint64_t)err * 1000 / t));
81
82 bio_close(dev);
83
84 rc = err;
85 } else if (!strcmp(argv[1].str, "write")) {
86 if (argc < 6) {
87 printf("not enough arguments:\n");
88 goto usage;
89 }
90
91 addr_t address = argv[3].u;
92 off_t offset = argv[4].u; // XXX use long
93 size_t len = argv[5].u;
94
95 bdev_t *dev = bio_open(argv[2].str);
96 if (!dev) {
97 printf("error opening block device\n");
98 return -1;
99 }
100
101 time_t t = current_time();
102 ssize_t err = bio_write(dev, (void *)address, offset, len);
103 t = current_time() - t;
104 dprintf(INFO, "bio_write returns %d, took %u msecs (%d bytes/sec)\n", (int)err, (uint)t, (uint32_t)((uint64_t)err * 1000 / t));
105
106 bio_close(dev);
107
108 rc = err;
109 } else if (!strcmp(argv[1].str, "erase")) {
110 if (argc < 5) {
111 printf("not enough arguments:\n");
112 goto usage;
113 }
114
115 off_t offset = argv[3].u; // XXX use long
116 size_t len = argv[4].u;
117
118 bdev_t *dev = bio_open(argv[2].str);
119 if (!dev) {
120 printf("error opening block device\n");
121 return -1;
122 }
123
124 time_t t = current_time();
125 ssize_t err = bio_erase(dev, offset, len);
126 t = current_time() - t;
127 dprintf(INFO, "bio_erase returns %d, took %u msecs (%d bytes/sec)\n", (int)err, (uint)t, (uint32_t)((uint64_t)err * 1000 / t));
128
129 bio_close(dev);
130
131 rc = err;
132 } else if (!strcmp(argv[1].str, "ioctl")) {
133 if (argc < 4) {
134 printf("not enough arguments:\n");
135 goto usage;
136 }
137
138 int request = argv[3].u;
139 int arg = (argc == 5) ? argv[4].u : 0;
140
141 bdev_t *dev = bio_open(argv[2].str);
142 if (!dev) {
143 printf("error opening block device\n");
144 return -1;
145 }
146
147 int err = bio_ioctl(dev, request, (void *)arg);
148 dprintf(INFO, "bio_ioctl returns %d\n", err);
149
150 bio_close(dev);
151
152 rc = err;
153 } else if (!strcmp(argv[1].str, "remove")) {
154 if (argc < 3) {
155 printf("not enough arguments:\n");
156 goto usage;
157 }
158
159 bdev_t *dev = bio_open(argv[2].str);
160 if (!dev) {
161 printf("error opening block device\n");
162 return -1;
163 }
164
165 bio_unregister_device(dev);
166 bio_close(dev);
167#if WITH_LIB_PARTITION
168 } else if (!strcmp(argv[1].str, "partscan")) {
169 if (argc < 3) {
170 printf("not enough arguments:\n");
171 goto usage;
172 }
173
174 off_t offset = 0;
175 if (argc > 3)
176 offset = argv[3].u;
177
178 rc = partition_publish(argv[2].str, offset);
179 dprintf(INFO, "partition_publish returns %d\n", rc);
180#endif
181 } else {
182 printf("unrecognized subcommand\n");
183 goto usage;
184 }
185
186 return rc;
187}
188
189#endif
190
191#endif
192