Use MEMF_PUBLIC for soft-link buffer.
[cake.git] / arch / common / ata.device / lowlevel.c
blob9f3454556e5deebd2f0a9cefb89e68a04a27fe1a
1 /*
2 Copyright © 2004-2008, The AROS Development Team. All rights reserved
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*
10 * 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
56 * TODO:
57 * - put a critical section around DMA transfers (shared dma channels)
60 #define DEBUG 0
61 // use #define xxx(a) D(a) to enable particular sections.
62 #define DIRQ(a)
63 #define DIRQ_MORE(a)
64 #define DUMP(a)
65 #define DATA(a)
66 #define DATAPI(a)
67 #define DINIT(a) D(a)
69 #include <aros/debug.h>
70 #include <exec/types.h>
71 #include <exec/exec.h>
72 #include <exec/resident.h>
73 #include <utility/utility.h>
74 #include <oop/oop.h>
76 #include <dos/bptr.h>
78 #include <proto/exec.h>
79 #include <devices/timer.h>
81 #include <asm/io.h>
83 #include "ata.h"
88 Prototypes of static functions from lowlevel.c. I do not want to make them
89 non-static as I'd like to remove as much symbols from global table as possible.
90 Besides some of this functions could conflict with old ide.device or any other
91 device.
93 static ULONG ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
94 static ULONG ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
95 static ULONG ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
96 static ULONG ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
97 static ULONG ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
98 static ULONG ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
99 static ULONG ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
100 static ULONG ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
101 static ULONG ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
102 static ULONG ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
103 static ULONG ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
104 static ULONG ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
105 static ULONG ata_Eject(struct ata_Unit *);
106 static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout);
108 static ULONG atapi_EndCmd(struct ata_Unit *unit);
110 static ULONG atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
111 static ULONG atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
112 static ULONG atapi_Eject(struct ata_Unit *);
114 static void common_SetBestXferMode(struct ata_Unit* unit);
117 Again piece of code which shouldn't be here. Geee. After removing all this
118 asm constrictuins this ata.device will really deserve for location in
119 /arch/common
122 * having an x86 assembly here i dare to assume that this is meant to be
123 * an x86[_64] device only.
125 * Not anymore.
127 * This functions will stay here for some time *IF* and only if the code is compiled for
128 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
129 * one who ports the driver will be reponsible for adding the missing code.
133 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
135 #if defined(__i386__) || defined(__x86_64__)
137 static VOID ata_insw(APTR address, UWORD port, ULONG count)
139 insw(port, address, count >> 1);
142 static VOID ata_insl(APTR address, UWORD port, ULONG count)
144 if (count & 2)
145 insw(port, address, count >> 1);
146 else
147 insl(port, address, count >> 2);
150 static VOID ata_outsw(APTR address, UWORD port, ULONG count)
152 outsw(port, address, count >> 1);
155 static VOID ata_outsl(APTR address, UWORD port, ULONG count)
157 if (count & 2)
158 outsw(port, address, count >> 1);
159 else
160 outsl(port, address, count >> 2);
164 * Very short delay (TM) by someone who assumes slow data ports.
165 * well, glad it works anyways.
167 void ata_400ns()
169 ata_in(ata_AltControl, 0x3f6);
170 ata_in(ata_AltControl, 0x3f6);
171 ata_in(ata_AltControl, 0x3f6);
172 ata_in(ata_AltControl, 0x3f6);
175 #else
176 extern VOID ata_insw(APTR address, UWORD port, ULONG count);
177 extern VOID ata_insl(APTR address, UWORD port, ULONG count);
178 extern VOID ata_outsw(APTR address, UWORD port, ULONG count);
179 extern VOID ata_outsl(APTR address, UWORD port, ULONG count);
180 extern void ata_400ns();
181 #endif
183 static void dump(APTR mem, ULONG len)
185 register int i,j;
186 for (j=0; j<(len+15)>>4; ++j)
188 bug("[ATA ] %06lx: ", j<<4);
190 for (i=0; i<len-(j<<4); i++)
192 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
193 if (i == 15)
194 break;
197 for (i=0; i<len-(j<<4); i++)
199 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
201 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
202 if (i == 15)
203 break;
205 bug("\n");
209 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
211 register int i = size;
213 while (size--)
215 str2[size^1] = str1[size];
218 while (i--)
220 if (str2[i] <= ' ')
221 str2[i] = 0;
227 * a STUB function for commands not supported by this particular device
229 static ULONG ata_STUB(struct ata_Unit *au)
231 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
232 return CDERR_NOCMD;
235 static ULONG ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len, APTR buf, ULONG* act)
237 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
238 return CDERR_NOCMD;
241 static ULONG ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len, APTR buf, ULONG* act)
243 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);
244 return CDERR_NOCMD;
247 static ULONG ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
249 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
250 return CDERR_NOCMD;
253 inline BOOL ata_SelectUnit(struct ata_Unit* unit)
255 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
259 ata_400ns();
261 while (0 != (ATAF_BUSY & ata_ReadStatus(unit->au_Bus)));
263 return TRUE;
266 inline struct ata_Unit* ata_GetSelectedUnit(struct ata_Bus* bus)
268 register int id = (ata_in(ata_DevHead, bus->ab_Port) & 0x10) >> 4;
269 return bus->ab_Units[id];
272 UBYTE ata_ReadStatus(struct ata_Bus *bus)
274 return ata_in(ata_Status, bus->ab_Port);
278 * enable / disable IRQ; this manages interrupt requests more effectively in case of legacy emulation
279 * as little code as there can be. and keep it that way.
281 void ata_EnableIRQ(struct ata_Bus *bus, BOOL enable)
283 enable &= (bus->ab_Dev[0] > DEV_UNKNOWN) || (bus->ab_Dev[1] > DEV_UNKNOWN);
284 bug("[ATA ] IRQ: Setting IRQ flag for bus %ld to %s\n", bus->ab_BusNum, enable ? "ENABLED" : "DISABLED");
285 bus->ab_IRQ = enable;
286 ata_out(enable ? 0x0 : 0x02, ata_AltControl, bus->ab_Alt);
290 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
291 * part of code moved here from ata.c to reduce containment
293 void ata_IRQSignalTask(struct ata_Bus *bus)
295 bus->ab_IntCnt++;
296 Signal(bus->ab_Task, 1UL << bus->ab_SleepySignal);
299 void ata_HandleIRQ(struct ata_Bus *bus)
301 struct ata_Unit *u = ata_GetSelectedUnit(bus);
302 UBYTE status = ata_ReadStatus(bus);
304 * don't waste your time on checking other devices.
305 * pass irq ONLY if task is expecting one;
308 if (0 != bus->ab_HandleIRQ)
311 * ok, we have a routine to handle any form of transmission etc
313 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
314 bus->ab_HandleIRQ(u, status);
315 return;
318 DIRQ_MORE({
320 * if we got *here* then device is most likely not expected to have an irq.
322 bug("[ATA%02ld] IRQ: Checking busy flag: ", u->au_UnitNum);
324 if (0 == (ATAF_BUSY & status))
326 bug("device ready. Dumping details:\n");
328 bug("[ATA ] STATUS: %02lx\n", status);
329 bug("[ATA ] ALT STATUS: %02lx\n", ata_in(ata_AltStatus, bus->ab_Alt));
330 bug("[ATA ] ERROR: %02lx\n", ata_in(ata_Error, bus->ab_Port));
331 bug("[ATA ] IRQ: REASON: %02lx\n", ata_in(atapi_Reason, bus->ab_Port));
333 else
335 bug("device still busy. ignoring irq.\n");
340 void ata_IRQSetHandler(struct ata_Unit *unit, void (*handler)(struct ata_Unit*, UBYTE), APTR piomem, ULONG blklen, ULONG piolen)
342 if (NULL != handler)
343 unit->au_cmd_error = 0;
345 unit->au_cmd_data = piomem;
346 unit->au_cmd_length = (piolen < blklen) ? piolen : blklen;
347 unit->au_cmd_total = piolen;
348 unit->au_Bus->ab_HandleIRQ = handler;
351 void ata_IRQNoData(struct ata_Unit *unit, UBYTE status)
353 if (status & ATAF_BUSY)
354 return;
356 if ((unit->au_cmd_error == 0) && (status & ATAF_ERROR))
357 unit->au_cmd_error = HFERR_BadStatus;
359 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit->au_UnitNum, status));
360 ata_IRQSetHandler(unit, NULL, NULL, 0, 0);
361 ata_IRQSignalTask(unit->au_Bus);
364 void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status)
366 if (status & ATAF_DATAREQ) {
367 DIRQ(bug("[ATA ] IRQ: PIOReadData - DRQ.\n"));
368 unit->au_ins(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
371 * indicate it's all done here
373 unit->au_cmd_data += unit->au_cmd_length;
374 unit->au_cmd_total -= unit->au_cmd_length;
375 if (unit->au_cmd_total) {
376 if (unit->au_cmd_length > unit->au_cmd_total)
377 unit->au_cmd_length = unit->au_cmd_total;
378 return;
380 DIRQ(bug("[ATA ] IRQ: PIOReadData - transfer completed.\n"));
382 ata_IRQNoData(unit, status);
385 void ata_PIOWriteBlk(struct ata_Unit *unit)
387 unit->au_outs(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
390 * indicate it's all done here
392 unit->au_cmd_data += unit->au_cmd_length;
393 unit->au_cmd_total -= unit->au_cmd_length;
394 if (unit->au_cmd_length > unit->au_cmd_total)
395 unit->au_cmd_length = unit->au_cmd_total;
398 void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status)
400 if (status & ATAF_DATAREQ) {
401 DIRQ(bug("[ATA ] IRQ: PIOWriteData - DRQ.\n"));
402 ata_PIOWriteBlk(unit);
403 return;
405 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
406 ata_IRQNoData(unit, status);
409 void ata_IRQDMAReadWrite(struct ata_Unit *au, UBYTE status)
411 UBYTE stat = ata_in(dma_Status, au->au_DMAPort);
412 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat));
414 if (0 == (stat & DMAF_Interrupt))
416 bug("[ATA ] IRQ: Fake IRQ.\n");
418 else if ((status & ATAF_ERROR) || (stat & DMAF_Error))
420 /* This is turned on in order to help Phantom - Pavel Fedin <sonic_amiga@rambler.ru> */
421 bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat);
422 bug("[ATA%02ld] IRQ: ERROR %02lx\n", au->au_UnitNum, ata_in(atapi_Error, au->au_Bus->ab_Port));
423 bug("[ATA ] IRQ: DMA Failed.\n");
424 au->au_cmd_error = HFERR_DMA;
425 ata_IRQNoData(au, status);
427 else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
429 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
430 ata_IRQNoData(au, status);
434 void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status)
436 ULONG port = unit->au_Bus->ab_Port;
437 ULONG size = 0;
438 UBYTE reason = ata_in(atapi_Reason, port);
439 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason));
441 /* have we failed yet? */
442 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
443 ata_IRQNoData(unit, status);
444 if (status & ATAF_ERROR)
445 ata_IRQNoData(unit, status);
447 /* anything for us please? */
448 if (ATAPIF_READ != (reason & ATAPIF_MASK))
449 return;
451 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
452 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
454 if (size > unit->au_cmd_total)
456 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", 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 if (unit->au_cmd_total == 0)
467 ata_IRQNoData(unit, status);
470 void ata_IRQPIOWriteAtapi(struct ata_Unit *unit, UBYTE status)
472 ULONG port = unit->au_Bus->ab_Port;
473 ULONG size = 0;
474 UBYTE reason = ata_in(atapi_Reason, port);
475 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason));
477 /* have we failed yet? */
478 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
479 ata_IRQNoData(unit, status);
480 if (status & ATAF_ERROR)
481 ata_IRQNoData(unit, status);
483 /* anything for us please? */
484 if (ATAPIF_READ != (reason & ATAPIF_MASK))
485 return;
487 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
488 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_total));
490 if (size > unit->au_cmd_total)
492 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_total);
493 size = unit->au_cmd_total;
496 unit->au_outs(unit->au_cmd_data, port, size);
497 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
498 unit->au_cmd_total -= size;
500 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size));
502 if (unit->au_cmd_total == 0)
503 ata_IRQNoData(unit, status);
507 * wait for timeout or drive ready
508 * polling-in-a-loop, but it should be safe to remove this already
510 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq, UBYTE *stout)
512 UBYTE status;
513 ULONG sigs = SIGBREAKF_CTRL_C;
514 ULONG step = 0;
515 BOOL res = TRUE;
517 if (irq && !unit->au_Bus->ab_IRQ)
519 bug("[ATA ] Requested IRQ wait, but IRQ is not enabled\n");
522 irq &= unit->au_Bus->ab_IRQ;
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 and irq
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 collissions. We may still want to go ahead and get some extra irq breaks
541 * this would reduce system load a little
548 * delay the check - this was found needed for some hardware
551 ata_400ns();
554 * lets check if the drive is already good
556 status = 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 dont keep receiving more of these (especially when system suffers collissions)
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);
582 res = FALSE;
586 * if we get as far as this, there's no more signals to expect
587 * but we still want the status
589 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
590 break;
592 else
595 * device not ready just yet. lets set whether we want an IRQ and move on - to polling or irq wait
597 ++step;
600 * every 16n rounds do some extra stuff
602 if ((step & 16) == 0)
605 * huhm. so it's been 16n rounds already. any timeout yet?
607 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
609 DIRQ(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit->au_UnitNum));
610 res = FALSE;
611 break;
615 * no timeout just yet, but it's not a good idea to keep spinning like that.
616 * let's give the system some time.
618 ata_400ns();
619 // TODO: Put some delay here!
622 } while(status & ATAF_BUSY);
625 * be nice to frustrated developer
627 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit->au_UnitNum, status, res));
630 * clear up all our expectations
632 Disable();
633 unit->au_Bus->ab_Timeout = -1;
634 Enable();
637 * release old junk
639 SetSignal(0, sigs);
642 * and say it went fine (i mean it)
644 if (stout)
645 *stout = status;
646 return res;
650 * just wait for timeout
652 void ata_Wait(struct ata_Unit *unit, UWORD tout)
654 SetSignal(0, SIGBREAKF_CTRL_C);
656 Disable();
657 unit->au_Bus->ab_Timeout = tout;
658 Enable();
660 Wait(SIGBREAKF_CTRL_C);
664 * Procedure for sending ATA command blocks
665 * it appears LARGE but there's a lot of COMMENTS here :)
666 * handles *all* ata commands (no data, pio and dma)
667 * naturally could be splitted at some point in the future
668 * depends if anyone believes that the change for 50 lines
669 * would make slow ATA transfers any faster
671 static ULONG ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
673 ULONG port = au->au_Bus->ab_Port;
674 ULONG err = 0;
675 APTR mem = block->buffer;
676 UBYTE status;
678 if (FALSE == ata_SelectUnit(au))
679 return IOERR_UNITBUSY;
681 switch (block->type)
683 case CT_LBA28:
684 if (block->sectors > 256)
686 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
687 return IOERR_BADLENGTH;
690 /* note:
691 * we want the above to fall in here!
692 * we really do (checking for secmul)
695 case CT_LBA48:
696 if (block->sectors > 65536)
698 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
699 return IOERR_BADLENGTH;
701 if (block->secmul == 0)
703 bug("[ATA%02ld] ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
704 block->secmul = 1;
706 break;
708 case CT_NoBlock:
709 break;
711 default:
712 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
713 return IOERR_NOCMD;
716 block->actual = 0;
717 D(bug("[ATA%02ld] Executing command %02lx\n", au->au_UnitNum, block->command));
719 if (block->feature != 0)
720 ata_out(block->feature, ata_Feature, port);
723 * - set LBA and sector count
725 switch (block->type)
727 case CT_LBA28:
728 DATA(bug("[ATA%02ld] Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
729 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
730 ata_out(block->blk >> 16, ata_LBAHigh, port);
731 ata_out(block->blk >> 8, ata_LBAMid, port);
732 ata_out(block->blk, ata_LBALow, port);
733 ata_out(block->sectors, ata_Count, port);
734 break;
736 case CT_LBA48:
737 DATA(bug("[ATA%02ld] Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
738 ata_out(block->blk >> 40, ata_LBAHigh, port);
739 ata_out(block->blk >> 32, ata_LBAMid, port);
740 ata_out(block->blk >> 24, ata_LBALow, port);
742 ata_out(block->blk >> 16, ata_LBAHigh, port);
743 ata_out(block->blk >> 8, ata_LBAMid, port);
744 ata_out(block->blk, ata_LBALow, port);
746 ata_out(block->sectors >> 8, ata_Count, port);
747 ata_out(block->sectors, ata_Count, port);
748 break;
750 case CT_NoBlock:
751 DATA(bug("[ATA%02ld] Command does not address any block\n", au->au_UnitNum));
752 break;
756 switch (block->method)
758 case CM_PIOWrite:
759 ata_IRQSetHandler(au, &ata_IRQPIOWrite, mem, block->secmul << au->au_SectorShift, block->length);
760 break;
762 case CM_PIORead:
763 ata_IRQSetHandler(au, &ata_IRQPIORead, mem, block->secmul << au->au_SectorShift, block->length);
764 break;
766 case CM_DMARead:
767 if (FALSE == dma_SetupPRDSize(au, mem, block->length, TRUE))
768 return IOERR_ABORTED;
769 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
770 dma_StartDMA(au);
771 break;
773 case CM_DMAWrite:
774 if (FALSE == dma_SetupPRDSize(au, mem, block->length, FALSE))
775 return IOERR_ABORTED;
776 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0, 0);
777 dma_StartDMA(au);
778 break;
780 case CM_NoData:
781 ata_IRQSetHandler(au, &ata_IRQNoData, NULL, 0, 0);
782 break;
784 default:
785 return IOERR_NOCMD;
786 break;
790 * send command now
791 * let drive propagate its signals
793 DATA(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
794 ata_out(block->command, ata_Command, port);
795 ata_400ns();
798 * In case of PIO write the drive won't issue an IRQ before first
799 * data transfer, so we should poll the status and send the firs
800 * block upon request.
802 if (block->method == CM_PIOWrite) {
803 if (FALSE == ata_WaitBusyTO(au, 300, FALSE, &status)) {
804 D(bug("[ATA%02ld] PIOWrite - no response from device\n", au->au_UnitNum));
805 return IOERR_UNITBUSY;
807 if (status & ATAF_DATAREQ) {
808 DATA(bug("[ATA%02ld] PIOWrite - DRQ.\n", au->au_UnitNum));
809 ata_PIOWriteBlk(au);
811 else
813 D(bug("[ATA%02ld] PIOWrite - bad status: %02X\n", status));
814 return HFERR_BadStatus;
819 * wait for drive to complete what it has to do
821 if (FALSE == ata_WaitBusyTO(au, 300, TRUE, NULL))
823 bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum);
824 err = IOERR_UNITBUSY;
826 else
827 err = au->au_cmd_error;
829 DATA(bug("[ATA%02ld] Command done\n", au->au_UnitNum));
831 * clean up DMA
832 * don't use 'mem' pointer here as it's already invalid.
834 if (block->method == CM_DMARead)
836 dma_StopDMA(au);
837 dma_Cleanup(block->buffer, block->length, TRUE);
839 else if (block->method == CM_DMAWrite)
841 dma_StopDMA(au);
842 dma_Cleanup(block->buffer, block->length, FALSE);
845 D(bug("[ATA%02ld] return code %ld\n", au->au_UnitNum, err));
846 return err;
850 * atapi packet iface
852 int atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, LONG datalen, BOOL *dma, BOOL write)
854 *dma &= (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
855 LONG err = 0;
857 UBYTE cmd[12] = {
860 register int t=5,l=0;
861 ULONG port = unit->au_Bus->ab_Port;
863 if (((UBYTE*)packet)[0] > 0x1f)
864 t+= 4;
865 if (((UBYTE*)packet)[0] > 0x5f)
866 t+= 2;
868 switch (((UBYTE*)packet)[0])
870 case 0x28: // read10
871 case 0xa8: // read12
872 case 0xbe: // readcd
873 case 0xb9: // readcdmsf
874 case 0x2f: // verify
875 case 0x2a: // write
876 case 0xaa: // write12
877 case 0x2e: // writeverify
878 break;
879 default:
880 *dma = FALSE;
883 while (l<=t)
885 cmd[l] = ((UBYTE*)packet)[l];
886 ++l;
890 bug("[ATA%02lx] Sending %s ATA packet: ", unit->au_UnitNum, (*dma) ? "DMA" : "PIO");
891 l=0;
892 while (l<=t)
894 bug("%02lx ", ((UBYTE*)cmd)[l]);
895 ++l;
897 bug("\n");
899 if (datalen & 1)
900 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
903 datalen = (datalen+1)&~1;
905 if (FALSE == ata_SelectUnit(unit))
907 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
908 return IOERR_UNITBUSY;
912 * tell device if whether we want to read or write and if we want a dma transfer
914 ata_out(((*dma) ? 1 : 0) | ((write) ? 4 : 0), atapi_Features, port);
915 ata_out((datalen & 0xff), atapi_ByteCntL, port);
916 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
919 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
920 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
922 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
923 ata_out(ATA_PACKET, atapi_Command, port);
924 ata_400ns();
926 ata_WaitBusyTO(unit, 30, FALSE, NULL);
927 if (0 == (ata_ReadStatus(unit->au_Bus) & ATAF_DATAREQ))
928 return HFERR_BadStatus;
931 * setup appropriate hooks. not really the best way.
933 if (datalen == 0)
934 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0, 0);
935 else if (*dma)
936 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0, 0);
937 else if (write)
938 ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, 0, datalen);
939 else
940 ata_IRQSetHandler(unit, &ata_IRQPIOReadAtapi, data, 0, datalen);
942 DATAPI(bug("[ATAPI] Sending packet\n"));
943 unit->au_outs(cmd, unit->au_Bus->ab_Port, 12);
944 ata_400ns(); /* give drive time to think about what we just said, then move on */
945 /* how much time could it take for drive to raise DMARQ signal?? */
947 DATAPI(bug("[ATAPI] Status after packet: %lx\n", ata_ReadStatus(unit->au_Bus)));
949 if (*dma)
951 DATAPI(bug("[ATAPI] Preparing for DMA\n"));
952 while (0 == ((t = ata_ReadStatus(unit->au_Bus)) & (ATAF_BUSY | ATAF_DATAREQ)))
954 if (t & ATAF_ERROR)
956 err = HFERR_DMA;
957 break;
959 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit->au_Bus)));
960 ata_400ns();
963 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit->au_Bus)));
965 if (0 == err)
967 DATAPI(bug("[ATAPI] Starting DMA\n"));
968 dma_StartDMA(unit);
972 if ((0 == err) && (ata_WaitBusyTO(unit, 300, TRUE, NULL) == FALSE))
974 DATAPI(bug("[DSCSI] Command timed out.\n"));
975 err = IOERR_UNITBUSY;
977 else
978 err = atapi_EndCmd(unit);
980 if (TRUE == *dma)
982 dma_StopDMA(unit);
983 dma_Cleanup(data, datalen, !write);
986 D(bug("[ATAPI] Error code %ld\n", err));
987 return err;
990 ULONG atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
992 APTR buffer = cmd->scsi_Data;
993 ULONG length = cmd->scsi_Length;
994 BOOL read = FALSE;
995 UBYTE status;
996 UBYTE err = 0;
997 BOOL dma = FALSE;
999 cmd->scsi_Actual = 0;
1001 DATAPI(bug("[DSCSI] Sending packet!\n"));
1005 * setup DMA & push command
1006 * it does not really mean we will use dma here btw
1008 if ((unit->au_XferModes & AF_XFER_DMA) && (length !=0) && (buffer != 0))
1010 dma = TRUE;
1011 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
1013 read = TRUE;
1014 if (FALSE == dma_SetupPRDSize(unit, buffer, length, TRUE))
1015 dma = FALSE;
1017 else
1019 if (FALSE == dma_SetupPRDSize(unit, buffer, length, FALSE))
1020 dma = FALSE;
1024 err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0);
1026 DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); });
1029 * on check condition - grab sense data
1031 DATAPI(bug("[ATA%02lx] SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err));
1032 if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
1034 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
1035 DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
1038 return err;
1042 * chops the large transfers into set of smaller transfers
1043 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1045 static ULONG ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
1047 ULONG err=0;
1048 ULONG part;
1049 ULONG max=256;
1050 ULONG count=blk->sectors;
1052 if (blk->type == CT_LBA48)
1053 max <<= 8;
1055 DATA(bug("[ATA%02ld] Accessing %ld sectors starting from %lx\n", unit->au_UnitNum, count, blk->blk));
1056 while ((count > 0) && (err == 0))
1058 part = (count > max) ? max : count;
1059 blk->sectors = part;
1060 blk->length = part << unit->au_SectorShift;
1062 err = ata_exec_cmd(unit, blk);
1064 blk->blk += part;
1065 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1066 count -= part;
1068 return err;
1072 * Initial device configuration that suits *all* cases
1074 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1076 struct ata_Unit *unit=NULL;
1078 DINIT(bug("[ATA ] Initializing unit %ld\n", u));
1080 unit = bus->ab_Units[u];
1081 if (NULL == unit)
1082 return FALSE;
1084 unit->au_Bus = bus;
1085 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1086 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1087 unit->au_DevMask = 0xa0 | (u << 4);
1088 if (bus->ab_Base->ata_32bit)
1090 unit->au_ins = ata_insl;
1091 unit->au_outs = ata_outsl;
1093 else
1095 unit->au_ins = ata_insw;
1096 unit->au_outs = ata_outsw;
1098 unit->au_SectorShift= 9; /* this really has to be set here. */
1099 unit->au_Flags = 0;
1101 NEWLIST(&unit->au_SoftList);
1104 * since the stack is always handled by caller
1105 * it's safe to stub all calls with one function
1107 unit->au_Read32 = ata_STUB_IO32;
1108 unit->au_Read64 = ata_STUB_IO64;
1109 unit->au_Write32 = ata_STUB_IO32;
1110 unit->au_Write64 = ata_STUB_IO64;
1111 unit->au_Eject = ata_STUB;
1112 unit->au_DirectSCSI = ata_STUB_SCSI;
1113 unit->au_Identify = ata_STUB;
1114 return TRUE;
1117 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1119 struct ata_Unit *unit=NULL;
1122 * this stuff always goes along the same way
1123 * WARNING: NO INTERRUPTS AT THIS POINT!
1125 DINIT(bug("[ATA ] setting up unit %ld\n", u));
1127 unit = bus->ab_Units[u];
1128 if (NULL == unit)
1129 return FALSE;
1131 ata_SelectUnit(unit);
1133 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE, NULL))
1135 DINIT(bug("[ATA%02ld] ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1136 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1137 unit->au_Drive = 0;
1138 return FALSE;
1141 switch (bus->ab_Dev[u])
1144 * safe fallback settings
1146 case DEV_SATAPI:
1147 case DEV_ATAPI:
1148 unit->au_Identify = atapi_Identify;
1149 break;
1151 case DEV_SATA:
1152 case DEV_ATA:
1153 unit->au_Identify = ata_Identify;
1154 break;
1157 default:
1158 DINIT(bug("[ATA%02ld] Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1159 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1160 unit->au_Drive = 0;
1161 return FALSE;
1164 bug("[ATA ] Enabling Bus IRQs\n");
1165 ata_EnableIRQ(bus, TRUE);
1167 * now make unit self diagnose
1169 if (unit->au_Identify(unit) != 0)
1171 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1172 unit->au_Drive = 0;
1173 return FALSE;
1176 return TRUE;
1182 * ata[pi] identify
1184 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1186 UBYTE type=0;
1187 BOOL dma=FALSE;
1188 ata_CommandBlock acb =
1190 0xef,
1191 0x03,
1192 0x01,
1193 0x00,
1194 0x00,
1195 0x00,
1196 0x00,
1197 0x00,
1198 0x00,
1199 CM_NoData,
1200 CT_LBA28
1203 if ((unit->au_DMAPort == 0) && (mode > AB_XFER_PIO7))
1205 DINIT(bug("[ATA%02ld] This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1206 common_SetBestXferMode(unit);
1207 return;
1212 * first, ONLY for ATA devices, set new commands
1214 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1216 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1218 if ((!unit->au_Bus->ab_Base->ata_NoMulti) && (unit->au_XferModes & AF_XFER_RWMULTI))
1220 ata_out(unit->au_Drive->id_RWMultipleSize & 0xFF, ata_Count, unit->au_Bus->ab_Port);
1221 ata_out(ATA_SET_MULTIPLE, ata_Command, unit->au_Bus->ab_Port);
1222 ata_WaitBusyTO(unit, -1, FALSE, NULL);
1224 unit->au_Read32 = ata_ReadMultiple32;
1225 unit->au_Write32 = ata_WriteMultiple32;
1226 if (unit->au_XferModes & AF_XFER_48BIT)
1228 unit->au_Read64 = ata_ReadMultiple64;
1229 unit->au_Write64 = ata_WriteMultiple64;
1232 else
1234 unit->au_Read32 = ata_ReadSector32;
1235 unit->au_Write32 = ata_WriteSector32;
1236 if (unit->au_XferModes & AF_XFER_48BIT)
1238 unit->au_Read64 = ata_ReadSector64;
1239 unit->au_Write64 = ata_WriteSector64;
1243 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1245 unit->au_Read32 = ata_ReadDMA32;
1246 unit->au_Write32 = ata_WriteDMA32;
1247 if (unit->au_XferModes & AF_XFER_48BIT)
1249 unit->au_Read64 = ata_ReadDMA64;
1250 unit->au_Write64 = ata_WriteDMA64;
1253 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1255 unit->au_Read32 = ata_ReadDMA32;
1256 unit->au_Write32 = ata_WriteDMA32;
1257 if (unit->au_XferModes & AF_XFER_48BIT)
1259 unit->au_Read64 = ata_ReadDMA64;
1260 unit->au_Write64 = ata_WriteDMA64;
1263 else
1265 unit->au_Read32 = ata_ReadSector32;
1266 unit->au_Write32 = ata_WriteSector32;
1267 if (unit->au_XferModes & AF_XFER_48BIT)
1269 unit->au_Read64 = ata_ReadSector64;
1270 unit->au_Write64 = ata_WriteSector64;
1275 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1277 type = 8 + (mode - AB_XFER_PIO0);
1279 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1281 type = 32 + (mode - AB_XFER_MDMA7);
1282 dma=TRUE;
1284 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1286 type = 64 + (mode - AB_XFER_MDMA7);
1287 dma=TRUE;
1289 else
1291 type = 0;
1294 acb.sectors = type;
1295 if (0 != ata_exec_cmd(unit, &acb))
1297 DINIT(bug("[ATA%02ld] ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1300 if (unit->au_DMAPort)
1302 type = ata_in(dma_Status, unit->au_DMAPort);
1303 type &= 0x60;
1304 if (dma)
1306 type |= 1 << (5 + (unit->au_UnitNum & 1));
1308 else
1310 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1313 DINIT(bug("[DSCSI] Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1315 ata_SelectUnit(unit);
1316 ata_out(type, dma_Status, unit->au_DMAPort);
1317 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1319 DINIT(bug("[DSCSI] New DMA Status: %02lx\n", type));
1321 else
1323 DINIT(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1324 dma = FALSE;
1328 if (dma)
1329 unit->au_XferModes |= AF_XFER_DMA;
1330 else
1331 unit->au_XferModes &=~AF_XFER_DMA;
1334 static void common_SetBestXferMode(struct ata_Unit* unit)
1336 int iter;
1337 int max = AB_XFER_UDMA7;
1339 if (unit->au_DMAPort == 0)
1342 * make sure you reduce scan search to pio here!
1343 * otherwise this and above function will fall into infinite loop
1345 DINIT(bug("[ATA%02ld] This controller does not own DMA port\n", unit->au_UnitNum));
1346 max = AB_XFER_PIO7;
1349 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1351 if (unit->au_XferModes & (1<<iter))
1353 common_SetXferMode(unit, iter);
1354 return;
1357 bug("[ATA%02ld] ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1358 common_SetXferMode(unit, AB_XFER_PIO0);
1361 void common_DetectXferModes(struct ata_Unit* unit)
1363 int iter;
1365 DINIT(bug("[ATA%02ld] Supports\n", unit->au_UnitNum));
1367 if (unit->au_Drive->id_Commands4 & (1 << 4))
1369 DINIT(bug("[ATA%02ld] - Packet interface\n", unit->au_UnitNum));
1370 unit->au_XferModes |= AF_XFER_PACKET;
1371 unit->au_DirectSCSI = atapi_DirectSCSI;
1373 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1375 /* ATAPI devices do not use this bit. */
1376 DINIT(bug("[ATA%02ld] - 48bit I/O\n", unit->au_UnitNum));
1377 unit->au_XferModes |= AF_XFER_48BIT;
1380 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1382 DINIT(bug("[ATA%02ld] - LBA Addressing\n", unit->au_UnitNum));
1383 unit->au_XferModes |= AF_XFER_LBA;
1385 else
1387 DINIT(bug("[ATA%02ld] - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1390 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1392 DINIT(bug("[ATA%02ld] - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1393 unit->au_XferModes |= AF_XFER_RWMULTI;
1396 if (unit->au_Drive->id_PIOSupport & 0xff)
1398 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1399 for (iter=0; iter<8; iter++)
1401 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1403 DINIT(bug("PIO%ld ", iter));
1404 unit->au_XferModes |= AF_XFER_PIO(iter);;
1407 DINIT(bug("\n"));
1410 if (unit->au_Drive->id_Capabilities & (1<<8))
1412 DINIT(bug("[ATA%02ld] DMA:\n", unit->au_UnitNum));
1413 if (unit->au_Drive->id_MWDMASupport & 0xff)
1415 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1416 for (iter=0; iter<8; iter++)
1418 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1420 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1421 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1423 DINIT(bug("[MDMA%ld] ", iter));
1425 else
1427 DINIT(bug("MDMA%ld ", iter));
1431 DINIT(bug("\n"));
1434 if (unit->au_Drive->id_UDMASupport & 0xff)
1436 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1437 for (iter=0; iter<8; iter++)
1439 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1441 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1442 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1444 DINIT(bug("[UDMA%ld] ", iter));
1446 else
1448 DINIT(bug("UDMA%ld ", iter));
1452 DINIT(bug("\n"));
1457 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1458 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1459 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1461 ULONG atapi_Identify(struct ata_Unit* unit)
1463 ata_CommandBlock acb =
1465 ATA_IDENTIFY_ATAPI,
1471 unit->au_Drive,
1472 sizeof(struct DriveIdent),
1474 CM_PIORead,
1475 CT_NoBlock
1478 ata_SelectUnit(unit);
1480 if (ata_exec_cmd(unit, &acb))
1482 return IOERR_OPENFAIL;
1485 #if (AROS_BIG_ENDIAN != 0)
1486 SWAP_LE_WORD(unit->au_Drive->id_General);
1487 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1488 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1489 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1490 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1491 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1492 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1493 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1494 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1495 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1496 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1497 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1498 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1499 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1500 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1501 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1502 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1503 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1504 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1505 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1506 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1507 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1508 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1509 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1510 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1511 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1512 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1513 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1514 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1515 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1516 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1517 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1518 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1519 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1520 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1521 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1522 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1523 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1524 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1525 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1526 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1527 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1528 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1530 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1531 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1532 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1534 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1535 #endif
1538 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1540 unit->au_SectorShift = 11;
1541 unit->au_Read32 = atapi_Read;
1542 unit->au_Write32 = atapi_Write;
1543 unit->au_DirectSCSI = atapi_DirectSCSI;
1544 unit->au_Eject = atapi_Eject;
1545 unit->au_Flags = AF_DiscChanged;
1546 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1547 unit->au_XferModes = AF_XFER_PACKET;
1549 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1550 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1551 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1553 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1554 common_DetectXferModes(unit);
1555 common_SetBestXferMode(unit);
1557 if (unit->au_Drive->id_General & 0x80)
1559 DINIT(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1560 unit->au_Flags |= AF_Removable;
1563 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1564 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1565 bug("[ATA%02ld] 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));
1568 * ok, this is not very original, but quite compatible :P
1570 switch (unit->au_DevType)
1572 case DG_CDROM:
1573 case DG_WORM:
1574 case DG_OPTICAL_DISK:
1575 unit->au_SectorShift = 11;
1576 unit->au_Heads = 1;
1577 unit->au_Sectors = 75;
1578 unit->au_Cylinders = 4440;
1579 break;
1581 case DG_DIRECT_ACCESS:
1582 unit->au_SectorShift = 9;
1583 if (!strcmp("LS-120", &unit->au_Model[0]))
1585 unit->au_Heads = 2;
1586 unit->au_Sectors = 18;
1587 unit->au_Cylinders = 6848;
1589 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1591 unit->au_Heads = 1;
1592 unit->au_Sectors = 64;
1593 unit->au_Cylinders = 3072;
1595 break;
1598 atapi_TestUnitOK(unit);
1600 return 0;
1603 ULONG ata_Identify(struct ata_Unit* unit)
1605 ata_CommandBlock acb =
1607 ATA_IDENTIFY_DEVICE,
1613 unit->au_Drive,
1614 sizeof(struct DriveIdent),
1616 CM_PIORead,
1617 CT_NoBlock
1620 if (ata_exec_cmd(unit, &acb))
1622 return IOERR_OPENFAIL;
1625 #if (AROS_BIG_ENDIAN != 0)
1626 SWAP_LE_WORD(unit->au_Drive->id_General);
1627 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1628 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1629 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1630 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1631 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1632 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1633 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1634 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1635 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1636 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1637 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1638 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1639 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1640 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1641 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1642 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1643 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1644 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1645 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1646 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1647 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1648 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1649 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1650 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1651 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1652 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1653 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1654 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1655 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1656 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1657 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1658 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1659 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1660 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1661 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1662 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1663 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1664 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1665 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1666 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1667 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1668 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1670 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1671 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1672 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1674 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1675 #endif
1677 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1679 unit->au_SectorShift = 9;
1680 unit->au_DevType = DG_DIRECT_ACCESS;
1681 unit->au_Read32 = ata_ReadSector32;
1682 unit->au_Write32 = ata_WriteSector32;
1683 unit->au_DirectSCSI = atapi_DirectSCSI;
1684 unit->au_Eject = ata_Eject;
1685 unit->au_XferModes = 0;
1686 unit->au_Flags |= AF_DiscPresent | AF_DiscChanged;
1687 unit->au_DevType = DG_DIRECT_ACCESS;
1689 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1690 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1691 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1693 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1694 common_DetectXferModes(unit);
1695 common_SetBestXferMode(unit);
1697 if (unit->au_Drive->id_General & 0x80)
1699 DINIT(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1700 unit->au_Flags |= AF_Removable;
1703 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1704 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1705 bug("[ATA%02ld] 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));
1708 For drive capacities > 8.3GB assume maximal possible layout.
1709 It really doesn't matter here, as BIOS will not handle them in
1710 CHS way anyway :)
1711 i guess this just solves that weirdo div-by-zero crash, if anything else...
1713 if ((unit->au_Drive->id_LBA48Sectors > (63 * 255 * 1024)) ||
1714 (unit->au_Drive->id_LBASectors > (63 * 255 * 1024)))
1716 ULONG div = 1;
1718 * TODO: this shouldn't be casted down here.
1720 ULONG sec = unit->au_Capacity48;
1722 if (sec < unit->au_Capacity48)
1723 sec = ~0ul;
1725 if (sec < unit->au_Capacity)
1726 sec = unit->au_Capacity;
1728 unit->au_Sectors = 63;
1729 sec /= 63;
1731 * keep dividing by 2
1735 if (((sec >> 1) << 1) != sec)
1736 break;
1737 if ((div << 1) > 255)
1738 break;
1739 div <<= 1;
1740 sec >>= 1;
1741 } while (1);
1745 if (((sec / 3) * 3) != sec)
1746 break;
1747 if ((div * 3) > 255)
1748 break;
1749 div *= 3;
1750 sec /= 3;
1751 } while (1);
1753 unit->au_Cylinders = sec;
1754 unit->au_Heads = div;
1756 else
1758 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1759 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1760 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1762 return 0;
1767 * ata read32 commands
1769 static ULONG ata_ReadSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1771 ata_CommandBlock acb =
1773 ATA_READ,
1777 block,
1778 count,
1779 buffer,
1780 count << unit->au_SectorShift,
1782 CM_PIORead,
1783 CT_LBA28
1785 register ULONG err;
1787 *act = 0;
1788 if (0 != (err = ata_exec_blk(unit, &acb)))
1789 return err;
1791 *act = count << unit->au_SectorShift;
1792 return 0;
1795 static ULONG ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1797 ata_CommandBlock acb =
1799 ATA_READ_MULTIPLE,
1801 unit->au_Drive->id_RWMultipleSize & 0xff,
1803 block,
1804 count,
1805 buffer,
1806 count << unit->au_SectorShift,
1808 CM_PIORead,
1809 CT_LBA28
1811 register ULONG err;
1813 *act = 0;
1814 if (0 != (err = ata_exec_blk(unit, &acb)))
1815 return err;
1817 *act = count << unit->au_SectorShift;
1818 return 0;
1821 static ULONG ata_ReadDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1823 register ULONG err;
1824 ata_CommandBlock acb =
1826 ATA_READ_DMA,
1830 block,
1831 count,
1832 buffer,
1833 count << unit->au_SectorShift,
1835 CM_DMARead,
1836 CT_LBA28
1839 *act = 0;
1840 if (0 != (err = ata_exec_blk(unit, &acb)))
1841 return err;
1843 *act = count << unit->au_SectorShift;
1844 return 0;
1849 * ata read64 commands
1851 static ULONG ata_ReadSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1853 ata_CommandBlock acb =
1855 ATA_READ64,
1859 block,
1860 count,
1861 buffer,
1862 count << unit->au_SectorShift,
1864 CM_PIORead,
1865 CT_LBA48
1867 register ULONG err = 0;
1869 *act = 0;
1870 if (0 != (err = ata_exec_blk(unit, &acb)))
1871 return err;
1873 *act = count << unit->au_SectorShift;
1874 return 0;
1877 static ULONG ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1879 ata_CommandBlock acb =
1881 ATA_READ_MULTIPLE64,
1883 unit->au_Drive->id_RWMultipleSize & 0xff,
1885 block,
1886 count,
1887 buffer,
1888 count << unit->au_SectorShift,
1890 CM_PIORead,
1891 CT_LBA48
1893 register ULONG err;
1895 *act = 0;
1896 if (0 != (err = ata_exec_blk(unit, &acb)))
1897 return err;
1899 *act = count << unit->au_SectorShift;
1900 return 0;
1903 static ULONG ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1905 ata_CommandBlock acb =
1907 ATA_READ_DMA64,
1911 block,
1912 count,
1913 buffer,
1914 count << unit->au_SectorShift,
1916 CM_DMARead,
1917 CT_LBA48
1919 register ULONG err;
1921 *act = 0;
1922 if (0 != (err = ata_exec_blk(unit, &acb)))
1923 return err;
1925 *act = count << unit->au_SectorShift;
1926 return 0;
1931 * ata write32 commands
1933 static ULONG ata_WriteSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1935 ata_CommandBlock acb =
1937 ATA_WRITE,
1941 block,
1942 count,
1943 buffer,
1944 count << unit->au_SectorShift,
1946 CM_PIOWrite,
1947 CT_LBA28
1949 register ULONG err;
1951 *act = 0;
1952 if (0 != (err = ata_exec_blk(unit, &acb)))
1953 return err;
1955 *act = count << unit->au_SectorShift;
1956 return 0;
1959 static ULONG ata_WriteMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1961 ata_CommandBlock acb =
1963 ATA_WRITE_MULTIPLE,
1965 unit->au_Drive->id_RWMultipleSize & 0xff,
1967 block,
1968 count,
1969 buffer,
1970 count << unit->au_SectorShift,
1972 CM_PIOWrite,
1973 CT_LBA28
1975 register ULONG err;
1977 *act = 0;
1978 if (0 != (err = ata_exec_blk(unit, &acb)))
1979 return err;
1981 *act = count << unit->au_SectorShift;
1982 return 0;
1985 static ULONG ata_WriteDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1987 ata_CommandBlock acb =
1989 ATA_WRITE_DMA,
1993 block,
1994 count,
1995 buffer,
1996 count << unit->au_SectorShift,
1998 CM_DMAWrite,
1999 CT_LBA28
2001 register ULONG err;
2003 *act = 0;
2004 if (0 != (err = ata_exec_blk(unit, &acb)))
2005 return err;
2007 *act = count << unit->au_SectorShift;
2008 return 0;
2013 * ata write64 commands
2015 static ULONG ata_WriteSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2017 ata_CommandBlock acb =
2019 ATA_WRITE64,
2023 block,
2024 count,
2025 buffer,
2026 count << unit->au_SectorShift,
2028 CM_PIOWrite,
2029 CT_LBA48
2031 register ULONG err;
2033 *act = 0;
2034 if (0 != (err = ata_exec_blk(unit, &acb)))
2035 return err;
2037 *act = count << unit->au_SectorShift;
2038 return 0;
2041 static ULONG ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2043 ata_CommandBlock acb =
2045 ATA_WRITE_MULTIPLE64,
2047 unit->au_Drive->id_RWMultipleSize & 0xff,
2049 block,
2050 count,
2051 buffer,
2052 count << unit->au_SectorShift,
2054 CM_PIOWrite,
2055 CT_LBA48
2057 register ULONG err;
2059 *act = 0;
2060 if (0 != (err = ata_exec_blk(unit, &acb)))
2061 return err;
2063 *act = count << unit->au_SectorShift;
2064 return 0;
2067 static ULONG ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2069 ata_CommandBlock acb =
2071 ATA_WRITE_DMA64,
2075 block,
2076 count,
2077 buffer,
2078 count << unit->au_SectorShift,
2080 CM_DMAWrite,
2081 CT_LBA48
2083 register ULONG err;
2085 *act = 0;
2086 if (0 != (err = ata_exec_blk(unit, &acb)))
2087 return err;
2089 *act = count << unit->au_SectorShift;
2090 return 0;
2094 * ata miscellaneous commands
2096 static ULONG ata_Eject(struct ata_Unit *unit)
2098 ata_CommandBlock acb =
2100 ATA_MEDIA_EJECT,
2109 CM_NoData,
2110 CT_NoBlock
2113 return ata_exec_cmd(unit, &acb);
2117 * atapi commands
2119 int atapi_TestUnitOK(struct ata_Unit *unit)
2121 UBYTE cmd[6] = {
2124 UBYTE sense[16] = {
2127 struct SCSICmd sc = {
2131 sc.scsi_Command = (void*) &cmd;
2132 sc.scsi_CmdLength = sizeof(cmd);
2133 sc.scsi_SenseData = (void*)&sense;
2134 sc.scsi_SenseLength = sizeof(sense);
2135 sc.scsi_Flags = SCSIF_AUTOSENSE;
2137 unit->au_DirectSCSI(unit, &sc);
2138 unit->au_SenseKey = sense[2];
2141 * we may have just lost the disc...?
2144 * per MMC, drives are expected to return 02-3a-0# status, when disc is not present
2145 * that would translate into following code:
2146 * int p1 = ((sense[2] == 2) && (sense[12] == 0x3a)) ? 1 : 0;
2147 * unfortunately, it's what MMC says, not what vendors code.
2149 int p1 = (sense[2] == 2) ? 1 : 0;
2150 int p2 = (0 != (AF_DiscPresent & unit->au_Flags)) ? 1 : 0;
2152 if (p1 == p2)
2154 //unit->au_Flags ^= AF_DiscPresent;
2155 if (p1 == 0)
2156 unit->au_Flags |= AF_DiscPresent;
2157 else
2158 unit->au_Flags &= ~AF_DiscPresent;
2160 unit->au_Flags |= AF_DiscChanged;
2163 DATAPI(bug("[ATA%02ld] Test Unit Ready sense: %02lx, Media %s\n", unit->au_UnitNum, sense[2], unit->au_Flags & AF_DiscPresent ? "PRESENT" : "ABSENT"));
2164 return sense[2];
2167 static ULONG atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2169 UBYTE cmd[] = {
2170 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2172 struct SCSICmd sc = {
2176 sc.scsi_Command = (void*) &cmd;
2177 sc.scsi_CmdLength = sizeof(cmd);
2178 sc.scsi_Data = buffer;
2179 sc.scsi_Length = count << unit->au_SectorShift;
2180 sc.scsi_Flags = SCSIF_READ;
2182 return unit->au_DirectSCSI(unit, &sc);
2185 static ULONG atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2187 UBYTE cmd[] = {
2188 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2190 struct SCSICmd sc = {
2194 sc.scsi_Command = (void*) &cmd;
2195 sc.scsi_CmdLength = sizeof(cmd);
2196 sc.scsi_Data = buffer;
2197 sc.scsi_Length = count << unit->au_SectorShift;
2198 sc.scsi_Flags = SCSIF_WRITE;
2200 return unit->au_DirectSCSI(unit, &sc);
2203 static ULONG atapi_Eject(struct ata_Unit *unit)
2205 struct atapi_StartStop cmd = {
2206 command: SCSI_STARTSTOP,
2207 immediate: 1,
2208 flags: ATAPI_SS_EJECT,
2211 struct SCSICmd sc = {
2215 sc.scsi_Command = (void*) &cmd;
2216 sc.scsi_CmdLength = sizeof(cmd);
2217 sc.scsi_Flags = SCSIF_READ;
2219 return unit->au_DirectSCSI(unit, &sc);
2222 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2224 UBYTE cmd[] = {
2225 3, 0, 0, 0, senselen & 0xfe, 0
2227 struct SCSICmd sc = {
2231 if ((senselen == 0) || (sense == 0))
2233 return 0;
2235 sc.scsi_Data = (void*)sense;
2236 sc.scsi_Length = senselen & 0xfe;
2237 sc.scsi_Command = (void*)&cmd;
2238 sc.scsi_CmdLength = 6;
2239 sc.scsi_Flags = SCSIF_READ;
2241 unit->au_DirectSCSI(unit, &sc);
2243 DATAPI(dump(sense, senselen));
2244 DATAPI(bug("[SENSE] sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2245 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2248 ULONG ata_ReadSignature(struct ata_Bus *bus, int unit)
2250 ULONG port = bus->ab_Port;
2251 UBYTE tmp1, tmp2;
2253 /* Check basic signature. All live devices should provide it */
2254 tmp1 = ata_in(ata_Count, port);
2255 tmp2 = ata_in(ata_LBALow, port);
2256 DINIT(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2258 DINIT(bug("[ATA ] Status %08lx Device %08lx\n", ata_in(ata_Status, port), ata_in(ata_DevHead, port)));
2260 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2262 /* Ok, ATA/ATAPI device. Get detailed signature */
2263 DINIT(bug("[ATA ] Found an ATA[PI] Device. Attempting to detect specific subtype\n"));
2265 tmp1 = ata_in(ata_LBAMid, port);
2266 tmp2 = ata_in(ata_LBAHigh, port);
2268 DINIT(bug("[ATA ] Subtype check returned %02lx:%02lx (%04lx)\n", tmp1, tmp2, (tmp1 << 8) | tmp2));
2271 switch ((tmp1 << 8) | tmp2)
2273 case 0x0000:
2274 if (0 == (ata_ReadStatus(bus) & 0xfe))
2275 return DEV_NONE;
2276 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2277 ata_out(ATA_EXECUTE_DIAG, ata_Command, port);
2278 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2280 while (ata_ReadStatus(bus) & ATAF_BUSY)
2281 ata_400ns();
2283 DINIT(bug("[ATA ] Further validating ATA signature: %lx & 0x7f = 1, %lx & 0x10 = unit\n", ata_in(ata_Error, port), ata_in(ata_DevHead, port)));
2285 if ((1 == (0x7f & ata_in(ata_Error, port))) &&
2286 (unit == ((ata_in(ata_DevHead, port) >> 4) & 1)))
2288 DINIT(bug("[ATA ] Found *valid* signature for ATA device\n"));
2289 return DEV_ATA;
2291 return DEV_NONE;
2293 case 0x14eb:
2294 DINIT(bug("[ATA ] Found signature for ATAPI device\n"));
2295 return DEV_ATAPI;
2297 case 0x3cc3:
2298 DINIT(bug("[ATA ] Found signature for SATA device\n"));
2299 return DEV_SATA;
2301 case 0x6996:
2302 DINIT(bug("[ATA ] Found signature for SATAPI device\n"));
2303 return DEV_SATAPI;
2305 default:
2306 if (((tmp1 | tmp2) == 0xff) &&
2307 ((tmp1 & tmp2) == 0x00))
2309 bug("[ATA ] Found valid subtype, but don't know how to handle this device: %02lx %02lx\n", tmp1, tmp2);
2311 else
2313 bug("[ATA ] Invalid signature: %02lx %02lx\n", tmp1, tmp2);
2315 return DEV_NONE;
2319 return DEV_NONE;
2322 void ata_ResetBus(struct timerequest *tr, struct ata_Bus *bus)
2324 ULONG alt = bus->ab_Alt;
2325 ULONG port = bus->ab_Port;
2326 int id;
2329 * issue and clear the software reset signal
2331 /* at this time both devices should report ready immediately */
2332 for (id = 0; id < 2; id++)
2334 if (DEV_NONE != bus->ab_Dev[id])
2336 ata_out(0xa0 | (id << 4), ata_DevHead, port);
2337 ata_400ns();
2339 ata_out(0x04, ata_AltControl, alt);
2340 ata_usleep(tr, 10); /* minimum required: 5us */
2341 ata_out(0x02, ata_AltControl, alt);
2342 ata_usleep(tr, 20000); /* minimum required: 2ms */
2344 ata_out(0xa0 | (id << 4), ata_DevHead, port);
2345 ata_400ns();
2347 while (0 != (ata_in(ata_Status, port) & ATAF_BUSY))
2348 ata_usleep(tr, 200);
2350 bus->ab_Dev[id] = ata_ReadSignature(bus, id);
2356 * --------------------------------------------------------------
2357 * - here ends the code that makes any sense. rest to be removed -
2358 * --------------------------------------------------------------
2362 void ata_usleep(struct timerequest *tr, ULONG usec)
2364 tr->tr_node.io_Command = TR_ADDREQUEST;
2365 tr->tr_time.tv_micro = usec % 1000000;
2366 tr->tr_time.tv_secs = usec / 1000000;
2368 DoIO((struct IORequest *)tr);
2372 Device scan routines - TO BE REPLACED
2375 * same here
2377 void ata_InitBus(struct ata_Bus *bus)
2379 ULONG port = bus->ab_Port;
2380 UBYTE tmp1, tmp2;
2382 struct MsgPort *p = CreateMsgPort();
2383 struct timerequest *tr = (struct timerequest *)CreateIORequest((struct MsgPort *)p,
2384 sizeof(struct timerequest));
2385 OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0);
2387 bus->ab_Dev[0] = DEV_NONE;
2388 bus->ab_Dev[1] = DEV_NONE;
2390 /* Disable IDE IRQ */
2391 ata_EnableIRQ(bus, FALSE);
2393 /* Select device 0 */
2394 ata_out(0xa0, ata_DevHead, port);
2395 ata_usleep(tr, 100);
2397 /* Write some pattern to registers */
2398 ata_out(0x55, ata_Count, port);
2399 ata_out(0xaa, ata_LBALow, port);
2400 ata_out(0xaa, ata_Count, port);
2401 ata_out(0x55, ata_LBALow, port);
2402 ata_out(0x55, ata_Count, port);
2403 ata_out(0xaa, ata_LBALow, port);
2405 tmp1 = ata_in(ata_Count, port);
2406 tmp2 = ata_in(ata_LBALow, port);
2408 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2409 bus->ab_Dev[0] = DEV_UNKNOWN;
2411 /* Select device 1 */
2412 ata_out(0xb0, ata_DevHead, port);
2413 ata_usleep(tr, 100);
2415 /* Write some pattern to registers */
2416 ata_out(0x55, ata_Count, port);
2417 ata_out(0xaa, ata_LBALow, port);
2418 ata_out(0xaa, ata_Count, port);
2419 ata_out(0x55, ata_LBALow, port);
2420 ata_out(0x55, ata_Count, port);
2421 ata_out(0xaa, ata_LBALow, port);
2423 tmp1 = ata_in(ata_Count, port);
2424 tmp2 = ata_in(ata_LBALow, port);
2426 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2427 bus->ab_Dev[1] = DEV_UNKNOWN;
2429 ata_ResetBus(tr, bus);
2431 CloseDevice((struct IORequest *)tr);
2432 DeleteIORequest((struct IORequest *)tr);
2433 DeleteMsgPort(p);
2437 * not really sure what this is meant to be - TO BE REPLACED
2439 static const ULONG ErrorMap[] = {
2440 CDERR_NotSpecified,
2441 CDERR_NoSecHdr,
2442 CDERR_NoDisk,
2443 CDERR_NoSecHdr,
2444 CDERR_NoSecHdr,
2445 CDERR_NOCMD,
2446 CDERR_NoDisk,
2447 CDERR_WriteProt,
2448 CDERR_NotSpecified,
2449 CDERR_NotSpecified,
2450 CDERR_NotSpecified,
2451 CDERR_ABORTED,
2452 CDERR_NotSpecified,
2453 CDERR_NotSpecified,
2454 CDERR_NoSecHdr,
2455 CDERR_NotSpecified,
2458 static ULONG atapi_EndCmd(struct ata_Unit *unit)
2460 UBYTE status;
2463 * read alternate status register (per specs)
2465 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2466 DATAPI(bug("[ATAPI] Alternate status: %lx\n", status));
2468 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2470 DATAPI(bug("[ATAPI] Command complete. Status: %lx\n", status));
2472 if (!(status & ATAPIF_CHECK))
2474 return 0;
2476 else
2478 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2479 DATAPI(bug("[ATAPI] Error code %lx\n", status >> 4));
2480 return ErrorMap[status >> 4];
2485 * vim: ts=4 et sw=4 fdm=marker fmr={,}