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.
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 "???";
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;
84 fprintf(stderr, "usage: atacontrol <command> channel [args]\n");
93 if (version == 0xffff)
95 for (bit = 15; bit >= 0; bit--)
96 if (version & (1<<bit))
102 param_print(struct ata_params *parm)
104 printf("<%.40s/%.8s> ATA/ATAPI rev %d\n",
105 parm->model, parm->revision, version(parm->version_major));
109 aparam_print(struct ata_params *parm)
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));
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);
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);
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");
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");
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");
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");
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");
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");
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");
154 printf(" advanced power management support %s\n", parm->support.apm ? "yes" : "no");
155 if(parm->support.apm)
157 printf(" enabled %s\n", parm->enabled.apm ? "yes" : "no");
158 printf(" value %d / 0x%02x\n", parm->apm_value, parm->apm_value);
160 printf(" automatic acoustic management support %s\n", parm->support.auto_acoustic ? "yes" : "no");
161 if(parm->support.auto_acoustic)
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);
170 ata_params_print(int fd, int channel, int master)
172 struct ata_cmd iocmd;
174 bzero(&iocmd, sizeof(struct ata_cmd));
176 iocmd.channel = channel;
178 iocmd.cmd = ATAGPARM;
180 if (ioctl(fd, IOCATA, &iocmd) < 0)
187 printf("ATA channel %d, %s", channel, master==0 ? "Master" : "Slave");
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]);
195 printf(": no device present\n");
201 info_print(int fd, int channel, int prchan)
203 struct ata_cmd iocmd;
205 bzero(&iocmd, sizeof(struct ata_cmd));
206 iocmd.channel = channel;
208 iocmd.cmd = ATAGPARM;
209 if (ioctl(fd, IOCATA, &iocmd) < 0)
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]);
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]);
226 printf(" no device present\n");
231 main(int argc, char **argv)
233 struct ata_cmd iocmd;
237 if ((fd = open("/dev/ata", O_RDWR)) < 0)
238 err(1, "control device not found");
243 bzero(&iocmd, sizeof(struct ata_cmd));
247 if (!(sscanf(argv[2], "%d", &chan) == 1 ||
248 sscanf(argv[2], "ata%d", &chan) == 1))
250 iocmd.channel = chan;
254 master = atoi(argv[3]);
256 if (!strcmp(argv[1], "list") && argc == 2) {
259 while (info_print(fd, unit++, 1) != ENXIO);
261 else if (!strcmp(argv[1], "info") && argc == 3) {
262 info_print(fd, iocmd.channel, 0);
264 else if (!strcmp(argv[1], "parm") && argc == 4) {
265 ata_params_print(fd, iocmd.channel, master);
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)");
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);
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);
284 else if (!strcmp(argv[1], "rebuild") && argc == 3) {
285 iocmd.cmd = ATAREBUILD;
286 if (ioctl(fd, IOCATA, &iocmd) < 0)
287 warn("ioctl(ATAREBUILD)");
289 else if (!strcmp(argv[1], "mode") && (argc == 3 || argc == 5)) {
291 iocmd.cmd = ATASMODE;
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)");
298 if (argc == 3 || argc == 5) {
299 iocmd.cmd = ATAGMODE;
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]));