2 * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sbin/atacontrol/atacontrol.c,v 1.11.2.5 2002/08/21 13:18:17 sos Exp $
43 case ATA_PIO: return "BIOSPIO";
44 case ATA_PIO0: return "PIO0";
45 case ATA_PIO1: return "PIO1";
46 case ATA_PIO2: return "PIO2";
47 case ATA_PIO3: return "PIO3";
48 case ATA_PIO4: return "PIO4";
49 case ATA_WDMA2: return "WDMA2";
50 case ATA_UDMA2: return "UDMA33";
51 case ATA_UDMA4: return "UDMA66";
52 case ATA_UDMA5: return "UDMA100";
53 case ATA_UDMA6: return "UDMA133";
54 case ATA_DMA: return "BIOSDMA";
55 default: return "???";
62 if (!strcasecmp(str, "BIOSPIO")) return ATA_PIO;
63 if (!strcasecmp(str, "PIO0")) return ATA_PIO0;
64 if (!strcasecmp(str, "PIO1")) return ATA_PIO1;
65 if (!strcasecmp(str, "PIO2")) return ATA_PIO2;
66 if (!strcasecmp(str, "PIO3")) return ATA_PIO3;
67 if (!strcasecmp(str, "PIO4")) return ATA_PIO4;
68 if (!strcasecmp(str, "WDMA2")) return ATA_WDMA2;
69 if (!strcasecmp(str, "UDMA2")) return ATA_UDMA2;
70 if (!strcasecmp(str, "UDMA33")) return ATA_UDMA2;
71 if (!strcasecmp(str, "UDMA4")) return ATA_UDMA4;
72 if (!strcasecmp(str, "UDMA66")) return ATA_UDMA4;
73 if (!strcasecmp(str, "UDMA5")) return ATA_UDMA5;
74 if (!strcasecmp(str, "UDMA100")) return ATA_UDMA5;
75 if (!strcasecmp(str, "UDMA6")) return ATA_UDMA6;
76 if (!strcasecmp(str, "UDMA133")) return ATA_UDMA6;
77 if (!strcasecmp(str, "BIOSDMA")) return ATA_DMA;
85 fprintf(stderr, "usage: atacontrol <command> channel [args]\n");
94 if (version == 0xffff)
96 for (bit = 15; bit >= 0; bit--)
97 if (version & (1<<bit))
103 param_print(struct ata_params *parm)
105 printf("<%.40s/%.8s> ATA/ATAPI rev %d\n",
106 parm->model, parm->revision, version(parm->version_major));
110 cap_print(struct ata_params *parm)
113 printf("ATA/ATAPI revision %d\n", version(parm->version_major));
114 printf("device model %.40s\n", parm->model);
115 printf("serial number %.20s\n", parm->serial);
116 printf("firmware revision %.8s\n", parm->revision);
118 printf("cylinders %d\n", parm->cylinders);
119 printf("heads %d\n", parm->heads);
120 printf("sectors/track %d\n", parm->sectors);
122 printf("lba%ssupported ", parm->support_lba ? " " : " not ");
124 printf("%d sectors\n", parm->lba_size);
128 printf("lba48%ssupported ", parm->support.address48 ? " " : " not ");
129 if (parm->lba_size48)
130 printf("%lld sectors\n", parm->lba_size48);
133 printf("dma%ssupported\n", parm->support_dma ? " " : " not");
135 printf("overlap%ssupported\n", parm->support_queueing ? " " : " not ");
137 printf("\nFeature Support Enable Value Vendor\n");
139 printf("write cache %s %s\n",
140 parm->support.write_cache ? "yes" : "no",
141 parm->enabled.write_cache ? "yes" : "no");
143 printf("read ahead %s %s\n",
144 parm->support.look_ahead ? "yes" : "no",
145 parm->enabled.look_ahead ? "yes" : "no");
147 printf("dma queued %s %s %d/%02X\n",
148 parm->support.queued ? "yes" : "no",
149 parm->enabled.queued ? "yes" : "no",
150 parm->queuelen, parm->queuelen);
152 printf("SMART %s %s\n",
153 parm->support.smart ? "yes" : "no",
154 parm->enabled.smart ? "yes" : "no");
156 printf("microcode download %s %s\n",
157 parm->support.microcode ? "yes" : "no",
158 parm->enabled.microcode ? "yes" : "no");
160 printf("security %s %s\n",
161 parm->support.smart ? "yes" : "no",
162 parm->enabled.smart ? "yes" : "no");
164 printf("power management %s %s\n",
165 parm->support.power_mngt ? "yes" : "no",
166 parm->enabled.power_mngt ? "yes" : "no");
168 printf("advanced power management %s %s %d/%02X\n",
169 parm->support.apm ? "yes" : "no",
170 parm->enabled.apm ? "yes" : "no",
171 parm->apm_value, parm->apm_value);
173 printf("automatic acoustic management %s %s %d/%02X %d/%02X\n",
174 parm->support.auto_acoustic ? "yes" : "no",
175 parm->enabled.auto_acoustic ? "yes" : "no",
176 parm->current_acoustic, parm->current_acoustic,
177 parm->vendor_acoustic, parm->vendor_acoustic);
181 ata_cap_print(int fd, int channel, int device)
183 struct ata_cmd iocmd;
185 bzero(&iocmd, sizeof(struct ata_cmd));
187 iocmd.channel = channel;
189 iocmd.cmd = ATAGPARM;
191 if (ioctl(fd, IOCATA, &iocmd) < 0)
194 printf("ATA channel %d, %s", channel, device==0 ? "Master" : "Slave");
196 if (iocmd.u.param.type[device]) {
197 printf(", device %s:\n", iocmd.u.param.name[device]);
198 cap_print(&iocmd.u.param.params[device]);
201 printf(": no device present\n");
206 info_print(int fd, int channel, int prchan)
208 struct ata_cmd iocmd;
210 bzero(&iocmd, sizeof(struct ata_cmd));
211 iocmd.channel = channel;
213 iocmd.cmd = ATAGPARM;
214 if (ioctl(fd, IOCATA, &iocmd) < 0)
217 printf("ATA channel %d:\n", channel);
218 printf("%sMaster: ", prchan ? " " : "");
219 if (iocmd.u.param.type[0]) {
220 printf("%4.4s ", iocmd.u.param.name[0]);
221 param_print(&iocmd.u.param.params[0]);
224 printf(" no device present\n");
225 printf("%sSlave: ", prchan ? " " : "");
226 if (iocmd.u.param.type[1]) {
227 printf("%4.4s ", iocmd.u.param.name[1]);
228 param_print(&iocmd.u.param.params[1]);
231 printf(" no device present\n");
236 main(int argc, char **argv)
238 struct ata_cmd iocmd;
241 if ((fd = open("/dev/ata", O_RDWR)) < 0)
242 err(1, "control device not found");
247 bzero(&iocmd, sizeof(struct ata_cmd));
249 if (argc > 2 && strcmp(argv[1], "create")) {
252 if (!strcmp(argv[1], "delete") ||
253 !strcmp(argv[1], "status") ||
254 !strcmp(argv[1], "rebuild")) {
255 if (!(sscanf(argv[2], "%d", &chan) == 1 ||
256 sscanf(argv[2], "ar%d", &chan) == 1))
260 if (!(sscanf(argv[2], "%d", &chan) == 1 ||
261 sscanf(argv[2], "ata%d", &chan) == 1))
264 iocmd.channel = chan;
267 if (!strcmp(argv[1], "list") && argc == 2) {
270 while (info_print(fd, unit++, 1) != ENXIO);
272 else if (!strcmp(argv[1], "info") && argc == 3) {
273 info_print(fd, iocmd.channel, 0);
275 else if (!strcmp(argv[1], "cap") && argc == 4) {
276 ata_cap_print(fd, iocmd.channel, atoi(argv[3]));
278 else if (!strcmp(argv[1], "enclosure") && argc == 4) {
279 iocmd.device = atoi(argv[3]);
280 iocmd.cmd = ATAENCSTAT;
281 if (ioctl(fd, IOCATA, &iocmd) < 0)
282 err(1, "ioctl(ATAENCSTAT)");
283 printf("fan RPM: %d temp: %.1f 5V: %.2f 12V: %.2f\n",
284 iocmd.u.enclosure.fan,
285 (double)iocmd.u.enclosure.temp / 10,
286 (double)iocmd.u.enclosure.v05 / 1000,
287 (double)iocmd.u.enclosure.v12 / 1000);
289 else if (!strcmp(argv[1], "detach") && argc == 3) {
290 iocmd.cmd = ATADETACH;
291 if (ioctl(fd, IOCATA, &iocmd) < 0)
292 err(1, "ioctl(ATADETACH)");
294 else if (!strcmp(argv[1], "attach") && argc == 3) {
295 iocmd.cmd = ATAATTACH;
296 if (ioctl(fd, IOCATA, &iocmd) < 0)
297 err(1, "ioctl(ATAATTACH)");
298 info_print(fd, iocmd.channel, 0);
300 else if (!strcmp(argv[1], "reinit") && argc == 3) {
301 iocmd.cmd = ATAREINIT;
302 if (ioctl(fd, IOCATA, &iocmd) < 0)
303 warn("ioctl(ATAREINIT)");
304 info_print(fd, iocmd.channel, 0);
306 else if (!strcmp(argv[1], "create")) {
307 int disk, dev, offset;
309 iocmd.cmd = ATARAIDCREATE;
310 if (!strcmp(argv[2], "RAID0") || !strcmp(argv[2], "stripe"))
311 iocmd.u.raid_setup.type = 1;
312 if (!strcmp(argv[2], "RAID1") || !strcmp(argv[2],"mirror"))
313 iocmd.u.raid_setup.type = 2;
314 if (!strcmp(argv[2], "RAID0+1"))
315 iocmd.u.raid_setup.type = 3;
316 if (!strcmp(argv[2], "SPAN") || !strcmp(argv[2], "JBOD"))
317 iocmd.u.raid_setup.type = 4;
318 if (!iocmd.u.raid_setup.type)
321 if (iocmd.u.raid_setup.type & 1) {
322 if (!sscanf(argv[3], "%d",
323 &iocmd.u.raid_setup.interleave) == 1)
330 for (disk = 0; disk < 16 && (offset + disk) < argc; disk++) {
331 if (!(sscanf(argv[offset + disk], "%d", &dev) == 1 ||
332 sscanf(argv[offset + disk], "ad%d", &dev) == 1))
334 iocmd.u.raid_setup.disks[disk] = dev;
336 iocmd.u.raid_setup.total_disks = disk;
337 if (ioctl(fd, IOCATA, &iocmd) < 0)
338 err(1, "ioctl(ATARAIDCREATE)");
340 printf("ar%d created\n", iocmd.u.raid_setup.unit);
342 else if (!strcmp(argv[1], "delete") && argc == 3) {
343 iocmd.cmd = ATARAIDDELETE;
344 if (ioctl(fd, IOCATA, &iocmd) < 0)
345 warn("ioctl(ATARAIDDELETE)");
347 else if (!strcmp(argv[1], "rebuild") && argc == 3) {
348 iocmd.cmd = ATARAIDREBUILD;
349 if (ioctl(fd, IOCATA, &iocmd) < 0)
350 warn("ioctl(ATARAIDREBUILD)");
352 else if (!strcmp(argv[1], "status") && argc == 3) {
355 iocmd.cmd = ATARAIDSTATUS;
356 if (ioctl(fd, IOCATA, &iocmd) < 0)
357 err(1, "ioctl(ATARAIDSTATUS)");
358 printf("ar%d: ATA ", iocmd.channel);
359 switch (iocmd.u.raid_status.type) {
366 case AR_RAID0 | AR_RAID1:
373 printf(" subdisks: ");
374 for (i = 0; i < iocmd.u.raid_status.total_disks; i++) {
375 if (iocmd.u.raid_status.disks[i] >= 0)
376 printf("ad%d ", iocmd.u.raid_status.disks[i]);
381 switch (iocmd.u.raid_status.status) {
385 case AR_READY | AR_DEGRADED:
386 printf("DEGRADED\n");
388 case AR_READY | AR_DEGRADED | AR_REBUILDING:
389 printf("REBUILDING %d%% completed\n",
390 iocmd.u.raid_status.progress);
396 else if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 5)) {
398 iocmd.cmd = ATASMODE;
400 iocmd.u.mode.mode[0] = str2mode(argv[3]);
401 iocmd.u.mode.mode[1] = str2mode(argv[4]);
402 if (ioctl(fd, IOCATA, &iocmd) < 0)
403 warn("ioctl(ATASMODE)");
405 if (argc == 3 || argc == 5) {
406 iocmd.cmd = ATAGMODE;
408 if (ioctl(fd, IOCATA, &iocmd) < 0)
409 err(1, "ioctl(ATAGMODE)");
410 printf("Master = %s \nSlave = %s\n",
411 mode2str(iocmd.u.mode.mode[0]),
412 mode2str(iocmd.u.mode.mode[1]));