Added 400ns delay in ata_WaitBusyTO before read of device status.
[tangerine.git] / arch / common / ata.device / lowlevel.c
blob0ba54bdd9c7ff0df3e8299bef061fe03f58ce1db
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.
53 * TODO:
54 * - put a critical section around DMA transfers (shared dma channels)
57 #define DEBUG 0
58 // use #define xxx(a) D(a) to enable particular sections.
59 #define DIRQ(a)
60 #define DIRQ_MORE(a)
61 #define DUMP(a)
62 #define DATA(a)
63 #define DATAPI(a)
64 #define DINIT(a) D(a)
66 #include <aros/debug.h>
67 #include <exec/types.h>
68 #include <exec/exec.h>
69 #include <exec/resident.h>
70 #include <utility/utility.h>
71 #include <oop/oop.h>
73 #include <dos/bptr.h>
75 #include <proto/exec.h>
76 #include <devices/timer.h>
78 #include <asm/io.h>
80 #include "ata.h"
85 Prototypes of static functions from lowlevel.c. I do not want to make them
86 non-static as I'd like to remove as much symbols from global table as possible.
87 Besides some of this functions could conflict with old ide.device or any other
88 device.
90 static ULONG ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
91 static ULONG ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
92 static ULONG ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
93 static ULONG ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
94 static ULONG ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
95 static ULONG ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
96 static ULONG ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
97 static ULONG ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
98 static ULONG ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
99 static ULONG ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
100 static ULONG ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
101 static ULONG ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
102 static ULONG ata_Eject(struct ata_Unit *);
103 static BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq);
105 static ULONG atapi_EndCmd(struct ata_Unit *unit);
107 static ULONG atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
108 static ULONG atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
109 static ULONG atapi_Eject(struct ata_Unit *);
111 static void common_SetBestXferMode(struct ata_Unit* unit);
114 Again piece of code which shouldn't be here. Geee. After removing all this
115 asm constrictuins this ata.device will really deserve for location in
116 /arch/common
119 * having an x86 assembly here i dare to assume that this is meant to be
120 * an x86[_64] device only.
122 * Not anymore.
124 * This functions will stay here for some time *IF* and only if the code is compiled for
125 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
126 * one who ports the driver will be reponsible for adding the missing code.
130 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
132 #if defined(__i386__) || defined(__x86_64__)
134 static VOID ata_insw(APTR address, UWORD port, ULONG count)
136 insw(port, address, count >> 1);
139 static VOID ata_insl(APTR address, UWORD port, ULONG count)
141 if (count & 2)
142 insw(port, address, count >> 1);
143 else
144 insl(port, address, count >> 2);
147 static VOID ata_outsw(APTR address, UWORD port, ULONG count)
149 outsw(port, address, count >> 1);
152 static VOID ata_outsl(APTR address, UWORD port, ULONG count)
154 if (count & 2)
155 outsw(port, address, count >> 1);
156 else
157 outsl(port, address, count >> 2);
161 * Very short delay (TM) by someone who assumes slow data ports.
162 * well, glad it works anyways.
164 void ata_400ns()
166 ata_in(ata_AltControl, 0x3f6);
167 ata_in(ata_AltControl, 0x3f6);
168 ata_in(ata_AltControl, 0x3f6);
169 ata_in(ata_AltControl, 0x3f6);
172 #else
173 extern VOID ata_insw(APTR address, UWORD port, ULONG count);
174 extern VOID ata_insl(APTR address, UWORD port, ULONG count);
175 extern VOID ata_outsw(APTR address, UWORD port, ULONG count);
176 extern VOID ata_outsl(APTR address, UWORD port, ULONG count);
177 extern void ata_400ns();
178 #endif
180 static void dump(APTR mem, ULONG len)
182 register int i,j;
183 for (j=0; j<(len+15)>>4; ++j)
185 bug("[ATA ] %06lx: ", j<<4);
187 for (i=0; i<len-(j<<4); i++)
189 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
190 if (i == 15)
191 break;
194 for (i=0; i<len-(j<<4); i++)
196 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
198 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
199 if (i == 15)
200 break;
202 bug("\n");
206 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
208 register int i = size;
210 while (size--)
212 str2[size^1] = str1[size];
215 while (i--)
217 if (str2[i] <= ' ')
218 str2[i] = 0;
224 * a STUB function for commands not supported by this particular device
226 static ULONG ata_STUB(struct ata_Unit *au)
228 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
229 return CDERR_NOCMD;
232 static ULONG ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len, APTR buf, ULONG* act)
234 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
235 return CDERR_NOCMD;
238 static ULONG ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len, APTR buf, ULONG* act)
240 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);
241 return CDERR_NOCMD;
244 static ULONG ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
246 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum);
247 return CDERR_NOCMD;
250 inline BOOL ata_SelectUnit(struct ata_Unit* unit)
252 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
256 ata_400ns();
258 while (0 != (ATAF_BUSY & ata_ReadStatus(unit->au_Bus)));
260 return TRUE;
263 inline struct ata_Unit* ata_GetSelectedUnit(struct ata_Bus* bus)
265 register int id = (ata_in(ata_DevHead, bus->ab_Port) & 0x10) >> 4;
266 return bus->ab_Units[id];
269 UBYTE ata_ReadStatus(struct ata_Bus *bus)
271 return ata_in(ata_Status, bus->ab_Port);
275 * enable / disable IRQ; this manages interrupt requests more effectively in case of legacy emulation
276 * as little code as there can be. and keep it that way.
278 void ata_EnableIRQ(struct ata_Bus *bus, BOOL enable)
280 enable &= (bus->ab_Dev[0] > DEV_UNKNOWN) || (bus->ab_Dev[1] > DEV_UNKNOWN);
281 bug("[ATA ] IRQ: Setting IRQ flag for bus %ld to %s\n", bus->ab_BusNum, enable ? "ENABLED" : "DISABLED");
282 bus->ab_IRQ = enable;
283 ata_out(enable ? 0x0 : 0x02, ata_AltControl, bus->ab_Alt);
287 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
288 * part of code moved here from ata.c to reduce containment
290 void ata_IRQSignalTask(struct ata_Bus *bus)
292 bus->ab_IntCnt++;
293 Signal(bus->ab_Task, 1UL << bus->ab_SleepySignal);
296 void ata_HandleIRQ(struct ata_Bus *bus)
298 struct ata_Unit *u = ata_GetSelectedUnit(bus);
299 UBYTE status = ata_ReadStatus(bus);
301 * don't waste your time on checking other devices.
302 * pass irq ONLY if task is expecting one;
305 if (0 != bus->ab_HandleIRQ)
308 * ok, we have a routine to handle any form of transmission etc
310 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
311 bus->ab_HandleIRQ(u, status);
312 return;
315 DIRQ_MORE({
317 * if we got *here* then device is most likely not expected to have an irq.
319 bug("[ATA%02ld] IRQ: Checking busy flag: ", u->au_UnitNum);
321 if (0 == (ATAF_BUSY & status))
323 bug("device ready. Dumping details:\n");
325 bug("[ATA ] STATUS: %02lx\n", status);
326 bug("[ATA ] ALT STATUS: %02lx\n", ata_in(ata_AltStatus, bus->ab_Alt));
327 bug("[ATA ] ERROR: %02lx\n", ata_in(ata_Error, bus->ab_Port));
328 bug("[ATA ] IRQ: REASON: %02lx\n", ata_in(atapi_Reason, bus->ab_Port));
330 else
332 bug("device still busy. ignoring irq.\n");
337 void ata_IRQSetHandler(struct ata_Unit *unit, void (*handler)(struct ata_Unit*, UBYTE), APTR piomem, ULONG piolen)
339 if (NULL != handler)
340 unit->au_cmd_error = 0;
342 unit->au_cmd_data = piomem;
343 unit->au_cmd_length = piolen;
344 unit->au_Bus->ab_HandleIRQ = handler;
347 void ata_IRQNoData(struct ata_Unit *unit, UBYTE status)
349 if (status & ATAF_BUSY)
350 return;
352 if ((unit->au_cmd_error == 0) && (status & ATAF_ERROR))
353 unit->au_cmd_error = HFERR_BadStatus;
355 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit->au_UnitNum, status));
356 ata_IRQSetHandler(unit, NULL, NULL, 0);
357 ata_IRQSignalTask(unit->au_Bus);
360 void ata_IRQPIORead(struct ata_Unit *unit, UBYTE status)
362 if (status & ATAF_ERROR)
363 ata_IRQNoData(unit, status);
364 if (status & ATAF_DATAREQ)
365 unit->au_ins(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
367 DIRQ(bug("[ATA ] IRQ: PIOReadData - done.\n"));
369 * indicate it's all done here
371 unit->au_cmd_length = 0;
372 ata_IRQNoData(unit, status);
375 void ata_IRQPIOWrite(struct ata_Unit *unit, UBYTE status)
377 if (status & ATAF_ERROR)
378 ata_IRQNoData(unit, status);
379 if (status & ATAF_DATAREQ)
380 unit->au_outs(unit->au_cmd_data, unit->au_Bus->ab_Port, unit->au_cmd_length);
382 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
384 * indicate it's all done here
386 unit->au_cmd_length = 0;
387 ata_IRQNoData(unit, status);
390 void ata_IRQDMAReadWrite(struct ata_Unit *au, UBYTE status)
392 UBYTE stat = ata_in(dma_Status, au->au_DMAPort);
393 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat));
395 if (0 == (stat & DMAF_Interrupt))
397 bug("[ATA ] IRQ: Fake IRQ.\n");
399 else if ((status & ATAF_ERROR) || (stat & DMAF_Error))
401 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au->au_UnitNum, status, stat));
402 DIRQ(bug("[ATA%02ld] IRQ: ERROR %02lx\n", au->au_UnitNum, ata_in(atapi_Error, au->au_Bus->ab_Port)));
403 bug("[ATA ] IRQ: DMA Failed.\n");
404 au->au_cmd_error = HFERR_DMA;
405 ata_IRQNoData(au, status);
407 else if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
409 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
410 ata_IRQNoData(au, status);
414 void ata_IRQPIOReadAtapi(struct ata_Unit *unit, UBYTE status)
416 ULONG port = unit->au_Bus->ab_Port;
417 ULONG size = 0;
418 UBYTE reason = ata_in(atapi_Reason, port);
419 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason));
421 /* have we failed yet? */
422 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
423 ata_IRQNoData(unit, status);
424 if (status & ATAF_ERROR)
425 ata_IRQNoData(unit, status);
427 /* anything for us please? */
428 if (ATAPIF_READ != (reason & ATAPIF_MASK))
429 return;
431 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
432 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_length));
434 if (size > unit->au_cmd_length)
436 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_length);
437 size = unit->au_cmd_length;
440 unit->au_ins(unit->au_cmd_data, port, size);
441 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
442 unit->au_cmd_length -= size;
444 DIRQ(bug("[ATAPI] IRQ: %lu bytes read.\n", size));
446 if (unit->au_cmd_length == 0)
447 ata_IRQNoData(unit, status);
450 void ata_IRQPIOWriteAtapi(struct ata_Unit *unit, UBYTE status)
452 ULONG port = unit->au_Bus->ab_Port;
453 ULONG size = 0;
454 UBYTE reason = ata_in(atapi_Reason, port);
455 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason));
457 /* have we failed yet? */
458 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
459 ata_IRQNoData(unit, status);
460 if (status & ATAF_ERROR)
461 ata_IRQNoData(unit, status);
463 /* anything for us please? */
464 if (ATAPIF_READ != (reason & ATAPIF_MASK))
465 return;
467 size = ata_in(atapi_ByteCntH, port) << 8 | ata_in(atapi_ByteCntL, port);
468 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size, unit->au_cmd_length));
470 if (size > unit->au_cmd_length)
472 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size, unit->au_cmd_length);
473 size = unit->au_cmd_length;
476 unit->au_outs(unit->au_cmd_data, port, size);
477 unit->au_cmd_data = &((UBYTE*)unit->au_cmd_data)[size];
478 unit->au_cmd_length -= size;
480 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size));
482 if (unit->au_cmd_length == 0)
483 ata_IRQNoData(unit, status);
487 * wait for timeout or drive ready
488 * polling-in-a-loop, but it should be safe to remove this already
490 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq)
492 UBYTE status;
493 ULONG sigs = SIGBREAKF_CTRL_C;
494 ULONG step = 0;
495 BOOL res = TRUE;
497 if (irq && !unit->au_Bus->ab_IRQ)
499 bug("[ATA ] Requested IRQ wait, but IRQ is not enabled\n");
502 irq &= unit->au_Bus->ab_IRQ;
503 sigs |= (irq ? (1 << unit->au_Bus->ab_SleepySignal) : 0);
506 * clear up all old signals
508 SetSignal(0, sigs);
511 * set up bus timeout and irq
513 Disable();
514 unit->au_Bus->ab_Timeout = tout;
515 Enable();
518 * this loop may experience one of two scenarios
519 * 1) we get a valid irq and the drive wanted to let us know that it's ready
520 * 2) we get an invalid irq due to some collissions. We may still want to go ahead and get some extra irq breaks
521 * this would reduce system load a little
528 * delay the check - this was found needed for some hardware
531 ata_400ns();
534 * lets check if the drive is already good
536 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
537 if (0 == (status & (ATAF_DATAREQ | ATAF_BUSY)))
538 break;
541 * so we're stuck in a loop?
543 DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", unit->au_UnitNum, status));
546 * if IRQ wait is requested then allow either timeout or irq;
547 * then clear irq flag so we dont keep receiving more of these (especially when system suffers collissions)
549 if (irq)
552 * wait for either IRQ or TIMEOUT
554 step = Wait(sigs);
557 * now if we did reach timeout, then there's no point in going ahead.
559 if (SIGBREAKB_CTRL_C & step)
561 bug("[ATA%02ld] Timeout while waiting for device to complete operation\n", unit->au_UnitNum);
562 res = FALSE;
566 * if we get as far as this, there's no more signals to expect
567 * but we still want the status
569 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
570 break;
572 else
575 * device not ready just yet. lets set whether we want an IRQ and move on - to polling or irq wait
577 ++step;
580 * every 16n rounds do some extra stuff
582 if ((step & 16) == 0)
585 * huhm. so it's been 16n rounds already. any timeout yet?
587 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
589 DIRQ(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit->au_UnitNum));
590 res = FALSE;
591 break;
595 * no timeout just yet, but it's not a good idea to keep spinning like that.
596 * let's give the system some time.
598 ata_400ns();
599 // TODO: Put some delay here!
602 } while(status & ATAF_BUSY);
605 * be nice to frustrated developer
607 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit->au_UnitNum, status, res));
610 * clear up all our expectations
612 Disable();
613 unit->au_Bus->ab_Timeout = -1;
614 Enable();
617 * release old junk
619 SetSignal(0, sigs);
622 * and say it went fine (i mean it)
624 return res;
628 * just wait for timeout
630 void ata_Wait(struct ata_Unit *unit, UWORD tout)
632 SetSignal(0, SIGBREAKF_CTRL_C);
634 Disable();
635 unit->au_Bus->ab_Timeout = tout;
636 Enable();
638 Wait(SIGBREAKF_CTRL_C);
642 * Procedure for sending ATA command blocks
643 * it appears LARGE but there's a lot of COMMENTS here :)
644 * handles *all* ata commands (no data, pio and dma)
645 * naturally could be splitted at some point in the future
646 * depends if anyone believes that the change for 50 lines
647 * would make slow ATA transfers any faster
649 static ULONG ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
651 ULONG port = au->au_Bus->ab_Port;
652 ULONG err = 0;
653 APTR mem = block->buffer;
655 if (FALSE == ata_SelectUnit(au))
656 return IOERR_UNITBUSY;
658 switch (block->type)
660 case CT_LBA28:
661 if (block->sectors > 256)
663 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
664 return IOERR_BADLENGTH;
667 /* note:
668 * we want the above to fall in here!
669 * we really do (checking for secmul)
672 case CT_LBA48:
673 if (block->sectors > 65536)
675 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
676 return IOERR_BADLENGTH;
678 if (block->secmul == 0)
680 bug("[ATA%02ld] ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
681 block->secmul = 1;
683 break;
685 case CT_NoBlock:
686 break;
688 default:
689 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
690 return IOERR_NOCMD;
693 block->actual = 0;
694 D(bug("[ATA%02ld] Executing command %02lx\n", au->au_UnitNum, block->command));
696 if (block->feature != 0)
697 ata_out(block->feature, ata_Feature, port);
700 * - set LBA and sector count
702 switch (block->type)
704 case CT_LBA28:
705 DATA(bug("[ATA%02ld] Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
706 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
707 ata_out(block->blk >> 16, ata_LBAHigh, port);
708 ata_out(block->blk >> 8, ata_LBAMid, port);
709 ata_out(block->blk, ata_LBALow, port);
710 ata_out(block->sectors, ata_Count, port);
711 break;
713 case CT_LBA48:
714 DATA(bug("[ATA%02ld] Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
715 ata_out(block->blk >> 40, ata_LBAHigh, port);
716 ata_out(block->blk >> 32, ata_LBAMid, port);
717 ata_out(block->blk >> 24, ata_LBALow, port);
719 ata_out(block->blk >> 16, ata_LBAHigh, port);
720 ata_out(block->blk >> 8, ata_LBAMid, port);
721 ata_out(block->blk, ata_LBALow, port);
723 ata_out(block->sectors >> 8, ata_Count, port);
724 ata_out(block->sectors, ata_Count, port);
725 break;
727 case CT_NoBlock:
728 DATA(bug("[ATA%02ld] Command does not address any block\n", au->au_UnitNum));
729 break;
733 switch (block->method)
735 case CM_PIOWrite:
736 ata_IRQSetHandler(au, &ata_IRQPIOWrite, mem, block->length);
737 break;
739 case CM_PIORead:
740 ata_IRQSetHandler(au, &ata_IRQPIORead, mem, block->length);
741 break;
743 case CM_DMARead:
744 if (FALSE == dma_SetupPRDSize(au, mem, block->length, TRUE))
745 return IOERR_ABORTED;
746 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0);
747 dma_StartDMA(au);
748 break;
750 case CM_DMAWrite:
751 if (FALSE == dma_SetupPRDSize(au, mem, block->length, FALSE))
752 return IOERR_ABORTED;
753 ata_IRQSetHandler(au, &ata_IRQDMAReadWrite, NULL, 0);
754 dma_StartDMA(au);
755 break;
757 case CM_NoData:
758 ata_IRQSetHandler(au, &ata_IRQNoData, NULL, 0);
759 break;
761 default:
762 return IOERR_NOCMD;
763 break;
767 * send command now
768 * let drive propagate its signals
770 DATA(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
771 ata_out(block->command, ata_Command, port);
772 ata_400ns();
775 * wait for drive to complete what it has to do
777 if (FALSE == ata_WaitBusyTO(au, 300, TRUE))
779 bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum);
780 err = IOERR_UNITBUSY;
782 else
783 err = au->au_cmd_error;
785 DATA(bug("[ATA%02ld] Command done\n", au->au_UnitNum));
787 * clean up DMA
788 * don't use 'mem' pointer here as it's already invalid.
790 if (block->method == CM_DMARead)
792 dma_StopDMA(au);
793 dma_Cleanup(block->buffer, block->length, TRUE);
795 else if (block->method == CM_DMAWrite)
797 dma_StopDMA(au);
798 dma_Cleanup(block->buffer, block->length, FALSE);
801 D(bug("[ATA%02ld] return code %ld\n", au->au_UnitNum, err));
802 return err;
806 * atapi packet iface
808 int atapi_SendPacket(struct ata_Unit *unit, APTR packet, APTR data, LONG datalen, BOOL *dma, BOOL write)
810 *dma &= (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
811 LONG err = 0;
813 UBYTE cmd[12] = {
816 register int t=5,l=0;
817 ULONG port = unit->au_Bus->ab_Port;
819 if (((UBYTE*)packet)[0] > 0x1f)
820 t+= 4;
821 if (((UBYTE*)packet)[0] > 0x5f)
822 t+= 2;
824 switch (((UBYTE*)packet)[0])
826 case 0x28: // read10
827 case 0xa8: // read12
828 case 0xbe: // readcd
829 case 0xb9: // readcdmsf
830 case 0x2f: // verify
831 case 0x2a: // write
832 case 0xaa: // write12
833 case 0x2e: // writeverify
834 break;
835 default:
836 *dma = FALSE;
839 while (l<=t)
841 cmd[l] = ((UBYTE*)packet)[l];
842 ++l;
846 bug("[ATA%02lx] Sending %s ATA packet: ", unit->au_UnitNum, (*dma) ? "DMA" : "PIO");
847 l=0;
848 while (l<=t)
850 bug("%02lx ", ((UBYTE*)cmd)[l]);
851 ++l;
853 bug("\n");
855 if (datalen & 1)
856 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
859 datalen = (datalen+1)&~1;
861 if (FALSE == ata_SelectUnit(unit))
863 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
864 return IOERR_UNITBUSY;
868 * tell device if whether we want to read or write and if we want a dma transfer
870 ata_out(((*dma) ? 1 : 0) | ((write) ? 4 : 0), atapi_Features, port);
871 ata_out((datalen & 0xff), atapi_ByteCntL, port);
872 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
875 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
876 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
878 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
879 ata_out(ATA_PACKET, atapi_Command, port);
880 ata_400ns();
882 ata_WaitBusyTO(unit, 30, FALSE);
883 if (0 == (ata_ReadStatus(unit->au_Bus) & ATAF_DATAREQ))
884 return HFERR_BadStatus;
887 * setup appropriate hooks. not really the best way.
889 if (datalen == 0)
890 ata_IRQSetHandler(unit, &ata_IRQNoData, 0, 0);
891 else if (*dma)
892 ata_IRQSetHandler(unit, &ata_IRQDMAReadWrite, NULL, 0);
893 else if (write)
894 ata_IRQSetHandler(unit, &ata_IRQPIOWriteAtapi, data, datalen);
895 else
896 ata_IRQSetHandler(unit, &ata_IRQPIOReadAtapi, data, datalen);
898 DATAPI(bug("[ATAPI] Sending packet\n"));
899 unit->au_outs(cmd, unit->au_Bus->ab_Port, 12);
900 ata_400ns(); /* give drive time to think about what we just said, then move on */
901 /* how much time could it take for drive to raise DMARQ signal?? */
903 DATAPI(bug("[ATAPI] Status after packet: %lx\n", ata_ReadStatus(unit->au_Bus)));
905 if (*dma)
907 DATAPI(bug("[ATAPI] Preparing for DMA\n"));
908 while (0 == ((t = ata_ReadStatus(unit->au_Bus)) & (ATAF_BUSY | ATAF_DATAREQ)))
910 if (t & ATAF_ERROR)
912 err = HFERR_DMA;
913 break;
915 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit->au_Bus)));
916 ata_400ns();
919 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit->au_Bus)));
921 if (0 == err)
923 DATAPI(bug("[ATAPI] Starting DMA\n"));
924 dma_StartDMA(unit);
928 if ((0 == err) && (ata_WaitBusyTO(unit, 300, TRUE) == FALSE))
930 DATAPI(bug("[DSCSI] Command timed out.\n"));
931 err = IOERR_UNITBUSY;
933 else
934 err = atapi_EndCmd(unit);
936 if (TRUE == *dma)
938 dma_StopDMA(unit);
939 dma_Cleanup(data, datalen, !write);
942 D(bug("[ATAPI] Error code %ld\n", err));
943 return err;
946 ULONG atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
948 APTR buffer = cmd->scsi_Data;
949 ULONG length = cmd->scsi_Length;
950 BOOL read = FALSE;
951 UBYTE status;
952 UBYTE err = 0;
953 BOOL dma = FALSE;
955 cmd->scsi_Actual = 0;
957 DATAPI(bug("[DSCSI] Sending packet!\n"));
961 * setup DMA & push command
962 * it does not really mean we will use dma here btw
964 if ((unit->au_XferModes & AF_XFER_DMA) && (length !=0) && (buffer != 0))
966 dma = TRUE;
967 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
969 read = TRUE;
970 if (FALSE == dma_SetupPRDSize(unit, buffer, length, TRUE))
971 dma = FALSE;
973 else
975 if (FALSE == dma_SetupPRDSize(unit, buffer, length, FALSE))
976 dma = FALSE;
980 err = atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Data, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0);
982 DUMP({ if (cmd->scsi_Data != 0) dump(cmd->scsi_Data, cmd->scsi_Length); });
985 * on check condition - grab sense data
987 DATAPI(bug("[ATA%02lx] SCSI Flags: %02lx / Error: %ld\n", unit->au_UnitNum, cmd->scsi_Flags, err));
988 if ((err != 0) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
990 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
991 DUMP(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
994 return err;
998 * chops the large transfers into set of smaller transfers
999 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1001 static ULONG ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
1003 ULONG err=0;
1004 ULONG part;
1005 ULONG max=256;
1006 ULONG count=blk->sectors;
1008 if (blk->type == CT_LBA48)
1009 max <<= 8;
1011 DATA(bug("[ATA%02ld] Accessing %ld sectors starting from %lx\n", unit->au_UnitNum, count, blk->blk));
1012 while ((count > 0) && (err == 0))
1014 part = (count > max) ? max : count;
1015 blk->sectors = part;
1016 blk->length = part << unit->au_SectorShift;
1018 err = ata_exec_cmd(unit, blk);
1020 blk->blk += part;
1021 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1022 count -= part;
1024 return err;
1028 * Initial device configuration that suits *all* cases
1030 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1032 struct ata_Unit *unit=NULL;
1034 DINIT(bug("[ATA ] Initializing unit %ld\n", u));
1036 unit = bus->ab_Units[u];
1037 if (NULL == unit)
1038 return FALSE;
1040 unit->au_Bus = bus;
1041 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1042 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1043 unit->au_DevMask = 0xa0 | (u << 4);
1044 if (bus->ab_Base->ata_32bit)
1046 unit->au_ins = ata_insl;
1047 unit->au_outs = ata_outsl;
1049 else
1051 unit->au_ins = ata_insw;
1052 unit->au_outs = ata_outsw;
1054 unit->au_SectorShift= 9; /* this really has to be set here. */
1055 unit->au_Flags = 0;
1057 NEWLIST(&unit->au_SoftList);
1060 * since the stack is always handled by caller
1061 * it's safe to stub all calls with one function
1063 unit->au_Read32 = ata_STUB_IO32;
1064 unit->au_Read64 = ata_STUB_IO64;
1065 unit->au_Write32 = ata_STUB_IO32;
1066 unit->au_Write64 = ata_STUB_IO64;
1067 unit->au_Eject = ata_STUB;
1068 unit->au_DirectSCSI = ata_STUB_SCSI;
1069 unit->au_Identify = ata_STUB;
1070 return TRUE;
1073 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1075 struct ata_Unit *unit=NULL;
1078 * this stuff always goes along the same way
1079 * WARNING: NO INTERRUPTS AT THIS POINT!
1081 DINIT(bug("[ATA ] setting up unit %ld\n", u));
1083 unit = bus->ab_Units[u];
1084 if (NULL == unit)
1085 return FALSE;
1087 ata_SelectUnit(unit);
1089 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE))
1091 DINIT(bug("[ATA%02ld] ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1092 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1093 unit->au_Drive = 0;
1094 return FALSE;
1097 switch (bus->ab_Dev[u])
1100 * safe fallback settings
1102 case DEV_SATAPI:
1103 case DEV_ATAPI:
1104 unit->au_Identify = atapi_Identify;
1105 break;
1107 case DEV_SATA:
1108 case DEV_ATA:
1109 unit->au_Identify = ata_Identify;
1110 break;
1113 default:
1114 DINIT(bug("[ATA%02ld] Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1115 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1116 unit->au_Drive = 0;
1117 return FALSE;
1120 bug("[ATA ] Enabling Bus IRQs\n");
1121 ata_EnableIRQ(bus, TRUE);
1123 * now make unit self diagnose
1125 if (unit->au_Identify(unit) != 0)
1127 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1128 unit->au_Drive = 0;
1129 return FALSE;
1132 return TRUE;
1138 * ata[pi] identify
1140 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1142 UBYTE type=0;
1143 BOOL dma=FALSE;
1144 ata_CommandBlock acb =
1146 0xef,
1147 0x03,
1148 0x01,
1149 0x00,
1150 0x00,
1151 0x00,
1152 0x00,
1153 0x00,
1154 0x00,
1155 CM_NoData,
1156 CT_LBA28
1159 if ((unit->au_DMAPort == 0) && (mode > AB_XFER_PIO7))
1161 DINIT(bug("[ATA%02ld] This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1162 common_SetBestXferMode(unit);
1163 return;
1168 * first, ONLY for ATA devices, set new commands
1170 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1172 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1174 if (unit->au_XferModes & AF_XFER_RWMULTI)
1176 ata_out(unit->au_Drive->id_RWMultipleSize & 0xFF, ata_Count, unit->au_Bus->ab_Port);
1177 ata_out(ATA_SET_MULTIPLE, ata_Command, unit->au_Bus->ab_Port);
1178 ata_WaitBusyTO(unit, -1, FALSE);
1180 unit->au_Read32 = ata_ReadMultiple32;
1181 unit->au_Write32 = ata_WriteMultiple32;
1182 if (unit->au_XferModes & AF_XFER_48BIT)
1184 unit->au_Read64 = ata_ReadMultiple64;
1185 unit->au_Write64 = ata_WriteMultiple64;
1188 else
1190 unit->au_Read32 = ata_ReadSector32;
1191 unit->au_Write32 = ata_WriteSector32;
1192 if (unit->au_XferModes & AF_XFER_48BIT)
1194 unit->au_Read64 = ata_ReadSector64;
1195 unit->au_Write64 = ata_WriteSector64;
1199 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1201 unit->au_Read32 = ata_ReadDMA32;
1202 unit->au_Write32 = ata_WriteDMA32;
1203 if (unit->au_XferModes & AF_XFER_48BIT)
1205 unit->au_Read64 = ata_ReadDMA64;
1206 unit->au_Write64 = ata_WriteDMA64;
1209 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1211 unit->au_Read32 = ata_ReadDMA32;
1212 unit->au_Write32 = ata_WriteDMA32;
1213 if (unit->au_XferModes & AF_XFER_48BIT)
1215 unit->au_Read64 = ata_ReadDMA64;
1216 unit->au_Write64 = ata_WriteDMA64;
1219 else
1221 unit->au_Read32 = ata_ReadSector32;
1222 unit->au_Write32 = ata_WriteSector32;
1223 if (unit->au_XferModes & AF_XFER_48BIT)
1225 unit->au_Read64 = ata_ReadSector64;
1226 unit->au_Write64 = ata_WriteSector64;
1231 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1233 type = 8 + (mode - AB_XFER_PIO0);
1235 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1237 type = 32 + (mode - AB_XFER_MDMA7);
1238 dma=TRUE;
1240 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1242 type = 64 + (mode - AB_XFER_MDMA7);
1243 dma=TRUE;
1245 else
1247 type = 0;
1250 acb.sectors = type;
1251 if (0 != ata_exec_cmd(unit, &acb))
1253 DINIT(bug("[ATA%02ld] ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1256 if (unit->au_DMAPort)
1258 type = ata_in(dma_Status, unit->au_DMAPort);
1259 type &= 0x60;
1260 if (dma)
1262 type |= 1 << (5 + (unit->au_UnitNum & 1));
1264 else
1266 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1269 DINIT(bug("[DSCSI] Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1271 ata_SelectUnit(unit);
1272 ata_out(type, dma_Status, unit->au_DMAPort);
1273 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1275 DINIT(bug("[DSCSI] New DMA Status: %02lx\n", type));
1277 else
1279 DINIT(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1280 dma = FALSE;
1284 if (dma)
1285 unit->au_XferModes |= AF_XFER_DMA;
1286 else
1287 unit->au_XferModes &=~AF_XFER_DMA;
1290 static void common_SetBestXferMode(struct ata_Unit* unit)
1292 int iter;
1293 int max = AB_XFER_UDMA7;
1295 if (unit->au_DMAPort == 0)
1298 * make sure you reduce scan search to pio here!
1299 * otherwise this and above function will fall into infinite loop
1301 DINIT(bug("[ATA%02ld] This controller does not own DMA port\n", unit->au_UnitNum));
1302 max = AB_XFER_PIO7;
1305 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1307 if (unit->au_XferModes & (1<<iter))
1309 common_SetXferMode(unit, iter);
1310 return;
1313 bug("[ATA%02ld] ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1314 common_SetXferMode(unit, AB_XFER_PIO0);
1317 void common_DetectXferModes(struct ata_Unit* unit)
1319 int iter;
1321 DINIT(bug("[ATA%02ld] Supports\n", unit->au_UnitNum));
1323 if (unit->au_Drive->id_Commands4 & (1 << 4))
1325 DINIT(bug("[ATA%02ld] - Packet interface\n", unit->au_UnitNum));
1326 unit->au_XferModes |= AF_XFER_PACKET;
1327 unit->au_DirectSCSI = atapi_DirectSCSI;
1329 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1331 /* ATAPI devices do not use this bit. */
1332 DINIT(bug("[ATA%02ld] - 48bit I/O\n", unit->au_UnitNum));
1333 unit->au_XferModes |= AF_XFER_48BIT;
1336 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1338 DINIT(bug("[ATA%02ld] - LBA Addressing\n", unit->au_UnitNum));
1339 unit->au_XferModes |= AF_XFER_LBA;
1341 else
1343 DINIT(bug("[ATA%02ld] - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1346 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1348 DINIT(bug("[ATA%02ld] - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1349 unit->au_XferModes |= AF_XFER_RWMULTI;
1352 if (unit->au_Drive->id_PIOSupport & 0xff)
1354 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1355 for (iter=0; iter<8; iter++)
1357 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1359 DINIT(bug("PIO%ld ", iter));
1360 unit->au_XferModes |= AF_XFER_PIO(iter);;
1363 DINIT(bug("\n"));
1366 if (unit->au_Drive->id_Capabilities & (1<<8))
1368 DINIT(bug("[ATA%02ld] DMA:\n", unit->au_UnitNum));
1369 if (unit->au_Drive->id_MWDMASupport & 0xff)
1371 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1372 for (iter=0; iter<8; iter++)
1374 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1376 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1377 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1379 DINIT(bug("[MDMA%ld] ", iter));
1381 else
1383 DINIT(bug("MDMA%ld ", iter));
1387 DINIT(bug("\n"));
1390 if (unit->au_Drive->id_UDMASupport & 0xff)
1392 DINIT(bug("[ATA%02ld] - ", unit->au_UnitNum));
1393 for (iter=0; iter<8; iter++)
1395 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1397 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1398 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1400 DINIT(bug("[UDMA%ld] ", iter));
1402 else
1404 DINIT(bug("UDMA%ld ", iter));
1408 DINIT(bug("\n"));
1413 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1414 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1415 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1417 ULONG atapi_Identify(struct ata_Unit* unit)
1419 ata_CommandBlock acb =
1421 ATA_IDENTIFY_ATAPI,
1427 unit->au_Drive,
1428 sizeof(struct DriveIdent),
1430 CM_PIORead,
1431 CT_NoBlock
1434 ata_SelectUnit(unit);
1436 if (ata_exec_cmd(unit, &acb))
1438 return IOERR_OPENFAIL;
1441 #if (AROS_BIG_ENDIAN != 0)
1442 SWAP_LE_WORD(unit->au_Drive->id_General);
1443 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1444 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1445 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1446 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1447 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1448 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1449 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1450 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1451 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1452 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1453 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1454 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1455 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1456 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1457 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1458 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1459 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1460 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1461 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1462 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1463 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1464 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1465 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1466 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1467 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1468 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1469 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1470 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1471 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1472 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1473 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1474 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1475 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1476 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1477 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1478 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1479 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1480 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1481 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1482 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1483 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1484 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1486 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1487 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1488 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1490 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1491 #endif
1494 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1496 unit->au_SectorShift = 11;
1497 unit->au_Read32 = atapi_Read;
1498 unit->au_Write32 = atapi_Write;
1499 unit->au_DirectSCSI = atapi_DirectSCSI;
1500 unit->au_Eject = atapi_Eject;
1501 unit->au_Flags = AF_DiscChanged;
1502 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1503 unit->au_XferModes = AF_XFER_PACKET;
1505 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1506 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1507 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1509 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1510 common_DetectXferModes(unit);
1511 common_SetBestXferMode(unit);
1513 if (unit->au_Drive->id_General & 0x80)
1515 DINIT(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1516 unit->au_Flags |= AF_Removable;
1519 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1520 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1521 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));
1524 * ok, this is not very original, but quite compatible :P
1526 switch (unit->au_DevType)
1528 case DG_CDROM:
1529 case DG_WORM:
1530 case DG_OPTICAL_DISK:
1531 unit->au_SectorShift = 11;
1532 unit->au_Heads = 1;
1533 unit->au_Sectors = 75;
1534 unit->au_Cylinders = 4440;
1535 break;
1537 case DG_DIRECT_ACCESS:
1538 unit->au_SectorShift = 9;
1539 if (!strcmp("LS-120", &unit->au_Model[0]))
1541 unit->au_Heads = 2;
1542 unit->au_Sectors = 18;
1543 unit->au_Cylinders = 6848;
1545 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1547 unit->au_Heads = 1;
1548 unit->au_Sectors = 64;
1549 unit->au_Cylinders = 3072;
1551 break;
1554 atapi_TestUnitOK(unit);
1556 return 0;
1559 ULONG ata_Identify(struct ata_Unit* unit)
1561 ata_CommandBlock acb =
1563 ATA_IDENTIFY_DEVICE,
1569 unit->au_Drive,
1570 sizeof(struct DriveIdent),
1572 CM_PIORead,
1573 CT_NoBlock
1576 if (ata_exec_cmd(unit, &acb))
1578 return IOERR_OPENFAIL;
1581 #if (AROS_BIG_ENDIAN != 0)
1582 SWAP_LE_WORD(unit->au_Drive->id_General);
1583 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1584 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1585 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1586 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1587 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1588 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1589 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1590 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1591 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1592 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1593 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1594 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1595 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1596 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1597 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1598 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1599 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1600 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1601 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1602 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1603 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1604 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1605 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1606 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1607 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1608 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1609 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1610 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1611 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1612 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1613 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1614 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1615 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1616 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1617 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1618 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1619 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1620 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1621 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1622 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1623 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1624 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1626 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1627 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1628 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1630 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1631 #endif
1633 DUMP(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1635 unit->au_SectorShift = 9;
1636 unit->au_DevType = DG_DIRECT_ACCESS;
1637 unit->au_Read32 = ata_ReadSector32;
1638 unit->au_Write32 = ata_WriteSector32;
1639 unit->au_DirectSCSI = atapi_DirectSCSI;
1640 unit->au_Eject = ata_Eject;
1641 unit->au_XferModes = 0;
1642 unit->au_Flags |= AF_DiscPresent | AF_DiscChanged;
1643 unit->au_DevType = DG_DIRECT_ACCESS;
1645 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1646 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1647 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1649 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1650 common_DetectXferModes(unit);
1651 common_SetBestXferMode(unit);
1653 if (unit->au_Drive->id_General & 0x80)
1655 DINIT(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1656 unit->au_Flags |= AF_Removable;
1659 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1660 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1661 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));
1664 For drive capacities > 8.3GB assume maximal possible layout.
1665 It really doesn't matter here, as BIOS will not handle them in
1666 CHS way anyway :)
1667 i guess this just solves that weirdo div-by-zero crash, if anything else...
1669 if ((unit->au_Drive->id_LBA48Sectors > (63 * 255 * 1024)) ||
1670 (unit->au_Drive->id_LBASectors > (63 * 255 * 1024)))
1672 ULONG div = 1;
1674 * TODO: this shouldn't be casted down here.
1676 ULONG sec = unit->au_Capacity48;
1678 if (sec < unit->au_Capacity48)
1679 sec = ~0ul;
1681 if (sec < unit->au_Capacity)
1682 sec = unit->au_Capacity;
1684 unit->au_Sectors = 63;
1685 sec /= 63;
1687 * keep dividing by 2
1691 if (((sec >> 1) << 1) != sec)
1692 break;
1693 if ((div << 1) > 255)
1694 break;
1695 div <<= 1;
1696 sec >>= 1;
1697 } while (1);
1701 if (((sec / 3) * 3) != sec)
1702 break;
1703 if ((div * 3) > 255)
1704 break;
1705 div *= 3;
1706 sec /= 3;
1707 } while (1);
1709 unit->au_Cylinders = sec;
1710 unit->au_Heads = div;
1712 else
1714 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1715 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1716 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1718 return 0;
1723 * ata read32 commands
1725 static ULONG ata_ReadSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1727 ata_CommandBlock acb =
1729 ATA_READ,
1733 block,
1734 count,
1735 buffer,
1736 count << unit->au_SectorShift,
1738 CM_PIORead,
1739 CT_LBA28
1741 register ULONG err;
1743 *act = 0;
1744 if (0 != (err = ata_exec_blk(unit, &acb)))
1745 return err;
1747 *act = count << unit->au_SectorShift;
1748 return 0;
1751 static ULONG ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1753 ata_CommandBlock acb =
1755 ATA_READ_MULTIPLE,
1757 unit->au_Drive->id_RWMultipleSize & 0xff,
1759 block,
1760 count,
1761 buffer,
1762 count << unit->au_SectorShift,
1764 CM_PIORead,
1765 CT_LBA28
1767 register ULONG err;
1769 *act = 0;
1770 if (0 != (err = ata_exec_blk(unit, &acb)))
1771 return err;
1773 *act = count << unit->au_SectorShift;
1774 return 0;
1777 static ULONG ata_ReadDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1779 register ULONG err;
1780 ata_CommandBlock acb =
1782 ATA_READ_DMA,
1786 block,
1787 count,
1788 buffer,
1789 count << unit->au_SectorShift,
1791 CM_DMARead,
1792 CT_LBA28
1795 *act = 0;
1796 if (0 != (err = ata_exec_blk(unit, &acb)))
1797 return err;
1799 *act = count << unit->au_SectorShift;
1800 return 0;
1805 * ata read64 commands
1807 static ULONG ata_ReadSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1809 ata_CommandBlock acb =
1811 ATA_READ64,
1815 block,
1816 count,
1817 buffer,
1818 count << unit->au_SectorShift,
1820 CM_PIORead,
1821 CT_LBA48
1823 register ULONG err = 0;
1825 *act = 0;
1826 if (0 != (err = ata_exec_blk(unit, &acb)))
1827 return err;
1829 *act = count << unit->au_SectorShift;
1830 return 0;
1833 static ULONG ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1835 ata_CommandBlock acb =
1837 ATA_READ_MULTIPLE64,
1839 unit->au_Drive->id_RWMultipleSize & 0xff,
1841 block,
1842 count,
1843 buffer,
1844 count << unit->au_SectorShift,
1846 CM_PIORead,
1847 CT_LBA48
1849 register ULONG err;
1851 *act = 0;
1852 if (0 != (err = ata_exec_blk(unit, &acb)))
1853 return err;
1855 *act = count << unit->au_SectorShift;
1856 return 0;
1859 static ULONG ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1861 ata_CommandBlock acb =
1863 ATA_READ_DMA64,
1867 block,
1868 count,
1869 buffer,
1870 count << unit->au_SectorShift,
1872 CM_DMARead,
1873 CT_LBA48
1875 register ULONG err;
1877 *act = 0;
1878 if (0 != (err = ata_exec_blk(unit, &acb)))
1879 return err;
1881 *act = count << unit->au_SectorShift;
1882 return 0;
1887 * ata write32 commands
1889 static ULONG ata_WriteSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1891 ata_CommandBlock acb =
1893 ATA_WRITE,
1897 block,
1898 count,
1899 buffer,
1900 count << unit->au_SectorShift,
1902 CM_PIOWrite,
1903 CT_LBA28
1905 register ULONG err;
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_WriteMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1917 ata_CommandBlock acb =
1919 ATA_WRITE_MULTIPLE,
1921 unit->au_Drive->id_RWMultipleSize & 0xff,
1923 block,
1924 count,
1925 buffer,
1926 count << unit->au_SectorShift,
1928 CM_PIOWrite,
1929 CT_LBA28
1931 register ULONG err;
1933 *act = 0;
1934 if (0 != (err = ata_exec_blk(unit, &acb)))
1935 return err;
1937 *act = count << unit->au_SectorShift;
1938 return 0;
1941 static ULONG ata_WriteDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1943 ata_CommandBlock acb =
1945 ATA_WRITE_DMA,
1949 block,
1950 count,
1951 buffer,
1952 count << unit->au_SectorShift,
1954 CM_DMAWrite,
1955 CT_LBA28
1957 register ULONG err;
1959 *act = 0;
1960 if (0 != (err = ata_exec_blk(unit, &acb)))
1961 return err;
1963 *act = count << unit->au_SectorShift;
1964 return 0;
1969 * ata write64 commands
1971 static ULONG ata_WriteSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1973 ata_CommandBlock acb =
1975 ATA_WRITE64,
1979 block,
1980 count,
1981 buffer,
1982 count << unit->au_SectorShift,
1984 CM_PIOWrite,
1985 CT_LBA48
1987 register ULONG err;
1989 *act = 0;
1990 if (0 != (err = ata_exec_blk(unit, &acb)))
1991 return err;
1993 *act = count << unit->au_SectorShift;
1994 return 0;
1997 static ULONG ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1999 ata_CommandBlock acb =
2001 ATA_WRITE_MULTIPLE64,
2003 unit->au_Drive->id_RWMultipleSize & 0xff,
2005 block,
2006 count,
2007 buffer,
2008 count << unit->au_SectorShift,
2010 CM_PIOWrite,
2011 CT_LBA48
2013 register ULONG err;
2015 *act = 0;
2016 if (0 != (err = ata_exec_blk(unit, &acb)))
2017 return err;
2019 *act = count << unit->au_SectorShift;
2020 return 0;
2023 static ULONG ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2025 ata_CommandBlock acb =
2027 ATA_WRITE_DMA64,
2031 block,
2032 count,
2033 buffer,
2034 count << unit->au_SectorShift,
2036 CM_DMAWrite,
2037 CT_LBA48
2039 register ULONG err;
2041 *act = 0;
2042 if (0 != (err = ata_exec_blk(unit, &acb)))
2043 return err;
2045 *act = count << unit->au_SectorShift;
2046 return 0;
2050 * ata miscellaneous commands
2052 static ULONG ata_Eject(struct ata_Unit *unit)
2054 ata_CommandBlock acb =
2056 ATA_MEDIA_EJECT,
2065 CM_NoData,
2066 CT_NoBlock
2069 return ata_exec_cmd(unit, &acb);
2073 * atapi commands
2075 int atapi_TestUnitOK(struct ata_Unit *unit)
2077 UBYTE cmd[6] = {
2080 UBYTE sense[16] = {
2083 struct SCSICmd sc = {
2087 sc.scsi_Command = (void*) &cmd;
2088 sc.scsi_CmdLength = sizeof(cmd);
2089 sc.scsi_SenseData = (void*)&sense;
2090 sc.scsi_SenseLength = sizeof(sense);
2091 sc.scsi_Flags = SCSIF_AUTOSENSE;
2093 unit->au_DirectSCSI(unit, &sc);
2094 unit->au_SenseKey = sense[2];
2097 * we may have just lost the disc...?
2099 int p1 = ((sense[2] == 2) && (sense[12] == 0x3a)) ? 1 : 0;
2100 int p2 = (0 != (AF_DiscPresent & unit->au_Flags)) ? 1 : 0;
2102 if (p1 == p2)
2104 //unit->au_Flags ^= AF_DiscPresent;
2105 if (p1 == 0)
2106 unit->au_Flags |= AF_DiscPresent;
2107 else
2108 unit->au_Flags &= ~AF_DiscPresent;
2110 unit->au_Flags |= AF_DiscChanged;
2113 DATAPI(bug("[ATA%02ld] Test Unit Ready sense: %02lx, Media %s\n", unit->au_UnitNum, sense[2], unit->au_Flags & AF_DiscPresent ? "PRESENT" : "ABSENT"));
2114 return sense[2];
2117 static ULONG atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2119 UBYTE cmd[] = {
2120 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2122 struct SCSICmd sc = {
2126 sc.scsi_Command = (void*) &cmd;
2127 sc.scsi_CmdLength = sizeof(cmd);
2128 sc.scsi_Data = buffer;
2129 sc.scsi_Length = count << unit->au_SectorShift;
2130 sc.scsi_Flags = SCSIF_READ;
2132 return unit->au_DirectSCSI(unit, &sc);
2135 static ULONG atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2137 UBYTE cmd[] = {
2138 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2140 struct SCSICmd sc = {
2144 sc.scsi_Command = (void*) &cmd;
2145 sc.scsi_CmdLength = sizeof(cmd);
2146 sc.scsi_Data = buffer;
2147 sc.scsi_Length = count << unit->au_SectorShift;
2148 sc.scsi_Flags = SCSIF_WRITE;
2150 return unit->au_DirectSCSI(unit, &sc);
2153 static ULONG atapi_Eject(struct ata_Unit *unit)
2155 struct atapi_StartStop cmd = {
2156 command: SCSI_STARTSTOP,
2157 immediate: 1,
2158 flags: ATAPI_SS_EJECT,
2161 struct SCSICmd sc = {
2165 sc.scsi_Command = (void*) &cmd;
2166 sc.scsi_CmdLength = sizeof(cmd);
2167 sc.scsi_Flags = SCSIF_READ;
2169 return unit->au_DirectSCSI(unit, &sc);
2172 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2174 UBYTE cmd[] = {
2175 3, 0, 0, 0, senselen & 0xfe, 0
2177 struct SCSICmd sc = {
2181 if ((senselen == 0) || (sense == 0))
2183 return 0;
2185 sc.scsi_Data = (void*)sense;
2186 sc.scsi_Length = senselen & 0xfe;
2187 sc.scsi_Command = (void*)&cmd;
2188 sc.scsi_CmdLength = 6;
2189 sc.scsi_Flags = SCSIF_READ;
2191 unit->au_DirectSCSI(unit, &sc);
2193 DATAPI(dump(sense, senselen));
2194 DATAPI(bug("[SENSE] sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2195 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2198 ULONG ata_ReadSignature(struct ata_Bus *bus, int unit)
2200 ULONG port = bus->ab_Port;
2201 UBYTE tmp1, tmp2;
2203 /* Check basic signature. All live devices should provide it */
2204 tmp1 = ata_in(ata_Count, port);
2205 tmp2 = ata_in(ata_LBALow, port);
2206 DINIT(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2208 DINIT(bug("[ATA ] Status %08lx Device %08lx\n", ata_in(ata_Status, port), ata_in(ata_DevHead, port)));
2210 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2212 /* Ok, ATA/ATAPI device. Get detailed signature */
2213 DINIT(bug("[ATA ] Found an ATA[PI] Device. Attempting to detect specific subtype\n"));
2215 tmp1 = ata_in(ata_LBAMid, port);
2216 tmp2 = ata_in(ata_LBAHigh, port);
2218 DINIT(bug("[ATA ] Subtype check returned %02lx:%02lx (%04lx)\n", tmp1, tmp2, (tmp1 << 8) | tmp2));
2221 switch ((tmp1 << 8) | tmp2)
2223 case 0x0000:
2224 if (0 == (ata_ReadStatus(bus) & 0xfe))
2225 return DEV_NONE;
2226 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2227 ata_out(ATA_EXECUTE_DIAG, ata_Command, port);
2228 ata_out(0xa0 | (unit << 4), ata_DevHead, port);
2230 while (ata_ReadStatus(bus) & ATAF_BUSY)
2231 ata_400ns();
2233 DINIT(bug("[ATA ] Further validating ATA signature: %lx & 0x7f = 1, %lx & 0x10 = unit\n", ata_in(ata_Error, port), ata_in(ata_DevHead, port)));
2235 if ((1 == (0x7f & ata_in(ata_Error, port))) &&
2236 (unit == ((ata_in(ata_DevHead, port) >> 4) & 1)))
2238 DINIT(bug("[ATA ] Found *valid* signature for ATA device\n"));
2239 return DEV_ATA;
2241 return DEV_NONE;
2243 case 0x14eb:
2244 DINIT(bug("[ATA ] Found signature for ATAPI device\n"));
2245 return DEV_ATAPI;
2247 case 0x3cc3:
2248 DINIT(bug("[ATA ] Found signature for SATA device\n"));
2249 return DEV_SATA;
2251 case 0x6996:
2252 DINIT(bug("[ATA ] Found signature for SATAPI device\n"));
2253 return DEV_SATAPI;
2255 default:
2256 if (((tmp1 | tmp2) == 0xff) &&
2257 ((tmp1 & tmp2) == 0x00))
2259 bug("[ATA ] Found valid subtype, but don't know how to handle this device: %02lx %02lx\n", tmp1, tmp2);
2261 else
2263 bug("[ATA ] Invalid signature: %02lx %02lx\n", tmp1, tmp2);
2265 return DEV_NONE;
2269 return DEV_NONE;
2272 void ata_ResetBus(struct timerequest *tr, struct ata_Bus *bus)
2274 ULONG alt = bus->ab_Alt;
2275 ULONG port = bus->ab_Port;
2276 int id;
2279 * issue and clear the software reset signal
2281 /* at this time both devices should report ready immediately */
2282 for (id = 0; id < 2; id++)
2284 if (DEV_NONE != bus->ab_Dev[id])
2286 ata_out(0xa0 | (id << 4), ata_DevHead, port);
2287 ata_400ns();
2289 ata_out(0x04, ata_AltControl, alt);
2290 ata_usleep(tr, 10); /* minimum required: 5us */
2291 ata_out(0x02, ata_AltControl, alt);
2292 ata_usleep(tr, 20000); /* minimum required: 2ms */
2294 ata_out(0xa0 | (id << 4), ata_DevHead, port);
2295 ata_400ns();
2297 while (0 != (ata_in(ata_Status, port) & ATAF_BUSY))
2298 ata_usleep(tr, 200);
2300 bus->ab_Dev[id] = ata_ReadSignature(bus, id);
2306 * --------------------------------------------------------------
2307 * - here ends the code that makes any sense. rest to be removed -
2308 * --------------------------------------------------------------
2312 void ata_usleep(struct timerequest *tr, ULONG usec)
2314 tr->tr_node.io_Command = TR_ADDREQUEST;
2315 tr->tr_time.tv_micro = usec % 1000000;
2316 tr->tr_time.tv_secs = usec / 1000000;
2318 DoIO((struct IORequest *)tr);
2322 Device scan routines - TO BE REPLACED
2325 * same here
2327 void ata_InitBus(struct ata_Bus *bus)
2329 ULONG port = bus->ab_Port;
2330 UBYTE tmp1, tmp2;
2332 struct MsgPort *p = CreateMsgPort();
2333 struct timerequest *tr = (struct timerequest *)CreateIORequest((struct MsgPort *)p,
2334 sizeof(struct timerequest));
2335 OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0);
2337 bus->ab_Dev[0] = DEV_NONE;
2338 bus->ab_Dev[1] = DEV_NONE;
2340 /* Disable IDE IRQ */
2341 ata_EnableIRQ(bus, FALSE);
2343 /* Select device 0 */
2344 ata_out(0xa0, ata_DevHead, port);
2345 ata_usleep(tr, 100);
2347 /* Write some pattern to registers */
2348 ata_out(0x55, ata_Count, port);
2349 ata_out(0xaa, ata_LBALow, port);
2350 ata_out(0xaa, ata_Count, port);
2351 ata_out(0x55, ata_LBALow, port);
2352 ata_out(0x55, ata_Count, port);
2353 ata_out(0xaa, ata_LBALow, port);
2355 tmp1 = ata_in(ata_Count, port);
2356 tmp2 = ata_in(ata_LBALow, port);
2358 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2359 bus->ab_Dev[0] = DEV_UNKNOWN;
2361 /* Select device 1 */
2362 ata_out(0xb0, ata_DevHead, port);
2363 ata_usleep(tr, 100);
2365 /* Write some pattern to registers */
2366 ata_out(0x55, ata_Count, port);
2367 ata_out(0xaa, ata_LBALow, port);
2368 ata_out(0xaa, ata_Count, port);
2369 ata_out(0x55, ata_LBALow, port);
2370 ata_out(0x55, ata_Count, port);
2371 ata_out(0xaa, ata_LBALow, port);
2373 tmp1 = ata_in(ata_Count, port);
2374 tmp2 = ata_in(ata_LBALow, port);
2376 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2377 bus->ab_Dev[1] = DEV_UNKNOWN;
2379 ata_ResetBus(tr, bus);
2381 CloseDevice((struct IORequest *)tr);
2382 DeleteIORequest((struct IORequest *)tr);
2383 DeleteMsgPort(p);
2387 * not really sure what this is meant to be - TO BE REPLACED
2389 static const ULONG ErrorMap[] = {
2390 CDERR_NotSpecified,
2391 CDERR_NoSecHdr,
2392 CDERR_NoDisk,
2393 CDERR_NoSecHdr,
2394 CDERR_NoSecHdr,
2395 CDERR_NOCMD,
2396 CDERR_NoDisk,
2397 CDERR_WriteProt,
2398 CDERR_NotSpecified,
2399 CDERR_NotSpecified,
2400 CDERR_NotSpecified,
2401 CDERR_ABORTED,
2402 CDERR_NotSpecified,
2403 CDERR_NotSpecified,
2404 CDERR_NoSecHdr,
2405 CDERR_NotSpecified,
2408 static ULONG atapi_EndCmd(struct ata_Unit *unit)
2410 UBYTE status;
2413 * read alternate status register (per specs)
2415 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2416 DATAPI(bug("[ATAPI] Alternate status: %lx\n", status));
2418 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2420 DATAPI(bug("[ATAPI] Command complete. Status: %lx\n", status));
2422 if (!(status & ATAPIF_CHECK))
2424 return 0;
2426 else
2428 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2429 DATAPI(bug("[ATAPI] Error code %lx\n", status >> 4));
2430 return ErrorMap[status >> 4];
2435 * vim: ts=4 et sw=4 fdm=marker fmr={,}