1 /* 2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. 3 * Copyright 2008, Marcus Overhagen. 4 * Copyright 2004-2010, Axel Dörfler, axeld@pinc-software.de. 5 * Copyright 2002-2003, Thomas Kurschel. 6 * 7 * Distributed under the terms of the MIT License. 8 */ 9 #ifndef ATA_PRIVATE_H 10 #define ATA_PRIVATE_H 11 12 13 #include <ata_types.h> 14 #include <bus/ATA.h> 15 #include <bus/SCSI.h> 16 #include <condition_variable.h> 17 #include <device_manager.h> 18 #include <lock.h> 19 #include <new> 20 #include <safemode.h> 21 #include <scsi_cmds.h> 22 #include <stdio.h> 23 #include <string.h> 24 #include <util/AutoLock.h> 25 26 #include "ATACommands.h" 27 #include "ATAInfoBlock.h" 28 #include "ATATracing.h" 29 30 31 #define ATA_MAX_DMA_FAILURES 3 32 #define ATA_STANDARD_TIMEOUT 10 * 1000 * 1000 33 #define ATA_RELEASE_TIMEOUT 10 * 1000 * 1000 34 #define ATA_SIGNATURE_ATA 0x0000 35 #define ATA_SIGNATURE_ATAPI 0xeb14 36 #define ATA_SIGNATURE_SATA 0xc33c 37 #define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1" 38 #define ATA_CHANNEL_ID_GENERATOR "ide/channel_id" 39 #define ATA_CHANNEL_ID_ITEM "ide/channel_id" 40 41 enum { 42 ATA_DEVICE_READY_REQUIRED = 0x01, 43 ATA_IS_WRITE = 0x02, 44 ATA_DMA_TRANSFER = 0x04, 45 ATA_CHECK_ERROR_BIT = 0x08, 46 ATA_WAIT_FINISH = 0x10, 47 ATA_WAIT_ANY_BIT = 0x20, 48 ATA_CHECK_DEVICE_FAULT = 0x40 49 }; 50 51 52 class ATADevice; 53 class ATARequest; 54 55 extern scsi_for_sim_interface *gSCSIModule; 56 extern device_manager_info *gDeviceManager; 57 58 bool copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength, 59 void *buffer, int size, bool toBuffer); 60 void swap_words(void *data, size_t size); 61 62 63 class ATAChannel { 64 public: 65 ATAChannel(device_node *node); 66 ~ATAChannel(); 67 68 status_t InitCheck(); ChannelID()69 uint32 ChannelID() const { return fChannelID; } 70 71 // SCSI stuff 72 void SetBus(scsi_bus bus); Bus()73 scsi_bus Bus() const { return fSCSIBus; } 74 status_t ScanBus(); 75 76 void PathInquiry(scsi_path_inquiry *info); 77 void GetRestrictions(uint8 targetID, bool *isATAPI, 78 bool *noAutoSense, uint32 *maxBlocks); 79 status_t ExecuteIO(scsi_ccb *ccb); 80 status_t Control(uint8 targetID, uint32 op, void *buffer, 81 size_t length); 82 83 // ATA stuff 84 status_t SelectDevice(uint8 index); 85 uint8 SelectedDevice(); 86 87 status_t Reset(); 88 UseDMA()89 bool UseDMA() const { return fUseDMA; } 90 91 status_t Wait(uint8 setBits, uint8 clearedBits, 92 uint32 flags, bigtime_t timeout); 93 status_t WaitDataRequest(bool high); 94 status_t WaitDeviceReady(); 95 status_t WaitForIdle(); 96 97 void PrepareWaitingForInterrupt(); 98 status_t WaitForInterrupt(bigtime_t timeout); 99 status_t RecoverLostInterrupt(); 100 101 // request handling 102 status_t SendRequest(ATARequest *request, uint32 flags); 103 status_t FinishRequest(ATARequest *request, uint32 flags, 104 uint8 errorMask); 105 106 // data transfers 107 status_t PrepareDMA(ATARequest *request); 108 status_t StartDMA(); 109 status_t FinishDMA(); 110 111 status_t ExecutePIOTransfer(ATARequest *request); 112 113 status_t ReadRegs(ATADevice *device); 114 uint8 AltStatus(); 115 116 status_t ReadPIO(uint8 *buffer, size_t length); 117 status_t WritePIO(uint8 *buffer, size_t length); 118 119 status_t Interrupt(uint8 status); 120 121 private: 122 status_t _ReadRegs(ata_task_file *taskFile, 123 ata_reg_mask mask); 124 status_t _WriteRegs(ata_task_file *taskFile, 125 ata_reg_mask mask); 126 status_t _WriteControl(uint8 value); 127 uint8 _Status(); 128 129 void _FlushAndWait(bigtime_t waitTime); 130 131 bool _DevicePresent(int device); 132 133 status_t _ReadPIOBlock(ATARequest *request, 134 size_t length); 135 status_t _WritePIOBlock(ATARequest *request, 136 size_t length); 137 status_t _TransferPIOBlock(ATARequest *request, 138 size_t length, size_t *transferred); 139 status_t _TransferPIOPhysical(ATARequest *request, 140 addr_t physicalAddress, size_t length, 141 size_t *transferred); 142 status_t _TransferPIOVirtual(ATARequest *request, 143 uint8 *virtualAddress, size_t length, 144 size_t *transferred); 145 _DebugContext()146 const char * _DebugContext() { return fDebugContext; } 147 148 private: 149 device_node * fNode; 150 uint32 fChannelID; 151 ata_controller_interface *fController; 152 void * fCookie; 153 154 spinlock fInterruptLock; 155 ConditionVariable fInterruptCondition; 156 ConditionVariableEntry fInterruptConditionEntry; 157 bool fExpectsInterrupt; 158 159 status_t fStatus; 160 scsi_bus fSCSIBus; 161 uint8 fDeviceCount; 162 ATADevice ** fDevices; 163 bool fUseDMA; 164 ATARequest * fRequest; 165 166 char fDebugContext[16]; 167 }; 168 169 170 class ATADevice { 171 public: 172 ATADevice(ATAChannel *channel, uint8 index); 173 virtual ~ATADevice(); 174 175 // SCSI stuff 176 status_t ModeSense(ATARequest *request); 177 status_t TestUnitReady(ATARequest *request); 178 status_t SynchronizeCache(ATARequest *request); 179 status_t Eject(ATARequest *request); 180 status_t Inquiry(ATARequest *request); 181 status_t ReadCapacity(ATARequest *request); 182 status_t ReadCapacity16(ATARequest *request); 183 virtual status_t ExecuteIO(ATARequest *request); 184 185 void GetRestrictions(bool *noAutoSense, 186 uint32 *maxBlocks); 187 status_t Control(uint32 op, void *buffer, size_t length); 188 189 // ATA stuff IsATAPI()190 virtual bool IsATAPI() const { return false; } 191 UseDMA()192 bool UseDMA() const { return fUseDMA; } Use48Bits()193 bool Use48Bits() const { return fUse48Bits; } BlockSize()194 size_t BlockSize() const { return fBlockSize; } 195 196 status_t Select(); 197 TaskFile()198 ata_task_file * TaskFile() { return &fTaskFile; } RegisterMask()199 ata_reg_mask RegisterMask() const { return fRegisterMask; } 200 201 status_t SetFeature(int feature); 202 status_t DisableCommandQueueing(); 203 status_t ConfigureDMA(); 204 205 virtual status_t Configure(); 206 status_t Identify(); 207 208 status_t ExecuteReadWrite(ATARequest *request, 209 uint64 address, uint32 sectorCount); 210 211 protected: _DebugContext()212 const char * _DebugContext() { return fDebugContext; } 213 214 ATAChannel * fChannel; 215 ata_device_infoblock fInfoBlock; 216 ata_task_file fTaskFile; 217 ata_reg_mask fRegisterMask; 218 219 bool fUseDMA; 220 uint8 fDMAMode; 221 uint8 fDMAFailures; 222 223 private: 224 status_t _FillTaskFile(ATARequest *request, 225 uint64 address); 226 227 uint64 fTotalSectors; 228 size_t fBlockSize; 229 size_t fPhysicalBlockSize; 230 size_t fBlockOffset; 231 uint8 fIndex; 232 bool fUse48Bits; 233 234 char fDebugContext[16]; 235 }; 236 237 238 class ATAPIDevice : public ATADevice { 239 public: 240 ATAPIDevice(ATAChannel *channel, uint8 index); 241 virtual ~ATAPIDevice(); 242 243 status_t SendPacket(ATARequest *request); 244 virtual status_t ExecuteIO(ATARequest *request); 245 IsATAPI()246 virtual bool IsATAPI() const { return true; } 247 248 virtual status_t Configure(); 249 250 private: 251 status_t _FillTaskFilePacket(ATARequest *request); 252 status_t _FinishRequest(ATARequest *request, 253 uint32 flags); 254 255 private: 256 uint8 fPacket[12]; 257 }; 258 259 260 class ATARequest { 261 public: 262 ATARequest(bool hasLock); 263 ~ATARequest(); 264 265 void SetStatus(uint8 status); Status()266 uint8 Status() const { return fStatus; } 267 268 void ClearSense(); 269 void SetSense(uint8 key, uint16 codeQualifier); SenseKey()270 uint8 SenseKey() const { return fSenseKey; } SenseCode()271 uint8 SenseCode() const { return fSenseCode; } SenseQualifier()272 uint8 SenseQualifier() const 273 { return fSenseQualifier; } 274 275 void SetDevice(ATADevice *device); Device()276 ATADevice * Device() const { return fDevice; } 277 278 void SetTimeout(bigtime_t timeout); Timeout()279 bigtime_t Timeout() const { return fTimeout; } 280 281 void SetIsWrite(bool isWrite); IsWrite()282 bool IsWrite() const { return fIsWrite; } 283 284 void SetUseDMA(bool useDMA); UseDMA()285 bool UseDMA() const { return fUseDMA; } 286 287 void SetBytesLeft(uint32 bytesLeft); BytesLeft()288 size_t * BytesLeft() { return &fBytesLeft; } 289 HasData()290 bool HasData() const 291 { return fCCB->data_length > 0; } HasSense()292 bool HasSense() const { return fSenseKey != 0; } 293 294 status_t Finish(bool resubmit); 295 296 // SCSI stuff 297 status_t Start(scsi_ccb *ccb); CCB()298 scsi_ccb * CCB() { return fCCB; } 299 300 void PrepareSGInfo(); 301 void AdvanceSG(uint32 bytes); 302 SGElementsLeft()303 uint32 SGElementsLeft() const 304 { return fSGElementsLeft; } CurrentSGElement()305 const physical_entry *CurrentSGElement() const 306 { return fCurrentSGElement; } CurrentSGOffset()307 uint32 CurrentSGOffset() const 308 { return fCurrentSGOffset; } 309 310 void SetOddByte(uint8 byte); 311 bool GetOddByte(uint8 *byte); 312 313 void RequestSense(); 314 315 private: 316 void _FillSense(scsi_sense *sense); 317 _DebugContext()318 const char * _DebugContext() { return " request"; }; 319 320 mutex fLock; 321 bool fHasLock; 322 323 uint8 fStatus; 324 uint8 fSenseKey; 325 uint8 fSenseCode; 326 uint8 fSenseQualifier; 327 328 ATADevice * fDevice; 329 bigtime_t fTimeout; 330 size_t fBytesLeft; 331 bool fIsWrite; 332 bool fUseDMA; 333 scsi_ccb * fCCB; 334 335 uint32 fSGElementsLeft; 336 const physical_entry *fCurrentSGElement; 337 uint32 fCurrentSGOffset; 338 bool fHasOddByte; 339 uint8 fOddByte; 340 }; 341 342 #endif // ATA_PRIVATE_H 343