]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/atacontrol/atacontrol.c
This commit was generated by cvs2svn to compensate for changes in r92948,
[FreeBSD/FreeBSD.git] / sbin / atacontrol / atacontrol.c
1 /*-
2  * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
16  *
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.
27  *
28  * $FreeBSD$
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <fcntl.h>
35 #include <errno.h>
36 #include <err.h>
37 #include <sys/ata.h>
38
39 char *
40 mode2str(int mode)
41 {
42         switch (mode) {
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_DMA: return "BIOSDMA";
54         default: return "???";
55         }
56 }
57
58 int
59 str2mode(char *str)
60 {
61         if (!strcasecmp(str, "BIOSPIO")) return ATA_PIO;
62         if (!strcasecmp(str, "PIO0")) return ATA_PIO0;
63         if (!strcasecmp(str, "PIO1")) return ATA_PIO1;
64         if (!strcasecmp(str, "PIO2")) return ATA_PIO2;
65         if (!strcasecmp(str, "PIO3")) return ATA_PIO3;
66         if (!strcasecmp(str, "PIO4")) return ATA_PIO4;
67         if (!strcasecmp(str, "WDMA2")) return ATA_WDMA2;
68         if (!strcasecmp(str, "UDMA2")) return ATA_UDMA2;
69         if (!strcasecmp(str, "UDMA33")) return ATA_UDMA2;
70         if (!strcasecmp(str, "UDMA4")) return ATA_UDMA4;
71         if (!strcasecmp(str, "UDMA66")) return ATA_UDMA4;
72         if (!strcasecmp(str, "UDMA5")) return ATA_UDMA5;
73         if (!strcasecmp(str, "UDMA100")) return ATA_UDMA5;
74         if (!strcasecmp(str, "UDMA6")) return ATA_UDMA6;
75         if (!strcasecmp(str, "UDMA133")) return ATA_UDMA6;
76         if (!strcasecmp(str, "BIOSDMA")) return ATA_DMA;
77         return -1;
78 }
79
80
81 void
82 usage()
83 {
84         fprintf(stderr, "usage: atacontrol <command> channel [args]\n");
85         exit(1);
86 }
87
88 int
89 version(int version)
90 {
91         int bit;
92     
93         if (version == 0xffff)
94                 return 0;
95         for (bit = 15; bit >= 0; bit--)
96                 if (version & (1<<bit))
97                         return bit;
98         return 0;
99 }
100
101 void
102 param_print(struct ata_params *parm)
103 {
104         printf("<%.40s/%.8s> ATA/ATAPI rev %d\n",
105                 parm->model, parm->revision, version(parm->version_major)); 
106 }
107
108 void
109 aparam_print(struct ata_params *parm)
110 {
111         printf("                                 disk model name %.40s\n", parm->model);
112         printf("                               firmware revision %.8s\n", parm->revision);
113         printf("                            ata / atapi revision %d\n", version(parm->version_major));
114
115         printf("                             number of cylinders %d\n", parm->cylinders);
116         printf("                                 number of heads %d\n", parm->heads);
117         printf("                               sectors per track %d\n", parm->sectors); 
118         
119         printf("                                     lba support %s\n", parm->support_lba ? "yes" : "no");
120         printf("                                     lba sectors %d\n", parm->lba_size);        
121         printf("                                     dma support %s\n", parm->support_dma ? "yes" : "no");
122         printf("                                queueing support %s\n", parm->support_queueing ? "yes" : "no");
123         if(parm->support_queueing)
124         printf("                                          length %d\n", parm->queuelen);        
125
126         printf("                                   SMART support %s\n", parm->support.smart ? "yes" : "no");
127         if(parm->support.smart)
128         printf("                                         enabled %s\n", parm->enabled.smart ? "yes" : "no");
129
130         printf("                                security support %s\n", parm->support.smart ? "yes" : "no");
131         if(parm->support.smart)
132         printf("                                         enabled %s\n", parm->enabled.smart ? "yes" : "no");    
133
134         printf("                        power management support %s\n", parm->support.power_mngt ? "yes" : "no");
135         if(parm->support.power_mngt)
136         printf("                                         enabled %s\n", parm->enabled.power_mngt ? "yes" : "no");       
137
138         printf("                             write cache support %s\n", parm->support.write_cache ? "yes" : "no");
139         if(parm->support.write_cache)
140         printf("                                         enabled %s\n", parm->enabled.write_cache ? "yes" : "no");      
141
142         printf("                              look ahead support %s\n", parm->support.look_ahead ? "yes" : "no");
143         if(parm->support.look_ahead)
144         printf("                                         enabled %s\n", parm->enabled.look_ahead ? "yes" : "no");       
145
146         printf("                      microcode download support %s\n", parm->support.microcode ? "yes" : "no");
147         if(parm->support.microcode)
148         printf("                                         enabled %s\n", parm->enabled.microcode ? "yes" : "no");        
149
150         printf("                        rd/wr dma queued support %s\n", parm->support.queued ? "yes" : "no");
151         if(parm->support.queued)
152         printf("                                         enabled %s\n", parm->enabled.queued ? "yes" : "no");   
153
154         printf("               advanced power management support %s\n", parm->support.apm ? "yes" : "no");
155         if(parm->support.apm)
156         {
157         printf("                                         enabled %s\n", parm->enabled.apm ? "yes" : "no");      
158         printf("                                           value %d / 0x%02x\n", parm->apm_value, parm->apm_value);
159         }       
160         printf("           automatic acoustic management support %s\n", parm->support.auto_acoustic ? "yes" : "no");
161         if(parm->support.auto_acoustic)
162         {
163         printf("                                         enabled %s\n", parm->enabled.auto_acoustic ? "yes" : "no");
164         printf("     automatic acoustic management current value %d / 0x%02x\n", parm->current_acoustic, parm->current_acoustic);
165         printf("                               recommended value %d / 0x%02x\n", parm->vendor_acoustic, parm->vendor_acoustic); 
166         }
167 }
168
169 int
170 ata_params_print(int fd, int channel, int master)
171 {
172         struct ata_cmd iocmd;
173
174         bzero(&iocmd, sizeof(struct ata_cmd));
175
176         iocmd.channel = channel;
177         iocmd.device = -1;
178         iocmd.cmd = ATAGPARM;
179
180         if (ioctl(fd, IOCATA, &iocmd) < 0)
181                 return errno;
182
183         if(master)
184                 master = 1;
185         master = !master;
186         
187         printf("ATA channel %d, %s", channel, master==0 ? "Master" : "Slave");
188
189         if (iocmd.u.param.type[master]) {
190                 printf(", device %s:\n", iocmd.u.param.name[master]);
191                 aparam_print(&iocmd.u.param.params[master]);
192         }
193         else
194         {
195                 printf(": no device present\n");
196         }
197         return 0;
198 }
199
200 int
201 info_print(int fd, int channel, int prchan)
202 {
203         struct ata_cmd iocmd;
204
205         bzero(&iocmd, sizeof(struct ata_cmd));
206         iocmd.channel = channel;
207         iocmd.device = -1;
208         iocmd.cmd = ATAGPARM;
209         if (ioctl(fd, IOCATA, &iocmd) < 0)
210                 return errno;
211         if (prchan)
212                 printf("ATA channel %d:\n", channel);
213         printf("%sMaster: ", prchan ? "    " : "");
214         if (iocmd.u.param.type[0]) {
215                 printf("%4.4s ", iocmd.u.param.name[0]);
216                 param_print(&iocmd.u.param.params[0]);
217         }
218         else
219                 printf("     no device present\n");
220         printf("%sSlave:  ", prchan ? "    " : "");
221         if (iocmd.u.param.type[1]) {
222                 printf("%4.4s ", iocmd.u.param.name[1]);
223                 param_print(&iocmd.u.param.params[1]);
224         }
225         else
226                 printf("     no device present\n");
227         return 0;
228 }
229
230 int
231 main(int argc, char **argv)
232 {
233         struct ata_cmd iocmd;
234         int master;
235         int fd;
236
237         if ((fd = open("/dev/ata", O_RDWR)) < 0)
238                 err(1, "control device not found");
239
240         if (argc < 2)
241                 usage();
242
243         bzero(&iocmd, sizeof(struct ata_cmd));
244
245         if (argc > 2) {
246                 int chan;
247                 if (!(sscanf(argv[2], "%d", &chan) == 1 ||
248                     sscanf(argv[2], "ata%d", &chan) == 1))
249                         usage();
250                 iocmd.channel = chan;
251         }
252
253         if (argc > 3)
254                 master = atoi(argv[3]);
255
256         if (!strcmp(argv[1], "list") && argc == 2) {
257                 int unit = 0;
258
259                 while (info_print(fd, unit++, 1) != ENXIO);
260         }
261         else if (!strcmp(argv[1], "info") && argc == 3) {
262                 info_print(fd, iocmd.channel, 0);
263         }
264         else if (!strcmp(argv[1], "parm") && argc == 4) {
265                 ata_params_print(fd, iocmd.channel, master);
266         }
267         else if (!strcmp(argv[1], "detach") && argc == 3) {
268                 iocmd.cmd = ATADETACH;
269                 if (ioctl(fd, IOCATA, &iocmd) < 0)
270                         err(1, "ioctl(ATADETACH)");
271         }
272         else if (!strcmp(argv[1], "attach") && argc == 3) {
273                 iocmd.cmd = ATAATTACH;
274                 if (ioctl(fd, IOCATA, &iocmd) < 0)
275                         err(1, "ioctl(ATAATTACH)");
276                 info_print(fd, iocmd.channel, 0);
277         }
278         else if (!strcmp(argv[1], "reinit") && argc == 3) {
279                 iocmd.cmd = ATAREINIT;
280                 if (ioctl(fd, IOCATA, &iocmd) < 0)
281                         warn("ioctl(ATAREINIT)");
282                 info_print(fd, iocmd.channel, 0);
283         }
284         else if (!strcmp(argv[1], "rebuild") && argc == 3) {
285                 iocmd.cmd = ATAREBUILD;
286                 if (ioctl(fd, IOCATA, &iocmd) < 0)
287                         warn("ioctl(ATAREBUILD)");
288         }
289         else if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 5)) {
290                 if (argc == 5) {
291                         iocmd.cmd = ATASMODE;
292                         iocmd.device = -1;
293                         iocmd.u.mode.mode[0] = str2mode(argv[3]);
294                         iocmd.u.mode.mode[1] = str2mode(argv[4]);
295                         if (ioctl(fd, IOCATA, &iocmd) < 0)
296                                 warn("ioctl(ATASMODE)");
297                 }
298                 if (argc == 3 || argc == 5) {
299                         iocmd.cmd = ATAGMODE;
300                         iocmd.device = -1;
301                         if (ioctl(fd, IOCATA, &iocmd) < 0)
302                                 err(1, "ioctl(ATAGMODE)");
303                         printf("Master = %s \nSlave  = %s\n",
304                                 mode2str(iocmd.u.mode.mode[0]), 
305                                 mode2str(iocmd.u.mode.mode[1]));
306                 }
307         }
308         else
309                 usage();
310         exit(0);
311 }