/******************************************************************** idediag shows characteristics of IDE hard disks. Public Domain by Paolo Bevilacqua, Rome. You can add more disk type to the idetypes[] table, and distribuite freely. ********************************************************************/ #include "1010_hdc.h" unsigned secbuf[256]; int drive; struct { unsigned cylinders, heads, sectors; char *name; } idetypes[] = { { 667, 4, 33, "Fujitsu M2611T (42.9 MB)" }, { 667, 8, 33, "Fujitsu M2612T (85.9 MB)" }, { 667, 12, 33, "Fujitsu M2613T (128.9 MB)" }, { 667, 16, 33, "Fujitsu M2614T (171.9 MB)" }, { 782, 2, 27, "Western Digital WD93024-A (20.6 MB)" }, { 782, 4, 27, "Western Digital WD93044-A (41.2 MB)" }, { 845, 3, 35, "Toshiba MK232FC (45.4 MB"}, { 845, 7, 35, "Toshiba MK234FC (106 MB"}, { 965, 5, 17, "Quantum ProDrive 40AT (40 MB)"}, { 965, 10, 17, "Quantum ProDrive 80AT (80 MB)"}, {1050, 2, 40, "Teac SD-340 (41 MB)"}, { 776, 8, 33, "Conner CP-3104 (100 MB)"}, { 745, 4, 28, "Priam 3804M 40.7 MB"}, { 0, 0, 0, ""} }; struct ideinfo { unsigned genconf, fixcyls, remcyls, heads, bytetrack, /* bytes per track */ bytesector, /* bytes per sector */ sectors, /* sectors per track */ byteisg, /* bytes intesector gap */ byteplo, /* bytes in sync */ worduniq; /* words unique status */ char serial[20]; unsigned contype, /* controller type */ bufsiz, /* buffer size in 512 byte blocks */ byteecc; /* ECC bytes trasferred in read/write long */ char firmware[8], /* firmware revision */ model[40]; /* model ID */ unsigned secsint, /* number of sectors transferred per interrupt */ dblword, /* double word transfer flag */ writepro; /* write protect */ }; printinfo() { struct ideinfo *id = (struct ideinfo *)secbuf; int i, capacity; char c, *type; /* get disk type by characteristics */ for (i=0; idetypes[i].cylinders != 0; ++i) if (idetypes[i].cylinders == id->fixcyls && idetypes[i].heads == id->heads && idetypes[i].sectors == id->sectors) { type = idetypes[i].name; break; } /* unknow disk */ if (idetypes[i].cylinders == 0) { type = "Unknown "; /* calculate capacity in MB */ capacity = (id->fixcyls * id->heads * id->sectors) / 2048; itoa(capacity, type+8, 10); strcat(type, "Mbytes"); } /* swap bytes in ASCII fields except for WD disks */ if (i != 4 && i != 5) { for(i=0; i < 10; ++i) { c = id->serial[i*2]; id->serial[i*2] = id->serial[i*2+1]; id->serial[i*2+1] = c; } for(i=0; i < 4; ++i) { c = id->firmware[i*2]; id->firmware[i*2] = id->firmware[i*2+1]; id->firmware[i*2+1] = c; } for(i=0; i < 20; ++i) { c = id->model[i*2]; id->model[i*2] = id->model[(i*2)+1]; id->model[i*2+1] = c; } } printf("Informations for drive %u, %s\n" "Drive ID: %04X\n" "%u fixed cylinders, %u removables\n" "%u heads, %u sectors\n" "Serial number: %.20s\n" "Controller firmware: %.8s\n" "Controller model: %.408s\n" "%u bytes per track, %u per sector\n" "%u bytes of intersector gap, %u of sync\n" "Controller type %u, buffer %u Kbytes\n" "%u bytes of ECC, %u sector(s) transferred per interrupt\n" "Double word transfer %s allowed, %s write protected.\n", drive, type, id->genconf, id->fixcyls, id->remcyls, id->heads, id->sectors, id->serial, id->firmware, id->model, id->bytetrack, id->bytesector, id->byteisg, id->byteplo, id->contype, id->bufsiz / 2, id->byteecc, id->secsint, id->dblword ? "" : "not", id->writepro ? "" : "not"); } main() { drive = 0; /* disable interrupt from drive */ outp(HDC_FIXED, HDC_FIXED_IRQ); /* set up task file parameter */ outp(HDC_SDH, 0xA0 + (drive<<4)); /* issue read parameters */ outp(HDC_COMMAND, HDC_COMMAND_READPAR); /* read up sector */ readsect(); /* print out info */ printinfo(); } readsect() { int i; /* poll DRQ */ while(inp(HDC_STATUS) & HDC_STATUS_BUSY) ; /* read up sector */ for (i=0; i<256; ++i) secbuf[i] = inpw(HDC_DATA); }