|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.0 (the 'License'). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License."
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24: /*
25: * Copyright 1997-1998 by Apple Computer, Inc., All rights reserved.
26: * Copyright 1994-1997 NeXT Software, Inc., All rights reserved.
27: *
28: * idemodes.c -- User level utility to print ATA disk parameters
29: * (will work with only 3.3 IDE driver patch and later)
30: *
31: * HISTORY
32: * 14-Aug-1994 Rakesh Dubey at NeXT
33: * Created.
34: *
35: */
36:
37: #import <stdio.h>
38: #import <stdlib.h>
39: #import <string.h>
40: #import <sys/ioctl.h>
41: #import <errno.h>
42: #import <libc.h>
43:
44: /* FIXME */
45: #import <ata_extern.h>
46:
47: void print_ide_info(ideIdentifyInfo_t *ideInfo);
48: void get_info_for_drive(char *name);
49:
50: char *progname;
51:
52: int main(int argc, char *argv[])
53: {
54: int i;
55:
56: if (argc == 1) {
57: fprintf(stderr, "Usages: %s <raw_device>\n", argv[0]);
58: exit(0);
59: }
60:
61: progname = argv[0];
62:
63: for (i = 1; i < argc; i++) {
64: get_info_for_drive(argv[i]);
65: }
66:
67: exit(0);
68: }
69:
70: void get_info_for_drive(char *name)
71: {
72: int fd, status;
73: ideIoReq_t ioReq;
74: ideIdentifyInfo_t *ideInfo;
75:
76: if ((fd = open(name, O_RDONLY)) < 0) {
77: //fprintf(stderr, "%s: can't open %s\n", progname, name);
78: perror(progname);
79: exit(1);
80: }
81:
82: bzero(&ioReq, sizeof(ideIoReq_t));
83:
84: ideInfo = (ideIdentifyInfo_t *) malloc(sizeof(ideIdentifyInfo_t));
85: if (ideInfo == NULL) {
86: perror(progname);
87: exit(2);
88: }
89: bzero(ideInfo, sizeof(ideIdentifyInfo_t));
90:
91: ioReq.cmd = IDE_IDENTIFY_DRIVE;
92: ioReq.addr = (void *) ideInfo;
93:
94: if ((status = ioctl(fd, IDEDIOCREQ, &ioReq)) < 0) {
95: perror(progname);
96: free(ideInfo);
97: exit(1);
98: }
99:
100: close(fd);
101:
102: if (status != IDER_SUCCESS) {
103: fprintf(stderr, "Command failed: error %d, status 0x%0x\n",
104: status, ioReq.status);
105: free(ideInfo);
106: exit(3);
107: }
108:
109: print_ide_info(ideInfo);
110: free(ideInfo);
111:
112: }
113:
114: char *byte_swap_string(char *s, int len)
115: {
116: int i;
117: char *tmp;
118:
119: tmp = (char *)malloc(len);
120:
121: for (i = 0; i < len/2; i++) {
122: tmp[2*i] = s[2*i+1];
123: tmp[2*i+1] = s[2*i];
124: }
125: strncpy(s, tmp, len);
126: s[len-1] = '\0';
127:
128: free(tmp);
129: return s;
130: }
131:
132:
133: void print_ide_info(ideIdentifyInfo_t *ideInfo)
134: {
135: int transfer_mode;
136: unsigned int sec_cnt;
137: unsigned long capacity;
138: unsigned char printall;
139: short *data = (short *)ideInfo;
140: int i;
141:
142: printall = 0;
143:
144: /* Name */
145: printf("Drive Name: %s\n", byte_swap_string(ideInfo->modelNumber, 40));
146: printf("Firmware Revision: %s\n",
147: byte_swap_string(ideInfo->firmwareRevision, 8));
148: printf("Serial Number: %s\n",
149: byte_swap_string(ideInfo->serialNumber, 10));
150:
151: /* Physical (hopefully) parameters */
152: printf("Cylinders: %d, heads: %d, sectors per track: %d.\n",
153: ideInfo->cylinders, ideInfo->heads, ideInfo->sectorsPerTrack);
154:
155: /* What this thing can do */
156: printf("Capabilities: ");
157: if (ideInfo->capabilities & IDE_CAP_LBA_SUPPORTED) {
158: printf("LBA");
159: }
160:
161: if (ideInfo->capabilities & IDE_CAP_IORDY_SUPPORTED) {
162: printf(", IORDY");
163: }
164: if (ideInfo->capabilities & IDE_CAP_DMA_SUPPORTED)
165: printf(", DMA");
166: printf("\n");
167:
168: /* Drive buffer features */
169: printf("Drive Buffer: ");
170: if (ideInfo->bufferType != 0) {
171: printf("type %d, size %d sectors.\n",
172: ideInfo->bufferType, ideInfo->bufferSize);
173: }
174:
175: /* Transfer mode */
176: printf("Data Transfer: ");
177: transfer_mode = (ideInfo->pioDataTransferCyleTimingMode &
178: IDE_PIO_TIMING_MODE_MASK) >> 8;
179: printf("PIO Mode %d", transfer_mode);
180:
181: if (ideInfo->capabilities & IDE_CAP_DMA_SUPPORTED) {
182: int i;
183:
184: /* Single word DMA */
185: transfer_mode = (ideInfo->dmaDataTransferCyleTimingMode &
186: IDE_DMA_TIMING_MODE_MASK) >> 8;
187: printf(", SW DMA Mode %d", transfer_mode);
188:
189: /* Multiword DMA */
190: for (i = 2; i >= 0; i--) {
191: if (ideInfo->mwDma & (1 << i)) {
192: printf(", MW DMA Mode %d", i);
193: break;
194: }
195: }
196:
197: /* UDMA/33 */
198: if (ideInfo->fieldValidity & IDE_WORD88_SUPPORTED) {
199: for (i = 2; i >= 0; i--) {
200: if (ideInfo->UDma & (1 << i)) {
201: printf(", UDMA/33 Mode %d", i);
202: break;
203: }
204: }
205: }
206: }
207: printf("\n");
208:
209: /* Transfer mode with IOCHRDY */
210: if ((ideInfo->fieldValidity & IDE_WORDS64_TO_68_SUPPORTED) &&
211: (ideInfo->capabilities & IDE_CAP_IORDY_SUPPORTED)) {
212: printf("Data Transfer (with IORDY): ");
213: transfer_mode = ideInfo->fcPioDataTransferCyleTimingMode;
214: if (transfer_mode & IDE_FC_PIO_MODE_5_SUPPORTED)
215: printf("PIO Mode 5 ");
216: else if (transfer_mode & IDE_FC_PIO_MODE_4_SUPPORTED)
217: printf("PIO Mode 4 ");
218: else if (transfer_mode & IDE_FC_PIO_MODE_3_SUPPORTED)
219: printf("PIO Mode 3 ");
220:
221: printf("\n");
222: }
223:
224: sec_cnt = ideInfo->multipleSectors & IDE_MULTI_SECTOR_MASK;
225: if (sec_cnt > 0) {
226: printf("Multiple Sector: %d sectors per transfer.\n",
227: sec_cnt);
228: }
229:
230: /* Drive capacity */
231: if (ideInfo->capabilities & IDE_CAP_LBA_SUPPORTED) {
232: capacity = ideInfo->userAddressableSectors;
233: } else {
234: capacity = ideInfo->cylinders * ideInfo->heads *
235: ideInfo->sectorsPerTrack;
236: }
237:
238: /*
239: * Some disks that support LBA have bogus info in userAddressableSectors
240: * field.
241: */
242: capacity = ideInfo->cylinders * ideInfo->heads *
243: ideInfo->sectorsPerTrack;
244:
245: printf("Drive Capacity: %lu sectors of 512 bytes each (total %7.2f MB).\n",
246: capacity, (float) (capacity*512.0)/(1024*1024));
247:
248: /*
249: * Dump all data returned by IDENTIFY DRIVE command.
250: */
251: if (printall) {
252: for (i = 0; i < 256; i++) {
253: if (i % 8 == 0)
254: printf("\n%3d: ", i);
255: printf("%4x ", data[i] & 0x0ffff);
256: }
257: printf("\n");
258: }
259:
260: return;
261: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.