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