1 | #include <stdlib.h>
|
---|
2 | #include <stdio.h>
|
---|
3 | #include <stddef.h>
|
---|
4 | #include <memory.h>
|
---|
5 |
|
---|
6 | #define INCL_DOS
|
---|
7 | #include <os2.h>
|
---|
8 | #include "../ioctl.h"
|
---|
9 |
|
---|
10 | void phex(const void *p, int len);
|
---|
11 |
|
---|
12 | int main(int arhc, char *argv[])
|
---|
13 | {
|
---|
14 | OS2AHCI_DEVLIST *dl;
|
---|
15 | OS2AHCI_PASSTHROUGH pt;
|
---|
16 | APIRET rc;
|
---|
17 | HFILE fh;
|
---|
18 | ULONG at;
|
---|
19 | ULONG cnt;
|
---|
20 | ULONG plen;
|
---|
21 | ULONG dlen;
|
---|
22 | char sense_buf[64];
|
---|
23 | char id_buf[512];
|
---|
24 | int i;
|
---|
25 | int n;
|
---|
26 |
|
---|
27 | /* open OS2AHCI character device driver */
|
---|
28 | rc = DosOpen("\\DEV\\OS2AHCI$", &fh, &at, 0, FILE_SYSTEM,
|
---|
29 | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
|
---|
30 | OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
|
---|
31 |
|
---|
32 | if (rc != 0) {
|
---|
33 | printf("couldn't open OS2AHCI$; rc = %ld\n", rc);
|
---|
34 | return(1);
|
---|
35 | }
|
---|
36 |
|
---|
37 | /* get device information */
|
---|
38 | cnt = 20;
|
---|
39 | plen = sizeof(cnt);
|
---|
40 | dlen = offsetof(OS2AHCI_DEVLIST, devs) + cnt * sizeof(dl->devs);
|
---|
41 | dl = malloc(dlen);
|
---|
42 | rc = DosDevIOCtl(fh, OS2AHCI_IOCTL_CATEGORY, OS2AHCI_IOCTL_GET_DEVLIST,
|
---|
43 | &cnt, plen, &plen, dl, dlen, &dlen);
|
---|
44 |
|
---|
45 | if (rc != 0) {
|
---|
46 | printf("couldn't get device list; rc = %ld\n", rc);
|
---|
47 | return(1);
|
---|
48 | }
|
---|
49 |
|
---|
50 | for (i = 0; i < dl->cnt; i++) {
|
---|
51 | printf("connection: %d.%d.%d, type: %d, ncq_max: %d, flags: 0x%04x\n",
|
---|
52 | dl->devs[i].adapter, dl->devs[i].port, dl->devs[i].device,
|
---|
53 | dl->devs[i].type, dl->devs[i].ncq_max, dl->devs[i].flags);
|
---|
54 | }
|
---|
55 |
|
---|
56 | printf("\n");
|
---|
57 |
|
---|
58 | /* get ATA ID buffer for each device */
|
---|
59 | for (i = 0; i < dl->cnt; i++) {
|
---|
60 | memset(&pt, 0x00, sizeof(pt));
|
---|
61 | memset(sense_buf, 0x00, sizeof(sense_buf));
|
---|
62 | pt.adapter = dl->devs[i].adapter;
|
---|
63 | pt.port = dl->devs[i].port;
|
---|
64 | pt.device = dl->devs[i].device;
|
---|
65 | pt.flags = 0;
|
---|
66 | pt.timeout = 0;
|
---|
67 |
|
---|
68 | pt.cmdlen = sizeof(pt.cmd.ata);
|
---|
69 | pt.cmd.ata.cmd = (dl->devs[i].flags & DF_ATAPI) ? 0xa1 : 0xec;
|
---|
70 |
|
---|
71 | pt.buflen = sizeof(id_buf);
|
---|
72 | pt.buf = id_buf;
|
---|
73 | pt.sense_len = sizeof(sense_buf);
|
---|
74 |
|
---|
75 | plen = sizeof(pt);
|
---|
76 | dlen = sizeof(sense_buf);
|
---|
77 | rc = DosDevIOCtl(fh, OS2AHCI_IOCTL_CATEGORY, OS2AHCI_IOCTL_PASSTHROUGH,
|
---|
78 | &pt, plen, &plen, sense_buf, dlen, &dlen);
|
---|
79 |
|
---|
80 | if (rc == 0) {
|
---|
81 | printf("ID for %d.%d.%d: ", dl->devs[i].adapter, dl->devs[i].port,
|
---|
82 | dl->devs[i].device);
|
---|
83 | for (n = 54; n < 94; n += 2) {
|
---|
84 | printf("%c%c", id_buf[n+1], id_buf[n]);
|
---|
85 | }
|
---|
86 | printf("\n");
|
---|
87 |
|
---|
88 | } else {
|
---|
89 | printf("\nID command failed (rc = %ld); sense code:\n", rc);
|
---|
90 | phex(sense_buf, sizeof(sense_buf));
|
---|
91 | }
|
---|
92 |
|
---|
93 | if (dl->devs[i].type == 5) {
|
---|
94 | /* Test sense buffer handling by ejecting the drive tray, then
|
---|
95 | * checking whether the unit is ready.
|
---|
96 | */
|
---|
97 | printf("ejecting drive tray\n");
|
---|
98 | memset(&pt, 0x00, sizeof(pt));
|
---|
99 | memset(sense_buf, 0x00, sizeof(sense_buf));
|
---|
100 | pt.adapter = dl->devs[i].adapter;
|
---|
101 | pt.port = dl->devs[i].port;
|
---|
102 | pt.device = dl->devs[i].device;
|
---|
103 | pt.flags = PT_ATAPI;
|
---|
104 | pt.timeout = 0;
|
---|
105 |
|
---|
106 | pt.cmdlen = 6;
|
---|
107 | pt.cmd.cdb[0] = 0x1b;
|
---|
108 | pt.cmd.cdb[4] = 0x02;
|
---|
109 |
|
---|
110 | pt.buflen = 0;
|
---|
111 | pt.buf = NULL;
|
---|
112 | pt.sense_len = sizeof(sense_buf);
|
---|
113 |
|
---|
114 | plen = sizeof(pt);
|
---|
115 | dlen = sizeof(sense_buf);
|
---|
116 | rc = DosDevIOCtl(fh, OS2AHCI_IOCTL_CATEGORY, OS2AHCI_IOCTL_PASSTHROUGH,
|
---|
117 | &pt, plen, &plen, sense_buf, dlen, &dlen);
|
---|
118 |
|
---|
119 | if (rc != 0) {
|
---|
120 | printf("\neject command failed (rc = %ld); sense code:\n", rc);
|
---|
121 | phex(sense_buf, sizeof(sense_buf));
|
---|
122 | break;
|
---|
123 | }
|
---|
124 |
|
---|
125 | printf("test unit ready\n");
|
---|
126 | memset(&pt, 0x00, sizeof(pt));
|
---|
127 | memset(sense_buf, 0x00, sizeof(sense_buf));
|
---|
128 | pt.adapter = dl->devs[i].adapter;
|
---|
129 | pt.port = dl->devs[i].port;
|
---|
130 | pt.device = dl->devs[i].device;
|
---|
131 | pt.flags = PT_ATAPI;
|
---|
132 | pt.timeout = 0;
|
---|
133 |
|
---|
134 | pt.cmdlen = 6;
|
---|
135 | pt.cmd.cdb[0] = 0x00;
|
---|
136 |
|
---|
137 | pt.buflen = 0;
|
---|
138 | pt.buf = NULL;
|
---|
139 | pt.sense_len = sizeof(sense_buf);
|
---|
140 |
|
---|
141 | plen = sizeof(pt);
|
---|
142 | dlen = sizeof(sense_buf);
|
---|
143 | rc = DosDevIOCtl(fh, OS2AHCI_IOCTL_CATEGORY, OS2AHCI_IOCTL_PASSTHROUGH,
|
---|
144 | &pt, plen, &plen, sense_buf, dlen, &dlen);
|
---|
145 |
|
---|
146 | if (rc != 0) {
|
---|
147 | printf("\ntest unit ready command failed as expected (rc = %ld); sense code:\n", rc);
|
---|
148 | phex(sense_buf, sizeof(sense_buf));
|
---|
149 | break;
|
---|
150 | }
|
---|
151 | }
|
---|
152 | }
|
---|
153 |
|
---|
154 | return(0);
|
---|
155 | }
|
---|
156 |
|
---|
157 | void phex(const void *p, int len)
|
---|
158 | {
|
---|
159 | const unsigned char *buf = p;
|
---|
160 | long pos = 0;
|
---|
161 | int i;
|
---|
162 |
|
---|
163 | /* print hex block */
|
---|
164 | while (len > 0) {
|
---|
165 | printf("%08X ", pos);
|
---|
166 |
|
---|
167 | /* print hex block */
|
---|
168 | for (i = 0; i < 16; i++) {
|
---|
169 | if (i < len) {
|
---|
170 | printf("%c%02x", ((i == 8) ? '-' : ' '), buf[i]);
|
---|
171 | } else {
|
---|
172 | printf(" ");
|
---|
173 | }
|
---|
174 | }
|
---|
175 |
|
---|
176 | /* print ASCII block */
|
---|
177 | printf(" ");
|
---|
178 | for (i = 0; i < ((len > 16) ? 16 : len); i++) {
|
---|
179 | printf("%c", (buf[i] >= 32 && buf[i] < 128) ? buf[i] : '.');
|
---|
180 | }
|
---|
181 | printf("\n");
|
---|
182 |
|
---|
183 | pos += 16;
|
---|
184 | buf += 16;
|
---|
185 | len -= 16;
|
---|
186 | }
|
---|
187 | }
|
---|
188 |
|
---|