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