add stubs for the ata trim/smart commands. make sysexplorer's ata and ahci modules...
[AROS.git] / rom / devs / ata / waitnano.c
blobe2f4c94dce427f09f68b45b30fe5aafe17cf6922
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <proto/exec.h>
10 /* We want all other bases obtained from our base */
11 #define __NOLIBBASE__
13 #include <proto/timer.h>
15 #include <exec/types.h>
16 #include <devices/timer.h>
17 #include <exec/io.h>
19 #include "timer.h"
20 #include "ata.h"
22 BOOL ata_Calibrate(struct IORequest* tmr, struct ataBase *base)
24 register ULONG x;
25 register ULONG scale = 0x8000; // min iterations...
26 volatile register ULONG t = 1;
27 struct timeval t1, t2;
28 struct Device *TimerBase = tmr->io_Device;
30 D(bug("[ATA ] Calibration started\n"));
32 while (scale <= 0x80000000)
34 Forbid();
35 GetUpTime(&t1);
36 for (x = 1; x < scale; x++)
37 t = (((t + x) * t) - x) / x; // add, mul, sub, div, trivial benchmark.
39 GetUpTime(&t2);
40 Permit();
41 SubTime(&t2, &t1);
43 // ok, it's going to be totally insane, if secs > 1.
44 if (t2.tv_secs != 0)
46 bug("[ATA ] micro wait useless.\n");
47 return FALSE;
50 /*
51 * we expect at least 10000 times longer period, which should be 'achievable'
52 * unlikely we will cross the magic boundary here of 4 billion instructions in 10 millisecond (yielding 400'000MIPS?)
53 * on the other side, if we go as low as 1, then 4 iterations of add/sub/mul/div is perfectly fine yielding a bit more than 400ns...
56 if (t2.tv_micro >= 10000)
57 break;
58 scale <<= 1;
61 D(bug("[ATA ] Executed %ld ops in %ldus\n", scale, t2.tv_micro));
63 // always round up to the next value.. so 30.9 -> 31, 5.1 -> 6, etc
64 x = (x + t2.tv_micro - 1) / t2.tv_micro;
65 x = (x+9) / 10;
67 bug("[ATA ] Approximate number of iterations per 100 nanoseconds: %ld\n", x);
68 base->ata_ItersPer100ns = x;
69 return TRUE;
72 void ata_WaitNano(register ULONG ns, struct ataBase *base)
74 volatile register ULONG t = 1;
75 ns = (ns + 99) / 100;
76 ns *= base->ata_ItersPer100ns;
77 while (ns > 0)
79 t = (((t + ns) * t) - ns) / ns; // add, mul, sub, div, trivial benchmark.
80 --ns;