2 Copyright © 2004-2008, The AROS Development Team. All rights reserved
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
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
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>
55 #include <proto/exec.h>
56 #include <devices/timer.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
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
98 * having an x86 assembly here i dare to assume that this is meant to be
99 * an x86[_64] device only.
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
)
121 insw(port
, address
, count
>> 1);
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
)
134 outsw(port
, address
, count
>> 1);
136 outsl(port
, address
, count
>> 2);
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
);
145 static void dump(APTR mem
, ULONG len
)
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
]);
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
: '.' : '.');
171 static void ata_strcpy(const UBYTE
*str1
, UBYTE
*str2
, ULONG size
)
173 register int i
= size
;
177 str2
[size
^1] = str1
[size
];
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
));
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
));
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
);
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
));
216 * Very short delay (TM) by someone who assumes slow data ports.
217 * well, glad it works anyways.
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
);
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
)
272 ULONG sigs
= SIGBREAKF_CTRL_C
| (irq
? (1 << unit
->au_Bus
->ab_SleepySignal
) : 0);
277 * clear up all old signals
282 * set up bus timeout and irq
285 ata_EnableIRQ(unit
->au_Bus
, irq
);
286 unit
->au_Bus
->ab_Timeout
= tout
;
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
))
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)
317 * wait for either IRQ or TIMEOUT
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
);
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
);
340 * device not ready just yet. lets set whether we want an IRQ and move on - to polling or irq wait
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
));
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
377 ata_EnableIRQ(unit
->au_Bus
, FALSE
);
378 unit
->au_Bus
->ab_Timeout
= -1;
387 * and say it went fine (i mean it)
393 * just wait for timeout
395 void ata_Wait(struct ata_Unit
*unit
, UWORD tout
)
397 SetSignal(0, SIGBREAKF_CTRL_C
);
400 unit
->au_Bus
->ab_Timeout
= tout
;
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
)
422 ULONG port
= au
->au_Bus
->ab_Port
;
424 APTR mem
= block
->buffer
;
430 * initial checks and stuff
432 switch (block
->method
)
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
;
456 * we want the above to fall in here!
457 * we really do (checking for secmul)
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
);
477 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au
->au_UnitNum
, block
->type
);
488 * PRECONDITIONS: ENABLED INTRQ (0x08 written to ata_Command port)
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
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
);
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
);
537 //D(bug("[ATA%02ld] Command does not address any block\n", au->au_UnitNum));
544 * setup DMA & push command
546 switch (block
->method
)
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
);
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
);
567 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
568 ata_out(block
->command
, ata_Command
, port
);
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
;
583 if (block
->method
== CM_PIORead
)
591 * entering main command loop here.
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
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));
622 //D(bug("[ATA%02ld] DMA transfer is still in progress\n", au->au_UnitNum));
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
;
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
);
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
)
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
673 * transferring one block at a time, no more.
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
];
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
689 * transferring one block at a time, no more.
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
];
699 * we will never get here.
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
)
711 bug("[ATA%02ld] Command %lx finished with an error. Aborting.\n", au
->au_UnitNum
, block
->command
);
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
))
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));
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
;
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));
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));
757 CachePostDMA(block
->buffer
, &block
->length
, 0);
759 //D(bug("[ATA%02ld] All done\n", au->au_UnitNum));
764 * signal error back to caller
769 stat
= ata_in(ata_Status
, port
);
770 if (stat
& ATAF_ERROR
)
771 return IOERR_ABORTED
;
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
;
786 register int t
=5,l
=0;
787 ULONG port
= unit
->au_Bus
->ab_Port
;
789 if (((UBYTE
*)packet
)[0] > 0x1f)
791 if (((UBYTE
*)packet
)[0] > 0x5f)
794 switch (((UBYTE
*)packet
)[0])
799 case 0xb9: // readcdmsf
802 case 0xaa: // write12
803 case 0x2e: // writeverify
811 cmd
[l
] = ((UBYTE
*)packet
)[l
];
816 bug("[ATAPI] Sending %s ATA packet: ", (*dma
) ? "DMA" : "PIO");
820 bug("%02lx ", ((UBYTE
*)cmd
)[l
]);
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
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);
879 D(bug("[ATAPI] interface not ready to retrieve data. Status: %lx\n", status
));
884 D(bug("[ATAPI] WaitBusy failed at first check\n"));
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
;
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
);
918 dma_SetupPRDSize(unit
, cmd
->scsi_Data
, cmd
->scsi_Length
, FALSE
);
919 CachePreDMA(cmd
->scsi_Data
, &cmd
->scsi_Length
, 0);
924 if (atapi_SendPacket(unit
, cmd
->scsi_Command
, cmd
->scsi_Length
, &dma
, (cmd
->scsi_Flags
& SCSIF_READ
) == 0))
931 if (ata_WaitBusyTO(unit
, 30, TRUE
) == FALSE
)
933 D(bug("[DSCSI] Command timed out.\n"));
934 err
= IOERR_UNITBUSY
;
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
));
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! */
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"));
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! */
975 unit
->au_outs(buffer
, port
, size
);
976 D(bug("[DSCSI] %lu bytes written.\n", size
));
980 D(bug("[DSCSI] Drive data ready, but there's no storage to transfer. R != W\n"));
982 err
= CDERR_InvalidState
;
986 cmd
->scsi_Actual
+= size
;
992 D(bug("[DSCSI] User transfer complete, %ld bytes transferred.\n", cmd
->scsi_Actual
));
993 err
= atapi_EndCmd(unit
);
1004 if (FALSE
== ata_WaitBusyTO(unit
, 30, TRUE
))
1006 err
= IOERR_UNITBUSY
;
1010 status
= ata_in(ata_Status
, port
);
1011 if (0 == (status
& (ATAF_BUSY
| ATAF_DATAREQ
)))
1014 status
= ata_in(dma_Status
, unit
->au_DMAPort
);
1015 D(bug("[ATAPI] DMA status: %lx\n", status
));
1016 if (0 == (status
& DMAF_Active
))
1020 if (0 != (status
& DMAF_Error
))
1022 err
= IOERR_ABORTED
;
1031 err
= CDERR_ABORTED
;
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
));
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
)
1073 ULONG count
=blk
->sectors
;
1075 if (blk
->type
== CT_LBA48
)
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
);
1088 blk
->buffer
= &((char*)blk
->buffer
)[part
<< unit
->au_SectorShift
];
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
];
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
;
1118 unit
->au_ins
= ata_insw
;
1119 unit
->au_outs
= ata_outsw
;
1121 unit
->au_SectorShift
= 9; /* this really has to be set here. */
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
;
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
];
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;
1164 switch (bus
->ab_Dev
[u
])
1167 * safe fallback settings
1171 unit
->au_Identify
= atapi_Identify
;
1176 unit
->au_Identify
= ata_Identify
;
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;
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;
1205 static void common_SetXferMode(struct ata_Unit
* unit
, ata_XferMode mode
)
1209 ata_CommandBlock acb
=
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
);
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
;
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
;
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
);
1301 else if ((mode
>= AB_XFER_UDMA0
) & (mode
<= AB_XFER_UDMA7
))
1303 type
= 64 + (mode
- AB_XFER_MDMA7
);
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
);
1323 type
|= 1 << (5 + (unit
->au_UnitNum
& 1));
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
));
1340 D(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1346 unit
->au_XferModes
|= AF_XFER_DMA
;
1348 unit
->au_XferModes
&=~AF_XFER_DMA
;
1351 static void common_SetBestXferMode(struct ata_Unit
* unit
)
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
));
1366 for (iter
=max
; iter
>=AB_XFER_PIO0
; --iter
)
1368 if (unit
->au_XferModes
& (1<<iter
))
1370 common_SetXferMode(unit
, iter
);
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
)
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
;
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
);;
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
));
1444 D(bug("MDMA%ld ", iter
));
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
));
1465 D(bug("UDMA%ld ", iter
));
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
=
1489 sizeof(struct DriveIdent
),
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
);
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
)
1596 case DG_OPTICAL_DISK
:
1597 unit
->au_SectorShift
= 11;
1598 unit
->au_Flags
|= AF_SlowDevice
;
1600 unit
->au_Sectors
= 75;
1601 unit
->au_Cylinders
= 4440;
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
;
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
;
1617 unit
->au_Sectors
= 64;
1618 unit
->au_Cylinders
= 3072;
1623 unit
->au_NumLoop
= 10000000;
1627 ULONG
ata_Identify(struct ata_Unit
* unit
)
1629 ata_CommandBlock acb
=
1631 ATA_IDENTIFY_DEVICE
,
1638 sizeof(struct DriveIdent
),
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
);
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
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;
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
;
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
=
1769 count
<< unit
->au_SectorShift
,
1777 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1780 *act
= count
<< unit
->au_SectorShift
;
1784 static ULONG
ata_ReadMultiple32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1786 ata_CommandBlock acb
=
1790 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
1795 count
<< unit
->au_SectorShift
,
1803 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1806 *act
= count
<< unit
->au_SectorShift
;
1810 static ULONG
ata_ReadDMA32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1813 ata_CommandBlock acb
=
1822 count
<< unit
->au_SectorShift
,
1829 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1832 *act
= count
<< unit
->au_SectorShift
;
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
=
1851 count
<< unit
->au_SectorShift
,
1856 register ULONG err
= 0;
1859 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1862 *act
= count
<< unit
->au_SectorShift
;
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,
1877 count
<< unit
->au_SectorShift
,
1885 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1888 *act
= count
<< unit
->au_SectorShift
;
1892 static ULONG
ata_ReadDMA64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1894 ata_CommandBlock acb
=
1903 count
<< unit
->au_SectorShift
,
1911 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1914 *act
= count
<< unit
->au_SectorShift
;
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
=
1933 count
<< unit
->au_SectorShift
,
1941 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1944 *act
= count
<< unit
->au_SectorShift
;
1948 static ULONG
ata_WriteMultiple32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1950 ata_CommandBlock acb
=
1954 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
1959 count
<< unit
->au_SectorShift
,
1967 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1970 *act
= count
<< unit
->au_SectorShift
;
1974 static ULONG
ata_WriteDMA32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1976 ata_CommandBlock acb
=
1985 count
<< unit
->au_SectorShift
,
1993 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1996 *act
= count
<< unit
->au_SectorShift
;
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
=
2015 count
<< unit
->au_SectorShift
,
2023 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
2026 *act
= count
<< unit
->au_SectorShift
;
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,
2041 count
<< unit
->au_SectorShift
,
2049 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
2052 *act
= count
<< unit
->au_SectorShift
;
2056 static ULONG
ata_WriteDMA64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
2058 ata_CommandBlock acb
=
2067 count
<< unit
->au_SectorShift
,
2075 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
2078 *act
= count
<< unit
->au_SectorShift
;
2083 * ata miscellaneous commands
2085 static ULONG
ata_Eject(struct ata_Unit
*unit
)
2087 ata_CommandBlock acb
=
2102 return ata_exec_cmd(unit
, &acb
);
2108 int atapi_TestUnitOK(struct ata_Unit
*unit
)
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]));
2132 static ULONG
atapi_Read(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
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
)
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
,
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
)
2190 3, 0, 0, 0, senselen
& 0xfe, 0
2192 struct SCSICmd sc
= {
2196 if ((senselen
== 0) || (sense
== 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
);
2209 for (q
=0; q
<((senselen
+15)>>4); q
++)
2212 if ((senselen
- (q
<<4)) < p
)
2213 p
= (senselen
- (q
<<4));
2215 bug("[SENSE] %02lx:", q
<<4);
2217 bug("%02lx ", sense
[(q
<<4) + t
]);
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
;
2252 /* Exclusive use of ATA registers */
2253 ObtainSemaphore(&bus
->ab_Lock
);
2256 ata_EnableIRQ(bus
, FALSE
);
2257 /* Issue software reset */
2258 ata_out(0x04, ata_AltControl
, alt
);
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.
2271 if ((ata_in(ata_Status
, port
) & ATAF_BUSY
) == 0)
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);
2286 if ((ata_in(ata_Status
, port
) & ATAF_BUSY
) == 0)
2289 ata_usleep(tr
, 1000);
2293 ReleaseSemaphore(&bus
->ab_Lock
);
2299 void ata_ScanBus(struct ata_Bus
*bus
)
2301 ULONG port
= bus
->ab_Port
;
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
;
2441 ReleaseSemaphore(&bus
->ab_Lock
);
2443 CloseDevice((struct IORequest
*)tr
);
2444 DeleteIORequest((struct IORequest
*)tr
);
2449 * not really sure what this is meant to be - TO BE REPLACED
2451 static const ULONG ErrorMap
[] = {
2470 static ULONG
atapi_EndCmd(struct ata_Unit
*unit
)
2472 unit
->au_Flags
|= AF_Used
;
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
))
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={,}