Be sure diag is executed even if there is nothing on ab_Dev[0]. Needed for sam port.
[AROS.git] / rom / devs / ata / lowlevel.c
blob1045123c5bfa62d2e6f25fe0839803b886729491
1 /*
2 Copyright © 2004-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*
10 * PARTIAL CHANGELOG:
11 * DATE NAME ENTRY
12 * ---------- ------------------ -------------------------------------------------------------------
13 * 2006-12-20 T. Wiszkowski Updated ATA Packet Interface to handle ATAPI/SCSI Commands
14 * 2008-01-06 T. Wiszkowski Corrected and completed ATA Packet Interface handling. PIO transfers fully operational.
15 * 2008-01-07 T. Wiszkowski Added initial DMA support for Direct SCSI commands. Corrected atapi
16 * READ and WRITE commands to pass proper transfer size to the atapi_SendPacket
17 * as discovered by mschulz
18 * 2008-01-25 T. Wiszkowski Rebuilt, rearranged and partially fixed 60% of the code here
19 * Enabled implementation to scan for other PCI IDE controllers
20 * Implemented ATAPI Packet Support for both read and write
21 * Corrected ATAPI DMA handling
22 * Fixed major IDE enumeration bugs severely handicapping transfers with more than one controller
23 * Compacted source and implemented major ATA support procedure
24 * Improved DMA and Interrupt management
25 * Removed obsolete code
26 * 2008-01-26 T. Wiszkowski Restored 32bit io
27 * Removed memory dump upon RequestSense
28 * 2008-02-08 T. Wiszkowski Fixed DMA accesses for direct scsi devices,
29 * Corrected IO Areas to allow ATA to talk to PCI controllers
30 * 2008-03-03 T. Wiszkowski Added drive reselection + setup delay on Init
31 * 2008-03-29 T. Wiszkowski Restored error on 64bit R/W access to non-64bit capable atapi devices
32 * cleared debug flag
33 * 2008-03-30 T. Wiszkowski Added workaround for interrupt collision handling; fixed SATA in LEGACY mode.
34 * nForce and Intel SATA chipsets should now be operational (nForce confirmed)
35 * 2008-03-31 M. Schulz The ins/outs function definitions used only in case of x86 and x86_64 architectures.
36 * Otherwise, function declaratons are emitted.
37 * 2008-04-01 M. Schulz Use C functions ata_ins[wl] ata_outs[wl]
38 * 2008-04-03 T. Wiszkowski Fixed IRQ flood issue, eliminated and reduced obsolete / redundant code
39 * 2008-04-05 T. Wiszkowski Improved IRQ management
40 * 2008-04-07 T. Wiszkowski Changed bus timeout mechanism
41 * increased failure timeout values to cover rainy day scenarios
42 * 2008-04-20 T. Wiszkowski Corrected the flaw in drive identification routines leading to ocassional system hangups
43 * 2008-05-11 T. Wiszkowski Remade the ata trannsfers altogether, corrected the pio/irq handling
44 * medium removal, device detection, bus management and much more
45 * 2008-05-12 P. Fedin Explicitly enable multisector transfers on the drive
46 * 2008-05-18 T. Wiszkowski Added extra checks to prevent duplicating drive0 in drive0 only configs
47 * 2008-05-18 T. Wiszkowski Replaced static C/H/S with more accurate calcs, should make HDTB and other tools see right capacity
48 * 2008-05-19 T. Wiszkowski Updated ATA DMA handling and transfer wait operation to allow complete transfer before dma_StopDMA()
49 * 2008-05-30 T. Wiszkowski Corrected CHS calculation for larger disks
50 * 2008-06-03 K. Smiechowicz Added 400ns delay in ata_WaitBusyTO before read of device status.
51 * 2008-06-25 P. Fedin Added "nomulti" flag
52 * PIO works correctly again
53 * 2008-11-28 T. Wiszkowski updated test unit ready to suit individual taste of hw manufacturers
54 * 2009-01-20 J. Koivisto Modified bus reseting scheme
55 * 2009-02-04 T. Wiszkowski Disabled ATA debug on official builds
56 * 2009-03-05 T. Wiszkowski remade timeouts, added timer-based and benchmark-based delays.
57 * 2011-05-19 P. Fedin The Big Rework. Separated bus-specific code. Made 64-bit-friendly.
60 * TODO:
61 * - put a critical section around DMA transfers (shared dma channels)
64 #define DEBUG 0
65 // use #define xxx(a) D(a) to enable particular sections.
66 #if DEBUG
67 #define DIRQ(a) D(a)
68 #define DIRQ_MORE(a)
69 #define DUMP(a) D(a)
70 #define DUMP_MORE(a)
71 #define DATA(a) D(a)
72 #define DATAPI(a) D(a)
73 #define DINIT(a) (a)
74 #else
75 #define DIRQ(a) do { } while (0)
76 #define DIRQ_MORE(a) do { } while (0)
77 #define DUMP(a) do { } while (0)
78 #define DUMP_MORE(a) do { } while (0)
79 #define DATA(a) do { } while (0)
80 #define DATAPI(a) do { } while (0)
81 #define DINIT(a) do { } while (0)
82 #endif
84 #include <aros/debug.h>
85 #include <exec/types.h>
86 #include <exec/exec.h>
87 #include <exec/resident.h>
88 #include <utility/utility.h>
89 #include <oop/oop.h>
91 #include <proto/exec.h>
92 #include <devices/timer.h>
94 #include "ata.h"
95 #include "timer.h"
98 Prototypes of static functions from lowlevel.c. I do not want to make them
99 non-static as I'd like to remove as much symbols from global table as possible.
100 Besides some of this functions could conflict with old ide.device or any other
101 device.
103 static BYTE ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
104 static BYTE ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
105 static BYTE ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
106 static BYTE ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
107 static BYTE ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
108 static BYTE ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
109 static BYTE ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
110 static BYTE ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
111 static BYTE ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
112 static BYTE ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
113 static BYTE ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
114 static BYTE ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
115 static BYTE ata_Eject(struct ata_Unit *);
116 static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout);
118 static BYTE atapi_EndCmd(struct ata_Unit *unit);
120 static BYTE atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
121 static BYTE atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
122 static BYTE atapi_Eject(struct ata_Unit *);
124 static void common_SetBestXferMode(struct ata_Unit* unit);
126 #if DEBUG
127 static void dump(APTR mem, ULONG len)
129 register int i, j = 0;
131 DUMP_MORE(for (j=0; j<(len+15)>>4; ++j))
133 bug("[ATA ] %06lx: ", j<<4);
135 for (i=0; i<len-(j<<4); i++)
137 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
138 if (i == 15)
139 break;
142 for (i=0; i<len-(j<<4); i++)
144 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
146 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
147 if (i == 15)
148 break;
150 bug("\n");
153 #endif
155 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
157 register int i = size;
159 while (size--)
160 str2[size ^ 1] = str1[size];
162 while (i > 0 && str2[--i] <= ' ')
163 str2[i] = '\0';
167 * a STUB function for commands not supported by this particular device
169 static BYTE ata_STUB(struct ata_Unit *au)
171 bug("[ATA%02ld] CALLED STUB FUNCTION (GENERIC). THIS OPERATION IS NOT "
172 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
173 return CDERR_NOCMD;
176 static BYTE ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len,
177 APTR buf, ULONG* act)
179 bug("[ATA%02ld] CALLED STUB FUNCTION (IO32). THIS OPERATION IS NOT "
180 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
181 return CDERR_NOCMD;
184 static BYTE ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len,
185 APTR buf, ULONG* act)
187 bug("[ATA%02ld] CALLED STUB FUNCTION -- IO ACCESS TO BLOCK %08lx:%08lx, LENGTH %08lx. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum, (blk >> 32), (blk & 0xffffffff), len);
188 return CDERR_NOCMD;
191 static BYTE ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
193 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
194 return CDERR_NOCMD;
197 static inline struct ata_Unit* ata_GetSelectedUnit(struct ata_Bus* bus)
199 return bus->ab_SelectedUnit;
202 static inline UBYTE ata_ReadStatus(struct ata_Bus *bus)
204 return bus->ab_Driver->ata_in(ata_Status, bus->ab_Port, bus->ab_DriverData);
207 static inline UBYTE ata_ReadAltStatus(struct ata_Bus *bus)
209 return bus->ab_Driver->ata_in(ata_AltStatus, bus->ab_Alt, bus->ab_DriverData);
212 static inline BOOL ata_SelectUnit(struct ata_Unit* unit)
214 struct ata_Bus *bus = unit->au_Bus;
216 if (unit == bus->ab_SelectedUnit)
217 return TRUE;
219 ATA_OUT(unit->au_DevMask, ata_DevHead, bus->ab_Port);
223 ata_WaitNano(400);
224 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
226 while (0 != (ATAF_BUSY & ata_ReadStatus(bus)));
228 bus->ab_SelectedUnit = unit;
230 return TRUE;
234 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
235 * part of code moved here from ata.c to reduce containment
237 void ata_IRQSignalTask(struct ata_Bus *bus)
239 bus->ab_IntCnt++;
240 Signal(bus->ab_Task, 1UL << bus->ab_SleepySignal);
243 /* PIO-only: IDE doublers don't have real AltStatus register.
244 * Do not assume reading AltStatus does not clear interrupt request.
246 void ata_HandleIRQ(struct ata_Bus *bus)
248 struct ata_Unit *unit = ata_GetSelectedUnit(bus);
249 UBYTE status;
250 BOOL for_us = FALSE;
253 * don't waste your time on checking other devices.
254 * pass irq ONLY if task is expecting one;
256 if ((unit != NULL) && (0 != bus->ab_HandleIRQ))
259 * The DMA status register indicates all interrupt types, not
260 * just DMA interrupts. However, if there's no DMA port, we have
261 * to rely on the busy flag, which is incompatible with IRQ sharing.
263 if (unit->au_DMAPort != 0) {
264 status = ata_ReadAltStatus(bus);
265 for_us =
266 (ATA_IN(dma_Status, unit->au_DMAPort) & DMAF_Interrupt) != 0;
267 } else {
268 status = ata_ReadStatus(bus);
269 for_us = (status & ATAF_BUSY) == 0;
273 if (for_us)
276 * Acknowledge interrupt (note that the DMA interrupt bit should be
277 * cleared for all interrupt types)
279 if (unit->au_DMAPort != 0) {
280 ATA_OUT(ATA_IN(dma_Status, unit->au_DMAPort) |
281 DMAF_Error | DMAF_Interrupt, dma_Status, unit->au_DMAPort);
282 status = ata_ReadStatus(bus);
286 * ok, we have a routine to handle any form of transmission etc.
288 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
289 bus->ab_HandleIRQ(unit, status);
291 return;
294 DIRQ_MORE({
296 * if we got *here* then device is most likely not expected to have an irq.
298 status = ata_ReadAltStatus(bus);
299 bug("[ATA%02ld] IRQ: Checking busy flag: ", unit->au_UnitNum);
301 if (0 == (ATAF_BUSY & status))
303 bug("device ready. Dumping details:\n");
305 bug("[ATA ] STATUS: %02lx\n", status);
306 bug("[ATA ] ALT STATUS: %02lx\n", ATA_IN(ata_AltStatus, bus->ab_Alt));
307 bug("[ATA ] ERROR: %02lx\n", ATA_IN(ata_Error, bus->ab_Port));
308 bug("[ATA ] IRQ: REASON: %02lx\n", ATA_IN(atapi_Reason, bus->ab_Port));
310 else
312 bug("device still busy. ignoring irq.\n");
317 void ata_IRQSetHandler(struct ata_Unit *unit, void (*handler)(struct ata_Unit*, UBYTE), APTR piomem, ULONG blklen, ULONG piolen)
319 if (NULL != handler)
320 unit->au_cmd_error = 0;
322 unit->au_cmd_data = piomem;
323 unit->au_cmd_length = (piolen < blklen) ? piolen : blklen;
324 unit->au_cmd_total = piolen;
325 unit->au_Bus->ab_HandleIRQ = handler;
328 void ata_IRQNoData(struct ata_Unit *unit, UBYTE status)
330 if (status & ATAF_BUSY)
331 return;
333 if ((unit->au_cmd_error == 0) && (status & ATAF_ERROR))
334 unit->au_cmd_error = HFERR_BadStatus;
336 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit->au_UnitNum, status));
337 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
338 ata_IRQSignalTask(unit->au_Bus);
341 void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status)
343 if (status & ATAF_DATAREQ) {
344 DIRQ(bug("[ATA ] IRQ: PIOReadData - DRQ.\n"));
345 unit->au_ins(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length, unit->au_Bus->ab_DriverData);
348 * indicate it's all done here
350 unit->au_cmd_data += unit->au_cmd_length;
351 unit->au_cmd_total -= unit->au_cmd_length;
352 if (unit->au_cmd_total) {
353 if (unit->au_cmd_length > unit->au_cmd_total)
354 unit->au_cmd_length = unit->au_cmd_total;
355 return;
357 DIRQ(bug("[ATA ] IRQ: PIOReadData - transfer completed.\n"));
359 ata_IRQNoData(unit, status);
362 void ata_PIOWriteBlk(struct ata_Unit *unit)
364 unit->au_outs(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length, unit->au_Bus->ab_DriverData);
367 * indicate it's all done here
369 unit->au_cmd_data += unit->au_cmd_length;
370 unit->au_cmd_total -= unit->au_cmd_length;
371 if (unit->au_cmd_length > unit->au_cmd_total)
372 unit->au_cmd_length = unit->au_cmd_total;
375 void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status)
377 if (status & ATAF_DATAREQ) {
378 DIRQ(bug("[ATA ] IRQ: PIOWriteData - DRQ.\n"));
379 ata_PIOWriteBlk(unit);
380 return;
382 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
383 ata_IRQNoData(unit, status);
386 void ata_IRQDMAReadWrite(struct ata_Unit *unit, UBYTE status)
388 UBYTE stat = ATA_IN(dma_Status, unit->au_DMAPort);
390 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", unit->au_UnitNum, status, stat));
392 if ((status & ATAF_ERROR) || (stat & DMAF_Error))
394 /* This is turned on in order to help Phantom - Pavel Fedin <sonic_amiga@rambler.ru> */
395 bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", unit->au_UnitNum, status, stat);
396 bug("[ATA%02ld] IRQ: ERROR %02lx\n", unit->au_UnitNum, ATA_IN(atapi_Error, unit->au_Bus->ab_Port));
397 bug("[ATA ] IRQ: DMA Failed.\n");
399 unit->au_cmd_error = HFERR_DMA;
400 ata_IRQNoData(unit, status);
402 else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
404 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
405 ata_IRQNoData(unit, status);
409 void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status)
411 ULONG port = unit->au_Bus->ab_Port;
412 ULONG size = 0;
413 LONG remainder = 0;
414 UBYTE reason = ATA_IN(atapi_Reason, port);
415 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason));
417 /* have we failed yet? */
418 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
419 ata_IRQNoData(unit, status);
420 if (status & ATAF_ERROR)
422 ata_IRQNoData(unit, status);
423 return;
426 /* anything for us please? */
427 if (ATAPIF_READ != (reason & ATAPIF_MASK))
428 return;
430 size = ATA_IN(atapi_ByteCntH, port) << 8 | ATA_IN(atapi_ByteCntL, port);
431 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
433 if (size > unit->au_cmd_total)
435 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
436 remainder = size - unit->au_cmd_total;
437 size = unit->au_cmd_total;
440 unit->au_ins(unit->au_cmd_data, port, size, unit->au_Bus->ab_DriverData);
441 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
442 unit->au_cmd_total -= size;
444 DIRQ(bug("[ATAPI] IRQ: %lu bytes read.\n", size));
446 for (; remainder > 0; remainder -= 2)
447 unit->au_ins(&size, port, 2, unit->au_Bus->ab_DriverData);
449 if (unit->au_cmd_total == 0)
450 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
453 void ata_IRQPIOWriteAtapi(struct ata_Unit *unit, UBYTE status)
455 ULONG port = unit->au_Bus->ab_Port;
456 ULONG size = 0;
457 UBYTE reason = ATA_IN(atapi_Reason, port);
458 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason));
460 /* have we failed yet? */
461 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
462 ata_IRQNoData(unit, status);
463 if (status & ATAF_ERROR)
465 ata_IRQNoData(unit, status);
466 return;
469 /* anything for us please? */
470 if (ATAPIF_WRITE != (reason & ATAPIF_MASK))
471 return;
473 size = ATA_IN(atapi_ByteCntH, port) << 8 | ATA_IN(atapi_ByteCntL, port);
474 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
476 if (size > unit->au_cmd_total)
478 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
479 size = unit->au_cmd_total;
482 unit->au_outs(unit->au_cmd_data, port, size, unit->au_Bus->ab_DriverData);
483 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
484 unit->au_cmd_total -= size;
486 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size));
488 if (unit->au_cmd_total == 0)
489 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
493 * wait for timeout or drive ready
495 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout)
497 UBYTE status;
498 ULONG sigs = SIGBREAKF_CTRL_C;
499 ULONG step = 0;
500 BOOL res = TRUE;
502 if (unit->au_Bus->ab_Base->ata_Poll)
503 irq = FALSE;
506 * set up bus timeout
508 Disable();
509 unit->au_Bus->ab_Timeout = tout;
510 Enable();
512 sigs |= (irq ? (1 << unit->au_Bus->ab_SleepySignal) : 0);
513 status = ATA_IN(ata_AltStatus, unit->au_Bus->ab_Alt);
515 if (irq)
518 * wait for either IRQ or TIMEOUT (unless device seems to be a
519 * phantom SATAPI drive, in which case we fake a timeout)
521 DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n",
522 unit->au_UnitNum, status));
523 if (status != 0)
524 step = Wait(sigs);
525 else
526 step = SIGBREAKF_CTRL_C;
529 * now if we did reach timeout, then there's no point in going ahead.
531 if (SIGBREAKF_CTRL_C & step)
533 bug("[ATA%02ld] Timeout while waiting for device to complete"
534 " operation\n", unit->au_UnitNum);
535 res = FALSE;
538 * do nothing if the interrupt eventually arrives
540 Disable();
541 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
542 Enable();
545 else
547 while (status & ATAF_BUSY)
549 ++step;
552 * every 16n rounds do some extra stuff
554 if ((step & 16) == 0)
557 * huhm. so it's been 16n rounds already. any timeout yet?
559 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
561 DIRQ(bug("[ATA%02ld] Device still busy after timeout."
562 " Aborting\n", unit->au_UnitNum));
563 res = FALSE;
564 break;
568 * no timeout just yet, but it's not a good idea to keep
569 * spinning like that. let's give the system some time.
571 ata_WaitNano(400);
574 status = ATA_IN(ata_AltStatus, unit->au_Bus->ab_Alt);
579 * clear up all our expectations
581 Disable();
582 unit->au_Bus->ab_Timeout = -1;
583 Enable();
586 * get final status and clear any interrupt (may be neccessary if we
587 * were polling, for example)
589 status = ATA_IN(ata_Status, unit->au_Bus->ab_Port);
592 * be nice to frustrated developer
594 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit->au_UnitNum,
595 status, res));
598 * release old junk
600 SetSignal(0, sigs);
603 * and say it went fine (i mean it)
605 if (stout)
606 *stout = status;
607 return res;
611 * Procedure for sending ATA command blocks
612 * it appears LARGE but there's a lot of COMMENTS here :)
613 * handles *all* ata commands (no data, pio and dma)
614 * naturally could be split at some point in the future
615 * depends if anyone believes that the change for 50 lines
616 * would make slow ATA transfers any faster
618 static BYTE ata_exec_cmd(struct ata_Unit* unit, ata_CommandBlock *block)
620 ULONG port = unit->au_Bus->ab_Port;
621 BYTE err = 0;
622 APTR mem = block->buffer;
623 UBYTE status;
625 if (FALSE == ata_SelectUnit(unit))
626 return IOERR_UNITBUSY;
628 switch (block->type)
630 case CT_LBA28:
631 if (block->sectors > 256)
633 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", unit->au_UnitNum, block->sectors);
634 return IOERR_BADLENGTH;
637 /* note:
638 * we want the above to fall in here!
639 * we really do (checking for secmul)
642 case CT_LBA48:
643 if (block->sectors > 65536)
645 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", unit->au_UnitNum, block->sectors);
646 return IOERR_BADLENGTH;
648 if (block->secmul == 0)
650 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", unit->au_UnitNum);
651 block->secmul = 1;
653 break;
655 case CT_NoBlock:
656 break;
658 default:
659 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid command type %lx. Aborting.\n", unit->au_UnitNum, block->type);
660 return IOERR_NOCMD;
663 block->actual = 0;
664 D(bug("[ATA%02ld] ata_exec_cmd: Executing command %02lx\n", unit->au_UnitNum, block->command));
666 if (block->feature != 0)
667 ATA_OUT(block->feature, ata_Feature, port);
670 * - set LBA and sector count
672 switch (block->type)
674 case CT_LBA28:
675 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 28bit LBA addressing (OLD)\n", unit->au_UnitNum));
677 ATA_OUT(((block->blk >> 24) & 0x0f) | 0x40 | unit->au_DevMask, ata_DevHead, port);
678 ATA_OUT(block->blk >> 16, ata_LBAHigh, port);
679 ATA_OUT(block->blk >> 8, ata_LBAMid, port);
680 ATA_OUT(block->blk, ata_LBALow, port);
681 ATA_OUT(block->sectors, ata_Count, port);
682 break;
684 case CT_LBA48:
685 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 48bit LBA addressing (NEW)\n", unit->au_UnitNum));
687 ATA_OUT(0x40 | unit->au_DevMask, ata_DevHead, port);
688 ATA_OUT(block->blk >> 40, ata_LBAHigh, port);
689 ATA_OUT(block->blk >> 32, ata_LBAMid, port);
690 ATA_OUT(block->blk >> 24, ata_LBALow, port);
692 ATA_OUT(block->blk >> 16, ata_LBAHigh, port);
693 ATA_OUT(block->blk >> 8, ata_LBAMid, port);
694 ATA_OUT(block->blk, ata_LBALow, port);
696 ATA_OUT(block->sectors >> 8, ata_Count, port);
697 ATA_OUT(block->sectors, ata_Count, port);
698 break;
700 case CT_NoBlock:
701 DATA(bug("[ATA%02ld] ata_exec_cmd: Command does not address any block\n", unit->au_UnitNum));
702 break;
705 switch (block->method)
707 case CM_PIOWrite:
708 ata_IRQSetHandler(unit, &ata_IRQPIOWrite, mem, block->secmul << unit->au_SectorShift, block->length);
709 break;
711 case CM_PIORead:
712 ata_IRQSetHandler(unit, &ata_IRQPIORead, mem, block->secmul << unit->au_SectorShift, block->length);
713 break;
715 case CM_DMARead:
716 if (FALSE == dma_SetupPRDSize(unit, mem, block->length, TRUE))
717 return IOERR_ABORTED;
718 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
719 dma_StartDMA(unit);
720 break;
722 case CM_DMAWrite:
723 if (FALSE == dma_SetupPRDSize(unit, mem, block->length, FALSE))
724 return IOERR_ABORTED;
725 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
726 dma_StartDMA(unit);
727 break;
729 case CM_NoData:
730 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
731 break;
733 default:
734 return IOERR_NOCMD;
735 break;
739 * send command now
740 * let drive propagate its signals
742 DATA(bug("[ATA%02ld] ata_exec_cmd: Sending command\n", unit->au_UnitNum));
743 ATA_OUT(block->command, ata_Command, port);
744 ata_WaitNano(400);
745 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
748 * In case of PIO write the drive won't issue an IRQ before first
749 * data transfer, so we should poll the status and send the first
750 * block upon request.
752 if (block->method == CM_PIOWrite)
754 if (FALSE == ata_WaitBusyTO(unit, TIMEOUT, FALSE, &status)) {
755 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - no response from device\n", unit->au_UnitNum));
756 return IOERR_UNITBUSY;
758 if (status & ATAF_DATAREQ) {
759 DATA(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - DRQ.\n", unit->au_UnitNum));
760 ata_PIOWriteBlk(unit);
762 else
764 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - bad status: %02X\n", status));
765 return HFERR_BadStatus;
770 * wait for drive to complete what it has to do
772 if (FALSE == ata_WaitBusyTO(unit, TIMEOUT, TRUE, NULL))
774 bug("[ATA%02ld] ata_exec_cmd: Device is late - no response\n", unit->au_UnitNum);
775 err = IOERR_UNITBUSY;
777 else
778 err = unit->au_cmd_error;
780 DATA(bug("[ATA%02ld] ata_exec_cmd: Command done\n", unit->au_UnitNum));
782 * clean up DMA
783 * don't use 'mem' pointer here as it's already invalid.
785 if (block->method == CM_DMARead)
787 dma_StopDMA(unit);
788 dma_Cleanup(block->buffer, block->length, TRUE);
790 else if (block->method == CM_DMAWrite)
792 dma_StopDMA(unit);
793 dma_Cleanup(block->buffer, block->length, FALSE);
796 D(bug("[ATA%02ld] ata_exec_cmd: return code %ld\n", unit->au_UnitNum, err));
797 return err;
801 * atapi packet iface
803 BYTE atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, LONG datalen, BOOL *dma, BOOL write)
805 *dma = *dma && (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
806 LONG err = 0;
808 UBYTE cmd[12] = {
811 register int t=5,l=0;
812 ULONG port = unit->au_Bus->ab_Port;
814 if (((UBYTE*)packet)[0] > 0x1f)
815 t+= 4;
816 if (((UBYTE*)packet)[0] > 0x5f)
817 t+= 2;
819 switch (((UBYTE*)packet)[0])
821 case 0x28: // read10
822 case 0xa8: // read12
823 case 0xbe: // readcd
824 case 0xb9: // readcdmsf
825 case 0x2f: // verify
826 case 0x2a: // write
827 case 0xaa: // write12
828 case 0x2e: // writeverify
829 case 0xad: // readdvdstructure
830 case 0xa4: // reportkey
831 case 0xa3: // sendkey
832 break;
833 default:
834 *dma = FALSE;
837 while (l<=t)
839 cmd[l] = ((UBYTE*)packet)[l];
840 ++l;
843 DATAPI({
844 bug("[ATA%02lx] Sending %s ATA packet: ", unit->au_UnitNum, (*dma) ? "DMA" : "PIO");
845 l=0;
846 while (l<=t)
848 bug("%02lx ", ((UBYTE*)cmd)[l]);
849 ++l;
851 bug("\n");
853 if (datalen & 1)
854 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
857 datalen = (datalen+1)&~1;
859 if (FALSE == ata_SelectUnit(unit))
861 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
862 return IOERR_UNITBUSY;
866 * tell device whether we want to read or write and if we want a dma transfer
868 ATA_OUT(((*dma) ? 1 : 0) |
869 (((unit->au_Drive->id_DMADir & 0x8000) && !write) ? 4 : 0),
870 atapi_Features, port);
871 ATA_OUT((datalen & 0xff), atapi_ByteCntL, port);
872 ATA_OUT((datalen >> 8) & 0xff, atapi_ByteCntH, port);
875 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
876 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
878 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
879 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
880 ATA_OUT(ATA_PACKET, atapi_Command, port);
881 ata_WaitNano(400);
882 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
884 ata_WaitBusyTO(unit, TIMEOUT, (unit->au_Drive->id_General & 0x60) == 0x20,
885 NULL);
886 if (0 == (ata_ReadStatus(unit->au_Bus) & ATAF_DATAREQ))
887 return HFERR_BadStatus;
890 * setup appropriate hooks
892 if (datalen == 0)
893 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
894 else if (*dma)
895 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
896 else if (write)
897 ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, 0, datalen);
898 else
899 ata_IRQSetHandler(unit, &ata_IRQPIOReadAtapi, data, 0, datalen);
901 if (*dma)
903 DATAPI(bug("[ATAPI] Starting DMA\n"));
904 dma_StartDMA(unit);
907 DATAPI(bug("[ATAPI] Sending packet\n"));
908 unit->au_outs(cmd, unit->au_Bus->ab_Port, 12, unit->au_Bus->ab_DriverData);
909 ata_WaitNano(400);
910 DATAPI(bug("[ATAPI] Status after packet: %lx\n",
911 ata_ReadAltStatus(unit->au_Bus)));
914 * Wait for command to complete. Note that two interrupts will occur
915 * before we wake up if this is a PIO data transfer
917 if (ata_WaitTO(unit->au_Bus->ab_Timer, TIMEOUT, 0,
918 1 << unit->au_Bus->ab_SleepySignal) == 0)
920 DATAPI(bug("[DSCSI] Command timed out.\n"));
921 err = IOERR_UNITBUSY;
923 else
924 err = atapi_EndCmd(unit);
926 if (*dma)
928 dma_StopDMA(unit);
929 dma_Cleanup(data, datalen, !write);
932 DATAPI(bug("[ATAPI] IO error code %ld\n", err));
933 return err;
936 BYTE atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
938 APTR buffer = cmd->scsi_Data;
939 ULONG length = cmd->scsi_Length;
940 BYTE err = 0;
941 BOOL dma = FALSE;
943 cmd->scsi_Actual = 0;
945 DATAPI(bug("[DSCSI] Sending packet!\n"));
948 * setup DMA & push command
949 * it does not really mean we will use dma here btw
951 if ((unit->au_XferModes & AF_XFER_DMA) && (length !=0) && (buffer != 0))
953 dma = TRUE;
954 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
956 if (FALSE == dma_SetupPRDSize(unit, buffer, length, TRUE))
957 dma = FALSE;
959 else
961 if (FALSE == dma_SetupPRDSize(unit, buffer, length, FALSE))
962 dma = FALSE;
966 err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0);
968 DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); });
971 * on check condition - grab sense data
973 DATAPI(bug("[ATA%02lx] atapi_DirectSCSI: SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err));
974 if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
976 DATAPI(bug("[DSCSI] atapi_DirectSCSI: Packet Failed. Calling atapi_RequestSense\n"));
977 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
978 DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
981 return err;
985 * chops the large transfers into set of smaller transfers
986 * specifically useful when requested transfer size is >256 sectors for 28bit commands
988 static BYTE ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
990 BYTE err = 0;
991 ULONG part;
992 ULONG max=256;
993 ULONG count=blk->sectors;
995 if (blk->type == CT_LBA48)
996 max <<= 8;
998 DATA(bug("[ATA%02ld] ata_exec_blk: Accessing %ld sectors starting from %x%08x\n", unit->au_UnitNum, count, (ULONG)(blk->blk >> 32), (ULONG)blk->blk));
999 while ((count > 0) && (err == 0))
1001 part = (count > max) ? max : count;
1002 blk->sectors = part;
1003 blk->length = part << unit->au_SectorShift;
1005 DATA(bug("[ATA%02ld] Transfer of %ld sectors from %x%08x\n", unit->au_UnitNum, part, (ULONG)(blk->blk >> 32), (ULONG)blk->blk));
1006 err = ata_exec_cmd(unit, blk);
1007 DATA(bug("[ATA%02ld] ata_exec_blk: ata_exec_cmd returned %lx\n", unit->au_UnitNum, err));
1009 blk->blk += part;
1010 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1011 count -= part;
1013 return err;
1017 * Initial device configuration that suits *all* cases
1019 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1021 struct ata_Unit *unit=NULL;
1023 DINIT(bug("[ATA ] ata_init_unit(%ld)\n", u));
1025 unit = bus->ab_Units[u];
1026 if (NULL == unit)
1027 return FALSE;
1029 unit->au_Bus = bus;
1030 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1031 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1032 unit->au_DevMask = 0xa0 | (u << 4);
1035 * 32-bit transfer routines are options.
1036 * If the bus doesn't support this, they will be NULLs.
1038 if (bus->ab_Base->ata_32bit && bus->ab_Driver->ata_insl)
1040 unit->au_ins = bus->ab_Driver->ata_insl;
1041 unit->au_outs = bus->ab_Driver->ata_outsl;
1043 else
1045 unit->au_ins = bus->ab_Driver->ata_insw;
1046 unit->au_outs = bus->ab_Driver->ata_outsw;
1048 unit->au_SectorShift= 9; /* this really has to be set here. */
1050 NEWLIST(&unit->au_SoftList);
1053 * since the stack is always handled by caller
1054 * it's safe to stub all calls with one function
1056 unit->au_Read32 = ata_STUB_IO32;
1057 unit->au_Read64 = ata_STUB_IO64;
1058 unit->au_Write32 = ata_STUB_IO32;
1059 unit->au_Write64 = ata_STUB_IO64;
1060 unit->au_Eject = ata_STUB;
1061 unit->au_DirectSCSI = ata_STUB_SCSI;
1062 unit->au_Identify = ata_STUB;
1063 return TRUE;
1066 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1068 struct ata_Unit *unit=NULL;
1071 * this stuff always goes along the same way
1072 * WARNING: NO INTERRUPTS AT THIS POINT!
1074 DINIT(bug("[ATA ] ata_setup_unit(%ld,%ld)\n", bus->ab_BusNum, u));
1076 unit = bus->ab_Units[u];
1077 if (NULL == unit)
1078 return FALSE;
1080 ata_SelectUnit(unit);
1082 if (unit->au_DMAPort != 0
1083 && (ATA_IN(dma_Status, unit->au_DMAPort) & 0x80) != 0)
1084 bug("[ATA%02ld] ata_setup_unit: WARNING: Controller only supports "
1085 "DMA on one bus at a time. DMAStatus=%lx\n", unit->au_UnitNum,
1086 ATA_IN(dma_Status, unit->au_DMAPort));
1088 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE, NULL))
1090 DINIT(bug("[ATA%02ld] ata_setup_unit: ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1091 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1092 unit->au_Drive = 0;
1093 return FALSE;
1096 switch (bus->ab_Dev[u])
1099 * safe fallback settings
1101 case DEV_SATAPI:
1102 case DEV_ATAPI:
1103 case DEV_SATA:
1104 case DEV_ATA:
1105 unit->au_Identify = ata_Identify;
1106 break;
1108 default:
1109 DINIT(bug("[ATA%02ld] ata_setup_unit: Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1110 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1111 unit->au_Drive = 0;
1112 return FALSE;
1115 DINIT(bug("[ATA ] ata_setup_unit: Enabling IRQs\n"));
1116 ATA_OUT(0x0, ata_AltControl, bus->ab_Alt);
1119 * now make unit self diagnose
1121 if (unit->au_Identify(unit) != 0)
1123 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1124 unit->au_Drive = NULL;
1125 return FALSE;
1128 return TRUE;
1132 * ata[pi] identify
1134 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1136 BOOL dma = FALSE;
1137 #if 0 // We can't set drive modes unless we also set the controller's timing registers
1138 UBYTE type=0;
1139 ata_CommandBlock acb =
1141 ATA_SET_FEATURES,
1142 0x03,
1143 0x01,
1144 0x00,
1145 0x00,
1146 0x00,
1147 0x00,
1148 0x00,
1149 0x00,
1150 CM_NoData,
1151 CT_LBA28
1153 #endif
1154 DINIT(bug("[ATA%02ld] common_SetXferMode: Trying to set mode %d\n", unit->au_UnitNum, mode));
1156 if ((unit->au_DMAPort == 0) && (mode >= AB_XFER_MDMA0))
1158 DINIT(bug("[ATA%02ld] common_SetXferMode: This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1159 common_SetBestXferMode(unit);
1160 return;
1164 * first, ONLY for ATA devices, set new commands
1166 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1168 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1170 if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI))
1172 ata_IRQSetHandler(unit, ata_IRQNoData, NULL, 0, 0);
1173 ATA_OUT(unit->au_Drive->id_RWMultipleSize & 0xFF, ata_Count, unit->au_Bus->ab_Port);
1174 ATA_OUT(ATA_SET_MULTIPLE, ata_Command, unit->au_Bus->ab_Port);
1175 ata_WaitBusyTO(unit, -1, TRUE, NULL);
1177 unit->au_Read32 = ata_ReadMultiple32;
1178 unit->au_Write32 = ata_WriteMultiple32;
1179 if (unit->au_XferModes & AF_XFER_48BIT)
1181 unit->au_Read64 = ata_ReadMultiple64;
1182 unit->au_Write64 = ata_WriteMultiple64;
1185 else
1187 unit->au_Read32 = ata_ReadSector32;
1188 unit->au_Write32 = ata_WriteSector32;
1189 if (unit->au_XferModes & AF_XFER_48BIT)
1191 unit->au_Read64 = ata_ReadSector64;
1192 unit->au_Write64 = ata_WriteSector64;
1195 dma=FALSE;
1197 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1199 unit->au_Read32 = ata_ReadDMA32;
1200 unit->au_Write32 = ata_WriteDMA32;
1201 if (unit->au_XferModes & AF_XFER_48BIT)
1203 unit->au_Read64 = ata_ReadDMA64;
1204 unit->au_Write64 = ata_WriteDMA64;
1206 dma=TRUE;
1208 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1210 unit->au_Read32 = ata_ReadDMA32;
1211 unit->au_Write32 = ata_WriteDMA32;
1212 if (unit->au_XferModes & AF_XFER_48BIT)
1214 unit->au_Read64 = ata_ReadDMA64;
1215 unit->au_Write64 = ata_WriteDMA64;
1217 dma=TRUE;
1219 else
1221 unit->au_Read32 = ata_ReadSector32;
1222 unit->au_Write32 = ata_WriteSector32;
1223 if (unit->au_XferModes & AF_XFER_48BIT)
1225 unit->au_Read64 = ata_ReadSector64;
1226 unit->au_Write64 = ata_WriteSector64;
1228 dma=FALSE;
1232 #if 0 // We can't set drive modes unless we also set the controller's timing registers
1233 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1235 type = 8 + (mode - AB_XFER_PIO0);
1237 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1239 type = 32 + (mode - AB_XFER_MDMA0);
1241 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1243 type = 64 + (mode - AB_XFER_UDMA0);
1245 else
1247 type = 0;
1250 acb.sectors = type;
1251 if (0 != ata_exec_cmd(unit, &acb))
1253 DINIT(bug("[ATA%02ld] common_SetXferMode: ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1256 if (unit->au_DMAPort)
1258 type = ATA_IN(dma_Status, unit->au_DMAPort);
1259 type &= 0x60;
1260 if (dma)
1262 type |= 1 << (5 + (unit->au_UnitNum & 1));
1264 else
1266 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1269 DINIT(bug("[DSCSI] common_SetXferMode: Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1271 ata_SelectUnit(unit);
1272 ATA_OUT(type, dma_Status, unit->au_DMAPort);
1273 if (type == (ATA_IN(dma_Status, unit->au_DMAPort) & 0x60))
1275 DINIT(bug("[DSCSI] common_SetXferMode: New DMA Status: %02lx\n", type));
1277 else
1279 DINIT(bug("[DSCSI] common_SetXferMode: Failed to modify DMA state for this device\n"));
1280 dma = FALSE;
1283 #endif
1285 if (dma)
1286 unit->au_XferModes |= AF_XFER_DMA;
1287 else
1288 unit->au_XferModes &= ~AF_XFER_DMA;
1291 static void common_SetBestXferMode(struct ata_Unit* unit)
1293 int iter;
1294 int max = AB_XFER_UDMA6;
1296 if (unit->au_Bus->ab_Base->ata_NoDMA || (unit->au_DMAPort == 0)
1297 || ( !(unit->au_Drive->id_MWDMASupport & 0x0700)
1298 && !(unit->au_Drive->id_UDMASupport & 0x7f00)))
1301 * make sure you reduce scan search to pio here!
1302 * otherwise this and above function will fall into infinite loop
1304 DINIT(bug("[ATA%02ld] common_SetBestXferMode: DMA is disabled for"
1305 " this drive.\n", unit->au_UnitNum));
1306 max = AB_XFER_PIO4;
1308 else if (!(unit->au_Flags & AF_80Wire))
1310 DINIT(bug("[ATA%02ld] common_SetBestXferMode: "
1311 "An 80-wire cable has not been detected for this drive. "
1312 "Disabling modes above UDMA2.\n", unit->au_UnitNum));
1313 max = AB_XFER_UDMA2;
1316 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1318 if (unit->au_XferModes & (1<<iter))
1320 common_SetXferMode(unit, iter);
1321 return;
1324 bug("[ATA%02ld] common_SetBestXferMode: ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1325 common_SetXferMode(unit, AB_XFER_PIO0);
1328 void common_DetectXferModes(struct ata_Unit* unit)
1330 int iter;
1332 DINIT(bug("[ATA%02ld] common_DetectXferModes: Supports\n", unit->au_UnitNum));
1334 if (unit->au_Drive->id_Commands4 & (1 << 4))
1336 DINIT(bug("[ATA%02ld] common_DetectXferModes: - Packet interface\n", unit->au_UnitNum));
1337 unit->au_XferModes |= AF_XFER_PACKET;
1338 unit->au_DirectSCSI = atapi_DirectSCSI;
1340 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1342 /* ATAPI devices do not use this bit. */
1343 DINIT(bug("[ATA%02ld] common_DetectXferModes: - 48bit I/O\n", unit->au_UnitNum));
1344 unit->au_XferModes |= AF_XFER_48BIT;
1347 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1349 DINIT(bug("[ATA%02ld] common_DetectXferModes: - LBA Addressing\n", unit->au_UnitNum));
1350 unit->au_XferModes |= AF_XFER_LBA;
1352 else
1354 DINIT(bug("[ATA%02ld] common_DetectXferModes: - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1357 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1359 DINIT(bug("[ATA%02ld] common_DetectXferModes: - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1360 unit->au_XferModes |= AF_XFER_RWMULTI;
1363 DINIT(bug("[ATA%02ld] common_DetectXferModes: - PIO0 PIO1 PIO2 ",
1364 unit->au_UnitNum));
1365 unit->au_XferModes |= AF_XFER_PIO(0) | AF_XFER_PIO(1) | AF_XFER_PIO(2);
1366 if (unit->au_Drive->id_ConfigAvailable & (1 << 1))
1368 for (iter = 0; iter < 2; iter++)
1370 if (unit->au_Drive->id_PIOSupport & (1 << iter))
1372 DINIT(bug("PIO%ld ", 3 + iter));
1373 unit->au_XferModes |= AF_XFER_PIO(3 + iter);
1376 DINIT(bug("\n"));
1379 if ((unit->au_Drive->id_ConfigAvailable & (1 << 1)) &&
1380 (unit->au_Drive->id_Capabilities & (1<<8)))
1382 DINIT(bug("[ATA%02ld] common_DetectXferModes: DMA:\n", unit->au_UnitNum));
1383 if (unit->au_Drive->id_MWDMASupport & 0xff)
1385 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1386 for (iter = 0; iter < 3; iter++)
1388 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1390 unit->au_XferModes |= AF_XFER_MDMA(iter);
1391 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1393 DINIT(bug("[MDMA%ld] ", iter));
1395 else
1397 DINIT(bug("MDMA%ld ", iter));
1401 DINIT(bug("\n"));
1404 if (unit->au_Drive->id_UDMASupport & 0xff)
1406 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1407 for (iter = 0; iter < 7; iter++)
1409 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1411 unit->au_XferModes |= AF_XFER_UDMA(iter);
1412 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1414 DINIT(bug("[UDMA%ld] ", iter));
1416 else
1418 DINIT(bug("UDMA%ld ", iter));
1422 DINIT(bug("\n"));
1427 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1428 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1429 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x) >> 32) | (((QUAD)(AROS_LE2LONG((x) & 0xffffffff))) << 32)
1431 BYTE ata_Identify(struct ata_Unit* unit)
1433 BOOL atapi = unit->au_Bus->ab_Dev[unit->au_UnitNum & 1] & 0x80;
1434 ata_CommandBlock acb =
1436 atapi ? ATA_IDENTIFY_ATAPI : ATA_IDENTIFY_DEVICE,
1442 unit->au_Drive,
1443 sizeof(struct DriveIdent),
1445 CM_PIORead,
1446 CT_NoBlock
1449 /* If the right command fails, try the wrong one. If both fail, abort */
1450 DINIT(bug("[ATA%02ld] ata_Identify: Executing ATA_IDENTIFY_%s command\n",
1451 unit->au_UnitNum, atapi ? "ATAPI" : "DEVICE"));
1452 if (ata_exec_cmd(unit, &acb))
1454 acb.command = atapi ? ATA_IDENTIFY_DEVICE : ATA_IDENTIFY_ATAPI;
1455 DINIT(bug("[ATA%02ld] ata_Identify: Executing ATA_IDENTIFY_%s command"
1456 " instead\n", unit->au_UnitNum, atapi ? "DEVICE" : "ATAPI"));
1457 if (ata_exec_cmd(unit, &acb))
1459 DINIT(bug("[ATA%02ld] ata_Identify: Both command variants failed\n",
1460 unit->au_UnitNum));
1461 return IOERR_OPENFAIL;
1463 unit->au_Bus->ab_Dev[unit->au_UnitNum & 1] ^= 0x82;
1464 atapi = unit->au_Bus->ab_Dev[unit->au_UnitNum & 1] & 0x80;
1465 DINIT(bug("[ATA%02ld] ata_Identify:"
1466 " Incorrect device signature detected."
1467 " Switching device type to %lx.\n", unit->au_UnitNum,
1468 unit->au_Bus->ab_Dev[unit->au_UnitNum & 1]));
1472 * If every second word is zero with 32-bit reads, switch to 16-bit
1473 * accesses for this drive and try again
1475 if (unit->au_Bus->ab_Base->ata_32bit)
1477 UWORD n = 0, *p, *limit;
1479 for (p = (UWORD *)unit->au_Drive, limit = p + 256; p < limit; p++)
1480 n |= *++p;
1482 if (n == 0)
1484 DINIT(bug("[ATA%02ld] Identify data was invalid with 32-bit reads."
1485 " Switching to 16-bit mode.\n", unit->au_UnitNum));
1487 unit->au_ins = unit->au_Bus->ab_Driver->ata_insw;
1488 unit->au_outs = unit->au_Bus->ab_Driver->ata_outsw;
1490 if (ata_exec_cmd(unit, &acb))
1491 return IOERR_OPENFAIL;
1495 #if (AROS_BIG_ENDIAN != 0)
1496 SWAP_LE_WORD(unit->au_Drive->id_General);
1497 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1498 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1499 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1500 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1501 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1502 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1503 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1504 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1505 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1506 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1507 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1508 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1509 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1510 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1511 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1512 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1513 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1514 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1515 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1516 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1517 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1518 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1519 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1520 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1521 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1522 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1523 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1524 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1525 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1526 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1527 SWAP_LE_WORD(unit->au_Drive->id_ESecurityEraseTime);
1528 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvPowerMode);
1529 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1530 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1531 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1532 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1533 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1534 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1535 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1536 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1537 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1538 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1540 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1541 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1542 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1544 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1545 #endif
1547 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1549 if (atapi)
1551 unit->au_SectorShift = 11;
1552 unit->au_Read32 = atapi_Read;
1553 unit->au_Write32 = atapi_Write;
1554 unit->au_DirectSCSI = atapi_DirectSCSI;
1555 unit->au_Eject = atapi_Eject;
1556 unit->au_Flags |= AF_DiscChanged;
1557 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1558 unit->au_XferModes = AF_XFER_PACKET;
1560 else
1562 unit->au_SectorShift = 9;
1563 unit->au_DevType = DG_DIRECT_ACCESS;
1564 unit->au_Read32 = ata_ReadSector32;
1565 unit->au_Write32 = ata_WriteSector32;
1566 unit->au_Eject = ata_Eject;
1567 unit->au_XferModes = 0;
1568 unit->au_Flags |= AF_DiscPresent | AF_DiscChanged;
1571 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1572 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1573 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1575 bug("[ATA%02ld] ata_Identify: Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1576 common_DetectXferModes(unit);
1577 common_SetBestXferMode(unit);
1579 if (unit->au_Drive->id_General & 0x80)
1581 DINIT(bug("[ATA%02ld] ata_Identify: Device is removable.\n", unit->au_UnitNum));
1582 unit->au_Flags |= AF_Removable;
1585 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1586 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1587 bug("[ATA%02ld] ata_Identify: Unit info: %07lx 28bit / %04lx:%08lx 48bit addressable blocks\n", unit->au_UnitNum, unit->au_Capacity, (ULONG)(unit->au_Capacity48 >> 32), (ULONG)(unit->au_Capacity48 & 0xfffffffful));
1589 if (atapi)
1592 * ok, this is not very original, but quite compatible :P
1594 switch (unit->au_DevType)
1596 case DG_CDROM:
1597 case DG_WORM:
1598 case DG_OPTICAL_DISK:
1599 unit->au_SectorShift = 11;
1600 unit->au_Heads = 1;
1601 unit->au_Sectors = 75;
1602 unit->au_Cylinders = 4440;
1603 break;
1605 case DG_DIRECT_ACCESS:
1606 unit->au_SectorShift = 9;
1607 if (!strcmp("LS-120", &unit->au_Model[0]))
1609 unit->au_Heads = 2;
1610 unit->au_Sectors = 18;
1611 unit->au_Cylinders = 6848;
1613 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1615 unit->au_Heads = 1;
1616 unit->au_Sectors = 64;
1617 unit->au_Cylinders = 3072;
1619 break;
1622 atapi_TestUnitOK(unit);
1624 else
1627 For drive capacities > 8.3GB assume maximal possible layout.
1628 It really doesn't matter here, as BIOS will not handle them in
1629 CHS way anyway :)
1630 i guess this just solves that weirdo div-by-zero crash, if nothing
1631 else...
1633 if ((unit->au_Drive->id_LBA48Sectors > (63 * 255 * 1024)) ||
1634 (unit->au_Drive->id_LBASectors > (63 * 255 * 1024)))
1636 ULONG div = 1;
1638 * TODO: this shouldn't be casted down here.
1640 ULONG sec = unit->au_Capacity48;
1642 if (sec < unit->au_Capacity48)
1643 sec = ~((ULONG)0);
1645 if (sec < unit->au_Capacity)
1646 sec = unit->au_Capacity;
1648 unit->au_Sectors = 63;
1649 sec /= 63;
1651 * keep dividing by 2
1655 if (((sec >> 1) << 1) != sec)
1656 break;
1657 if ((div << 1) > 255)
1658 break;
1659 div <<= 1;
1660 sec >>= 1;
1661 } while (1);
1665 if (((sec / 3) * 3) != sec)
1666 break;
1667 if ((div * 3) > 255)
1668 break;
1669 div *= 3;
1670 sec /= 3;
1671 } while (1);
1673 unit->au_Cylinders = sec;
1674 unit->au_Heads = div;
1676 else
1678 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1679 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1680 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1684 return 0;
1688 * ata read32 commands
1690 static BYTE ata_ReadSector32(struct ata_Unit *unit, ULONG block,
1691 ULONG count, APTR buffer, ULONG *act)
1693 ata_CommandBlock acb =
1695 ATA_READ,
1699 block,
1700 count,
1701 buffer,
1702 count << unit->au_SectorShift,
1704 CM_PIORead,
1705 CT_LBA28
1707 BYTE err;
1709 D(bug("[ATA%02ld] ata_ReadSector32()\n", unit->au_UnitNum));
1711 *act = 0;
1712 if (0 != (err = ata_exec_blk(unit, &acb)))
1713 return err;
1715 *act = count << unit->au_SectorShift;
1716 return 0;
1719 static BYTE ata_ReadMultiple32(struct ata_Unit *unit, ULONG block,
1720 ULONG count, APTR buffer, ULONG *act)
1722 ata_CommandBlock acb =
1724 ATA_READ_MULTIPLE,
1726 unit->au_Drive->id_RWMultipleSize & 0xff,
1728 block,
1729 count,
1730 buffer,
1731 count << unit->au_SectorShift,
1733 CM_PIORead,
1734 CT_LBA28
1736 BYTE err;
1738 D(bug("[ATA%02ld] ata_ReadMultiple32()\n", unit->au_UnitNum));
1740 *act = 0;
1741 if (0 != (err = ata_exec_blk(unit, &acb)))
1742 return err;
1744 *act = count << unit->au_SectorShift;
1745 return 0;
1748 static BYTE ata_ReadDMA32(struct ata_Unit *unit, ULONG block,
1749 ULONG count, APTR buffer, ULONG *act)
1751 BYTE err;
1752 ata_CommandBlock acb =
1754 ATA_READ_DMA,
1758 block,
1759 count,
1760 buffer,
1761 count << unit->au_SectorShift,
1763 CM_DMARead,
1764 CT_LBA28
1767 D(bug("[ATA%02ld] ata_ReadDMA32()\n", unit->au_UnitNum));
1769 *act = 0;
1770 if (0 != (err = ata_exec_blk(unit, &acb)))
1771 return err;
1773 *act = count << unit->au_SectorShift;
1774 return 0;
1778 * ata read64 commands
1780 static BYTE ata_ReadSector64(struct ata_Unit *unit, UQUAD block,
1781 ULONG count, APTR buffer, ULONG *act)
1783 ata_CommandBlock acb =
1785 ATA_READ64,
1789 block,
1790 count,
1791 buffer,
1792 count << unit->au_SectorShift,
1794 CM_PIORead,
1795 CT_LBA48
1797 BYTE err = 0;
1799 D(bug("[ATA%02ld] ata_ReadSector64()\n", unit->au_UnitNum));
1801 *act = 0;
1802 if (0 != (err = ata_exec_blk(unit, &acb)))
1803 return err;
1805 *act = count << unit->au_SectorShift;
1806 return 0;
1809 static BYTE ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block,
1810 ULONG count, APTR buffer, ULONG *act)
1812 ata_CommandBlock acb =
1814 ATA_READ_MULTIPLE64,
1816 unit->au_Drive->id_RWMultipleSize & 0xff,
1818 block,
1819 count,
1820 buffer,
1821 count << unit->au_SectorShift,
1823 CM_PIORead,
1824 CT_LBA48
1826 BYTE err;
1828 D(bug("[ATA%02ld] ata_ReadMultiple64()\n", unit->au_UnitNum));
1830 *act = 0;
1831 if (0 != (err = ata_exec_blk(unit, &acb)))
1832 return err;
1834 *act = count << unit->au_SectorShift;
1835 return 0;
1838 static BYTE ata_ReadDMA64(struct ata_Unit *unit, UQUAD block,
1839 ULONG count, APTR buffer, ULONG *act)
1841 ata_CommandBlock acb =
1843 ATA_READ_DMA64,
1847 block,
1848 count,
1849 buffer,
1850 count << unit->au_SectorShift,
1852 CM_DMARead,
1853 CT_LBA48
1855 BYTE err;
1857 D(bug("[ATA%02ld] ata_ReadDMA64()\n", unit->au_UnitNum));
1859 *act = 0;
1860 if (0 != (err = ata_exec_blk(unit, &acb)))
1861 return err;
1863 *act = count << unit->au_SectorShift;
1864 return 0;
1868 * ata write32 commands
1870 static BYTE ata_WriteSector32(struct ata_Unit *unit, ULONG block,
1871 ULONG count, APTR buffer, ULONG *act)
1873 ata_CommandBlock acb =
1875 ATA_WRITE,
1879 block,
1880 count,
1881 buffer,
1882 count << unit->au_SectorShift,
1884 CM_PIOWrite,
1885 CT_LBA28
1887 BYTE err;
1889 D(bug("[ATA%02ld] ata_WriteSector32()\n", unit->au_UnitNum));
1891 *act = 0;
1892 if (0 != (err = ata_exec_blk(unit, &acb)))
1893 return err;
1895 *act = count << unit->au_SectorShift;
1896 return 0;
1899 static BYTE ata_WriteMultiple32(struct ata_Unit *unit, ULONG block,
1900 ULONG count, APTR buffer, ULONG *act)
1902 ata_CommandBlock acb =
1904 ATA_WRITE_MULTIPLE,
1906 unit->au_Drive->id_RWMultipleSize & 0xff,
1908 block,
1909 count,
1910 buffer,
1911 count << unit->au_SectorShift,
1913 CM_PIOWrite,
1914 CT_LBA28
1916 BYTE err;
1918 D(bug("[ATA%02ld] ata_WriteMultiple32()\n", unit->au_UnitNum));
1920 *act = 0;
1921 if (0 != (err = ata_exec_blk(unit, &acb)))
1922 return err;
1924 *act = count << unit->au_SectorShift;
1925 return 0;
1928 static BYTE ata_WriteDMA32(struct ata_Unit *unit, ULONG block,
1929 ULONG count, APTR buffer, ULONG *act)
1931 ata_CommandBlock acb =
1933 ATA_WRITE_DMA,
1937 block,
1938 count,
1939 buffer,
1940 count << unit->au_SectorShift,
1942 CM_DMAWrite,
1943 CT_LBA28
1945 BYTE err;
1947 D(bug("[ATA%02ld] ata_WriteDMA32()\n", unit->au_UnitNum));
1949 *act = 0;
1950 if (0 != (err = ata_exec_blk(unit, &acb)))
1951 return err;
1953 *act = count << unit->au_SectorShift;
1954 return 0;
1958 * ata write64 commands
1960 static BYTE ata_WriteSector64(struct ata_Unit *unit, UQUAD block,
1961 ULONG count, APTR buffer, ULONG *act)
1963 ata_CommandBlock acb =
1965 ATA_WRITE64,
1969 block,
1970 count,
1971 buffer,
1972 count << unit->au_SectorShift,
1974 CM_PIOWrite,
1975 CT_LBA48
1977 BYTE err;
1979 D(bug("[ATA%02ld] ata_WriteSector64()\n", unit->au_UnitNum));
1981 *act = 0;
1982 if (0 != (err = ata_exec_blk(unit, &acb)))
1983 return err;
1985 *act = count << unit->au_SectorShift;
1986 return 0;
1989 static BYTE ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block,
1990 ULONG count, APTR buffer, ULONG *act)
1992 ata_CommandBlock acb =
1994 ATA_WRITE_MULTIPLE64,
1996 unit->au_Drive->id_RWMultipleSize & 0xff,
1998 block,
1999 count,
2000 buffer,
2001 count << unit->au_SectorShift,
2003 CM_PIOWrite,
2004 CT_LBA48
2006 BYTE err;
2008 D(bug("[ATA%02ld] ata_WriteMultiple64()\n", unit->au_UnitNum));
2010 *act = 0;
2011 if (0 != (err = ata_exec_blk(unit, &acb)))
2012 return err;
2014 *act = count << unit->au_SectorShift;
2015 return 0;
2018 static BYTE ata_WriteDMA64(struct ata_Unit *unit, UQUAD block,
2019 ULONG count, APTR buffer, ULONG *act)
2021 ata_CommandBlock acb =
2023 ATA_WRITE_DMA64,
2027 block,
2028 count,
2029 buffer,
2030 count << unit->au_SectorShift,
2032 CM_DMAWrite,
2033 CT_LBA48
2035 BYTE err;
2037 D(bug("[ATA%02ld] ata_WriteDMA64()\n", unit->au_UnitNum));
2039 *act = 0;
2040 if (0 != (err = ata_exec_blk(unit, &acb)))
2041 return err;
2043 *act = count << unit->au_SectorShift;
2044 return 0;
2048 * ata miscellaneous commands
2050 static BYTE ata_Eject(struct ata_Unit *unit)
2052 ata_CommandBlock acb =
2054 ATA_MEDIA_EJECT,
2063 CM_NoData,
2064 CT_NoBlock
2067 D(bug("[ATA%02ld] ata_Eject()\n", unit->au_UnitNum));
2069 return ata_exec_cmd(unit, &acb);
2073 * atapi commands
2075 int atapi_TestUnitOK(struct ata_Unit *unit)
2077 UBYTE cmd[6] = {
2080 UBYTE sense[16] = {
2083 struct SCSICmd sc = {
2087 D(bug("[ATA%02ld] atapi_TestUnitOK()\n", unit->au_UnitNum));
2089 sc.scsi_Command = (void*) &cmd;
2090 sc.scsi_CmdLength = sizeof(cmd);
2091 sc.scsi_SenseData = (void*)&sense;
2092 sc.scsi_SenseLength = sizeof(sense);
2093 sc.scsi_Flags = SCSIF_AUTOSENSE;
2095 DATAPI(bug("[ATA%02ld] atapi_TestUnitOK: Testing Unit Ready sense...\n", unit->au_UnitNum));
2096 unit->au_DirectSCSI(unit, &sc);
2097 unit->au_SenseKey = sense[2];
2100 * we may have just lost the disc...?
2103 * per MMC, drives are expected to return 02-3a-0# status, when disc is not present
2104 * that would translate into following code:
2105 * int p1 = ((sense[2] == 2) && (sense[12] == 0x3a)) ? 1 : 0;
2106 * unfortunately, it's what MMC says, not what vendors code.
2108 int p1 = (sense[2] == 2) ? 1 : 0;
2109 int p2 = (0 != (AF_DiscPresent & unit->au_Flags)) ? 1 : 0;
2111 if (p1 == p2)
2113 //unit->au_Flags ^= AF_DiscPresent;
2114 if (p1 == 0)
2115 unit->au_Flags |= AF_DiscPresent;
2116 else
2117 unit->au_Flags &= ~AF_DiscPresent;
2119 unit->au_Flags |= AF_DiscChanged;
2122 DATAPI(bug("[ATA%02ld] atapi_TestUnitOK: Test Unit Ready sense: %02lx, Media %s\n", unit->au_UnitNum, sense[2], unit->au_Flags & AF_DiscPresent ? "PRESENT" : "ABSENT"));
2123 return sense[2];
2126 static BYTE atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count,
2127 APTR buffer, ULONG *act)
2129 UBYTE cmd[] = {
2130 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2132 struct SCSICmd sc = {
2136 D(bug("[ATA%02ld] atapi_Read()\n", unit->au_UnitNum));
2138 sc.scsi_Command = (void*) &cmd;
2139 sc.scsi_CmdLength = sizeof(cmd);
2140 sc.scsi_Data = buffer;
2141 sc.scsi_Length = count << unit->au_SectorShift;
2142 sc.scsi_Flags = SCSIF_READ;
2144 return unit->au_DirectSCSI(unit, &sc);
2147 static BYTE atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count,
2148 APTR buffer, ULONG *act)
2150 UBYTE cmd[] = {
2151 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2153 struct SCSICmd sc = {
2157 D(bug("[ATA%02ld] atapi_Write()\n", unit->au_UnitNum));
2159 sc.scsi_Command = (void*) &cmd;
2160 sc.scsi_CmdLength = sizeof(cmd);
2161 sc.scsi_Data = buffer;
2162 sc.scsi_Length = count << unit->au_SectorShift;
2163 sc.scsi_Flags = SCSIF_WRITE;
2165 return unit->au_DirectSCSI(unit, &sc);
2168 static BYTE atapi_Eject(struct ata_Unit *unit)
2170 struct atapi_StartStop cmd = {
2171 command: SCSI_STARTSTOP,
2172 immediate: 1,
2173 flags: ATAPI_SS_EJECT,
2176 struct SCSICmd sc = {
2180 D(bug("[ATA%02ld] atapi_Eject()\n", unit->au_UnitNum));
2182 sc.scsi_Command = (void*) &cmd;
2183 sc.scsi_CmdLength = sizeof(cmd);
2184 sc.scsi_Flags = SCSIF_READ;
2186 return unit->au_DirectSCSI(unit, &sc);
2189 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2191 UBYTE cmd[] = {
2192 3, 0, 0, 0, senselen & 0xfe, 0
2194 struct SCSICmd sc = {
2198 D(bug("[ATA%02ld] atapi_RequestSense()\n", unit->au_UnitNum));
2200 if ((senselen == 0) || (sense == 0))
2202 return 0;
2204 sc.scsi_Data = (void*)sense;
2205 sc.scsi_Length = senselen & 0xfe;
2206 sc.scsi_Command = (void*)&cmd;
2207 sc.scsi_CmdLength = 6;
2208 sc.scsi_Flags = SCSIF_READ;
2210 unit->au_DirectSCSI(unit, &sc);
2212 DATAPI(dump(sense, senselen));
2213 DATAPI(bug("[SENSE] atapi_RequestSense: sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2214 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2217 ULONG ata_ReadSignature(struct ata_Bus *bus, int unit, BOOL *DiagExecuted)
2219 ULONG port = bus->ab_Port;
2220 UBYTE tmp1, tmp2;
2222 D(bug("[ATA ] ata_ReadSignature(%02ld)\n", unit));
2224 BUS_OUT(0xa0 | (unit << 4), ata_DevHead, port);
2225 ata_WaitNano(400);
2226 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2228 DINIT(bug("[ATA ] ata_ReadSignature: Status %02lx Device %02lx\n",
2229 ata_ReadStatus(bus), BUS_IN(ata_DevHead, port)));
2231 /* Ok, ATA/ATAPI device. Get detailed signature */
2232 DINIT(bug("[ATA ] ata_ReadSignature: ATA[PI] device present. Attempting to detect specific subtype\n"));
2234 tmp1 = BUS_IN(ata_LBAMid, port);
2235 tmp2 = BUS_IN(ata_LBAHigh, port);
2237 DINIT(bug("[ATA ] ata_ReadSignature: Subtype check returned %02lx:%02lx (%04lx)\n", tmp1, tmp2, (tmp1 << 8) | tmp2));
2239 switch ((tmp1 << 8) | tmp2)
2241 case 0x14eb:
2242 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for ATAPI device\n"));
2243 return DEV_ATAPI;
2245 case 0x3cc3:
2246 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATA device\n"));
2247 return DEV_SATA;
2249 case 0x6996:
2250 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATAPI device\n"));
2251 return DEV_SATAPI;
2253 default:
2254 if (0 == (ata_ReadStatus(bus) & 0xfe))
2255 return DEV_NONE;
2256 /* ATA_EXECUTE_DIAG is executed by both devices, do it only once */
2257 if (!*DiagExecuted)
2259 BUS_OUT(ATA_EXECUTE_DIAG, ata_Command, port);
2260 *DiagExecuted = TRUE;
2263 ata_WaitTO(bus->ab_Timer, 0, 2000, 0);
2264 while (ata_ReadStatus(bus) & ATAF_BUSY)
2265 ata_WaitNano(400);
2266 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2268 BUS_OUT(0xa0 | (unit << 4), ata_DevHead, port);
2271 ata_WaitNano(400);
2272 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
2274 while (0 != (ATAF_BUSY & ata_ReadStatus(bus)));
2275 DINIT(bug("[ATA ] ata_ReadSignature: Further validating ATA signature: %lx & 0x7f = 1, %lx & 0x10 = unit\n", BUS_IN(ata_Error, port), BUS_IN(ata_DevHead, port)));
2277 if ((BUS_IN(ata_Error, port) & 0x7f) == 1)
2279 DINIT(bug("[ATA ] ata_ReadSignature: Found *valid* signature for ATA device\n"));
2280 /* this might still be an (S)ATAPI device, but we correct that in ata_Identify */
2281 return DEV_ATA;
2283 bug("[ATA ] ata_ReadSignature: Found signature for ATA "
2284 "device, but further validation failed\n");
2285 return DEV_NONE;
2289 void ata_ResetBus(struct ata_Bus *bus)
2291 ULONG alt = bus->ab_Alt;
2292 ULONG port = bus->ab_Port;
2293 ULONG TimeOut;
2294 BOOL DiagExecuted = FALSE;
2296 /* Set and then reset the soft reset bit in the Device Control
2297 * register. This causes device 0 be selected */
2298 DINIT(bug("[ATA ] ata_ResetBus(%d)\n", bus->ab_BusNum));
2299 BUS_OUT(0xa0 | (0 << 4), ata_DevHead, port); /* Select it never the less */
2300 ata_WaitNano(400);
2301 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2303 BUS_OUT(0x04, ata_AltControl, alt);
2304 ata_WaitTO(bus->ab_Timer, 0, 10, 0); /* sleep 10us; min: 5us */
2305 BUS_OUT(0x02, ata_AltControl, alt);
2306 ata_WaitTO(bus->ab_Timer, 0, 20000, 0); /* sleep 20ms; min: 2ms */
2308 /* If there is a device 0, wait for device 0 to clear BSY */
2309 if (DEV_NONE != bus->ab_Dev[0]) {
2310 DINIT(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n",
2311 ((bus->ab_BusNum << 1 ) + 0)));
2312 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2313 while ( 1 ) {
2314 if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0)
2315 break;
2316 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2317 if (!(--TimeOut)) {
2318 DINIT(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n",
2319 ((bus->ab_BusNum << 1 ) + 0)));
2320 bus->ab_Dev[0] = DEV_NONE;
2321 break;
2324 DINIT(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n",
2325 ((bus->ab_BusNum << 1 ) + 0), (1000 - TimeOut)));
2328 /* If there is a device 1, wait some time until device 1 allows
2329 * register access, but fail only if BSY isn't cleared */
2330 if (DEV_NONE != bus->ab_Dev[1]) {
2331 DINIT(bug("[ATA ] ata_ResetBus: Wait DEV1 to allow access\n"));
2332 BUS_OUT(0xa0 | (1 << 4), ata_DevHead, port);
2333 ata_WaitNano(400);
2334 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2336 TimeOut = 50; /* Timeout 50ms (1ms x 50) */
2337 while ( 1 ) {
2338 if ( (BUS_IN(ata_Count, port) == 0x01) && (BUS_IN(ata_LBALow, port) == 0x01) )
2339 break;
2340 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2341 if (!(--TimeOut)) {
2342 DINIT(bug("[ATA ] ata_ResetBus: DEV1 1/2 TimeOut!\n"));
2343 break;
2346 DINIT(bug("[ATA ] ata_ResetBus: DEV1 1/2 Wait left after %d ms\n",
2347 (1000 - TimeOut)));
2349 if (DEV_NONE != bus->ab_Dev[1]) {
2350 DINIT(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n",
2351 ((bus->ab_BusNum << 1 ) + 1)));
2352 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2353 while ( 1 ) {
2354 if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0)
2355 break;
2356 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2357 if (!(--TimeOut)) {
2358 DINIT(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n",
2359 ((bus->ab_BusNum << 1 ) + 1)));
2360 bus->ab_Dev[1] = DEV_NONE;
2361 break;
2364 DINIT(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n",
2365 ((bus->ab_BusNum << 1 ) + 1), 1000 - TimeOut));
2369 if (DEV_NONE != bus->ab_Dev[0])
2370 bus->ab_Dev[0] = ata_ReadSignature(bus, 0, &DiagExecuted);
2371 if (DEV_NONE != bus->ab_Dev[1])
2372 bus->ab_Dev[1] = ata_ReadSignature(bus, 1, &DiagExecuted);
2375 void ata_InitBus(struct ata_Bus *bus)
2377 ULONG port = bus->ab_Port;
2378 UBYTE tmp1, tmp2;
2379 UWORD i;
2382 * initialize timer for the sake of scanning
2384 bus->ab_Timer = ata_OpenTimer();
2386 DINIT(bug("[ATA ] ata_InitBus(%d)\n", bus->ab_BusNum));
2388 bus->ab_Dev[0] = DEV_NONE;
2389 bus->ab_Dev[1] = DEV_NONE;
2391 for (i = 0; i < MAX_BUSUNITS; i++)
2393 /* Select device and disable IRQs */
2394 BUS_OUT(0xa0 | (i << 4), ata_DevHead, port);
2395 ata_WaitTO(bus->ab_Timer, 0, 100, 0);
2396 BUS_OUT(0x2, ata_AltControl, bus->ab_Alt);
2398 /* Write some pattern to registers */
2399 BUS_OUT(0x55, ata_Count, port);
2400 BUS_OUT(0xaa, ata_LBALow, port);
2401 BUS_OUT(0xaa, ata_Count, port);
2402 BUS_OUT(0x55, ata_LBALow, port);
2403 BUS_OUT(0x55, ata_Count, port);
2404 BUS_OUT(0xaa, ata_LBALow, port);
2406 tmp1 = BUS_IN(ata_Count, port);
2407 tmp2 = BUS_IN(ata_LBALow, port);
2409 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2410 bus->ab_Dev[i] = DEV_UNKNOWN;
2411 DINIT(bug("[ATA%02ld] ata_InitBus: Device type = %x\n",
2412 (bus->ab_BusNum << 1 ) + i, bus->ab_Dev[i]));
2415 ata_ResetBus(bus);
2416 ata_CloseTimer(bus->ab_Timer);
2417 DINIT(bug("[ATA ] ata_InitBus: Finished\n"));
2421 * not really sure what this is meant to be - TO BE REPLACED
2423 static const ULONG ErrorMap[] = {
2424 CDERR_NotSpecified,
2425 CDERR_NoSecHdr,
2426 CDERR_NoDisk,
2427 CDERR_NoSecHdr,
2428 CDERR_NoSecHdr,
2429 CDERR_NOCMD,
2430 CDERR_NoDisk,
2431 CDERR_WriteProt,
2432 CDERR_NotSpecified,
2433 CDERR_NotSpecified,
2434 CDERR_NotSpecified,
2435 CDERR_ABORTED,
2436 CDERR_NotSpecified,
2437 CDERR_NotSpecified,
2438 CDERR_NoSecHdr,
2439 CDERR_NotSpecified,
2442 static BYTE atapi_EndCmd(struct ata_Unit *unit)
2444 UBYTE status;
2446 DATAPI(bug("[ATA%02ld] atapi_EndCmd()\n", unit->au_UnitNum));
2449 * read alternate status register (per specs)
2451 status = ATA_IN(ata_AltStatus, unit->au_Bus->ab_Alt);
2452 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Alternate status: %lx\n", unit->au_UnitNum, status));
2454 status = ATA_IN(atapi_Status, unit->au_Bus->ab_Port);
2456 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Command complete. Status: %lx\n",
2457 unit->au_UnitNum, status));
2459 if (!(status & ATAPIF_CHECK))
2461 return 0;
2463 else
2465 status = ATA_IN(atapi_Error, unit->au_Bus->ab_Port);
2466 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Error code 0x%lx\n", unit->au_UnitNum, status >> 4));
2467 return ErrorMap[status >> 4];
2472 * vim: ts=4 et sw=4 fdm=marker fmr={,}