| 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 |
|
|---|