delint
[AROS.git] / rom / devs / ata / bus_class.c
blobbb5c8bb6ceb0a638a1b49668482e20899dad6169
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/debug.h>
7 #include <hidd/ata.h>
8 #include <oop/oop.h>
9 #include <utility/tagitem.h>
10 #include <proto/exec.h>
11 #include <proto/oop.h>
12 #include <proto/utility.h>
14 #include "ata.h"
15 #include "ata_bus.h"
17 #define DIRQ(x)
19 static void Hidd_ATABus_HandleIRQ(UBYTE status, struct ata_Bus *bus)
21 struct ata_Unit *unit = bus->ab_SelectedUnit;
24 * don't waste your time on checking other devices.
25 * pass irq ONLY if task is expecting one;
27 if (unit && bus->ab_HandleIRQ)
29 /* ok, we have a routine to handle any form of transmission etc. */
30 DIRQ(bug("[ATA%02d] IRQ: Calling dedicated handler 0x%p... \n",
31 unit->au_UnitNum, bus->ab_HandleIRQ));
32 bus->ab_HandleIRQ(unit, status);
34 return;
37 DIRQ({
39 * if we got *here* then device is most likely not expected to have an irq.
41 bug("[ATA%02d] Spurious IRQ\n", unit ? unit->au_UnitNum : -1);
43 if (0 == (ATAF_BUSY & status))
45 bug("[ATA ] STATUS: %02lx\n" , status);
46 bug("[ATA ] ALT STATUS: %02lx\n" , PIO_InAlt(bus, ata_AltStatus));
47 bug("[ATA ] ERROR: %02lx\n" , PIO_In(bus, ata_Error));
48 bug("[ATA ] IRQ: REASON: %02lx\n", PIO_In(bus, atapi_Reason));
50 });
53 static AROS_INTH1(ataBus_Reset, struct ata_Bus *, bus)
55 AROS_INTFUNC_INIT
57 struct ataBase *ATABase = bus->ab_Base;
58 OOP_Object *obj = (void *)bus - ATABase->busClass->InstOffset;
60 HIDD_ATABus_Shutdown(obj);
62 return FALSE;
64 AROS_INTFUNC_EXIT
67 /*****************************************************************************************
69 NAME
70 --background--
72 LOCATION
73 CLID_Hidd_ATABus
75 NOTES
76 This class serves as a base class for implementing IDE (ATA) bus drivers.
77 One particularity of this class is that IDE bus is very speed-critical.
78 At the other hand, the driver implements very lowlevel operations which
79 are called quite often. OOP_DoMethod() call is not fast enough, and in
80 order to circumvent this limitation, additionally to normal OOP API
81 IDE bus drivers offer two additional non-standard interfaces. Internally
82 they are implemented as library-alike function table plus driver-specific
83 data. For the purpose of some performance optimizations the function
84 table is private to ata.device and managed entirely by the base class.
85 Driver classes have access only to data portion.
87 These interfaces are documented below.
89 *****************************************************************************************/
90 /*****************************************************************************************
92 NAME
93 --PIO interface--
95 LOCATION
96 CLID_Hidd_ATABus
98 NOTES
99 PIO interface is responsible for accessing I/O registers on the IDE
100 bus, as well as performing PIO-mode 16- and 32-bit data transfers.
101 This interface is mandatory and must be implemented by the driver,
102 however some functions are optional. They can be either omitted
103 entirely from the function table, or set to NULL pointers.
105 Control functions table for the interface consists of the following
106 functions (listed in their order in the array):
108 VOID ata_out(void *obj, UBYTE val, UWORD offset)
109 - Write byte into primary register bank with the given offset.
111 UBYTE ata_in(void *obj, UWORD offset)
112 - Read byte from primary register bank with the given offset.
114 VOID ata_out_alt(void *obj, UBYTE val, UWORD offset)
115 - Write byte into alternate register bank with the given offset.
116 This function is optional.
118 UBYTE ata_in_alt(void *obj, UWORD offset)
119 - Read byte from alternate register bank with the given offset.
120 This function is optional.
122 Transfer functions table for the interface consists of the following
123 functions (listed in their order in the array):
125 VOID ata_outsw(void *obj, APTR address, ULONG count)
126 - Perform 16-bit PIO data write operation from the given memory
127 region of the given size.
129 VOID ata_insw(void *obj, APTR address, ULONG count)
130 - Perform 16-bit PIO data read operation into the given memory
131 region of the given size.
133 VOID ata_outsl(void *obj, APTR address, ULONG count)
134 - Perform 32-bit PIO data write operation from the given memory
135 region of the given size. This function is optional.
137 UBYTE ata_insl(void *obj, APTR address, ULONG count)
138 - Perform 32-bit PIO data read operation into the given memory
139 region of the given size. This function is optional.
141 *****************************************************************************************/
142 /*****************************************************************************************
144 NAME
145 --DMA interface--
147 LOCATION
148 CLID_Hidd_ATABus
150 NOTES
151 DMA interface is optional, and is needed in order to support DMA data
152 transfers.
154 Function table for the interface consists of the following functions:
156 BOOL dma_Setup(void *obj, APTR buffer, IPTR size, BOOL read)
157 - Prepare the controller to DMA data transfer. The last argument is
158 TRUE for read operation and FALSE for write. The function should
159 return TRUE for success or FALSE for failure.
161 VOID dma_Start(void *obj)
162 - Start DMA transfer.
164 VOID dma_End(void *obj, APTR buffer, IPTR size, BOOL read)
165 - End DMA transfer and perform post-transfer cleanup of the given region.
167 ULONG dma_Result(void *obj)
168 - Get resulting status of the operation. The function should return 0
169 for successful completion or error code to be passed up to ata.device
170 caller in io_Result field of the IORequest.
172 *****************************************************************************************/
173 /*****************************************************************************************
175 NAME
176 aoHidd_ATABus_Use80Wire
178 SYNOPSIS
179 [..G], BOOL
181 LOCATION
182 CLID_Hidd_ATABus
184 FUNCTION
185 Tells whether the bus currently uses 80-conductor cable.
187 NOTES
188 This attribute actually makes difference only for DMA modes. If
189 your bus driver returns FALSE, ata.device will not use modes
190 higher than UDMA2 on the bus.
192 EXAMPLE
194 BUGS
196 SEE ALSO
198 INTERNALS
200 *****************************************************************************************/
201 /*****************************************************************************************
203 NAME
204 aoHidd_ATABus_Use32Bit
206 SYNOPSIS
207 [.SG], BOOL
209 LOCATION
210 CLID_Hidd_ATABus
212 FUNCTION
213 When queried, tells whether the bus supports 32-bit PIO data transfers.
214 When set, enables or disables 32-bit mode for PIO data transfers.
216 NOTES
218 EXAMPLE
220 BUGS
222 SEE ALSO
224 INTERNALS
226 *****************************************************************************************/
227 /*****************************************************************************************
229 NAME
230 aoHidd_ATABus_UseDMA
232 SYNOPSIS
233 [..G], BOOL
235 LOCATION
236 CLID_Hidd_ATABus
238 FUNCTION
239 Tells whether the bus supports DMA transfers.
241 NOTES
243 EXAMPLE
245 BUGS
247 SEE ALSO
249 INTERNALS
250 Default implementation in base class returns value depending on whether
251 the subclass provided DMA interface function table during object creation.
253 *****************************************************************************************/
254 /*****************************************************************************************
256 NAME
257 aoHidd_ATABus_PIODataSize
259 SYNOPSIS
260 [I..], BOOL
262 LOCATION
263 CLID_Hidd_ATABus
265 FUNCTION
266 Specifies size of PIO interface data structure.
268 NOTES
270 EXAMPLE
272 BUGS
274 SEE ALSO
276 INTERNALS
278 *****************************************************************************************/
279 /*****************************************************************************************
281 NAME
282 aoHidd_ATABus_DMADataSize
284 SYNOPSIS
285 [I..], BOOL
287 LOCATION
288 CLID_Hidd_ATABus
290 FUNCTION
291 Specifies size of DMA interface data structure.
293 NOTES
295 EXAMPLE
297 BUGS
299 SEE ALSO
301 INTERNALS
303 *****************************************************************************************/
304 /*****************************************************************************************
306 NAME
307 aoHidd_ATABus_BusVectors
309 SYNOPSIS
310 [I..], APTR *
312 LOCATION
313 CLID_Hidd_ATABus
315 FUNCTION
316 Specifies control functions table for building PIO interface object.
317 The function table is an array of function pointers terminated
318 by -1 value. The terminator must be present for purpose of
319 binary compatibility with future extensions.
321 NOTES
322 This function table is mandatory to be implemented by the driver.
324 EXAMPLE
326 BUGS
328 SEE ALSO
330 INTERNALS
332 *****************************************************************************************/
333 /*****************************************************************************************
335 NAME
336 aoHidd_ATABus_PIOVectors
338 SYNOPSIS
339 [I..], APTR *
341 LOCATION
342 CLID_Hidd_ATABus
344 FUNCTION
345 Specifies transfers function table for building PIO interface object.
346 The function table is an array of function pointers terminated
347 by -1 value. The terminator must be present for purpose of
348 binary compatibility with future extensions.
350 NOTES
351 This function table is mandatory to be implemented by the driver.
353 EXAMPLE
355 BUGS
357 SEE ALSO
359 INTERNALS
361 *****************************************************************************************/
362 /*****************************************************************************************
364 NAME
365 aoHidd_ATABus_DMAVectors
367 SYNOPSIS
368 [I..], APTR *
370 LOCATION
371 CLID_Hidd_ATABus
373 FUNCTION
374 Specifies function table for building DMA interface object. If not supplied,
375 the bus is considered not DMA-capable.
377 NOTES
379 EXAMPLE
381 BUGS
383 SEE ALSO
384 aoHidd_ATABus_PIOVectors
386 INTERNALS
388 *****************************************************************************************/
389 /*****************************************************************************************
391 NAME
392 aoHidd_ATABus_IRQHandler
394 SYNOPSIS
395 [.S.], APTR
397 LOCATION
398 CLID_Hidd_ATABus
400 FUNCTION
401 Specifies IRQ handler function to be called when bus interrupt arrives.
402 The function should be called using "C" calling convention and has the
403 following prototype:
405 void ata_HandleIRQ(UBYTE status, APTR userdata);
407 Your driver should pass the following arguments to this function:
408 status - value read from ATA main status register.
409 userdata - value of aoHidd_ATABus_IRQData attribute.
411 NOTES
412 Reading the drive status register is part of the interrupt acknowledge
413 process, and therefore has to be done by the driver.
415 It is driver's job to check whether the interrupt really belongs to
416 the IDE bus. A generic way to do this is to test ATAF_BUSY bit of
417 the status register for being zero. However, this may not work
418 reliably with IRQ sharing, so advanced IDE controllers may offer
419 different, better way to do this.
421 EXAMPLE
423 BUGS
425 SEE ALSO
426 aoHidd_ATABus_IRQData
428 INTERNALS
430 *****************************************************************************************/
431 /*****************************************************************************************
433 NAME
434 aoHidd_ATABus_IRQData
436 SYNOPSIS
437 [.S.], APTR
439 LOCATION
440 CLID_Hidd_ATABus
442 FUNCTION
443 Caller's private data to be supplied to IRQ handler function.
445 NOTES
447 EXAMPLE
449 BUGS
451 SEE ALSO
452 aoHidd_ATABus_IRQData
454 INTERNALS
456 *****************************************************************************************/
457 /*****************************************************************************************
459 NAME
460 aoHidd_ATABus_UseIOAlt
462 SYNOPSIS
463 [..G], BOOL
465 LOCATION
466 CLID_Hidd_ATABus
468 FUNCTION
469 Tells whether the bus supports alternate registers bank
470 (ata_AltControl and ata_AltStatus).
472 NOTES
474 EXAMPLE
476 BUGS
478 SEE ALSO
480 INTERNALS
481 Default implementation in base class returns value depending on whether
482 the subclass provided respective I/O functions in bus interface vector
483 table during object creation.
485 *****************************************************************************************/
486 /*****************************************************************************************
488 NAME
489 aoHidd_ATABus_KeepEmpty
491 SYNOPSIS
492 [I..], BOOL
494 LOCATION
495 CLID_Hidd_ATABus
497 FUNCTION
498 If this attribute is set to FALSE during object creation, the object
499 will be destroyed if no devices are detected on the bus.
501 This can be useful for optional buses like legacy ISA controllers,
502 which have no other way to detect their presence.
504 NOTES
506 EXAMPLE
508 BUGS
510 SEE ALSO
512 INTERNALS
514 *****************************************************************************************/
515 /*****************************************************************************************
517 NAME
518 aoHidd_ATABus_Master
520 SYNOPSIS
521 [..G], OOP_Object *
523 LOCATION
524 CLID_Hidd_ATABus
526 FUNCTION
527 Returns a pointer to OOP object of private unit class, representing
528 a master drive on the bus, or NULL if there's no master device.
530 NOTES
532 EXAMPLE
534 BUGS
536 SEE ALSO
537 aoHidd_ATABus_Slave
539 INTERNALS
541 *****************************************************************************************/
542 /*****************************************************************************************
544 NAME
545 aoHidd_ATABus_Slave
547 SYNOPSIS
548 [..G], OOP_Object *
550 LOCATION
551 CLID_Hidd_ATABus
553 FUNCTION
554 Returns a pointer to OOP object of private unit class, representing
555 a slave drive on the bus, or NULL if there's no master device.
557 NOTES
559 EXAMPLE
561 BUGS
563 SEE ALSO
564 aoHidd_ATABus_Master
566 INTERNALS
568 *****************************************************************************************/
569 /*****************************************************************************************
571 NAME
572 aoHidd_ATABus_CanSetXferMode
574 SYNOPSIS
575 [..G], BOOL
577 LOCATION
578 CLID_Hidd_ATABus
580 FUNCTION
581 Tells whether the bus driver implements moHidd_ATABus_SetXferMode method.
583 NOTES
585 EXAMPLE
587 BUGS
588 Current version of ata.device does not use this attribute, and it is
589 considered reserved.
591 SEE ALSO
592 moHidd_ATABus_SetXferMode
594 INTERNALS
596 *****************************************************************************************/
598 OOP_Object *ATABus__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
600 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, &msg->mID);
601 if (o)
603 struct ataBase *ATABase = cl->UserData;
604 struct ata_Bus *data = OOP_INST_DATA(cl, o);
605 struct TagItem *tstate = msg->attrList;
606 struct TagItem *tag;
608 /* Defaults */
609 data->keepEmpty = TRUE;
611 while ((tag = NextTagItem(&tstate)))
613 ULONG idx;
615 Hidd_ATABus_Switch(tag->ti_Tag, idx)
617 case aoHidd_ATABus_PIODataSize:
618 data->pioDataSize = tag->ti_Data;
619 break;
621 case aoHidd_ATABus_DMADataSize:
622 data->dmaDataSize = tag->ti_Data;
623 break;
625 case aoHidd_ATABus_BusVectors:
626 data->busVectors = (struct ATA_BusInterface *)tag->ti_Data;
627 break;
629 case aoHidd_ATABus_PIOVectors:
630 data->pioVectors = (struct ATA_PIOInterface *)tag->ti_Data;
631 break;
633 case aoHidd_ATABus_DMAVectors:
634 data->dmaVectors = (APTR *)tag->ti_Data;
635 break;
637 case aoHidd_ATABus_KeepEmpty:
638 data->keepEmpty = tag->ti_Data;
639 break;
643 /* Cache device base pointer. Useful. */
644 data->ab_Base = ATABase;
646 /* Install reset callback */
647 data->ab_ResetInt.is_Node.ln_Name = ATABase->ata_Device.dd_Library.lib_Node.ln_Name;
648 data->ab_ResetInt.is_Code = (VOID_FUNC)ataBus_Reset;
649 data->ab_ResetInt.is_Data = data;
650 AddResetCallback(&data->ab_ResetInt);
652 return o;
655 void ATABus__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
657 struct ata_Bus *data = OOP_INST_DATA(cl, o);
659 RemResetCallback(&data->ab_ResetInt);
661 if (data->dmaInterface)
663 void *ptr = data->dmaInterface - sizeof(struct ATA_DMAInterface);
665 FreeMem(ptr, sizeof(struct ATA_DMAInterface) + data->dmaDataSize);
667 if (data->pioInterface)
669 void *ptr = data->pioInterface - sizeof(struct ATA_BusInterface);
671 FreeMem(ptr, sizeof(struct ATA_BusInterface) + data->pioDataSize);
674 OOP_DoSuperMethod(cl, o, msg);
678 * Here we take into account that the table can be either
679 * terminated early, or have NULL entries.
681 #define HAVE_VECTOR(x) (x && (x != (APTR)-1))
683 void ATABus__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
685 struct ataBase *ATABase = cl->UserData;
686 struct ata_Bus *data = OOP_INST_DATA(cl, o);
687 ULONG idx;
689 Hidd_ATABus_Switch (msg->attrID, idx)
691 case aoHidd_ATABus_Use80Wire:
692 *msg->storage = FALSE;
693 return;
695 case aoHidd_ATABus_Use32Bit:
696 *msg->storage = (HAVE_VECTOR(data->pioVectors->ata_outsl) &&
697 HAVE_VECTOR(data->pioVectors->ata_insl)) ?
698 TRUE : FALSE;
699 return;
701 case aoHidd_ATABus_UseDMA:
702 *msg->storage = data->dmaVectors ? TRUE : FALSE;
703 return;
705 case aoHidd_ATABus_UseIOAlt:
706 *msg->storage = (HAVE_VECTOR(data->busVectors->ata_out_alt) &&
707 HAVE_VECTOR(data->busVectors->ata_in_alt)) ?
708 TRUE : FALSE;
709 return;
711 case aoHidd_ATABus_Master:
712 *msg->storage = (IPTR)data->ab_Units[0];
713 return;
715 case aoHidd_ATABus_Slave:
716 *msg->storage = (IPTR)data->ab_Units[1];
717 return;
719 case aoHidd_ATABus_CanSetXferMode:
720 *msg->storage = FALSE;
721 return;
724 OOP_DoSuperMethod(cl, o, &msg->mID);
727 /* Default ata_out_alt does nothing */
728 static void default_out_alt(void *obj, UBYTE val, UWORD offset)
733 /* Default ata_in_alt wraps AltStatus to status */
734 static UBYTE default_in_alt(void *obj, UWORD offset)
736 struct ATA_BusInterface *vec = obj - sizeof(struct ATA_BusInterface);
738 return vec->ata_in(obj, ata_Status);
741 static void CopyVectors(APTR *dest, APTR *src, unsigned int num)
743 unsigned int i;
745 for (i = 0; i < num; i++)
747 if (src[i] == (APTR *)-1)
748 return;
749 if (src[i])
750 dest[i] = src[i];
754 /*****************************************************************************************
756 NAME
757 moHidd_ATABus_GetPIOInterface
759 SYNOPSIS
760 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_GetPIOInterface *Msg);
762 APTR HIDD_ATABus_GetPIOInterface(void);
764 LOCATION
765 CLID_Hidd_ATABus
767 FUNCTION
768 Instantiates encapsulated PIO interface object and returns its
769 pointer.
771 INPUTS
772 None
774 RESULT
775 A pointer to opaque PIO interface object or NULL in case of failure.
777 NOTES
778 This method should be overloaded by driver subclasses in order to
779 initialize data portion of the interface object.
781 EXAMPLE
783 BUGS
785 SEE ALSO
786 moHidd_ATABus_GetDMAInterface
788 INTERNALS
789 Interface objects contain not only driver-specific data, but also
790 a private vector table. Because of this you cannot just AllocMem()
791 the necessary structure in your driver. Always call OOP_DoSuperMethod()
792 in order for the base class to instantiate the interface correctly.
794 *****************************************************************************************/
796 APTR ATABus__Hidd_ATABus__GetPIOInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
798 struct ata_Bus *data = OOP_INST_DATA(cl, o);
799 struct ATA_BusInterface *vec;
801 vec = AllocMem(sizeof(struct ATA_BusInterface) + data->pioDataSize,
802 MEMF_PUBLIC|MEMF_CLEAR);
803 if (vec)
805 /* Some default vectors for simplicity */
806 vec->ata_out_alt = default_out_alt;
807 vec->ata_in_alt = default_in_alt;
809 CopyVectors((APTR *)vec, (APTR *)data->busVectors,
810 sizeof(struct ATA_BusInterface) / sizeof(APTR));
812 data->pioInterface = &vec[1];
813 return data->pioInterface;
816 return NULL;
819 /*****************************************************************************************
821 NAME
822 moHidd_ATABus_GetDMAInterface
824 SYNOPSIS
825 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_GetDMAInterface *Msg);
827 APTR HIDD_ATABus_GetDMAInterface(void);
829 LOCATION
830 CLID_Hidd_ATABus
832 FUNCTION
833 Instantiates encapsulated DMA interface object and returns its
834 pointer.
836 INPUTS
837 None
839 RESULT
840 A pointer to opaque DMA interface object or NULL upon failure or
841 if DMA is not supported by this bus.
843 NOTES
844 This method should be overloaded by driver subclasses in order to
845 initialize data portion of the interface object.
847 EXAMPLE
849 BUGS
851 SEE ALSO
852 moHidd_ATABus_GetPIOInterface
854 INTERNALS
855 Interface objects contain not only driver-specific data, but also
856 a private vector table. Because of this you cannot just AllocMem()
857 the necessary structure in your driver. Always call OOP_DoSuperMethod()
858 in order for the base class to instantiate the interface correctly.
860 *****************************************************************************************/
862 APTR ATABus__Hidd_ATABus__GetDMAInterface(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
864 struct ata_Bus *data = OOP_INST_DATA(cl, o);
865 struct ATA_DMAInterface *vec;
867 if (!data->dmaVectors)
868 return NULL;
870 vec = AllocMem(sizeof(struct ATA_DMAInterface) + data->dmaDataSize,
871 MEMF_PUBLIC|MEMF_CLEAR);
872 if (vec)
874 CopyVectors((APTR *)vec, data->dmaVectors,
875 sizeof(struct ATA_DMAInterface) / sizeof(APTR));
877 data->dmaInterface = &vec[1];
878 return data->dmaInterface;
881 return NULL;
884 /*****************************************************************************************
886 NAME
887 moHidd_ATABus_SetXferMode
889 SYNOPSIS
890 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_SetXferMode *Msg);
892 APTR HIDD_ATABus_SetXferMode(UBYTE unit, ata_XferMode mode);
894 LOCATION
895 CLID_Hidd_ATABus
897 FUNCTION
898 Sets the desired transfer mode for the given drive on the bus controller.
900 INPUTS
901 unit - drive number (0 for master and 1 for slave)
902 mode - Mode number (see hidd/ata.h)
904 RESULT
905 TRUE if successful or FALSE if the desired mode is not supported
906 by the hardware.
908 NOTES
909 The default implementation is provided for drivers not supporting
910 DMA and always returns FALSE if the caller attempts to set any of
911 DMA modes.
913 EXAMPLE
915 BUGS
916 Current version of ata.device does not use this method, and it is
917 considered reserved.
919 SEE ALSO
920 aoHidd_ATABus_CanSetXferMode
922 INTERNALS
924 *****************************************************************************************/
926 BOOL ATABus__Hidd_ATABus__SetXferMode(OOP_Class *cl, OOP_Object *o, struct pHidd_ATABus_SetXferMode *msg)
928 if ((msg->mode >= AB_XFER_MDMA0) && (msg->mode <= AB_XFER_UDMA6))
930 /* DMA is not supported, we cannot set DMA modes */
931 return FALSE;
934 return TRUE;
937 /*****************************************************************************************
939 NAME
940 moHidd_ATABus_Shutdown
942 SYNOPSIS
943 APTR OOP_DoMethod(OOP_Object *obj, struct pHidd_ATABus_Shutdown *Msg);
945 APTR HIDD_ATABus_Shutdown(void);
947 LOCATION
948 CLID_Hidd_ATABus
950 FUNCTION
951 Instantly shutdown all activity on the bus.
953 INPUTS
954 None
956 RESULT
957 None
959 NOTES
960 This method is called by ata.device during system reset handler execution.
962 EXAMPLE
964 BUGS
966 SEE ALSO
968 INTERNALS
969 Default implementation disables interrupt using AltControl register.
971 *****************************************************************************************/
973 void ATABus__Hidd_ATABus__Shutdown(OOP_Class *cl, OOP_Object *o, OOP_Msg *msg)
975 struct ata_Bus *data = OOP_INST_DATA(cl, o);
977 if (data->pioInterface)
979 struct ATA_BusInterface *vec = data->pioInterface - sizeof(struct ATA_BusInterface);
981 vec->ata_out_alt(data->pioInterface, ATACTLF_INT_DISABLE, ata_AltControl);
985 /***************** Private nonvirtual methods follow *****************/
987 BOOL Hidd_ATABus_Start(OOP_Object *o, struct ataBase *ATABase)
989 struct ata_Bus *ab = OOP_INST_DATA(ATABase->busClass, o);
991 /* Attach IRQ handler */
992 OOP_SetAttrsTags(o, aHidd_ATABus_IRQHandler, Hidd_ATABus_HandleIRQ,
993 aHidd_ATABus_IRQData , ab,
994 TAG_DONE);
996 /* scan bus - try to locate all devices (disables irq) */
997 ata_InitBus(ab);
999 if ((ab->ab_Dev[0] == DEV_NONE) && (ab->ab_Dev[1] == DEV_NONE) &&
1000 (!ab->keepEmpty))
1003 * If there are no devices, and KeepEmpty is not set
1004 * the bus will be thrown away.
1006 return FALSE;
1010 * Assign bus number.
1011 * TODO:
1012 * 1. This does not take into account possibility to
1013 * unload drivers. In this case existing units will disappear,
1014 * freeing up their numbers. These numbers should be reused.
1015 * 2. We REALLY need modify-and-fetch atomics.
1017 Forbid();
1018 ab->ab_BusNum = ATABase->ata__buscount++;
1019 Permit();
1021 if ((ab->ab_Dev[0] < DEV_ATA) && (ab->ab_Dev[1] < DEV_ATA))
1023 /* Do not start up task if there are no usable devices. */
1024 return TRUE;
1028 * This small trick is based on the fact that shared semaphores
1029 * have no specific owner. You can obtain and release them from
1030 * within any task. It will block only on attempt to re-lock it
1031 * in exclusive mode.
1032 * So instead of complex handshake we obtain the semaphore before
1033 * starting bus task. It will release the semaphore when done.
1035 ObtainSemaphoreShared(&ATABase->DetectionSem);
1038 * Start up bus task. It will perform scanning asynchronously, and
1039 * then, if successful, insert units. This allows to keep things parallel.
1041 D(bug("[ATA>>] Start: Bus %u: Unit 0 - %d, Unit 1 - %d\n", ab->ab_BusNum, ab->ab_Dev[0], ab->ab_Dev[1]));
1042 return NewCreateTask(TASKTAG_PC , BusTaskCode,
1043 TASKTAG_NAME , "ATA[PI] Subsystem",
1044 TASKTAG_STACKSIZE , STACK_SIZE,
1045 TASKTAG_PRI , TASK_PRI,
1046 TASKTAG_TASKMSGPORT, &ab->ab_MsgPort,
1047 TASKTAG_ARG1 , ab,
1048 TASKTAG_ARG2 , ATABase,
1049 TAG_DONE) ? TRUE : FALSE;
1052 AROS_UFH3(BOOL, Hidd_ATABus_Open,
1053 AROS_UFHA(struct Hook *, h, A0),
1054 AROS_UFHA(OOP_Object *, obj, A2),
1055 AROS_UFHA(IPTR, reqUnit, A1))
1057 AROS_USERFUNC_INIT
1059 struct IORequest *req = h->h_Data;
1060 struct ataBase *ATABase = (struct ataBase *)req->io_Device;
1061 struct ata_Bus *b = (struct ata_Bus *)OOP_INST_DATA(ATABase->busClass, obj);
1062 ULONG bus = reqUnit >> 1;
1063 UBYTE dev = reqUnit & 1;
1065 D(bug("[ATA%02ld] Checking bus %u dev %u\n", reqUnit, bus, dev));
1067 if ((b->ab_BusNum == bus) && b->ab_Units[dev])
1069 /* Got the unit */
1070 req->io_Unit = &b->ab_Units[dev]->au_Unit;
1071 req->io_Error = 0;
1073 b->ab_Units[dev]->au_Unit.unit_OpenCnt++;
1074 return TRUE;
1077 return FALSE;
1079 AROS_USERFUNC_EXIT