Changeset 73 for hacks/xtide/writeatatest.c
- Timestamp:
- Dec 20, 2015, 10:17:34 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
hacks/xtide/writeatatest.c
r72 r73 33 33 #include <io.h> 34 34 #include <conio.h> 35 #include "atalib.h" 36 35 37 36 38 /********************************************************************************************************************************* … … 52 54 #define X86_EFL_CF 1 53 55 54 /* The necessary I/O ports, indexed by "bus". */55 #define ATA_PORT_SHIFT 1 /* For XT-CF trick */56 #define ATA_REG_DATA(x) (x)57 #define ATA_REG_FEATURES(x) ((x) + (1 << ATA_PORT_SHIFT))58 #define ATA_REG_SECTOR_COUNT(x) ((x) + (2 << ATA_PORT_SHIFT))59 60 #define ATA_REG_SECTOR_NUMBER(x) ((x) + (3 << ATA_PORT_SHIFT))61 #define ATA_REG_CYLINDER_LOW(x) ((x) + (4 << ATA_PORT_SHIFT))62 #define ATA_REG_CYLINDER_HIGH(x) ((x) + (5 << ATA_PORT_SHIFT))63 #define ATA_REG_HEAD(x) ((x) + (6 << ATA_PORT_SHIFT))64 65 #define ATA_REG_LBA_0_7(x) ((x) + (3 << ATA_PORT_SHIFT))66 #define ATA_REG_LBA_8_15(x) ((x) + (4 << ATA_PORT_SHIFT))67 #define ATA_REG_LBA_16_23(x) ((x) + (5 << ATA_PORT_SHIFT))68 #define ATA_REG_LBA_24_27_MODE(x) ((x) + (6 << ATA_PORT_SHIFT))69 #define ATA_LBA_MODE UINT8_C(0x40) /**< Selects LBA mode in ATA_REG_LBA_24_27_MODE. */70 71 #define ATA_REG_DEVICE_SELECT(x) ((x) + (6 << ATA_PORT_SHIFT))72 #define ATA_REG_COMMAND(x) ((x) + (7 << ATA_PORT_SHIFT))73 74 75 #define ATA_REG_STATUS(x) ATA_REG_COMMAND(x)76 #define ATA_REG_ALT_STATUS(x) ATA_REG_CONTROL(x)77 #define ATA_STS_BUSY UINT8_C(0x80)78 #define ATA_STS_DRDY UINT8_C(0x40)79 #define ATA_STS_DF UINT8_C(0x20)80 #define ATA_STS_DSC UINT8_C(0x10)81 #define ATA_STS_DRQ UINT8_C(0x08)82 #define ATA_STS_CORR UINT8_C(0x04)83 #define ATA_STS_IDX UINT8_C(0x02)84 #define ATA_STS_ERR UINT8_C(0x01)85 86 #define ATA_REG_ERROR(x) ATA_REG_FEATURES(x)87 #define ATA_ERR_RSVR UINT8_C(0x80)88 #define ATA_ERR_UNC UINT8_C(0x40)89 #define ATA_ERR_MC UINT8_C(0x20)90 #define ATA_ERR_IDNF UINT8_C(0x10)91 #define ATA_ERR_MCR UINT8_C(0x08)92 #define ATA_ERR_ABRT UINT8_C(0x04)93 #define ATA_ERR_TKNONF UINT8_C(0x02)94 #define ATA_ERR_AMNF UINT8_C(0x01)95 96 #define ATA_REG_CONTROL(x) ((x) + (14 << ATA_PORT_SHIFT))97 #define ATA_CTL_IEN UINT8_C(0x02) /**< Interrupt enable. */98 #define ATA_CTL_SRST UINT8_C(0x04) /**< software reset */99 100 #define ATA_CMD_NOP UINT8_C(0x00)101 #define ATA_CMD_READ_SECTORS UINT8_C(0x20)102 #define ATA_CMD_READ_SECTORS_NR UINT8_C(0x21)103 #define ATA_CMD_READ_LONG UINT8_C(0x22)104 #define ATA_CMD_READ_LONG_NR UINT8_C(0x23)105 #define ATA_CMD_WRITE_SECTORS UINT8_C(0x30)106 #define ATA_CMD_WRITE_SECTORS_NR UINT8_C(0x31)107 #define ATA_CMD_WRITE_LONG UINT8_C(0x32)108 #define ATA_CMD_WRITE_LONG_NR UINT8_C(0x33)109 #define ATA_CMD_INIT_DEVICE_PARAMS UINT8_C(0x91)110 #define ATA_CMD_SET_FEATURES UINT8_C(0xef)111 #define ATA_CMD_IDENTIFY_DEVICE UINT8_C(0xec)112 113 114 #define ATA_DEV_MASTER UINT8_C(0x00) /**< Master device selection bit value. */115 #define ATA_DEV_SLAVE UINT8_C(0x10) /**< Slave device selection bit value. */116 117 #define ATA_FEATURE_EN_8BIT_DATA UINT8_C(0x01)118 #define ATA_FEATURE_DI_8BIT_DATA UINT8_C(0x81)119 #define ATA_FEATURE_EN_WRITE_CACHE UINT8_C(0x02)120 #define ATA_FEATURE_DI_WRITE_CACHE UINT8_C(0x82)121 #define ATA_FEATURE_SET_XFERMODE UINT8_C(0x03)122 #define ATA_FV_XFERMODE_PIO_MODE_DEFAULT UINT8_C(0x00)123 #define ATA_FV_XFERMODE_PIO_MODE_DEFAULT_NO_IORDY UINT8_C(0x01)124 #define ATA_FV_XFERMODE_PIO_MODE_XXX_FLAG UINT8_C(0x08)125 #define ATA_FV_XFERMODE_SWDMA_MODE_XXX_FLAG UINT8_C(0x10)126 #define ATA_FV_XFERMODE_MWDMA_MODE_XXX_FLAG UINT8_C(0x20)127 128 /** Delay a bit by reading PIC mask. Should take 4-5 bus cycles,129 * and thus be more than the required 400ns delay on old computers. */130 #define ATA_DELAY_400NS() do { inp(0x21); } while (0)131 132 133 56 134 57 /********************************************************************************************************************************* 135 58 * Global Variables * 136 59 *********************************************************************************************************************************/ 137 uint16_t g_uBasePort = 0x300;138 uint16_t g_uPortShift = 1;139 uint8_t g_fUseLbaMode = 1;140 uint8_t g_f8BitData = 1;141 uint8_t g_bDevice = ATA_DEV_MASTER;142 60 uint8_t g_bDrv = 0x80; 143 144 145 uint16_t g_cHeads;146 uint8_t g_cSectorsPerTrack;147 uint16_t g_cCylinders;148 uint16_t g_cSectorsPerCylinder;149 150 /** The result of the identify command. */151 uint16_t g_awIdentify[256];152 153 154 size_t AtaPrintStatus(FILE *pOut, uint8_t bSts)155 {156 size_t cch = fprintf(pOut, "%#x", bSts);157 if (bSts & ATA_STS_BUSY) cch += fprintf(pOut, " busy");158 if (bSts & ATA_STS_DRDY) cch += fprintf(pOut, " drdy");159 if (bSts & ATA_STS_DF ) cch += fprintf(pOut, " df");160 if (bSts & ATA_STS_DSC ) cch += fprintf(pOut, " dsc");161 if (bSts & ATA_STS_DRQ ) cch += fprintf(pOut, " drq");162 if (bSts & ATA_STS_CORR) cch += fprintf(pOut, " corr");163 if (bSts & ATA_STS_IDX ) cch += fprintf(pOut, " idx");164 if (bSts & ATA_STS_ERR ) cch += fprintf(pOut, " err");165 return cch;166 }167 168 size_t AtaPrintError(FILE *pOut, uint8_t bErr)169 {170 size_t cch = fprintf(pOut, "%#x", bErr);171 if (bErr & ATA_ERR_RSVR ) cch += fprintf(pOut, " rsrv");172 if (bErr & ATA_ERR_UNC ) cch += fprintf(pOut, " unc");173 if (bErr & ATA_ERR_MC ) cch += fprintf(pOut, " mc");174 if (bErr & ATA_ERR_IDNF ) cch += fprintf(pOut, " idnf");175 if (bErr & ATA_ERR_MCR ) cch += fprintf(pOut, " mcr");176 if (bErr & ATA_ERR_ABRT ) cch += fprintf(pOut, " abrt");177 if (bErr & ATA_ERR_TKNONF) cch += fprintf(pOut, " tknonf");178 if (bErr & ATA_ERR_AMNF ) cch += fprintf(pOut, " amnf");179 return cch;180 }181 182 static int AtaError(uint8_t bSts, const char *pszFormat, ...)183 {184 va_list va;185 186 fprintf(stderr, "error: ");187 va_start(va, pszFormat);188 vfprintf(stderr, pszFormat, va);189 va_end(va);190 191 fprintf(stderr, "\n status=");192 AtaPrintStatus(stderr, bSts);193 fprintf(stderr, "\n error= ");194 AtaPrintError(stderr, inp(ATA_REG_ERROR(g_uBasePort)));195 fprintf(stderr, "\n");196 197 return -1;198 }199 200 uint8_t AtaWaitBusy(void)201 {202 uint32_t cLoops = 0;203 uint8_t bStatus;204 do205 {206 if ((++cLoops & 0xfffff) == 0)207 fprintf(stderr, "AtaWaitBusyForData: cLoops=%#lx\n", cLoops);208 bStatus = inp(ATA_REG_STATUS(g_uBasePort));209 } while ((bStatus & (ATA_STS_BUSY | ATA_STS_ERR)) == ATA_STS_BUSY);210 return bStatus;211 }212 213 uint8_t AtaWaitBusyDeviceReady(void)214 {215 uint32_t cLoops = 0;216 uint8_t bStatus;217 do218 {219 if ((++cLoops & 0xfffff) == 0)220 fprintf(stderr, "AtaWaitBusyForData: cLoops=%#lx\n", cLoops);221 bStatus = inp(ATA_REG_STATUS(g_uBasePort));222 } while ( (bStatus & (ATA_STS_BUSY | ATA_STS_DRDY)) != ATA_STS_DRDY223 && !(bStatus & ATA_STS_ERR) );224 return bStatus;225 }226 227 uint8_t AtaWaitBusyForData(void)228 {229 uint32_t cLoops = 0;230 uint8_t bStatus;231 do232 {233 if ((++cLoops & 0xfffff) == 0)234 fprintf(stderr, "AtaWaitBusyForData: cLoops=%#lx\n", cLoops);235 bStatus = inp(ATA_REG_STATUS(g_uBasePort));236 } while ( (bStatus & (ATA_STS_BUSY | ATA_STS_DRQ)) != ATA_STS_DRQ237 && !(bStatus & ATA_STS_ERR) );238 return bStatus;239 }240 241 uint8_t AtaSubmitCommandAndWait(uint8_t bCommand)242 {243 244 outp(ATA_REG_COMMAND(g_uBasePort), bCommand);245 ATA_DELAY_400NS();246 return AtaWaitBusy();247 }248 249 uint8_t AtaSubmitCommandAndWaitForData(uint8_t bCommand)250 {251 252 outp(ATA_REG_COMMAND(g_uBasePort), bCommand);253 ATA_DELAY_400NS();254 return AtaWaitBusyForData();255 }256 257 uint8_t AtaSelectDevice(uint8_t bDevice)258 {259 outp(ATA_REG_DEVICE_SELECT(g_uBasePort), g_bDevice);260 ATA_DELAY_400NS();261 return AtaWaitBusyDeviceReady();262 }263 264 void AtaSetSectorAddress(uint32_t iSector, uint8_t bDevice)265 {266 if (g_fUseLbaMode)267 {268 outp(ATA_REG_LBA_0_7(g_uBasePort), iSector & 0xff);269 outp(ATA_REG_LBA_8_15(g_uBasePort), (iSector >> 8) & 0xff);270 outp(ATA_REG_LBA_16_23(g_uBasePort), (iSector >> 16) & 0xff);271 outp(ATA_REG_LBA_24_27_MODE(g_uBasePort), ((iSector >> 24) & 0x0f) | ATA_LBA_MODE | bDevice);272 }273 else274 {275 uint16_t iCyl = iSector / g_cSectorsPerCylinder;276 uint16_t iRem = iSector % g_cSectorsPerCylinder;277 uint8_t iHd = iRem / g_cSectorsPerTrack;278 uint8_t iSec = iRem % g_cSectorsPerTrack;279 280 outp(ATA_REG_SECTOR_NUMBER(g_uBasePort), iSec);281 outp(ATA_REG_CYLINDER_LOW(g_uBasePort), iCyl & 0xff);282 outp(ATA_REG_CYLINDER_HIGH(g_uBasePort), iCyl >> 8);283 outp(ATA_REG_HEAD(g_uBasePort), iHd | bDevice);284 }285 }286 287 void AtaReadData(void *pvBuf, size_t cb, uint8_t f8BitData)288 {289 uint16_t uDataPort = ATA_REG_DATA(g_uBasePort);290 uint16_t *pu16 = (uint16_t *)pvBuf;291 cb >>= 1;292 293 if (f8BitData)294 {295 while (cb-- > 0)296 {297 uint8_t b1 = inp(uDataPort);298 uint8_t b2 = inp(uDataPort);299 *pu16++ = b1 | ((uint16_t)b2 << 8);300 }301 }302 else303 {304 while (cb-- > 0)305 *pu16++ = inpw(uDataPort);306 }307 }308 309 ////static uint8_t AtaWaitForDataRequest(size_t cbLeft)310 ////{311 //// uint16_t uAltStsPort = ATA_REG_ALT_STATUS(g_uBasePort);312 //// uint8_t bStsFirst = inp(uAltStsPort);313 //// uint8_t bSts = bStsFirst;314 //// uint32_t cLoops = 0;315 //// do316 //// {317 //// if (++cLoops & 0xffff)318 //// {319 ////static unsigned x = 0;320 ////if (x < 16)321 ////{322 //// printf("AtaWaitForDataRequest: bFirst=%#x bLast=%#x cbLeft=%#x\n", bStsFirst, bSts, cbLeft);323 //// x++;324 ////}325 //// break;326 //// }327 //// bSts = inp(uAltStsPort);328 //// } while (!(bSts & (ATA_STS_DRQ | ATA_STS_ERR)));329 //// return bSts;330 ////}331 332 void xchg(uint8_t volatile *pb);333 #pragma aux xchg = \334 "xchg [si], cx" \335 "xchg [si], cx" \336 "xchg [si], cx" \337 "xchg [si], cx" \338 parm [si] \339 modify exact [cx];340 341 void AtaWriteData(void const *pvBuf, size_t cb, uint8_t f8BitData)342 {343 // uint16_t uAltStsPort = ATA_REG_ALT_STATUS(g_uBasePort);344 uint16_t register uDataPort = ATA_REG_DATA(g_uBasePort);345 346 if (f8BitData)347 {348 #if 0349 uint8_t const * volatile pbSrc = (uint8_t const *)pvBuf;350 uint8_t volatile ab[64];351 uint8_t volatile *pb = &ab[0];352 while (((uintptr_t)pb & 0x1f) != 0x1f)353 pb++;354 //uint8_t bSts1, bSts2;355 inp(0x21);356 xchg(pb);357 358 while (cb-- > 0)359 {360 uint8_t b = *pbSrc++;361 xchg(pb);362 outp(uDataPort, b);363 xchg(pb);364 b = *pbSrc++;365 xchg(pb);366 //inp(0x21);367 outp(uDataPort, b);368 xchg(pb);369 //inp(0x21);370 //if (cb < 30)371 //{372 // if ((cb & 3) == 3)373 // printf("bSts1=%#x bSts2=%#x ", bSts1, bSts2);374 // else375 // printf("bSts1=%#x bSts2=%#x\n", bSts1, bSts2);376 //}377 }378 inp(0x21);379 #else380 uint16_t const *pu16 = (uint16_t const *)pvBuf;381 cb >>= 1;382 while (cb-- > 0)383 {384 uint16_t register u16 = *pu16++;385 outp(uDataPort, (uint8_t)u16);386 outp(uDataPort, (uint8_t)(u16 >> 8));387 }388 #endif389 }390 else391 {392 uint16_t const *pu16 = (uint16_t const *)pvBuf;393 cb >>= 1;394 while (cb-- > 0)395 outp(uDataPort, *pu16++);396 }397 }398 399 int AtaReadSector(uint32_t iSector, void *pvBuf)400 {401 uint8_t bSts = AtaWaitBusy();402 if (bSts & ATA_STS_ERR)403 return AtaError(bSts, "Prepping for reading sector %lu", iSector);404 405 printf("AtaReadSector #2\n");406 bSts = AtaSelectDevice(g_bDevice);407 if (bSts & ATA_STS_ERR)408 return AtaError(bSts, "Selecting device for reading sector %lu", iSector);409 410 //printf("AtaReadSector #3\n");411 outp(ATA_REG_FEATURES(g_uBasePort), 0x0);412 outp(ATA_REG_SECTOR_COUNT(g_uBasePort), 1);413 AtaSetSectorAddress(iSector, g_bDevice);414 415 //printf("AtaReadSector #4\n");416 bSts = AtaSubmitCommandAndWaitForData(ATA_CMD_READ_SECTORS);417 if (bSts & ATA_STS_ERR)418 return AtaError(bSts, "Reading sector %lu", iSector);419 420 if (!(bSts & ATA_STS_DRQ))421 return AtaError(bSts, "DRQ not set after reading sector %lu", iSector);422 423 424 //printf("AtaReadSector #5\n");425 AtaReadData(pvBuf, 512, g_f8BitData);426 //printf("AtaReadSector #6: bSts=%#x\n", inp(ATA_REG_ALT_STATUS(g_uBasePort)));427 bSts = inp(ATA_REG_STATUS(g_uBasePort));428 if ((bSts & ATA_STS_DRQ))429 return AtaError(bSts, "DRQ is still set after reading sector %lu", iSector);430 if ((bSts & ATA_STS_ERR))431 return AtaError(bSts, "ERR is set after reading sector %lu (#2)", iSector);432 return 0;433 }434 435 int AtaWriteSector(uint32_t iSector, void const *pvBuf)436 {437 //int x = printf("AtaWriteSector #1\n");438 uint8_t bSts = AtaWaitBusy();439 if (bSts & ATA_STS_ERR)440 return AtaError(bSts, "Prepping for writing sector %lu", iSector);441 printf("AtaWriteSector #2\n");442 443 bSts = AtaSelectDevice(g_bDevice);444 if (bSts & ATA_STS_ERR)445 return AtaError(bSts, "Selecting device for writing sector %lu", iSector);446 447 outp(ATA_REG_FEATURES(g_uBasePort), 0x0);448 outp(ATA_REG_SECTOR_COUNT(g_uBasePort), 1);449 AtaSetSectorAddress(iSector, g_bDevice);450 451 //printf("AtaWriteSector #3\n");452 bSts = AtaSubmitCommandAndWaitForData(ATA_CMD_WRITE_SECTORS);453 if (bSts & ATA_STS_ERR)454 return AtaError(bSts, "writing sector (#1) %lu", iSector);455 if (!(bSts & ATA_STS_DRQ))456 return AtaError(bSts, "DRQ not set after writing sector (#1) %lu", iSector);457 458 //printf("AtaWriteSector #4\n");459 AtaWriteData(pvBuf, 512, g_f8BitData);460 //printf("AtaWriteSector #5\n");461 ATA_DELAY_400NS();462 bSts = AtaWaitBusy();463 //printf("AtaWriteSector #6\n");464 if (bSts & ATA_STS_ERR)465 return AtaError(bSts, "writing sector (#2) %lu", iSector);466 if (bSts & ATA_STS_DRQ)467 return AtaError(bSts, "DRQ is set after writing sector (#2) %lu", iSector);468 469 return 0;470 }471 472 int AtaIdentifyDevice(uint8_t bDevice, void *pvBuf)473 {474 uint8_t bSts = AtaWaitBusy();475 if (bSts & ATA_STS_ERR)476 return AtaError(bSts, "Prepping for device %#x identification", bDevice);477 478 bSts = AtaSelectDevice(g_bDevice);479 if (bSts & ATA_STS_ERR)480 return AtaError(bSts, "Selecting device %#x for identification", bDevice);481 482 outp(ATA_REG_FEATURES(g_uBasePort), 0);483 outp(ATA_REG_SECTOR_COUNT(g_uBasePort), 0);484 outp(ATA_REG_SECTOR_NUMBER(g_uBasePort), 0);485 outp(ATA_REG_CYLINDER_LOW(g_uBasePort), 0);486 outp(ATA_REG_CYLINDER_HIGH(g_uBasePort), 0);487 //outp(ATA_REG_HEAD(g_uBasePort), g_bDevice);488 489 bSts = AtaSubmitCommandAndWaitForData(ATA_CMD_IDENTIFY_DEVICE);490 if (bSts & ATA_STS_ERR)491 return AtaError(bSts, "Device %#x identification", bDevice);492 if (!(bSts & ATA_STS_DRQ))493 return AtaError(bSts, "DRQ not set after device %#x identification", bDevice);494 495 AtaReadData(pvBuf, 512, g_f8BitData);496 return 0;497 }498 499 int AtaSetFeature(uint8_t bDevice, uint8_t bFeature, uint8_t bValue)500 {501 uint8_t bSts = AtaWaitBusy();502 if (bSts & ATA_STS_ERR)503 return AtaError(bSts, "Prepping for setting device %#x feature %#x (%#x)", bDevice, bFeature, bValue);504 505 bSts = AtaSelectDevice(g_bDevice);506 if (bSts & ATA_STS_ERR)507 return AtaError(bSts, "Selecting device %#x for setting feature %#x (%#x)", bDevice, bFeature, bValue);508 509 outp(ATA_REG_FEATURES(g_uBasePort), bFeature);510 outp(ATA_REG_SECTOR_COUNT(g_uBasePort), 0);511 outp(ATA_REG_SECTOR_NUMBER(g_uBasePort), bValue);512 outp(ATA_REG_CYLINDER_LOW(g_uBasePort), 0);513 outp(ATA_REG_CYLINDER_HIGH(g_uBasePort), 0);514 //outp(ATA_REG_HEAD(g_uBasePort), g_bDevice);515 516 bSts = AtaSubmitCommandAndWait(ATA_CMD_SET_FEATURES);517 if (bSts & ATA_STS_ERR)518 return AtaError(bSts, "Setting device %#x feature %#x (%#x)", bDevice, bFeature, bValue);519 if (bSts & ATA_STS_DRQ)520 return AtaError(bSts, "DRQ is set after setting device %#x feature %#x (%#x)", bDevice, bFeature, bValue);521 return 0;522 }523 524 int AtaInitDeviceParams(uint8_t bDevice, uint8_t cSectorsPerTrack, uint8_t cHeads)525 {526 uint8_t bSts = AtaWaitBusy();527 if (bSts & ATA_STS_ERR)528 return AtaError(bSts, "Prepping for device %#x parameter initialization", bDevice);529 530 bSts = AtaSelectDevice(g_bDevice);531 if (bSts & ATA_STS_ERR)532 return AtaError(bSts, "Selecting device for device %#x parameter initialization", bDevice);533 534 outp(ATA_REG_FEATURES(g_uBasePort), 0);535 outp(ATA_REG_SECTOR_COUNT(g_uBasePort), cSectorsPerTrack);536 outp(ATA_REG_SECTOR_NUMBER(g_uBasePort), 0);537 outp(ATA_REG_CYLINDER_LOW(g_uBasePort), 0);538 outp(ATA_REG_CYLINDER_HIGH(g_uBasePort), 0);539 outp(ATA_REG_HEAD(g_uBasePort), g_bDevice | cHeads);540 541 bSts = AtaSubmitCommandAndWait(ATA_CMD_INIT_DEVICE_PARAMS);542 if (bSts & ATA_STS_ERR)543 return AtaError(bSts, "Device %#x parameter initialization", bDevice);544 if (bSts & ATA_STS_DRQ)545 return AtaError(bSts, "DRQ is set after device %#x parameter initialization", bDevice);546 return 0;547 }548 549 int AtaReset(void)550 {551 uint8_t bSts;552 553 /* Set the reset flat. */554 outp(ATA_REG_CONTROL(g_uBasePort), ATA_CTL_SRST);555 556 /* Wait for the busy flag response. */557 ATA_DELAY_400NS();558 ATA_DELAY_400NS();559 while (!(bSts = inp(ATA_REG_STATUS(g_uBasePort))) & ATA_STS_BUSY)560 ATA_DELAY_400NS();561 562 /* Clear the reset flag. */563 outp(ATA_REG_CONTROL(g_uBasePort), 0);564 ATA_DELAY_400NS();565 566 /* Wait for the controller to become non-busy. */567 bSts = AtaWaitBusy();568 if (bSts & ATA_STS_ERR)569 return AtaError(bSts, "Software reset failed");570 return 0;571 }572 573 574 int AtaInit(void)575 {576 uint8_t bSts = inp(ATA_REG_ALT_STATUS(g_uBasePort));577 printf("alt status=");578 AtaPrintStatus(stdout, bSts);579 printf("\n");580 581 bSts = inp(ATA_REG_STATUS(g_uBasePort));582 printf(" status=");583 AtaPrintStatus(stdout, bSts);584 printf("\n");585 586 if (AtaReset() != 0)587 return -1;588 589 /* Enable 8-bit data transfers (just to be on the safe side). */590 AtaSetFeature(g_bDevice, ATA_FEATURE_EN_8BIT_DATA, 0);591 592 /* Identify the device. */593 memset(g_awIdentify, 0, sizeof(g_awIdentify));594 if (AtaIdentifyDevice(g_bDevice, g_awIdentify) != 0)595 return -1;596 597 /** @todo this is rather simple... */598 g_cCylinders = g_awIdentify[1];599 g_cHeads = g_awIdentify[3];600 g_cSectorsPerTrack = g_awIdentify[6];601 g_cSectorsPerCylinder = g_cHeads * g_cSectorsPerTrack;602 printf("Device %#x parameters: %u cylinders, %u heads, %u sectors\n",603 g_bDevice, g_cCylinders, g_cHeads, g_cSectorsPerTrack);604 605 /* Disable stuff and try select pio modes. */606 AtaSetFeature(g_bDevice, ATA_FEATURE_DI_WRITE_CACHE, 0);607 AtaSetFeature(g_bDevice, ATA_FEATURE_SET_XFERMODE, ATA_FV_XFERMODE_PIO_MODE_DEFAULT_NO_IORDY);608 AtaSetFeature(g_bDevice, ATA_FEATURE_SET_XFERMODE, ATA_FV_XFERMODE_PIO_MODE_XXX_FLAG | 0);609 610 return 0;611 }612 613 614 61 615 62 … … 746 193 747 194 748 int GetDriveParams( void)195 int GetDriveParams(uint8_t bDevice) 749 196 { 750 197 #ifdef USE_INT13H 751 198 return Int13hInit(); 752 199 #else 753 return AtaInit();200 return 0; 754 201 #endif 755 202 } … … 791 238 */ 792 239 uint32_t iSector = 3; 240 uint8_t bDevice = ATA_DEV_MASTER; 793 241 g_bDrv = 0x80; 794 g_bDevice = ATA_DEV_MASTER;795 242 796 243 if (argc > 3) … … 812 259 if (argc > 2) 813 260 { 814 unsigned long uTmp = strtoul(argv[2], NULL, 0); 815 if (uTmp < 0x80 || uTmp > 0x8f) 816 { 817 fprintf(stderr, "error: drive number is out of bounds: %s (%lu)\n", argv[1], uTmp); 261 if (AtaInitFromArgv(2, argc, argv) != 0) 818 262 return usage(); 819 }820 g_bDrv = (uint8_t)uTmp;821 g_bDevice = g_bDrv == 0x80 ? ATA_DEV_MASTER : ATA_DEV_SLAVE; /* simplified */822 263 } 823 264 … … 825 266 * Detect drive parameters. 826 267 */ 827 if (GetDriveParams( ) == 0)268 if (GetDriveParams(bDevice) == 0) 828 269 { 829 270 static uint8_t s_abSaved[512];
Note:
See TracChangeset
for help on using the changeset viewer.