make the linux-ppc packags be in synch with other platforms
[tangerine.git] / arch / common / ata.device / lowlevel.c
bloba892535a23e7ef101a502325685cf149bea7cc15
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
45 #define DEBUG 0
46 #include <aros/debug.h>
47 #include <exec/types.h>
48 #include <exec/exec.h>
49 #include <exec/resident.h>
50 #include <utility/utility.h>
51 #include <oop/oop.h>
53 #include <dos/bptr.h>
55 #include <proto/exec.h>
56 #include <devices/timer.h>
58 #include <asm/io.h>
60 #include "ata.h"
65 Prototypes of static functions from lowlevel.c. I do not want to make them
66 non-static as I'd like to remove as much symbols from global table as possible.
67 Besides some of this functions could conflict with old ide.device or any other
68 device.
70 static ULONG ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
71 static ULONG ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
72 static ULONG ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
73 static ULONG ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
74 static ULONG ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
75 static ULONG ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
76 static ULONG ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
77 static ULONG ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
78 static ULONG ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
79 static ULONG ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
80 static ULONG ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
81 static ULONG ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
82 static ULONG ata_Eject(struct ata_Unit *);
84 static ULONG atapi_EndCmd(struct ata_Unit *unit);
86 static ULONG atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
87 static ULONG atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
88 static ULONG atapi_Eject(struct ata_Unit *);
90 static void common_SetBestXferMode(struct ata_Unit* unit);
93 Again piece of code which shouldn't be here. Geee. After removing all this
94 asm constrictuins this ata.device will really deserve for location in
95 /arch/common
98 * having an x86 assembly here i dare to assume that this is meant to be
99 * an x86[_64] device only.
101 * Not anymore.
103 * This functions will stay here for some time *IF* and only if the code is compiled for
104 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
105 * one who ports the driver will be reponsible for adding the missing code.
109 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
111 #if defined(__i386__) || defined(__x86_64__)
113 static VOID ata_insw(APTR address, UWORD port, ULONG count)
115 insw(port, address, count >> 1);
118 static VOID ata_insl(APTR address, UWORD port, ULONG count)
120 if (count & 2)
121 insw(port, address, count >> 1);
122 else
123 insl(port, address, count >> 2);
126 static VOID ata_outsw(APTR address, UWORD port, ULONG count)
128 outsw(port, address, count >> 1);
131 static VOID ata_outsl(APTR address, UWORD port, ULONG count)
133 if (count & 2)
134 outsw(port, address, count >> 1);
135 else
136 outsl(port, address, count >> 2);
138 #else
139 extern VOID ata_insw(APTR address, UWORD port, ULONG count);
140 extern VOID ata_insl(APTR address, UWORD port, ULONG count);
141 extern VOID ata_outsw(APTR address, UWORD port, ULONG count);
142 extern VOID ata_outsl(APTR address, UWORD port, ULONG count);
143 #endif
145 static void dump(APTR mem, ULONG len)
147 register int i,j;
148 for (j=0; j<(len+15)>>4; ++j)
150 bug("[ATA ] %06lx: ", j<<4);
152 for (i=0; i<len-(j<<4); i++)
154 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
155 if (i == 15)
156 break;
159 for (i=0; i<len-(j<<4); i++)
161 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
163 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
164 if (i == 15)
165 break;
167 bug("\n");
171 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
173 register int i = size;
175 while (size--)
177 str2[size^1] = str1[size];
180 while (i--)
182 if (str2[i] <= ' ')
183 str2[i] = 0;
189 * a STUB function for commands not supported by this particular device
191 static ULONG ata_STUB(struct ata_Unit *au)
193 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
194 return CDERR_NOCMD;
197 static ULONG ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len, APTR buf, ULONG* act)
199 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
200 return CDERR_NOCMD;
203 static ULONG ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len, APTR buf, ULONG* act)
205 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);
206 return CDERR_NOCMD;
209 static ULONG ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
211 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
212 return CDERR_NOCMD;
216 * Very short delay (TM) by someone who assumes slow data ports.
217 * well, glad it works anyways.
219 void ata_400ns()
221 ata_in(ata_AltControl, 0x3f6);
222 ata_in(ata_AltControl, 0x3f6);
223 ata_in(ata_AltControl, 0x3f6);
224 ata_in(ata_AltControl, 0x3f6);
227 inline void ata_SelectUnit(struct ata_Unit* unit)
229 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
233 * enable / disable IRQ; this manages interrupt requests more effectively in case of legacy emulation
234 * as little code as there can be. and keep it that way.
236 void ata_EnableIRQ(struct ata_Bus *bus, BOOL enable)
238 enable = TRUE; // Needed in order to work with many PCs. Better fix welcome
239 bus->ab_Waiting = enable;
240 ata_out(enable ? 0x0 : 0x02, ata_AltControl, bus->ab_Alt);
244 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
245 * part of code moved here from ata.c to reduce containment
247 void ata_HandleIRQ(struct ata_Bus *bus)
250 * don't waste your time on checking other devices.
251 * pass irq ONLY if task is expecting one;
253 if (TRUE == bus->ab_Waiting)
255 if (0 == (ATAF_BUSY & ata_ReadStatus(bus)))
257 D(bug("[ATA ] Got Intrq\n"));
258 ata_EnableIRQ(bus, FALSE);
259 bus->ab_IntCnt++;
260 Signal(bus->ab_Task, 1L << bus->ab_SleepySignal);
266 * wait for timeout or drive ready
267 * polling-in-a-loop, but it should be safe to remove this already
269 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout, BOOL irq)
271 UBYTE status;
272 ULONG sigs = SIGBREAKF_CTRL_C | (irq ? (1 << unit->au_Bus->ab_SleepySignal) : 0);
273 ULONG step = 0;
274 BOOL res = TRUE;
277 * clear up all old signals
279 SetSignal(0, sigs);
282 * set up bus timeout and irq
284 Disable();
285 ata_EnableIRQ(unit->au_Bus, irq);
286 unit->au_Bus->ab_Timeout = tout;
287 Enable();
290 * this loop may experience one of two scenarios
291 * 1) we get a valid irq and the drive wanted to let us know that it's ready
292 * 2) we get an invalid irq due to some collissions. We may still want to go ahead and get some extra irq breaks
293 * this would reduce system load a little
299 * lets check if the drive is already good
301 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
302 if (0 == (status & ATAF_BUSY))
303 break;
306 * so we're stuck in a loop?
308 D(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", unit->au_UnitNum, status));
311 * if IRQ wait is requested then allow either timeout or irq;
312 * then clear irq flag so we dont keep receiving more of these (especially when system suffers collissions)
314 if (irq)
317 * wait for either IRQ or TIMEOUT
319 step = Wait(sigs);
322 * now if we did reach timeout, then there's no point in going ahead.
324 if (SIGBREAKB_CTRL_C & step)
326 bug("[ATA%02ld] Timeout while waiting for device to complete operation\n", unit->au_UnitNum);
327 res = FALSE;
331 * if we get as far as this, there's no more signals to expect
332 * but we still want the status
334 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
335 break;
337 else
340 * device not ready just yet. lets set whether we want an IRQ and move on - to polling or irq wait
342 ++step;
345 * every 16n rounds do some extra stuff
347 if ((step & 16) == 0)
350 * huhm. so it's been 16n rounds already. any timeout yet?
352 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
354 D(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit->au_UnitNum));
355 res = FALSE;
356 break;
360 * no timeout just yet, but it's not a good idea to keep spinning like that.
361 * let's give the system some time.
363 // TODO: Put some delay here!
366 } while(status & ATAF_BUSY);
369 * be nice to frustrated developer
371 D(bug("[ATA%02ld] WaitBusy status: %ld\n", unit->au_UnitNum, res));
374 * clear up all our expectations
376 Disable();
377 ata_EnableIRQ(unit->au_Bus, FALSE);
378 unit->au_Bus->ab_Timeout = -1;
379 Enable();
382 * release old junk
384 SetSignal(0, sigs);
387 * and say it went fine (i mean it)
389 return res;
393 * just wait for timeout
395 void ata_Wait(struct ata_Unit *unit, UWORD tout)
397 SetSignal(0, SIGBREAKF_CTRL_C);
399 Disable();
400 unit->au_Bus->ab_Timeout = tout;
401 Enable();
403 Wait(SIGBREAKF_CTRL_C);
406 UBYTE ata_ReadStatus(struct ata_Bus *bus)
408 return ata_in(ata_Status, bus->ab_Port);
412 * Procedure for sending ATA command blocks
413 * it appears LARGE but there's a lot of COMMENTS here :)
414 * handles *all* ata commands (no data, pio and dma)
415 * naturally could be splitted at some point in the future
416 * depends if anyone believes that the change for 50 lines
417 * would make slow ATA transfers any faster
419 static ULONG ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
421 UBYTE stat;
422 ULONG port = au->au_Bus->ab_Port;
423 ULONG err = 0;
424 APTR mem = block->buffer;
425 BOOL dma = FALSE;
427 ata_SelectUnit(au);
430 * initial checks and stuff
432 switch (block->method)
434 case CM_DMARead:
435 case CM_DMAWrite:
436 dma = TRUE;
437 break;
438 case CM_PIORead:
439 case CM_PIOWrite:
440 case CM_NoData:
441 break;
442 default:
443 return IOERR_NOCMD;
446 switch (block->type)
448 case CT_LBA28:
449 if (block->sectors > 256)
451 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
452 return IOERR_BADLENGTH;
455 /* note:
456 * we want the above to fall in here!
457 * we really do (checking for secmul)
460 case CT_LBA48:
461 if (block->sectors > 65536)
463 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
464 return IOERR_BADLENGTH;
466 if (block->secmul == 0)
468 bug("[ATA%02ld] ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
469 block->secmul = 1;
471 break;
473 case CT_NoBlock:
474 break;
476 default:
477 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
478 return IOERR_NOCMD;
481 ata_SelectUnit(au);
483 block->actual = 0;
488 * PRECONDITIONS: ENABLED INTRQ (0x08 written to ata_Command port)
490 * - select device
492 D(bug("[ATA%02ld] Executing command %02lx\n", au->au_UnitNum, block->command));
495 * generally we could consider marking unit as 'retarded' upon three attempts or stuff like that
497 if (ata_WaitBusyTO(au, 1, TRUE) == FALSE)
499 bug("[ATA%02ld] UNIT BUSY AT SELECTION\n", au->au_UnitNum);
500 return IOERR_UNITBUSY;
503 if (block->feature != 0)
505 ata_out(block->feature, ata_Feature, port);
509 * - set LBA and sector count
511 switch (block->type)
513 case CT_LBA28:
514 //D(bug("[ATA%02ld] Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
515 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
516 ata_out(block->blk >> 16, ata_LBAHigh, port);
517 ata_out(block->blk >> 8, ata_LBAMid, port);
518 ata_out(block->blk, ata_LBALow, port);
519 ata_out(block->sectors, ata_Count, port);
520 break;
522 case CT_LBA48:
523 //D(bug("[ATA%02ld] Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
524 ata_out(block->blk >> 40, ata_LBAHigh, port);
525 ata_out(block->blk >> 32, ata_LBAMid, port);
526 ata_out(block->blk >> 24, ata_LBALow, port);
528 ata_out(block->blk >> 16, ata_LBAHigh, port);
529 ata_out(block->blk >> 8, ata_LBAMid, port);
530 ata_out(block->blk, ata_LBALow, port);
532 ata_out(block->sectors >> 8, ata_Count, port);
533 ata_out(block->sectors, ata_Count, port);
534 break;
536 case CT_NoBlock:
537 //D(bug("[ATA%02ld] Command does not address any block\n", au->au_UnitNum));
538 break;
544 * setup DMA & push command
546 switch (block->method)
548 case CM_DMARead:
549 //D(bug("[ATA%02ld] Initializing DMA for Read\n", au->au_UnitNum));
550 dma_SetupPRDSize(au, mem, block->length, TRUE);
551 CachePreDMA(mem, &block->length, DMA_ReadFromRAM);
552 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
553 ata_out(block->command, ata_Command, port);
554 dma_StartDMA(au);
555 break;
557 case CM_DMAWrite:
558 //D(bug("[ATA%02ld] Initializing DMA for Write\n", au->au_UnitNum));
559 dma_SetupPRDSize(au, mem, block->length, FALSE);
560 CachePreDMA(mem, &block->length, 0);
561 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
562 ata_out(block->command, ata_Command, port);
563 dma_StartDMA(au);
564 break;
566 case CM_PIOWrite:
567 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
568 ata_out(block->command, ata_Command, port);
569 ata_400ns();
570 break;
572 case CM_PIORead:
573 case CM_NoData:
574 D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
575 ata_out(block->command, ata_Command, port);
576 if (FALSE == ata_WaitBusyTO(au, 10, TRUE))
578 D(bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum));
579 err = IOERR_UNITBUSY;
580 break;
583 if (block->method == CM_PIORead)
584 break;
586 return 0;
591 * entering main command loop here.
593 while (err == 0)
596 * THEORY: PIO is entering stage H1. Waiting for drive to clear 'busy'
597 * once busy clears and no data is requested, we're free to go.
598 * DMA is waiting for the DMARQ to be raised
600 if (dma)
603 * we're not really expected to do much here.
604 * just wait for the dma transfer to complete
605 * check if dma transfer completed, otherwise give it another wait.
607 stat = ata_in(dma_Status, au->au_DMAPort);
608 D(bug("[ATA%02ld] DMA status %02lx\n", au->au_UnitNum, stat));
610 if (0 == (stat & DMAF_Active))
612 //D(bug("[ATA%02ld] DMA transfer is now complete\n", au->au_UnitNum));
613 block->actual = block->length;
615 else if (stat & DMAF_Error)
617 //D(bug("[ATA%02ld] DMA ended with an error\n", au->au_UnitNum));
618 err = IOERR_ABORTED;
620 else
622 //D(bug("[ATA%02ld] DMA transfer is still in progress\n", au->au_UnitNum));
625 else
627 UWORD len = (block->secmul << au->au_SectorShift);
630 * wait for drive to clear busy
632 if (FALSE == ata_WaitBusyTO(au, 30, FALSE))
634 bug("[ATA%02ld] Device busy after timeout\n", au->au_UnitNum);
635 err = IOERR_UNITBUSY;
636 break;
642 * check if we have the state: BSY=1 && DRQ=0 && DMARQ=1
643 * this means dma is still progressing
645 stat = ata_in(ata_Status, port);
646 if (0 == (stat & ATAF_DATAREQ))
648 bug("[ATA%02ld] No more data\n", au->au_UnitNum);
649 break;
654 * THEORY: we loop here: wait for interrupt, then wait for busy cleared, then
655 * while datareq transfer one long (or byte, or whatever).
656 * PRACTICE: transfer all data as it goes, as do most other systems.
658 while (stat & ATAF_DATAREQ)
660 if (len > (block->length - block->actual))
661 len = block->length - block->actual;
663 //D(bug("[ATA%02ld] Transferring %ld bytes to %08lx\n", au->au_UnitNum, len, mem));
665 switch (block->method)
668 * first case
669 * data is ready to transfer over PIO
670 * actually we are expected to check status prior to each insw/insl,
671 * doubt anyone does this. could cause problems with SLOW ata devices
672 * right here.
673 * transferring one block at a time, no more.
675 case CM_PIORead:
676 D(bug("[ATA%02ld] Reading bytes (PIO)\n", au->au_UnitNum));
677 au->au_ins(mem, au->au_Bus->ab_Port, len);
678 block->actual += len;
679 mem = &((char*)mem)[block->actual];
680 break;
683 * second case
684 * drive is ready to accept data over PIO
685 * we're supposed to check status prior to each outsw/outsl
686 * to make sure drive is actually ready to accept more data.
687 * otherwise slow devices will have problems accepting flood
688 * right here
689 * transferring one block at a time, no more.
691 case CM_PIOWrite:
692 D(bug("[ATA%02ld] Writing bytes (PIO)\n", au->au_UnitNum));
693 au->au_outs(mem, au->au_Bus->ab_Port, len);
694 block->actual += len;
695 mem = &((char*)mem)[block->actual];
696 break;
699 * we will never get here.
701 default:
702 break;
706 stat = ata_in(ata_Status, port);
707 D(bug("[ATA%02ld] Current command status %02lx\n", au->au_UnitNum, stat));
708 if (stat & ATAF_ERROR)
710 err = IOERR_ABORTED;
711 bug("[ATA%02ld] Command %lx finished with an error. Aborting.\n", au->au_UnitNum, block->command);
712 break;
718 stat = ata_in(ata_Status, port);
721 * check if previous transfer failed OR if we got all data we need
723 if ((err != 0) || (block->actual >= block->length))
724 break;
727 * THEORY: entering stage H0, waititng for drive to ping us with an interrupt
729 //D(bug("[ATA%02ld] Waiting for device to raise interrupt (data ready)\n", au->au_UnitNum));
731 * wait for interrupt
733 if (FALSE == ata_WaitBusyTO(au, 30, TRUE))
735 bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum);
736 err = IOERR_UNITBUSY;
737 break;
744 * clean up DMA
745 * don't use 'mem' pointer here as it's already invalid.
747 if (block->method == CM_DMARead)
749 //D(bug("[ATA%02ld] Finalizing DMA Read\n", au->au_UnitNum));
750 dma_StopDMA(au);
751 CachePostDMA(block->buffer, &block->length, DMA_ReadFromRAM);
753 else if (block->method == CM_DMAWrite)
755 //D(bug("[ATA%02ld] Finalizing DMA Write\n", au->au_UnitNum));
756 dma_StopDMA(au);
757 CachePostDMA(block->buffer, &block->length, 0);
759 //D(bug("[ATA%02ld] All done\n", au->au_UnitNum));
764 * signal error back to caller
766 if (0 != err)
767 return err;
769 stat = ata_in(ata_Status, port);
770 if (stat & ATAF_ERROR)
771 return IOERR_ABORTED;
773 return 0;
777 * atapi packet iface
779 int atapi_SendPacket(struct ata_Unit *unit, APTR packet, LONG datalen, BOOL *dma, BOOL write)
781 *dma &= (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
783 UBYTE cmd[12] = {
786 register int t=5,l=0;
787 ULONG port = unit->au_Bus->ab_Port;
789 if (((UBYTE*)packet)[0] > 0x1f)
790 t+= 4;
791 if (((UBYTE*)packet)[0] > 0x5f)
792 t+= 2;
794 switch (((UBYTE*)packet)[0])
796 case 0x28: // read10
797 case 0xa8: // read12
798 case 0xbe: // readcd
799 case 0xb9: // readcdmsf
800 case 0x2f: // verify
801 case 0x2a: // write
802 case 0xaa: // write12
803 case 0x2e: // writeverify
804 break;
805 default:
806 *dma = FALSE;
809 while (l<=t)
811 cmd[l] = ((UBYTE*)packet)[l];
812 ++l;
816 bug("[ATAPI] Sending %s ATA packet: ", (*dma) ? "DMA" : "PIO");
817 l=0;
818 while (l<=t)
820 bug("%02lx ", ((UBYTE*)cmd)[l]);
821 ++l;
823 bug("\n");
825 if (datalen & 1)
826 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
829 datalen = (datalen+1)&~1;
831 ata_out(unit->au_DevMask, atapi_DevSel, port);
832 if (ata_WaitBusyTO(unit, 1, TRUE))
835 * since the device is now ready (~BSY) && (~DRQ), we can set up features and transfer size
838 * we should consider using the DIRECTION flag here, too
840 ata_out(((*dma) ? 1 : 0) | ((write) ? 4 : 0), atapi_Features, port);
841 ata_out((datalen & 0xff), atapi_ByteCntL, port);
842 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
845 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
846 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
848 ata_out(ATA_PACKET, atapi_Command, port);
849 if (ata_WaitBusyTO(unit, 50, FALSE) == FALSE)
851 D(bug("[ATAPI] Unit not ready to accept command.\n"));
852 return IOERR_UNITBUSY;
856 * now we're waiting for the device to process following:
857 * - set BSY to prepare for packet reception
858 * - set COD bit and clear IO,
859 * - set DRQ bit and finally
860 * - clear BSY
863 * at this point we can expect DATAREQ (that would indicate device wants to retrieve packet
864 * OR some fault meaning device does not support packets
866 UBYTE status = ata_in(atapi_Status, port);
868 if (status & ATAF_DATAREQ)
871 * if we got here, it means that device most likely expects us to send exactly 12 bytes
872 * of packet data. no more, and no less. 12 bytes.
874 unit->au_outs(cmd, port, 12);
875 return 1;
877 else
879 D(bug("[ATAPI] interface not ready to retrieve data. Status: %lx\n", status));
882 else
884 D(bug("[ATAPI] WaitBusy failed at first check\n"));
887 return 0;
890 ULONG atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
892 ULONG port = unit->au_Bus->ab_Port;
893 APTR buffer = cmd->scsi_Data;
894 ULONG length = cmd->scsi_Length;
895 ULONG size = 0;
896 UBYTE status;
897 UBYTE err = 0;
898 BOOL dma = FALSE;
900 cmd->scsi_Actual = 0;
902 D(bug("[DSCSI] Sending packet!\n"));
906 * setup DMA & push command
907 * it does not really mean we will use dma here btw
909 if ((unit->au_XferModes & AF_XFER_DMA) && (cmd->scsi_Length !=0) && (cmd->scsi_Data != 0))
911 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
913 dma_SetupPRDSize(unit, cmd->scsi_Data, cmd->scsi_Length, TRUE);
914 CachePreDMA(cmd->scsi_Data, &cmd->scsi_Length, DMA_ReadFromRAM);
916 else
918 dma_SetupPRDSize(unit, cmd->scsi_Data, cmd->scsi_Length, FALSE);
919 CachePreDMA(cmd->scsi_Data, &cmd->scsi_Length, 0);
921 dma = TRUE;
924 if (atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0))
927 * PIO vs DMA
929 if (FALSE == dma)
931 if (ata_WaitBusyTO(unit, 30, TRUE) == FALSE)
933 D(bug("[DSCSI] Command timed out.\n"));
934 err = IOERR_UNITBUSY;
937 while (err == 0)
940 while ((status = ata_in(atapi_Status, port)) & ATAF_BUSY);
941 D(bug("[DSCSI] Command status: %lx\n", status));
943 if (status & ATAF_DATAREQ)
945 UBYTE reason = ata_in(atapi_Reason, port);
946 D(bug("[DSCSI] Current status: %ld, SCSI flags: %ld\n", reason, cmd->scsi_Flags));
948 if (((cmd->scsi_Flags & SCSIF_READ) == SCSIF_READ) &&
949 ((reason & ATAPIF_MASK) == ATAPIF_READ))
951 size = ata_in(atapi_ByteCntH, port) << 8 |
952 ata_in(atapi_ByteCntL, port);
953 D(bug("[DSCSI] data available for read (%ld bytes, max: %ld bytes)\n", size, length));
954 if (size > length)
956 D(bug("[DSCSI] CRITICAL! MORE DATA THAN STORAGE ALLOWS: %ld bytes vs %ld bytes left!\n", size, length));
957 /* damnit!! need to report some critical error here! */
958 //size = length;
960 unit->au_ins(buffer, port, size);
961 D(bug("[DSCSI] %lu bytes read.\n", size));
963 else if (((cmd->scsi_Flags & SCSIF_READ) == 0) &&
964 ((reason & ATAPIF_MASK) == ATAPIF_WRITE))
966 size = ata_in(atapi_ByteCntH, port) << 8 |
967 ata_in(atapi_ByteCntL, port);
968 D(bug("[DSCSI] device available for write\n"));
969 if (size > length)
971 D(bug("[DSCSI] CRITICAL! MORE DATA THAN STORAGE ALLOWS: %ld bytes vs %ld bytes left!\n", size, length));
972 /* damnit!! need to report some critical error here! */
973 //size = length;
975 unit->au_outs(buffer, port, size);
976 D(bug("[DSCSI] %lu bytes written.\n", size));
978 else
980 D(bug("[DSCSI] Drive data ready, but there's no storage to transfer. R != W\n"));
981 size = 0;
982 err = CDERR_InvalidState;
983 break;
986 cmd->scsi_Actual += size;
987 buffer += size;
988 length -= size;
990 else
992 D(bug("[DSCSI] User transfer complete, %ld bytes transferred.\n", cmd->scsi_Actual));
993 err = atapi_EndCmd(unit);
994 break;
998 else
1000 dma_StartDMA(unit);
1002 while (err == 0)
1004 if (FALSE == ata_WaitBusyTO(unit, 30, TRUE))
1006 err = IOERR_UNITBUSY;
1007 break;
1010 status = ata_in(ata_Status, port);
1011 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
1012 break;
1014 status = ata_in(dma_Status, unit->au_DMAPort);
1015 D(bug("[ATAPI] DMA status: %lx\n", status));
1016 if (0 == (status & DMAF_Active))
1018 break;
1020 if (0 != (status & DMAF_Error))
1022 err = IOERR_ABORTED;
1023 break;
1026 dma_StopDMA(unit);
1029 else
1031 err = CDERR_ABORTED;
1035 * clean up DMA
1036 * don't use 'mem' pointer here as it's already invalid.
1038 if (unit->au_XferModes & AF_XFER_DMA)
1040 if ((cmd->scsi_Flags & SCSIF_READ) == SCSIF_READ)
1042 CachePostDMA(cmd->scsi_Data, &cmd->scsi_Length, DMA_ReadFromRAM);
1044 else if ((cmd->scsi_Flags & SCSIF_READ) == 0)
1046 CachePostDMA(cmd->scsi_Data, &cmd->scsi_Length, 0);
1052 * on check condition - grab sense data
1054 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
1055 if (((err != 0) || (status & ATAPIF_CHECK)) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
1057 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
1058 D(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
1061 return err;
1065 * chops the large transfers into set of smaller transfers
1066 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1068 static ULONG ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
1070 ULONG err=0;
1071 ULONG part;
1072 ULONG max=256;
1073 ULONG count=blk->sectors;
1075 if (blk->type == CT_LBA48)
1076 max <<= 8;
1078 D(bug("[ATA%02ld] Accessing %ld sectors starting from %lx\n", unit->au_UnitNum, count, blk->blk));
1079 while ((count > 0) && (err == 0))
1081 part = (count > max) ? max : count;
1082 blk->sectors = part;
1083 blk->length = part << unit->au_SectorShift;
1085 err = ata_exec_cmd(unit, blk);
1087 blk->blk += part;
1088 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
1089 count -= part;
1091 return err;
1095 * Initial device configuration that suits *all* cases
1097 BOOL ata_init_unit(struct ata_Bus *bus, UBYTE u)
1099 struct ata_Unit *unit=NULL;
1101 D(bug("[ATA ] Initializing unit %ld\n", u));
1103 unit = bus->ab_Units[u];
1104 if (NULL == unit)
1105 return FALSE;
1107 unit->au_Bus = bus;
1108 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1109 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1110 unit->au_DevMask = 0xa0 | (u << 4);
1111 if (bus->ab_Base->ata_32bit)
1113 unit->au_ins = ata_insl;
1114 unit->au_outs = ata_outsl;
1116 else
1118 unit->au_ins = ata_insw;
1119 unit->au_outs = ata_outsw;
1121 unit->au_SectorShift= 9; /* this really has to be set here. */
1122 unit->au_Flags = 0;
1124 NEWLIST(&unit->au_SoftList);
1127 * since the stack is always handled by caller
1128 * it's safe to stub all calls with one function
1130 unit->au_Read32 = ata_STUB_IO32;
1131 unit->au_Read64 = ata_STUB_IO64;
1132 unit->au_Write32 = ata_STUB_IO32;
1133 unit->au_Write64 = ata_STUB_IO64;
1134 unit->au_Eject = ata_STUB;
1135 unit->au_DirectSCSI = ata_STUB_SCSI;
1136 unit->au_Identify = ata_STUB;
1137 return TRUE;
1140 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
1142 struct ata_Unit *unit=NULL;
1145 * this stuff always goes along the same way
1146 * WARNING: NO INTERRUPTS AT THIS POINT!
1148 D(bug("[ATA ] setting up unit %ld\n", u));
1150 unit = bus->ab_Units[u];
1151 if (NULL == unit)
1152 return FALSE;
1154 ata_SelectUnit(unit);
1156 if (FALSE == ata_WaitBusyTO(unit, 1, FALSE))
1158 D(bug("[ATA%02ld] ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1159 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1160 bus->ab_Base->ata_MemPool = 0;
1161 return FALSE;
1164 switch (bus->ab_Dev[u])
1167 * safe fallback settings
1169 case DEV_SATAPI:
1170 case DEV_ATAPI:
1171 unit->au_Identify = atapi_Identify;
1172 break;
1174 case DEV_SATA:
1175 case DEV_ATA:
1176 unit->au_Identify = ata_Identify;
1177 break;
1180 default:
1181 D(bug("[ATA%02ld] Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1182 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1183 bus->ab_Base->ata_MemPool = 0;
1184 return FALSE;
1188 * now make unit self diagnose
1190 if (unit->au_Identify(unit) != 0)
1192 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1193 bus->ab_Base->ata_MemPool = 0;
1194 return FALSE;
1197 return TRUE;
1203 * ata[pi] identify
1205 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1207 UBYTE type=0;
1208 BOOL dma=FALSE;
1209 ata_CommandBlock acb =
1211 0xef,
1212 0x03,
1213 0x01,
1214 0x00,
1215 0x00,
1216 0x00,
1217 0x00,
1218 0x00,
1219 0x00,
1220 CM_NoData,
1221 CT_LBA28
1224 if ((unit->au_DMAPort == 0) && (mode > AB_XFER_PIO7))
1226 D(bug("[ATA%02ld] This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1227 common_SetBestXferMode(unit);
1228 return;
1233 * first, ONLY for ATA devices, set new commands
1235 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1237 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1239 if (unit->au_XferModes & AF_XFER_RWMULTI)
1241 unit->au_Read32 = ata_ReadMultiple32;
1242 unit->au_Write32 = ata_WriteMultiple32;
1243 if (unit->au_XferModes & AF_XFER_48BIT)
1245 unit->au_Read64 = ata_ReadMultiple64;
1246 unit->au_Write64 = ata_WriteMultiple64;
1249 else
1251 unit->au_Read32 = ata_ReadSector32;
1252 unit->au_Write32 = ata_WriteSector32;
1253 if (unit->au_XferModes & AF_XFER_48BIT)
1255 unit->au_Read64 = ata_ReadSector64;
1256 unit->au_Write64 = ata_WriteSector64;
1260 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1262 unit->au_Read32 = ata_ReadDMA32;
1263 unit->au_Write32 = ata_WriteDMA32;
1264 if (unit->au_XferModes & AF_XFER_48BIT)
1266 unit->au_Read64 = ata_ReadDMA64;
1267 unit->au_Write64 = ata_WriteDMA64;
1270 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1272 unit->au_Read32 = ata_ReadDMA32;
1273 unit->au_Write32 = ata_WriteDMA32;
1274 if (unit->au_XferModes & AF_XFER_48BIT)
1276 unit->au_Read64 = ata_ReadDMA64;
1277 unit->au_Write64 = ata_WriteDMA64;
1280 else
1282 unit->au_Read32 = ata_ReadSector32;
1283 unit->au_Write32 = ata_WriteSector32;
1284 if (unit->au_XferModes & AF_XFER_48BIT)
1286 unit->au_Read64 = ata_ReadSector64;
1287 unit->au_Write64 = ata_WriteSector64;
1292 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1294 type = 8 + (mode - AB_XFER_PIO0);
1296 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1298 type = 32 + (mode - AB_XFER_MDMA7);
1299 dma=TRUE;
1301 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1303 type = 64 + (mode - AB_XFER_MDMA7);
1304 dma=TRUE;
1306 else
1308 type = 0;
1311 acb.sectors = type;
1312 if (0 != ata_exec_cmd(unit, &acb))
1314 D(bug("[ATA%02ld] ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1317 if (unit->au_DMAPort)
1319 type = ata_in(dma_Status, unit->au_DMAPort);
1320 type &= 0x60;
1321 if (dma)
1323 type |= 1 << (5 + (unit->au_UnitNum & 1));
1325 else
1327 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1330 D(bug("[DSCSI] Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1332 ata_SelectUnit(unit);
1333 ata_out(type, dma_Status, unit->au_DMAPort);
1334 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1336 D(bug("[DSCSI] New DMA Status: %02lx\n", type));
1338 else
1340 D(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1341 dma = FALSE;
1345 if (dma)
1346 unit->au_XferModes |= AF_XFER_DMA;
1347 else
1348 unit->au_XferModes &=~AF_XFER_DMA;
1351 static void common_SetBestXferMode(struct ata_Unit* unit)
1353 int iter;
1354 int max = AB_XFER_UDMA7;
1356 if (unit->au_DMAPort == 0)
1359 * make sure you reduce scan search to pio here!
1360 * otherwise this and above function will fall into infinite loop
1362 D(bug("[ATA%02ld] This controller does not own DMA port\n", unit->au_UnitNum));
1363 max = AB_XFER_PIO7;
1366 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1368 if (unit->au_XferModes & (1<<iter))
1370 common_SetXferMode(unit, iter);
1371 return;
1374 bug("[ATA%02ld] ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1375 common_SetXferMode(unit, AB_XFER_PIO0);
1378 void common_DetectXferModes(struct ata_Unit* unit)
1380 int iter;
1382 D(bug("[ATA%02ld] Supports\n", unit->au_UnitNum));
1384 if (unit->au_Drive->id_Commands4 & (1 << 4))
1386 D(bug("[ATA%02ld] - Packet interface\n", unit->au_UnitNum));
1387 unit->au_XferModes |= AF_XFER_PACKET;
1388 unit->au_DirectSCSI = atapi_DirectSCSI;
1390 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1392 /* ATAPI devices do not use this bit. */
1393 D(bug("[ATA%02ld] - 48bit I/O\n", unit->au_UnitNum));
1394 unit->au_XferModes |= AF_XFER_48BIT;
1397 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1399 D(bug("[ATA%02ld] - LBA Addressing\n", unit->au_UnitNum));
1400 unit->au_XferModes |= AF_XFER_LBA;
1402 else
1404 D(bug("[ATA%02ld] - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1407 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1409 D(bug("[ATA%02ld] - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1410 unit->au_XferModes |= AF_XFER_RWMULTI;
1413 if (unit->au_Drive->id_PIOSupport & 0xff)
1415 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1416 for (iter=0; iter<8; iter++)
1418 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1420 D(bug("PIO%ld ", iter));
1421 unit->au_XferModes |= AF_XFER_PIO(iter);;
1424 D(bug("\n"));
1427 if (unit->au_Drive->id_Capabilities & (1<<8))
1429 D(bug("[ATA%02ld] DMA:\n", unit->au_UnitNum));
1430 if (unit->au_Drive->id_MWDMASupport & 0xff)
1432 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1433 for (iter=0; iter<8; iter++)
1435 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1437 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1438 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1440 D(bug("[MDMA%ld] ", iter));
1442 else
1444 D(bug("MDMA%ld ", iter));
1448 D(bug("\n"));
1451 if (unit->au_Drive->id_UDMASupport & 0xff)
1453 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1454 for (iter=0; iter<8; iter++)
1456 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1458 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1459 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1461 D(bug("[UDMA%ld] ", iter));
1463 else
1465 D(bug("UDMA%ld ", iter));
1469 D(bug("\n"));
1474 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1475 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1476 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1478 ULONG atapi_Identify(struct ata_Unit* unit)
1480 ata_CommandBlock acb =
1482 ATA_IDENTIFY_ATAPI,
1488 unit->au_Drive,
1489 sizeof(struct DriveIdent),
1491 CM_PIORead,
1492 CT_NoBlock
1495 ata_SelectUnit(unit);
1496 if (ata_WaitBusyTO(unit, 1, FALSE) == FALSE)
1498 bug("[ATA%02ld] Unit not ready after timeout. Aborting.\n", unit->au_UnitNum);
1499 return IOERR_UNITBUSY;
1502 if (ata_exec_cmd(unit, &acb))
1504 return IOERR_OPENFAIL;
1507 #if (AROS_BIG_ENDIAN != 0)
1508 SWAP_LE_WORD(unit->au_Drive->id_General);
1509 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1510 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1511 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1512 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1513 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1514 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1515 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1516 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1517 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1518 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1519 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1520 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1521 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1522 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1523 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1524 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1525 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1526 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1527 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1528 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1529 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1530 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1531 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1532 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1533 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1534 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1535 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1536 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1537 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1538 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1539 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1540 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1541 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1542 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1543 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1544 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1545 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1546 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1547 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1548 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1549 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1550 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1552 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1553 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1554 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1556 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1557 #endif
1560 D(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1562 unit->au_SectorShift = 11;
1563 unit->au_Read32 = atapi_Read;
1564 unit->au_Write32 = atapi_Write;
1565 unit->au_DirectSCSI = atapi_DirectSCSI;
1566 unit->au_Eject = atapi_Eject;
1567 unit->au_Flags |= AF_DiscPresenceUnknown;
1568 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1569 unit->au_XferModes = AF_XFER_PACKET;
1571 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1572 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1573 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1575 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1576 common_DetectXferModes(unit);
1577 common_SetBestXferMode(unit);
1579 if (unit->au_Drive->id_General & 0x80)
1581 D(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1582 unit->au_Flags |= AF_Removable;
1585 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1586 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1587 bug("[ATA%02ld] 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));
1590 * ok, this is not very original, but quite compatible :P
1592 switch (unit->au_DevType)
1594 case DG_CDROM:
1595 case DG_WORM:
1596 case DG_OPTICAL_DISK:
1597 unit->au_SectorShift = 11;
1598 unit->au_Flags |= AF_SlowDevice;
1599 unit->au_Heads = 1;
1600 unit->au_Sectors = 75;
1601 unit->au_Cylinders = 4440;
1602 break;
1604 case DG_DIRECT_ACCESS:
1605 unit->au_SectorShift = 9;
1606 if (!strcmp("LS-120", &unit->au_Model[0]))
1608 unit->au_Flags |= AF_SlowDevice;
1609 unit->au_Heads = 2;
1610 unit->au_Sectors = 18;
1611 unit->au_Cylinders = 6848;
1613 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1615 unit->au_Flags &= ~AF_SlowDevice;
1616 unit->au_Heads = 1;
1617 unit->au_Sectors = 64;
1618 unit->au_Cylinders = 3072;
1620 break;
1623 unit->au_NumLoop = 10000000;
1624 return 0;
1627 ULONG ata_Identify(struct ata_Unit* unit)
1629 ata_CommandBlock acb =
1631 ATA_IDENTIFY_DEVICE,
1637 unit->au_Drive,
1638 sizeof(struct DriveIdent),
1640 CM_PIORead,
1641 CT_NoBlock
1644 if (ata_exec_cmd(unit, &acb))
1646 return IOERR_OPENFAIL;
1649 #if (AROS_BIG_ENDIAN != 0)
1650 SWAP_LE_WORD(unit->au_Drive->id_General);
1651 SWAP_LE_WORD(unit->au_Drive->id_OldCylinders);
1652 SWAP_LE_WORD(unit->au_Drive->id_SpecificConfig);
1653 SWAP_LE_WORD(unit->au_Drive->id_OldHeads);
1654 SWAP_LE_WORD(unit->au_Drive->id_OldSectors);
1655 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleSize);
1656 SWAP_LE_WORD(unit->au_Drive->id_Capabilities);
1657 SWAP_LE_WORD(unit->au_Drive->id_OldCaps);
1658 SWAP_LE_WORD(unit->au_Drive->id_OldPIO);
1659 SWAP_LE_WORD(unit->au_Drive->id_ConfigAvailable);
1660 SWAP_LE_WORD(unit->au_Drive->id_OldLCylinders);
1661 SWAP_LE_WORD(unit->au_Drive->id_OldLHeads);
1662 SWAP_LE_WORD(unit->au_Drive->id_OldLSectors);
1663 SWAP_LE_WORD(unit->au_Drive->id_RWMultipleTrans);
1664 SWAP_LE_WORD(unit->au_Drive->id_MWDMASupport);
1665 SWAP_LE_WORD(unit->au_Drive->id_PIOSupport);
1666 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_MinCycleTime);
1667 SWAP_LE_WORD(unit->au_Drive->id_MWDMA_DefCycleTime);
1668 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTime);
1669 SWAP_LE_WORD(unit->au_Drive->id_PIO_MinCycleTImeIORDY);
1670 SWAP_LE_WORD(unit->au_Drive->id_QueueDepth);
1671 SWAP_LE_WORD(unit->au_Drive->id_ATAVersion);
1672 SWAP_LE_WORD(unit->au_Drive->id_ATARevision);
1673 SWAP_LE_WORD(unit->au_Drive->id_Commands1);
1674 SWAP_LE_WORD(unit->au_Drive->id_Commands2);
1675 SWAP_LE_WORD(unit->au_Drive->id_Commands3);
1676 SWAP_LE_WORD(unit->au_Drive->id_Commands4);
1677 SWAP_LE_WORD(unit->au_Drive->id_Commands5);
1678 SWAP_LE_WORD(unit->au_Drive->id_Commands6);
1679 SWAP_LE_WORD(unit->au_Drive->id_UDMASupport);
1680 SWAP_LE_WORD(unit->au_Drive->id_SecurityEraseTime);
1681 SWAP_LE_WORD(unit->au_Drive->id_EnchSecurityEraseTime);
1682 SWAP_LE_WORD(unit->au_Drive->id_CurrentAdvowerMode);
1683 SWAP_LE_WORD(unit->au_Drive->id_MasterPwdRevision);
1684 SWAP_LE_WORD(unit->au_Drive->id_HWResetResult);
1685 SWAP_LE_WORD(unit->au_Drive->id_AcousticManagement);
1686 SWAP_LE_WORD(unit->au_Drive->id_StreamMinimunReqSize);
1687 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimeDMA);
1688 SWAP_LE_WORD(unit->au_Drive->id_StreamingLatency);
1689 SWAP_LE_WORD(unit->au_Drive->id_StreamingTimePIO);
1690 SWAP_LE_WORD(unit->au_Drive->id_PhysSectorSize);
1691 SWAP_LE_WORD(unit->au_Drive->id_RemMediaStatusNotificationFeatures);
1692 SWAP_LE_WORD(unit->au_Drive->id_SecurityStatus);
1694 SWAP_LE_LONG(unit->au_Drive->id_WordsPerLogicalSector);
1695 SWAP_LE_LONG(unit->au_Drive->id_LBASectors);
1696 SWAP_LE_LONG(unit->au_Drive->id_StreamingGranularity);
1698 SWAP_LE_QUAD(unit->au_Drive->id_LBA48Sectors);
1699 #endif
1701 D(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1703 unit->au_SectorShift = 9;
1704 unit->au_DevType = DG_DIRECT_ACCESS;
1705 unit->au_Read32 = ata_ReadSector32;
1706 unit->au_Write32 = ata_WriteSector32;
1707 unit->au_DirectSCSI = atapi_DirectSCSI;
1708 unit->au_Eject = ata_Eject;
1709 unit->au_XferModes = 0;
1710 unit->au_Flags |= AF_DiscPresent;
1711 unit->au_DevType = DG_DIRECT_ACCESS;
1713 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1714 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1715 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1717 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev);
1718 common_DetectXferModes(unit);
1719 common_SetBestXferMode(unit);
1721 if (unit->au_Drive->id_General & 0x80)
1723 D(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1724 unit->au_Flags |= AF_Removable;
1727 unit->au_NumLoop = 4000000;
1729 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1730 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1731 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));
1734 For drive capacities > 8.3GB assume maximal possible layout.
1735 It really doesn't matter here, as BIOS will not handle them in
1736 CHS way anyway :)
1737 i guess this just solves that weirdo div-by-zero crash, if anything else...
1739 if (unit->au_Drive->id_LBASectors > (63*255*1024))
1741 unit->au_Cylinders = unit->au_Drive->id_LBASectors / (255*63);
1742 unit->au_Heads = 255;
1743 unit->au_Sectors = 63;
1745 else
1747 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1748 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1749 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1751 return 0;
1756 * ata read32 commands
1758 static ULONG ata_ReadSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1760 ata_CommandBlock acb =
1762 ATA_READ,
1766 block,
1767 count,
1768 buffer,
1769 count << unit->au_SectorShift,
1771 CM_PIORead,
1772 CT_LBA28
1774 register ULONG err;
1776 *act = 0;
1777 if (0 != (err = ata_exec_blk(unit, &acb)))
1778 return err;
1780 *act = count << unit->au_SectorShift;
1781 return 0;
1784 static ULONG ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1786 ata_CommandBlock acb =
1788 ATA_READ_MULTIPLE,
1790 unit->au_Drive->id_RWMultipleSize & 0xff,
1792 block,
1793 count,
1794 buffer,
1795 count << unit->au_SectorShift,
1797 CM_PIORead,
1798 CT_LBA28
1800 register ULONG err;
1802 *act = 0;
1803 if (0 != (err = ata_exec_blk(unit, &acb)))
1804 return err;
1806 *act = count << unit->au_SectorShift;
1807 return 0;
1810 static ULONG ata_ReadDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1812 register ULONG err;
1813 ata_CommandBlock acb =
1815 ATA_READ_DMA,
1819 block,
1820 count,
1821 buffer,
1822 count << unit->au_SectorShift,
1824 CM_DMARead,
1825 CT_LBA28
1828 *act = 0;
1829 if (0 != (err = ata_exec_blk(unit, &acb)))
1830 return err;
1832 *act = count << unit->au_SectorShift;
1833 return 0;
1838 * ata read64 commands
1840 static ULONG ata_ReadSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1842 ata_CommandBlock acb =
1844 ATA_READ64,
1848 block,
1849 count,
1850 buffer,
1851 count << unit->au_SectorShift,
1853 CM_PIORead,
1854 CT_LBA48
1856 register ULONG err = 0;
1858 *act = 0;
1859 if (0 != (err = ata_exec_blk(unit, &acb)))
1860 return err;
1862 *act = count << unit->au_SectorShift;
1863 return 0;
1866 static ULONG ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1868 ata_CommandBlock acb =
1870 ATA_READ_MULTIPLE64,
1872 unit->au_Drive->id_RWMultipleSize & 0xff,
1874 block,
1875 count,
1876 buffer,
1877 count << unit->au_SectorShift,
1879 CM_PIORead,
1880 CT_LBA48
1882 register ULONG err;
1884 *act = 0;
1885 if (0 != (err = ata_exec_blk(unit, &acb)))
1886 return err;
1888 *act = count << unit->au_SectorShift;
1889 return 0;
1892 static ULONG ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1894 ata_CommandBlock acb =
1896 ATA_READ_DMA64,
1900 block,
1901 count,
1902 buffer,
1903 count << unit->au_SectorShift,
1905 CM_DMARead,
1906 CT_LBA48
1908 register ULONG err;
1910 *act = 0;
1911 if (0 != (err = ata_exec_blk(unit, &acb)))
1912 return err;
1914 *act = count << unit->au_SectorShift;
1915 return 0;
1920 * ata write32 commands
1922 static ULONG ata_WriteSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1924 ata_CommandBlock acb =
1926 ATA_WRITE,
1930 block,
1931 count,
1932 buffer,
1933 count << unit->au_SectorShift,
1935 CM_PIOWrite,
1936 CT_LBA28
1938 register ULONG err;
1940 *act = 0;
1941 if (0 != (err = ata_exec_blk(unit, &acb)))
1942 return err;
1944 *act = count << unit->au_SectorShift;
1945 return 0;
1948 static ULONG ata_WriteMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1950 ata_CommandBlock acb =
1952 ATA_WRITE_MULTIPLE,
1954 unit->au_Drive->id_RWMultipleSize & 0xff,
1956 block,
1957 count,
1958 buffer,
1959 count << unit->au_SectorShift,
1961 CM_PIOWrite,
1962 CT_LBA28
1964 register ULONG err;
1966 *act = 0;
1967 if (0 != (err = ata_exec_blk(unit, &acb)))
1968 return err;
1970 *act = count << unit->au_SectorShift;
1971 return 0;
1974 static ULONG ata_WriteDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1976 ata_CommandBlock acb =
1978 ATA_WRITE_DMA,
1982 block,
1983 count,
1984 buffer,
1985 count << unit->au_SectorShift,
1987 CM_DMAWrite,
1988 CT_LBA28
1990 register ULONG err;
1992 *act = 0;
1993 if (0 != (err = ata_exec_blk(unit, &acb)))
1994 return err;
1996 *act = count << unit->au_SectorShift;
1997 return 0;
2002 * ata write64 commands
2004 static ULONG ata_WriteSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2006 ata_CommandBlock acb =
2008 ATA_WRITE64,
2012 block,
2013 count,
2014 buffer,
2015 count << unit->au_SectorShift,
2017 CM_PIOWrite,
2018 CT_LBA48
2020 register ULONG err;
2022 *act = 0;
2023 if (0 != (err = ata_exec_blk(unit, &acb)))
2024 return err;
2026 *act = count << unit->au_SectorShift;
2027 return 0;
2030 static ULONG ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2032 ata_CommandBlock acb =
2034 ATA_WRITE_MULTIPLE64,
2036 unit->au_Drive->id_RWMultipleSize & 0xff,
2038 block,
2039 count,
2040 buffer,
2041 count << unit->au_SectorShift,
2043 CM_PIOWrite,
2044 CT_LBA48
2046 register ULONG err;
2048 *act = 0;
2049 if (0 != (err = ata_exec_blk(unit, &acb)))
2050 return err;
2052 *act = count << unit->au_SectorShift;
2053 return 0;
2056 static ULONG ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
2058 ata_CommandBlock acb =
2060 ATA_WRITE_DMA64,
2064 block,
2065 count,
2066 buffer,
2067 count << unit->au_SectorShift,
2069 CM_DMAWrite,
2070 CT_LBA48
2072 register ULONG err;
2074 *act = 0;
2075 if (0 != (err = ata_exec_blk(unit, &acb)))
2076 return err;
2078 *act = count << unit->au_SectorShift;
2079 return 0;
2083 * ata miscellaneous commands
2085 static ULONG ata_Eject(struct ata_Unit *unit)
2087 ata_CommandBlock acb =
2089 ATA_MEDIA_EJECT,
2098 CM_NoData,
2099 CT_NoBlock
2102 return ata_exec_cmd(unit, &acb);
2106 * atapi commands
2108 int atapi_TestUnitOK(struct ata_Unit *unit)
2110 UBYTE cmd[6] = {
2113 UBYTE sense[4] = {
2116 struct SCSICmd sc = {
2120 sc.scsi_Command = (void*) &cmd;
2121 sc.scsi_CmdLength = sizeof(cmd);
2122 sc.scsi_SenseData = (void*)&sense;
2123 sc.scsi_SenseLength = sizeof(sense);
2124 sc.scsi_Flags = SCSIF_AUTOSENSE;
2126 unit->au_DirectSCSI(unit, &sc);
2127 unit->au_SenseKey = sense[2];
2128 D(bug("[ATA%02ld] Test Unit Ready sense: %02lx\n", unit->au_UnitNum, sense[2]));
2129 return sense[2];
2132 static ULONG atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2134 UBYTE cmd[] = {
2135 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2137 struct SCSICmd sc = {
2141 sc.scsi_Command = (void*) &cmd;
2142 sc.scsi_CmdLength = sizeof(cmd);
2143 sc.scsi_Data = buffer;
2144 sc.scsi_Length = count << unit->au_SectorShift;
2145 sc.scsi_Flags = SCSIF_READ;
2147 return unit->au_DirectSCSI(unit, &sc);
2150 static ULONG atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
2152 UBYTE cmd[] = {
2153 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
2155 struct SCSICmd sc = {
2159 sc.scsi_Command = (void*) &cmd;
2160 sc.scsi_CmdLength = sizeof(cmd);
2161 sc.scsi_Data = buffer;
2162 sc.scsi_Length = count << unit->au_SectorShift;
2163 sc.scsi_Flags = SCSIF_WRITE;
2165 return unit->au_DirectSCSI(unit, &sc);
2168 static ULONG atapi_Eject(struct ata_Unit *unit)
2170 struct atapi_StartStop cmd = {
2171 command: SCSI_STARTSTOP,
2172 immediate: 1,
2173 flags: ATAPI_SS_EJECT,
2176 struct SCSICmd sc = {
2180 sc.scsi_Command = (void*) &cmd;
2181 sc.scsi_CmdLength = sizeof(cmd);
2182 sc.scsi_Flags = SCSIF_READ;
2184 return unit->au_DirectSCSI(unit, &sc);
2187 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
2189 UBYTE cmd[] = {
2190 3, 0, 0, 0, senselen & 0xfe, 0
2192 struct SCSICmd sc = {
2196 if ((senselen == 0) || (sense == 0))
2198 return 0;
2200 sc.scsi_Data = (void*)sense;
2201 sc.scsi_Length = senselen & 0xfe;
2202 sc.scsi_Command = (void*)&cmd;
2203 sc.scsi_CmdLength = 6;
2204 sc.scsi_Flags = SCSIF_READ;
2206 unit->au_DirectSCSI(unit, &sc);
2208 int t,p,q;
2209 for (q=0; q<((senselen+15)>>4); q++)
2211 p = 16;
2212 if ((senselen - (q<<4)) < p)
2213 p = (senselen - (q<<4));
2215 bug("[SENSE] %02lx:", q<<4);
2216 for (t=0; t<p; t++)
2217 bug("%02lx ", sense[(q<<4) + t]);
2218 bug("\n");
2222 D(bug("[SENSE] sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
2223 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
2228 * --------------------------------------------------------------
2229 * - here ends the code that makes any sense. rest to be removed -
2230 * --------------------------------------------------------------
2234 void ata_usleep(struct timerequest *tr, ULONG usec)
2236 tr->tr_node.io_Command = TR_ADDREQUEST;
2237 tr->tr_time.tv_micro = usec % 1000000;
2238 tr->tr_time.tv_secs = usec / 1000000;
2240 DoIO((struct IORequest *)tr);
2244 Device scan routines - TO BE REPLACED
2246 void ata_ResetBus(struct timerequest *tr, struct ata_Bus *bus)
2248 ULONG port = bus->ab_Port;
2249 ULONG alt = bus->ab_Alt;
2250 int cnt;
2252 /* Exclusive use of ATA registers */
2253 ObtainSemaphore(&bus->ab_Lock);
2255 /* Disable IRQ */
2256 ata_EnableIRQ(bus, FALSE);
2257 /* Issue software reset */
2258 ata_out(0x04, ata_AltControl, alt);
2259 /* wait a while */
2260 ata_usleep(tr, 400);
2261 /* Clear reset signal */
2262 ata_EnableIRQ(bus, FALSE);
2263 /* And wait again */
2264 ata_usleep(tr, 400);
2265 /* wait for dev0 to come online. Limited delay up to 30µs */
2266 if (bus->ab_Dev[0] != DEV_NONE)
2268 cnt=1000; // 1000ms delay for slowest devices to reply.
2269 while (cnt--)
2271 if ((ata_in(ata_Status, port) & ATAF_BUSY) == 0)
2272 break;
2273 ata_usleep(tr, 1000);
2277 /* wait for dev1 to come online. Limited delay up to 30µs */
2278 if (bus->ab_Dev[1] != DEV_NONE)
2280 ata_out(0xb0, ata_DevHead, port);
2281 ata_usleep(tr, 100);
2283 cnt=1000;
2284 while (cnt--)
2286 if ((ata_in(ata_Status, port) & ATAF_BUSY) == 0)
2287 break;
2289 ata_usleep(tr, 1000);
2293 ReleaseSemaphore(&bus->ab_Lock);
2297 * same here
2299 void ata_ScanBus(struct ata_Bus *bus)
2301 ULONG port = bus->ab_Port;
2302 UBYTE tmp1, tmp2;
2304 struct MsgPort *p = CreateMsgPort();
2305 struct timerequest *tr = (struct timerequest *)CreateIORequest((struct MsgPort *)p,
2306 sizeof(struct timerequest));
2307 OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0);
2309 /* Exclusive use of ATA registers */
2310 ObtainSemaphore(&bus->ab_Lock);
2312 bus->ab_Dev[0] = DEV_NONE;
2313 bus->ab_Dev[1] = DEV_NONE;
2315 /* Disable IDE IRQ */
2316 ata_EnableIRQ(bus, FALSE);
2318 /* Select device 0 */
2319 ata_out(0xa0, ata_DevHead, port);
2320 ata_usleep(tr, 100);
2322 /* Write some pattern to registers */
2323 ata_out(0x55, ata_Count, port);
2324 ata_out(0xaa, ata_LBALow, port);
2325 ata_out(0xaa, ata_Count, port);
2326 ata_out(0x55, ata_LBALow, port);
2327 ata_out(0x55, ata_Count, port);
2328 ata_out(0xaa, ata_LBALow, port);
2330 tmp1 = ata_in(ata_Count, port);
2331 tmp2 = ata_in(ata_LBALow, port);
2333 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2334 bus->ab_Dev[0] = DEV_UNKNOWN;
2336 /* Select device 1 */
2337 ata_out(0xb0, ata_DevHead, port);
2338 ata_usleep(tr, 100);
2340 /* Write some pattern to registers */
2341 ata_out(0x55, ata_Count, port);
2342 ata_out(0xaa, ata_LBALow, port);
2343 ata_out(0xaa, ata_Count, port);
2344 ata_out(0x55, ata_LBALow, port);
2345 ata_out(0x55, ata_Count, port);
2346 ata_out(0xaa, ata_LBALow, port);
2348 tmp1 = ata_in(ata_Count, port);
2349 tmp2 = ata_in(ata_LBALow, port);
2351 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2352 bus->ab_Dev[1] = DEV_UNKNOWN;
2355 * According to ATA specs it is quite possible, that the dev0 will respond
2356 * for both self and dev1. Similar, when only dev1 is available, it may as
2357 * well respond as dev0. Do more precise test now.
2359 ata_out(0xa0, ata_DevHead, port);
2360 ata_usleep(tr, 100);
2361 ata_ResetBus(tr, bus);
2363 /* check device 0 */
2364 ata_out(0xa0, ata_DevHead, port);
2365 ata_usleep(tr, 100);
2367 /* Check basic signature. All live devices should provide it */
2368 tmp1 = ata_in(ata_Count, port);
2369 tmp2 = ata_in(ata_LBALow, port);
2370 D(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2372 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2374 /* Ok, ATA/ATAPI device. Get detailed signature */
2375 D(bug("[ATA ] Found an ATA[PI] Device[0]. Attempting to detect specific subtype\n"));
2377 bus->ab_Dev[0] = DEV_UNKNOWN;
2378 tmp1 = ata_in(ata_LBAMid, port);
2379 tmp2 = ata_in(ata_LBAHigh, port);
2381 D(bug("[ATA ] Subtype check returned %02lx:%02lx\n", tmp1, tmp2));
2383 if ((tmp1 == 0x14) && (tmp2 == 0xeb))
2385 bus->ab_Dev[0] = DEV_ATAPI;
2387 else if ((tmp1 == 0) && (tmp2 == 0) && ((ata_in(ata_Status, port) & 0xfe) != 0))
2389 bus->ab_Dev[0] = DEV_ATA;
2391 else if ((tmp1 == 0x3c) && (tmp2 == 0xc3))
2393 bus->ab_Dev[0] = DEV_SATA;
2395 else if ((tmp1 == 0x69) && (tmp2 == 0x96))
2397 bus->ab_Dev[0] = DEV_SATAPI;
2401 /* check device 1 */
2402 ata_out(0xb0, ata_DevHead, port);
2403 ata_usleep(tr, 100);
2405 /* Check basic signature. All live devices should provide it */
2406 tmp1 = ata_in(ata_Count, port);
2407 tmp2 = ata_in(ata_LBALow, port);
2408 D(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2410 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2412 D(bug("[ATA ] Found an ATA[PI] Device[1]. Attempting to detect specific subtype\n"));
2413 /* Ok, ATA/ATAPI device. Get detailed signature */
2414 bus->ab_Dev[1] = DEV_UNKNOWN;
2415 tmp1 = ata_in(ata_LBAMid, port);
2416 tmp2 = ata_in(ata_LBAHigh, port);
2418 D(bug("[ATA ] Subtype check returned %02lx:%02lx\n", tmp1, tmp2));
2420 if ((tmp1 == 0x14) && (tmp2 == 0xeb))
2422 bus->ab_Dev[1] = DEV_ATAPI;
2424 else if ((tmp1 == 0) && (tmp2 == 0) && ((ata_in(ata_Status, port) & 0xfe) != 0))
2426 bus->ab_Dev[1] = DEV_ATA;
2428 else if ((tmp1 == 0x3c) && (tmp2 == 0xc3))
2430 bus->ab_Dev[0] = DEV_SATA;
2432 else if ((tmp1 == 0x69) && (tmp2 == 0x96))
2434 bus->ab_Dev[0] = DEV_SATAPI;
2439 * restore IRQ
2441 ReleaseSemaphore(&bus->ab_Lock);
2443 CloseDevice((struct IORequest *)tr);
2444 DeleteIORequest((struct IORequest *)tr);
2445 DeleteMsgPort(p);
2449 * not really sure what this is meant to be - TO BE REPLACED
2451 static const ULONG ErrorMap[] = {
2452 CDERR_NotSpecified,
2453 CDERR_NoSecHdr,
2454 CDERR_NoDisk,
2455 CDERR_NoSecHdr,
2456 CDERR_NoSecHdr,
2457 CDERR_NOCMD,
2458 CDERR_NoDisk,
2459 CDERR_WriteProt,
2460 CDERR_NotSpecified,
2461 CDERR_NotSpecified,
2462 CDERR_NotSpecified,
2463 CDERR_ABORTED,
2464 CDERR_NotSpecified,
2465 CDERR_NotSpecified,
2466 CDERR_NoSecHdr,
2467 CDERR_NotSpecified,
2470 static ULONG atapi_EndCmd(struct ata_Unit *unit)
2472 unit->au_Flags |= AF_Used;
2473 UBYTE status;
2476 * read alternate status register (per specs)
2478 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2479 D(bug("[ATAPI] Alternate status: %lx\n", status));
2481 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2483 D(bug("[ATAPI] Command complete. Status: %lx\n", status));
2485 if (!(status & ATAPIF_CHECK))
2487 return 0;
2489 else
2491 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2492 D(bug("[ATAPI] Error code %lx\n", status >> 4));
2493 return ErrorMap[status >> 4];
2498 * vim: ts=4 et sw=4 fdm=marker fmr={,}