Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals   Related Pages  

IdeLow.c

Go to the documentation of this file.
00001 /*!     \file drivers/ata/IdeLow.c
00002  *      \brief IDE driver::Low level routines.
00003  *      \author Luca Giovacchini
00004  *      \date Last update: 2003-11-07
00005  *      \note Copyright (©) 2003 Luca Giovacchini
00006  *
00007  *      <b>IMPORTANT!!!</b>\n
00008  *      Here you can find the base sub for communicating with
00009  *      Ide Devices.
00010  *      First subs expose a simpler interface to the
00011  *      rest of the driver, creating a simpler logical view of
00012  *      registers and most important data.
00013  *      You must not issue commands to device only with these subs,
00014  *      but you must use IdeAta subs (Ata protocol).
00015  */
00016 
00017 #include <string.h>
00018 
00019 #include <arch/i386.h>
00020 #include <arch/interrupt.h>
00021 #include <arch/mem.h>
00022 
00023 #include <kernel/clock.h>
00024 #include <kernel/Ide.h>
00025 #include <kernel/IdeAta.h>
00026 #include <kernel/IdeDebug.h>
00027 #include <kernel/IdeTimer.h>
00028 #include <kernel/keyboard.h>
00029 #include <kernel/video.h>
00030 
00031 #include <kernel/IdeLow.h>
00032 
00033 // store current selected channel (all command refer to this)
00034 // volatile IdeChannel_Struct IdeChannel[2];
00035 volatile IdeChannel_Struct * CurrentChannel;
00036 
00037 // absolute port of the register of the primary controller channel
00038 static IdeChannel_Struct IdePriReg;
00039 // absolute port of the register of the secondary controller channel
00040 static IdeChannel_Struct IdeSecReg;
00041 
00042 // ****************** SetAtaRegisterIoPort ******************
00043 // Set a unique logical vector with all the controller register used.
00044 // This is used as our logical view of the register without worring about 
00045 // underlying combination.
00046 // **********************************************************
00047 void SetAtaRegisterIoPort(word CmdBase, word CntBase, int IntN) 
00048 {
00049         CurrentChannel->CmdBasePort=CmdBase;
00050         CurrentChannel->CntBasePort=CntBase;
00051 
00052         CurrentChannel->IoPort[ CC_DATA  ] = CmdBase + HDC_DATA;
00053         CurrentChannel->IoPort[ CC_ERR   ] = CmdBase + HDC_ERR;
00054         CurrentChannel->IoPort[ CC_SECC  ] = CmdBase + HDC_SECC;
00055         CurrentChannel->IoPort[ CC_SECN  ] = CmdBase + HDC_SECN;
00056         CurrentChannel->IoPort[ CC_CYLL  ] = CmdBase + HDC_CYLL;
00057         CurrentChannel->IoPort[ CC_CYLH  ] = CmdBase + HDC_CYLH;
00058         CurrentChannel->IoPort[ CC_DEVH  ] = CmdBase + HDC_DEVH;
00059         CurrentChannel->IoPort[ CC_STAT  ] = CmdBase + HDC_STATUS;
00060         CurrentChannel->IoPort[ CC_ASTAT ] = CntBase + HDC_ASTAT;
00061         CurrentChannel->IoPort[ CC_ADDR  ] = CntBase + HDC_ADD;
00062         CurrentChannel->Device[ CC_DEV0 ].RegBit = HDC_DEVH_DEV0;
00063         CurrentChannel->Device[ CC_DEV0 ].Type   = CC_DEVTYPE_NONE;
00064         CurrentChannel->Device[ CC_DEV1 ].RegBit = HDC_DEVH_DEV1;
00065         CurrentChannel->Device[ CC_DEV1 ].Type   = CC_DEVTYPE_NONE;
00066 
00067         CurrentChannel->IntDone = FALSE;
00068         CurrentChannel->IntNum = IntN;
00069 }
00070 
00071 // ******************** SelectAtaChannel ********************
00072 // Instead of passing always what atachannel to use we set it here
00073 // Other functions will use the ata channel previously set
00074 // **********************************************************
00075 void SelectAtaChannel (int Channel)
00076 {
00077         // let primary be the default channel   
00078         if ( Channel == CC_SECONDARY )
00079         {
00080                 CurrentChannel=&IdeSecReg;
00081         }
00082         else
00083         {
00084                 CurrentChannel=&IdePriReg;      
00085         }
00086 }
00087 
00088 // ************************ AtaPort *************************
00089 // Translate Register Port in Absolute Port
00090 // **********************************************************
00091 word AtaPort(word Port)
00092 {
00093         return CurrentChannel->IoPort[Port];
00094 }
00095 
00096 // *********************** OutPortAta ***********************
00097 // Call outport with the translated (logical-physiscal) port
00098 // **********************************************************
00099 void OutPortAta(word Port, byte Val) 
00100 {
00101         outportb(AtaPort(Port),Val);
00102 }
00103 
00104 // *********************** InPortAta ************************
00105 // Call inport with the translated (logical-physiscal) port
00106 // **********************************************************
00107 byte InPortAta(word Port) 
00108 {
00109         return inportb(AtaPort(Port));
00110 }
00111 
00112 // ********************** InPortAtaMul **********************
00113 // Call inportwmul with the translated (logical-physiscal) port
00114 // **********************************************************
00115 void InPortAtaMul(word Port, word * Buffer,word Count)
00116 {
00117         // i suppose that user had set Buffer bigger enough!
00118         inportwm(AtaPort(Port),Buffer,Count);
00119 }
00120 
00121 // ********************** OutPortAtaMul **********************
00122 // Call outportwmul with the translated (logical-physiscal) port
00123 // **********************************************************
00124 void OutPortAtaMul(word Port, word * Buffer, word Count)
00125 {
00126         outportwm(AtaPort(Port),Buffer,Count);
00127 }
00128 
00129 
00130 // *********************** SetDevBit ************************
00131 // Set the proper device bit in the DeviceHead register
00132 // **********************************************************
00133 void SetDevBit(int Dev) 
00134 {
00135         OutPortAta( CC_DEVH, CurrentChannel->Device[Dev].RegBit);
00136         DELAY400NS;
00137 }
00138 
00139 // ********************* SetFirstDevBit *********************
00140 // If possible, select a device that exists,
00141 // try device 0 first.
00142 // **********************************************************
00143 void SetFirstDevBit() 
00144 {       
00145         if ( CurrentChannel->Device[CC_DEV0].Type != CC_DEVTYPE_NONE )
00146                 SetDevBit(CC_DEV0);             
00147         else if( CurrentChannel->Device[CC_DEV1].Type != CC_DEVTYPE_NONE ) 
00148                 SetDevBit(CC_DEV1);             
00149 }
00150 
00151 // ********************** Ide_Handler ***********************
00152 // This sub must be called only from maing OS interrupt handler
00153 // when interrupts come so we can know it.
00154 // **********************************************************
00155 
00156 // --- modified by: Andrea Righi 2003-09-16 ----------------------------//
00157 void Ide_Handler_Pri()
00158 {
00159         IdePriReg.IntDone = TRUE;
00160 }
00161 
00162 void Ide_Handler_Sec()
00163 {
00164         IdeSecReg.IntDone = TRUE;
00165 }
00166 // ---------------------------------------------------------------------//

Generated on Fri Feb 20 15:32:15 2004 for Minirighi by doxygen1.2.18