- Give PCI controllers lower unit numbers than legacy controllers.
[cake.git] / arch / common / ata.device / lowlevel.c
blob0e96d12d3f904552024a286540b61c019568d03c
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) D(a)
67 #define DUMP(a)
68 #define DATA(a) D(a)
69 #define DATAPI(a) D(a)
70 #define DINIT(a) D(a)
72 #include <aros/debug.h>
73 #include <exec/types.h>
74 #include <exec/exec.h>
75 #include <exec/resident.h>
76 #include <utility/utility.h>
77 #include <oop/oop.h>
79 #include <proto/exec.h>
80 #include <devices/timer.h>
82 #include <asm/io.h>
84 #include "ata.h"
85 #include "timer.h"
90 Prototypes of static functions from lowlevel.c. I do not want to make them
91 non-static as I'd like to remove as much symbols from global table as possible.
92 Besides some of this functions could conflict with old ide.device or any other
93 device.
95 static ULONG ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
96 static ULONG ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
97 static ULONG ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
98 static ULONG ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
99 static ULONG ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
100 static ULONG ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
101 static ULONG ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
102 static ULONG ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
103 static ULONG ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
104 static ULONG ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
105 static ULONG ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
106 static ULONG ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
107 static ULONG ata_Eject(struct ata_Unit *);
108 static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout);
110 static ULONG atapi_EndCmd(struct ata_Unit *unit);
112 static ULONG atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
113 static ULONG atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
114 static ULONG atapi_Eject(struct ata_Unit *);
116 static void common_SetBestXferMode(struct ata_Unit* unit);
119 Again piece of code which shouldn't be here. Geee. After removing all this
120 asm constrictuins this ata.device will really deserve for location in
121 /arch/common
124 * having an x86 assembly here i dare to assume that this is meant to be
125 * an x86[_64] device only.
127 * Not anymore.
129 * This functions will stay here for some time *IF* and only if the code is compiled for
130 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
131 * one who ports the driver will be reponsible for adding the missing code.
135 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
137 #if defined(__i386__) || defined(__x86_64__)
139 static VOID ata_insw(APTR address, UWORD port, ULONG count)
141 insw(port, address, count >> 1);
144 static VOID ata_insl(APTR address, UWORD port, ULONG count)
146 if (count & 2)
147 insw(port, address, count >> 1);
148 else
149 insl(port, address, count >> 2);
152 static VOID ata_outsw(APTR address, UWORD port, ULONG count)
154 outsw(port, address, count >> 1);
157 static VOID ata_outsl(APTR address, UWORD port, ULONG count)
159 if (count & 2)
160 outsw(port, address, count >> 1);
161 else
162 outsl(port, address, count >> 2);
165 #else
166 extern VOID ata_insw(APTR address, UWORD port, ULONG count);
167 extern VOID ata_insl(APTR address, UWORD port, ULONG count);
168 extern VOID ata_outsw(APTR address, UWORD port, ULONG count);
169 extern VOID ata_outsl(APTR address, UWORD port, ULONG count);
170 #endif
172 static void dump(APTR mem, ULONG len)
174 register int i,j;
175 for (j=0; j<(len+15)>>4; ++j)
177 bug("[ATA ] %06lx: ", j<<4);
179 for (i=0; i<len-(j<<4); i++)
181 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
182 if (i == 15)
183 break;
186 for (i=0; i<len-(j<<4); i++)
188 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
190 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
191 if (i == 15)
192 break;
194 bug("\n");
198 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
200 register int i = size;
202 while (size--)
204 str2[size^1] = str1[size];
207 while (i--)
209 if (str2[i] <= ' ')
210 str2[i] = 0;
216 * a STUB function for commands not supported by this particular device
218 static ULONG ata_STUB(struct ata_Unit *au)
220 bug("[ATA%02ld] CALLED STUB FUNCTION (GENERIC). THIS OPERATION IS NOT "
221 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
222 return CDERR_NOCMD;
225 static ULONG ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len, APTR buf, ULONG* act)
227 bug("[ATA%02ld] CALLED STUB FUNCTION (IO32). THIS OPERATION IS NOT "
228 "SUPPORTED BY DEVICE\n", au->au_UnitNum);
229 return CDERR_NOCMD;
232 static ULONG ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len, APTR buf, ULONG* act)
234 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);
235 return CDERR_NOCMD;
238 static ULONG ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
240 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
241 return CDERR_NOCMD;
244 inline BOOL ata_SelectUnit(struct ata_Unit* unit)
246 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
250 ata_WaitNano(400);
251 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
253 while (0 != (ATAF_BUSY & ata_ReadStatus(unit->au_Bus)));
255 return TRUE;
258 inline struct ata_Unit* ata_GetSelectedUnit(struct ata_Bus* bus)
260 register int id = (ata_in(ata_DevHead, bus->ab_Port) & 0x10) >> 4;
261 return bus->ab_Units[id];
264 UBYTE ata_ReadStatus(struct ata_Bus *bus)
266 return ata_in(ata_Status, bus->ab_Port);
269 UBYTE ata_ReadAltStatus(struct ata_Bus *bus)
271 return ata_in(ata_AltStatus, bus->ab_Alt);
275 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
276 * part of code moved here from ata.c to reduce containment
278 void ata_IRQSignalTask(struct ata_Bus *bus)
280 bus->ab_IntCnt++;
281 Signal(bus->ab_Task, 1UL << bus->ab_SleepySignal);
284 void ata_HandleIRQ(struct ata_Bus *bus)
286 struct ata_Unit *unit = ata_GetSelectedUnit(bus);
287 UBYTE status = ata_ReadStatus(bus);
290 * don't waste your time on checking other devices.
291 * pass irq ONLY if task is expecting one;
293 if ((unit != NULL) && (0 != bus->ab_HandleIRQ)
294 && ((status & ATAF_BUSY) == 0))
297 * ok, we have a routine to handle any form of transmission etc.
299 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
300 bus->ab_HandleIRQ(unit, status);
303 * Acknowledge DMA interrupt bit (some controllers require this for
304 * all interrupt types)
306 if (unit->au_DMAPort != 0)
307 ata_out(ata_in(dma_Status, unit->au_DMAPort) |
308 DMAF_Error | DMAF_Interrupt, dma_Status, unit->au_DMAPort);
310 return;
313 DIRQ_MORE({
315 * if we got *here* then device is most likely not expected to have an irq.
317 bug("[ATA%02ld] IRQ: Checking busy flag: ", unit->au_UnitNum);
319 if (0 == (ATAF_BUSY & status))
321 bug("device ready. Dumping details:\n");
323 bug("[ATA ] STATUS: %02lx\n", status);
324 bug("[ATA ] ALT STATUS: %02lx\n", ata_in(ata_AltStatus, bus->ab_Alt));
325 bug("[ATA ] ERROR: %02lx\n", ata_in(ata_Error, bus->ab_Port));
326 bug("[ATA ] IRQ: REASON: %02lx\n", ata_in(atapi_Reason, bus->ab_Port));
328 else
330 bug("device still busy. ignoring irq.\n");
335 void ata_IRQSetHandler(struct ata_Unit *unit, void (*handler)(struct ata_Unit*, UBYTE), APTR piomem, ULONG blklen, ULONG piolen)
337 if (NULL != handler)
338 unit->au_cmd_error = 0;
340 unit->au_cmd_data = piomem;
341 unit->au_cmd_length = (piolen < blklen) ? piolen : blklen;
342 unit->au_cmd_total = piolen;
343 unit->au_Bus->ab_HandleIRQ = handler;
346 void ata_IRQNoData(struct ata_Unit *unit, UBYTE status)
348 if (status & ATAF_BUSY)
349 return;
351 if ((unit->au_cmd_error == 0) && (status & ATAF_ERROR))
352 unit->au_cmd_error = HFERR_BadStatus;
354 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit->au_UnitNum, status));
355 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
356 ata_IRQSignalTask(unit->au_Bus);
359 void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status)
361 if (status & ATAF_DATAREQ) {
362 DIRQ(bug("[ATA ] IRQ: PIOReadData - DRQ.\n"));
363 unit->au_ins(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
366 * indicate it's all done here
368 unit->au_cmd_data += unit->au_cmd_length;
369 unit->au_cmd_total -= unit->au_cmd_length;
370 if (unit->au_cmd_total) {
371 if (unit->au_cmd_length > unit->au_cmd_total)
372 unit->au_cmd_length = unit->au_cmd_total;
373 return;
375 DIRQ(bug("[ATA ] IRQ: PIOReadData - transfer completed.\n"));
377 ata_IRQNoData(unit, status);
380 void ata_PIOWriteBlk(struct ata_Unit *unit)
382 unit->au_outs(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
385 * indicate it's all done here
387 unit->au_cmd_data += unit->au_cmd_length;
388 unit->au_cmd_total -= unit->au_cmd_length;
389 if (unit->au_cmd_length > unit->au_cmd_total)
390 unit->au_cmd_length = unit->au_cmd_total;
393 void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status)
395 if (status & ATAF_DATAREQ) {
396 DIRQ(bug("[ATA ] IRQ: PIOWriteData - DRQ.\n"));
397 ata_PIOWriteBlk(unit);
398 return;
400 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
401 ata_IRQNoData(unit, status);
404 void ata_IRQDMAReadWrite(struct ata_Unit *au, UBYTE status)
406 UBYTE stat = ata_in(dma_Status, au->au_DMAPort);
407 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat));
409 if (0 == (stat & DMAF_Interrupt))
411 bug("[ATA ] IRQ: Fake IRQ.\n");
413 else if ((status & ATAF_ERROR) || (stat & DMAF_Error))
415 /* This is turned on in order to help Phantom - Pavel Fedin <sonic_amiga@rambler.ru> */
416 bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat);
417 bug("[ATA%02ld] IRQ: ERROR %02lx\n", au->au_UnitNum, ata_in(atapi_Error, au->au_Bus->ab_Port));
418 bug("[ATA ] IRQ: DMA Failed.\n");
419 au->au_cmd_error = HFERR_DMA;
420 ata_IRQNoData(au, status);
422 else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
424 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
425 ata_IRQNoData(au, status);
429 void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status)
431 ULONG port = unit->au_Bus->ab_Port;
432 ULONG size = 0;
433 LONG remainder = 0;
434 UBYTE reason = ata_in(atapi_Reason, port);
435 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason));
437 /* have we failed yet? */
438 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
439 ata_IRQNoData(unit, status);
440 if (status & ATAF_ERROR)
442 ata_IRQNoData(unit, status);
443 return;
446 /* anything for us please? */
447 if (ATAPIF_READ != (reason & ATAPIF_MASK))
448 return;
450 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
451 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
453 if (size > unit->au_cmd_total)
455 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
456 remainder = size - unit->au_cmd_total;
457 size = unit->au_cmd_total;
460 unit->au_ins(unit->au_cmd_data, port, size);
461 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
462 unit->au_cmd_total -= size;
464 DIRQ(bug("[ATAPI] IRQ: %lu bytes read.\n", size));
466 for (; remainder > 0; remainder -= 2)
467 unit->au_ins(&size, port, 2);
469 if (unit->au_cmd_total == 0)
470 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
473 void ata_IRQPIOWriteAtapi(struct ata_Unit *unit, UBYTE status)
475 ULONG port = unit->au_Bus->ab_Port;
476 ULONG size = 0;
477 UBYTE reason = ata_in(atapi_Reason, port);
478 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason));
480 /* have we failed yet? */
481 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
482 ata_IRQNoData(unit, status);
483 if (status & ATAF_ERROR)
485 ata_IRQNoData(unit, status);
486 return;
489 /* anything for us please? */
490 if (ATAPIF_WRITE != (reason & ATAPIF_MASK))
491 return;
493 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
494 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
496 if (size > unit->au_cmd_total)
498 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
499 size = unit->au_cmd_total;
502 unit->au_outs(unit->au_cmd_data, port, size);
503 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
504 unit->au_cmd_total -= size;
506 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size));
508 if (unit->au_cmd_total == 0)
509 ata_IRQSetHandler(unit, &ata_IRQNoData, NULL, 0, 0);
513 * wait for timeout or drive ready
514 * polling-in-a-loop, but it should be safe to remove this already
516 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout)
518 UBYTE status;
519 ULONG sigs = SIGBREAKF_CTRL_C;
520 ULONG step = 0;
521 BOOL res = TRUE;
523 sigs |= (irq ? (1 << unit->au_Bus->ab_SleepySignal) : 0);
526 * clear up all old signals
528 SetSignal(0, sigs);
531 * set up bus timeout
533 Disable();
534 unit->au_Bus->ab_Timeout = tout;
535 Enable();
538 * this loop may experience one of two scenarios
539 * 1) we get a valid irq and the drive wanted to let us know that it's ready
540 * 2) we get an invalid irq due to some collisions. We may still want to go ahead and get some extra irq breaks
541 * this would reduce system load a little
547 * delay the check - this was found needed for some hardware
550 ata_WaitNano(400);
551 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
554 * let's check if the drive is already good
556 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt); //ata_in(ata_Status, unit->au_Bus->ab_Port);
557 if (0 == (status & (ATAF_DATAREQ | ATAF_BUSY)))
558 break;
561 * so we're stuck in a loop?
563 DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", unit->au_UnitNum, status));
566 * if IRQ wait is requested then allow either timeout or irq;
567 * then clear irq flag so we don't keep receiving more of these (especially when system suffers collisions)
569 if (irq)
572 * wait for either IRQ or TIMEOUT
574 step = Wait(sigs);
577 * now if we did reach timeout, then there's no point in going ahead.
579 if (SIGBREAKF_CTRL_C & step)
581 bug("[ATA%02ld] Timeout while waiting for device to complete operation\n", unit->au_UnitNum);
583 res = FALSE;
587 * if we get as far as this, there's no more signals to expect
588 * but we still want the status
590 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
591 break;
593 else
595 ++step;
598 * every 16n rounds do some extra stuff
600 if ((step & 16) == 0)
603 * huhm. so it's been 16n rounds already. any timeout yet?
605 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
607 DIRQ(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit->au_UnitNum));
608 res = FALSE;
609 break;
613 * no timeout just yet, but it's not a good idea to keep spinning like that.
614 * let's give the system some time.
616 ata_WaitNano(400);
617 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
618 // TODO: Put some delay here!
621 } while(status & ATAF_BUSY);
624 * be nice to frustrated developer
626 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit->au_UnitNum, status, res));
629 * clear up all our expectations
631 Disable();
632 unit->au_Bus->ab_Timeout = -1;
633 Enable();
636 * clear any interrupt (may be neccessary if we were polling, for example)
638 ata_in(ata_Status, unit->au_Bus->ab_Port);
641 * release old junk
643 SetSignal(0, sigs);
646 * and say it went fine (i mean it)
648 if (stout)
649 *stout = status;
650 return res;
654 * Procedure for sending ATA command blocks
655 * it appears LARGE but there's a lot of COMMENTS here :)
656 * handles *all* ata commands (no data, pio and dma)
657 * naturally could be split at some point in the future
658 * depends if anyone believes that the change for 50 lines
659 * would make slow ATA transfers any faster
661 static ULONG ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
663 ULONG port = au->au_Bus->ab_Port;
664 ULONG err = 0;
665 APTR mem = block->buffer;
666 UBYTE status;
668 if (FALSE == ata_SelectUnit(au))
669 return IOERR_UNITBUSY;
671 switch (block->type)
673 case CT_LBA28:
674 if (block->sectors > 256)
676 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
677 return IOERR_BADLENGTH;
680 /* note:
681 * we want the above to fall in here!
682 * we really do (checking for secmul)
685 case CT_LBA48:
686 if (block->sectors > 65536)
688 bug("[ATA%02ld] ata_exec_cmd: ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
689 return IOERR_BADLENGTH;
691 if (block->secmul == 0)
693 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
694 block->secmul = 1;
696 break;
698 case CT_NoBlock:
699 break;
701 default:
702 bug("[ATA%02ld] ata_exec_cmd: ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
703 return IOERR_NOCMD;
706 block->actual = 0;
707 D(bug("[ATA%02ld] ata_exec_cmd: Executing command %02lx\n", au->au_UnitNum, block->command));
709 if (block->feature != 0)
710 ata_out(block->feature, ata_Feature, port);
713 * - set LBA and sector count
715 switch (block->type)
717 case CT_LBA28:
718 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
719 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
720 ata_out(block->blk >> 16, ata_LBAHigh, port);
721 ata_out(block->blk >> 8, ata_LBAMid, port);
722 ata_out(block->blk, ata_LBALow, port);
723 ata_out(block->sectors, ata_Count, port);
724 break;
726 case CT_LBA48:
727 DATA(bug("[ATA%02ld] ata_exec_cmd: Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
728 ata_out(block->blk >> 40, ata_LBAHigh, port);
729 ata_out(block->blk >> 32, ata_LBAMid, port);
730 ata_out(block->blk >> 24, ata_LBALow, port);
732 ata_out(block->blk >> 16, ata_LBAHigh, port);
733 ata_out(block->blk >> 8, ata_LBAMid, port);
734 ata_out(block->blk, ata_LBALow, port);
736 ata_out(block->sectors >> 8, ata_Count, port);
737 ata_out(block->sectors, ata_Count, port);
738 break;
740 case CT_NoBlock:
741 DATA(bug("[ATA%02ld] ata_exec_cmd: Command does not address any block\n", au->au_UnitNum));
742 break;
745 switch (block->method)
747 case CM_PIOWrite:
748 ata_IRQSetHandler(au, &ata_IRQPIOWrite, mem, block->secmul << au->au_SectorShift, block->length);
749 break;
751 case CM_PIORead:
752 ata_IRQSetHandler(au, &ata_IRQPIORead, mem, block->secmul << au->au_SectorShift, block->length);
753 break;
755 case CM_DMARead:
756 if (FALSE == dma_SetupPRDSize(au, mem, block->length, TRUE))
757 return IOERR_ABORTED;
758 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
759 dma_StartDMA(au);
760 break;
762 case CM_DMAWrite:
763 if (FALSE == dma_SetupPRDSize(au, mem, block->length, FALSE))
764 return IOERR_ABORTED;
765 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
766 dma_StartDMA(au);
767 break;
769 case CM_NoData:
770 ata_IRQSetHandler(au, &ata_IRQNoData, NULL, 0, 0);
771 break;
773 default:
774 return IOERR_NOCMD;
775 break;
779 * send command now
780 * let drive propagate its signals
782 DATA(bug("[ATA%02ld] ata_exec_cmd: Sending command\n", au->au_UnitNum));
783 ata_out(block->command, ata_Command, port);
784 ata_WaitNano(400);
785 //ata_WaitTO(au->au_Bus->ab_Timer, 0, 1, 0);
788 * In case of PIO write the drive won't issue an IRQ before first
789 * data transfer, so we should poll the status and send the first
790 * block upon request.
792 if (block->method == CM_PIOWrite) {
793 if (FALSE == ata_WaitBusyTO(au, 30, FALSE, &status)) {
794 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - no response from device\n", au->au_UnitNum));
795 return IOERR_UNITBUSY;
797 if (status & ATAF_DATAREQ) {
798 DATA(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - DRQ.\n", au->au_UnitNum));
799 ata_PIOWriteBlk(au);
801 else
803 D(bug("[ATA%02ld] ata_exec_cmd: PIOWrite - bad status: %02X\n", status));
804 return HFERR_BadStatus;
809 * wait for drive to complete what it has to do
811 if (FALSE == ata_WaitBusyTO(au, 30, TRUE, NULL))
813 bug("[ATA%02ld] ata_exec_cmd: Device is late - no response\n", au->au_UnitNum);
814 err = IOERR_UNITBUSY;
816 else
817 err = au->au_cmd_error;
819 DATA(bug("[ATA%02ld] ata_exec_cmd: Command done\n", au->au_UnitNum));
821 * clean up DMA
822 * don't use 'mem' pointer here as it's already invalid.
824 if (block->method == CM_DMARead)
826 dma_StopDMA(au);
827 dma_Cleanup(block->buffer, block->length, TRUE);
829 else if (block->method == CM_DMAWrite)
831 dma_StopDMA(au);
832 dma_Cleanup(block->buffer, block->length, FALSE);
835 D(bug("[ATA%02ld] ata_exec_cmd: return code %ld\n", au->au_UnitNum, err));
836 return err;
840 * atapi packet iface
842 int atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, LONG datalen, BOOL *dma, BOOL write)
844 *dma = *dma && (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
845 LONG err = 0;
847 UBYTE cmd[12] = {
850 register int t=5,l=0;
851 ULONG port = unit->au_Bus->ab_Port;
853 if (((UBYTE*)packet)[0] > 0x1f)
854 t+= 4;
855 if (((UBYTE*)packet)[0] > 0x5f)
856 t+= 2;
858 switch (((UBYTE*)packet)[0])
860 case 0x28: // read10
861 case 0xa8: // read12
862 case 0xbe: // readcd
863 case 0xb9: // readcdmsf
864 case 0x2f: // verify
865 case 0x2a: // write
866 case 0xaa: // write12
867 case 0x2e: // writeverify
868 case 0xad: // readdvdstructure
869 case 0xa4: // reportkey
870 case 0xa3: // sendkey
871 break;
872 default:
873 *dma = FALSE;
876 while (l<=t)
878 cmd[l] = ((UBYTE*)packet)[l];
879 ++l;
882 DATAPI({
883 bug("[ATA%02lx] Sending %s ATA packet: ", unit->au_UnitNum, (*dma) ? "DMA" : "PIO");
884 l=0;
885 while (l<=t)
887 bug("%02lx ", ((UBYTE*)cmd)[l]);
888 ++l;
890 bug("\n");
892 if (datalen & 1)
893 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
896 datalen = (datalen+1)&~1;
898 if (FALSE == ata_SelectUnit(unit))
900 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
901 return IOERR_UNITBUSY;
905 * tell device whether we want to read or write and if we want a dma transfer
907 ata_out(((*dma) ? 1 : 0) |
908 (((unit->au_Drive->id_DMADir & 0x8000) && !write) ? 4 : 0),
909 atapi_Features, port);
910 ata_out((datalen & 0xff), atapi_ByteCntL, port);
911 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
914 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
915 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
917 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
918 ata_out(ATA_PACKET, atapi_Command, port);
919 ata_WaitNano(400);
920 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
922 ata_WaitBusyTO(unit, 30, (unit->au_Drive->id_General & 0x60) == 0x20, NULL);
923 if (0 == (ata_ReadStatus(unit->au_Bus) & ATAF_DATAREQ))
924 return HFERR_BadStatus;
927 * setup appropriate hooks
929 if (datalen == 0)
930 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
931 else if (*dma)
932 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
933 else if (write)
934 ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, 0, datalen);
935 else
936 ata_IRQSetHandler(unit, &ata_IRQPIOReadAtapi, data, 0, datalen);
938 if (*dma)
940 DATAPI(bug("[ATAPI] Starting DMA\n"));
941 dma_StartDMA(unit);
944 DATAPI(bug("[ATAPI] Sending packet\n"));
945 unit->au_outs(cmd, unit->au_Bus->ab_Port, 12);
946 ata_WaitNano(400);
947 DATAPI(bug("[ATAPI] Status after packet: %lx\n",
948 ata_ReadAltStatus(unit->au_Bus)));
951 * Wait for command to complete. Note that two interrupts will occur
952 * before we wake up if this is a PIO data transfer
954 if (ata_WaitTO(unit->au_Bus->ab_Timer, 30, 0,
955 1 << unit->au_Bus->ab_SleepySignal) == 0)
957 DATAPI(bug("[DSCSI] Command timed out.\n"));
958 err = IOERR_UNITBUSY;
960 else
961 err = atapi_EndCmd(unit);
963 if (*dma)
965 dma_StopDMA(unit);
966 dma_Cleanup(data, datalen, !write);
969 DATAPI(bug("[ATAPI] IO error code %ld\n", err));
970 return err;
973 ULONG atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
975 APTR buffer = cmd->scsi_Data;
976 ULONG length = cmd->scsi_Length;
977 BOOL read = FALSE;
978 UBYTE err = 0;
979 BOOL dma = FALSE;
981 cmd->scsi_Actual = 0;
983 DATAPI(bug("[DSCSI] Sending packet!\n"));
986 * setup DMA & push command
987 * it does not really mean we will use dma here btw
989 if ((unit->au_XferModes & AF_XFER_DMA) && (length !=0) && (buffer != 0))
991 dma = TRUE;
992 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
994 read = TRUE;
995 if (FALSE == dma_SetupPRDSize(unit, buffer, length, TRUE))
996 dma = FALSE;
998 else
1000 if (FALSE == dma_SetupPRDSize(unit, buffer, length, FALSE))
1001 dma = FALSE;
1005 err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0);
1007 DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); });
1010 * on check condition - grab sense data
1012 DATAPI(bug("[ATA%02lx] atapi_DirectSCSI: SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err));
1013 if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
1015 DATAPI(bug("[DSCSI] atapi_DirectSCSI: Packet Failed. Calling atapi_RequestSense\n"));
1016 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
1017 DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
1020 return err;
1024 * chops the large transfers into set of smaller transfers
1025 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1027 static ULONG ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
1029 ULONG err=0;
1030 ULONG part;
1031 ULONG max=256;
1032 ULONG count=blk->sectors;
1034 if (blk->type == CT_LBA48)
1035 max <<= 8;
1037 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));
1038 while ((count > 0) && (err == 0))
1040 part = (count > max) ? max : count;
1041 blk->sectors = part;
1042 blk->length = part << unit->au_SectorShift;
1044 DATA(bug("[ATA%02ld] Transfer of %ld sectors from %x%08x\n", unit->au_UnitNum, part, (ULONG)(blk->blk >> 32), (ULONG)blk->blk));
1045 err = ata_exec_cmd(unit, blk);
1046 DATA(bug("[ATA%02ld] ata_exec_blk: ata_exec_cmd returned %lx\n", unit->au_UnitNum, err));
1048 blk->blk += part;
1049 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1050 count -= part;
1052 return err;
1056 * Initial device configuration that suits *all* cases
1058 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1060 struct ata_Unit *unit=NULL;
1062 DINIT(bug("[ATA ] ata_init_unit(%ld)\n", u));
1064 unit = bus->ab_Units[u];
1065 if (NULL == unit)
1066 return FALSE;
1068 unit->au_Bus = bus;
1069 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1070 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1071 unit->au_DevMask = 0xa0 | (u << 4);
1072 if (bus->ab_Base->ata_32bit)
1074 unit->au_ins = ata_insl;
1075 unit->au_outs = ata_outsl;
1077 else
1079 unit->au_ins = ata_insw;
1080 unit->au_outs = ata_outsw;
1082 unit->au_SectorShift= 9; /* this really has to be set here. */
1084 NEWLIST(&unit->au_SoftList);
1087 * since the stack is always handled by caller
1088 * it's safe to stub all calls with one function
1090 unit->au_Read32 = ata_STUB_IO32;
1091 unit->au_Read64 = ata_STUB_IO64;
1092 unit->au_Write32 = ata_STUB_IO32;
1093 unit->au_Write64 = ata_STUB_IO64;
1094 unit->au_Eject = ata_STUB;
1095 unit->au_DirectSCSI = ata_STUB_SCSI;
1096 unit->au_Identify = ata_STUB;
1097 return TRUE;
1100 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1102 struct ata_Unit *unit=NULL;
1105 * this stuff always goes along the same way
1106 * WARNING: NO INTERRUPTS AT THIS POINT!
1108 DINIT(bug("[ATA ] ata_setup_unit(%ld,%ld)\n", bus->ab_BusNum, u));
1110 unit = bus->ab_Units[u];
1111 if (NULL == unit)
1112 return FALSE;
1114 ata_SelectUnit(unit);
1116 if (unit->au_DMAPort != 0
1117 && (ata_in(dma_Status, unit->au_DMAPort) & 0x80) != 0)
1118 bug("[ATA%02ld] ata_setup_unit: WARNING: Controller only supports "
1119 "DMA on one bus at a time. DMAStatus=%lx\n", unit->au_UnitNum,
1120 ata_in(dma_Status, unit->au_DMAPort));
1122 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE, NULL))
1124 DINIT(bug("[ATA%02ld] ata_setup_unit: ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1125 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1126 unit->au_Drive = 0;
1127 return FALSE;
1130 switch (bus->ab_Dev[u])
1133 * safe fallback settings
1135 case DEV_SATAPI:
1136 case DEV_ATAPI:
1137 unit->au_Identify = atapi_Identify;
1138 break;
1140 case DEV_SATA:
1141 case DEV_ATA:
1142 unit->au_Identify = ata_Identify;
1143 break;
1145 default:
1146 DINIT(bug("[ATA%02ld] ata_setup_unit: Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1147 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1148 unit->au_Drive = 0;
1149 return FALSE;
1152 D(bug("[ATA ] ata_setup_unit: Enabling IRQs\n"));
1153 ata_out(0x0, ata_AltControl, bus->ab_Alt);
1156 * now make unit self diagnose
1158 if (unit->au_Identify(unit) != 0)
1160 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1161 unit->au_Drive = 0;
1162 return FALSE;
1165 return TRUE;
1169 * ata[pi] identify
1171 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1173 UBYTE type=0;
1174 BOOL dma=FALSE;
1175 ata_CommandBlock acb =
1177 ATA_SET_FEATURES,
1178 0x03,
1179 0x01,
1180 0x00,
1181 0x00,
1182 0x00,
1183 0x00,
1184 0x00,
1185 0x00,
1186 CM_NoData,
1187 CT_LBA28
1189 DINIT(bug("[ATA%02ld] common_SetXferMode: Trying to set mode %d\n", unit->au_UnitNum, mode));
1191 if ((unit->au_DMAPort == 0) && (mode >= AB_XFER_MDMA0))
1193 DINIT(bug("[ATA%02ld] common_SetXferMode: This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1194 common_SetBestXferMode(unit);
1195 return;
1199 * first, ONLY for ATA devices, set new commands
1201 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1203 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1205 if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI))
1207 ata_IRQSetHandler(unit, ata_IRQNoData, NULL, 0, 0);
1208 ata_out(unit->au_Drive->id_RWMultipleSize & 0xFF, ata_Count, unit->au_Bus->ab_Port);
1209 ata_out(ATA_SET_MULTIPLE, ata_Command, unit->au_Bus->ab_Port);
1210 ata_WaitBusyTO(unit, -1, TRUE, NULL);
1212 unit->au_Read32 = ata_ReadMultiple32;
1213 unit->au_Write32 = ata_WriteMultiple32;
1214 if (unit->au_XferModes & AF_XFER_48BIT)
1216 unit->au_Read64 = ata_ReadMultiple64;
1217 unit->au_Write64 = ata_WriteMultiple64;
1220 else
1222 unit->au_Read32 = ata_ReadSector32;
1223 unit->au_Write32 = ata_WriteSector32;
1224 if (unit->au_XferModes & AF_XFER_48BIT)
1226 unit->au_Read64 = ata_ReadSector64;
1227 unit->au_Write64 = ata_WriteSector64;
1231 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1233 unit->au_Read32 = ata_ReadDMA32;
1234 unit->au_Write32 = ata_WriteDMA32;
1235 if (unit->au_XferModes & AF_XFER_48BIT)
1237 unit->au_Read64 = ata_ReadDMA64;
1238 unit->au_Write64 = ata_WriteDMA64;
1241 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1243 unit->au_Read32 = ata_ReadDMA32;
1244 unit->au_Write32 = ata_WriteDMA32;
1245 if (unit->au_XferModes & AF_XFER_48BIT)
1247 unit->au_Read64 = ata_ReadDMA64;
1248 unit->au_Write64 = ata_WriteDMA64;
1251 else
1253 unit->au_Read32 = ata_ReadSector32;
1254 unit->au_Write32 = ata_WriteSector32;
1255 if (unit->au_XferModes & AF_XFER_48BIT)
1257 unit->au_Read64 = ata_ReadSector64;
1258 unit->au_Write64 = ata_WriteSector64;
1263 if ((mode >= AB_XFER_PIO0) && (mode <= AB_XFER_PIO4))
1265 type = 8 + (mode - AB_XFER_PIO0);
1267 else if ((mode >= AB_XFER_MDMA0) && (mode <= AB_XFER_MDMA2))
1269 type = 32 + (mode - AB_XFER_MDMA0);
1270 dma=TRUE;
1272 else if ((mode >= AB_XFER_UDMA0) && (mode <= AB_XFER_UDMA6))
1274 type = 64 + (mode - AB_XFER_UDMA0);
1275 dma=TRUE;
1277 else
1279 type = 0;
1282 #if 0 // We can't set drive modes unless we also set the controller's timing registers
1283 acb.sectors = type;
1284 if (0 != ata_exec_cmd(unit, &acb))
1286 DINIT(bug("[ATA%02ld] common_SetXferMode: ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1288 #endif
1290 if (unit->au_DMAPort)
1292 type = ata_in(dma_Status, unit->au_DMAPort);
1293 type &= 0x60;
1294 if (dma)
1296 type |= 1 << (5 + (unit->au_UnitNum & 1));
1298 else
1300 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1303 DINIT(bug("[DSCSI] common_SetXferMode: Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1305 ata_SelectUnit(unit);
1306 ata_out(type, dma_Status, unit->au_DMAPort);
1307 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1309 DINIT(bug("[DSCSI] common_SetXferMode: New DMA Status: %02lx\n", type));
1311 else
1313 DINIT(bug("[DSCSI] common_SetXferMode: Failed to modify DMA state for this device\n"));
1314 dma = FALSE;
1318 if (dma)
1319 unit->au_XferModes |= AF_XFER_DMA;
1320 else
1321 unit->au_XferModes &= ~AF_XFER_DMA;
1324 static void common_SetBestXferMode(struct ata_Unit* unit)
1326 int iter;
1327 int max = AB_XFER_UDMA6;
1329 if (unit->au_DMAPort == 0
1330 || !(unit->au_Drive->id_MWDMASupport & 0x0700)
1331 && !(unit->au_Drive->id_UDMASupport & 0x7f00))
1334 * make sure you reduce scan search to pio here!
1335 * otherwise this and above function will fall into infinite loop
1337 DINIT(bug("[ATA%02ld] common_SetBestXferMode: This controller does not own DMA port\n", unit->au_UnitNum));
1338 max = AB_XFER_PIO4;
1340 else if (!(unit->au_Flags & AF_80Wire))
1342 DINIT(bug("[ATA%02ld] common_SetBestXferMode: "
1343 "An 80-wire cable has not been detected for this drive. "
1344 "Disabling modes above UDMA2.\n", unit->au_UnitNum));
1345 max = AB_XFER_UDMA2;
1348 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1350 if (unit->au_XferModes & (1<<iter))
1352 common_SetXferMode(unit, iter);
1353 return;
1356 bug("[ATA%02ld] common_SetBestXferMode: ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1357 common_SetXferMode(unit, AB_XFER_PIO0);
1360 void common_DetectXferModes(struct ata_Unit* unit)
1362 int iter;
1364 DINIT(bug("[ATA%02ld] common_DetectXferModes: Supports\n", unit->au_UnitNum));
1366 if (unit->au_Drive->id_Commands4 & (1 << 4))
1368 DINIT(bug("[ATA%02ld] common_DetectXferModes: - Packet interface\n", unit->au_UnitNum));
1369 unit->au_XferModes |= AF_XFER_PACKET;
1370 unit->au_DirectSCSI = atapi_DirectSCSI;
1372 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1374 /* ATAPI devices do not use this bit. */
1375 DINIT(bug("[ATA%02ld] common_DetectXferModes: - 48bit I/O\n", unit->au_UnitNum));
1376 unit->au_XferModes |= AF_XFER_48BIT;
1379 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1381 DINIT(bug("[ATA%02ld] common_DetectXferModes: - LBA Addressing\n", unit->au_UnitNum));
1382 unit->au_XferModes |= AF_XFER_LBA;
1384 else
1386 DINIT(bug("[ATA%02ld] common_DetectXferModes: - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1389 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1391 DINIT(bug("[ATA%02ld] common_DetectXferModes: - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1392 unit->au_XferModes |= AF_XFER_RWMULTI;
1395 DINIT(bug("[ATA%02ld] common_DetectXferModes: - PIO0 PIO1 PIO2 ",
1396 unit->au_UnitNum));
1397 unit->au_XferModes |= AF_XFER_PIO(0) | AF_XFER_PIO(1) | AF_XFER_PIO(2);
1398 if (unit->au_Drive->id_ConfigAvailable & (1 << 1))
1400 for (iter = 0; iter < 2; iter++)
1402 if (unit->au_Drive->id_PIOSupport & (1 << iter))
1404 DINIT(bug("PIO%ld ", 3 + iter));
1405 unit->au_XferModes |= AF_XFER_PIO(3 + iter);
1408 DINIT(bug("\n"));
1411 if ((unit->au_Drive->id_ConfigAvailable & (1 << 1)) &&
1412 (unit->au_Drive->id_Capabilities & (1<<8)))
1414 DINIT(bug("[ATA%02ld] common_DetectXferModes: DMA:\n", unit->au_UnitNum));
1415 if (unit->au_Drive->id_MWDMASupport & 0xff)
1417 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1418 for (iter = 0; iter < 3; iter++)
1420 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1422 unit->au_XferModes |= AF_XFER_MDMA(iter);
1423 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1425 DINIT(bug("[MDMA%ld] ", iter));
1427 else
1429 DINIT(bug("MDMA%ld ", iter));
1433 DINIT(bug("\n"));
1436 if (unit->au_Drive->id_UDMASupport & 0xff)
1438 DINIT(bug("[ATA%02ld] common_DetectXferModes: - ", unit->au_UnitNum));
1439 for (iter = 0; iter < 7; iter++)
1441 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1443 unit->au_XferModes |= AF_XFER_UDMA(iter);
1444 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1446 DINIT(bug("[UDMA%ld] ", iter));
1448 else
1450 DINIT(bug("UDMA%ld ", iter));
1454 DINIT(bug("\n"));
1459 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1460 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1461 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1463 ULONG atapi_Identify(struct ata_Unit* unit)
1465 ata_CommandBlock acb =
1467 ATA_IDENTIFY_ATAPI,
1473 unit->au_Drive,
1474 sizeof(struct DriveIdent),
1476 CM_PIORead,
1477 CT_NoBlock
1480 ata_SelectUnit(unit);
1482 if (ata_exec_cmd(unit, &acb))
1484 return IOERR_OPENFAIL;
1487 #if (AROS_BIG_ENDIAN != 0)
1488 SWAP_LE_WORD(unit->au_Drive->id_General);
1489 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1490 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1491 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1492 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1493 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1494 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1495 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1496 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1497 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1498 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1499 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1500 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1501 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1502 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1503 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1504 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1505 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1506 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1507 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1508 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1509 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1510 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1511 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1512 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1513 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1514 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1515 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1516 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1517 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1518 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1519 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1520 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1521 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1522 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1523 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1524 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1525 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1526 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1527 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1528 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1529 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1530 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1532 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1533 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1534 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1536 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1537 #endif
1540 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1542 unit->au_SectorShift = 11;
1543 unit->au_Read32 = atapi_Read;
1544 unit->au_Write32 = atapi_Write;
1545 unit->au_DirectSCSI = atapi_DirectSCSI;
1546 unit->au_Eject = atapi_Eject;
1547 unit->au_Flags |= AF_DiscChanged;
1548 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1549 unit->au_XferModes = AF_XFER_PACKET;
1551 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1552 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1553 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1555 bug("[ATA%02ld] atapi_Identify: Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1556 common_DetectXferModes(unit);
1557 common_SetBestXferMode(unit);
1559 if (unit->au_Drive->id_General & 0x80)
1561 DINIT(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1562 unit->au_Flags |= AF_Removable;
1565 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1566 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1567 bug("[ATA%02ld] atapi_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));
1570 * ok, this is not very original, but quite compatible :P
1572 switch (unit->au_DevType)
1574 case DG_CDROM:
1575 case DG_WORM:
1576 case DG_OPTICAL_DISK:
1577 unit->au_SectorShift = 11;
1578 unit->au_Heads = 1;
1579 unit->au_Sectors = 75;
1580 unit->au_Cylinders = 4440;
1581 break;
1583 case DG_DIRECT_ACCESS:
1584 unit->au_SectorShift = 9;
1585 if (!strcmp("LS-120", &unit->au_Model[0]))
1587 unit->au_Heads = 2;
1588 unit->au_Sectors = 18;
1589 unit->au_Cylinders = 6848;
1591 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1593 unit->au_Heads = 1;
1594 unit->au_Sectors = 64;
1595 unit->au_Cylinders = 3072;
1597 break;
1600 atapi_TestUnitOK(unit);
1602 return 0;
1605 ULONG ata_Identify(struct ata_Unit* unit)
1607 ata_CommandBlock acb =
1609 ATA_IDENTIFY_DEVICE,
1615 unit->au_Drive,
1616 sizeof(struct DriveIdent),
1618 CM_PIORead,
1619 CT_NoBlock
1622 if (ata_exec_cmd(unit, &acb))
1624 return IOERR_OPENFAIL;
1627 #if (AROS_BIG_ENDIAN != 0)
1628 SWAP_LE_WORD(unit->au_Drive->id_General);
1629 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1630 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1631 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1632 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1633 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1634 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1635 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1636 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1637 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1638 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1639 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1640 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1641 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1642 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1643 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1644 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1645 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1646 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1647 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1648 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1649 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1650 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1651 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1652 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1653 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1654 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1655 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1656 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1657 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1658 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1659 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1660 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1661 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1662 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1663 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1664 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1665 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1666 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1667 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1668 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1669 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1670 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1672 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1673 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1674 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1676 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1677 #endif
1679 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1681 unit->au_SectorShift = 9;
1682 unit->au_DevType = DG_DIRECT_ACCESS;
1683 unit->au_Read32 = ata_ReadSector32;
1684 unit->au_Write32 = ata_WriteSector32;
1685 unit->au_DirectSCSI = atapi_DirectSCSI;
1686 unit->au_Eject = ata_Eject;
1687 unit->au_XferModes = 0;
1688 unit->au_Flags |= AF_DiscPresent | AF_DiscChanged;
1689 unit->au_DevType = DG_DIRECT_ACCESS;
1691 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1692 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1693 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1695 bug("[ATA%02ld] ata_Identify: Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1696 common_DetectXferModes(unit);
1697 common_SetBestXferMode(unit);
1699 if (unit->au_Drive->id_General & 0x80)
1701 DINIT(bug("[ATA%02ld] ata_Identify: Device is removable.\n", unit->au_UnitNum));
1702 unit->au_Flags |= AF_Removable;
1705 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1706 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1707 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));
1710 For drive capacities > 8.3GB assume maximal possible layout.
1711 It really doesn't matter here, as BIOS will not handle them in
1712 CHS way anyway :)
1713 i guess this just solves that weirdo div-by-zero crash, if nothing else...
1715 if ((unit->au_Drive->id_LBA48Sectors > (63 * 255 * 1024)) ||
1716 (unit->au_Drive->id_LBASectors > (63 * 255 * 1024)))
1718 ULONG div = 1;
1720 * TODO: this shouldn't be casted down here.
1722 ULONG sec = unit->au_Capacity48;
1724 if (sec < unit->au_Capacity48)
1725 sec = ~0ul;
1727 if (sec < unit->au_Capacity)
1728 sec = unit->au_Capacity;
1730 unit->au_Sectors = 63;
1731 sec /= 63;
1733 * keep dividing by 2
1737 if (((sec >> 1) << 1) != sec)
1738 break;
1739 if ((div << 1) > 255)
1740 break;
1741 div <<= 1;
1742 sec >>= 1;
1743 } while (1);
1747 if (((sec / 3) * 3) != sec)
1748 break;
1749 if ((div * 3) > 255)
1750 break;
1751 div *= 3;
1752 sec /= 3;
1753 } while (1);
1755 unit->au_Cylinders = sec;
1756 unit->au_Heads = div;
1758 else
1760 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1761 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1762 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1764 return 0;
1769 * ata read32 commands
1771 static ULONG ata_ReadSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1773 ata_CommandBlock acb =
1775 ATA_READ,
1779 block,
1780 count,
1781 buffer,
1782 count << unit->au_SectorShift,
1784 CM_PIORead,
1785 CT_LBA28
1787 register ULONG err;
1789 D(bug("[ATA%02ld] ata_ReadSector32()\n", unit->au_UnitNum));
1791 *act = 0;
1792 if (0 != (err = ata_exec_blk(unit, &acb)))
1793 return err;
1795 *act = count << unit->au_SectorShift;
1796 return 0;
1799 static ULONG ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1801 ata_CommandBlock acb =
1803 ATA_READ_MULTIPLE,
1805 unit->au_Drive->id_RWMultipleSize & 0xff,
1807 block,
1808 count,
1809 buffer,
1810 count << unit->au_SectorShift,
1812 CM_PIORead,
1813 CT_LBA28
1815 register ULONG err;
1817 D(bug("[ATA%02ld] ata_ReadMultiple32()\n", unit->au_UnitNum));
1819 *act = 0;
1820 if (0 != (err = ata_exec_blk(unit, &acb)))
1821 return err;
1823 *act = count << unit->au_SectorShift;
1824 return 0;
1827 static ULONG ata_ReadDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1829 register ULONG err;
1830 ata_CommandBlock acb =
1832 ATA_READ_DMA,
1836 block,
1837 count,
1838 buffer,
1839 count << unit->au_SectorShift,
1841 CM_DMARead,
1842 CT_LBA28
1845 D(bug("[ATA%02ld] ata_ReadDMA32()\n", unit->au_UnitNum));
1847 *act = 0;
1848 if (0 != (err = ata_exec_blk(unit, &acb)))
1849 return err;
1851 *act = count << unit->au_SectorShift;
1852 return 0;
1857 * ata read64 commands
1859 static ULONG ata_ReadSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1861 ata_CommandBlock acb =
1863 ATA_READ64,
1867 block,
1868 count,
1869 buffer,
1870 count << unit->au_SectorShift,
1872 CM_PIORead,
1873 CT_LBA48
1875 register ULONG err = 0;
1877 D(bug("[ATA%02ld] ata_ReadSector64()\n", unit->au_UnitNum));
1879 *act = 0;
1880 if (0 != (err = ata_exec_blk(unit, &acb)))
1881 return err;
1883 *act = count << unit->au_SectorShift;
1884 return 0;
1887 static ULONG ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1889 ata_CommandBlock acb =
1891 ATA_READ_MULTIPLE64,
1893 unit->au_Drive->id_RWMultipleSize & 0xff,
1895 block,
1896 count,
1897 buffer,
1898 count << unit->au_SectorShift,
1900 CM_PIORead,
1901 CT_LBA48
1903 register ULONG err;
1905 D(bug("[ATA%02ld] ata_ReadMultiple64()\n", unit->au_UnitNum));
1907 *act = 0;
1908 if (0 != (err = ata_exec_blk(unit, &acb)))
1909 return err;
1911 *act = count << unit->au_SectorShift;
1912 return 0;
1915 static ULONG ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1917 ata_CommandBlock acb =
1919 ATA_READ_DMA64,
1923 block,
1924 count,
1925 buffer,
1926 count << unit->au_SectorShift,
1928 CM_DMARead,
1929 CT_LBA48
1931 register ULONG err;
1933 D(bug("[ATA%02ld] ata_ReadDMA64()\n", unit->au_UnitNum));
1935 *act = 0;
1936 if (0 != (err = ata_exec_blk(unit, &acb)))
1937 return err;
1939 *act = count << unit->au_SectorShift;
1940 return 0;
1945 * ata write32 commands
1947 static ULONG ata_WriteSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1949 ata_CommandBlock acb =
1951 ATA_WRITE,
1955 block,
1956 count,
1957 buffer,
1958 count << unit->au_SectorShift,
1960 CM_PIOWrite,
1961 CT_LBA28
1963 register ULONG err;
1965 D(bug("[ATA%02ld] ata_WriteSector32()\n", unit->au_UnitNum));
1967 *act = 0;
1968 if (0 != (err = ata_exec_blk(unit, &acb)))
1969 return err;
1971 *act = count << unit->au_SectorShift;
1972 return 0;
1975 static ULONG ata_WriteMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1977 ata_CommandBlock acb =
1979 ATA_WRITE_MULTIPLE,
1981 unit->au_Drive->id_RWMultipleSize & 0xff,
1983 block,
1984 count,
1985 buffer,
1986 count << unit->au_SectorShift,
1988 CM_PIOWrite,
1989 CT_LBA28
1991 register ULONG err;
1993 D(bug("[ATA%02ld] ata_WriteMultiple32()\n", unit->au_UnitNum));
1995 *act = 0;
1996 if (0 != (err = ata_exec_blk(unit, &acb)))
1997 return err;
1999 *act = count << unit->au_SectorShift;
2000 return 0;
2003 static ULONG ata_WriteDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2005 ata_CommandBlock acb =
2007 ATA_WRITE_DMA,
2011 block,
2012 count,
2013 buffer,
2014 count << unit->au_SectorShift,
2016 CM_DMAWrite,
2017 CT_LBA28
2019 register ULONG err;
2021 D(bug("[ATA%02ld] ata_WriteDMA32()\n", unit->au_UnitNum));
2023 *act = 0;
2024 if (0 != (err = ata_exec_blk(unit, &acb)))
2025 return err;
2027 *act = count << unit->au_SectorShift;
2028 return 0;
2033 * ata write64 commands
2035 static ULONG ata_WriteSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2037 ata_CommandBlock acb =
2039 ATA_WRITE64,
2043 block,
2044 count,
2045 buffer,
2046 count << unit->au_SectorShift,
2048 CM_PIOWrite,
2049 CT_LBA48
2051 register ULONG err;
2053 D(bug("[ATA%02ld] ata_WriteSector64()\n", unit->au_UnitNum));
2055 *act = 0;
2056 if (0 != (err = ata_exec_blk(unit, &acb)))
2057 return err;
2059 *act = count << unit->au_SectorShift;
2060 return 0;
2063 static ULONG ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2065 ata_CommandBlock acb =
2067 ATA_WRITE_MULTIPLE64,
2069 unit->au_Drive->id_RWMultipleSize & 0xff,
2071 block,
2072 count,
2073 buffer,
2074 count << unit->au_SectorShift,
2076 CM_PIOWrite,
2077 CT_LBA48
2079 register ULONG err;
2081 D(bug("[ATA%02ld] ata_WriteMultiple64()\n", unit->au_UnitNum));
2083 *act = 0;
2084 if (0 != (err = ata_exec_blk(unit, &acb)))
2085 return err;
2087 *act = count << unit->au_SectorShift;
2088 return 0;
2091 static ULONG ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2093 ata_CommandBlock acb =
2095 ATA_WRITE_DMA64,
2099 block,
2100 count,
2101 buffer,
2102 count << unit->au_SectorShift,
2104 CM_DMAWrite,
2105 CT_LBA48
2107 register ULONG err;
2109 D(bug("[ATA%02ld] ata_WriteDMA64()\n", unit->au_UnitNum));
2111 *act = 0;
2112 if (0 != (err = ata_exec_blk(unit, &acb)))
2113 return err;
2115 *act = count << unit->au_SectorShift;
2116 return 0;
2120 * ata miscellaneous commands
2122 static ULONG ata_Eject(struct ata_Unit *unit)
2124 ata_CommandBlock acb =
2126 ATA_MEDIA_EJECT,
2135 CM_NoData,
2136 CT_NoBlock
2139 D(bug("[ATA%02ld] ata_Eject()\n", unit->au_UnitNum));
2141 return ata_exec_cmd(unit, &acb);
2145 * atapi commands
2147 int atapi_TestUnitOK(struct ata_Unit *unit)
2149 UBYTE cmd[6] = {
2152 UBYTE sense[16] = {
2155 struct SCSICmd sc = {
2159 D(bug("[ATA%02ld] atapi_TestUnitOK()\n", unit->au_UnitNum));
2161 sc.scsi_Command = (void*) &cmd;
2162 sc.scsi_CmdLength = sizeof(cmd);
2163 sc.scsi_SenseData = (void*)&sense;
2164 sc.scsi_SenseLength = sizeof(sense);
2165 sc.scsi_Flags = SCSIF_AUTOSENSE;
2167 DATAPI(bug("[ATA%02ld] atapi_TestUnitOK: Testing Unit Ready sense...\n", unit->au_UnitNum));
2168 unit->au_DirectSCSI(unit, &sc);
2169 unit->au_SenseKey = sense[2];
2172 * we may have just lost the disc...?
2175 * per MMC, drives are expected to return 02-3a-0# status, when disc is not present
2176 * that would translate into following code:
2177 * int p1 = ((sense[2] == 2) && (sense[12] == 0x3a)) ? 1 : 0;
2178 * unfortunately, it's what MMC says, not what vendors code.
2180 int p1 = (sense[2] == 2) ? 1 : 0;
2181 int p2 = (0 != (AF_DiscPresent & unit->au_Flags)) ? 1 : 0;
2183 if (p1 == p2)
2185 //unit->au_Flags ^= AF_DiscPresent;
2186 if (p1 == 0)
2187 unit->au_Flags |= AF_DiscPresent;
2188 else
2189 unit->au_Flags &= ~AF_DiscPresent;
2191 unit->au_Flags |= AF_DiscChanged;
2194 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"));
2195 return sense[2];
2198 static ULONG atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2200 UBYTE cmd[] = {
2201 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2203 struct SCSICmd sc = {
2207 D(bug("[ATA%02ld] atapi_Read()\n", unit->au_UnitNum));
2209 sc.scsi_Command = (void*) &cmd;
2210 sc.scsi_CmdLength = sizeof(cmd);
2211 sc.scsi_Data = buffer;
2212 sc.scsi_Length = count << unit->au_SectorShift;
2213 sc.scsi_Flags = SCSIF_READ;
2215 return unit->au_DirectSCSI(unit, &sc);
2218 static ULONG atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2220 UBYTE cmd[] = {
2221 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2223 struct SCSICmd sc = {
2227 D(bug("[ATA%02ld] atapi_Write()\n", unit->au_UnitNum));
2229 sc.scsi_Command = (void*) &cmd;
2230 sc.scsi_CmdLength = sizeof(cmd);
2231 sc.scsi_Data = buffer;
2232 sc.scsi_Length = count << unit->au_SectorShift;
2233 sc.scsi_Flags = SCSIF_WRITE;
2235 return unit->au_DirectSCSI(unit, &sc);
2238 static ULONG atapi_Eject(struct ata_Unit *unit)
2240 struct atapi_StartStop cmd = {
2241 command: SCSI_STARTSTOP,
2242 immediate: 1,
2243 flags: ATAPI_SS_EJECT,
2246 struct SCSICmd sc = {
2250 D(bug("[ATA%02ld] atapi_Eject()\n", unit->au_UnitNum));
2252 sc.scsi_Command = (void*) &cmd;
2253 sc.scsi_CmdLength = sizeof(cmd);
2254 sc.scsi_Flags = SCSIF_READ;
2256 return unit->au_DirectSCSI(unit, &sc);
2259 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2261 UBYTE cmd[] = {
2262 3, 0, 0, 0, senselen & 0xfe, 0
2264 struct SCSICmd sc = {
2268 D(bug("[ATA%02ld] atapi_RequestSense()\n", unit->au_UnitNum));
2270 if ((senselen == 0) || (sense == 0))
2272 return 0;
2274 sc.scsi_Data = (void*)sense;
2275 sc.scsi_Length = senselen & 0xfe;
2276 sc.scsi_Command = (void*)&cmd;
2277 sc.scsi_CmdLength = 6;
2278 sc.scsi_Flags = SCSIF_READ;
2280 unit->au_DirectSCSI(unit, &sc);
2282 DATAPI(dump(sense, senselen));
2283 DATAPI(bug("[SENSE] atapi_RequestSense: sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2284 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2287 ULONG ata_ReadSignature(struct ata_Bus *bus, int unit)
2289 ULONG port = bus->ab_Port;
2290 UBYTE tmp1, tmp2;
2292 D(bug("[ATA ] ata_ReadSignature(%02ld)\n", unit));
2294 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2295 ata_WaitNano(400);
2296 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2298 /* Check basic signature. All live devices should provide it */
2299 tmp1 = ata_in(ata_Count, port);
2300 tmp2 = ata_in(ata_LBALow, port);
2301 DINIT(bug("[ATA ] ata_ReadSignature: Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2303 DINIT(bug("[ATA ] ata_ReadSignature: Status %08lx Device %08lx\n", ata_in(ata_Status, port), ata_in(ata_DevHead, port)));
2305 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2307 /* Ok, ATA/ATAPI device. Get detailed signature */
2308 DINIT(bug("[ATA ] ata_ReadSignature: Found an ATA[PI] Device. Attempting to detect specific subtype\n"));
2310 tmp1 = ata_in(ata_LBAMid, port);
2311 tmp2 = ata_in(ata_LBAHigh, port);
2313 DINIT(bug("[ATA ] ata_ReadSignature: Subtype check returned %02lx:%02lx (%04lx)\n", tmp1, tmp2, (tmp1 << 8) | tmp2));
2315 switch ((tmp1 << 8) | tmp2)
2317 case 0x0000:
2318 if (0 == (ata_ReadStatus(bus) & 0xfe))
2319 return DEV_NONE;
2320 ata_out(ATA_EXECUTE_DIAG, ata_Command, port);
2322 ata_WaitTO(bus->ab_Timer, 0, 2000, 0);
2323 while (ata_ReadStatus(bus) & ATAF_BUSY)
2324 ata_WaitNano(400);
2325 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2327 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2330 ata_WaitNano(400);
2331 //ata_WaitTO(unit->au_Bus->ab_Timer, 0, 1, 0);
2333 while (0 != (ATAF_BUSY & ata_ReadStatus(bus)));
2334 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)));
2336 if ((ata_in(ata_Error, port) & 0x7f) == 1)
2338 DINIT(bug("[ATA ] ata_ReadSignature: Found *valid* signature for ATA device\n"));
2339 return DEV_ATA;
2341 bug("[ATA ] ata_ReadSignature: Found signature for ATA "
2342 "device, but further validation failed\n");
2343 return DEV_NONE;
2345 case 0x14eb:
2346 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for ATAPI device\n"));
2347 return DEV_ATAPI;
2349 case 0x3cc3:
2350 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATA device\n"));
2351 return DEV_SATA;
2353 case 0x6996:
2354 DINIT(bug("[ATA ] ata_ReadSignature: Found signature for SATAPI device\n"));
2355 return DEV_SATAPI;
2357 default:
2358 if (((tmp1 | tmp2) == 0xff) &&
2359 ((tmp1 & tmp2) == 0x00))
2361 bug("[ATA ] ata_ReadSignature: Found valid subtype, but don't know how to handle this device: %02lx %02lx\n", tmp1, tmp2);
2363 else
2365 bug("[ATA ] ata_ReadSignature: Invalid signature: %02lx %02lx\n", tmp1, tmp2);
2367 return DEV_NONE;
2371 return DEV_NONE;
2374 void ata_ResetBus(struct ata_Bus *bus)
2377 ULONG alt = bus->ab_Alt;
2378 ULONG port = bus->ab_Port;
2379 ULONG TimeOut;
2381 /* Set and then reset the soft reset bit in the Device Control
2382 * register. This causes device 0 be selected */
2383 D(bug("[ATA ] ata_ResetBus(%d)\n", bus->ab_BusNum));
2384 ata_out(0xa0 | (0 << 4), ata_DevHead, port); /* Select it never the less */
2385 ata_WaitNano(400);
2386 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2388 ata_out(0x04, ata_AltControl, alt);
2389 ata_WaitTO(bus->ab_Timer, 0, 10, 0); /* sleep 10us; min: 5us */
2390 ata_out(0x02, ata_AltControl, alt);
2391 ata_WaitTO(bus->ab_Timer, 0, 20000, 0); /* sleep 20ms; min: 2ms */
2393 /* If there is a device 0, wait for device 0 to clear BSY */
2394 if (DEV_NONE != bus->ab_Dev[0]) {
2395 D(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n", ((bus->ab_BusNum << 1 ) + 0)));
2396 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2397 while ( 1 ) {
2398 if( (ata_ReadStatus(bus) & ATAF_BUSY) == 0 )
2399 break;
2400 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2401 if (!(--TimeOut)) {
2402 D(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n", ((bus->ab_BusNum << 1 ) + 0)));
2403 bus->ab_Dev[0] = DEV_NONE;
2404 break;
2407 D(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n", ((bus->ab_BusNum << 1 ) + 0), (1000 - TimeOut)));
2410 /* If there is a device 1, wait until device 1 allows
2411 * register access */
2412 if (DEV_NONE != bus->ab_Dev[1]) {
2413 D(bug("[ATA ] ata_ResetBus: Wait DEV1 to allow access\n"));
2414 ata_out(0xa0 | (1 << 4), ata_DevHead, port);
2415 ata_WaitNano(400);
2416 //ata_WaitTO(bus->ab_Timer, 0, 1, 0);
2417 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2418 while ( 1 ) {
2419 if ( (ata_in(2, port) == 0x01) && (ata_in(3, port) == 0x01) )
2420 break;
2421 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2422 if (!(--TimeOut)) {
2423 D(bug("[ATA ] ata_ResetBus: DEV1 1/2 TimeOut!\n"));
2424 bus->ab_Dev[1] = DEV_NONE;
2425 break;
2428 D(bug("[ATA ] ata_ResetBus: DEV1 1/2 Wait left after %d ms\n", (1000 - TimeOut)));
2430 if (DEV_NONE != bus->ab_Dev[1]) {
2431 D(bug("[ATA%02ld] ata_ResetBus: Wait for Device to clear BSY\n", ((bus->ab_BusNum << 1 ) + 1)));
2432 TimeOut = 1000; /* Timeout 1s (1ms x 1000) */
2433 while ( 1 ) {
2434 if( (ata_ReadStatus(bus) & ATAF_BUSY) == 0 )
2435 break;
2436 ata_WaitTO(bus->ab_Timer, 0, 1000, 0);
2437 if (!(--TimeOut)) {
2438 D(bug("[ATA%02ld] ata_ResetBus: Device Timed Out!\n", ((bus->ab_BusNum << 1 ) + 1)));
2439 bus->ab_Dev[1] = DEV_NONE;
2440 break;
2443 D(bug("[ATA%02ld] ata_ResetBus: Wait left after %d ms\n", ((bus->ab_BusNum << 1 ) + 1), 1000 - TimeOut));
2447 if (DEV_NONE != bus->ab_Dev[0])
2448 bus->ab_Dev[0] = ata_ReadSignature(bus, 0);
2449 if (DEV_NONE != bus->ab_Dev[1])
2450 bus->ab_Dev[1] = ata_ReadSignature(bus, 1);
2453 void ata_InitBus(struct ata_Bus *bus)
2455 ULONG port = bus->ab_Port;
2456 UBYTE tmp1, tmp2;
2459 * initialize timer for the sake of scanning
2461 bus->ab_Timer = ata_OpenTimer();
2463 D(bug("[ATA ] ata_InitBus(%d)\n", bus->ab_BusNum));
2465 bus->ab_Dev[0] = DEV_NONE;
2466 bus->ab_Dev[1] = DEV_NONE;
2468 /* Select device 0 and disable IRQs */
2469 ata_out(0xa0, ata_DevHead, port);
2470 ata_WaitTO(bus->ab_Timer, 0, 100, 0);
2471 ata_out(0x2, ata_AltControl, bus->ab_Alt);
2473 /* Write some pattern to registers */
2474 ata_out(0x55, ata_Count, port);
2475 ata_out(0xaa, ata_LBALow, port);
2476 ata_out(0xaa, ata_Count, port);
2477 ata_out(0x55, ata_LBALow, port);
2478 ata_out(0x55, ata_Count, port);
2479 ata_out(0xaa, ata_LBALow, port);
2481 tmp1 = ata_in(ata_Count, port);
2482 tmp2 = ata_in(ata_LBALow, port);
2484 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2485 bus->ab_Dev[0] = DEV_UNKNOWN;
2486 D(bug("[ATA%02ld] ata_InitBus: Device type = %x\n", (bus->ab_BusNum << 1 ) + 0, bus->ab_Dev[0]));
2488 /* Select device 1 and disable IRQs */
2489 ata_out(0xb0, ata_DevHead, port);
2490 ata_WaitTO(bus->ab_Timer, 0, 100, 0);
2491 ata_out(0x2, ata_AltControl, bus->ab_Alt);
2493 /* Write some pattern to registers */
2494 ata_out(0x55, ata_Count, port);
2495 ata_out(0xaa, ata_LBALow, port);
2496 ata_out(0xaa, ata_Count, port);
2497 ata_out(0x55, ata_LBALow, port);
2498 ata_out(0x55, ata_Count, port);
2499 ata_out(0xaa, ata_LBALow, port);
2501 tmp1 = ata_in(ata_Count, port);
2502 tmp2 = ata_in(ata_LBALow, port);
2504 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2505 bus->ab_Dev[1] = DEV_UNKNOWN;
2506 D(bug("[ATA%02ld] ata_InitBus: Device type = %x\n", (bus->ab_BusNum << 1 ) + 1, bus->ab_Dev[1]));
2508 ata_ResetBus(bus);
2509 ata_CloseTimer(bus->ab_Timer);
2510 D(bug("[ATA ] ata_InitBus: Finished\n"));
2514 * not really sure what this is meant to be - TO BE REPLACED
2516 static const ULONG ErrorMap[] = {
2517 CDERR_NotSpecified,
2518 CDERR_NoSecHdr,
2519 CDERR_NoDisk,
2520 CDERR_NoSecHdr,
2521 CDERR_NoSecHdr,
2522 CDERR_NOCMD,
2523 CDERR_NoDisk,
2524 CDERR_WriteProt,
2525 CDERR_NotSpecified,
2526 CDERR_NotSpecified,
2527 CDERR_NotSpecified,
2528 CDERR_ABORTED,
2529 CDERR_NotSpecified,
2530 CDERR_NotSpecified,
2531 CDERR_NoSecHdr,
2532 CDERR_NotSpecified,
2535 static ULONG atapi_EndCmd(struct ata_Unit *unit)
2537 UBYTE status;
2539 DATAPI(bug("[ATA%02ld] atapi_EndCmd()\n", unit->au_UnitNum));
2542 * read alternate status register (per specs)
2544 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2545 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Alternate status: %lx\n", unit->au_UnitNum, status));
2547 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2549 DATAPI(bug("[ATAPI] atapi_EndCmd: Command complete. Status: %lx\n", unit->au_UnitNum, status));
2551 if (!(status & ATAPIF_CHECK))
2553 return 0;
2555 else
2557 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2558 DATAPI(bug("[ATA%02ld] atapi_EndCmd: Error code 0x%lx\n", unit->au_UnitNum, status >> 4));
2559 return ErrorMap[status >> 4];
2564 * vim: ts=4 et sw=4 fdm=marker fmr={,}