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