define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / arch / common / ata.device / lowlevel.c
blobbed7085db154f26baf225ecd08256f4180f3a56d
1 /*
2 Copyright � 2004-2009, 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.
59 * TODO:
60 * - put a critical section around DMA transfers (shared dma channels)
63 #define DEBUG 0
64 // use #define xxx(a) D(a) to enable particular sections.
65 #define DIRQ(a) D(a)
66 #define DIRQ_MORE(a)
67 #define DUMP(a) D(a)
68 #define DUMP_MORE(a)
69 #define DATA(a) D(a)
70 #define DATAPI(a) D(a)
71 #define DINIT(a) D(a)
73 #include <aros/debug.h>
74 #include <exec/types.h>
75 #include <exec/exec.h>
76 #include <exec/resident.h>
77 #include <utility/utility.h>
78 #include <oop/oop.h>
80 #include <proto/exec.h>
81 #include <devices/timer.h>
83 #include <asm/io.h>
85 #include "ata.h"
86 #include "timer.h"
91 Prototypes of static functions from lowlevel.c. I do not want to make them
92 non-static as I'd like to remove as much symbols from global table as possible.
93 Besides some of this functions could conflict with old ide.device or any other
94 device.
96 static BYTE ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
97 static BYTE ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
98 static BYTE ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
99 static BYTE ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
100 static BYTE ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
101 static BYTE ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
102 static BYTE ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
103 static BYTE ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
104 static BYTE ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
105 static BYTE ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
106 static BYTE ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
107 static BYTE ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
108 static BYTE ata_Eject(struct ata_Unit *);
109 static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout);
111 static BYTE atapi_EndCmd(struct ata_Unit *unit);
113 static BYTE atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
114 static BYTE atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
115 static BYTE atapi_Eject(struct ata_Unit *);
117 static void common_SetBestXferMode(struct ata_Unit* unit);
120 Again piece of code which shouldn't be here. Geee. After removing all this
121 asm constrictuins this ata.device will really deserve for location in
122 /arch/common
125 * having an x86 assembly here i dare to assume that this is meant to be
126 * an x86[_64] device only.
128 * Not anymore.
130 * This functions will stay here for some time *IF* and only if the code is compiled for
131 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
132 * one who ports the driver will be reponsible for adding the missing code.
136 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
138 #if defined(__i386__) || defined(__x86_64__)
140 static VOID ata_insw(APTR address, UWORD port, ULONG count)
142 insw(port, address, count >> 1);
145 static VOID ata_insl(APTR address, UWORD port, ULONG count)
147 if (count & 2)
148 insw(port, address, count >> 1);
149 else
150 insl(port, address, count >> 2);
153 static VOID ata_outsw(APTR address, UWORD port, ULONG count)
155 outsw(port, address, count >> 1);
158 static VOID ata_outsl(APTR address, UWORD port, ULONG count)
160 if (count & 2)
161 outsw(port, address, count >> 1);
162 else
163 outsl(port, address, count >> 2);
166 #else
167 extern VOID ata_insw(APTR address, UWORD port, ULONG count);
168 extern VOID ata_insl(APTR address, UWORD port, ULONG count);
169 extern VOID ata_outsw(APTR address, UWORD port, ULONG count);
170 extern VOID ata_outsl(APTR address, UWORD port, ULONG count);
171 #endif
173 static void dump(APTR mem, ULONG len)
175 register int i, j = 0;
177 DUMP_MORE(for (j=0; j<(len+15)>>4; ++j))
179 bug("[ATA ] %06lx: ", j<<4);
181 for (i=0; i<len-(j<<4); i++)
183 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
184 if (i == 15)
185 break;
188 for (i=0; i<len-(j<<4); i++)
190 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
192 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
193 if (i == 15)
194 break;
196 bug("\n");
200 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
202 register int i = size;
204 while (size--)
205 str2[size ^ 1] = str1[size];
207 while (i > 0 && str2[--i] <= ' ')
208 str2[i] = '\0';
212 * a STUB function for commands not supported by this particular device
214 static BYTE ata_STUB(struct ata_Unit *au)
216 bug("[ATA%02ld] CALLED STUB FUNCTION (GENERIC). THIS OPERATION IS NOT "
217 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
218 return CDERR_NOCMD;
221 static BYTE ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len,
222 APTR buf, ULONG* act)
224 bug("[ATA%02ld] CALLED STUB FUNCTION (IO32). THIS OPERATION IS NOT "
225 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
226 return CDERR_NOCMD;
229 static BYTE ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len,
230 APTR buf, ULONG* act)
232 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);
233 return CDERR_NOCMD;
236 static BYTE ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
238 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
239 return CDERR_NOCMD;
242 inline struct ata_Unit* ata_GetSelectedUnit(struct ata_Bus* bus)
244 register int id = (ata_in(ata_DevHead, bus->ab_Port) & 0x10) >> 4;
245 return bus->ab_Units[id];
248 inline BOOL ata_SelectUnit(struct ata_Unit* unit)
250 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
254 ata_WaitNano(400);
255 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
257 while (0 != (ATAF_BUSY & ata_ReadStatus(unit->au_Bus)));
259 return TRUE;
262 UBYTE ata_ReadStatus(struct ata_Bus *bus)
264 return ata_in(ata_Status, bus->ab_Port);
267 UBYTE ata_ReadAltStatus(struct ata_Bus *bus)
269 return ata_in(ata_AltStatus, bus->ab_Alt);
273 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
274 * part of code moved here from ata.c to reduce containment
276 void ata_IRQSignalTask(struct ata_Bus *bus)
278 bus->ab_IntCnt++;
279 Signal(bus->ab_Task, 1UL << bus->ab_SleepySignal);
282 void ata_HandleIRQ(struct ata_Bus *bus)
284 struct ata_Unit *unit = ata_GetSelectedUnit(bus);
285 UBYTE status = ata_ReadAltStatus(bus);
286 BOOL for_us = FALSE;
289 * don't waste your time on checking other devices.
290 * pass irq ONLY if task is expecting one;
292 if ((unit != NULL) && (0 != bus->ab_HandleIRQ))
295 * The DMA status register indicates all interrupt types, not
296 * just DMA interrupts. However, if there's no DMA port, we have
297 * to rely on the busy flag, which is incompatible with IRQ sharing.
299 if (unit->au_DMAPort != 0)
300 for_us =
301 (ata_in(dma_Status, unit->au_DMAPort) & DMAF_Interrupt) != 0;
302 else
303 for_us = (status & ATAF_BUSY) == 0;
306 if (for_us)
309 * Acknowledge interrupt (note that the DMA interrupt bit should be
310 * cleared for all interrupt types)
312 if (unit->au_DMAPort != 0)
313 ata_out(ata_in(dma_Status, unit->au_DMAPort) |
314 DMAF_Error | DMAF_Interrupt, dma_Status, unit->au_DMAPort);
315 status = ata_ReadStatus(bus);
318 * ok, we have a routine to handle any form of transmission etc.
320 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
321 bus->ab_HandleIRQ(unit, status);
323 return;
326 DIRQ_MORE({
328 * if we got *here* then device is most likely not expected to have an irq.
330 bug("[ATA%02ld] IRQ: Checking busy flag: ", unit->au_UnitNum);
332 if (0 == (ATAF_BUSY & status))
334 bug("device ready. Dumping details:\n");
336 bug("[ATA ] STATUS: %02lx\n", status);
337 bug("[ATA ] ALT STATUS: %02lx\n", ata_in(ata_AltStatus, bus->ab_Alt));
338 bug("[ATA ] ERROR: %02lx\n", ata_in(ata_Error, bus->ab_Port));
339 bug("[ATA ] IRQ: REASON: %02lx\n", ata_in(atapi_Reason, bus->ab_Port));
341 else
343 bug("device still busy. ignoring irq.\n");
348 void ata_IRQSetHandler(struct ata_Unit *unit, void (*handler)(struct ata_Unit*, UBYTE), APTR piomem, ULONG blklen, ULONG piolen)
350 if (NULL != handler)
351 unit->au_cmd_error = 0;
353 unit->au_cmd_data = piomem;
354 unit->au_cmd_length = (piolen < blklen) ? piolen : blklen;
355 unit->au_cmd_total = piolen;
356 unit->au_Bus->ab_HandleIRQ = handler;
359 void ata_IRQNoData(struct ata_Unit *unit, UBYTE status)
361 if (status & ATAF_BUSY)
362 return;
364 if ((unit->au_cmd_error == 0) && (status & ATAF_ERROR))
365 unit->au_cmd_error = HFERR_BadStatus;
367 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit->au_UnitNum, status));
368 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
369 ata_IRQSignalTask(unit->au_Bus);
372 void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status)
374 if (status & ATAF_DATAREQ) {
375 DIRQ(bug("[ATA ] IRQ: PIOReadData - DRQ.\n"));
376 unit->au_ins(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
379 * indicate it's all done here
381 unit->au_cmd_data += unit->au_cmd_length;
382 unit->au_cmd_total -= unit->au_cmd_length;
383 if (unit->au_cmd_total) {
384 if (unit->au_cmd_length > unit->au_cmd_total)
385 unit->au_cmd_length = unit->au_cmd_total;
386 return;
388 DIRQ(bug("[ATA ] IRQ: PIOReadData - transfer completed.\n"));
390 ata_IRQNoData(unit, status);
393 void ata_PIOWriteBlk(struct ata_Unit *unit)
395 unit->au_outs(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
398 * indicate it's all done here
400 unit->au_cmd_data += unit->au_cmd_length;
401 unit->au_cmd_total -= unit->au_cmd_length;
402 if (unit->au_cmd_length > unit->au_cmd_total)
403 unit->au_cmd_length = unit->au_cmd_total;
406 void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status)
408 if (status & ATAF_DATAREQ) {
409 DIRQ(bug("[ATA ] IRQ: PIOWriteData - DRQ.\n"));
410 ata_PIOWriteBlk(unit);
411 return;
413 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
414 ata_IRQNoData(unit, status);
417 void ata_IRQDMAReadWrite(struct ata_Unit *au, UBYTE status)
419 UBYTE stat = ata_in(dma_Status, au->au_DMAPort);
420 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat));
422 if ((status & ATAF_ERROR) || (stat & DMAF_Error))
424 /* This is turned on in order to help Phantom - Pavel Fedin <sonic_amiga@rambler.ru> */
425 bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat);
426 bug("[ATA%02ld] IRQ: ERROR %02lx\n", au->au_UnitNum, ata_in(atapi_Error, au->au_Bus->ab_Port));
427 bug("[ATA ] IRQ: DMA Failed.\n");
428 au->au_cmd_error = HFERR_DMA;
429 ata_IRQNoData(au, status);
431 else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
433 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
434 ata_IRQNoData(au, status);
438 void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status)
440 ULONG port = unit->au_Bus->ab_Port;
441 ULONG size = 0;
442 LONG remainder = 0;
443 UBYTE reason = ata_in(atapi_Reason, port);
444 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason));
446 /* have we failed yet? */
447 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
448 ata_IRQNoData(unit, status);
449 if (status & ATAF_ERROR)
451 ata_IRQNoData(unit, status);
452 return;
455 /* anything for us please? */
456 if (ATAPIF_READ != (reason & ATAPIF_MASK))
457 return;
459 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
460 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
462 if (size > unit->au_cmd_total)
464 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
465 remainder = size - unit->au_cmd_total;
466 size = unit->au_cmd_total;
469 unit->au_ins(unit->au_cmd_data, port, size);
470 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
471 unit->au_cmd_total -= size;
473 DIRQ(bug("[ATAPI] IRQ: %lu bytes read.\n", size));
475 for (; remainder > 0; remainder -= 2)
476 unit->au_ins(&size, port, 2);
478 if (unit->au_cmd_total == 0)
479 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
482 void ata_IRQPIOWriteAtapi(struct ata_Unit *unit, UBYTE status)
484 ULONG port = unit->au_Bus->ab_Port;
485 ULONG size = 0;
486 UBYTE reason = ata_in(atapi_Reason, port);
487 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason));
489 /* have we failed yet? */
490 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
491 ata_IRQNoData(unit, status);
492 if (status & ATAF_ERROR)
494 ata_IRQNoData(unit, status);
495 return;
498 /* anything for us please? */
499 if (ATAPIF_WRITE != (reason & ATAPIF_MASK))
500 return;
502 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
503 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
505 if (size > unit->au_cmd_total)
507 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
508 size = unit->au_cmd_total;
511 unit->au_outs(unit->au_cmd_data, port, size);
512 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
513 unit->au_cmd_total -= size;
515 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size));
517 if (unit->au_cmd_total == 0)
518 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
522 * wait for timeout or drive ready
524 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout)
526 UBYTE status;
527 ULONG sigs = SIGBREAKF_CTRL_C;
528 ULONG step = 0;
529 BOOL res = TRUE;
532 * set up bus timeout
534 Disable();
535 unit->au_Bus->ab_Timeout = tout;
536 Enable();
538 sigs |= (irq ? (1 << unit->au_Bus->ab_SleepySignal) : 0);
539 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
541 if (irq)
544 * wait for either IRQ or TIMEOUT (unless device seems to be a
545 * phantom SATAPI drive, in which case we fake a timeout)
547 DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n",
548 unit->au_UnitNum, status));
549 if (status != 0)
550 step = Wait(sigs);
551 else
552 step = SIGBREAKF_CTRL_C;
555 * now if we did reach timeout, then there's no point in going ahead.
557 if (SIGBREAKF_CTRL_C & step)
559 bug("[ATA%02ld] Timeout while waiting for device to complete"
560 " operation\n", unit->au_UnitNum);
561 res = FALSE;
564 * do nothing if the interrupt eventually arrives
566 Disable();
567 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
568 Enable();
571 else
573 while (status & ATAF_BUSY)
575 ++step;
578 * every 16n rounds do some extra stuff
580 if ((step & 16) == 0)
583 * huhm. so it's been 16n rounds already. any timeout yet?
585 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
587 DIRQ(bug("[ATA%02ld] Device still busy after timeout."
588 " Aborting\n", unit->au_UnitNum));
589 res = FALSE;
590 break;
594 * no timeout just yet, but it's not a good idea to keep
595 * spinning like that. let's give the system some time.
597 ata_WaitNano(400);
600 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
605 * clear up all our expectations
607 Disable();
608 unit->au_Bus->ab_Timeout = -1;
609 Enable();
612 * get final status and clear any interrupt (may be neccessary if we
613 * were polling, for example)
615 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
618 * be nice to frustrated developer
620 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit->au_UnitNum,
621 status, res));
624 * release old junk
626 SetSignal(0, sigs);
629 * and say it went fine (i mean it)
631 if (stout)
632 *stout = status;
633 return res;
637 * Procedure for sending ATA command blocks
638 * it appears LARGE but there's a lot of COMMENTS here :)
639 * handles *all* ata commands (no data, pio and dma)
640 * naturally could be split at some point in the future
641 * depends if anyone believes that the change for 50 lines
642 * would make slow ATA transfers any faster
644 static BYTE ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
646 ULONG port = au->au_Bus->ab_Port;
647 BYTE err = 0;
648 APTR mem = block->buffer;
649 UBYTE status;
651 if (FALSE == ata_SelectUnit(au))
652 return IOERR_UNITBUSY;
654 switch (block->type)
656 case CT_LBA28:
657 if (block->sectors > 256)
659 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
660 return IOERR_BADLENGTH;
663 /* note:
664 * we want the above to fall in here!
665 * we really do (checking for secmul)
668 case CT_LBA48:
669 if (block->sectors > 65536)
671 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
672 return IOERR_BADLENGTH;
674 if (block->secmul == 0)
676 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
677 block->secmul = 1;
679 break;
681 case CT_NoBlock:
682 break;
684 default:
685 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
686 return IOERR_NOCMD;
689 block->actual = 0;
690 D(bug("[ATA%02ld] ata_exec_cmd: Executing command %02lx\n", au->au_UnitNum, block->command));
692 if (block->feature != 0)
693 ata_out(block->feature, ata_Feature, port);
696 * - set LBA and sector count
698 switch (block->type)
700 case CT_LBA28:
701 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
702 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
703 ata_out(block->blk >> 16, ata_LBAHigh, port);
704 ata_out(block->blk >> 8, ata_LBAMid, port);
705 ata_out(block->blk, ata_LBALow, port);
706 ata_out(block->sectors, ata_Count, port);
707 break;
709 case CT_LBA48:
710 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
711 ata_out(0x40 | au->au_DevMask, ata_DevHead, port);
712 ata_out(block->blk >> 40, ata_LBAHigh, port);
713 ata_out(block->blk >> 32, ata_LBAMid, port);
714 ata_out(block->blk >> 24, ata_LBALow, port);
716 ata_out(block->blk >> 16, ata_LBAHigh, port);
717 ata_out(block->blk >> 8, ata_LBAMid, port);
718 ata_out(block->blk, ata_LBALow, port);
720 ata_out(block->sectors >> 8, ata_Count, port);
721 ata_out(block->sectors, ata_Count, port);
722 break;
724 case CT_NoBlock:
725 DATA(bug("[ATA%02ld] ata_exec_cmd: Command does not address any block\n", au->au_UnitNum));
726 break;
729 switch (block->method)
731 case CM_PIOWrite:
732 ata_IRQSetHandler(au, &ata_IRQPIOWrite, mem, block->secmul << au->au_SectorShift, block->length);
733 break;
735 case CM_PIORead:
736 ata_IRQSetHandler(au, &ata_IRQPIORead, mem, block->secmul << au->au_SectorShift, block->length);
737 break;
739 case CM_DMARead:
740 if (FALSE == dma_SetupPRDSize(au, mem, block->length, TRUE))
741 return IOERR_ABORTED;
742 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
743 dma_StartDMA(au);
744 break;
746 case CM_DMAWrite:
747 if (FALSE == dma_SetupPRDSize(au, mem, block->length, FALSE))
748 return IOERR_ABORTED;
749 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
750 dma_StartDMA(au);
751 break;
753 case CM_NoData:
754 ata_IRQSetHandler(au, &ata_IRQNoData, NULL, 0, 0);
755 break;
757 default:
758 return IOERR_NOCMD;
759 break;
763 * send command now
764 * let drive propagate its signals
766 DATA(bug("[ATA%02ld] ata_exec_cmd: Sending command\n", au->au_UnitNum));
767 ata_out(block->command, ata_Command, port);
768 ata_WaitNano(400);
769 //ata_WaitTO(au->au_Bus->ab_Timer, 0, 1, 0);
772 * In case of PIO write the drive won't issue an IRQ before first
773 * data transfer, so we should poll the status and send the first
774 * block upon request.
776 if (block->method == CM_PIOWrite) {
777 if (FALSE == ata_WaitBusyTO(au, TIMEOUT, FALSE, &status)) {
778 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - no response from device\n", au->au_UnitNum));
779 return IOERR_UNITBUSY;
781 if (status & ATAF_DATAREQ) {
782 DATA(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - DRQ.\n", au->au_UnitNum));
783 ata_PIOWriteBlk(au);
785 else
787 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - bad status: %02X\n", status));
788 return HFERR_BadStatus;
793 * wait for drive to complete what it has to do
795 if (FALSE == ata_WaitBusyTO(au, TIMEOUT, TRUE, NULL))
797 bug("[ATA%02ld] ata_exec_cmd: Device is late - no response\n", au->au_UnitNum);
798 err = IOERR_UNITBUSY;
800 else
801 err = au->au_cmd_error;
803 DATA(bug("[ATA%02ld] ata_exec_cmd: Command done\n", au->au_UnitNum));
805 * clean up DMA
806 * don't use 'mem' pointer here as it's already invalid.
808 if (block->method == CM_DMARead)
810 dma_StopDMA(au);
811 dma_Cleanup(block->buffer, block->length, TRUE);
813 else if (block->method == CM_DMAWrite)
815 dma_StopDMA(au);
816 dma_Cleanup(block->buffer, block->length, FALSE);
819 D(bug("[ATA%02ld] ata_exec_cmd: return code %ld\n", au->au_UnitNum, err));
820 return err;
824 * atapi packet iface
826 BYTE atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, LONG datalen, BOOL *dma, BOOL write)
828 *dma = *dma && (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
829 LONG err = 0;
831 UBYTE cmd[12] = {
834 register int t=5,l=0;
835 ULONG port = unit->au_Bus->ab_Port;
837 if (((UBYTE*)packet)[0] > 0x1f)
838 t+= 4;
839 if (((UBYTE*)packet)[0] > 0x5f)
840 t+= 2;
842 switch (((UBYTE*)packet)[0])
844 case 0x28: // read10
845 case 0xa8: // read12
846 case 0xbe: // readcd
847 case 0xb9: // readcdmsf
848 case 0x2f: // verify
849 case 0x2a: // write
850 case 0xaa: // write12
851 case 0x2e: // writeverify
852 case 0xad: // readdvdstructure
853 case 0xa4: // reportkey
854 case 0xa3: // sendkey
855 break;
856 default:
857 *dma = FALSE;
860 while (l<=t)
862 cmd[l] = ((UBYTE*)packet)[l];
863 ++l;
866 DATAPI({
867 bug("[ATA%02lx] Sending %s ATA packet: ", unit->au_UnitNum, (*dma) ? "DMA" : "PIO");
868 l=0;
869 while (l<=t)
871 bug("%02lx ", ((UBYTE*)cmd)[l]);
872 ++l;
874 bug("\n");
876 if (datalen & 1)
877 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
880 datalen = (datalen+1)&~1;
882 if (FALSE == ata_SelectUnit(unit))
884 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
885 return IOERR_UNITBUSY;
889 * tell device whether we want to read or write and if we want a dma transfer
891 ata_out(((*dma) ? 1 : 0) |
892 (((unit->au_Drive->id_DMADir & 0x8000) && !write) ? 4 : 0),
893 atapi_Features, port);
894 ata_out((datalen & 0xff), atapi_ByteCntL, port);
895 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
898 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
899 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
901 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
902 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
903 ata_out(ATA_PACKET, atapi_Command, port);
904 ata_WaitNano(400);
905 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
907 ata_WaitBusyTO(unit, TIMEOUT, (unit->au_Drive->id_General & 0x60) == 0x20,
908 NULL);
909 if (0 == (ata_ReadStatus(unit->au_Bus) & ATAF_DATAREQ))
910 return HFERR_BadStatus;
913 * setup appropriate hooks
915 if (datalen == 0)
916 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
917 else if (*dma)
918 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
919 else if (write)
920 ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, 0, datalen);
921 else
922 ata_IRQSetHandler(unit, &ata_IRQPIOReadAtapi, data, 0, datalen);
924 if (*dma)
926 DATAPI(bug("[ATAPI] Starting DMA\n"));
927 dma_StartDMA(unit);
930 DATAPI(bug("[ATAPI] Sending packet\n"));
931 unit->au_outs(cmd, unit->au_Bus->ab_Port, 12);
932 ata_WaitNano(400);
933 DATAPI(bug("[ATAPI] Status after packet: %lx\n",
934 ata_ReadAltStatus(unit->au_Bus)));
937 * Wait for command to complete. Note that two interrupts will occur
938 * before we wake up if this is a PIO data transfer
940 if (ata_WaitTO(unit->au_Bus->ab_Timer, TIMEOUT, 0,
941 1 << unit->au_Bus->ab_SleepySignal) == 0)
943 DATAPI(bug("[DSCSI] Command timed out.\n"));
944 err = IOERR_UNITBUSY;
946 else
947 err = atapi_EndCmd(unit);
949 if (*dma)
951 dma_StopDMA(unit);
952 dma_Cleanup(data, datalen, !write);
955 DATAPI(bug("[ATAPI] IO error code %ld\n", err));
956 return err;
959 BYTE atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
961 APTR buffer = cmd->scsi_Data;
962 ULONG length = cmd->scsi_Length;
963 BOOL read = FALSE;
964 BYTE err = 0;
965 BOOL dma = FALSE;
967 cmd->scsi_Actual = 0;
969 DATAPI(bug("[DSCSI] Sending packet!\n"));
972 * setup DMA & push command
973 * it does not really mean we will use dma here btw
975 if ((unit->au_XferModes & AF_XFER_DMA) && (length !=0) && (buffer != 0))
977 dma = TRUE;
978 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
980 read = TRUE;
981 if (FALSE == dma_SetupPRDSize(unit, buffer, length, TRUE))
982 dma = FALSE;
984 else
986 if (FALSE == dma_SetupPRDSize(unit, buffer, length, FALSE))
987 dma = FALSE;
991 err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0);
993 DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); });
996 * on check condition - grab sense data
998 DATAPI(bug("[ATA%02lx] atapi_DirectSCSI: SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err));
999 if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
1001 DATAPI(bug("[DSCSI] atapi_DirectSCSI: Packet Failed. Calling atapi_RequestSense\n"));
1002 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
1003 DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
1006 return err;
1010 * chops the large transfers into set of smaller transfers
1011 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1013 static BYTE ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
1015 BYTE err = 0;
1016 ULONG part;
1017 ULONG max=256;
1018 ULONG count=blk->sectors;
1020 if (blk->type == CT_LBA48)
1021 max <<= 8;
1023 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));
1024 while ((count > 0) && (err == 0))
1026 part = (count > max) ? max : count;
1027 blk->sectors = part;
1028 blk->length = part << unit->au_SectorShift;
1030 DATA(bug("[ATA%02ld] Transfer of %ld sectors from %x%08x\n", unit->au_UnitNum, part, (ULONG)(blk->blk >> 32), (ULONG)blk->blk));
1031 err = ata_exec_cmd(unit, blk);
1032 DATA(bug("[ATA%02ld] ata_exec_blk: ata_exec_cmd returned %lx\n", unit->au_UnitNum, err));
1034 blk->blk += part;
1035 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1036 count -= part;
1038 return err;
1042 * Initial device configuration that suits *all* cases
1044 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1046 struct ata_Unit *unit=NULL;
1048 DINIT(bug("[ATA ] ata_init_unit(%ld)\n", u));
1050 unit = bus->ab_Units[u];
1051 if (NULL == unit)
1052 return FALSE;
1054 unit->au_Bus = bus;
1055 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1056 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1057 unit->au_DevMask = 0xa0 | (u << 4);
1058 if (bus->ab_Base->ata_32bit)
1060 unit->au_ins = ata_insl;
1061 unit->au_outs = ata_outsl;
1063 else
1065 unit->au_ins = ata_insw;
1066 unit->au_outs = ata_outsw;
1068 unit->au_SectorShift= 9; /* this really has to be set here. */
1070 NEWLIST(&unit->au_SoftList);
1073 * since the stack is always handled by caller
1074 * it's safe to stub all calls with one function
1076 unit->au_Read32 = ata_STUB_IO32;
1077 unit->au_Read64 = ata_STUB_IO64;
1078 unit->au_Write32 = ata_STUB_IO32;
1079 unit->au_Write64 = ata_STUB_IO64;
1080 unit->au_Eject = ata_STUB;
1081 unit->au_DirectSCSI = ata_STUB_SCSI;
1082 unit->au_Identify = ata_STUB;
1083 return TRUE;
1086 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1088 struct ata_Unit *unit=NULL;
1091 * this stuff always goes along the same way
1092 * WARNING: NO INTERRUPTS AT THIS POINT!
1094 DINIT(bug("[ATA ] ata_setup_unit(%ld,%ld)\n", bus->ab_BusNum, u));
1096 unit = bus->ab_Units[u];
1097 if (NULL == unit)
1098 return FALSE;
1100 ata_SelectUnit(unit);
1102 if (unit->au_DMAPort != 0
1103 && (ata_in(dma_Status, unit->au_DMAPort) & 0x80) != 0)
1104 bug("[ATA%02ld] ata_setup_unit: WARNING: Controller only supports "
1105 "DMA on one bus at a time. DMAStatus=%lx\n", unit->au_UnitNum,
1106 ata_in(dma_Status, unit->au_DMAPort));
1108 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE, NULL))
1110 DINIT(bug("[ATA%02ld] ata_setup_unit: ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1111 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1112 unit->au_Drive = 0;
1113 return FALSE;
1116 switch (bus->ab_Dev[u])
1119 * safe fallback settings
1121 case DEV_SATAPI:
1122 case DEV_ATAPI:
1123 case DEV_SATA:
1124 case DEV_ATA:
1125 unit->au_Identify = ata_Identify;
1126 break;
1128 default:
1129 DINIT(bug("[ATA%02ld] ata_setup_unit: Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1130 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1131 unit->au_Drive = 0;
1132 return FALSE;
1135 D(bug("[ATA ] ata_setup_unit: Enabling IRQs\n"));
1136 ata_out(0x0, ata_AltControl, bus->ab_Alt);
1139 * now make unit self diagnose
1141 if (unit->au_Identify(unit) != 0)
1143 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1144 unit->au_Drive = NULL;
1145 return FALSE;
1148 return TRUE;
1152 * ata[pi] identify
1154 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1156 UBYTE type=0;
1157 BOOL dma=FALSE;
1158 ata_CommandBlock acb =
1160 ATA_SET_FEATURES,
1161 0x03,
1162 0x01,
1163 0x00,
1164 0x00,
1165 0x00,
1166 0x00,
1167 0x00,
1168 0x00,
1169 CM_NoData,
1170 CT_LBA28
1172 DINIT(bug("[ATA%02ld] common_SetXferMode: Trying to set mode %d\n", unit->au_UnitNum, mode));
1174 if ((unit->au_DMAPort == 0) && (mode >= AB_XFER_MDMA0))
1176 DINIT(bug("[ATA%02ld] common_SetXferMode: This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1177 common_SetBestXferMode(unit);
1178 return;
1182 * first, ONLY for ATA devices, set new commands
1184 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1186 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1188 if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI))
1190 ata_IRQSetHandler(unit, ata_IRQNoData, NULL, 0, 0);
1191 ata_out(unit->au_Drive->id_RWMultipleSize & 0xFF, ata_Count, unit->au_Bus->ab_Port);
1192 ata_out(ATA_SET_MULTIPLE, ata_Command, unit->au_Bus->ab_Port);
1193 ata_WaitBusyTO(unit, -1, TRUE, NULL);
1195 unit->au_Read32 = ata_ReadMultiple32;
1196 unit->au_Write32 = ata_WriteMultiple32;
1197 if (unit->au_XferModes & AF_XFER_48BIT)
1199 unit->au_Read64 = ata_ReadMultiple64;
1200 unit->au_Write64 = ata_WriteMultiple64;
1203 else
1205 unit->au_Read32 = ata_ReadSector32;
1206 unit->au_Write32 = ata_WriteSector32;
1207 if (unit->au_XferModes & AF_XFER_48BIT)
1209 unit->au_Read64 = ata_ReadSector64;
1210 unit->au_Write64 = ata_WriteSector64;
1214 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1216 unit->au_Read32 = ata_ReadDMA32;
1217 unit->au_Write32 = ata_WriteDMA32;
1218 if (unit->au_XferModes & AF_XFER_48BIT)
1220 unit->au_Read64 = ata_ReadDMA64;
1221 unit->au_Write64 = ata_WriteDMA64;
1224 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1226 unit->au_Read32 = ata_ReadDMA32;
1227 unit->au_Write32 = ata_WriteDMA32;
1228 if (unit->au_XferModes & AF_XFER_48BIT)
1230 unit->au_Read64 = ata_ReadDMA64;
1231 unit->au_Write64 = ata_WriteDMA64;
1234 else
1236 unit->au_Read32 = ata_ReadSector32;
1237 unit->au_Write32 = ata_WriteSector32;
1238 if (unit->au_XferModes & AF_XFER_48BIT)
1240 unit->au_Read64 = ata_ReadSector64;
1241 unit->au_Write64 = ata_WriteSector64;
1246 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1248 type = 8 + (mode - AB_XFER_PIO0);
1250 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1252 type = 32 + (mode - AB_XFER_MDMA0);
1253 dma=TRUE;
1255 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1257 type = 64 + (mode - AB_XFER_UDMA0);
1258 dma=TRUE;
1260 else
1262 type = 0;
1265 #if 0 // We can't set drive modes unless we also set the controller's timing registers
1266 acb.sectors = type;
1267 if (0 != ata_exec_cmd(unit, &acb))
1269 DINIT(bug("[ATA%02ld] common_SetXferMode: ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1272 if (unit->au_DMAPort)
1274 type = ata_in(dma_Status, unit->au_DMAPort);
1275 type &= 0x60;
1276 if (dma)
1278 type |= 1 << (5 + (unit->au_UnitNum & 1));
1280 else
1282 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1285 DINIT(bug("[DSCSI] common_SetXferMode: Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1287 ata_SelectUnit(unit);
1288 ata_out(type, dma_Status, unit->au_DMAPort);
1289 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1291 DINIT(bug("[DSCSI] common_SetXferMode: New DMA Status: %02lx\n", type));
1293 else
1295 DINIT(bug("[DSCSI] common_SetXferMode: Failed to modify DMA state for this device\n"));
1296 dma = FALSE;
1299 #endif
1301 if (dma)
1302 unit->au_XferModes |= AF_XFER_DMA;
1303 else
1304 unit->au_XferModes &= ~AF_XFER_DMA;
1307 static void common_SetBestXferMode(struct ata_Unit* unit)
1309 int iter;
1310 int max = AB_XFER_UDMA6;
1312 if (unit->au_Bus->ab_Base->ata_NoDMA || unit->au_DMAPort == 0
1313 || !(unit->au_Drive->id_MWDMASupport & 0x0700)
1314 && !(unit->au_Drive->id_UDMASupport & 0x7f00))
1317 * make sure you reduce scan search to pio here!
1318 * otherwise this and above function will fall into infinite loop
1320 DINIT(bug("[ATA%02ld] common_SetBestXferMode: DMA is disabled for"
1321 " this drive.\n", unit->au_UnitNum));
1322 max = AB_XFER_PIO4;
1324 else if (!(unit->au_Flags & AF_80Wire))
1326 DINIT(bug("[ATA%02ld] common_SetBestXferMode: "
1327 "An 80-wire cable has not been detected for this drive. "
1328 "Disabling modes above UDMA2.\n", unit->au_UnitNum));
1329 max = AB_XFER_UDMA2;
1332 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1334 if (unit->au_XferModes & (1<<iter))
1336 common_SetXferMode(unit, iter);
1337 return;
1340 bug("[ATA%02ld] common_SetBestXferMode: ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1341 common_SetXferMode(unit, AB_XFER_PIO0);
1344 void common_DetectXferModes(struct ata_Unit* unit)
1346 int iter;
1348 DINIT(bug("[ATA%02ld] common_DetectXferModes: Supports\n", unit->au_UnitNum));
1350 if (unit->au_Drive->id_Commands4 & (1 << 4))
1352 DINIT(bug("[ATA%02ld] common_DetectXferModes: - Packet interface\n", unit->au_UnitNum));
1353 unit->au_XferModes |= AF_XFER_PACKET;
1354 unit->au_DirectSCSI = atapi_DirectSCSI;
1356 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1358 /* ATAPI devices do not use this bit. */
1359 DINIT(bug("[ATA%02ld] common_DetectXferModes: - 48bit I/O\n", unit->au_UnitNum));
1360 unit->au_XferModes |= AF_XFER_48BIT;
1363 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1365 DINIT(bug("[ATA%02ld] common_DetectXferModes: - LBA Addressing\n", unit->au_UnitNum));
1366 unit->au_XferModes |= AF_XFER_LBA;
1368 else
1370 DINIT(bug("[ATA%02ld] common_DetectXferModes: - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1373 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1375 DINIT(bug("[ATA%02ld] common_DetectXferModes: - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1376 unit->au_XferModes |= AF_XFER_RWMULTI;
1379 DINIT(bug("[ATA%02ld] common_DetectXferModes: - PIO0 PIO1 PIO2 ",
1380 unit->au_UnitNum));
1381 unit->au_XferModes |= AF_XFER_PIO(0) | AF_XFER_PIO(1) | AF_XFER_PIO(2);
1382 if (unit->au_Drive->id_ConfigAvailable & (1 << 1))
1384 for (iter = 0; iter < 2; iter++)
1386 if (unit->au_Drive->id_PIOSupport & (1 << iter))
1388 DINIT(bug("PIO%ld ", 3 + iter));
1389 unit->au_XferModes |= AF_XFER_PIO(3 + iter);
1392 DINIT(bug("\n"));
1395 if ((unit->au_Drive->id_ConfigAvailable & (1 << 1)) &&
1396 (unit->au_Drive->id_Capabilities & (1<<8)))
1398 DINIT(bug("[ATA%02ld] common_DetectXferModes: DMA:\n", unit->au_UnitNum));
1399 if (unit->au_Drive->id_MWDMASupport & 0xff)
1401 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1402 for (iter = 0; iter < 3; iter++)
1404 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1406 unit->au_XferModes |= AF_XFER_MDMA(iter);
1407 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1409 DINIT(bug("[MDMA%ld] ", iter));
1411 else
1413 DINIT(bug("MDMA%ld ", iter));
1417 DINIT(bug("\n"));
1420 if (unit->au_Drive->id_UDMASupport & 0xff)
1422 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1423 for (iter = 0; iter < 7; iter++)
1425 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1427 unit->au_XferModes |= AF_XFER_UDMA(iter);
1428 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1430 DINIT(bug("[UDMA%ld] ", iter));
1432 else
1434 DINIT(bug("UDMA%ld ", iter));
1438 DINIT(bug("\n"));
1443 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1444 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1445 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1447 BYTE ata_Identify(struct ata_Unit* unit)
1449 BOOL atapi = unit->au_Bus->ab_Dev[unit->au_UnitNum & 1] & 0x80;
1450 ata_CommandBlock acb =
1452 atapi ? ATA_IDENTIFY_ATAPI : ATA_IDENTIFY_DEVICE,
1458 unit->au_Drive,
1459 sizeof(struct DriveIdent),
1461 CM_PIORead,
1462 CT_NoBlock
1465 if (ata_exec_cmd(unit, &acb))
1466 return IOERR_OPENFAIL;
1469 * If every second word is zero with 32-bit reads, switch to 16-bit
1470 * accesses for this drive and try again
1472 if (unit->au_Bus->ab_Base->ata_32bit)
1474 UWORD n = 0, *p, *limit;
1476 for (p = unit->au_Drive, limit = p + 256; p < limit; p++)
1477 n |= *++p;
1479 if (n == 0)
1481 DINIT(bug("[ATA%02ld] Identify data was invalid with 32-bit reads."
1482 " Switching to 16-bit mode.\n", unit->au_UnitNum));
1483 unit->au_ins = ata_insw;
1484 unit->au_outs = ata_outsw;
1485 if (ata_exec_cmd(unit, &acb))
1486 return IOERR_OPENFAIL;
1490 #if (AROS_BIG_ENDIAN != 0)
1491 SWAP_LE_WORD(unit->au_Drive->id_General);
1492 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1493 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1494 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1495 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1496 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1497 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1498 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1499 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1500 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1501 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1502 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1503 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1504 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1505 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1506 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1507 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1508 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1509 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1510 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1511 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1512 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1513 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1514 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1515 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1516 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1517 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1518 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1519 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1520 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1521 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1522 SWAP_LE_WORD(unit->au_Drive->id_ESecurityEraseTime);
1523 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvPowerMode);
1524 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1525 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1526 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1527 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1528 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1529 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1530 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1531 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1532 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1533 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1535 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1536 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1537 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1539 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1540 #endif
1542 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1544 if (atapi)
1546 unit->au_SectorShift = 11;
1547 unit->au_Read32 = atapi_Read;
1548 unit->au_Write32 = atapi_Write;
1549 unit->au_DirectSCSI = atapi_DirectSCSI;
1550 unit->au_Eject = atapi_Eject;
1551 unit->au_Flags |= AF_DiscChanged;
1552 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1553 unit->au_XferModes = AF_XFER_PACKET;
1555 else
1557 unit->au_SectorShift = 9;
1558 unit->au_DevType = DG_DIRECT_ACCESS;
1559 unit->au_Read32 = ata_ReadSector32;
1560 unit->au_Write32 = ata_WriteSector32;
1561 unit->au_Eject = ata_Eject;
1562 unit->au_XferModes = 0;
1563 unit->au_Flags |= AF_DiscPresent | AF_DiscChanged;
1566 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1567 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1568 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1570 bug("[ATA%02ld] ata_Identify: Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1571 common_DetectXferModes(unit);
1572 common_SetBestXferMode(unit);
1574 if (unit->au_Drive->id_General & 0x80)
1576 DINIT(bug("[ATA%02ld] ata_Identify: Device is removable.\n", unit->au_UnitNum));
1577 unit->au_Flags |= AF_Removable;
1580 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1581 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1582 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));
1584 if (atapi)
1587 * ok, this is not very original, but quite compatible :P
1589 switch (unit->au_DevType)
1591 case DG_CDROM:
1592 case DG_WORM:
1593 case DG_OPTICAL_DISK:
1594 unit->au_SectorShift = 11;
1595 unit->au_Heads = 1;
1596 unit->au_Sectors = 75;
1597 unit->au_Cylinders = 4440;
1598 break;
1600 case DG_DIRECT_ACCESS:
1601 unit->au_SectorShift = 9;
1602 if (!strcmp("LS-120", &unit->au_Model[0]))
1604 unit->au_Heads = 2;
1605 unit->au_Sectors = 18;
1606 unit->au_Cylinders = 6848;
1608 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1610 unit->au_Heads = 1;
1611 unit->au_Sectors = 64;
1612 unit->au_Cylinders = 3072;
1614 break;
1617 atapi_TestUnitOK(unit);
1619 else
1622 For drive capacities > 8.3GB assume maximal possible layout.
1623 It really doesn't matter here, as BIOS will not handle them in
1624 CHS way anyway :)
1625 i guess this just solves that weirdo div-by-zero crash, if nothing
1626 else...
1628 if ((unit->au_Drive->id_LBA48Sectors > (63 * 255 * 1024)) ||
1629 (unit->au_Drive->id_LBASectors > (63 * 255 * 1024)))
1631 ULONG div = 1;
1633 * TODO: this shouldn't be casted down here.
1635 ULONG sec = unit->au_Capacity48;
1637 if (sec < unit->au_Capacity48)
1638 sec = ~0ul;
1640 if (sec < unit->au_Capacity)
1641 sec = unit->au_Capacity;
1643 unit->au_Sectors = 63;
1644 sec /= 63;
1646 * keep dividing by 2
1650 if (((sec >> 1) << 1) != sec)
1651 break;
1652 if ((div << 1) > 255)
1653 break;
1654 div <<= 1;
1655 sec >>= 1;
1656 } while (1);
1660 if (((sec / 3) * 3) != sec)
1661 break;
1662 if ((div * 3) > 255)
1663 break;
1664 div *= 3;
1665 sec /= 3;
1666 } while (1);
1668 unit->au_Cylinders = sec;
1669 unit->au_Heads = div;
1671 else
1673 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1674 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1675 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1679 return 0;
1683 * ata read32 commands
1685 static BYTE ata_ReadSector32(struct ata_Unit *unit, ULONG block,
1686 ULONG count, APTR buffer, ULONG *act)
1688 ata_CommandBlock acb =
1690 ATA_READ,
1694 block,
1695 count,
1696 buffer,
1697 count << unit->au_SectorShift,
1699 CM_PIORead,
1700 CT_LBA28
1702 BYTE err;
1704 D(bug("[ATA%02ld] ata_ReadSector32()\n", unit->au_UnitNum));
1706 *act = 0;
1707 if (0 != (err = ata_exec_blk(unit, &acb)))
1708 return err;
1710 *act = count << unit->au_SectorShift;
1711 return 0;
1714 static BYTE ata_ReadMultiple32(struct ata_Unit *unit, ULONG block,
1715 ULONG count, APTR buffer, ULONG *act)
1717 ata_CommandBlock acb =
1719 ATA_READ_MULTIPLE,
1721 unit->au_Drive->id_RWMultipleSize & 0xff,
1723 block,
1724 count,
1725 buffer,
1726 count << unit->au_SectorShift,
1728 CM_PIORead,
1729 CT_LBA28
1731 BYTE err;
1733 D(bug("[ATA%02ld] ata_ReadMultiple32()\n", unit->au_UnitNum));
1735 *act = 0;
1736 if (0 != (err = ata_exec_blk(unit, &acb)))
1737 return err;
1739 *act = count << unit->au_SectorShift;
1740 return 0;
1743 static BYTE ata_ReadDMA32(struct ata_Unit *unit, ULONG block,
1744 ULONG count, APTR buffer, ULONG *act)
1746 BYTE err;
1747 ata_CommandBlock acb =
1749 ATA_READ_DMA,
1753 block,
1754 count,
1755 buffer,
1756 count << unit->au_SectorShift,
1758 CM_DMARead,
1759 CT_LBA28
1762 D(bug("[ATA%02ld] ata_ReadDMA32()\n", unit->au_UnitNum));
1764 *act = 0;
1765 if (0 != (err = ata_exec_blk(unit, &acb)))
1766 return err;
1768 *act = count << unit->au_SectorShift;
1769 return 0;
1773 * ata read64 commands
1775 static BYTE ata_ReadSector64(struct ata_Unit *unit, UQUAD block,
1776 ULONG count, APTR buffer, ULONG *act)
1778 ata_CommandBlock acb =
1780 ATA_READ64,
1784 block,
1785 count,
1786 buffer,
1787 count << unit->au_SectorShift,
1789 CM_PIORead,
1790 CT_LBA48
1792 BYTE err = 0;
1794 D(bug("[ATA%02ld] ata_ReadSector64()\n", unit->au_UnitNum));
1796 *act = 0;
1797 if (0 != (err = ata_exec_blk(unit, &acb)))
1798 return err;
1800 *act = count << unit->au_SectorShift;
1801 return 0;
1804 static BYTE ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block,
1805 ULONG count, APTR buffer, ULONG *act)
1807 ata_CommandBlock acb =
1809 ATA_READ_MULTIPLE64,
1811 unit->au_Drive->id_RWMultipleSize & 0xff,
1813 block,
1814 count,
1815 buffer,
1816 count << unit->au_SectorShift,
1818 CM_PIORead,
1819 CT_LBA48
1821 BYTE err;
1823 D(bug("[ATA%02ld] ata_ReadMultiple64()\n", unit->au_UnitNum));
1825 *act = 0;
1826 if (0 != (err = ata_exec_blk(unit, &acb)))
1827 return err;
1829 *act = count << unit->au_SectorShift;
1830 return 0;
1833 static BYTE ata_ReadDMA64(struct ata_Unit *unit, UQUAD block,
1834 ULONG count, APTR buffer, ULONG *act)
1836 ata_CommandBlock acb =
1838 ATA_READ_DMA64,
1842 block,
1843 count,
1844 buffer,
1845 count << unit->au_SectorShift,
1847 CM_DMARead,
1848 CT_LBA48
1850 BYTE err;
1852 D(bug("[ATA%02ld] ata_ReadDMA64()\n", unit->au_UnitNum));
1854 *act = 0;
1855 if (0 != (err = ata_exec_blk(unit, &acb)))
1856 return err;
1858 *act = count << unit->au_SectorShift;
1859 return 0;
1863 * ata write32 commands
1865 static BYTE ata_WriteSector32(struct ata_Unit *unit, ULONG block,
1866 ULONG count, APTR buffer, ULONG *act)
1868 ata_CommandBlock acb =
1870 ATA_WRITE,
1874 block,
1875 count,
1876 buffer,
1877 count << unit->au_SectorShift,
1879 CM_PIOWrite,
1880 CT_LBA28
1882 BYTE err;
1884 D(bug("[ATA%02ld] ata_WriteSector32()\n", unit->au_UnitNum));
1886 *act = 0;
1887 if (0 != (err = ata_exec_blk(unit, &acb)))
1888 return err;
1890 *act = count << unit->au_SectorShift;
1891 return 0;
1894 static BYTE ata_WriteMultiple32(struct ata_Unit *unit, ULONG block,
1895 ULONG count, APTR buffer, ULONG *act)
1897 ata_CommandBlock acb =
1899 ATA_WRITE_MULTIPLE,
1901 unit->au_Drive->id_RWMultipleSize & 0xff,
1903 block,
1904 count,
1905 buffer,
1906 count << unit->au_SectorShift,
1908 CM_PIOWrite,
1909 CT_LBA28
1911 BYTE err;
1913 D(bug("[ATA%02ld] ata_WriteMultiple32()\n", unit->au_UnitNum));
1915 *act = 0;
1916 if (0 != (err = ata_exec_blk(unit, &acb)))
1917 return err;
1919 *act = count << unit->au_SectorShift;
1920 return 0;
1923 static BYTE ata_WriteDMA32(struct ata_Unit *unit, ULONG block,
1924 ULONG count, APTR buffer, ULONG *act)
1926 ata_CommandBlock acb =
1928 ATA_WRITE_DMA,
1932 block,
1933 count,
1934 buffer,
1935 count << unit->au_SectorShift,
1937 CM_DMAWrite,
1938 CT_LBA28
1940 BYTE err;
1942 D(bug("[ATA%02ld] ata_WriteDMA32()\n", unit->au_UnitNum));
1944 *act = 0;
1945 if (0 != (err = ata_exec_blk(unit, &acb)))
1946 return err;
1948 *act = count << unit->au_SectorShift;
1949 return 0;
1953 * ata write64 commands
1955 static BYTE ata_WriteSector64(struct ata_Unit *unit, UQUAD block,
1956 ULONG count, APTR buffer, ULONG *act)
1958 ata_CommandBlock acb =
1960 ATA_WRITE64,
1964 block,
1965 count,
1966 buffer,
1967 count << unit->au_SectorShift,
1969 CM_PIOWrite,
1970 CT_LBA48
1972 BYTE err;
1974 D(bug("[ATA%02ld] ata_WriteSector64()\n", unit->au_UnitNum));
1976 *act = 0;
1977 if (0 != (err = ata_exec_blk(unit, &acb)))
1978 return err;
1980 *act = count << unit->au_SectorShift;
1981 return 0;
1984 static BYTE ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block,
1985 ULONG count, APTR buffer, ULONG *act)
1987 ata_CommandBlock acb =
1989 ATA_WRITE_MULTIPLE64,
1991 unit->au_Drive->id_RWMultipleSize & 0xff,
1993 block,
1994 count,
1995 buffer,
1996 count << unit->au_SectorShift,
1998 CM_PIOWrite,
1999 CT_LBA48
2001 BYTE err;
2003 D(bug("[ATA%02ld] ata_WriteMultiple64()\n", unit->au_UnitNum));
2005 *act = 0;
2006 if (0 != (err = ata_exec_blk(unit, &acb)))
2007 return err;
2009 *act = count << unit->au_SectorShift;
2010 return 0;
2013 static BYTE ata_WriteDMA64(struct ata_Unit *unit, UQUAD block,
2014 ULONG count, APTR buffer, ULONG *act)
2016 ata_CommandBlock acb =
2018 ATA_WRITE_DMA64,
2022 block,
2023 count,
2024 buffer,
2025 count << unit->au_SectorShift,
2027 CM_DMAWrite,
2028 CT_LBA48
2030 BYTE err;
2032 D(bug("[ATA%02ld] ata_WriteDMA64()\n", unit->au_UnitNum));
2034 *act = 0;
2035 if (0 != (err = ata_exec_blk(unit, &acb)))
2036 return err;
2038 *act = count << unit->au_SectorShift;
2039 return 0;
2043 * ata miscellaneous commands
2045 static BYTE ata_Eject(struct ata_Unit *unit)
2047 ata_CommandBlock acb =
2049 ATA_MEDIA_EJECT,
2058 CM_NoData,
2059 CT_NoBlock
2062 D(bug("[ATA%02ld] ata_Eject()\n", unit->au_UnitNum));
2064 return ata_exec_cmd(unit, &acb);
2068 * atapi commands
2070 int atapi_TestUnitOK(struct ata_Unit *unit)
2072 UBYTE cmd[6] = {
2075 UBYTE sense[16] = {
2078 struct SCSICmd sc = {
2082 D(bug("[ATA%02ld] atapi_TestUnitOK()\n", unit->au_UnitNum));
2084 sc.scsi_Command = (void*) &cmd;
2085 sc.scsi_CmdLength = sizeof(cmd);
2086 sc.scsi_SenseData = (void*)&sense;
2087 sc.scsi_SenseLength = sizeof(sense);
2088 sc.scsi_Flags = SCSIF_AUTOSENSE;
2090 DATAPI(bug("[ATA%02ld] atapi_TestUnitOK: Testing Unit Ready sense...\n", unit->au_UnitNum));
2091 unit->au_DirectSCSI(unit, &sc);
2092 unit->au_SenseKey = sense[2];
2095 * we may have just lost the disc...?
2098 * per MMC, drives are expected to return 02-3a-0# status, when disc is not present
2099 * that would translate into following code:
2100 * int p1 = ((sense[2] == 2) && (sense[12] == 0x3a)) ? 1 : 0;
2101 * unfortunately, it's what MMC says, not what vendors code.
2103 int p1 = (sense[2] == 2) ? 1 : 0;
2104 int p2 = (0 != (AF_DiscPresent & unit->au_Flags)) ? 1 : 0;
2106 if (p1 == p2)
2108 //unit->au_Flags ^= AF_DiscPresent;
2109 if (p1 == 0)
2110 unit->au_Flags |= AF_DiscPresent;
2111 else
2112 unit->au_Flags &= ~AF_DiscPresent;
2114 unit->au_Flags |= AF_DiscChanged;
2117 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"));
2118 return sense[2];
2121 static BYTE atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count,
2122 APTR buffer, ULONG *act)
2124 UBYTE cmd[] = {
2125 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2127 struct SCSICmd sc = {
2131 D(bug("[ATA%02ld] atapi_Read()\n", unit->au_UnitNum));
2133 sc.scsi_Command = (void*) &cmd;
2134 sc.scsi_CmdLength = sizeof(cmd);
2135 sc.scsi_Data = buffer;
2136 sc.scsi_Length = count << unit->au_SectorShift;
2137 sc.scsi_Flags = SCSIF_READ;
2139 return unit->au_DirectSCSI(unit, &sc);
2142 static BYTE atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count,
2143 APTR buffer, ULONG *act)
2145 UBYTE cmd[] = {
2146 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2148 struct SCSICmd sc = {
2152 D(bug("[ATA%02ld] atapi_Write()\n", unit->au_UnitNum));
2154 sc.scsi_Command = (void*) &cmd;
2155 sc.scsi_CmdLength = sizeof(cmd);
2156 sc.scsi_Data = buffer;
2157 sc.scsi_Length = count << unit->au_SectorShift;
2158 sc.scsi_Flags = SCSIF_WRITE;
2160 return unit->au_DirectSCSI(unit, &sc);
2163 static BYTE atapi_Eject(struct ata_Unit *unit)
2165 struct atapi_StartStop cmd = {
2166 command: SCSI_STARTSTOP,
2167 immediate: 1,
2168 flags: ATAPI_SS_EJECT,
2171 struct SCSICmd sc = {
2175 D(bug("[ATA%02ld] atapi_Eject()\n", unit->au_UnitNum));
2177 sc.scsi_Command = (void*) &cmd;
2178 sc.scsi_CmdLength = sizeof(cmd);
2179 sc.scsi_Flags = SCSIF_READ;
2181 return unit->au_DirectSCSI(unit, &sc);
2184 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2186 UBYTE cmd[] = {
2187 3, 0, 0, 0, senselen & 0xfe, 0
2189 struct SCSICmd sc = {
2193 D(bug("[ATA%02ld] atapi_RequestSense()\n", unit->au_UnitNum));
2195 if ((senselen == 0) || (sense == 0))
2197 return 0;
2199 sc.scsi_Data = (void*)sense;
2200 sc.scsi_Length = senselen & 0xfe;
2201 sc.scsi_Command = (void*)&cmd;
2202 sc.scsi_CmdLength = 6;
2203 sc.scsi_Flags = SCSIF_READ;
2205 unit->au_DirectSCSI(unit, &sc);
2207 DATAPI(dump(sense, senselen));
2208 DATAPI(bug("[SENSE] atapi_RequestSense: sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2209 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2212 ULONG ata_ReadSignature(struct ata_Bus *bus, int unit)
2214 ULONG port = bus->ab_Port;
2215 UBYTE tmp1, tmp2;
2217 D(bug("[ATA ] ata_ReadSignature(%02ld)\n", unit));
2219 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2220 ata_WaitNano(400);
2221 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2223 /* Check basic signature. All live devices should provide it */
2224 tmp1 = ata_in(ata_Count, port);
2225 tmp2 = ata_in(ata_LBALow, port);
2226 DINIT(bug("[ATA ] ata_ReadSignature: Checking Count / LBA (%d:%d) against expected values\n", tmp1, tmp2));
2228 DINIT(bug("[ATA ] ata_ReadSignature: Status %02lx Device %02lx\n",
2229 ata_in(ata_Status, port), ata_in(ata_DevHead, port)));
2231 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2233 /* Ok, ATA/ATAPI device. Get detailed signature */
2234 DINIT(bug("[ATA ] ata_ReadSignature: Found an ATA[PI] Device. Attempting to detect specific subtype\n"));
2236 tmp1 = ata_in(ata_LBAMid, port);
2237 tmp2 = ata_in(ata_LBAHigh, port);
2239 DINIT(bug("[ATA ] ata_ReadSignature: Subtype check returned %02lx:%02lx (%04lx)\n", tmp1, tmp2, (tmp1 << 8) | tmp2));
2241 switch ((tmp1 << 8) | tmp2)
2243 case 0x0000:
2244 if (0 == (ata_ReadStatus(bus) & 0xfe))
2245 return DEV_NONE;
2246 ata_out(ATA_EXECUTE_DIAG, ata_Command, port);
2248 ata_WaitTO(bus->ab_Timer, 0, 2000, 0);
2249 while (ata_ReadStatus(bus) & ATAF_BUSY)
2250 ata_WaitNano(400);
2251 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2253 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2256 ata_WaitNano(400);
2257 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
2259 while (0 != (ATAF_BUSY & ata_ReadStatus(bus)));
2260 DINIT(bug("[ATA ] ata_ReadSignature: Further validating ATA signature: %lx & 0x7f = 1, %lx & 0x10 = unit\n", ata_in(ata_Error, port), ata_in(ata_DevHead, port)));
2262 if ((ata_in(ata_Error, port) & 0x7f) == 1)
2264 DINIT(bug("[ATA ] ata_ReadSignature: Found *valid* signature for ATA device\n"));
2265 return DEV_ATA;
2267 bug("[ATA ] ata_ReadSignature: Found signature for ATA "
2268 "device, but further validation failed\n");
2269 return DEV_NONE;
2271 case 0x14eb:
2272 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for ATAPI device\n"));
2273 return DEV_ATAPI;
2275 case 0x3cc3:
2276 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATA device\n"));
2277 return DEV_SATA;
2279 case 0x6996:
2280 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATAPI device\n"));
2281 return DEV_SATAPI;
2283 default:
2284 if (((tmp1 | tmp2) == 0xff) &&
2285 ((tmp1 & tmp2) == 0x00))
2287 bug("[ATA ] ata_ReadSignature: Found valid subtype, but don't know how to handle this device: %02lx %02lx\n", tmp1, tmp2);
2289 else
2291 bug("[ATA ] ata_ReadSignature: Invalid signature: %02lx %02lx\n", tmp1, tmp2);
2293 return DEV_NONE;
2297 return DEV_NONE;
2300 void ata_ResetBus(struct ata_Bus *bus)
2302 ULONG alt = bus->ab_Alt;
2303 ULONG port = bus->ab_Port;
2304 ULONG TimeOut;
2306 /* Set and then reset the soft reset bit in the Device Control
2307 * register. This causes device 0 be selected */
2308 D(bug("[ATA ] ata_ResetBus(%d)\n", bus->ab_BusNum));
2309 ata_out(0xa0 | (0 << 4), ata_DevHead, port); /* Select it never the less */
2310 ata_WaitNano(400);
2311 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2313 ata_out(0x04, ata_AltControl, alt);
2314 ata_WaitTO(bus->ab_Timer, 0, 10, 0); /* sleep 10us; min: 5us */
2315 ata_out(0x02, ata_AltControl, alt);
2316 ata_WaitTO(bus->ab_Timer, 0, 20000, 0); /* sleep 20ms; min: 2ms */
2318 /* If there is a device 0, wait for device 0 to clear BSY */
2319 if (DEV_NONE != bus->ab_Dev[0]) {
2320 D(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n", ((bus->ab_BusNum << 1 ) + 0)));
2321 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2322 while ( 1 ) {
2323 if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0)
2324 break;
2325 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2326 if (!(--TimeOut)) {
2327 D(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n", ((bus->ab_BusNum << 1 ) + 0)));
2328 bus->ab_Dev[0] = DEV_NONE;
2329 break;
2332 D(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n", ((bus->ab_BusNum << 1 ) + 0), (1000 - TimeOut)));
2335 /* If there is a device 1, wait until device 1 allows
2336 * register access */
2337 if (DEV_NONE != bus->ab_Dev[1]) {
2338 D(bug("[ATA ] ata_ResetBus: Wait DEV1 to allow access\n"));
2339 ata_out(0xa0 | (1 << 4), ata_DevHead, port);
2340 ata_WaitNano(400);
2341 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2342 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2343 while ( 1 ) {
2344 if ( (ata_in(2, port) == 0x01) && (ata_in(3, port) == 0x01) )
2345 break;
2346 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2347 if (!(--TimeOut)) {
2348 D(bug("[ATA ] ata_ResetBus: DEV1 1/2 TimeOut!\n"));
2349 bus->ab_Dev[1] = DEV_NONE;
2350 break;
2353 D(bug("[ATA ] ata_ResetBus: DEV1 1/2 Wait left after %d ms\n", (1000 - TimeOut)));
2355 if (DEV_NONE != bus->ab_Dev[1]) {
2356 D(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n", ((bus->ab_BusNum << 1 ) + 1)));
2357 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2358 while ( 1 ) {
2359 if ((ata_ReadStatus(bus) & ATAF_BUSY) == 0)
2360 break;
2361 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2362 if (!(--TimeOut)) {
2363 D(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n", ((bus->ab_BusNum << 1 ) + 1)));
2364 bus->ab_Dev[1] = DEV_NONE;
2365 break;
2368 D(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n", ((bus->ab_BusNum << 1 ) + 1), 1000 - TimeOut));
2372 if (DEV_NONE != bus->ab_Dev[0])
2373 bus->ab_Dev[0] = ata_ReadSignature(bus, 0);
2374 if (DEV_NONE != bus->ab_Dev[1])
2375 bus->ab_Dev[1] = ata_ReadSignature(bus, 1);
2378 void ata_InitBus(struct ata_Bus *bus)
2380 ULONG port = bus->ab_Port;
2381 UBYTE tmp1, tmp2;
2382 UWORD i;
2385 * initialize timer for the sake of scanning
2387 bus->ab_Timer = ata_OpenTimer();
2389 D(bug("[ATA ] ata_InitBus(%d)\n", bus->ab_BusNum));
2391 bus->ab_Dev[0] = DEV_NONE;
2392 bus->ab_Dev[1] = DEV_NONE;
2394 for (i = 0; i < MAX_BUSUNITS; i++)
2396 /* Select device and disable IRQs */
2397 ata_out(0xa0 | (i << 4), ata_DevHead, port);
2398 ata_WaitTO(bus->ab_Timer, 0, 100, 0);
2399 ata_out(0x2, ata_AltControl, bus->ab_Alt);
2401 /* Write some pattern to registers */
2402 ata_out(0x55, ata_LBAMid, port);
2403 ata_out(0xaa, ata_LBAHigh, port);
2404 ata_out(0xaa, ata_LBAMid, port);
2405 ata_out(0x55, ata_LBAHigh, port);
2406 ata_out(0x55, ata_LBAMid, port);
2407 ata_out(0xaa, ata_LBAHigh, port);
2409 tmp1 = ata_in(ata_LBAMid, port);
2410 tmp2 = ata_in(ata_LBAHigh, port);
2412 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2413 bus->ab_Dev[i] = DEV_UNKNOWN;
2414 D(bug("[ATA%02ld] ata_InitBus: Device type = %x\n",
2415 (bus->ab_BusNum << 1 ) + i, bus->ab_Dev[i]));
2418 ata_ResetBus(bus);
2419 ata_CloseTimer(bus->ab_Timer);
2420 D(bug("[ATA ] ata_InitBus: Finished\n"));
2424 * not really sure what this is meant to be - TO BE REPLACED
2426 static const ULONG ErrorMap[] = {
2427 CDERR_NotSpecified,
2428 CDERR_NoSecHdr,
2429 CDERR_NoDisk,
2430 CDERR_NoSecHdr,
2431 CDERR_NoSecHdr,
2432 CDERR_NOCMD,
2433 CDERR_NoDisk,
2434 CDERR_WriteProt,
2435 CDERR_NotSpecified,
2436 CDERR_NotSpecified,
2437 CDERR_NotSpecified,
2438 CDERR_ABORTED,
2439 CDERR_NotSpecified,
2440 CDERR_NotSpecified,
2441 CDERR_NoSecHdr,
2442 CDERR_NotSpecified,
2445 static BYTE atapi_EndCmd(struct ata_Unit *unit)
2447 UBYTE status;
2449 DATAPI(bug("[ATA%02ld] atapi_EndCmd()\n", unit->au_UnitNum));
2452 * read alternate status register (per specs)
2454 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2455 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Alternate status: %lx\n", unit->au_UnitNum, status));
2457 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2459 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Command complete. Status: %lx\n",
2460 unit->au_UnitNum, status));
2462 if (!(status & ATAPIF_CHECK))
2464 return 0;
2466 else
2468 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2469 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Error code 0x%lx\n", unit->au_UnitNum, status >> 4));
2470 return ErrorMap[status >> 4];
2475 * vim: ts=4 et sw=4 fdm=marker fmr={,}