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
43 * 2008-05-11 T. Wiszkowski Remade the ata trannsfers altogether, corrected the pio/irq handling
44 * medium removal, device detection, bus management and much more
45 * 2008-05-12 P. Fedin Explicitly enable multisector transfers on the drive
46 * 2008-05-18 T. Wiszkowski Added extra checks to prevent duplicating drive0 in drive0 only configs
47 * 2008-05-18 T. Wiszkowski Replaced static C/H/S with more accurate calcs, should make HDTB and other tools see right capacity
48 * 2008-05-19 T. Wiszkowski Updated ATA DMA handling and transfer wait operation to allow complete transfer before dma_StopDMA()
49 * 2008-05-30 T. Wiszkowski Corrected CHS calculation for larger disks
50 * 2008-06-03 K. Smiechowicz Added 400ns delay in ata_WaitBusyTO before read of device status.
54 * - put a critical section around DMA transfers (shared dma channels)
58 // use #define xxx(a) D(a) to enable particular sections.
66 #include <aros/debug.h>
67 #include <exec/types.h>
68 #include <exec/exec.h>
69 #include <exec/resident.h>
70 #include <utility/utility.h>
75 #include <proto/exec.h>
76 #include <devices/timer.h>
85 Prototypes of static functions from lowlevel.c. I do not want to make them
86 non-static as I'd like to remove as much symbols from global table as possible.
87 Besides some of this functions could conflict with old ide.device or any other
90 static ULONG
ata_ReadSector32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
91 static ULONG
ata_ReadSector64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
92 static ULONG
ata_ReadMultiple32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
93 static ULONG
ata_ReadMultiple64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
94 static ULONG
ata_ReadDMA32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
95 static ULONG
ata_ReadDMA64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
96 static ULONG
ata_WriteSector32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
97 static ULONG
ata_WriteSector64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
98 static ULONG
ata_WriteMultiple32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
99 static ULONG
ata_WriteMultiple64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
100 static ULONG
ata_WriteDMA32(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
101 static ULONG
ata_WriteDMA64(struct ata_Unit
*, UQUAD
, ULONG
, APTR
, ULONG
*);
102 static ULONG
ata_Eject(struct ata_Unit
*);
103 static BOOL
ata_WaitBusyTO(struct ata_Unit
*unit
, UWORD tout
, BOOL irq
);
105 static ULONG
atapi_EndCmd(struct ata_Unit
*unit
);
107 static ULONG
atapi_Read(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
108 static ULONG
atapi_Write(struct ata_Unit
*, ULONG
, ULONG
, APTR
, ULONG
*);
109 static ULONG
atapi_Eject(struct ata_Unit
*);
111 static void common_SetBestXferMode(struct ata_Unit
* unit
);
114 Again piece of code which shouldn't be here. Geee. After removing all this
115 asm constrictuins this ata.device will really deserve for location in
119 * having an x86 assembly here i dare to assume that this is meant to be
120 * an x86[_64] device only.
124 * This functions will stay here for some time *IF* and only if the code is compiled for
125 * x86 or x86_64 architecture. Otherwise, function declarations will be emitted and the
126 * one who ports the driver will be reponsible for adding the missing code.
130 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
132 #if defined(__i386__) || defined(__x86_64__)
134 static VOID
ata_insw(APTR address
, UWORD port
, ULONG count
)
136 insw(port
, address
, count
>> 1);
139 static VOID
ata_insl(APTR address
, UWORD port
, ULONG count
)
142 insw(port
, address
, count
>> 1);
144 insl(port
, address
, count
>> 2);
147 static VOID
ata_outsw(APTR address
, UWORD port
, ULONG count
)
149 outsw(port
, address
, count
>> 1);
152 static VOID
ata_outsl(APTR address
, UWORD port
, ULONG count
)
155 outsw(port
, address
, count
>> 1);
157 outsl(port
, address
, count
>> 2);
161 * Very short delay (TM) by someone who assumes slow data ports.
162 * well, glad it works anyways.
166 ata_in(ata_AltControl
, 0x3f6);
167 ata_in(ata_AltControl
, 0x3f6);
168 ata_in(ata_AltControl
, 0x3f6);
169 ata_in(ata_AltControl
, 0x3f6);
173 extern VOID
ata_insw(APTR address
, UWORD port
, ULONG count
);
174 extern VOID
ata_insl(APTR address
, UWORD port
, ULONG count
);
175 extern VOID
ata_outsw(APTR address
, UWORD port
, ULONG count
);
176 extern VOID
ata_outsl(APTR address
, UWORD port
, ULONG count
);
177 extern void ata_400ns();
180 static void dump(APTR mem
, ULONG len
)
183 for (j
=0; j
<(len
+15)>>4; ++j
)
185 bug("[ATA ] %06lx: ", j
<<4);
187 for (i
=0; i
<len
-(j
<<4); i
++)
189 bug("%02lx ", ((unsigned char*)mem
)[(j
<<4)|i
]);
194 for (i
=0; i
<len
-(j
<<4); i
++)
196 unsigned char c
= ((unsigned char*)mem
)[(j
<<4)|i
];
198 bug("%c", c
>= 0x20 ? c
<=0x7f ? c
: '.' : '.');
206 static void ata_strcpy(const UBYTE
*str1
, UBYTE
*str2
, ULONG size
)
208 register int i
= size
;
212 str2
[size
^1] = str1
[size
];
224 * a STUB function for commands not supported by this particular device
226 static ULONG
ata_STUB(struct ata_Unit
*au
)
228 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au
->au_UnitNum
);
232 static ULONG
ata_STUB_IO32(struct ata_Unit
*au
, ULONG blk
, ULONG len
, APTR buf
, ULONG
* act
)
234 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au
->au_UnitNum
);
238 static ULONG
ata_STUB_IO64(struct ata_Unit
*au
, UQUAD blk
, ULONG len
, APTR buf
, ULONG
* act
)
240 bug("[ATA%02ld] CALLED STUB FUNCTION -- IO ACCESS TO BLOCK %08lx:%08lx, LENGTH %08lx. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au
->au_UnitNum
, (blk
>> 32), (blk
& 0xffffffff), len
);
244 static ULONG
ata_STUB_SCSI(struct ata_Unit
*au
, struct SCSICmd
* cmd
)
246 bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au
->au_UnitNum
);
250 inline BOOL
ata_SelectUnit(struct ata_Unit
* unit
)
252 ata_out(unit
->au_DevMask
, ata_DevHead
, unit
->au_Bus
->ab_Port
);
258 while (0 != (ATAF_BUSY
& ata_ReadStatus(unit
->au_Bus
)));
263 inline struct ata_Unit
* ata_GetSelectedUnit(struct ata_Bus
* bus
)
265 register int id
= (ata_in(ata_DevHead
, bus
->ab_Port
) & 0x10) >> 4;
266 return bus
->ab_Units
[id
];
269 UBYTE
ata_ReadStatus(struct ata_Bus
*bus
)
271 return ata_in(ata_Status
, bus
->ab_Port
);
275 * enable / disable IRQ; this manages interrupt requests more effectively in case of legacy emulation
276 * as little code as there can be. and keep it that way.
278 void ata_EnableIRQ(struct ata_Bus
*bus
, BOOL enable
)
280 enable
&= (bus
->ab_Dev
[0] > DEV_UNKNOWN
) || (bus
->ab_Dev
[1] > DEV_UNKNOWN
);
281 bug("[ATA ] IRQ: Setting IRQ flag for bus %ld to %s\n", bus
->ab_BusNum
, enable
? "ENABLED" : "DISABLED");
282 bus
->ab_IRQ
= enable
;
283 ata_out(enable
? 0x0 : 0x02, ata_AltControl
, bus
->ab_Alt
);
287 * handle IRQ; still fast and efficient, supposed to verify if this irq is for us and take adequate steps
288 * part of code moved here from ata.c to reduce containment
290 void ata_IRQSignalTask(struct ata_Bus
*bus
)
293 Signal(bus
->ab_Task
, 1UL << bus
->ab_SleepySignal
);
296 void ata_HandleIRQ(struct ata_Bus
*bus
)
298 struct ata_Unit
*u
= ata_GetSelectedUnit(bus
);
299 UBYTE status
= ata_ReadStatus(bus
);
301 * don't waste your time on checking other devices.
302 * pass irq ONLY if task is expecting one;
305 if (0 != bus
->ab_HandleIRQ
)
308 * ok, we have a routine to handle any form of transmission etc
310 DIRQ(bug("[ATA ] IRQ: Calling dedicated handler... \n"));
311 bus
->ab_HandleIRQ(u
, status
);
317 * if we got *here* then device is most likely not expected to have an irq.
319 bug("[ATA%02ld] IRQ: Checking busy flag: ", u
->au_UnitNum
);
321 if (0 == (ATAF_BUSY
& status
))
323 bug("device ready. Dumping details:\n");
325 bug("[ATA ] STATUS: %02lx\n", status
);
326 bug("[ATA ] ALT STATUS: %02lx\n", ata_in(ata_AltStatus
, bus
->ab_Alt
));
327 bug("[ATA ] ERROR: %02lx\n", ata_in(ata_Error
, bus
->ab_Port
));
328 bug("[ATA ] IRQ: REASON: %02lx\n", ata_in(atapi_Reason
, bus
->ab_Port
));
332 bug("device still busy. ignoring irq.\n");
337 void ata_IRQSetHandler(struct ata_Unit
*unit
, void (*handler
)(struct ata_Unit
*, UBYTE
), APTR piomem
, ULONG piolen
)
340 unit
->au_cmd_error
= 0;
342 unit
->au_cmd_data
= piomem
;
343 unit
->au_cmd_length
= piolen
;
344 unit
->au_Bus
->ab_HandleIRQ
= handler
;
347 void ata_IRQNoData(struct ata_Unit
*unit
, UBYTE status
)
349 if (status
& ATAF_BUSY
)
352 if ((unit
->au_cmd_error
== 0) && (status
& ATAF_ERROR
))
353 unit
->au_cmd_error
= HFERR_BadStatus
;
355 DIRQ(bug("[ATA%02ld] IRQ: NoData - done; status %02lx.\n", unit
->au_UnitNum
, status
));
356 ata_IRQSetHandler(unit
, NULL
, NULL
, 0);
357 ata_IRQSignalTask(unit
->au_Bus
);
360 void ata_IRQPIORead(struct ata_Unit
*unit
, UBYTE status
)
362 if (status
& ATAF_ERROR
)
363 ata_IRQNoData(unit
, status
);
364 if (status
& ATAF_DATAREQ
)
365 unit
->au_ins(unit
->au_cmd_data
, unit
->au_Bus
->ab_Port
, unit
->au_cmd_length
);
367 DIRQ(bug("[ATA ] IRQ: PIOReadData - done.\n"));
369 * indicate it's all done here
371 unit
->au_cmd_length
= 0;
372 ata_IRQNoData(unit
, status
);
375 void ata_IRQPIOWrite(struct ata_Unit
*unit
, UBYTE status
)
377 if (status
& ATAF_ERROR
)
378 ata_IRQNoData(unit
, status
);
379 if (status
& ATAF_DATAREQ
)
380 unit
->au_outs(unit
->au_cmd_data
, unit
->au_Bus
->ab_Port
, unit
->au_cmd_length
);
382 DIRQ(bug("[ATA ] IRQ: PIOWriteData - done.\n"));
384 * indicate it's all done here
386 unit
->au_cmd_length
= 0;
387 ata_IRQNoData(unit
, status
);
390 void ata_IRQDMAReadWrite(struct ata_Unit
*au
, UBYTE status
)
392 UBYTE stat
= ata_in(dma_Status
, au
->au_DMAPort
);
393 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au
->au_UnitNum
, status
, stat
));
395 if (0 == (stat
& DMAF_Interrupt
))
397 bug("[ATA ] IRQ: Fake IRQ.\n");
399 else if ((status
& ATAF_ERROR
) || (stat
& DMAF_Error
))
401 DIRQ(bug("[ATA%02ld] IRQ: IO status %02lx, DMA status %02lx\n", au
->au_UnitNum
, status
, stat
));
402 DIRQ(bug("[ATA%02ld] IRQ: ERROR %02lx\n", au
->au_UnitNum
, ata_in(atapi_Error
, au
->au_Bus
->ab_Port
)));
403 bug("[ATA ] IRQ: DMA Failed.\n");
404 au
->au_cmd_error
= HFERR_DMA
;
405 ata_IRQNoData(au
, status
);
407 else if (0 == (status
& (ATAF_BUSY
| ATAF_DATAREQ
)))
409 DIRQ(bug("[ATA ] IRQ: DMA Done.\n"));
410 ata_IRQNoData(au
, status
);
414 void ata_IRQPIOReadAtapi(struct ata_Unit
*unit
, UBYTE status
)
416 ULONG port
= unit
->au_Bus
->ab_Port
;
418 UBYTE reason
= ata_in(atapi_Reason
, port
);
419 DIRQ(bug("[DSCSI] Current status: %ld during READ\n", reason
));
421 /* have we failed yet? */
422 if (0 == (status
& (ATAF_BUSY
| ATAF_DATAREQ
)))
423 ata_IRQNoData(unit
, status
);
424 if (status
& ATAF_ERROR
)
425 ata_IRQNoData(unit
, status
);
427 /* anything for us please? */
428 if (ATAPIF_READ
!= (reason
& ATAPIF_MASK
))
431 size
= ata_in(atapi_ByteCntH
, port
) << 8 | ata_in(atapi_ByteCntL
, port
);
432 DIRQ(bug("[ATAPI] IRQ: data available for read (%ld bytes, max: %ld bytes)\n", size
, unit
->au_cmd_length
));
434 if (size
> unit
->au_cmd_length
)
436 bug("[ATAPI] IRQ: CRITICAL! MORE DATA OFFERED THAN STORAGE CAN TAKE: %ld bytes vs %ld bytes left!\n", size
, unit
->au_cmd_length
);
437 size
= unit
->au_cmd_length
;
440 unit
->au_ins(unit
->au_cmd_data
, port
, size
);
441 unit
->au_cmd_data
= &((UBYTE
*)unit
->au_cmd_data
)[size
];
442 unit
->au_cmd_length
-= size
;
444 DIRQ(bug("[ATAPI] IRQ: %lu bytes read.\n", size
));
446 if (unit
->au_cmd_length
== 0)
447 ata_IRQNoData(unit
, status
);
450 void ata_IRQPIOWriteAtapi(struct ata_Unit
*unit
, UBYTE status
)
452 ULONG port
= unit
->au_Bus
->ab_Port
;
454 UBYTE reason
= ata_in(atapi_Reason
, port
);
455 DIRQ(bug("[ATAPI] IRQ: Current status: %ld during WRITE\n", reason
));
457 /* have we failed yet? */
458 if (0 == (status
& (ATAF_BUSY
| ATAF_DATAREQ
)))
459 ata_IRQNoData(unit
, status
);
460 if (status
& ATAF_ERROR
)
461 ata_IRQNoData(unit
, status
);
463 /* anything for us please? */
464 if (ATAPIF_READ
!= (reason
& ATAPIF_MASK
))
467 size
= ata_in(atapi_ByteCntH
, port
) << 8 | ata_in(atapi_ByteCntL
, port
);
468 DIRQ(bug("[ATAPI] IRQ: data requested for write (%ld bytes, max: %ld bytes)\n", size
, unit
->au_cmd_length
));
470 if (size
> unit
->au_cmd_length
)
472 bug("[ATAPI] IRQ: CRITICAL! MORE DATA REQUESTED THAN STORAGE CAN GIVE: %ld bytes vs %ld bytes left!\n", size
, unit
->au_cmd_length
);
473 size
= unit
->au_cmd_length
;
476 unit
->au_outs(unit
->au_cmd_data
, port
, size
);
477 unit
->au_cmd_data
= &((UBYTE
*)unit
->au_cmd_data
)[size
];
478 unit
->au_cmd_length
-= size
;
480 DIRQ(bug("[ATAPI] IRQ: %lu bytes written.\n", size
));
482 if (unit
->au_cmd_length
== 0)
483 ata_IRQNoData(unit
, status
);
487 * wait for timeout or drive ready
488 * polling-in-a-loop, but it should be safe to remove this already
490 BOOL
ata_WaitBusyTO(struct ata_Unit
*unit
, UWORD tout
, BOOL irq
)
493 ULONG sigs
= SIGBREAKF_CTRL_C
;
497 if (irq
&& !unit
->au_Bus
->ab_IRQ
)
499 bug("[ATA ] Requested IRQ wait, but IRQ is not enabled\n");
502 irq
&= unit
->au_Bus
->ab_IRQ
;
503 sigs
|= (irq
? (1 << unit
->au_Bus
->ab_SleepySignal
) : 0);
506 * clear up all old signals
511 * set up bus timeout and irq
514 unit
->au_Bus
->ab_Timeout
= tout
;
518 * this loop may experience one of two scenarios
519 * 1) we get a valid irq and the drive wanted to let us know that it's ready
520 * 2) we get an invalid irq due to some collissions. We may still want to go ahead and get some extra irq breaks
521 * this would reduce system load a little
528 * delay the check - this was found needed for some hardware
534 * lets check if the drive is already good
536 status
= ata_in(ata_Status
, unit
->au_Bus
->ab_Port
);
537 if (0 == (status
& (ATAF_DATAREQ
| ATAF_BUSY
)))
541 * so we're stuck in a loop?
543 DIRQ(bug("[ATA%02ld] Waiting (Current status: %02lx)...\n", unit
->au_UnitNum
, status
));
546 * if IRQ wait is requested then allow either timeout or irq;
547 * then clear irq flag so we dont keep receiving more of these (especially when system suffers collissions)
552 * wait for either IRQ or TIMEOUT
557 * now if we did reach timeout, then there's no point in going ahead.
559 if (SIGBREAKB_CTRL_C
& step
)
561 bug("[ATA%02ld] Timeout while waiting for device to complete operation\n", unit
->au_UnitNum
);
566 * if we get as far as this, there's no more signals to expect
567 * but we still want the status
569 status
= ata_in(ata_Status
, unit
->au_Bus
->ab_Port
);
575 * device not ready just yet. lets set whether we want an IRQ and move on - to polling or irq wait
580 * every 16n rounds do some extra stuff
582 if ((step
& 16) == 0)
585 * huhm. so it's been 16n rounds already. any timeout yet?
587 if (SetSignal(0, SIGBREAKF_CTRL_C
) & SIGBREAKF_CTRL_C
)
589 DIRQ(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit
->au_UnitNum
));
595 * no timeout just yet, but it's not a good idea to keep spinning like that.
596 * let's give the system some time.
599 // TODO: Put some delay here!
602 } while(status
& ATAF_BUSY
);
605 * be nice to frustrated developer
607 DIRQ(bug("[ATA%02ld] WaitBusy status: %lx / %ld\n", unit
->au_UnitNum
, status
, res
));
610 * clear up all our expectations
613 unit
->au_Bus
->ab_Timeout
= -1;
622 * and say it went fine (i mean it)
628 * just wait for timeout
630 void ata_Wait(struct ata_Unit
*unit
, UWORD tout
)
632 SetSignal(0, SIGBREAKF_CTRL_C
);
635 unit
->au_Bus
->ab_Timeout
= tout
;
638 Wait(SIGBREAKF_CTRL_C
);
642 * Procedure for sending ATA command blocks
643 * it appears LARGE but there's a lot of COMMENTS here :)
644 * handles *all* ata commands (no data, pio and dma)
645 * naturally could be splitted at some point in the future
646 * depends if anyone believes that the change for 50 lines
647 * would make slow ATA transfers any faster
649 static ULONG
ata_exec_cmd(struct ata_Unit
* au
, ata_CommandBlock
*block
)
651 ULONG port
= au
->au_Bus
->ab_Port
;
653 APTR mem
= block
->buffer
;
655 if (FALSE
== ata_SelectUnit(au
))
656 return IOERR_UNITBUSY
;
661 if (block
->sectors
> 256)
663 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au
->au_UnitNum
, block
->sectors
);
664 return IOERR_BADLENGTH
;
668 * we want the above to fall in here!
669 * we really do (checking for secmul)
673 if (block
->sectors
> 65536)
675 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au
->au_UnitNum
, block
->sectors
);
676 return IOERR_BADLENGTH
;
678 if (block
->secmul
== 0)
680 bug("[ATA%02ld] ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au
->au_UnitNum
);
689 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au
->au_UnitNum
, block
->type
);
694 D(bug("[ATA%02ld] Executing command %02lx\n", au
->au_UnitNum
, block
->command
));
696 if (block
->feature
!= 0)
697 ata_out(block
->feature
, ata_Feature
, port
);
700 * - set LBA and sector count
705 DATA(bug("[ATA%02ld] Command uses 28bit LBA addressing (OLD)\n", au
->au_UnitNum
));
706 ata_out(((block
->blk
>> 24) & 0x0f) | 0x40 | au
->au_DevMask
, ata_DevHead
, port
);
707 ata_out(block
->blk
>> 16, ata_LBAHigh
, port
);
708 ata_out(block
->blk
>> 8, ata_LBAMid
, port
);
709 ata_out(block
->blk
, ata_LBALow
, port
);
710 ata_out(block
->sectors
, ata_Count
, port
);
714 DATA(bug("[ATA%02ld] Command uses 48bit LBA addressing (NEW)\n", au
->au_UnitNum
));
715 ata_out(block
->blk
>> 40, ata_LBAHigh
, port
);
716 ata_out(block
->blk
>> 32, ata_LBAMid
, port
);
717 ata_out(block
->blk
>> 24, ata_LBALow
, port
);
719 ata_out(block
->blk
>> 16, ata_LBAHigh
, port
);
720 ata_out(block
->blk
>> 8, ata_LBAMid
, port
);
721 ata_out(block
->blk
, ata_LBALow
, port
);
723 ata_out(block
->sectors
>> 8, ata_Count
, port
);
724 ata_out(block
->sectors
, ata_Count
, port
);
728 DATA(bug("[ATA%02ld] Command does not address any block\n", au
->au_UnitNum
));
733 switch (block
->method
)
736 ata_IRQSetHandler(au
, &ata_IRQPIOWrite
, mem
, block
->length
);
740 ata_IRQSetHandler(au
, &ata_IRQPIORead
, mem
, block
->length
);
744 if (FALSE
== dma_SetupPRDSize(au
, mem
, block
->length
, TRUE
))
745 return IOERR_ABORTED
;
746 ata_IRQSetHandler(au
, &ata_IRQDMAReadWrite
, NULL
, 0);
751 if (FALSE
== dma_SetupPRDSize(au
, mem
, block
->length
, FALSE
))
752 return IOERR_ABORTED
;
753 ata_IRQSetHandler(au
, &ata_IRQDMAReadWrite
, NULL
, 0);
758 ata_IRQSetHandler(au
, &ata_IRQNoData
, NULL
, 0);
768 * let drive propagate its signals
770 DATA(bug("[ATA%02ld] Sending command\n", au
->au_UnitNum
));
771 ata_out(block
->command
, ata_Command
, port
);
775 * wait for drive to complete what it has to do
777 if (FALSE
== ata_WaitBusyTO(au
, 300, TRUE
))
779 bug("[ATA%02ld] Device is late - no response\n", au
->au_UnitNum
);
780 err
= IOERR_UNITBUSY
;
783 err
= au
->au_cmd_error
;
785 DATA(bug("[ATA%02ld] Command done\n", au
->au_UnitNum
));
788 * don't use 'mem' pointer here as it's already invalid.
790 if (block
->method
== CM_DMARead
)
793 dma_Cleanup(block
->buffer
, block
->length
, TRUE
);
795 else if (block
->method
== CM_DMAWrite
)
798 dma_Cleanup(block
->buffer
, block
->length
, FALSE
);
801 D(bug("[ATA%02ld] return code %ld\n", au
->au_UnitNum
, err
));
808 int atapi_SendPacket(struct ata_Unit
*unit
, APTR packet
, APTR data
, LONG datalen
, BOOL
*dma
, BOOL write
)
810 *dma
&= (unit
->au_XferModes
& AF_XFER_DMA
) ? TRUE
: FALSE
;
816 register int t
=5,l
=0;
817 ULONG port
= unit
->au_Bus
->ab_Port
;
819 if (((UBYTE
*)packet
)[0] > 0x1f)
821 if (((UBYTE
*)packet
)[0] > 0x5f)
824 switch (((UBYTE
*)packet
)[0])
829 case 0xb9: // readcdmsf
832 case 0xaa: // write12
833 case 0x2e: // writeverify
841 cmd
[l
] = ((UBYTE
*)packet
)[l
];
846 bug("[ATA%02lx] Sending %s ATA packet: ", unit
->au_UnitNum
, (*dma
) ? "DMA" : "PIO");
850 bug("%02lx ", ((UBYTE
*)cmd
)[l
]);
856 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen
);
859 datalen
= (datalen
+1)&~1;
861 if (FALSE
== ata_SelectUnit(unit
))
863 DATAPI(bug("[ATAPI] WaitBusy failed at first check\n"));
864 return IOERR_UNITBUSY
;
868 * tell device if whether we want to read or write and if we want a dma transfer
870 ata_out(((*dma
) ? 1 : 0) | ((write
) ? 4 : 0), atapi_Features
, port
);
871 ata_out((datalen
& 0xff), atapi_ByteCntL
, port
);
872 ata_out((datalen
>> 8) & 0xff, atapi_ByteCntH
, port
);
875 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
876 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
878 DATAPI(bug("[ATAPI] Issuing ATA_PACKET command.\n"));
879 ata_out(ATA_PACKET
, atapi_Command
, port
);
882 ata_WaitBusyTO(unit
, 30, FALSE
);
883 if (0 == (ata_ReadStatus(unit
->au_Bus
) & ATAF_DATAREQ
))
884 return HFERR_BadStatus
;
887 * setup appropriate hooks. not really the best way.
890 ata_IRQSetHandler(unit
, &ata_IRQNoData
, 0, 0);
892 ata_IRQSetHandler(unit
, &ata_IRQDMAReadWrite
, NULL
, 0);
894 ata_IRQSetHandler(unit
, &ata_IRQPIOWriteAtapi
, data
, datalen
);
896 ata_IRQSetHandler(unit
, &ata_IRQPIOReadAtapi
, data
, datalen
);
898 DATAPI(bug("[ATAPI] Sending packet\n"));
899 unit
->au_outs(cmd
, unit
->au_Bus
->ab_Port
, 12);
900 ata_400ns(); /* give drive time to think about what we just said, then move on */
901 /* how much time could it take for drive to raise DMARQ signal?? */
903 DATAPI(bug("[ATAPI] Status after packet: %lx\n", ata_ReadStatus(unit
->au_Bus
)));
907 DATAPI(bug("[ATAPI] Preparing for DMA\n"));
908 while (0 == ((t
= ata_ReadStatus(unit
->au_Bus
)) & (ATAF_BUSY
| ATAF_DATAREQ
)))
915 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit
->au_Bus
)));
919 DATAPI(bug("[ATAPI] status %02lx\n", ata_ReadStatus(unit
->au_Bus
)));
923 DATAPI(bug("[ATAPI] Starting DMA\n"));
928 if ((0 == err
) && (ata_WaitBusyTO(unit
, 300, TRUE
) == FALSE
))
930 DATAPI(bug("[DSCSI] Command timed out.\n"));
931 err
= IOERR_UNITBUSY
;
934 err
= atapi_EndCmd(unit
);
939 dma_Cleanup(data
, datalen
, !write
);
942 D(bug("[ATAPI] Error code %ld\n", err
));
946 ULONG
atapi_DirectSCSI(struct ata_Unit
*unit
, struct SCSICmd
*cmd
)
948 APTR buffer
= cmd
->scsi_Data
;
949 ULONG length
= cmd
->scsi_Length
;
955 cmd
->scsi_Actual
= 0;
957 DATAPI(bug("[DSCSI] Sending packet!\n"));
961 * setup DMA & push command
962 * it does not really mean we will use dma here btw
964 if ((unit
->au_XferModes
& AF_XFER_DMA
) && (length
!=0) && (buffer
!= 0))
967 if ((cmd
->scsi_Flags
& SCSIF_READ
) != 0)
970 if (FALSE
== dma_SetupPRDSize(unit
, buffer
, length
, TRUE
))
975 if (FALSE
== dma_SetupPRDSize(unit
, buffer
, length
, FALSE
))
980 err
= atapi_SendPacket(unit
, cmd
->scsi_Command
, cmd
->scsi_Data
, cmd
->scsi_Length
, &dma
, (cmd
->scsi_Flags
& SCSIF_READ
) == 0);
982 DUMP({ if (cmd
->scsi_Data
!= 0) dump(cmd
->scsi_Data
, cmd
->scsi_Length
); });
985 * on check condition - grab sense data
987 DATAPI(bug("[ATA%02lx] SCSI Flags: %02lx / Error: %ld\n", unit
->au_UnitNum
, cmd
->scsi_Flags
, err
));
988 if ((err
!= 0) && (cmd
->scsi_Flags
& SCSIF_AUTOSENSE
))
990 atapi_RequestSense(unit
, cmd
->scsi_SenseData
, cmd
->scsi_SenseLength
);
991 DUMP(dump(cmd
->scsi_SenseData
, cmd
->scsi_SenseLength
));
998 * chops the large transfers into set of smaller transfers
999 * specifically useful when requested transfer size is >256 sectors for 28bit commands
1001 static ULONG
ata_exec_blk(struct ata_Unit
*unit
, ata_CommandBlock
*blk
)
1006 ULONG count
=blk
->sectors
;
1008 if (blk
->type
== CT_LBA48
)
1011 DATA(bug("[ATA%02ld] Accessing %ld sectors starting from %lx\n", unit
->au_UnitNum
, count
, blk
->blk
));
1012 while ((count
> 0) && (err
== 0))
1014 part
= (count
> max
) ? max
: count
;
1015 blk
->sectors
= part
;
1016 blk
->length
= part
<< unit
->au_SectorShift
;
1018 err
= ata_exec_cmd(unit
, blk
);
1021 blk
->buffer
= &((char*)blk
->buffer
)[part
<< unit
->au_SectorShift
];
1028 * Initial device configuration that suits *all* cases
1030 BOOL
ata_init_unit(struct ata_Bus
*bus
, UBYTE u
)
1032 struct ata_Unit
*unit
=NULL
;
1034 DINIT(bug("[ATA ] Initializing unit %ld\n", u
));
1036 unit
= bus
->ab_Units
[u
];
1041 unit
->au_Drive
= AllocPooled(bus
->ab_Base
->ata_MemPool
, sizeof(struct DriveIdent
));
1042 unit
->au_UnitNum
= bus
->ab_BusNum
<< 1 | u
; // b << 8 | u
1043 unit
->au_DevMask
= 0xa0 | (u
<< 4);
1044 if (bus
->ab_Base
->ata_32bit
)
1046 unit
->au_ins
= ata_insl
;
1047 unit
->au_outs
= ata_outsl
;
1051 unit
->au_ins
= ata_insw
;
1052 unit
->au_outs
= ata_outsw
;
1054 unit
->au_SectorShift
= 9; /* this really has to be set here. */
1057 NEWLIST(&unit
->au_SoftList
);
1060 * since the stack is always handled by caller
1061 * it's safe to stub all calls with one function
1063 unit
->au_Read32
= ata_STUB_IO32
;
1064 unit
->au_Read64
= ata_STUB_IO64
;
1065 unit
->au_Write32
= ata_STUB_IO32
;
1066 unit
->au_Write64
= ata_STUB_IO64
;
1067 unit
->au_Eject
= ata_STUB
;
1068 unit
->au_DirectSCSI
= ata_STUB_SCSI
;
1069 unit
->au_Identify
= ata_STUB
;
1073 BOOL
ata_setup_unit(struct ata_Bus
*bus
, UBYTE u
)
1075 struct ata_Unit
*unit
=NULL
;
1078 * this stuff always goes along the same way
1079 * WARNING: NO INTERRUPTS AT THIS POINT!
1081 DINIT(bug("[ATA ] setting up unit %ld\n", u
));
1083 unit
= bus
->ab_Units
[u
];
1087 ata_SelectUnit(unit
);
1089 if (FALSE
== ata_WaitBusyTO(unit
, 1, FALSE
))
1091 DINIT(bug("[ATA%02ld] ERROR: Drive not ready for use. Keeping functions stubbed\n", unit
->au_UnitNum
));
1092 FreePooled(bus
->ab_Base
->ata_MemPool
, unit
->au_Drive
, sizeof(struct DriveIdent
));
1097 switch (bus
->ab_Dev
[u
])
1100 * safe fallback settings
1104 unit
->au_Identify
= atapi_Identify
;
1109 unit
->au_Identify
= ata_Identify
;
1114 DINIT(bug("[ATA%02ld] Unsupported device %lx. All functions will remain stubbed.\n", unit
->au_UnitNum
, bus
->ab_Dev
[u
]));
1115 FreePooled(bus
->ab_Base
->ata_MemPool
, unit
->au_Drive
, sizeof(struct DriveIdent
));
1120 bug("[ATA ] Enabling Bus IRQs\n");
1121 ata_EnableIRQ(bus
, TRUE
);
1123 * now make unit self diagnose
1125 if (unit
->au_Identify(unit
) != 0)
1127 FreePooled(bus
->ab_Base
->ata_MemPool
, unit
->au_Drive
, sizeof(struct DriveIdent
));
1140 static void common_SetXferMode(struct ata_Unit
* unit
, ata_XferMode mode
)
1144 ata_CommandBlock acb
=
1159 if ((unit
->au_DMAPort
== 0) && (mode
> AB_XFER_PIO7
))
1161 DINIT(bug("[ATA%02ld] This controller does not own DMA port! Will set best PIO\n", unit
->au_UnitNum
));
1162 common_SetBestXferMode(unit
);
1168 * first, ONLY for ATA devices, set new commands
1170 if (0 == (unit
->au_XferModes
& AF_XFER_PACKET
))
1172 if ((mode
>= AB_XFER_PIO0
) & (mode
<= AB_XFER_PIO7
))
1174 if (unit
->au_XferModes
& AF_XFER_RWMULTI
)
1176 ata_out(unit
->au_Drive
->id_RWMultipleSize
& 0xFF, ata_Count
, unit
->au_Bus
->ab_Port
);
1177 ata_out(ATA_SET_MULTIPLE
, ata_Command
, unit
->au_Bus
->ab_Port
);
1178 ata_WaitBusyTO(unit
, -1, FALSE
);
1180 unit
->au_Read32
= ata_ReadMultiple32
;
1181 unit
->au_Write32
= ata_WriteMultiple32
;
1182 if (unit
->au_XferModes
& AF_XFER_48BIT
)
1184 unit
->au_Read64
= ata_ReadMultiple64
;
1185 unit
->au_Write64
= ata_WriteMultiple64
;
1190 unit
->au_Read32
= ata_ReadSector32
;
1191 unit
->au_Write32
= ata_WriteSector32
;
1192 if (unit
->au_XferModes
& AF_XFER_48BIT
)
1194 unit
->au_Read64
= ata_ReadSector64
;
1195 unit
->au_Write64
= ata_WriteSector64
;
1199 else if ((mode
>= AB_XFER_MDMA0
) & (mode
<= AB_XFER_MDMA7
))
1201 unit
->au_Read32
= ata_ReadDMA32
;
1202 unit
->au_Write32
= ata_WriteDMA32
;
1203 if (unit
->au_XferModes
& AF_XFER_48BIT
)
1205 unit
->au_Read64
= ata_ReadDMA64
;
1206 unit
->au_Write64
= ata_WriteDMA64
;
1209 else if ((mode
>= AB_XFER_UDMA0
) & (mode
<= AB_XFER_UDMA7
))
1211 unit
->au_Read32
= ata_ReadDMA32
;
1212 unit
->au_Write32
= ata_WriteDMA32
;
1213 if (unit
->au_XferModes
& AF_XFER_48BIT
)
1215 unit
->au_Read64
= ata_ReadDMA64
;
1216 unit
->au_Write64
= ata_WriteDMA64
;
1221 unit
->au_Read32
= ata_ReadSector32
;
1222 unit
->au_Write32
= ata_WriteSector32
;
1223 if (unit
->au_XferModes
& AF_XFER_48BIT
)
1225 unit
->au_Read64
= ata_ReadSector64
;
1226 unit
->au_Write64
= ata_WriteSector64
;
1231 if ((mode
>= AB_XFER_PIO0
) & (mode
<= AB_XFER_PIO7
))
1233 type
= 8 + (mode
- AB_XFER_PIO0
);
1235 else if ((mode
>= AB_XFER_MDMA0
) & (mode
<= AB_XFER_MDMA7
))
1237 type
= 32 + (mode
- AB_XFER_MDMA7
);
1240 else if ((mode
>= AB_XFER_UDMA0
) & (mode
<= AB_XFER_UDMA7
))
1242 type
= 64 + (mode
- AB_XFER_MDMA7
);
1251 if (0 != ata_exec_cmd(unit
, &acb
))
1253 DINIT(bug("[ATA%02ld] ERROR: Failed to apply new xfer mode.\n", unit
->au_UnitNum
));
1256 if (unit
->au_DMAPort
)
1258 type
= ata_in(dma_Status
, unit
->au_DMAPort
);
1262 type
|= 1 << (5 + (unit
->au_UnitNum
& 1));
1266 type
&= ~(1 << (5 + (unit
->au_UnitNum
& 1)));
1269 DINIT(bug("[DSCSI] Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit
->au_DMAPort
, type
, unit
->au_UnitNum
& 1));
1271 ata_SelectUnit(unit
);
1272 ata_out(type
, dma_Status
, unit
->au_DMAPort
);
1273 if (type
== (ata_in(dma_Status
, unit
->au_DMAPort
) & 0x60))
1275 DINIT(bug("[DSCSI] New DMA Status: %02lx\n", type
));
1279 DINIT(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1285 unit
->au_XferModes
|= AF_XFER_DMA
;
1287 unit
->au_XferModes
&=~AF_XFER_DMA
;
1290 static void common_SetBestXferMode(struct ata_Unit
* unit
)
1293 int max
= AB_XFER_UDMA7
;
1295 if (unit
->au_DMAPort
== 0)
1298 * make sure you reduce scan search to pio here!
1299 * otherwise this and above function will fall into infinite loop
1301 DINIT(bug("[ATA%02ld] This controller does not own DMA port\n", unit
->au_UnitNum
));
1305 for (iter
=max
; iter
>=AB_XFER_PIO0
; --iter
)
1307 if (unit
->au_XferModes
& (1<<iter
))
1309 common_SetXferMode(unit
, iter
);
1313 bug("[ATA%02ld] ERROR: device never reported any valid xfer modes. will continue at default\n", unit
->au_UnitNum
);
1314 common_SetXferMode(unit
, AB_XFER_PIO0
);
1317 void common_DetectXferModes(struct ata_Unit
* unit
)
1321 DINIT(bug("[ATA%02ld] Supports\n", unit
->au_UnitNum
));
1323 if (unit
->au_Drive
->id_Commands4
& (1 << 4))
1325 DINIT(bug("[ATA%02ld] - Packet interface\n", unit
->au_UnitNum
));
1326 unit
->au_XferModes
|= AF_XFER_PACKET
;
1327 unit
->au_DirectSCSI
= atapi_DirectSCSI
;
1329 else if (unit
->au_Drive
->id_Commands5
& (1 << 10))
1331 /* ATAPI devices do not use this bit. */
1332 DINIT(bug("[ATA%02ld] - 48bit I/O\n", unit
->au_UnitNum
));
1333 unit
->au_XferModes
|= AF_XFER_48BIT
;
1336 if ((unit
->au_XferModes
& AF_XFER_PACKET
) || (unit
->au_Drive
->id_Capabilities
& (1<< 9)))
1338 DINIT(bug("[ATA%02ld] - LBA Addressing\n", unit
->au_UnitNum
));
1339 unit
->au_XferModes
|= AF_XFER_LBA
;
1343 DINIT(bug("[ATA%02ld] - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit
->au_UnitNum
));
1346 if (unit
->au_Drive
->id_RWMultipleSize
& 0xff)
1348 DINIT(bug("[ATA%02ld] - R/W Multiple (%ld sectors per xfer)\n", unit
->au_UnitNum
, unit
->au_Drive
->id_RWMultipleSize
& 0xff));
1349 unit
->au_XferModes
|= AF_XFER_RWMULTI
;
1352 if (unit
->au_Drive
->id_PIOSupport
& 0xff)
1354 DINIT(bug("[ATA%02ld] - ", unit
->au_UnitNum
));
1355 for (iter
=0; iter
<8; iter
++)
1357 if (unit
->au_Drive
->id_MWDMASupport
& (1 << iter
))
1359 DINIT(bug("PIO%ld ", iter
));
1360 unit
->au_XferModes
|= AF_XFER_PIO(iter
);;
1366 if (unit
->au_Drive
->id_Capabilities
& (1<<8))
1368 DINIT(bug("[ATA%02ld] DMA:\n", unit
->au_UnitNum
));
1369 if (unit
->au_Drive
->id_MWDMASupport
& 0xff)
1371 DINIT(bug("[ATA%02ld] - ", unit
->au_UnitNum
));
1372 for (iter
=0; iter
<8; iter
++)
1374 if (unit
->au_Drive
->id_MWDMASupport
& (1 << iter
))
1376 unit
->au_XferModes
|= AF_XFER_MDMA(iter
);;
1377 if (unit
->au_Drive
->id_MWDMASupport
& (256 << iter
))
1379 DINIT(bug("[MDMA%ld] ", iter
));
1383 DINIT(bug("MDMA%ld ", iter
));
1390 if (unit
->au_Drive
->id_UDMASupport
& 0xff)
1392 DINIT(bug("[ATA%02ld] - ", unit
->au_UnitNum
));
1393 for (iter
=0; iter
<8; iter
++)
1395 if (unit
->au_Drive
->id_UDMASupport
& (1 << iter
))
1397 unit
->au_XferModes
|= AF_XFER_MDMA(iter
);;
1398 if (unit
->au_Drive
->id_UDMASupport
& (256 << iter
))
1400 DINIT(bug("[UDMA%ld] ", iter
));
1404 DINIT(bug("UDMA%ld ", iter
));
1413 #define SWAP_LE_WORD(x) (x) = AROS_LE2WORD((x))
1414 #define SWAP_LE_LONG(x) (x) = AROS_LE2LONG((x))
1415 #define SWAP_LE_QUAD(x) (x) = AROS_LE2LONG((x)>>32) | AROS_LE2LONG((x) & 0xffffffff) << 32
1417 ULONG
atapi_Identify(struct ata_Unit
* unit
)
1419 ata_CommandBlock acb
=
1428 sizeof(struct DriveIdent
),
1434 ata_SelectUnit(unit
);
1436 if (ata_exec_cmd(unit
, &acb
))
1438 return IOERR_OPENFAIL
;
1441 #if (AROS_BIG_ENDIAN != 0)
1442 SWAP_LE_WORD(unit
->au_Drive
->id_General
);
1443 SWAP_LE_WORD(unit
->au_Drive
->id_OldCylinders
);
1444 SWAP_LE_WORD(unit
->au_Drive
->id_SpecificConfig
);
1445 SWAP_LE_WORD(unit
->au_Drive
->id_OldHeads
);
1446 SWAP_LE_WORD(unit
->au_Drive
->id_OldSectors
);
1447 SWAP_LE_WORD(unit
->au_Drive
->id_RWMultipleSize
);
1448 SWAP_LE_WORD(unit
->au_Drive
->id_Capabilities
);
1449 SWAP_LE_WORD(unit
->au_Drive
->id_OldCaps
);
1450 SWAP_LE_WORD(unit
->au_Drive
->id_OldPIO
);
1451 SWAP_LE_WORD(unit
->au_Drive
->id_ConfigAvailable
);
1452 SWAP_LE_WORD(unit
->au_Drive
->id_OldLCylinders
);
1453 SWAP_LE_WORD(unit
->au_Drive
->id_OldLHeads
);
1454 SWAP_LE_WORD(unit
->au_Drive
->id_OldLSectors
);
1455 SWAP_LE_WORD(unit
->au_Drive
->id_RWMultipleTrans
);
1456 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMASupport
);
1457 SWAP_LE_WORD(unit
->au_Drive
->id_PIOSupport
);
1458 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMA_MinCycleTime
);
1459 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMA_DefCycleTime
);
1460 SWAP_LE_WORD(unit
->au_Drive
->id_PIO_MinCycleTime
);
1461 SWAP_LE_WORD(unit
->au_Drive
->id_PIO_MinCycleTImeIORDY
);
1462 SWAP_LE_WORD(unit
->au_Drive
->id_QueueDepth
);
1463 SWAP_LE_WORD(unit
->au_Drive
->id_ATAVersion
);
1464 SWAP_LE_WORD(unit
->au_Drive
->id_ATARevision
);
1465 SWAP_LE_WORD(unit
->au_Drive
->id_Commands1
);
1466 SWAP_LE_WORD(unit
->au_Drive
->id_Commands2
);
1467 SWAP_LE_WORD(unit
->au_Drive
->id_Commands3
);
1468 SWAP_LE_WORD(unit
->au_Drive
->id_Commands4
);
1469 SWAP_LE_WORD(unit
->au_Drive
->id_Commands5
);
1470 SWAP_LE_WORD(unit
->au_Drive
->id_Commands6
);
1471 SWAP_LE_WORD(unit
->au_Drive
->id_UDMASupport
);
1472 SWAP_LE_WORD(unit
->au_Drive
->id_SecurityEraseTime
);
1473 SWAP_LE_WORD(unit
->au_Drive
->id_EnchSecurityEraseTime
);
1474 SWAP_LE_WORD(unit
->au_Drive
->id_CurrentAdvowerMode
);
1475 SWAP_LE_WORD(unit
->au_Drive
->id_MasterPwdRevision
);
1476 SWAP_LE_WORD(unit
->au_Drive
->id_HWResetResult
);
1477 SWAP_LE_WORD(unit
->au_Drive
->id_AcousticManagement
);
1478 SWAP_LE_WORD(unit
->au_Drive
->id_StreamMinimunReqSize
);
1479 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingTimeDMA
);
1480 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingLatency
);
1481 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingTimePIO
);
1482 SWAP_LE_WORD(unit
->au_Drive
->id_PhysSectorSize
);
1483 SWAP_LE_WORD(unit
->au_Drive
->id_RemMediaStatusNotificationFeatures
);
1484 SWAP_LE_WORD(unit
->au_Drive
->id_SecurityStatus
);
1486 SWAP_LE_LONG(unit
->au_Drive
->id_WordsPerLogicalSector
);
1487 SWAP_LE_LONG(unit
->au_Drive
->id_LBASectors
);
1488 SWAP_LE_LONG(unit
->au_Drive
->id_StreamingGranularity
);
1490 SWAP_LE_QUAD(unit
->au_Drive
->id_LBA48Sectors
);
1494 DUMP(dump(unit
->au_Drive
, sizeof(struct DriveIdent
)));
1496 unit
->au_SectorShift
= 11;
1497 unit
->au_Read32
= atapi_Read
;
1498 unit
->au_Write32
= atapi_Write
;
1499 unit
->au_DirectSCSI
= atapi_DirectSCSI
;
1500 unit
->au_Eject
= atapi_Eject
;
1501 unit
->au_Flags
= AF_DiscChanged
;
1502 unit
->au_DevType
= (unit
->au_Drive
->id_General
>>8) & 0x1f;
1503 unit
->au_XferModes
= AF_XFER_PACKET
;
1505 ata_strcpy(unit
->au_Drive
->id_Model
, unit
->au_Model
, 40);
1506 ata_strcpy(unit
->au_Drive
->id_SerialNumber
, unit
->au_SerialNumber
, 20);
1507 ata_strcpy(unit
->au_Drive
->id_FirmwareRev
, unit
->au_FirmwareRev
, 8);
1509 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit
->au_UnitNum
, unit
->au_Model
, unit
->au_SerialNumber
, unit
->au_FirmwareRev
);
1510 common_DetectXferModes(unit
);
1511 common_SetBestXferMode(unit
);
1513 if (unit
->au_Drive
->id_General
& 0x80)
1515 DINIT(bug("[ATA%02ld] Device is removable.\n", unit
->au_UnitNum
));
1516 unit
->au_Flags
|= AF_Removable
;
1519 unit
->au_Capacity
= unit
->au_Drive
->id_LBASectors
;
1520 unit
->au_Capacity48
= unit
->au_Drive
->id_LBA48Sectors
;
1521 bug("[ATA%02ld] Unit info: %07lx 28bit / %04lx:%08lx 48bit addressable blocks\n", unit
->au_UnitNum
, unit
->au_Capacity
, (ULONG
)(unit
->au_Capacity48
>> 32), (ULONG
)(unit
->au_Capacity48
& 0xfffffffful
));
1524 * ok, this is not very original, but quite compatible :P
1526 switch (unit
->au_DevType
)
1530 case DG_OPTICAL_DISK
:
1531 unit
->au_SectorShift
= 11;
1533 unit
->au_Sectors
= 75;
1534 unit
->au_Cylinders
= 4440;
1537 case DG_DIRECT_ACCESS
:
1538 unit
->au_SectorShift
= 9;
1539 if (!strcmp("LS-120", &unit
->au_Model
[0]))
1542 unit
->au_Sectors
= 18;
1543 unit
->au_Cylinders
= 6848;
1545 else if (!strcmp("ZIP 100 ", &unit
->au_Model
[8]))
1548 unit
->au_Sectors
= 64;
1549 unit
->au_Cylinders
= 3072;
1554 atapi_TestUnitOK(unit
);
1559 ULONG
ata_Identify(struct ata_Unit
* unit
)
1561 ata_CommandBlock acb
=
1563 ATA_IDENTIFY_DEVICE
,
1570 sizeof(struct DriveIdent
),
1576 if (ata_exec_cmd(unit
, &acb
))
1578 return IOERR_OPENFAIL
;
1581 #if (AROS_BIG_ENDIAN != 0)
1582 SWAP_LE_WORD(unit
->au_Drive
->id_General
);
1583 SWAP_LE_WORD(unit
->au_Drive
->id_OldCylinders
);
1584 SWAP_LE_WORD(unit
->au_Drive
->id_SpecificConfig
);
1585 SWAP_LE_WORD(unit
->au_Drive
->id_OldHeads
);
1586 SWAP_LE_WORD(unit
->au_Drive
->id_OldSectors
);
1587 SWAP_LE_WORD(unit
->au_Drive
->id_RWMultipleSize
);
1588 SWAP_LE_WORD(unit
->au_Drive
->id_Capabilities
);
1589 SWAP_LE_WORD(unit
->au_Drive
->id_OldCaps
);
1590 SWAP_LE_WORD(unit
->au_Drive
->id_OldPIO
);
1591 SWAP_LE_WORD(unit
->au_Drive
->id_ConfigAvailable
);
1592 SWAP_LE_WORD(unit
->au_Drive
->id_OldLCylinders
);
1593 SWAP_LE_WORD(unit
->au_Drive
->id_OldLHeads
);
1594 SWAP_LE_WORD(unit
->au_Drive
->id_OldLSectors
);
1595 SWAP_LE_WORD(unit
->au_Drive
->id_RWMultipleTrans
);
1596 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMASupport
);
1597 SWAP_LE_WORD(unit
->au_Drive
->id_PIOSupport
);
1598 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMA_MinCycleTime
);
1599 SWAP_LE_WORD(unit
->au_Drive
->id_MWDMA_DefCycleTime
);
1600 SWAP_LE_WORD(unit
->au_Drive
->id_PIO_MinCycleTime
);
1601 SWAP_LE_WORD(unit
->au_Drive
->id_PIO_MinCycleTImeIORDY
);
1602 SWAP_LE_WORD(unit
->au_Drive
->id_QueueDepth
);
1603 SWAP_LE_WORD(unit
->au_Drive
->id_ATAVersion
);
1604 SWAP_LE_WORD(unit
->au_Drive
->id_ATARevision
);
1605 SWAP_LE_WORD(unit
->au_Drive
->id_Commands1
);
1606 SWAP_LE_WORD(unit
->au_Drive
->id_Commands2
);
1607 SWAP_LE_WORD(unit
->au_Drive
->id_Commands3
);
1608 SWAP_LE_WORD(unit
->au_Drive
->id_Commands4
);
1609 SWAP_LE_WORD(unit
->au_Drive
->id_Commands5
);
1610 SWAP_LE_WORD(unit
->au_Drive
->id_Commands6
);
1611 SWAP_LE_WORD(unit
->au_Drive
->id_UDMASupport
);
1612 SWAP_LE_WORD(unit
->au_Drive
->id_SecurityEraseTime
);
1613 SWAP_LE_WORD(unit
->au_Drive
->id_EnchSecurityEraseTime
);
1614 SWAP_LE_WORD(unit
->au_Drive
->id_CurrentAdvowerMode
);
1615 SWAP_LE_WORD(unit
->au_Drive
->id_MasterPwdRevision
);
1616 SWAP_LE_WORD(unit
->au_Drive
->id_HWResetResult
);
1617 SWAP_LE_WORD(unit
->au_Drive
->id_AcousticManagement
);
1618 SWAP_LE_WORD(unit
->au_Drive
->id_StreamMinimunReqSize
);
1619 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingTimeDMA
);
1620 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingLatency
);
1621 SWAP_LE_WORD(unit
->au_Drive
->id_StreamingTimePIO
);
1622 SWAP_LE_WORD(unit
->au_Drive
->id_PhysSectorSize
);
1623 SWAP_LE_WORD(unit
->au_Drive
->id_RemMediaStatusNotificationFeatures
);
1624 SWAP_LE_WORD(unit
->au_Drive
->id_SecurityStatus
);
1626 SWAP_LE_LONG(unit
->au_Drive
->id_WordsPerLogicalSector
);
1627 SWAP_LE_LONG(unit
->au_Drive
->id_LBASectors
);
1628 SWAP_LE_LONG(unit
->au_Drive
->id_StreamingGranularity
);
1630 SWAP_LE_QUAD(unit
->au_Drive
->id_LBA48Sectors
);
1633 DUMP(dump(unit
->au_Drive
, sizeof(struct DriveIdent
)));
1635 unit
->au_SectorShift
= 9;
1636 unit
->au_DevType
= DG_DIRECT_ACCESS
;
1637 unit
->au_Read32
= ata_ReadSector32
;
1638 unit
->au_Write32
= ata_WriteSector32
;
1639 unit
->au_DirectSCSI
= atapi_DirectSCSI
;
1640 unit
->au_Eject
= ata_Eject
;
1641 unit
->au_XferModes
= 0;
1642 unit
->au_Flags
|= AF_DiscPresent
| AF_DiscChanged
;
1643 unit
->au_DevType
= DG_DIRECT_ACCESS
;
1645 ata_strcpy(unit
->au_Drive
->id_Model
, unit
->au_Model
, 40);
1646 ata_strcpy(unit
->au_Drive
->id_SerialNumber
, unit
->au_SerialNumber
, 20);
1647 ata_strcpy(unit
->au_Drive
->id_FirmwareRev
, unit
->au_FirmwareRev
, 8);
1649 bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit
->au_UnitNum
, unit
->au_Model
, unit
->au_SerialNumber
, unit
->au_FirmwareRev
);
1650 common_DetectXferModes(unit
);
1651 common_SetBestXferMode(unit
);
1653 if (unit
->au_Drive
->id_General
& 0x80)
1655 DINIT(bug("[ATA%02ld] Device is removable.\n", unit
->au_UnitNum
));
1656 unit
->au_Flags
|= AF_Removable
;
1659 unit
->au_Capacity
= unit
->au_Drive
->id_LBASectors
;
1660 unit
->au_Capacity48
= unit
->au_Drive
->id_LBA48Sectors
;
1661 bug("[ATA%02ld] Unit info: %07lx 28bit / %04lx:%08lx 48bit addressable blocks\n", unit
->au_UnitNum
, unit
->au_Capacity
, (ULONG
)(unit
->au_Capacity48
>> 32), (ULONG
)(unit
->au_Capacity48
& 0xfffffffful
));
1664 For drive capacities > 8.3GB assume maximal possible layout.
1665 It really doesn't matter here, as BIOS will not handle them in
1667 i guess this just solves that weirdo div-by-zero crash, if anything else...
1669 if ((unit
->au_Drive
->id_LBA48Sectors
> (63 * 255 * 1024)) ||
1670 (unit
->au_Drive
->id_LBASectors
> (63 * 255 * 1024)))
1674 * TODO: this shouldn't be casted down here.
1676 ULONG sec
= unit
->au_Capacity48
;
1678 if (sec
< unit
->au_Capacity48
)
1681 if (sec
< unit
->au_Capacity
)
1682 sec
= unit
->au_Capacity
;
1684 unit
->au_Sectors
= 63;
1687 * keep dividing by 2
1691 if (((sec
>> 1) << 1) != sec
)
1693 if ((div
<< 1) > 255)
1701 if (((sec
/ 3) * 3) != sec
)
1703 if ((div
* 3) > 255)
1709 unit
->au_Cylinders
= sec
;
1710 unit
->au_Heads
= div
;
1714 unit
->au_Cylinders
= unit
->au_Drive
->id_OldLCylinders
;
1715 unit
->au_Heads
= unit
->au_Drive
->id_OldLHeads
;
1716 unit
->au_Sectors
= unit
->au_Drive
->id_OldLSectors
;
1723 * ata read32 commands
1725 static ULONG
ata_ReadSector32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1727 ata_CommandBlock acb
=
1736 count
<< unit
->au_SectorShift
,
1744 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1747 *act
= count
<< unit
->au_SectorShift
;
1751 static ULONG
ata_ReadMultiple32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1753 ata_CommandBlock acb
=
1757 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
1762 count
<< unit
->au_SectorShift
,
1770 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1773 *act
= count
<< unit
->au_SectorShift
;
1777 static ULONG
ata_ReadDMA32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1780 ata_CommandBlock acb
=
1789 count
<< unit
->au_SectorShift
,
1796 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1799 *act
= count
<< unit
->au_SectorShift
;
1805 * ata read64 commands
1807 static ULONG
ata_ReadSector64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1809 ata_CommandBlock acb
=
1818 count
<< unit
->au_SectorShift
,
1823 register ULONG err
= 0;
1826 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1829 *act
= count
<< unit
->au_SectorShift
;
1833 static ULONG
ata_ReadMultiple64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1835 ata_CommandBlock acb
=
1837 ATA_READ_MULTIPLE64
,
1839 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
1844 count
<< unit
->au_SectorShift
,
1852 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1855 *act
= count
<< unit
->au_SectorShift
;
1859 static ULONG
ata_ReadDMA64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1861 ata_CommandBlock acb
=
1870 count
<< unit
->au_SectorShift
,
1878 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1881 *act
= count
<< unit
->au_SectorShift
;
1887 * ata write32 commands
1889 static ULONG
ata_WriteSector32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1891 ata_CommandBlock acb
=
1900 count
<< unit
->au_SectorShift
,
1908 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1911 *act
= count
<< unit
->au_SectorShift
;
1915 static ULONG
ata_WriteMultiple32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1917 ata_CommandBlock acb
=
1921 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
1926 count
<< unit
->au_SectorShift
,
1934 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1937 *act
= count
<< unit
->au_SectorShift
;
1941 static ULONG
ata_WriteDMA32(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
1943 ata_CommandBlock acb
=
1952 count
<< unit
->au_SectorShift
,
1960 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1963 *act
= count
<< unit
->au_SectorShift
;
1969 * ata write64 commands
1971 static ULONG
ata_WriteSector64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1973 ata_CommandBlock acb
=
1982 count
<< unit
->au_SectorShift
,
1990 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
1993 *act
= count
<< unit
->au_SectorShift
;
1997 static ULONG
ata_WriteMultiple64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
1999 ata_CommandBlock acb
=
2001 ATA_WRITE_MULTIPLE64
,
2003 unit
->au_Drive
->id_RWMultipleSize
& 0xff,
2008 count
<< unit
->au_SectorShift
,
2016 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
2019 *act
= count
<< unit
->au_SectorShift
;
2023 static ULONG
ata_WriteDMA64(struct ata_Unit
*unit
, UQUAD block
, ULONG count
, APTR buffer
, ULONG
*act
)
2025 ata_CommandBlock acb
=
2034 count
<< unit
->au_SectorShift
,
2042 if (0 != (err
= ata_exec_blk(unit
, &acb
)))
2045 *act
= count
<< unit
->au_SectorShift
;
2050 * ata miscellaneous commands
2052 static ULONG
ata_Eject(struct ata_Unit
*unit
)
2054 ata_CommandBlock acb
=
2069 return ata_exec_cmd(unit
, &acb
);
2075 int atapi_TestUnitOK(struct ata_Unit
*unit
)
2083 struct SCSICmd sc
= {
2087 sc
.scsi_Command
= (void*) &cmd
;
2088 sc
.scsi_CmdLength
= sizeof(cmd
);
2089 sc
.scsi_SenseData
= (void*)&sense
;
2090 sc
.scsi_SenseLength
= sizeof(sense
);
2091 sc
.scsi_Flags
= SCSIF_AUTOSENSE
;
2093 unit
->au_DirectSCSI(unit
, &sc
);
2094 unit
->au_SenseKey
= sense
[2];
2097 * we may have just lost the disc...?
2099 int p1
= ((sense
[2] == 2) && (sense
[12] == 0x3a)) ? 1 : 0;
2100 int p2
= (0 != (AF_DiscPresent
& unit
->au_Flags
)) ? 1 : 0;
2104 //unit->au_Flags ^= AF_DiscPresent;
2106 unit
->au_Flags
|= AF_DiscPresent
;
2108 unit
->au_Flags
&= ~AF_DiscPresent
;
2110 unit
->au_Flags
|= AF_DiscChanged
;
2113 DATAPI(bug("[ATA%02ld] Test Unit Ready sense: %02lx, Media %s\n", unit
->au_UnitNum
, sense
[2], unit
->au_Flags
& AF_DiscPresent
? "PRESENT" : "ABSENT"));
2117 static ULONG
atapi_Read(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
2120 SCSI_READ10
, 0, block
>>24, block
>>16, block
>>8, block
, 0, count
>>8, count
, 0
2122 struct SCSICmd sc
= {
2126 sc
.scsi_Command
= (void*) &cmd
;
2127 sc
.scsi_CmdLength
= sizeof(cmd
);
2128 sc
.scsi_Data
= buffer
;
2129 sc
.scsi_Length
= count
<< unit
->au_SectorShift
;
2130 sc
.scsi_Flags
= SCSIF_READ
;
2132 return unit
->au_DirectSCSI(unit
, &sc
);
2135 static ULONG
atapi_Write(struct ata_Unit
*unit
, ULONG block
, ULONG count
, APTR buffer
, ULONG
*act
)
2138 SCSI_WRITE10
, 0, block
>>24, block
>>16, block
>>8, block
, 0, count
>>8, count
, 0
2140 struct SCSICmd sc
= {
2144 sc
.scsi_Command
= (void*) &cmd
;
2145 sc
.scsi_CmdLength
= sizeof(cmd
);
2146 sc
.scsi_Data
= buffer
;
2147 sc
.scsi_Length
= count
<< unit
->au_SectorShift
;
2148 sc
.scsi_Flags
= SCSIF_WRITE
;
2150 return unit
->au_DirectSCSI(unit
, &sc
);
2153 static ULONG
atapi_Eject(struct ata_Unit
*unit
)
2155 struct atapi_StartStop cmd
= {
2156 command
: SCSI_STARTSTOP
,
2158 flags
: ATAPI_SS_EJECT
,
2161 struct SCSICmd sc
= {
2165 sc
.scsi_Command
= (void*) &cmd
;
2166 sc
.scsi_CmdLength
= sizeof(cmd
);
2167 sc
.scsi_Flags
= SCSIF_READ
;
2169 return unit
->au_DirectSCSI(unit
, &sc
);
2172 ULONG
atapi_RequestSense(struct ata_Unit
* unit
, UBYTE
* sense
, ULONG senselen
)
2175 3, 0, 0, 0, senselen
& 0xfe, 0
2177 struct SCSICmd sc
= {
2181 if ((senselen
== 0) || (sense
== 0))
2185 sc
.scsi_Data
= (void*)sense
;
2186 sc
.scsi_Length
= senselen
& 0xfe;
2187 sc
.scsi_Command
= (void*)&cmd
;
2188 sc
.scsi_CmdLength
= 6;
2189 sc
.scsi_Flags
= SCSIF_READ
;
2191 unit
->au_DirectSCSI(unit
, &sc
);
2193 DATAPI(dump(sense
, senselen
));
2194 DATAPI(bug("[SENSE] sensed data: %lx %lx %lx\n", sense
[2]&0xf, sense
[12], sense
[13]));
2195 return ((sense
[2]&0xf)<<16) | (sense
[12]<<8) | (sense
[13]);
2198 ULONG
ata_ReadSignature(struct ata_Bus
*bus
, int unit
)
2200 ULONG port
= bus
->ab_Port
;
2203 /* Check basic signature. All live devices should provide it */
2204 tmp1
= ata_in(ata_Count
, port
);
2205 tmp2
= ata_in(ata_LBALow
, port
);
2206 DINIT(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1
, tmp2
));
2208 DINIT(bug("[ATA ] Status %08lx Device %08lx\n", ata_in(ata_Status
, port
), ata_in(ata_DevHead
, port
)));
2210 if ((tmp1
== 0x01) && (tmp2
== 0x01))
2212 /* Ok, ATA/ATAPI device. Get detailed signature */
2213 DINIT(bug("[ATA ] Found an ATA[PI] Device. Attempting to detect specific subtype\n"));
2215 tmp1
= ata_in(ata_LBAMid
, port
);
2216 tmp2
= ata_in(ata_LBAHigh
, port
);
2218 DINIT(bug("[ATA ] Subtype check returned %02lx:%02lx (%04lx)\n", tmp1
, tmp2
, (tmp1
<< 8) | tmp2
));
2221 switch ((tmp1
<< 8) | tmp2
)
2224 if (0 == (ata_ReadStatus(bus
) & 0xfe))
2226 ata_out(0xa0 | (unit
<< 4), ata_DevHead
, port
);
2227 ata_out(ATA_EXECUTE_DIAG
, ata_Command
, port
);
2228 ata_out(0xa0 | (unit
<< 4), ata_DevHead
, port
);
2230 while (ata_ReadStatus(bus
) & ATAF_BUSY
)
2233 DINIT(bug("[ATA ] Further validating ATA signature: %lx & 0x7f = 1, %lx & 0x10 = unit\n", ata_in(ata_Error
, port
), ata_in(ata_DevHead
, port
)));
2235 if ((1 == (0x7f & ata_in(ata_Error
, port
))) &&
2236 (unit
== ((ata_in(ata_DevHead
, port
) >> 4) & 1)))
2238 DINIT(bug("[ATA ] Found *valid* signature for ATA device\n"));
2244 DINIT(bug("[ATA ] Found signature for ATAPI device\n"));
2248 DINIT(bug("[ATA ] Found signature for SATA device\n"));
2252 DINIT(bug("[ATA ] Found signature for SATAPI device\n"));
2256 if (((tmp1
| tmp2
) == 0xff) &&
2257 ((tmp1
& tmp2
) == 0x00))
2259 bug("[ATA ] Found valid subtype, but don't know how to handle this device: %02lx %02lx\n", tmp1
, tmp2
);
2263 bug("[ATA ] Invalid signature: %02lx %02lx\n", tmp1
, tmp2
);
2272 void ata_ResetBus(struct timerequest
*tr
, struct ata_Bus
*bus
)
2274 ULONG alt
= bus
->ab_Alt
;
2275 ULONG port
= bus
->ab_Port
;
2279 * issue and clear the software reset signal
2281 /* at this time both devices should report ready immediately */
2282 for (id
= 0; id
< 2; id
++)
2284 if (DEV_NONE
!= bus
->ab_Dev
[id
])
2286 ata_out(0xa0 | (id
<< 4), ata_DevHead
, port
);
2289 ata_out(0x04, ata_AltControl
, alt
);
2290 ata_usleep(tr
, 10); /* minimum required: 5us */
2291 ata_out(0x02, ata_AltControl
, alt
);
2292 ata_usleep(tr
, 20000); /* minimum required: 2ms */
2294 ata_out(0xa0 | (id
<< 4), ata_DevHead
, port
);
2297 while (0 != (ata_in(ata_Status
, port
) & ATAF_BUSY
))
2298 ata_usleep(tr
, 200);
2300 bus
->ab_Dev
[id
] = ata_ReadSignature(bus
, id
);
2306 * --------------------------------------------------------------
2307 * - here ends the code that makes any sense. rest to be removed -
2308 * --------------------------------------------------------------
2312 void ata_usleep(struct timerequest
*tr
, ULONG usec
)
2314 tr
->tr_node
.io_Command
= TR_ADDREQUEST
;
2315 tr
->tr_time
.tv_micro
= usec
% 1000000;
2316 tr
->tr_time
.tv_secs
= usec
/ 1000000;
2318 DoIO((struct IORequest
*)tr
);
2322 Device scan routines - TO BE REPLACED
2327 void ata_InitBus(struct ata_Bus
*bus
)
2329 ULONG port
= bus
->ab_Port
;
2332 struct MsgPort
*p
= CreateMsgPort();
2333 struct timerequest
*tr
= (struct timerequest
*)CreateIORequest((struct MsgPort
*)p
,
2334 sizeof(struct timerequest
));
2335 OpenDevice("timer.device", UNIT_MICROHZ
, (struct IORequest
*)tr
, 0);
2337 bus
->ab_Dev
[0] = DEV_NONE
;
2338 bus
->ab_Dev
[1] = DEV_NONE
;
2340 /* Disable IDE IRQ */
2341 ata_EnableIRQ(bus
, FALSE
);
2343 /* Select device 0 */
2344 ata_out(0xa0, ata_DevHead
, port
);
2345 ata_usleep(tr
, 100);
2347 /* Write some pattern to registers */
2348 ata_out(0x55, ata_Count
, port
);
2349 ata_out(0xaa, ata_LBALow
, port
);
2350 ata_out(0xaa, ata_Count
, port
);
2351 ata_out(0x55, ata_LBALow
, port
);
2352 ata_out(0x55, ata_Count
, port
);
2353 ata_out(0xaa, ata_LBALow
, port
);
2355 tmp1
= ata_in(ata_Count
, port
);
2356 tmp2
= ata_in(ata_LBALow
, port
);
2358 if ((tmp1
== 0x55) && (tmp2
== 0xaa))
2359 bus
->ab_Dev
[0] = DEV_UNKNOWN
;
2361 /* Select device 1 */
2362 ata_out(0xb0, ata_DevHead
, port
);
2363 ata_usleep(tr
, 100);
2365 /* Write some pattern to registers */
2366 ata_out(0x55, ata_Count
, port
);
2367 ata_out(0xaa, ata_LBALow
, port
);
2368 ata_out(0xaa, ata_Count
, port
);
2369 ata_out(0x55, ata_LBALow
, port
);
2370 ata_out(0x55, ata_Count
, port
);
2371 ata_out(0xaa, ata_LBALow
, port
);
2373 tmp1
= ata_in(ata_Count
, port
);
2374 tmp2
= ata_in(ata_LBALow
, port
);
2376 if ((tmp1
== 0x55) && (tmp2
== 0xaa))
2377 bus
->ab_Dev
[1] = DEV_UNKNOWN
;
2379 ata_ResetBus(tr
, bus
);
2381 CloseDevice((struct IORequest
*)tr
);
2382 DeleteIORequest((struct IORequest
*)tr
);
2387 * not really sure what this is meant to be - TO BE REPLACED
2389 static const ULONG ErrorMap
[] = {
2408 static ULONG
atapi_EndCmd(struct ata_Unit
*unit
)
2413 * read alternate status register (per specs)
2415 status
= ata_in(ata_AltStatus
, unit
->au_Bus
->ab_Alt
);
2416 DATAPI(bug("[ATAPI] Alternate status: %lx\n", status
));
2418 status
= ata_in(atapi_Status
, unit
->au_Bus
->ab_Port
);
2420 DATAPI(bug("[ATAPI] Command complete. Status: %lx\n", status
));
2422 if (!(status
& ATAPIF_CHECK
))
2428 status
= ata_in(atapi_Error
, unit
->au_Bus
->ab_Port
);
2429 DATAPI(bug("[ATAPI] Error code %lx\n", status
>> 4));
2430 return ErrorMap
[status
>> 4];
2435 * vim: ts=4 et sw=4 fdm=marker fmr={,}