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