fix some flag usage in mmakefiles. provide suitable names for amiga hardware devices...
[AROS.git] / rom / devs / ata / ata_busclass.c
blob3257d3799de09532352bb0fcde10750c8c6b8f8f
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
8 #include <proto/exec.h>
10 /* We want all other bases obtained from our base */
11 #define __NOLIBBASE__
13 #include <proto/oop.h>
14 #include <proto/utility.h>
16 #include <hidd/storage.h>
17 #include <hidd/ata.h>
18 #include <oop/oop.h>
19 #include <utility/tagitem.h>
21 #include "ata.h"
22 #include "ata_bus.h"
24 #define DIRQ(x)
26 static void Hidd_ATABus_HandleIRQ(UBYTE status, struct ata_Bus *bus)
28 struct ata_Unit *unit = bus->ab_SelectedUnit;
31 * don't waste your time on checking other devices.
32 * pass irq ONLY if task is expecting one;
34 if (unit && bus->ab_HandleIRQ)
36 /* ok, we have a routine to handle any form of transmission etc. */
37 DIRQ(bug("[ATA%02d] IRQ: Calling dedicated handler 0x%p... \n",
38 unit->au_UnitNum, bus->ab_HandleIRQ));
39 bus->ab_HandleIRQ(unit, status);
41 return;
44 DIRQ({
46 * if we got *here* then device is most likely not expected to have an irq.
48 bug("[ATA%02d] Spurious IRQ\n", unit ? unit->au_UnitNum : -1);
50 if (0 == (ATAF_BUSY & status))
52 bug("[ATA ] STATUS: %02lx\n" , status);
53 bug("[ATA ] ALT STATUS: %02lx\n" , PIO_InAlt(bus, ata_AltStatus));
54 bug("[ATA ] ERROR: %02lx\n" , PIO_In(bus, ata_Error));
55 bug("[ATA ] IRQ: REASON: %02lx\n", PIO_In(bus, atapi_Reason));
57 });
60 static AROS_INTH1(ataBus_Reset, struct ata_Bus *, bus)
62 AROS_INTFUNC_INIT
64 struct ataBase *ATABase = bus->ab_Base;
65 OOP_Object *obj = (void *)bus - ATABase->busClass->InstOffset;
67 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
69 HIDD_ATABus_Shutdown(obj);
71 return FALSE;
73 AROS_INTFUNC_EXIT
76 /*****************************************************************************************
78 NAME
79 --background--
81 LOCATION
82 CLID_Hidd_ATABus
84 NOTES
85 This class serves as a base class for implementing IDE (ATA) bus drivers.
86 One particularity of this class is that IDE bus is very speed-critical.
87 At the other hand, the driver implements very lowlevel operations which
88 are called quite often. OOP_DoMethod() call is not fast enough, and in
89 order to circumvent this limitation, additionally to normal OOP API
90 IDE bus drivers offer two additional non-standard interfaces. Internally
91 they are implemented as library-alike function table plus driver-specific
92 data. For the purpose of some performance optimizations the function
93 table is private to ata.device and managed entirely by the base class.
94 Driver classes have access only to data portion.
96 These interfaces are documented below.
98 *****************************************************************************************/
99 /*****************************************************************************************
101 NAME
102 --PIO interface--
104 LOCATION
105 CLID_Hidd_ATABus
107 NOTES
108 PIO interface is responsible for accessing I/O registers on the IDE
109 bus, as well as performing PIO-mode 16- and 32-bit data transfers.
110 This interface is mandatory and must be implemented by the driver,
111 however some functions are optional. They can be either omitted
112 entirely from the function table, or set to NULL pointers.
114 Control functions table for the interface consists of the following
115 functions (listed in their order in the array):
117 VOID ata_out(void *obj, UBYTE val, UWORD offset)
118 - Write byte into primary register bank with the given offset.
120 UBYTE ata_in(void *obj, UWORD offset)
121 - Read byte from primary register bank with the given offset.
123 VOID ata_out_alt(void *obj, UBYTE val, UWORD offset)
124 - Write byte into alternate register bank with the given offset.
125 This function is optional.
127 UBYTE ata_in_alt(void *obj, UWORD offset)
128 - Read byte from alternate register bank with the given offset.
129 This function is optional.
131 Transfer functions table for the interface consists of the following
132 functions (listed in their order in the array):
134 VOID ata_outsw(void *obj, APTR address, ULONG count)
135 - Perform 16-bit PIO data write operation from the given memory
136 region of the given size.
138 VOID ata_insw(void *obj, APTR address, ULONG count)
139 - Perform 16-bit PIO data read operation into the given memory
140 region of the given size.
142 VOID ata_outsl(void *obj, APTR address, ULONG count)
143 - Perform 32-bit PIO data write operation from the given memory
144 region of the given size. This function is optional.
146 UBYTE ata_insl(void *obj, APTR address, ULONG count)
147 - Perform 32-bit PIO data read operation into the given memory
148 region of the given size. This function is optional.
150 *****************************************************************************************/
151 /*****************************************************************************************
153 NAME
154 --DMA interface--
156 LOCATION
157 CLID_Hidd_ATABus
159 NOTES
160 DMA interface is optional, and is needed in order to support DMA data
161 transfers.
163 Function table for the interface consists of the following functions:
165 BOOL dma_Setup(void *obj, APTR buffer, IPTR size, BOOL read)
166 - Prepare the controller to DMA data transfer. The last argument is
167 TRUE for read operation and FALSE for write. The function should
168 return TRUE for success or FALSE for failure.
170 VOID dma_Start(void *obj)
171 - Start DMA transfer.
173 VOID dma_End(void *obj, APTR buffer, IPTR size, BOOL read)
174 - End DMA transfer and perform post-transfer cleanup of the given region.
176 ULONG dma_Result(void *obj)
177 - Get resulting status of the operation. The function should return 0
178 for successful completion or error code to be passed up to ata.device
179 caller in io_Result field of the IORequest.
181 *****************************************************************************************/
182 /*****************************************************************************************
184 NAME
185 aoHidd_ATABus_Use80Wire
187 SYNOPSIS
188 [..G], BOOL
190 LOCATION
191 CLID_Hidd_ATABus
193 FUNCTION
194 Tells whether the bus currently uses 80-conductor cable.
196 NOTES
197 This attribute actually makes difference only for DMA modes. If
198 your bus driver returns FALSE, ata.device will not use modes
199 higher than UDMA2 on the bus.
201 EXAMPLE
203 BUGS
205 SEE ALSO
207 INTERNALS
209 *****************************************************************************************/
210 /*****************************************************************************************
212 NAME
213 aoHidd_ATABus_Use32Bit
215 SYNOPSIS
216 [.SG], BOOL
218 LOCATION
219 CLID_Hidd_ATABus
221 FUNCTION
222 When queried, tells whether the bus supports 32-bit PIO data transfers.
223 When set, enables or disables 32-bit mode for PIO data transfers.
225 NOTES
227 EXAMPLE
229 BUGS
231 SEE ALSO
233 INTERNALS
235 *****************************************************************************************/
236 /*****************************************************************************************
238 NAME
239 aoHidd_ATABus_UseDMA
241 SYNOPSIS
242 [..G], BOOL
244 LOCATION
245 CLID_Hidd_ATABus
247 FUNCTION
248 Tells whether the bus supports DMA transfers.
250 NOTES
252 EXAMPLE
254 BUGS
256 SEE ALSO
258 INTERNALS
259 Default implementation in base class returns value depending on whether
260 the subclass provided DMA interface function table during object creation.
262 *****************************************************************************************/
263 /*****************************************************************************************
265 NAME
266 aoHidd_ATABus_PIODataSize
268 SYNOPSIS
269 [I..], BOOL
271 LOCATION
272 CLID_Hidd_ATABus
274 FUNCTION
275 Specifies size of PIO interface data structure.
277 NOTES
279 EXAMPLE
281 BUGS
283 SEE ALSO
285 INTERNALS
287 *****************************************************************************************/
288 /*****************************************************************************************
290 NAME
291 aoHidd_ATABus_DMADataSize
293 SYNOPSIS
294 [I..], BOOL
296 LOCATION
297 CLID_Hidd_ATABus
299 FUNCTION
300 Specifies size of DMA interface data structure.
302 NOTES
304 EXAMPLE
306 BUGS
308 SEE ALSO
310 INTERNALS
312 *****************************************************************************************/
313 /*****************************************************************************************
315 NAME
316 aoHidd_ATABus_BusVectors
318 SYNOPSIS
319 [I..], APTR *
321 LOCATION
322 CLID_Hidd_ATABus
324 FUNCTION
325 Specifies control functions table for building PIO interface object.
326 The function table is an array of function pointers terminated
327 by -1 value. The terminator must be present for purpose of
328 binary compatibility with future extensions.
330 NOTES
331 This function table is mandatory to be implemented by the driver.
333 EXAMPLE
335 BUGS
337 SEE ALSO
339 INTERNALS
341 *****************************************************************************************/
342 /*****************************************************************************************
344 NAME
345 aoHidd_ATABus_PIOVectors
347 SYNOPSIS
348 [I..], APTR *
350 LOCATION
351 CLID_Hidd_ATABus
353 FUNCTION
354 Specifies transfers function table for building PIO interface object.
355 The function table is an array of function pointers terminated
356 by -1 value. The terminator must be present for purpose of
357 binary compatibility with future extensions.
359 NOTES
360 This function table is mandatory to be implemented by the driver.
362 EXAMPLE
364 BUGS
366 SEE ALSO
368 INTERNALS
370 *****************************************************************************************/
371 /*****************************************************************************************
373 NAME
374 aoHidd_ATABus_DMAVectors
376 SYNOPSIS
377 [I..], APTR *
379 LOCATION
380 CLID_Hidd_ATABus
382 FUNCTION
383 Specifies function table for building DMA interface object. If not supplied,
384 the bus is considered not DMA-capable.
386 NOTES
388 EXAMPLE
390 BUGS
392 SEE ALSO
393 aoHidd_ATABus_PIOVectors
395 INTERNALS
397 *****************************************************************************************/
398 /*****************************************************************************************
400 NAME
401 aoHidd_ATABus_IRQHandler
403 SYNOPSIS
404 [.S.], APTR
406 LOCATION
407 CLID_Hidd_ATABus
409 FUNCTION
410 Specifies IRQ handler function to be called when bus interrupt arrives.
411 The function should be called using "C" calling convention and has the
412 following prototype:
414 void ata_HandleIRQ(UBYTE status, APTR userdata);
416 Your driver should pass the following arguments to this function:
417 status - value read from ATA main status register.
418 userdata - value of aoHidd_ATABus_IRQData attribute.
420 NOTES
421 Reading the drive status register is part of the interrupt acknowledge
422 process, and therefore has to be done by the driver.
424 It is driver's job to check whether the interrupt really belongs to
425 the IDE bus. A generic way to do this is to test ATAF_BUSY bit of
426 the status register for being zero. However, this may not work
427 reliably with IRQ sharing, so advanced IDE controllers may offer
428 different, better way to do this.
430 EXAMPLE
432 BUGS
434 SEE ALSO
435 aoHidd_ATABus_IRQData
437 INTERNALS
439 *****************************************************************************************/
440 /*****************************************************************************************
442 NAME
443 aoHidd_ATABus_IRQData
445 SYNOPSIS
446 [.S.], APTR
448 LOCATION
449 CLID_Hidd_ATABus
451 FUNCTION
452 Caller's private data to be supplied to IRQ handler function.
454 NOTES
456 EXAMPLE
458 BUGS
460 SEE ALSO
461 aoHidd_ATABus_IRQData
463 INTERNALS
465 *****************************************************************************************/
466 /*****************************************************************************************
468 NAME
469 aoHidd_ATABus_UseIOAlt
471 SYNOPSIS
472 [..G], BOOL
474 LOCATION
475 CLID_Hidd_ATABus
477 FUNCTION
478 Tells whether the bus supports alternate registers bank
479 (ata_AltControl and ata_AltStatus).
481 NOTES
483 EXAMPLE
485 BUGS
487 SEE ALSO
489 INTERNALS
490 Default implementation in base class returns value depending on whether
491 the subclass provided respective I/O functions in bus interface vector
492 table during object creation.
494 *****************************************************************************************/
495 /*****************************************************************************************
497 NAME
498 aoHidd_ATABus_KeepEmpty
500 SYNOPSIS
501 [I..], BOOL
503 LOCATION
504 CLID_Hidd_ATABus
506 FUNCTION
507 If this attribute is set to FALSE during object creation, the object
508 will be destroyed if no devices are detected on the bus.
510 This can be useful for optional buses like legacy ISA controllers,
511 which have no other way to detect their presence.
513 NOTES
515 EXAMPLE
517 BUGS
519 SEE ALSO
521 INTERNALS
523 *****************************************************************************************/
524 /*****************************************************************************************
526 NAME
527 aoHidd_ATABus_Master
529 SYNOPSIS
530 [..G], OOP_Object *
532 LOCATION
533 CLID_Hidd_ATABus
535 FUNCTION
536 Returns a pointer to OOP object of private unit class, representing
537 a master drive on the bus, or NULL if there's no master device.
539 NOTES
541 EXAMPLE
543 BUGS
545 SEE ALSO
546 aoHidd_ATABus_Slave
548 INTERNALS
550 *****************************************************************************************/
551 /*****************************************************************************************
553 NAME
554 aoHidd_ATABus_Slave
556 SYNOPSIS
557 [..G], OOP_Object *
559 LOCATION
560 CLID_Hidd_ATABus
562 FUNCTION
563 Returns a pointer to OOP object of private unit class, representing
564 a slave drive on the bus, or NULL if there's no master device.
566 NOTES
568 EXAMPLE
570 BUGS
572 SEE ALSO
573 aoHidd_ATABus_Master
575 INTERNALS
577 *****************************************************************************************/
578 /*****************************************************************************************
580 NAME
581 aoHidd_ATABus_CanSetXferMode
583 SYNOPSIS
584 [..G], BOOL
586 LOCATION
587 CLID_Hidd_ATABus
589 FUNCTION
590 Tells whether the bus driver implements moHidd_ATABus_SetXferMode method.
592 NOTES
594 EXAMPLE
596 BUGS
597 Current version of ata.device does not use this attribute, and it is
598 considered reserved.
600 SEE ALSO
601 moHidd_ATABus_SetXferMode
603 INTERNALS
605 *****************************************************************************************/
607 OOP_Object *ATABus__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
609 struct ataBase *ATABase = cl->UserData;
610 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
611 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, &msg->mID);
612 if (o)
614 struct ata_Bus *data = OOP_INST_DATA(cl, o);
615 struct TagItem *tstate = msg->attrList;
616 struct TagItem *tag;
618 D(bug("[ATA:Bus] %s: instance @ 0x%p\n", __PRETTY_FUNCTION__, o));
620 /* Defaults */
621 data->keepEmpty = TRUE;
623 while ((tag = NextTagItem(&tstate)))
625 ULONG idx;
627 Hidd_ATABus_Switch(tag->ti_Tag, idx)
629 case aoHidd_ATABus_PIODataSize:
630 data->pioDataSize = tag->ti_Data;
631 break;
633 case aoHidd_ATABus_DMADataSize:
634 data->dmaDataSize = tag->ti_Data;
635 break;
637 case aoHidd_ATABus_BusVectors:
638 data->busVectors = (struct ATA_BusInterface *)tag->ti_Data;
639 break;
641 case aoHidd_ATABus_PIOVectors:
642 data->pioVectors = (struct ATA_PIOInterface *)tag->ti_Data;
643 break;
645 case aoHidd_ATABus_DMAVectors:
646 data->dmaVectors = (APTR *)tag->ti_Data;
647 break;
649 case aoHidd_ATABus_KeepEmpty:
650 data->keepEmpty = tag->ti_Data;
651 break;
655 /* Cache device base pointer. Useful. */
656 data->ab_Base = ATABase;
658 /* Install reset callback */
659 data->ab_ResetInt.is_Node.ln_Name = ATABase->ata_Device.dd_Library.lib_Node.ln_Name;
660 data->ab_ResetInt.is_Code = (VOID_FUNC)ataBus_Reset;
661 data->ab_ResetInt.is_Data = data;
662 AddResetCallback(&data->ab_ResetInt);
664 return o;
667 void ATABus__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
669 struct ata_Bus *data = OOP_INST_DATA(cl, o);
671 RemResetCallback(&data->ab_ResetInt);
673 if (data->dmaInterface)
675 void *ptr = data->dmaInterface - sizeof(struct ATA_DMAInterface);
677 FreeMem(ptr, sizeof(struct ATA_DMAInterface) + data->dmaDataSize);
679 if (data->pioInterface)
681 void *ptr = data->pioInterface - sizeof(struct ATA_BusInterface);
683 FreeMem(ptr, sizeof(struct ATA_BusInterface) + data->pioDataSize);
686 OOP_DoSuperMethod(cl, o, msg);
690 * Here we take into account that the table can be either
691 * terminated early, or have NULL entries.
693 #define HAVE_VECTOR(x) (x && (x != (APTR)-1))
695 void ATABus__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
697 struct ataBase *ATABase = cl->UserData;
698 struct ata_Bus *data = OOP_INST_DATA(cl, o);
699 ULONG idx;
701 Hidd_Bus_Switch (msg->attrID, idx)
703 case aoHidd_Bus_MaxUnits:
704 *msg->storage = MAX_BUSUNITS;
705 return;
708 Hidd_ATABus_Switch (msg->attrID, idx)
710 case aoHidd_ATABus_Use80Wire:
711 *msg->storage = FALSE;
712 return;
714 case aoHidd_ATABus_Use32Bit:
715 *msg->storage = (HAVE_VECTOR(data->pioVectors->ata_outsl) &&
716 HAVE_VECTOR(data->pioVectors->ata_insl)) ?
717 TRUE : FALSE;
718 return;
720 case aoHidd_ATABus_UseDMA:
721 *msg->storage = data->dmaVectors ? TRUE : FALSE;
722 return;
724 case aoHidd_ATABus_UseIOAlt:
725 *msg->storage = (HAVE_VECTOR(data->busVectors->ata_out_alt) &&
726 HAVE_VECTOR(data->busVectors->ata_in_alt)) ?
727 TRUE : FALSE;
728 return;
730 case aoHidd_ATABus_CanSetXferMode:
731 *msg->storage = FALSE;
732 return;
735 OOP_DoSuperMethod(cl, o, &msg->mID);
738 void ATABus__Hidd_StorageBus__EnumUnits(OOP_Class *cl, OOP_Object *o, struct pHidd_StorageBus_EnumUnits *msg)
740 struct ata_Bus *data = OOP_INST_DATA(cl, o);
741 BOOL stop = FALSE;
743 D(bug ("[ATA:Bus] Hidd_StorageBus__EnumUnits()\n");)
745 if (data->ab_Units[0])
746 stop = CALLHOOKPKT(msg->callback, data->ab_Units[0], msg->hookMsg);
747 if ((!stop) && (data->ab_Units[1]))
748 stop = CALLHOOKPKT(msg->callback, data->ab_Units[1], msg->hookMsg);
751 /* Default ata_out_alt does nothing */
752 static void default_out_alt(void *obj, UBYTE val, UWORD offset)
757 /* Default ata_in_alt wraps AltStatus to status */
758 static UBYTE default_in_alt(void *obj, UWORD offset)
760 struct ATA_BusInterface *vec = obj - sizeof(struct ATA_BusInterface);
762 return vec->ata_in(obj, ata_Status);
765 static void CopyVectors(APTR *dest, APTR *src, unsigned int num)
767 unsigned int i;
769 for (i = 0; i < num; i++)
771 if (src[i] == (APTR *)-1)
772 return;
773 if (src[i])
774 dest[i] = src[i];
778 /*****************************************************************************************
780 NAME
781 moHidd_ATABus_GetPIOInterface
783 SYNOPSIS
784 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_GetPIOInterface *Msg);
786 APTR HIDD_ATABus_GetPIOInterface(void);
788 LOCATION
789 CLID_Hidd_ATABus
791 FUNCTION
792 Instantiates encapsulated PIO interface object and returns its
793 pointer.
795 INPUTS
796 None
798 RESULT
799 A pointer to opaque PIO interface object or NULL in case of failure.
801 NOTES
802 This method should be overloaded by driver subclasses in order to
803 initialize data portion of the interface object.
805 EXAMPLE
807 BUGS
809 SEE ALSO
810 moHidd_ATABus_GetDMAInterface
812 INTERNALS
813 Interface objects contain not only driver-specific data, but also
814 a private vector table. Because of this you cannot just AllocMem()
815 the necessary structure in your driver. Always call OOP_DoSuperMethod()
816 in order for the base class to instantiate the interface correctly.
818 *****************************************************************************************/
820 APTR ATABus__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
822 struct ata_Bus *data = OOP_INST_DATA(cl, o);
823 struct ATA_BusInterface *vec;
825 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
827 vec = AllocMem(sizeof(struct ATA_BusInterface) + data->pioDataSize,
828 MEMF_PUBLIC|MEMF_CLEAR);
829 if (vec)
831 /* Some default vectors for simplicity */
832 vec->ata_out_alt = default_out_alt;
833 vec->ata_in_alt = default_in_alt;
835 CopyVectors((APTR *)vec, (APTR *)data->busVectors,
836 sizeof(struct ATA_BusInterface) / sizeof(APTR));
838 data->pioInterface = &vec[1];
839 return data->pioInterface;
842 return NULL;
845 /*****************************************************************************************
847 NAME
848 moHidd_ATABus_GetDMAInterface
850 SYNOPSIS
851 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_GetDMAInterface *Msg);
853 APTR HIDD_ATABus_GetDMAInterface(void);
855 LOCATION
856 CLID_Hidd_ATABus
858 FUNCTION
859 Instantiates encapsulated DMA interface object and returns its
860 pointer.
862 INPUTS
863 None
865 RESULT
866 A pointer to opaque DMA interface object or NULL upon failure or
867 if DMA is not supported by this bus.
869 NOTES
870 This method should be overloaded by driver subclasses in order to
871 initialize data portion of the interface object.
873 EXAMPLE
875 BUGS
877 SEE ALSO
878 moHidd_ATABus_GetPIOInterface
880 INTERNALS
881 Interface objects contain not only driver-specific data, but also
882 a private vector table. Because of this you cannot just AllocMem()
883 the necessary structure in your driver. Always call OOP_DoSuperMethod()
884 in order for the base class to instantiate the interface correctly.
886 *****************************************************************************************/
888 APTR ATABus__Hidd_ATABus__GetDMAInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
890 struct ata_Bus *data = OOP_INST_DATA(cl, o);
891 struct ATA_DMAInterface *vec;
893 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
895 if (!data->dmaVectors)
896 return NULL;
898 vec = AllocMem(sizeof(struct ATA_DMAInterface) + data->dmaDataSize,
899 MEMF_PUBLIC|MEMF_CLEAR);
900 if (vec)
902 CopyVectors((APTR *)vec, data->dmaVectors,
903 sizeof(struct ATA_DMAInterface) / sizeof(APTR));
905 data->dmaInterface = &vec[1];
906 return data->dmaInterface;
909 return NULL;
912 /*****************************************************************************************
914 NAME
915 moHidd_ATABus_SetXferMode
917 SYNOPSIS
918 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_SetXferMode *Msg);
920 APTR HIDD_ATABus_SetXferMode(UBYTE unit, ata_XferMode mode);
922 LOCATION
923 CLID_Hidd_ATABus
925 FUNCTION
926 Sets the desired transfer mode for the given drive on the bus controller.
928 INPUTS
929 unit - drive number (0 for master and 1 for slave)
930 mode - Mode number (see hidd/ata.h)
932 RESULT
933 TRUE if successful or FALSE if the desired mode is not supported
934 by the hardware.
936 NOTES
937 The default implementation is provided for drivers not supporting
938 DMA and always returns FALSE if the caller attempts to set any of
939 DMA modes.
941 EXAMPLE
943 BUGS
944 Current version of ata.device does not use this method, and it is
945 considered reserved.
947 SEE ALSO
948 aoHidd_ATABus_CanSetXferMode
950 INTERNALS
952 *****************************************************************************************/
954 BOOL ATABus__Hidd_ATABus__SetXferMode(OOP_Class *cl, OOP_Object *o, struct pHidd_ATABus_SetXferMode *msg)
956 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
958 if ((msg->mode >= AB_XFER_MDMA0) && (msg->mode <= AB_XFER_UDMA6))
960 /* DMA is not supported, we cannot set DMA modes */
961 return FALSE;
964 return TRUE;
967 /*****************************************************************************************
969 NAME
970 moHidd_ATABus_Shutdown
972 SYNOPSIS
973 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_Shutdown *Msg);
975 APTR HIDD_ATABus_Shutdown(void);
977 LOCATION
978 CLID_Hidd_ATABus
980 FUNCTION
981 Instantly shutdown all activity on the bus.
983 INPUTS
984 None
986 RESULT
987 None
989 NOTES
990 This method is called by ata.device during system reset handler execution.
992 EXAMPLE
994 BUGS
996 SEE ALSO
998 INTERNALS
999 Default implementation disables interrupt using AltControl register.
1001 *****************************************************************************************/
1003 void ATABus__Hidd_ATABus__Shutdown(OOP_Class *cl, OOP_Object *o, OOP_Msg *msg)
1005 struct ata_Bus *data = OOP_INST_DATA(cl, o);
1007 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
1009 if (data->pioInterface)
1011 struct ATA_BusInterface *vec = data->pioInterface - sizeof(struct ATA_BusInterface);
1013 vec->ata_out_alt(data->pioInterface, ATACTLF_INT_DISABLE, ata_AltControl);
1017 /***************** Private nonvirtual methods follow *****************/
1019 BOOL Hidd_ATABus_Start(OOP_Object *o, struct ataBase *ATABase)
1021 struct ata_Bus *ab = OOP_INST_DATA(ATABase->busClass, o);
1023 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
1025 /* Attach IRQ handler */
1026 OOP_SetAttrsTags(o, aHidd_ATABus_IRQHandler, Hidd_ATABus_HandleIRQ,
1027 aHidd_ATABus_IRQData , ab,
1028 TAG_DONE);
1030 /* scan bus - try to locate all devices (disables irq) */
1031 ata_InitBus(ab);
1033 if ((ab->ab_Dev[0] == DEV_NONE) && (ab->ab_Dev[1] == DEV_NONE) &&
1034 (!ab->keepEmpty))
1037 * If there are no devices, and KeepEmpty is not set
1038 * the bus will be thrown away.
1040 return FALSE;
1044 * Assign bus number.
1045 * TODO:
1046 * 1. This does not take into account possibility to
1047 * unload drivers. In this case existing units will disappear,
1048 * freeing up their numbers. These numbers should be reused.
1049 * 2. We REALLY need modify-and-fetch atomics.
1051 Forbid();
1052 ab->ab_BusNum = ATABase->ata__buscount++;
1053 Permit();
1055 if ((ab->ab_Dev[0] < DEV_ATA) && (ab->ab_Dev[1] < DEV_ATA))
1057 /* Do not start up task if there are no usable devices. */
1058 return TRUE;
1062 * This small trick is based on the fact that shared semaphores
1063 * have no specific owner. You can obtain and release them from
1064 * within any task. It will block only on attempt to re-lock it
1065 * in exclusive mode.
1066 * So instead of complex handshake we obtain the semaphore before
1067 * starting bus task. It will release the semaphore when done.
1069 ObtainSemaphoreShared(&ATABase->DetectionSem);
1072 * Start up bus task. It will perform scanning asynchronously, and
1073 * then, if successful, insert units. This allows to keep things parallel.
1075 D(bug("[ATA>>] Start: Bus %u: Unit 0 - %d, Unit 1 - %d\n", ab->ab_BusNum, ab->ab_Dev[0], ab->ab_Dev[1]));
1076 return NewCreateTask(TASKTAG_PC , BusTaskCode,
1077 TASKTAG_NAME , "ATA[PI] Subsystem",
1078 TASKTAG_STACKSIZE , STACK_SIZE,
1079 TASKTAG_PRI , TASK_PRI,
1080 TASKTAG_TASKMSGPORT, &ab->ab_MsgPort,
1081 TASKTAG_ARG1 , ab,
1082 TASKTAG_ARG2 , ATABase,
1083 TAG_DONE) ? TRUE : FALSE;
1086 AROS_UFH3(BOOL, Hidd_ATABus_Open,
1087 AROS_UFHA(struct Hook *, h, A0),
1088 AROS_UFHA(OOP_Object *, obj, A2),
1089 AROS_UFHA(IPTR, reqUnit, A1))
1091 AROS_USERFUNC_INIT
1093 struct IORequest *req = h->h_Data;
1094 struct ataBase *ATABase = (struct ataBase *)req->io_Device;
1095 struct ata_Bus *b = (struct ata_Bus *)OOP_INST_DATA(ATABase->busClass, obj);
1096 ULONG bus = reqUnit >> 1;
1097 UBYTE dev = reqUnit & 1;
1099 D(bug("[ATA:Bus] %s()\n", __PRETTY_FUNCTION__));
1100 D(bug("[ATA%02ld] Checking bus %u dev %u\n", reqUnit, bus, dev));
1102 if ((b->ab_BusNum == bus) && b->ab_Units[dev])
1104 struct ata_Unit *unit = (struct ata_Unit *)OOP_INST_DATA(ATABase->unitClass, b->ab_Units[dev]);
1106 /* Got the unit */
1107 req->io_Unit = &unit->au_Unit;
1108 req->io_Error = 0;
1110 unit->au_Unit.unit_OpenCnt++;
1111 return TRUE;
1114 return FALSE;
1116 AROS_USERFUNC_EXIT