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