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

Ide.c

Go to the documentation of this file.
00001 /*!     \file drivers/ata/Ide.c
00002  *      \brief IDE driver.
00003  *      \author Luca Giovacchini
00004  *      \date Last update: 2003-11-07
00005  *      \note Copyright (©) 2003 Luca Giovacchini
00006  *
00007  *      This driver is based on Atadrv by Hale Landis
00008  *      but it is completely rearranged for the minirighi32.
00009  *      \n
00010  *      <b>IMPORTANT!!!</b>\n
00011  *      Here you can find what the driver should expose to the rest
00012  *      of the world.
00013  *
00014  *      Read IdeAta, IdeLow, IdeDebug and IdeTimer comments for better
00015  *      understand how this driver works.
00016  *      Implementing new ide commands is very very simple.
00017  *      All the major part of the Ata protocol is in "IdeAta.c".
00018  *      You only need to look for Ata-4 references, search for a
00019  *      command and see what protocol and what parameter you have
00020  *      to use.
00021  *      I have written specific subroutines to read, write and identify
00022  *      identifying devices, but they only simplify the interface for
00023  *      the more generic ata protocol.
00024  *
00025  *      I have already set inizialization of Ide Driver in main.c so
00026  *      you only need to:
00027  *      \li select the channel you want to use (with SelectAtaChannel);
00028  *      \li check CurrentChannel to find a specific device (directly
00029  *      with CurrentChannel var);
00030  *      \li use one of the specific command sub (i.e. ReadSectorLba,
00031  *      WriteSectorLba, ...)
00032  */
00033 
00034 #include <string.h>
00035 
00036 #include <arch/i386.h>
00037 #include <arch/interrupt.h>
00038 #include <arch/mem.h>
00039 
00040 #include <kernel/clock.h>
00041 #include <kernel/IdeTimer.h>
00042 #include <kernel/IdeDebug.h>
00043 #include <kernel/IdeLow.h>
00044 #include <kernel/video.h>
00045 #include <kernel/IdeAta.h>
00046 #include <kernel/keyboard.h>
00047 
00048 #include <kernel/Ide.h>
00049 
00050 extern IdeChannel_Struct * CurrentChannel;
00051 
00052 
00053 // static BusMaster_Struct BusMaster; // UNDER CONSTRUCTION
00054 
00055 
00056 void ShowDeviceSubData(int Dev)
00057 {
00058 
00059         Device_Struct * CurDev=&CurrentChannel->Device[Dev];
00060 
00061         if ( CurDev->Type==CC_DEVTYPE_ATA )
00062         {
00063                 kprintf("\n\rDevice %d: %s",Dev, CurDev->Info.ModelNumber);
00064                 kprintf("\n\r    Type: ATA %d - UDMA %d",
00065                         CurDev->Info.HighestAtaSupported,
00066                         CurDev->Info.HighestUDMASupported);
00067                 kprintf("\n\r    Firmware Rev: %s", CurDev->Info.FirmwareRev);
00068                 kprintf("\n\r    SerialNumber: %s", CurDev->Info.SerialNumber);
00069                 kprintf("\n\r    Capacity: %i MB",CurDev->Info.CapacityLba / 2 / 1024);
00070         }
00071         else if ( CurDev->Type==CC_DEVTYPE_NONE )
00072                 kprintf("\n\rDevice %d NOT FOUND",Dev);
00073         else if ( CurDev->Type==CC_DEVTYPE_ATAPI )
00074                 kprintf("\n\rDevice %d FOUND Type: ATAPI",Dev);
00075         else
00076                 kprintf("\n\rDevice %d FOUND Type: UNKNOW",Dev);
00077 }
00078 
00079 void ShowIdeSubData()
00080 {
00081         SelectAtaChannel(CC_PRIMARY);
00082         kprintf("\n\rPRIMARY CHANNEL");
00083         ShowDeviceSubData(CC_DEV0);
00084         ShowDeviceSubData(CC_DEV1);
00085         kprintf("\n\r");
00086         SelectAtaChannel(CC_SECONDARY);
00087         kprintf("\n\rSECONDARY CHANNEL");
00088         ShowDeviceSubData(CC_DEV0);
00089         ShowDeviceSubData(CC_DEV1);
00090 }
00091 
00092 
00093 // ********************* ScanDevice *************************
00094 // Initialize, reset and scan for all device in a channel
00095 // The channel must be selected before calling this
00096 // All information were stored in CurrentChannel global structure
00097 // **********************************************************
00098 int ScanDevice(int UseInterrupt)
00099 {
00100         byte DevCtrl;
00101         int Err=FALSE;
00102 
00103         // HDC_DEVC_HD15 is not needed in recent ata (is for compatibility)
00104         DevCtrl= HDC_DEVC_HD15 | ( UseInterrupt ? 0 : HDC_DEVC_NIEN );
00105 
00106         // Send To Device Control Register his Initialization Parameter
00107         OutPortAta(CC_DEVC,DevCtrl);
00108 
00109         // Try to chek for some sort of device before
00110         // execute some sort of command on it
00111         IdeDeviceDetection(CC_DEV0);
00112         IdeDeviceDetection(CC_DEV1);
00113 
00114         // select device 0
00115         SetDevBit(CC_DEV0);
00116         // Know that you know what devices exist you can
00117         // do a soft reset. The reset is for both device,
00118         // after the reset we will select Dev0 if possible
00119         Err=IdeSoftReset( FALSE, UseInterrupt );
00120 
00121         // Now we can issue command because we know how many devices
00122         // are on the channel and we have done the reset on they so:
00123         // is device really there? is it ATA or ATAPI?
00124         IdeDeviceTypeDetection(CC_DEV0);
00125         IdeDeviceTypeDetection(CC_DEV1);
00126 
00127         // Select first selectable device
00128         SetFirstDevBit();
00129         // take in mind that error from this function
00130         // are not critical, the caller can continue
00131         // to do his normal operation in respect
00132         // to DeviceType field of CurrentChannel->Device[Dev]
00133         return Err;
00134         // END: Now we have each device type in CurrentChannel
00135 }
00136 
00137 
00138 // ********************* IdentifyDevice *********************
00139 // Execute Identify Device Command
00140 // Store in Buffer the 256 word of Device Info
00141 // Translate Buffer in DeviceInfo_Struct
00142 // This sub works only on Ata device, to get information from 
00143 // Atapi you should use IdentifyPacketDevice command
00144 // **********************************************************
00145 int IdentifyDevice (int Dev) 
00146 {
00147         int i;
00148         word Buffer[256];
00149         word * Tmp;
00150         int Err=0;
00151         DeviceInfo_Struct * TmpDev=(DeviceInfo_Struct *) &(CurrentChannel->Device[Dev].Info);
00152 
00153         //kprintf("\n\rIdentify Dev=%d",Dev);
00154 
00155         // Be sure to reset the buffer
00156         memsetw( &Buffer, 0, 256);
00157 
00158         // Get 256 word of device info
00159         Err = IdePioDataInLba(Dev, HDC_CMD_IDENTIFY_DEVICE, 0, 0, 0L, (word *) &Buffer , 1, 0, TRUE);
00160         if ( Err ) 
00161                 return Err;
00162 
00163         // now the buffer contain raw word of info
00164         // we must translate it in a more readable struct
00165         //kprintf("\n\r Fill Structure");
00166         TmpDev->Ata                     =(byte) GETBITW(Buffer[0],15);
00167         TmpDev->Removable               =(byte) GETBITW(Buffer[0],7);
00168         TmpDev->NotRemovable            =(byte) GETBITW(Buffer[0],6);
00169         TmpDev->LogicalCylinders        =(word) Buffer[1];
00170         TmpDev->LogicalHeads            =(word) Buffer[3];
00171         TmpDev->LogicalSectorsPerTrack=(word) Buffer[6];
00172 
00173         Tmp=(word *) &(TmpDev->SerialNumber);
00174         for (i=10;i<=19;i++)
00175         {
00176                 *Tmp=SWAPBYTEW(Buffer[i]);
00177                 Tmp++;
00178         }
00179         TmpDev->SerialNumber[21]='\0';
00180         
00181 
00182         Tmp=(word *) &(TmpDev->FirmwareRev);
00183         for (i=23;i<=26;i++)
00184         {
00185                 *Tmp=SWAPBYTEW(Buffer[i]);
00186                 Tmp++;
00187         }
00188         TmpDev->FirmwareRev[9]='\0';
00189 
00190         Tmp=(word *) &(TmpDev->ModelNumber);
00191         for (i=27;i<=46;i++)
00192         {
00193                 *Tmp=SWAPBYTEW(Buffer[i]);
00194                 Tmp++;
00195         }
00196         TmpDev->ModelNumber[41]='\0';
00197 
00198         TmpDev->MaxMulitSectPerBlock    = (byte) GETBYTEW(Buffer[47],0);
00199         TmpDev->StandByTimerSupport     = (byte) GETBITW(Buffer[49],13);
00200         TmpDev->IORDYSupport            = (byte) GETBITW(Buffer[49],11);
00201         TmpDev->IORDYDisabled           = (byte) GETBITW(Buffer[49],10);        
00202         TmpDev->PioMode                 = (byte) GETBYTEW(Buffer[51],1);
00203         TmpDev->ValidUDMAMode           = (byte) GETBITW(Buffer[53],2);
00204         TmpDev->ValidCycleTime          = (byte) GETBITW(Buffer[53],1);
00205         TmpDev->ValidCurLogicalValue= (byte) GETBITW(Buffer[53],0);
00206         TmpDev->CurLogicalCylinders = (word) Buffer[54];
00207         TmpDev->CurLogicalHeads     = (word) Buffer[55];
00208         TmpDev->CurLogicalSectorsPerTrack = (word) Buffer[56];
00209         TmpDev->CapacityInSectors   = (dword) MAKEDWORDW(Buffer[58],Buffer[57]);
00210         TmpDev->ValidCurMultiSectPerInt  = (byte) GETBITW(Buffer[59],8);
00211         TmpDev->CurMultiSectPerInt  = (byte) GETBYTEW(Buffer[59],0);
00212         TmpDev->CapacityLba         = (dword) MAKEDWORDW(Buffer[61],Buffer[60]);
00213 
00214         TmpDev->MultiDMASupported = ((byte) GETBYTEW(Buffer[63],1)) & 0x07; // only 3 least sig bit
00215         TmpDev->MultiDMASelected  = ((byte) GETBYTEW(Buffer[63],0)) & 0x07; // only 3 least sig bit
00216 
00217         TmpDev->AdvPioModeSupported = (byte) GETBYTEW(Buffer[64],0);
00218         TmpDev->MinCycleTime        = (word) Buffer[65];
00219         TmpDev->RecCycleTime        = (word) Buffer[66];
00220         TmpDev->MinPioCycleTime     = (word) Buffer[67];
00221         TmpDev->MinPioCyleTimeFlow  = (word) Buffer[68];
00222         TmpDev->QueueDepth          = (byte) GETBYTEW(Buffer[75],0) & 0x1F;
00223         
00224         TmpDev->AtaSupported        = (word) Buffer[80];
00225 
00226         i=14;
00227         while ( i>0 && (GETBITW(Buffer[80],i)==0) )
00228                 i--;
00229 
00230         TmpDev->HighestAtaSupported=(byte) i;
00231 
00232         if ( Buffer[81]==0xFFFF )
00233                 TmpDev->MinorVersion    = (word) Buffer[81];
00234         else
00235                 TmpDev->MinorVersion    = (word) Buffer[81];
00236         
00237         TmpDev->SFSNopSupported            = (byte) GETBITW(Buffer[82],14);
00238         TmpDev->SFSReadBufferSupported     = (byte) GETBITW(Buffer[82],13);
00239         TmpDev->SFSWriteBufferSupported    = (byte) GETBITW(Buffer[82],12);
00240         TmpDev->SFSProtectedAreaSupported  = (byte) GETBITW(Buffer[82],10);
00241         TmpDev->SFSDeviceResetSupported    = (byte) GETBITW(Buffer[82],9);
00242         TmpDev->SFSServiceIntSupported     = (byte) GETBITW(Buffer[82],8);
00243         TmpDev->SFSReleaseIntSupported     = (byte) GETBITW(Buffer[82],7);
00244         TmpDev->SFSLookAheadSupported      = (byte) GETBITW(Buffer[82],6);
00245         TmpDev->SFSWriteCacheSupported     = (byte) GETBITW(Buffer[82],5);
00246         TmpDev->SFSPacketSupported         = (byte) GETBITW(Buffer[82],4);
00247         TmpDev->SFSPowerManagSupported     = (byte) GETBITW(Buffer[82],3);
00248         TmpDev->SFSRemovableMediaSupported = (byte) GETBITW(Buffer[82],2);
00249         TmpDev->SFSSecurityModeSupported   = (byte) GETBITW(Buffer[82],1);
00250         TmpDev->SFSSmartSupported          = (byte) GETBITW(Buffer[82],0);
00251         TmpDev->SFSRemMediaNotifSupported  = (byte) GETBITW(Buffer[83],4);
00252         TmpDev->SFSAdvPowerManagSupported  = (byte) GETBITW(Buffer[83],3);
00253         TmpDev->SFSCFASupported            = (byte) GETBITW(Buffer[83],2);
00254         TmpDev->SFSRWDmaQueuedSupported    = (byte) GETBITW(Buffer[83],1);
00255         TmpDev->SFSDownMicrocodeSupported  = (byte) GETBITW(Buffer[83],1);
00256 
00257         TmpDev->SFEServiceIntEnalbed       = (byte) GETBITW(Buffer[85],8);
00258         TmpDev->SFEReleaseIntEnabled       = (byte) GETBITW(Buffer[85],7);
00259         TmpDev->SFELookAheadEnabled        = (byte) GETBITW(Buffer[85],6);
00260         TmpDev->SFEWriteCacheEnabled       = (byte) GETBITW(Buffer[85],5);
00261         TmpDev->SFESecurityModeEnabled     = (byte) GETBITW(Buffer[85],1);
00262         TmpDev->SFESmartEnabled            = (byte) GETBITW(Buffer[85],0);
00263         TmpDev->SFERemMediaNotifEnabled    = (byte) GETBITW(Buffer[86],4);
00264         TmpDev->SFEAdvPowerManagEnabled    = (byte) GETBITW(Buffer[86],3);
00265 
00266         TmpDev->UDMASelected = ((byte) GETBYTEW(Buffer[88],1)) & 0x3F; // filtro i primi 2 bit
00267         TmpDev->UDMASupported =((byte) GETBYTEW(Buffer[88],0)) & 0x3F;
00268         
00269         i=5;
00270         while ( i>=0 && (GETBITW(Buffer[88],i)==0) )
00271                 i--;
00272 
00273         TmpDev->HighestUDMASupported=(byte) i;
00274 
00275         TmpDev->SecurityEraseTime    = (word) Buffer[89];
00276         TmpDev->SecurityEnEraseTime  = (word) Buffer[90];
00277         TmpDev->CurAPMValue          = (word) Buffer[91];
00278 
00279         TmpDev->SecurityLevel        = (byte) GETBITW(Buffer[128],8);
00280         TmpDev->SecurityEnErase      = (byte) GETBITW(Buffer[128],5);
00281         TmpDev->SecurityCountExpired = (byte) GETBITW(Buffer[128],4);
00282         TmpDev->SecurityFrozen       = (byte) GETBITW(Buffer[128],3);
00283         TmpDev->SecurityLocked       = (byte) GETBITW(Buffer[128],2);
00284         TmpDev->SecurityEnabled      = (byte) GETBITW(Buffer[128],1);
00285         TmpDev->SecuritySupported    = (byte) GETBITW(Buffer[128],0);
00286 
00287         Tmp=(word *) &(TmpDev->VendorSpecific);
00288         for (i=129;i<=159;i++)
00289         {
00290                 *Tmp=(word) Buffer[i];
00291                 Tmp++;
00292         }
00293         return 0;
00294 }
00295 
00296 
00297 void ShowDeviceDataRowName(char * Name,int Col)
00298 {
00299         kprintf(Name);
00300         gotoxy(Col,-1);
00301         kprintf("=");
00302 }
00303 
00304 
00305 void ShowDeviceDataRowValue(char * Name, int Col, char * Format, dword Value)
00306 {
00307         ShowDeviceDataRowName(Name,Col);
00308         kprintf(Format, Value);
00309 }
00310 
00311 void ShowDeviceDataRowString(char * Name, int Col, char * Value)
00312 {
00313         ShowDeviceDataRowName(Name,Col);
00314         kprintf("%s", Value);
00315 }
00316 
00317 
00318 void ShowDeviceDataRowSup(char * Name,int Col, byte Supported)
00319 {
00320         ShowDeviceDataRowName(Name,Col);
00321         kprintf("Supported:%s",Bit2YesNo(Supported));
00322 }
00323 
00324 void ShowDeviceDataRowSupEn(char * Name,int Col,byte Supported,byte Enabled)
00325 {
00326         ShowDeviceDataRowName(Name,Col);
00327         kprintf("Supported:%s",Bit2YesNo(Supported));
00328         kprintf("  -  ");
00329         kprintf("Enabled:%s",Bit2YesNo(Enabled));
00330 }
00331 
00332 void ShowDeviceDataRowBitNum(word BitCode,byte StartFrom, byte EndTo, byte StartPrintNum)
00333 {
00334         int i;
00335         byte Val=BitCode;
00336 
00337         if ( StartFrom )
00338                 Val=Val >> StartFrom;
00339 
00340         for (i=0;i<=EndTo-StartFrom;i++)
00341         {
00342                 if (Val & 0x01)
00343                         kprintf("%d  ",StartPrintNum+i);
00344                 Val=Val >> 1;
00345         }
00346 }
00347 
00348 
00349 void ShowDeviceData(int Dev,int Col)
00350 {
00351 
00352         DeviceInfo_Struct * TmpDev=(DeviceInfo_Struct *) &(CurrentChannel->Device[Dev].Info);
00353 
00354         kprintf("\n\r***** GENERAL INFORMATION *****");
00355         ShowDeviceDataRowString("\n\rModel Name",Col,TmpDev->ModelNumber);      
00356         ShowDeviceDataRowString("\n\rFirmware Revision",Col,TmpDev->FirmwareRev);
00357         ShowDeviceDataRowString("\n\rSerial Number",Col,TmpDev->SerialNumber);
00358 
00359         ShowDeviceDataRowName("\n\rType",Col);
00360         if (CurrentChannel->Device[Dev].Type==CC_DEVTYPE_ATA )
00361                 kprintf("ATA");
00362         else if (CurrentChannel->Device[Dev].Type==CC_DEVTYPE_ATAPI )
00363                 kprintf("ATAPI");
00364         else if (CurrentChannel->Device[Dev].Type==CC_DEVTYPE_UNKN )
00365                 kprintf("UNKNOW");
00366 
00367         if ( TmpDev->Removable )
00368                 kprintf(" - Removable");
00369         if ( TmpDev->NotRemovable )
00370                 kprintf(" - Not Removable");
00371 
00372 
00373         kprintf("\n\r\n\r***** STANDARD SUPPORTED AND SELECTED *****");
00374 
00375         ShowDeviceDataRowName("\n\rAta Supported",Col); 
00376         if ( (TmpDev->AtaSupported == 0x0000) || (TmpDev->AtaSupported == 0xFFFF) )
00377                 kprintf("UNKNOW");
00378         else
00379                 // bit 0 is reserved
00380                 ShowDeviceDataRowBitNum(TmpDev->AtaSupported,1,14,1);
00381 
00382         ShowDeviceDataRowName("\n\rUdma Supported",Col);        
00383         if ( TmpDev->ValidUDMAMode )
00384         {
00385                 
00386                 if ( TmpDev->UDMASupported )
00387                         // Udma star from 0
00388                         ShowDeviceDataRowBitNum((word) TmpDev->UDMASupported,0,7,0);                    
00389                 else
00390                         kprintf("NONE");
00391         }
00392         else
00393                 kprintf("UNKNOW");
00394 
00395 
00396         ShowDeviceDataRowName("\n\rUdma Selected",Col);
00397         if ( TmpDev->ValidUDMAMode )
00398         {
00399                 if ( TmpDev->UDMASelected )
00400                         ShowDeviceDataRowBitNum((word) TmpDev->UDMASelected,0,7,0);                     
00401                 else
00402                         kprintf("NONE");
00403         }
00404         else
00405                 kprintf("UNKNOW");
00406 
00407         ShowDeviceDataRowName("\n\rMultiDma Supported",Col);
00408         if ( TmpDev->MultiDMASupported )
00409                 ShowDeviceDataRowBitNum((word) TmpDev->UDMASupported,0,2,0);            
00410         else
00411                 kprintf("NONE");
00412 
00413         ShowDeviceDataRowName("\n\rMultiDma Selected",Col);
00414         if ( TmpDev->MultiDMASelected  )
00415                 ShowDeviceDataRowBitNum((word) TmpDev->UDMASelected,0,2,0);             
00416         else
00417                 kprintf("NONE");
00418 
00419 
00420         ShowDeviceDataRowValue("\n\rStandard Pio Mode",Col,"%d",TmpDev->PioMode);
00421 
00422         ShowDeviceDataRowName("\n\rAdvanced Pio Mode Supported",Col);   
00423         if ( TmpDev->AdvPioModeSupported )
00424                 ShowDeviceDataRowBitNum(TmpDev->AdvPioModeSupported,0,7,3);     
00425         else
00426                 kprintf("NONE");
00427         
00428         WaitKeyPress(MSG_PRESSKEY);     
00429 
00430         kprintf("\n\r\n\r***** DEVICE LOGICAL INFORMATION *****");
00431         ShowDeviceDataRowValue("\n\rLogical Cylinders",Col,"%u",TmpDev->LogicalCylinders);
00432         ShowDeviceDataRowValue("\n\rLogical Heads",Col,"%u",TmpDev->LogicalHeads);
00433         ShowDeviceDataRowValue("\n\rLogical Sectors",Col,"%u",TmpDev->LogicalSectorsPerTrack);
00434         if ( TmpDev->ValidCurLogicalValue )
00435         {
00436                 ShowDeviceDataRowValue("\n\rCurrent Logical Cylinders",Col, "%u",TmpDev->CurLogicalCylinders);
00437                 ShowDeviceDataRowValue("\n\rCurrent Logical Heads",Col,"%u",TmpDev->CurLogicalHeads);
00438                 ShowDeviceDataRowValue("\n\rCurrent Logical Sectors",Col,"%u",TmpDev->CurLogicalSectorsPerTrack);
00439         }
00440         else
00441         {
00442                 ShowDeviceDataRowString("\n\rCurrent Logical Cylinders",Col,"UNKNOW");
00443                 ShowDeviceDataRowString("\n\rCurrent Logical Heads",Col,"UNKNOW");
00444                 ShowDeviceDataRowString("\n\rCurrent Logical Sectors",Col,"UNKNOW");
00445         }
00446         ShowDeviceDataRowValue("\n\rCapacity Sectors Current CHS",Col,"%u",TmpDev->CapacityInSectors);
00447         ShowDeviceDataRowValue("\n\rCapacity Sectors",Col,"%u",TmpDev->CapacityLba);
00448         ShowDeviceDataRowValue("\n\rCapacity in MB",Col,"%u",TmpDev->CapacityLba / 2 / 1024);
00449 
00450         ShowDeviceDataRowSupEn("\n\rIORDY",Col,TmpDev->IORDYSupport,TmpDev->IORDYDisabled);
00451         
00452         WaitKeyPress(MSG_PRESSKEY);     
00453 
00454         kprintf("\n\r\n\r***** DEVICE FEATURES AND SETTING INFORMATION *****");
00455         ShowDeviceDataRowSup("\n\rR W Dma Queued",Col,TmpDev->SFSRWDmaQueuedSupported);
00456         ShowDeviceDataRowValue("\n\rQueue Depth",Col,"%u",TmpDev->QueueDepth);
00457         ShowDeviceDataRowValue("\n\rMax Sect Per Block (in Multi)",Col,"%u",TmpDev->MaxMulitSectPerBlock);
00458         ShowDeviceDataRowSupEn("\n\rAdv Power Management",Col,TmpDev->SFSAdvPowerManagSupported,TmpDev->SFEAdvPowerManagEnabled);
00459         ShowDeviceDataRowValue("\n\rAdv Power Management Level",Col,"%u",TmpDev->CurAPMValue);
00460 
00461         ShowDeviceDataRowSupEn("\n\rLook Ahead",Col,TmpDev->SFSLookAheadSupported,TmpDev->SFELookAheadEnabled);
00462         ShowDeviceDataRowSupEn("\n\rRelease Interrupt",Col,TmpDev->SFSReleaseIntSupported,TmpDev->SFEReleaseIntEnabled);
00463         ShowDeviceDataRowSupEn("\n\rRemovable Media Notif",Col,TmpDev->SFSRemMediaNotifSupported,TmpDev->SFERemMediaNotifEnabled);
00464         ShowDeviceDataRowSupEn("\n\rService Interrupt",Col,TmpDev->SFSServiceIntSupported,TmpDev->SFEServiceIntEnalbed);
00465         ShowDeviceDataRowSupEn("\n\rSmart",Col,TmpDev->SFSSmartSupported,TmpDev->SFESmartEnabled);
00466         ShowDeviceDataRowSupEn("\n\rWrite Cache",Col,TmpDev->SFSWriteCacheSupported,TmpDev->SFEWriteCacheEnabled);
00467         ShowDeviceDataRowSup("\n\rRead Buffer",Col,TmpDev->SFSReadBufferSupported);
00468         ShowDeviceDataRowSup("\n\rWrite Buffer",Col,TmpDev->SFSWriteBufferSupported);
00469         ShowDeviceDataRowSup("\n\rNop",Col,TmpDev->SFSNopSupported);
00470         ShowDeviceDataRowSup("\n\rPacket",Col,TmpDev->SFSPacketSupported);
00471         ShowDeviceDataRowSup("\n\rPower Management",Col,TmpDev->SFSPowerManagSupported);
00472         ShowDeviceDataRowSup("\n\rProtected Area",Col,TmpDev->SFSProtectedAreaSupported);
00473         ShowDeviceDataRowSup("\n\rDownload Microcode",Col,TmpDev->SFSDownMicrocodeSupported);
00474         ShowDeviceDataRowSup("\n\rCFA",Col,TmpDev->SFSCFASupported);
00475         ShowDeviceDataRowSup("\n\rDevice Reset",Col,TmpDev->SFSDeviceResetSupported);
00476         ShowDeviceDataRowSup("\n\rStandBy Timer",Col,TmpDev->StandByTimerSupport);
00477 
00478         WaitKeyPress(MSG_PRESSKEY);     
00479 
00480 
00481         kprintf("\n\r\n\r***** DEVICE TIMING INFORMATION *****");
00482         ShowDeviceDataRowSup("\n\rStandBy Timer",Col,TmpDev->StandByTimerSupport);
00483         
00484         if (TmpDev->ValidCycleTime )
00485         {
00486                 ShowDeviceDataRowValue("\n\rMin Multi Dma Cycle Time (ns)",Col,"%u",TmpDev->MinCycleTime);
00487                 ShowDeviceDataRowValue("\n\rRecc MultiDma Cycle Time (ns)",Col,"%u",TmpDev->RecCycleTime);
00488                 ShowDeviceDataRowValue("\n\rMin Pio Cycle Time (ns)",Col,"%u",TmpDev->MinPioCycleTime);
00489                 ShowDeviceDataRowValue("\n\rMin Pio Cycle Time Flow (ns)",Col,"%u",TmpDev->MinPioCyleTimeFlow);
00490         }
00491         else
00492         {
00493                 kprintf("\n\rTiming Information Unavaiable");
00494         }
00495 
00496         kprintf("\n\r\n\r***** SECURITY INFORMATION *****");
00497         ShowDeviceDataRowSupEn("\n\rSecurity",Col,TmpDev->SecuritySupported,TmpDev->SecurityEnabled);
00498         ShowDeviceDataRowSupEn("\n\rSecurity Mode",Col,TmpDev->SFSSecurityModeSupported,TmpDev->SFESecurityModeEnabled);
00499         ShowDeviceDataRowValue("\n\rSecurity Erase Time (min)",Col,"%u",(int) TmpDev->SecurityEraseTime*2);
00500         ShowDeviceDataRowValue("\n\rEnh Security Erase Time (min)",Col,"%u",(int) TmpDev->SecurityEnEraseTime*2);
00501         
00502         ShowDeviceDataRowName("\n\rSecurity Level",Col);        
00503         if ( TmpDev->SFESecurityModeEnabled )
00504         {
00505                 if (TmpDev->SecurityLevel)
00506                         kprintf("Max");
00507                 else
00508                         kprintf("High");
00509         }
00510         else
00511         {
00512                 kprintf("Disabled");
00513         }
00514 
00515         ShowDeviceDataRowString("\n\rSecurity Frozen",Col,Bit2YesNo(TmpDev->SecurityFrozen));
00516         kprintf("\n\rSecurity CountExpired");
00517         gotoxy(Col,-1);
00518         kprintf("=%s",Bit2YesNo(TmpDev->SecurityCountExpired));
00519         kprintf("\n\rSecurity Locked");
00520         gotoxy(Col,-1);
00521         kprintf("=%s",Bit2YesNo(TmpDev->SecurityLocked));
00522         ShowDeviceDataRowSup("\n\rSecurity Enh Erase Supported",Col,TmpDev->SecurityEnErase);
00523 
00524         kprintf("\n\r\n\r END DEVICE INFORMATION \n\r");
00525 }
00526 
00527 
00528 
00529 // ************************ InitIde *************************
00530 // Initialization of the driver.
00531 // Prepare data structure, check fo device on each channel
00532 // and fill structure with channel and device info
00533 // **********************************************************
00534 void InitIde()
00535 {
00536         extern void Ide_Handler_Pri, Ide_Handler_Sec;
00537 
00538         // --- modified by: Andrea Righi -------------------------------//
00539         // Install the IRQ handlers for both IDE channels               //
00540         install_irq_handler(IDEP_IRQ, &Ide_Handler_Pri);
00541         install_irq_handler(IDES_IRQ, &Ide_Handler_Sec);
00542         // -------------------------------------------------------------//
00543 
00544         // Initialize structure for primary channel
00545         SelectAtaChannel(CC_PRIMARY);
00546         SetAtaRegisterIoPort(HDC_BASEPRI,HDC_BASEPRI+HDC_CONTROLGAP,HDC_INTPRI);
00547 
00548         // Initialize devices
00549         ScanDevice(TRUE);
00550         if ( CurrentChannel->Device[CC_DEV0].Type==CC_DEVTYPE_ATA )
00551                 IdentifyDevice(CC_DEV0);
00552         if ( CurrentChannel->Device[CC_DEV1].Type==CC_DEVTYPE_ATA )
00553                 IdentifyDevice(CC_DEV1);
00554 
00555         // Initialize structure for secondary channel
00556         SelectAtaChannel(CC_SECONDARY);
00557         SetAtaRegisterIoPort(HDC_BASESEC,HDC_BASESEC+HDC_CONTROLGAP,HDC_INTSEC);
00558 
00559         // Initialize devices
00560         ScanDevice(TRUE);
00561         if ( CurrentChannel->Device[CC_DEV0].Type==CC_DEVTYPE_ATA )
00562                 IdentifyDevice(CC_DEV0);
00563         if ( CurrentChannel->Device[CC_DEV1].Type==CC_DEVTYPE_ATA )
00564                 IdentifyDevice(CC_DEV1);
00565 }
00566 
00567 
00568 
00569 // ******************** ReadSectorsLba **********************
00570 // Read one or more sector of data from hd
00571 // **********************************************************
00572 int ReadSectorsLba(int Dev, uint64 Lba, int NumSect, word * Buffer,int UseInterrupt)
00573 {
00574 
00575         // kprintf("\n\rReadSectorLba: Dev=%d,Lba=%i,NumSect=%i,UseInt=%i",Dev,(int) Lba,NumSect,UseInterrupt);
00576         return IdePioDataInLba(Dev,HDC_CMD_READ_SECTORS,0,NumSect,Lba,Buffer,NumSect,1,UseInterrupt);
00577 }
00578 
00579 // ******************** WriteSectorsLba *********************
00580 // Write one or more sector of data from hd
00581 // **********************************************************
00582 int WriteSectorsLba(int Dev, uint64 Lba, int NumSect, word * Buffer,int UseInterrupt)
00583 {
00584         return IdePioDataOutLba(Dev,HDC_CMD_WRITE_SECTORS,0,NumSect,Lba,Buffer,NumSect,1,UseInterrupt);
00585 }
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 // **********************************************************************
00601 // **********************************************************************
00602 // The next section is under construction and must no be used
00603 // This is not beta nor alpha sub but very very very incomplete code
00604 // Don't try to execute - it can damage your computer
00605 // **********************************************************************
00606 // **********************************************************************
00607 
00608 // UNDER CONSTRUCTION
00609 //See SFF-8038-r01  o Idems100 (Bus Master Programming Interface 1.0)
00610 /*
00611 
00612 int PciConfig(dword RegAddr)
00613 {
00614         // dword Off;
00615         // dword Seg;
00616         // uint64 Lw;
00617 
00618         kprintf("\n\rPCI CONFIG");
00619         // check reg address
00620 
00621         if ( RegAddr & 0x0007 )          // error if regs addr
00622         {
00623                 kprintf("->RegAddress Error");
00624                 return 1;                  // are not xxx0h or xxx8h
00625         }
00626 
00627         // save the address of the bus master (SFF-8038) regs
00628 
00629         //dma_pci_sff_reg_addr = busMasterRegs = regAddr;
00630         BusMaster.BaseAddress=RegAddr;
00631         // disable if reg address is zero
00632 
00633         if ( ! RegAddr )              // if zero,
00634         {
00635                 kprintf("->RegAddr Zero");
00636                 return 0;                  // PCI DMA is disabled.
00637         }
00638 
00639         // the bus master must be setup now
00640 
00641         
00642 
00643         if ( !( inportb( BusMaster.BaseAddress  + BM_STATUS_REG ) &
00644                         ( BM_SR_MASK_DRV1 | BM_SR_MASK_DRV0 ) ) )
00645    {
00646                 kprintf("->DRIVES CAN'T DO DMA");
00647                 return 2;
00648    }
00649 
00650    // set up the PRD buffer address
00651 
00652    seg = FP_SEG( (unsigned char far *) prdBuf );
00653    off = FP_OFF( (unsigned char far *) prdBuf );
00654    off = off + 16;
00655    off = off >> 4;
00656    seg = seg + off;
00657    dma_pci_prd_addr = seg;
00658    prdBufPtr = MK_FP( seg, 0 );
00659    lw = seg;
00660    lw = lw << 4;
00661    prdBufPtrLow16 = (unsigned int) ( lw & 0x0000ffffL );
00662    prdBufPtrHigh16 = (unsigned int) ( ( lw & 0xffff0000L ) >> 16 );
00663 
00664         Seg=SEGMENT( (byte *) BusMaster.PrdBuf );
00665         Off=OFFSET( (byte *) BusMaster.PrdBuf );
00666         Off=(Off + 16) >> 4;
00667         Seg=Seg + Off;
00668         BusMaster.DmaPciPrdAddr=Seg;
00669         BusMaster.PrdBufPtr=LINEAR(Seg,0);
00670         Lw=Seg << 4;
00671         BusMaster.PrdBufPtrLow  = (dword) ( Lw & 0x0000ffffL );
00672         BusMaster.PrdBufPtrHigh = (dword) ( ( Lw & 0xffff0000L ) >> 16 );
00673 
00674    //  DEVO FARE UN POP DAL FRAME PERCHE IL DMA VEDE SOLO I PRIMI 16 MB
00675    //  USO POI PHYSICAL E PRENDO LA PARTE ALTA E BASSA
00676 
00677 
00678 
00679 
00680    // read the BM status reg and save the upper 3 bits.
00681 
00682         BusMaster.StatReg = inportb( BusMaster.BaseAddress + BM_STATUS_REG );
00683         BusMaster.StatReg = BusMaster.StatReg & 0xe0;
00684 
00685    return 0;
00686 }
00687 
00688 */
00689 
00690 /*
00691 // UNDER CONSTRUCTION
00692  int DmaPciAtaLba( int Dev, int Cmd,
00693                             int Feat, int SecC,
00694                             uint64 Lba,
00695                             unsigned Seg, unsigned Off )
00696 {
00697    dword Cyl;
00698    int Head, Sect;
00699 
00700    Sect = (int) ( Lba & 0x000000FFL );
00701    Lba = Lba >> 8;
00702    Cyl = (int) ( Lba & 0x0000FFFFL );
00703    Lba = Lba >> 16;
00704    Head = ( (int) ( Lba & 0x0FL ) ) | 0x40;
00705 
00706    return DmaPciAta( Dev, Cmd,
00707                        Feat, SecC,
00708                        Cyl, Head, Sect,
00709                        Seg, Off );
00710 }
00711 
00712 void EnableChanPci()
00713 {
00714         OutPortPci( BM_COMMAND_REG, BusMaster.RWControl | BM_CR_MASK_START );
00715 }
00716 void DisableChanPci()
00717 {
00718         OutPortPci( BM_COMMAND_REG, BM_CR_MASK_STOP );
00719 }
00720 void ClearChanPci()
00721 {
00722         OutPortPci( BM_STATUS_REG, BusMaster.StatReg | BM_SR_MASK_INT | BM_SR_MASK_ERR );
00723 }
00724 
00725 void OutPortPci(word Port, byte Val)
00726 {
00727         outportb( BusMaster.BaseAddress + Port,Val );
00728 }
00729 
00730 byte InPortPci(word Port)
00731 {
00732         return inportb( Port );
00733 }
00734 
00735 */
00736 
00737 /*
00738 // UNDER CONSTRUCTION
00739 int DmaPciAta( int Dev, int Cmd,
00740                  int Feat, int SecC,
00741                  dword Cyl, int Head, int Sect,
00742                  unsigned Seg, unsigned Off )
00743 
00744 {
00745    byte DevHead;
00746    byte DevCtrl;
00747    byte CylLow;
00748    byte CylHigh;
00749    byte Status;
00750    int ns;
00751    int Err=0;
00752 
00753    // setup register values
00754 
00755    DevCtrl = 0;      // in the old days we would set CB_DC_HD15 = 1
00756    DevHead = CurrentChannel->Device[Dev].RegBit;
00757    DevHead = DevHead | ( Head & 0x4F );
00758    CylLow = Cyl & 0x00FF;
00759    CylHigh = ( Cyl & 0xFF00 ) >> 8;
00760 
00761    // Quit now if the command is incorrect.
00762 
00763    if ( ( Cmd != HDC_CMD_READ_DMA ) && ( Cmd != HDC_CMD_WRITE_DMA ) )
00764    {
00765       return 1;
00766    }
00767 
00768    // Quit now if no dma channel set up.
00769 
00770    if ( ! BusMaster.BaseAddress  )
00771    {
00772       return 1;
00773    }
00774 
00775    // set up the dma transfer
00776 
00777    ns = SecC;
00778    if ( ! ns )
00779       ns = 256;
00780    SetUpXfer( Cmd == HDC_CMD_WRITE_DMA, ns * 512L, Seg, Off );
00781 
00782    // Set command time out.
00783 
00784    TimerStart(HDC_ATATIMEOUT);
00785 
00786    // Select the drive - call the sub_select function.
00787    // Quit now if this fails.
00788 
00789    if ( IdeDeviceSelection( Dev ) )
00790    {
00791       return 1;
00792    }
00793 
00794    // Set up all the registers except the command register.
00795 
00796    OutPortAta( CC_DEVC, DevCtrl );
00797    OutPortAta( CC_FEAT, Feat );
00798    OutPortAta( CC_SECC, SecC );
00799    OutPortAta( CC_SECN, Sect );
00800    OutPortAta( CC_CYLL, CylLow );
00801    OutPortAta( CC_CYLH, CylHigh );
00802    OutPortAta( CC_DEVH, DevHead );
00803 
00804    // For interrupt mode,
00805    // Take over INT 7x and initialize interrupt controller
00806    // and reset interrupt flag.
00807 
00808    //int_save_int_vect();
00809 
00810    // Start the command by setting the Command register.  The drive
00811    // should immediately set BUSY status.
00812 
00813    OutPortAta( CC_CMD, Cmd );
00814 
00815    // Waste some time by reading the alternate status a few times.
00816    // This gives the drive time to set BUSY in the status register on
00817    // really fast systems.  If we don't do this, a slow drive on a fast
00818    // system may not set BUSY fast enough and we would think it had
00819    // completed the command when it really had not even started the
00820    // command yet.
00821 
00822    DELAY400NS;
00823 
00824    // enable/start the dma channel.
00825 
00826    //trc_llt( 0, 0, TRC_LLT_DMA1 );
00827    EnableChanPci();
00828 
00829    // Data transfer...
00830    // the device and dma channel transfer the data here while we start
00831    // checking for command completion...
00832 
00833    // End of command...
00834    // if no error,
00835    // wait for drive to signal command completion
00836    // -or-
00837    // time out if this takes to long.
00838 
00839    Err=WaitForInt();
00840 
00841 
00842    // End of command...
00843    // now wait for the PCI BM DMA channel to flush the data.
00844 
00845    while ( 1 )
00846    {
00847           
00848       if ( ( inportb( BusMaster.BaseAddress + BM_STATUS_REG )
00849              & BM_SR_MASK_INT )
00850          )                                // done yet ?
00851          break;                           // yes
00852       if ( TimerElapsed() )            // time out yet ?
00853       {
00854          
00855          break;
00856       }
00857    }
00858 
00859    #if 0
00860    trc_llt( 0,
00861             inportb( busMasterRegs + BM_STATUS_REG ),
00862             TRC_LLT_DEBUG );     // for debugging
00863    #endif
00864 
00865    // End of command...
00866    // disable/stop the dma channel
00867 
00868    // trc_llt( 0, 0, TRC_LLT_DMA3 );
00869    DisableChanPci();
00870 
00871    // End of command...
00872    // Read the primary status register.  In keeping with the rules
00873    // stated above the primary status register is read only
00874    // ONCE.
00875 
00876    Status = InPortAta( CC_STAT );
00877 
00878    // Final status check...
00879    // if no error, check final status...
00880    // Error if BUSY, DEVICE FAULT, DRQ or ERROR status now.
00881 
00882     if ( reg_cmd_info.ec == 0 )
00883    {
00884       if ( Status & ( CB_STAT_BSY | CB_STAT_DF | CB_STAT_DRQ | CB_STAT_ERR ) )
00885       {
00886          reg_cmd_info.ec = 74;
00887          trc_llt( 0, reg_cmd_info.ec, TRC_LLT_ERROR );
00888       }
00889    }
00890 
00891    // Final status check...
00892    // if no error, check make sure the device asserted the INTRQ signal.
00893 
00894    if ( ( reg_cmd_info.ec == 0 )
00895         &&
00896         ( ( inportb( busMasterRegs + BM_STATUS_REG ) & BM_SR_MASK_INT ) == 0 )
00897       )
00898    {
00899       reg_cmd_info.ec = 71;
00900       trc_llt( 0, reg_cmd_info.ec, TRC_LLT_ERROR );
00901    }
00902 
00903    // Final status check...
00904    // if any error, update total bytes transferred.
00905 
00906    if ( reg_cmd_info.ec == 0 )
00907       reg_cmd_info.totalBytesXfer = ns * 512L;
00908    else
00909       reg_cmd_info.totalBytesXfer = 0L;
00910 
00911    // Done...
00912    // Read the output registers and trace the command.
00913 
00914    //sub_trace_command();
00915 
00916    // Done...
00917    // For interrupt mode, restore the INT 7x vector.
00918 
00919    //int_restore_int_vect();
00920 
00921    // Done...
00922    // mark end of a R/W DMA command in low level trace
00923 
00924    //trc_llt( 0, 0, TRC_LLT_E_RWD );
00925 
00926    // All done.  The return values of this function are described in
00927    // ATAIO.H.
00928 
00929    if ( reg_cmd_info.ec )
00930       return 1;
00931    return 0;
00932 }
00933 */
00934 
00935 /*
00936 // UNDER CONSTRUCTION
00937 void SetUpXfer( int dir, long count, unsigned seg, unsigned off )
00938 
00939 {
00940 
00941    int numPrd;             // number of PRD required
00942    uint64 addr;     // physical memory address
00943    uint64 addr1;    // physical address for 1st prd area
00944    uint64 addr2;    // physical address for 2nd prd area
00945    uint64 addr3;    // physical address for 3rd prd area
00946    int64 count1;            // byte count for 1st prd area
00947    int64 count2;            // byte count for 2nd prd area
00948    int64 count3;            // byte count for 3nd prd area
00949    int64 temp;
00950    uint64 * lwp;
00951 
00952    // disable/stop the dma channel, clear interrupt and error bits
00953 
00954    //trc_llt( 0, 0, TRC_LLT_DMA3 );
00955    DisableChanPci();
00956    ClearChanPci();
00957 
00958    // convert transfer address from seg:off to an absolute memory address
00959 
00960    addr = (unsigned long) seg;
00961    addr = addr << 4;
00962    addr = addr + (unsigned long) off;
00963 
00964    // the address for each prd is easy to compute.
00965    // note: the address must be an even number but that
00966    //       is not checked here.
00967 
00968    addr1 = addr;
00969    addr2 = ( addr1 & 0xffff0000L ) + 0x00010000L;
00970    addr3 = ( addr2 & 0xffff0000L ) + 0x00010000L;
00971 
00972    // set up the 1st, 2nd and 3rd prd's as required.
00973    // note: count must be an even number but that is
00974    //       not checked here!
00975 
00976    numPrd = 1;                      // assume only 1 prd
00977    count1 = count;
00978    count2 = 0L;
00979    count3 = 0L;
00980    temp = addr2 - addr1;            // size of 1st prd area
00981    if ( count > temp )              // does it fit?
00982    {
00983       count = count - temp;         // no...
00984       numPrd = 2;                   // need 2 prd
00985       count1 = temp;
00986       count2 = count;
00987       temp = addr3 - addr2;         // size of 2nd prd area
00988       if ( count > temp )           // does it fit?
00989       {
00990          count = count - temp;      // no...
00991          numPrd = 3;                // need 3 prd
00992          count2 = temp;
00993          count3 = count;
00994       }
00995    }
00996 
00997    // set the end bit in the prd list
00998 
00999    if ( numPrd == 3 )
01000       count3 = count3 | 0x80000000L;
01001    else
01002    if ( numPrd == 2 )
01003       count2 = count2 | 0x80000000L;
01004    else
01005       count1 = count1 | 0x80000000L;
01006 
01007    // build the prd list in the prd buffer
01008 
01009    lwp = prdBufPtr;
01010    * lwp = addr1;
01011    lwp ++ ;
01012    * lwp = count1 & 0x8000ffffL;
01013    lwp ++ ;
01014    * lwp = addr2;
01015    lwp ++ ;
01016    * lwp = count2 & 0x8000ffffL;
01017    lwp ++ ;
01018    * lwp = addr3;
01019    lwp ++ ;
01020    * lwp = count3 & 0x8000ffffL;
01021 
01022    // set the prd list address
01023 
01024    OutPortPci( BM_PRD_ADDR_LOW, prdBufPtrLow16 );
01025    OutPortPci( BM_PRD_ADDR_HIGH, prdBufPtrHigh16 );
01026 
01027    // set the read/write control:
01028    // PCI reads for ATA Write DMA commands,
01029    // PCI writes for ATA Read DMA commands.
01030 
01031    if ( dir )
01032       BusMaster.RWControl = BM_CR_MASK_READ;     // ATA Write DMA
01033    else
01034       BusMaster.RWControl = BM_CR_MASK_WRITE;    // ATA Read DMA
01035    OutPortPci( BM_COMMAND_REG, BusMaster.RWControl );
01036 }
01037 */
01038 
01039 
01040 

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