1 #ifndef ATA_PRIVATE_H 2 #define ATA_PRIVATE_H 3 4 #include <ata_types.h> 5 #include <bus/ATA.h> 6 #include <bus/SCSI.h> 7 #include <device_manager.h> 8 #include <lock.h> 9 #include <new> 10 #include <safemode.h> 11 #include <scsi_cmds.h> 12 #include <stdio.h> 13 #include <string.h> 14 #include <util/AutoLock.h> 15 16 #include "ATACommands.h" 17 #include "ATATracing.h" 18 #include "ata_device_infoblock.h" 19 20 #define ATA_STANDARD_TIMEOUT 10 * 1000 * 1000 21 #define ATA_RELEASE_TIMEOUT 10 * 1000 * 1000 22 #define ATA_SIGNATURE_ATAPI 0xeb140101 23 #define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1" 24 #define ATA_CHANNEL_ID_GENERATOR "ata/channel_id" 25 #define ATA_CHANNEL_ID_ITEM "ata/channel_id" 26 27 enum { 28 ATA_DEVICE_READY_REQUIRED = 0x01, 29 ATA_IS_WRITE = 0x02, 30 ATA_DMA_TRANSFER = 0x03, 31 ATA_CHECK_ERROR_BIT = 0x04, 32 ATA_WAIT_FINISH = 0x08, 33 ATA_WAIT_ANY_BIT = 0x10 34 }; 35 36 37 class ATADevice; 38 class ATARequest; 39 40 extern scsi_for_sim_interface *gSCSIModule; 41 extern device_manager_info *gDeviceManager; 42 43 bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, 44 void *buffer, int size, bool toBuffer); 45 46 class ATAChannel { 47 public: 48 ATAChannel(device_node *node); 49 ~ATAChannel(); 50 51 status_t InitCheck(); 52 uint32 ChannelID() { return fChannelID; }; 53 54 // SCSI stuff 55 void SetBus(scsi_bus bus); 56 scsi_bus Bus() { return fSCSIBus; }; 57 status_t ScanBus(); 58 59 void PathInquiry(scsi_path_inquiry *info); 60 void GetRestrictions(uint8 targetID, 61 bool *isATAPI, bool *noAutoSense, 62 uint32 *maxBlocks); 63 status_t ExecuteIO(scsi_ccb *ccb); 64 65 // ATA stuff 66 status_t SelectDevice(uint8 index); 67 bool IsDevicePresent(uint8 index); 68 69 status_t Reset(bool *presence, uint32 *signatures); 70 71 bool UseDMA() { return fUseDMA; }; 72 73 status_t Wait(uint8 setBits, uint8 clearedBits, 74 uint32 flags, bigtime_t timeout); 75 status_t WaitDataRequest(bool high); 76 status_t WaitDeviceReady(); 77 status_t WaitForIdle(); 78 79 // request handling 80 status_t SendRequest(ATARequest *request, 81 uint32 flags); 82 status_t FinishRequest(ATARequest *request, 83 uint32 flags, uint8 errorMask); 84 85 // data transfers 86 status_t ExecuteDMATransfer(ATARequest *request); 87 status_t ExecutePIOTransfer(ATARequest *request); 88 89 status_t ReadPIO(uint8 *buffer, size_t length); 90 91 private: 92 status_t _ReadRegs(ata_task_file *taskFile, 93 ata_reg_mask mask); 94 status_t _WriteRegs(ata_task_file *taskFile, 95 ata_reg_mask mask); 96 status_t _WriteControl(uint8 value); 97 98 uint8 _AltStatus(); 99 void _FlushAndWait(bigtime_t waitTime); 100 101 status_t _ReadPIOBlock(ATARequest *request, 102 size_t length); 103 status_t _WritePIOBlock(ATARequest *request, 104 size_t length); 105 status_t _TransferPIOBlock(ATARequest *request, 106 size_t length, size_t *transferred); 107 status_t _TransferPIOPhysical(ATARequest *request, 108 addr_t physicalAddress, size_t length, 109 size_t *transferred); 110 status_t _TransferPIOVirtual(ATARequest *request, 111 uint8 *virtualAddress, size_t length, 112 size_t *transferred); 113 114 const char * _DebugContext() { return fDebugContext; }; 115 116 device_node * fNode; 117 uint32 fChannelID; 118 ata_controller_interface * fController; 119 void * fCookie; 120 mutex fLock; 121 status_t fStatus; 122 scsi_bus fSCSIBus; 123 uint8 fDeviceCount; 124 ATADevice ** fDevices; 125 bool fUseDMA; 126 ATARequest * fRequest; 127 128 char fDebugContext[16]; 129 }; 130 131 132 class ATADevice { 133 public: 134 ATADevice(ATAChannel *channel, 135 uint8 index); 136 virtual ~ATADevice(); 137 138 // SCSI stuff 139 status_t ModeSense(ATARequest *request); 140 status_t TestUnitReady(ATARequest *request); 141 status_t SynchronizeCache(ATARequest *request); 142 status_t Eject(ATARequest *request); 143 status_t Inquiry(ATARequest *request); 144 status_t ReadCapacity(ATARequest *request); 145 virtual status_t ExecuteIO(ATARequest *request); 146 147 // ATA stuff 148 virtual bool IsATAPI() { return false; }; 149 150 bool UseDMA() { return fUseDMA; }; 151 bool UseLBA() { return fUseLBA; }; 152 bool Use48Bits() { return fUse48Bits; }; 153 154 status_t Select(); 155 156 ata_task_file * TaskFile() { return &fTaskFile; }; 157 ata_reg_mask RegisterMask() { return fRegisterMask; }; 158 159 status_t SetFeature(int feature); 160 status_t DisableCommandQueueing(); 161 status_t ConfigureDMA(); 162 163 status_t Configure(); 164 status_t Identify(); 165 166 status_t ExecuteReadWrite(ATARequest *request, 167 uint64 address, uint32 sectorCount); 168 169 private: 170 status_t _FillTaskFile(ATARequest *request, 171 uint64 address); 172 173 status_t _PrepareDMA(ATARequest *request); 174 status_t _PreparePIO(ATARequest *request); 175 176 const char * _DebugContext() { return fDebugContext; }; 177 178 ATAChannel * fChannel; 179 uint8 fIndex; 180 bool fUseLBA; 181 bool fUse48Bits; 182 bool fUseDMA; 183 uint64 fTotalSectors; 184 ata_device_infoblock fInfoBlock; 185 ata_task_file fTaskFile; 186 ata_reg_mask fRegisterMask; 187 188 char fDebugContext[16]; 189 }; 190 191 192 class ATAPIDevice : public ATADevice { 193 public: 194 ATAPIDevice(ATAChannel *channel, 195 uint8 index); 196 virtual ~ATAPIDevice(); 197 198 virtual status_t ExecuteIO(ATARequest *request); 199 200 virtual bool IsATAPI() { return true; }; 201 202 private: 203 uint8 fLastLun; 204 }; 205 206 207 class ATARequest { 208 public: 209 ATARequest(); 210 211 void SetStatus(uint8 status); 212 uint8 Status() { return fStatus; }; 213 214 void ClearSense(); 215 void SetSense(uint8 key, uint16 codeQualifier); 216 uint8 SenseKey() { return fSenseKey; }; 217 uint8 SenseCode() { return fSenseCode; }; 218 uint8 SenseQualifier() { return fSenseQualifier; }; 219 220 void SetDevice(ATADevice *device); 221 ATADevice * Device() { return fDevice; }; 222 223 void SetTimeout(bigtime_t timeout); 224 bigtime_t Timeout() { return fTimeout; }; 225 226 void SetIsWrite(bool isWrite); 227 bool IsWrite() { return fIsWrite; }; 228 229 void SetUseDMA(bool useDMA); 230 bool UseDMA() { return fUseDMA; }; 231 232 void SetBlocksLeft(uint32 blocksLeft); 233 uint32 * BlocksLeft() { return &fBlocksLeft; }; 234 235 status_t Finish(bool resubmit); 236 237 // SCSI stuff 238 void SetCCB(scsi_ccb *ccb); 239 scsi_ccb * CCB() { return fCCB; }; 240 241 void PrepareSGInfo(); 242 void AdvanceSG(uint32 bytes); 243 244 uint32 SGElementsLeft() 245 { return fSGElementsLeft; }; 246 const physical_entry * CurrentSGElement() 247 { return fCurrentSGElement; }; 248 uint32 CurrentSGOffset() 249 { return fCurrentSGOffset; }; 250 251 void SetOddByte(uint8 byte); 252 bool GetOddByte(uint8 *byte); 253 254 void RequestSense(); 255 256 private: 257 void _FillSense(scsi_sense *sense); 258 259 const char * _DebugContext() { return " request"; }; 260 261 uint8 fStatus; 262 uint8 fSenseKey; 263 uint8 fSenseCode; 264 uint8 fSenseQualifier; 265 266 ATADevice * fDevice; 267 bigtime_t fTimeout; 268 uint32 fBlocksLeft; 269 bool fIsWrite; 270 bool fUseDMA; 271 scsi_ccb * fCCB; 272 273 uint32 fSGElementsLeft; 274 const physical_entry * fCurrentSGElement; 275 uint32 fCurrentSGOffset; 276 bool fHasOddByte; 277 uint8 fOddByte; 278 }; 279 280 #endif // ATA_PRIVATE_H 281