added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / common / ata.device / lowlevel.c
blobb37aa679917b6fb7cb9f1c7415feda9a8fbee99d
1 /*
2 Copyright © 2004-2006, The AROS Development Team. All rights reserved
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*
10 * CHANGELOG:
11 * DATE NAME ENTRY
12 * ---------- ------------------ -------------------------------------------------------------------
13 * 2006-12-20 T. Wiszkowski Updated ATA Packet Interface to handle ATAPI/SCSI Commands
14 * 2008-01-06 T. Wiszkowski Corrected and completed ATA Packet Interface handling. PIO transfers fully operational.
15 * 2008-01-07 T. Wiszkowski Added initial DMA support for Direct SCSI commands. Corrected atapi
16 * READ and WRITE commands to pass proper transfer size to the atapi_SendPacket
17 * as discovered by mschulz
18 * 2008-01-25 T. Wiszkowski Rebuilt, rearranged and partially fixed 60% of the code here
19 * Enabled implementation to scan for other PCI IDE controllers
20 * Implemented ATAPI Packet Support for both read and write
21 * Corrected ATAPI DMA handling
22 * Fixed major IDE enumeration bugs severely handicapping transfers with more than one controller
23 * Compacted source and implemented major ATA support procedure
24 * Improved DMA and Interrupt management
25 * Removed obsolete code
26 * 2008-01-26 T. Wiszkowski Restored 32bit io
27 * Removed memory dump upon RequestSense
28 * 2008-02-08 T. Wiszkowski Fixed DMA accesses for direct scsi devices,
29 * Corrected IO Areas to allow ATA to talk to PCI controllers
32 #define DEBUG 0
33 #include <aros/debug.h>
34 #include <exec/types.h>
35 #include <exec/exec.h>
36 #include <exec/resident.h>
37 #include <utility/utility.h>
38 #include <oop/oop.h>
40 #include <dos/bptr.h>
42 #include <proto/exec.h>
43 #include <devices/timer.h>
45 #include "ata.h"
50 Prototypes of static functions from lowlevel.c. I do not want to make them
51 non-static as I'd like to remove as much symbols from global table as possible.
52 Besides some of this functions could conflict with old ide.device or any other
53 device.
55 static ULONG ata_ReadSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
56 static ULONG ata_ReadSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
57 static ULONG ata_ReadMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
58 static ULONG ata_ReadMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
59 static ULONG ata_ReadDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
60 static ULONG ata_ReadDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
61 static ULONG ata_WriteSector32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
62 static ULONG ata_WriteSector64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
63 static ULONG ata_WriteMultiple32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
64 static ULONG ata_WriteMultiple64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
65 static ULONG ata_WriteDMA32(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
66 static ULONG ata_WriteDMA64(struct ata_Unit *, UQUAD, ULONG, APTR, ULONG *);
67 static ULONG ata_Eject(struct ata_Unit *);
69 static ULONG atapi_ErrCmd();
70 static ULONG atapi_EndCmd(struct ata_Unit *unit);
72 static ULONG atapi_Read(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
73 static ULONG atapi_Write(struct ata_Unit *, ULONG, ULONG, APTR, ULONG *);
74 static ULONG atapi_Eject(struct ata_Unit *);
76 static void common_SetBestXferMode(struct ata_Unit* unit);
79 Again piece of code which shouldn't be here. Geee. After removing all this
80 asm constrictuins this ata.device will really deserve for location in
81 /arch/common
84 * having an x86 assembly here i dare to assume that this is meant to be
85 * an x86[_64] device only.
89 * the outsl and insl commands improperly assumed that every transfer is sized to multiple of four
91 static VOID insw(APTR address, UWORD port, ULONG count)
93 asm volatile ("cld; rep insw"::"Nd"(port),"c"(count >> 1),"D"(address):"memory");
96 static VOID insl(APTR address, UWORD port, ULONG count)
98 asm volatile ("cld; testb $2,%%al; je _insl_; insw; _insl_: rep insl" ::"Nd"(port),"a"(count&2),"c"(count >> 2),"D"(address));
101 static VOID outsw(APTR address, UWORD port, ULONG count)
103 asm volatile ("cld; rep outsw"::"Nd"(port),"c"(count >> 1),"S"(address));
106 static VOID outsl(APTR address, UWORD port, ULONG count)
108 asm volatile ("cld; testb $2,%%al; je _outsl_; outsw; _outsl_: rep outsl" ::"Nd"(port),"a"(count&2),"c"(count >> 2),"S"(address));
111 static void dump(APTR mem, ULONG len)
113 register int i,j;
114 for (j=0; j<(len+15)>>4; ++j)
116 bug("[ATA ] %06lx: ", j<<4);
118 for (i=0; i<len-(j<<4); i++)
120 bug("%02lx ", ((unsigned char*)mem)[(j<<4)|i]);
121 if (i == 15)
122 break;
125 for (i=0; i<len-(j<<4); i++)
127 unsigned char c = ((unsigned char*)mem)[(j<<4)|i];
129 bug("%c", c >= 0x20 ? c<=0x7f ? c : '.' : '.');
130 if (i == 15)
131 break;
133 bug("\n");
137 static void ata_strcpy(const UBYTE *str1, UBYTE *str2, ULONG size)
139 register int i = size;
141 while (size--)
143 str2[size^1] = str1[size];
146 while (i--)
148 if (str2[i] <= ' ')
149 str2[i] = 0;
155 * a STUB function for commands not supported by this particular device
157 static ULONG ata_STUB(struct ata_Unit *au)
159 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
160 return CDERR_NOCMD;
163 static ULONG ata_STUB_IO32(struct ata_Unit *au, ULONG blk, ULONG len, APTR buf, ULONG* act)
165 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
166 return CDERR_NOCMD;
169 static ULONG ata_STUB_IO64(struct ata_Unit *au, UQUAD blk, ULONG len, APTR buf, ULONG* act)
171 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
172 return CDERR_NOCMD;
175 static ULONG ata_STUB_SCSI(struct ata_Unit *au, struct SCSICmd* cmd)
177 D(bug("[ATA%02ld] CALLED STUB FUNCTION. THIS OPERATION IS NOT SUPPORTED BY DEVICE\n", au->au_UnitNum));
178 return CDERR_NOCMD;
182 * Very short delay (TM) by someone who assumes slow data ports.
183 * well, glad it works anyways.
185 void ata_400ns()
187 ata_in(ata_AltControl, 0x3f6);
188 ata_in(ata_AltControl, 0x3f6);
189 ata_in(ata_AltControl, 0x3f6);
190 ata_in(ata_AltControl, 0x3f6);
193 inline void ata_SelectUnit(struct ata_Unit* unit)
195 ata_out(unit->au_DevMask, ata_DevHead, unit->au_Bus->ab_Port);
198 inline void ata_ClearOldIRQ(struct ata_Unit *unit)
200 SetSignal(0, (1 << unit->au_Bus->ab_SleepySignal) | SIGBREAKF_CTRL_C);
204 * wait for timeout or drive ready
206 BOOL ata_WaitBusyTO(struct ata_Unit *unit, UWORD tout)
208 UBYTE status;
209 ULONG step = 0;
211 SetSignal(0, SIGBREAKF_CTRL_C);
213 Disable();
214 unit->au_Bus->ab_Timeout = tout;
215 Enable();
219 status = ata_in(ata_Status, unit->au_Bus->ab_Port);
220 ++step;
221 if ((step & 16) == 0)
223 if (SetSignal(0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
225 D(bug("[ATA%02ld] Device still busy after timeout. Aborting\n", unit->au_UnitNum));
226 return FALSE;
229 D(bug("[ATA%02ld] Still waiting (%02lx)...\n", unit->au_UnitNum, status));
230 } while(status & ATAF_BUSY);
232 D(bug("[ATA%02ld] Ready.\n", unit->au_UnitNum));
233 Disable();
234 unit->au_Bus->ab_Timeout = 0;
235 Enable();
237 SetSignal(0, SIGBREAKF_CTRL_C);
239 return TRUE;
243 * wait for timeout or IRQ
245 BOOL ata_WaitIRQ(struct ata_Unit *unit, UWORD tout)
247 SetSignal(0, SIGBREAKF_CTRL_C);
249 Disable();
250 unit->au_Bus->ab_Timeout = tout;
251 Enable();
253 D(bug("[ATA%02ld] Awaiting IRQ.\n", unit->au_UnitNum));
255 if (Wait((1<<unit->au_Bus->ab_SleepySignal) | SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
257 D(bug("[ATA%02ld] Timed out.\n", unit->au_UnitNum));
258 return FALSE;
261 D(bug("[ATA%02ld] Ready.\n", unit->au_UnitNum));
262 Disable();
263 unit->au_Bus->ab_Timeout = 0;
264 Enable();
267 * clear signal just in case
269 SetSignal(0, SIGBREAKF_CTRL_C);
271 return TRUE;
275 * just wait for timeout
277 void ata_Wait(struct ata_Unit *unit, UWORD tout)
279 SetSignal(0, SIGBREAKF_CTRL_C);
281 Disable();
282 unit->au_Bus->ab_Timeout = tout;
283 Enable();
285 Wait(SIGBREAKF_CTRL_C);
290 * Procedure for sending ATA command blocks
291 * it appears LARGE but there's a lot of COMMENTS here :)
292 * handles *all* ata commands (no data, pio and dma)
293 * naturally could be splitted at some point in the future
294 * depends if anyone believes that the change for 50 lines
295 * would make slow ATA transfers any faster
297 static ULONG ata_exec_cmd(struct ata_Unit* au, ata_CommandBlock *block)
299 UBYTE stat;
300 ULONG port = au->au_Bus->ab_Port;
301 ULONG err = 0;
302 APTR mem = block->buffer;
303 BOOL dma = FALSE;
307 * initial checks and stuff
309 switch (block->method)
311 case CM_DMARead:
312 case CM_DMAWrite:
313 dma = TRUE;
314 break;
315 case CM_PIORead:
316 case CM_PIOWrite:
317 case CM_NoData:
318 break;
319 default:
320 return IOERR_NOCMD;
323 switch (block->type)
325 case CT_LBA28:
326 if (block->sectors > 256)
328 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 256 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
329 return IOERR_BADLENGTH;
332 /* note:
333 * we want the above to fall in here!
334 * we really do (checking for secmul)
337 case CT_LBA48:
338 if (block->sectors > 65536)
340 bug("[ATA%02ld] ERROR: Transfer length (%ld) exceeds 65536 sectors. Aborting.\n", au->au_UnitNum, block->sectors);
341 return IOERR_BADLENGTH;
343 if (block->secmul == 0)
345 bug("[ATA%02ld] ERROR: Invalid transfer multiplier. Should be at least set to 1 (correcting)\n", au->au_UnitNum);
346 block->secmul = 1;
348 break;
350 case CT_NoBlock:
351 break;
353 default:
354 bug("[ATA%02ld] ERROR: Invalid command type %lx. Aborting.\n", au->au_UnitNum, block->type);
355 return IOERR_NOCMD;
359 block->actual = 0;
364 * PRECONDITIONS: ENABLED INTRQ (0x08 written to ata_Command port)
366 * - select device
368 ata_out(0x08, ata_AltControl, au->au_Bus->ab_Alt);
369 D(bug("[ATA%02ld] Executing command %02lx\n", au->au_UnitNum, block->command));
370 ata_out(au->au_DevMask, ata_DevHead, port);
373 * generally we could consider marking unit as 'retarded' upon three attempts or stuff like that
375 if (ata_WaitBusyTO(au, 100) == FALSE)
377 bug("[ATA%02ld] UNIT BUSY AT SELECTION\n", au->au_UnitNum);
378 return IOERR_UNITBUSY;
381 if (block->feature != 0)
383 ata_out(block->feature, ata_Feature, port);
388 * - clear all old signals
390 //D(bug("[ATA%02ld] Clearing old signals\n", au->au_UnitNum));
391 SetSignal(0, (1 << au->au_Bus->ab_SleepySignal) | SIGBREAKF_CTRL_C);
392 ata_in(ata_Status, port);
397 * - set LBA and sector count
399 switch (block->type)
401 case CT_LBA28:
402 //D(bug("[ATA%02ld] Command uses 28bit LBA addressing (OLD)\n", au->au_UnitNum));
403 ata_out(((block->blk >> 24) & 0x0f) | 0x40 | au->au_DevMask, ata_DevHead, port);
404 ata_out(block->blk >> 16, ata_LBAHigh, port);
405 ata_out(block->blk >> 8, ata_LBAMid, port);
406 ata_out(block->blk, ata_LBALow, port);
407 ata_out(block->sectors, ata_Count, port);
408 break;
410 case CT_LBA48:
411 //D(bug("[ATA%02ld] Command uses 48bit LBA addressing (NEW)\n", au->au_UnitNum));
412 ata_out(block->blk >> 40, ata_LBAHigh, port);
413 ata_out(block->blk >> 32, ata_LBAMid, port);
414 ata_out(block->blk >> 24, ata_LBALow, port);
416 ata_out(block->blk >> 16, ata_LBAHigh, port);
417 ata_out(block->blk >> 8, ata_LBAMid, port);
418 ata_out(block->blk, ata_LBALow, port);
420 ata_out(block->sectors >> 8, ata_Count, port);
421 ata_out(block->sectors, ata_Count, port);
422 break;
424 case CT_NoBlock:
425 //D(bug("[ATA%02ld] Command does not address any block\n", au->au_UnitNum));
426 break;
432 * setup DMA & push command
434 switch (block->method)
436 case CM_DMARead:
437 //D(bug("[ATA%02ld] Initializing DMA for Read\n", au->au_UnitNum));
438 dma_SetupPRDSize(au, mem, block->length, TRUE);
439 CachePreDMA(mem, &block->length, DMA_ReadFromRAM);
440 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
441 ata_out(block->command, ata_Command, port);
442 dma_StartDMA(au);
443 break;
445 case CM_DMAWrite:
446 //D(bug("[ATA%02ld] Initializing DMA for Write\n", au->au_UnitNum));
447 dma_SetupPRDSize(au, mem, block->length, FALSE);
448 CachePreDMA(mem, &block->length, 0);
449 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
450 ata_out(block->command, ata_Command, port);
451 dma_StartDMA(au);
452 break;
454 case CM_PIOWrite:
455 //D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
456 ata_out(block->command, ata_Command, port);
457 ata_400ns();
458 break;
460 case CM_PIORead:
461 case CM_NoData:
462 D(bug("[ATA%02ld] Sending command\n", au->au_UnitNum));
463 ata_ClearOldIRQ(au);
464 ata_out(block->command, ata_Command, port);
465 if (FALSE == ata_WaitIRQ(au, 1000))
467 D(bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum));
468 err = IOERR_UNITBUSY;
469 break;
472 if (block->method == CM_PIORead)
473 break;
475 return 0;
480 * entering main command loop here.
482 while (err == 0)
485 * THEORY: PIO is entering stage H1. Waiting for drive to clear 'busy'
486 * once busy clears and no data is requested, we're free to go.
487 * DMA is waiting for the DMARQ to be raised
489 if (dma)
492 * we're not really expected to do much here.
493 * just wait for the dma transfer to complete
494 * check if dma transfer completed, otherwise give it another wait.
496 stat = ata_in(dma_Status, au->au_DMAPort);
497 D(bug("[ATA%02ld] DMA status %02lx\n", au->au_UnitNum, stat));
499 if (stat & DMAF_Interrupt)
501 //D(bug("[ATA%02ld] DMA transfer is now complete\n", au->au_UnitNum));
502 block->actual = block->length;
504 else if (stat & DMAF_Error)
506 //D(bug("[ATA%02ld] DMA ended with an error\n", au->au_UnitNum));
507 err = IOERR_ABORTED;
509 else
511 //D(bug("[ATA%02ld] DMA transfer is still in progress\n", au->au_UnitNum));
514 else
516 UWORD len = (block->secmul << au->au_SectorShift);
519 * wait for drive to clear busy
521 if (FALSE == ata_WaitBusyTO(au, 1000))
523 bug("[ATA%02ld] Device busy after timeout\n", au->au_UnitNum);
524 err = IOERR_UNITBUSY;
525 break;
531 * check if we have the state: BSY=1 && DRQ=0 && DMARQ=1
532 * this means dma is still progressing
534 stat = ata_in(ata_Status, port);
535 if (0 == (stat & ATAF_DATAREQ))
537 bug("[ATA%02ld] No more data\n", au->au_UnitNum);
538 break;
543 * THEORY: we loop here: wait for interrupt, then wait for busy cleared, then
544 * while datareq transfer one long (or byte, or whatever).
545 * PRACTICE: transfer all data as it goes, as do most other systems.
547 while (stat & ATAF_DATAREQ)
549 if (len > (block->length - block->actual))
550 len = block->length - block->actual;
552 //D(bug("[ATA%02ld] Transferring %ld bytes to %08lx\n", au->au_UnitNum, len, mem));
554 switch (block->method)
557 * first case
558 * data is ready to transfer over PIO
559 * actually we are expected to check status prior to each insw/insl,
560 * doubt anyone does this. could cause problems with SLOW ata devices
561 * right here.
562 * transferring one block at a time, no more.
564 case CM_PIORead:
565 D(bug("[ATA%02ld] Reading bytes (PIO)\n", au->au_UnitNum));
566 au->au_ins(mem, au->au_Bus->ab_Port, len);
567 block->actual += len;
568 mem = &((char*)mem)[block->actual];
569 break;
572 * second case
573 * drive is ready to accept data over PIO
574 * we're supposed to check status prior to each outsw/outsl
575 * to make sure drive is actually ready to accept more data.
576 * otherwise slow devices will have problems accepting flood
577 * right here
578 * transferring one block at a time, no more.
580 case CM_PIOWrite:
581 D(bug("[ATA%02ld] Writing bytes (PIO)\n", au->au_UnitNum));
582 au->au_outs(mem, au->au_Bus->ab_Port, len);
583 block->actual += len;
584 mem = &((char*)mem)[block->actual];
585 break;
588 * we will never get here.
590 default:
591 break;
595 stat = ata_in(ata_Status, port);
596 D(bug("[ATA%02ld] Current command status %02lx\n", au->au_UnitNum, stat));
597 if (stat & ATAF_ERROR)
599 err = IOERR_ABORTED;
600 bug("[ATA%02ld] Command %lx finished with an error. Aborting.\n", au->au_UnitNum, block->command);
601 break;
607 stat = ata_in(ata_Status, port);
610 * check if previous transfer failed OR if we got all data we need
612 if ((err != 0) || (block->actual >= block->length))
613 break;
616 * THEORY: entering stage H0, waititng for drive to ping us with an interrupt
618 //D(bug("[ATA%02ld] Waiting for device to raise interrupt (data ready)\n", au->au_UnitNum));
620 * wait for interrupt
622 if (FALSE == ata_WaitIRQ(au, 1000))
624 bug("[ATA%02ld] Device is late - no response\n", au->au_UnitNum);
625 err = IOERR_UNITBUSY;
626 break;
633 * clean up DMA
634 * don't use 'mem' pointer here as it's already invalid.
636 if (block->method == CM_DMARead)
638 //D(bug("[ATA%02ld] Finalizing DMA Read\n", au->au_UnitNum));
639 dma_StopDMA(au);
640 CachePostDMA(block->buffer, &block->length, DMA_ReadFromRAM);
642 else if (block->method == CM_DMAWrite)
644 //D(bug("[ATA%02ld] Finalizing DMA Write\n", au->au_UnitNum));
645 dma_StopDMA(au);
646 CachePostDMA(block->buffer, &block->length, 0);
648 //D(bug("[ATA%02ld] All done\n", au->au_UnitNum));
653 * signal error back to caller
655 if (0 != err)
656 return err;
658 stat = ata_in(ata_Status, port);
659 if (stat & ATAF_ERROR)
660 return IOERR_ABORTED;
662 return 0;
666 * atapi packet iface
668 int atapi_SendPacket(struct ata_Unit *unit, APTR packet, LONG datalen, BOOL *dma, BOOL write)
670 *dma &= (unit->au_XferModes & AF_XFER_DMA) ? TRUE : FALSE;
672 UBYTE cmd[12] = {
675 register int t=5,l=0;
676 ULONG port = unit->au_Bus->ab_Port;
678 if (((UBYTE*)packet)[0] > 0x1f)
679 t+= 4;
680 if (((UBYTE*)packet)[0] > 0x5f)
681 t+= 2;
683 switch (((UBYTE*)packet)[0])
685 case 0x28: // read10
686 case 0xa8: // read12
687 case 0xbe: // readcd
688 case 0xb9: // readcdmsf
689 case 0x2f: // verify
690 case 0x2a: // write
691 case 0xaa: // write12
692 case 0x2e: // writeverify
693 break;
694 default:
695 *dma = FALSE;
698 while (l<=t)
700 cmd[l] = ((UBYTE*)packet)[l];
701 ++l;
705 bug("[ATAPI] Sending %s ATA packet: ", (*dma) ? "DMA" : "PIO");
706 l=0;
707 while (l<=t)
709 bug("%02lx ", ((UBYTE*)cmd)[l]);
710 ++l;
712 bug("\n");
714 if (datalen & 1)
715 bug("[ATAPI] ERROR: DATA LENGTH NOT EVEN! Rounding Up! (%ld bytes requested)\n", datalen);
718 datalen = (datalen+1)&~1;
720 ata_out(0x08, ata_AltControl, unit->au_Bus->ab_Alt);
721 ata_out(unit->au_DevMask, atapi_DevSel, port);
722 if (ata_WaitBusyTO(unit, 10))
725 * since the device is now ready (~BSY) && (~DRQ), we can set up features and transfer size
728 * we should consider using the DIRECTION flag here, too
730 ata_out(((*dma) ? 1 : 0) | ((write) ? 4 : 0), atapi_Features, port);
731 ata_out((datalen & 0xff), atapi_ByteCntL, port);
732 ata_out((datalen >> 8) & 0xff, atapi_ByteCntH, port);
735 * once we're done with that, we can go ahead and inform device that we're about to send atapi packet
736 * after command is dispatched, we are obliged to give 400ns for the unit to parse command and set status
738 ata_ClearOldIRQ(unit);
739 ata_out(ATA_PACKET, atapi_Command, port);
740 if (ata_WaitBusyTO(unit, 50) == FALSE)
742 D(bug("[ATAPI] Unit not ready to accept command.\n"));
743 return IOERR_UNITBUSY;
747 * now we're waiting for the device to process following:
748 * - set BSY to prepare for packet reception
749 * - set COD bit and clear IO,
750 * - set DRQ bit and finally
751 * - clear BSY
754 * at this point we can expect DATAREQ (that would indicate device wants to retrieve packet
755 * OR some fault meaning device does not support packets
757 UBYTE status = ata_in(atapi_Status, port);
759 if (status & ATAF_DATAREQ)
762 * if we got here, it means that device most likely expects us to send exactly 12 bytes
763 * of packet data. no more, and no less. 12 bytes.
765 unit->au_outs(cmd, port, 12);
766 return 1;
768 else
770 D(bug("[ATAPI] interface not ready to retrieve data. Status: %lx\n", status));
773 else
775 D(bug("[ATAPI] WaitBusy failed at first check\n"));
778 return 0;
781 ULONG atapi_DirectSCSI(struct ata_Unit *unit, struct SCSICmd *cmd)
783 ULONG port = unit->au_Bus->ab_Port;
784 APTR buffer = cmd->scsi_Data;
785 ULONG length = cmd->scsi_Length;
786 ULONG size = 0;
787 UBYTE status;
788 UBYTE err = 0;
789 BOOL dma = FALSE;
791 cmd->scsi_Actual = 0;
793 D(bug("[DSCSI] Sending packet!\n"));
797 * setup DMA & push command
798 * it does not really mean we will use dma here btw
800 if ((unit->au_XferModes & AF_XFER_DMA) && (cmd->scsi_Length !=0) && (cmd->scsi_Data != 0))
802 if ((cmd->scsi_Flags & SCSIF_READ) != 0)
804 dma_SetupPRDSize(unit, cmd->scsi_Data, cmd->scsi_Length, TRUE);
805 CachePreDMA(cmd->scsi_Data, &cmd->scsi_Length, DMA_ReadFromRAM);
807 else
809 dma_SetupPRDSize(unit, cmd->scsi_Data, cmd->scsi_Length, FALSE);
810 CachePreDMA(cmd->scsi_Data, &cmd->scsi_Length, 0);
812 dma = TRUE;
815 if (atapi_SendPacket(unit, cmd->scsi_Command, cmd->scsi_Length, &dma, (cmd->scsi_Flags & SCSIF_READ) == 0))
818 * PIO vs DMA
820 if (FALSE == dma)
822 if (ata_WaitIRQ(unit, 1000) == FALSE)
824 D(bug("[DSCSI] Command timed out.\n"));
825 err = IOERR_UNITBUSY;
828 while (err == 0)
831 while ((status = ata_in(atapi_Status, port)) & ATAF_BUSY);
832 D(bug("[DSCSI] Command status: %lx\n", status));
834 if (status & ATAF_DATAREQ)
836 UBYTE reason = ata_in(atapi_Reason, port);
837 D(bug("[DSCSI] Current status: %ld, SCSI flags: %ld\n", reason, cmd->scsi_Flags));
839 if (((cmd->scsi_Flags & SCSIF_READ) == SCSIF_READ) &&
840 ((reason & ATAPIF_MASK) == ATAPIF_READ))
842 size = ata_in(atapi_ByteCntH, port) << 8 |
843 ata_in(atapi_ByteCntL, port);
844 D(bug("[DSCSI] data available for read (%ld bytes, max: %ld bytes)\n", size, length));
845 if (size > length)
847 D(bug("[DSCSI] CRITICAL! MORE DATA THAN STORAGE ALLOWS: %ld bytes vs %ld bytes left!\n", size, length));
848 /* damnit!! need to report some critical error here! */
849 //size = length;
851 unit->au_ins(buffer, port, size);
852 D(bug("[DSCSI] %lu bytes read.\n", size));
854 else if (((cmd->scsi_Flags & SCSIF_READ) == 0) &&
855 ((reason & ATAPIF_MASK) == ATAPIF_WRITE))
857 size = ata_in(atapi_ByteCntH, port) << 8 |
858 ata_in(atapi_ByteCntL, port);
859 D(bug("[DSCSI] device available for write\n"));
860 if (size > length)
862 D(bug("[DSCSI] CRITICAL! MORE DATA THAN STORAGE ALLOWS: %ld bytes vs %ld bytes left!\n", size, length));
863 /* damnit!! need to report some critical error here! */
864 //size = length;
866 unit->au_outs(buffer, port, size);
867 D(bug("[DSCSI] %lu bytes written.\n", size));
869 else
871 D(bug("[DSCSI] Drive data ready, but there's no storage to transfer. R != W\n"));
872 size = 0;
873 err = CDERR_InvalidState;
874 break;
877 cmd->scsi_Actual += size;
878 buffer += size;
879 length -= size;
881 else
883 D(bug("[DSCSI] User transfer complete, %ld bytes transferred.\n", cmd->scsi_Actual));
884 err = atapi_EndCmd(unit);
885 break;
889 else
891 dma_StartDMA(unit);
893 while (err == 0)
895 if (FALSE == ata_WaitIRQ(unit, 300))
897 err = IOERR_UNITBUSY;
898 break;
901 status = ata_in(ata_Status, port);
902 if (0 == (status & (ATAF_BUSY | ATAF_DATAREQ)))
903 break;
905 status = ata_in(dma_Status, unit->au_DMAPort);
906 D(bug("[ATAPI] DMA status: %lx\n", status));
907 if (0 == (status & DMAF_Interrupt))
909 break;
911 if (0 != (status & DMAF_Error))
913 err = IOERR_ABORTED;
914 break;
917 dma_StopDMA(unit);
920 else
922 err = atapi_ErrCmd();
926 * clean up DMA
927 * don't use 'mem' pointer here as it's already invalid.
929 if (unit->au_XferModes & AF_XFER_DMA)
931 if ((cmd->scsi_Flags & SCSIF_READ) == SCSIF_READ)
933 CachePostDMA(cmd->scsi_Data, &cmd->scsi_Length, DMA_ReadFromRAM);
935 else if ((cmd->scsi_Flags & SCSIF_READ) == 0)
937 CachePostDMA(cmd->scsi_Data, &cmd->scsi_Length, 0);
943 * on check condition - grab sense data
945 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
946 if (((err != 0) || (status & ATAPIF_CHECK)) && (cmd->scsi_Flags & SCSIF_AUTOSENSE))
948 atapi_RequestSense(unit, cmd->scsi_SenseData, cmd->scsi_SenseLength);
949 D(dump(cmd->scsi_SenseData, cmd->scsi_SenseLength));
952 return err;
956 * chops the large transfers into set of smaller transfers
957 * specifically useful when requested transfer size is >256 sectors for 28bit commands
959 static ULONG ata_exec_blk(struct ata_Unit *unit, ata_CommandBlock *blk)
961 ULONG err=0;
962 ULONG part;
963 ULONG max=256;
964 ULONG count=blk->sectors;
966 if (blk->type == CT_LBA48)
967 max <<= 8;
969 D(bug("[ATA%02ld] Accessing %ld sectors starting from %lx\n", unit->au_UnitNum, count, blk->blk));
970 while ((count > 0) && (err == 0))
972 part = (count > max) ? max : count;
973 blk->sectors = part;
974 blk->length = part << unit->au_SectorShift;
976 err = ata_exec_cmd(unit, blk);
978 blk->blk += part;
979 blk->buffer = &((char*)blk->buffer)[part << unit->au_SectorShift];
980 count -= part;
982 return err;
986 * Initial device configuration that suits *all* cases
988 BOOL ata_setup_unit(struct ata_Bus *bus, UBYTE u)
990 struct ata_Unit *unit=NULL;
993 * this stuff always goes along the same way
995 D(bug("[ATA ] setting up unit %ld\n", u));
997 unit = bus->ab_Units[u];
998 if (NULL == unit)
999 return FALSE;
1001 unit->au_Bus = bus;
1002 unit->au_Drive = AllocPooled(bus->ab_Base->ata_MemPool, sizeof(struct DriveIdent));
1003 unit->au_UnitNum = bus->ab_BusNum << 1 | u; // b << 8 | u
1004 unit->au_DevMask = 0xa0 | (u << 4);
1005 if (bus->ab_Base->ata_32bit)
1007 unit->au_ins = insl;
1008 unit->au_outs = outsl;
1010 else
1012 unit->au_ins = insw;
1013 unit->au_outs = outsw;
1015 unit->au_SectorShift= 9; /* this really has to be set here. */
1016 unit->au_Flags = 0;
1018 NEWLIST(&unit->au_SoftList);
1021 * since the stack is always handled by caller
1022 * it's safe to stub all calls with one function
1024 unit->au_Read32 = ata_STUB_IO32;
1025 unit->au_Read64 = ata_STUB_IO64;
1026 unit->au_Write32 = ata_STUB_IO32;
1027 unit->au_Write64 = ata_STUB_IO64;
1028 unit->au_Eject = ata_STUB;
1029 unit->au_DirectSCSI = ata_STUB_SCSI;
1030 unit->au_Identify = ata_STUB;
1032 if (FALSE == ata_WaitBusyTO(unit, 10))
1034 D(bug("[ATA%02ld] ERROR: Drive not ready for use. Keeping functions stubbed\n", unit->au_UnitNum));
1035 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1036 bus->ab_Base->ata_MemPool = 0;
1037 return FALSE;
1040 switch (bus->ab_Dev[u])
1043 * safe fallback settings
1045 case DEV_SATAPI:
1046 case DEV_ATAPI:
1047 unit->au_Identify = atapi_Identify;
1048 break;
1050 case DEV_SATA:
1051 case DEV_ATA:
1052 unit->au_Identify = ata_Identify;
1053 break;
1056 default:
1057 D(bug("[ATA%02ld] Unsupported device %lx. All functions will remain stubbed.\n", unit->au_UnitNum, bus->ab_Dev[u]));
1058 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1059 bus->ab_Base->ata_MemPool = 0;
1060 return FALSE;
1064 * now make unit self diagnose
1066 if (unit->au_Identify(unit) != 0)
1068 FreePooled(bus->ab_Base->ata_MemPool, unit->au_Drive, sizeof(struct DriveIdent));
1069 bus->ab_Base->ata_MemPool = 0;
1070 return FALSE;
1073 return TRUE;
1079 * ata[pi] identify
1081 static void common_SetXferMode(struct ata_Unit* unit, ata_XferMode mode)
1083 UBYTE type=0;
1084 BOOL dma=FALSE;
1085 ata_CommandBlock acb =
1087 0xef,
1088 0x03,
1089 0x01,
1090 0x00,
1091 0x00,
1092 0x00,
1093 0x00,
1094 0x00,
1095 0x00,
1096 CM_NoData,
1097 CT_LBA28
1100 if ((unit->au_DMAPort == 0) && (mode > AB_XFER_PIO7))
1102 D(bug("[ATA%02ld] This controller does not own DMA port! Will set best PIO\n", unit->au_UnitNum));
1103 common_SetBestXferMode(unit);
1104 return;
1109 * first, ONLY for ATA devices, set new commands
1111 if (0 == (unit->au_XferModes & AF_XFER_PACKET))
1113 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1115 if (unit->au_XferModes & AF_XFER_RWMULTI)
1117 unit->au_Read32 = ata_ReadMultiple32;
1118 unit->au_Write32 = ata_WriteMultiple32;
1119 if (unit->au_XferModes & AF_XFER_48BIT)
1121 unit->au_Read64 = ata_ReadMultiple64;
1122 unit->au_Write64 = ata_WriteMultiple64;
1125 else
1127 unit->au_Read32 = ata_ReadSector32;
1128 unit->au_Write32 = ata_WriteSector32;
1129 if (unit->au_XferModes & AF_XFER_48BIT)
1131 unit->au_Read64 = ata_ReadSector64;
1132 unit->au_Write64 = ata_WriteSector64;
1136 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1138 unit->au_Read32 = ata_ReadDMA32;
1139 unit->au_Write32 = ata_WriteDMA32;
1140 if (unit->au_XferModes & AF_XFER_48BIT)
1142 unit->au_Read64 = ata_ReadDMA64;
1143 unit->au_Write64 = ata_WriteDMA64;
1146 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1148 unit->au_Read32 = ata_ReadDMA32;
1149 unit->au_Write32 = ata_WriteDMA32;
1150 if (unit->au_XferModes & AF_XFER_48BIT)
1152 unit->au_Read64 = ata_ReadDMA64;
1153 unit->au_Write64 = ata_WriteDMA64;
1156 else
1158 unit->au_Read32 = ata_ReadSector32;
1159 unit->au_Write32 = ata_WriteSector32;
1160 if (unit->au_XferModes & AF_XFER_48BIT)
1162 unit->au_Read64 = ata_ReadSector64;
1163 unit->au_Write64 = ata_WriteSector64;
1168 if ((mode >= AB_XFER_PIO0) & (mode <= AB_XFER_PIO7))
1170 type = 8 + (mode - AB_XFER_PIO0);
1172 else if ((mode >= AB_XFER_MDMA0) & (mode <= AB_XFER_MDMA7))
1174 type = 32 + (mode - AB_XFER_MDMA7);
1175 dma=TRUE;
1177 else if ((mode >= AB_XFER_UDMA0) & (mode <= AB_XFER_UDMA7))
1179 type = 64 + (mode - AB_XFER_MDMA7);
1180 dma=TRUE;
1182 else
1184 type = 0;
1187 acb.sectors = type;
1188 if (0 != ata_exec_cmd(unit, &acb))
1190 D(bug("[ATA%02ld] ERROR: Failed to apply new xfer mode.\n", unit->au_UnitNum));
1193 if (unit->au_DMAPort)
1195 type = ata_in(dma_Status, unit->au_DMAPort);
1196 type &= 0x60;
1197 if (dma)
1199 type |= 1 << (5 + (unit->au_UnitNum & 1));
1201 else
1203 type &= ~(1 << (5 + (unit->au_UnitNum & 1)));
1206 D(bug("[DSCSI] Trying to apply new DMA (%lx) status: %02lx (unit %ld)\n", unit->au_DMAPort, type, unit->au_UnitNum & 1));
1208 ata_SelectUnit(unit);
1209 ata_out(type, dma_Status, unit->au_DMAPort);
1210 if (type == (ata_in(dma_Status, unit->au_DMAPort) & 0x60))
1212 D(bug("[DSCSI] New DMA Status: %02lx\n", type));
1214 else
1216 D(bug("[DSCSI] Failed to modify DMA state for this device\n"));
1217 dma = FALSE;
1221 if (dma)
1222 unit->au_XferModes |= AF_XFER_DMA;
1223 else
1224 unit->au_XferModes &=~AF_XFER_DMA;
1227 static void common_SetBestXferMode(struct ata_Unit* unit)
1229 int iter;
1230 int max = AB_XFER_UDMA7;
1232 if (unit->au_DMAPort == 0)
1235 * make sure you reduce scan search to pio here!
1236 * otherwise this and above function will fall into infinite loop
1238 D(bug("[ATA%02ld] This controller does not own DMA port\n", unit->au_UnitNum));
1239 max = AB_XFER_PIO7;
1242 for (iter=max; iter>=AB_XFER_PIO0; --iter)
1244 if (unit->au_XferModes & (1<<iter))
1246 common_SetXferMode(unit, iter);
1247 return;
1250 bug("[ATA%02ld] ERROR: device never reported any valid xfer modes. will continue at default\n", unit->au_UnitNum);
1251 common_SetXferMode(unit, AB_XFER_PIO0);
1254 void common_DetectXferModes(struct ata_Unit* unit)
1256 int iter;
1258 D(bug("[ATA%02ld] Supports\n", unit->au_UnitNum));
1260 if (unit->au_Drive->id_Commands4 & (1 << 4))
1262 D(bug("[ATA%02ld] - Packet interface\n", unit->au_UnitNum));
1263 unit->au_XferModes |= AF_XFER_PACKET;
1264 unit->au_DirectSCSI = atapi_DirectSCSI;
1266 else if (unit->au_Drive->id_Commands5 & (1 << 10))
1268 /* ATAPI devices do not use this bit. */
1269 D(bug("[ATA%02ld] - 48bit I/O\n", unit->au_UnitNum));
1270 unit->au_XferModes |= AF_XFER_48BIT;
1273 if ((unit->au_XferModes & AF_XFER_PACKET) || (unit->au_Drive->id_Capabilities & (1<< 9)))
1275 D(bug("[ATA%02ld] - LBA Addressing\n", unit->au_UnitNum));
1276 unit->au_XferModes |= AF_XFER_LBA;
1278 else
1280 D(bug("[ATA%02ld] - DEVICE DOES NOT SUPPORT LBA ADDRESSING >> THIS IS A POTENTIAL PROBLEM <<\n", unit->au_UnitNum));
1283 if (unit->au_Drive->id_RWMultipleSize & 0xff)
1285 D(bug("[ATA%02ld] - R/W Multiple (%ld sectors per xfer)\n", unit->au_UnitNum, unit->au_Drive->id_RWMultipleSize & 0xff));
1286 unit->au_XferModes |= AF_XFER_RWMULTI;
1289 if (unit->au_Drive->id_PIOSupport & 0xff)
1291 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1292 for (iter=0; iter<8; iter++)
1294 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1296 D(bug("PIO%ld ", iter));
1297 unit->au_XferModes |= AF_XFER_PIO(iter);;
1300 D(bug("\n"));
1303 if (unit->au_Drive->id_Capabilities & (1<<8))
1305 D(bug("[ATA%02ld] DMA:\n", unit->au_UnitNum));
1306 if (unit->au_Drive->id_MWDMASupport & 0xff)
1308 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1309 for (iter=0; iter<8; iter++)
1311 if (unit->au_Drive->id_MWDMASupport & (1 << iter))
1313 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1314 if (unit->au_Drive->id_MWDMASupport & (256 << iter))
1316 D(bug("[MDMA%ld] ", iter));
1318 else
1320 D(bug("MDMA%ld ", iter));
1324 D(bug("\n"));
1327 if (unit->au_Drive->id_UDMASupport & 0xff)
1329 D(bug("[ATA%02ld] - ", unit->au_UnitNum));
1330 for (iter=0; iter<8; iter++)
1332 if (unit->au_Drive->id_UDMASupport & (1 << iter))
1334 unit->au_XferModes |= AF_XFER_MDMA(iter);;
1335 if (unit->au_Drive->id_UDMASupport & (256 << iter))
1337 D(bug("[UDMA%ld] ", iter));
1339 else
1341 D(bug("UDMA%ld ", iter));
1345 D(bug("\n"));
1350 ULONG atapi_Identify(struct ata_Unit* unit)
1352 ata_CommandBlock acb =
1354 ATA_IDENTIFY_ATAPI,
1360 unit->au_Drive,
1361 sizeof(struct DriveIdent),
1363 CM_PIORead,
1364 CT_NoBlock
1367 ata_SelectUnit(unit);
1368 if (ata_WaitBusyTO(unit, 100) == FALSE)
1370 bug("[ATA%02ld] Unit not ready after timeout. Aborting.\n", unit->au_UnitNum);
1371 return IOERR_UNITBUSY;
1374 if (ata_exec_cmd(unit, &acb))
1376 return IOERR_OPENFAIL;
1379 D(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1381 unit->au_SectorShift = 11;
1382 unit->au_Read32 = atapi_Read;
1383 unit->au_Read64 = NULL;
1384 unit->au_Write32 = atapi_Write;
1385 unit->au_Write64 = NULL;
1386 unit->au_DirectSCSI = atapi_DirectSCSI;
1387 unit->au_Eject = atapi_Eject;
1388 unit->au_Flags |= AF_DiscPresenceUnknown;
1389 unit->au_DevType = (unit->au_Drive->id_General >>8) & 0x1f;
1390 unit->au_XferModes = AF_XFER_PACKET;
1392 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1393 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1394 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1396 D(bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev));
1397 common_DetectXferModes(unit);
1398 common_SetBestXferMode(unit);
1400 if (unit->au_Drive->id_General & 0x80)
1402 D(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1403 unit->au_Flags |= AF_Removable;
1406 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1407 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1410 * ok, this is not very original, but quite compatible :P
1412 switch (unit->au_DevType)
1414 case DG_CDROM:
1415 case DG_WORM:
1416 case DG_OPTICAL_DISK:
1417 unit->au_SectorShift = 11;
1418 unit->au_Flags |= AF_SlowDevice;
1419 unit->au_Heads = 1;
1420 unit->au_Sectors = 75;
1421 unit->au_Cylinders = 4440;
1422 break;
1424 case DG_DIRECT_ACCESS:
1425 unit->au_SectorShift = 9;
1426 if (!strcmp("LS-120", &unit->au_Model[0]))
1428 unit->au_Flags |= AF_SlowDevice;
1429 unit->au_Heads = 2;
1430 unit->au_Sectors = 18;
1431 unit->au_Cylinders = 6848;
1433 else if (!strcmp("ZIP 100 ", &unit->au_Model[8]))
1435 unit->au_Flags &= ~AF_SlowDevice;
1436 unit->au_Heads = 1;
1437 unit->au_Sectors = 64;
1438 unit->au_Cylinders = 3072;
1440 break;
1443 unit->au_NumLoop = 10000000;
1444 return 0;
1447 ULONG ata_Identify(struct ata_Unit* unit)
1449 ata_CommandBlock acb =
1451 ATA_IDENTIFY_DEVICE,
1457 unit->au_Drive,
1458 sizeof(struct DriveIdent),
1460 CM_PIORead,
1461 CT_NoBlock
1464 if (ata_exec_cmd(unit, &acb))
1466 return IOERR_OPENFAIL;
1469 D(dump(unit->au_Drive, sizeof(struct DriveIdent)));
1471 unit->au_SectorShift = 9;
1472 unit->au_DevType = DG_DIRECT_ACCESS;
1473 unit->au_Read32 = ata_ReadSector32;
1474 unit->au_Write32 = ata_WriteSector32;
1475 unit->au_DirectSCSI = atapi_DirectSCSI;
1476 unit->au_Eject = ata_Eject;
1477 unit->au_XferModes = 0;
1478 unit->au_Flags |= AF_DiscPresent;
1479 unit->au_DevType = DG_DIRECT_ACCESS;
1481 ata_strcpy(unit->au_Drive->id_Model, unit->au_Model, 40);
1482 ata_strcpy(unit->au_Drive->id_SerialNumber, unit->au_SerialNumber, 20);
1483 ata_strcpy(unit->au_Drive->id_FirmwareRev, unit->au_FirmwareRev, 8);
1485 D(bug("[ATA%02ld] Unit info: %s / %s / %s\n", unit->au_UnitNum, unit->au_Model, unit->au_SerialNumber, unit->au_FirmwareRev));
1486 common_DetectXferModes(unit);
1487 common_SetBestXferMode(unit);
1489 if (unit->au_Drive->id_General & 0x80)
1491 D(bug("[ATA%02ld] Device is removable.\n", unit->au_UnitNum));
1492 unit->au_Flags |= AF_Removable;
1495 unit->au_NumLoop = 4000000;
1497 unit->au_Capacity = unit->au_Drive->id_LBASectors;
1498 unit->au_Capacity48 = unit->au_Drive->id_LBA48Sectors;
1501 For drive capacities > 8.3GB assume maximal possible layout.
1502 It really doesn't matter here, as BIOS will not handle them in
1503 CHS way anyway :)
1504 i guess this just solves that weirdo div-by-zero crash, if anything else...
1506 if (unit->au_Drive->id_LBASectors > (63*255*1024))
1508 unit->au_Cylinders = unit->au_Drive->id_LBASectors / (255*63);
1509 unit->au_Heads = 255;
1510 unit->au_Sectors = 63;
1512 else
1514 unit->au_Cylinders = unit->au_Drive->id_OldLCylinders;
1515 unit->au_Heads = unit->au_Drive->id_OldLHeads;
1516 unit->au_Sectors = unit->au_Drive->id_OldLSectors;
1518 return 0;
1523 * ata read32 commands
1525 static ULONG ata_ReadSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1527 ata_CommandBlock acb =
1529 ATA_READ,
1533 block,
1534 count,
1535 buffer,
1536 count << unit->au_SectorShift,
1538 CM_PIORead,
1539 CT_LBA28
1541 register ULONG err;
1543 *act = 0;
1544 if (0 != (err = ata_exec_blk(unit, &acb)))
1545 return err;
1547 *act = count << unit->au_SectorShift;
1548 return 0;
1551 static ULONG ata_ReadMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1553 ata_CommandBlock acb =
1555 ATA_READ_MULTIPLE,
1557 unit->au_Drive->id_RWMultipleSize & 0xff,
1559 block,
1560 count,
1561 buffer,
1562 count << unit->au_SectorShift,
1564 CM_PIORead,
1565 CT_LBA28
1567 register ULONG err;
1569 *act = 0;
1570 if (0 != (err = ata_exec_blk(unit, &acb)))
1571 return err;
1573 *act = count << unit->au_SectorShift;
1574 return 0;
1577 static ULONG ata_ReadDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1579 register ULONG err;
1580 ata_CommandBlock acb =
1582 ATA_READ_DMA,
1586 block,
1587 count,
1588 buffer,
1589 count << unit->au_SectorShift,
1591 CM_DMARead,
1592 CT_LBA28
1595 *act = 0;
1596 if (0 != (err = ata_exec_blk(unit, &acb)))
1597 return err;
1599 *act = count << unit->au_SectorShift;
1600 return 0;
1605 * ata read64 commands
1607 static ULONG ata_ReadSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1609 ata_CommandBlock acb =
1611 ATA_READ64,
1615 block,
1616 count,
1617 buffer,
1618 count << unit->au_SectorShift,
1620 CM_PIORead,
1621 CT_LBA48
1623 register ULONG err = 0;
1625 *act = 0;
1626 if (0 != (err = ata_exec_blk(unit, &acb)))
1627 return err;
1629 *act = count << unit->au_SectorShift;
1630 return 0;
1633 static ULONG ata_ReadMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1635 ata_CommandBlock acb =
1637 ATA_READ_MULTIPLE64,
1639 unit->au_Drive->id_RWMultipleSize & 0xff,
1641 block,
1642 count,
1643 buffer,
1644 count << unit->au_SectorShift,
1646 CM_PIORead,
1647 CT_LBA48
1649 register ULONG err;
1651 *act = 0;
1652 if (0 != (err = ata_exec_blk(unit, &acb)))
1653 return err;
1655 *act = count << unit->au_SectorShift;
1656 return 0;
1659 static ULONG ata_ReadDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1661 ata_CommandBlock acb =
1663 ATA_READ_DMA64,
1667 block,
1668 count,
1669 buffer,
1670 count << unit->au_SectorShift,
1672 CM_DMARead,
1673 CT_LBA48
1675 register ULONG err;
1677 *act = 0;
1678 if (0 != (err = ata_exec_blk(unit, &acb)))
1679 return err;
1681 *act = count << unit->au_SectorShift;
1682 return 0;
1687 * ata write32 commands
1689 static ULONG ata_WriteSector32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1691 ata_CommandBlock acb =
1693 ATA_WRITE,
1697 block,
1698 count,
1699 buffer,
1700 count << unit->au_SectorShift,
1702 CM_PIOWrite,
1703 CT_LBA28
1705 register ULONG err;
1707 *act = 0;
1708 if (0 != (err = ata_exec_blk(unit, &acb)))
1709 return err;
1711 *act = count << unit->au_SectorShift;
1712 return 0;
1715 static ULONG ata_WriteMultiple32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1717 ata_CommandBlock acb =
1719 ATA_WRITE_MULTIPLE,
1721 unit->au_Drive->id_RWMultipleSize & 0xff,
1723 block,
1724 count,
1725 buffer,
1726 count << unit->au_SectorShift,
1728 CM_PIOWrite,
1729 CT_LBA28
1731 register ULONG err;
1733 *act = 0;
1734 if (0 != (err = ata_exec_blk(unit, &acb)))
1735 return err;
1737 *act = count << unit->au_SectorShift;
1738 return 0;
1741 static ULONG ata_WriteDMA32(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1743 ata_CommandBlock acb =
1745 ATA_WRITE_DMA,
1749 block,
1750 count,
1751 buffer,
1752 count << unit->au_SectorShift,
1754 CM_DMAWrite,
1755 CT_LBA28
1757 register ULONG err;
1759 *act = 0;
1760 if (0 != (err = ata_exec_blk(unit, &acb)))
1761 return err;
1763 *act = count << unit->au_SectorShift;
1764 return 0;
1769 * ata write64 commands
1771 static ULONG ata_WriteSector64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1773 ata_CommandBlock acb =
1775 ATA_WRITE64,
1779 block,
1780 count,
1781 buffer,
1782 count << unit->au_SectorShift,
1784 CM_PIOWrite,
1785 CT_LBA48
1787 register ULONG err;
1789 *act = 0;
1790 if (0 != (err = ata_exec_blk(unit, &acb)))
1791 return err;
1793 *act = count << unit->au_SectorShift;
1794 return 0;
1797 static ULONG ata_WriteMultiple64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1799 ata_CommandBlock acb =
1801 ATA_WRITE_MULTIPLE64,
1803 unit->au_Drive->id_RWMultipleSize & 0xff,
1805 block,
1806 count,
1807 buffer,
1808 count << unit->au_SectorShift,
1810 CM_PIOWrite,
1811 CT_LBA48
1813 register ULONG err;
1815 *act = 0;
1816 if (0 != (err = ata_exec_blk(unit, &acb)))
1817 return err;
1819 *act = count << unit->au_SectorShift;
1820 return 0;
1823 static ULONG ata_WriteDMA64(struct ata_Unit *unit, UQUAD block, ULONG count, APTR buffer, ULONG *act)
1825 ata_CommandBlock acb =
1827 ATA_WRITE_DMA64,
1831 block,
1832 count,
1833 buffer,
1834 count << unit->au_SectorShift,
1836 CM_DMAWrite,
1837 CT_LBA48
1839 register ULONG err;
1841 *act = 0;
1842 if (0 != (err = ata_exec_blk(unit, &acb)))
1843 return err;
1845 *act = count << unit->au_SectorShift;
1846 return 0;
1850 * ata miscellaneous commands
1852 static ULONG ata_Eject(struct ata_Unit *unit)
1854 ata_CommandBlock acb =
1856 ATA_MEDIA_EJECT,
1865 CM_NoData,
1866 CT_NoBlock
1869 return ata_exec_cmd(unit, &acb);
1873 * atapi commands
1875 int atapi_TestUnitOK(struct ata_Unit *unit)
1877 UBYTE cmd[6] = {
1880 UBYTE sense[4] = {
1883 struct SCSICmd sc = {
1887 sc.scsi_Command = (void*) &cmd;
1888 sc.scsi_CmdLength = sizeof(cmd);
1889 sc.scsi_SenseData = (void*)&sense;
1890 sc.scsi_SenseLength = sizeof(sense);
1891 sc.scsi_Flags = SCSIF_AUTOSENSE;
1893 unit->au_DirectSCSI(unit, &sc);
1894 unit->au_SenseKey = sense[2];
1895 D(bug("[ATA%02ld] Test Unit Ready sense: %02lx\n", unit->au_UnitNum, sense[2]));
1896 return sense[2];
1899 static ULONG atapi_Read(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1901 UBYTE cmd[] = {
1902 SCSI_READ10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
1904 struct SCSICmd sc = {
1908 sc.scsi_Command = (void*) &cmd;
1909 sc.scsi_CmdLength = sizeof(cmd);
1910 sc.scsi_Data = buffer;
1911 sc.scsi_Length = count << unit->au_SectorShift;
1912 sc.scsi_Flags = SCSIF_READ;
1914 return unit->au_DirectSCSI(unit, &sc);
1917 static ULONG atapi_Write(struct ata_Unit *unit, ULONG block, ULONG count, APTR buffer, ULONG *act)
1919 UBYTE cmd[] = {
1920 SCSI_WRITE10, 0, block>>24, block>>16, block>>8, block, 0, count>>8, count, 0
1922 struct SCSICmd sc = {
1926 sc.scsi_Command = (void*) &cmd;
1927 sc.scsi_CmdLength = sizeof(cmd);
1928 sc.scsi_Data = buffer;
1929 sc.scsi_Length = count << unit->au_SectorShift;
1930 sc.scsi_Flags = SCSIF_WRITE;
1932 return unit->au_DirectSCSI(unit, &sc);
1935 static ULONG atapi_Eject(struct ata_Unit *unit)
1937 struct atapi_StartStop cmd = {
1938 command: SCSI_STARTSTOP,
1939 immediate: 1,
1940 flags: ATAPI_SS_EJECT,
1943 struct SCSICmd sc = {
1947 sc.scsi_Command = (void*) &cmd;
1948 sc.scsi_CmdLength = sizeof(cmd);
1949 sc.scsi_Flags = SCSIF_READ;
1951 return unit->au_DirectSCSI(unit, &sc);
1954 ULONG atapi_RequestSense(struct ata_Unit* unit, UBYTE* sense, ULONG senselen)
1956 UBYTE cmd[] = {
1957 3, 0, 0, 0, senselen & 0xfe, 0
1959 struct SCSICmd sc = {
1963 if ((senselen == 0) || (sense == 0))
1965 return 0;
1967 sc.scsi_Data = (void*)sense;
1968 sc.scsi_Length = senselen & 0xfe;
1969 sc.scsi_Command = (void*)&cmd;
1970 sc.scsi_CmdLength = 6;
1971 sc.scsi_Flags = SCSIF_READ;
1973 unit->au_DirectSCSI(unit, &sc);
1975 int t,p,q;
1976 for (q=0; q<((senselen+15)>>4); q++)
1978 p = 16;
1979 if ((senselen - (q<<4)) < p)
1980 p = (senselen - (q<<4));
1982 bug("[SENSE] %02lx:", q<<4);
1983 for (t=0; t<p; t++)
1984 bug("%02lx ", sense[(q<<4) + t]);
1985 bug("\n");
1989 D(bug("[SENSE] sensed data: %lx %lx %lx\n", sense[2]&0xf, sense[12], sense[13]));
1990 return ((sense[2]&0xf)<<16) | (sense[12]<<8) | (sense[13]);
1995 * --------------------------------------------------------------
1996 * - here ends the code that makes any sense. rest to be removed -
1997 * --------------------------------------------------------------
2001 void ata_usleep(struct timerequest *tr, ULONG usec)
2003 tr->tr_node.io_Command = TR_ADDREQUEST;
2004 tr->tr_time.tv_micro = usec % 1000000;
2005 tr->tr_time.tv_secs = usec / 1000000;
2007 DoIO((struct IORequest *)tr);
2011 Device scan routines - TO BE REPLACED
2013 void ata_ResetBus(struct timerequest *tr, struct ata_Bus *bus)
2015 ULONG port = bus->ab_Port;
2016 ULONG alt = bus->ab_Alt;
2017 int cnt;
2019 /* Exclusive use of ATA registers */
2020 ObtainSemaphore(&bus->ab_Lock);
2022 /* Disable IRQ */
2023 ata_out(0x0a, ata_AltControl, alt);
2024 /* Issue software reset */
2025 ata_out(0x0e, ata_AltControl, alt);
2026 /* wait a while */
2027 ata_usleep(tr, 400);
2028 /* Clear reset signal */
2029 ata_out(0x0a, ata_AltControl, alt);
2030 /* And wait again */
2031 ata_usleep(tr, 400);
2032 /* wait for dev0 to come online. Limited delay up to 30µs */
2033 if (bus->ab_Dev[0] != DEV_NONE)
2035 cnt=1000; // 1000ms delay for slowest devices to reply.
2036 while (cnt--)
2038 if ((ata_in(ata_Status, port) & ATAF_BUSY) == 0)
2039 break;
2040 ata_usleep(tr, 1000);
2044 /* wait for dev1 to come online. Limited delay up to 30µs */
2045 if (bus->ab_Dev[1] != DEV_NONE)
2047 ata_out(0xb0, ata_DevHead, port);
2048 ata_usleep(tr, 100);
2050 cnt=1000;
2051 while (cnt--)
2053 if ((ata_in(ata_Status, port) & ATAF_BUSY) == 0)
2054 break;
2056 ata_usleep(tr, 1000);
2060 ata_out(0x08, ata_AltControl, alt);
2061 ReleaseSemaphore(&bus->ab_Lock);
2065 * same here
2067 void ata_ScanBus(struct ata_Bus *bus)
2069 ULONG port = bus->ab_Port;
2070 UBYTE tmp1, tmp2;
2072 struct MsgPort *p = CreateMsgPort();
2073 struct timerequest *tr = (struct timerequest *)CreateIORequest((struct MsgPort *)p,
2074 sizeof(struct timerequest));
2075 OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0);
2077 /* Exclusive use of ATA registers */
2078 ObtainSemaphore(&bus->ab_Lock);
2080 bus->ab_Dev[0] = DEV_NONE;
2081 bus->ab_Dev[1] = DEV_NONE;
2083 /* Disable IDE IRQ */
2084 ata_out(0x0a, ata_AltControl, bus->ab_Alt);
2086 /* Select device 0 */
2087 ata_out(0xa0, ata_DevHead, port);
2088 ata_usleep(tr, 100);
2090 /* Write some pattern to registers */
2091 ata_out(0x55, ata_Count, port);
2092 ata_out(0xaa, ata_LBALow, port);
2093 ata_out(0xaa, ata_Count, port);
2094 ata_out(0x55, ata_LBALow, port);
2095 ata_out(0x55, ata_Count, port);
2096 ata_out(0xaa, ata_LBALow, port);
2098 tmp1 = ata_in(ata_Count, port);
2099 tmp2 = ata_in(ata_LBALow, port);
2101 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2102 bus->ab_Dev[0] = DEV_UNKNOWN;
2104 /* Select device 1 */
2105 ata_out(0xb0, ata_DevHead, port);
2106 ata_usleep(tr, 100);
2108 /* Write some pattern to registers */
2109 ata_out(0x55, ata_Count, port);
2110 ata_out(0xaa, ata_LBALow, port);
2111 ata_out(0xaa, ata_Count, port);
2112 ata_out(0x55, ata_LBALow, port);
2113 ata_out(0x55, ata_Count, port);
2114 ata_out(0xaa, ata_LBALow, port);
2116 tmp1 = ata_in(ata_Count, port);
2117 tmp2 = ata_in(ata_LBALow, port);
2119 if ((tmp1 == 0x55) && (tmp2 == 0xaa))
2120 bus->ab_Dev[1] = DEV_UNKNOWN;
2123 * According to ATA specs it is quite possible, that the dev0 will respond
2124 * for both self and dev1. Similar, when only dev1 is available, it may as
2125 * well respond as dev0. Do more precise test now.
2127 ata_out(0xa0, ata_DevHead, port);
2128 ata_usleep(tr, 100);
2129 ata_ResetBus(tr, bus);
2131 /* check device 0 */
2132 ata_out(0xa0, ata_DevHead, port);
2133 ata_usleep(tr, 100);
2135 /* Check basic signature. All live devices should provide it */
2136 tmp1 = ata_in(ata_Count, port);
2137 tmp2 = ata_in(ata_LBALow, port);
2138 D(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2140 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2142 /* Ok, ATA/ATAPI device. Get detailed signature */
2143 D(bug("[ATA ] Found an ATA[PI] Device[0]. Attempting to detect specific subtype\n"));
2145 bus->ab_Dev[0] = DEV_UNKNOWN;
2146 tmp1 = ata_in(ata_LBAMid, port);
2147 tmp2 = ata_in(ata_LBAHigh, port);
2149 if ((tmp1 == 0x14) && (tmp2 == 0xeb))
2151 bus->ab_Dev[0] = DEV_ATAPI;
2153 else if ((tmp1 == 0) && (tmp2 == 0) && ((ata_in(ata_Status, port) & 0xfe) != 0))
2155 bus->ab_Dev[0] = DEV_ATA;
2157 else if ((tmp1 == 0x3c) && (tmp2 == 0xc3))
2159 bus->ab_Dev[0] = DEV_SATA;
2161 else if ((tmp1 == 0x69) && (tmp2 == 0x96))
2163 bus->ab_Dev[0] = DEV_SATAPI;
2167 /* check device 1 */
2168 ata_out(0xb0, ata_DevHead, port);
2169 ata_usleep(tr, 100);
2171 /* Check basic signature. All live devices should provide it */
2172 tmp1 = ata_in(ata_Count, port);
2173 tmp2 = ata_in(ata_LBALow, port);
2174 D(bug("[ATA ] Checking Count / LBA against expected values (%d:%d)\n", tmp1, tmp2));
2176 if ((tmp1 == 0x01) && (tmp2 == 0x01))
2178 D(bug("[ATA ] Found an ATA[PI] Device[1]. Attempting to detect specific subtype\n"));
2179 /* Ok, ATA/ATAPI device. Get detailed signature */
2180 bus->ab_Dev[1] = DEV_UNKNOWN;
2181 tmp1 = ata_in(ata_LBAMid, port);
2182 tmp2 = ata_in(ata_LBAHigh, port);
2184 if ((tmp1 == 0x14) && (tmp2 == 0xeb))
2186 bus->ab_Dev[1] = DEV_ATAPI;
2188 else if ((tmp1 == 0) && (tmp2 == 0) && ((ata_in(ata_Status, port) & 0xfe) != 0))
2190 bus->ab_Dev[1] = DEV_ATA;
2192 else if ((tmp1 == 0x3c) && (tmp2 == 0xc3))
2194 bus->ab_Dev[0] = DEV_SATA;
2196 else if ((tmp1 == 0x69) && (tmp2 == 0x96))
2198 bus->ab_Dev[0] = DEV_SATAPI;
2203 * restore IRQ
2205 ata_out(0x08, ata_AltControl, bus->ab_Alt);
2206 ReleaseSemaphore(&bus->ab_Lock);
2208 CloseDevice((struct IORequest *)tr);
2209 DeleteIORequest((struct IORequest *)tr);
2210 DeleteMsgPort(p);
2214 * not really sure what this is meant to be - TO BE REPLACED
2216 static const ULONG ErrorMap[] = {
2217 CDERR_NotSpecified,
2218 CDERR_NoSecHdr,
2219 CDERR_NoDisk,
2220 CDERR_NoSecHdr,
2221 CDERR_NoSecHdr,
2222 CDERR_NOCMD,
2223 CDERR_NoDisk,
2224 CDERR_WriteProt,
2225 CDERR_NotSpecified,
2226 CDERR_NotSpecified,
2227 CDERR_NotSpecified,
2228 CDERR_ABORTED,
2229 CDERR_NotSpecified,
2230 CDERR_NotSpecified,
2231 CDERR_NoSecHdr,
2232 CDERR_NotSpecified,
2235 static ULONG atapi_ErrCmd()
2237 return CDERR_ABORTED;
2240 static ULONG atapi_EndCmd(struct ata_Unit *unit)
2242 unit->au_Flags |= AF_Used;
2243 UBYTE status;
2246 * read alternate status register (per specs)
2248 status = ata_in(ata_AltStatus, unit->au_Bus->ab_Alt);
2249 D(bug("[ATAPI] Alternate status: %lx\n", status));
2251 status = ata_in(atapi_Status, unit->au_Bus->ab_Port);
2253 D(bug("[ATAPI] Command complete. Status: %lx\n", status));
2255 if (!(status & ATAPIF_CHECK))
2257 return 0;
2259 else
2261 status = ata_in(atapi_Error, unit->au_Bus->ab_Port);
2262 D(bug("[ATAPI] Error code %lx\n", status >> 4));
2263 return ErrorMap[status >> 4];
2268 * vim: ts=4 et sw=4 fdm=marker fmr={,}