| 292 | } |
| 293 | |
| 294 | int Port::Access(uint64_t lba, uint32_t count, uintptr_t physBuffer, int write){ |
| 295 | //portLock.Wait(); |
| 296 | acquireLock(&portLock); |
| 297 | |
| 298 | registers->ie = 0xffffffff; |
| 299 | registers->is = 0; |
| 300 | int spin = 0; |
| 301 | |
| 302 | int slot = FindCmdSlot(); |
| 303 | if(slot == -1){ |
| 304 | Log::Warning("[SATA] Could not find command slot!"); |
| 305 | |
| 306 | //portLock.Signal(); |
| 307 | releaseLock(&portLock); |
| 308 | return 2; |
| 309 | } |
| 310 | |
| 311 | registers->serr = registers->tfd = 0; |
| 312 | |
| 313 | hba_cmd_header_t* commandHeader = &commandList[slot]; |
| 314 | |
| 315 | commandHeader->cfl = sizeof(fis_reg_h2d_t) / sizeof(uint32_t); |
| 316 | |
| 317 | commandHeader->a = 0; |
| 318 | commandHeader->w = write; |
| 319 | commandHeader->c = 0; |
| 320 | commandHeader->p = 0; |
| 321 | |
| 322 | commandHeader->prdbc = 0; |
| 323 | commandHeader->pmp = 0; |
| 324 | |
| 325 | hba_cmd_tbl_t* commandTable = commandTables[slot]; |
| 326 | memset(commandTable, 0, sizeof(hba_cmd_tbl_t)); |
| 327 | |
| 328 | commandTable->prdt_entry[0].dba = physBuffer & 0xFFFFFFFF; |
| 329 | commandTable->prdt_entry[0].dbau = (physBuffer >> 32) & 0xFFFFFFFF; |
| 330 | commandTable->prdt_entry[0].dbc = 512 * count - 1; // 512 bytes per sector |
| 331 | commandTable->prdt_entry[0].i = 1; |
| 332 | |
| 333 | fis_reg_h2d_t* cmdfis = (fis_reg_h2d_t*)(commandTable->cfis); |
| 334 | memset(commandTable->cfis, 0, sizeof(fis_reg_h2d_t)); |
| 335 | |
| 336 | cmdfis->fis_type = FIS_TYPE_REG_H2D; |
| 337 | cmdfis->c = 1; // Command |
| 338 | cmdfis->pmport = 0; // Port multiplier |
| 339 | |
| 340 | if(write){ |
| 341 | cmdfis->command = ATA_CMD_WRITE_DMA_EX; |
| 342 | } else { |
| 343 | cmdfis->command = ATA_CMD_READ_DMA_EX; |
| 344 | } |
| 345 | |
| 346 | cmdfis->lba0 = lba & 0xFF; |
| 347 | cmdfis->lba1 = (lba >> 8) & 0xFF; |
| 348 | cmdfis->lba2 = (lba >> 16) & 0xFF; |
| 349 | cmdfis->device = 1 << 6; |
| 350 | |
| 351 | cmdfis->lba3 = (lba >> 24) & 0xFF; |