ATAPort.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /*
  2. * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <Kernel/Arch/CPU.h>
  7. #include <Kernel/Arch/Delay.h>
  8. #include <Kernel/Devices/Storage/ATA/ATADiskDevice.h>
  9. #include <Kernel/Devices/Storage/ATA/ATAPort.h>
  10. #include <Kernel/Devices/Storage/ATA/Definitions.h>
  11. #include <Kernel/Tasks/WorkQueue.h>
  12. namespace Kernel {
  13. class ATAPortInterruptDisabler {
  14. public:
  15. ATAPortInterruptDisabler(ATAPort& port)
  16. : m_port(port)
  17. {
  18. (void)port.disable_interrupts();
  19. }
  20. ~ATAPortInterruptDisabler()
  21. {
  22. (void)m_port->enable_interrupts();
  23. }
  24. private:
  25. LockRefPtr<ATAPort> m_port;
  26. };
  27. class ATAPortInterruptCleaner {
  28. public:
  29. ATAPortInterruptCleaner(ATAPort& port)
  30. : m_port(port)
  31. {
  32. }
  33. ~ATAPortInterruptCleaner()
  34. {
  35. (void)m_port->force_clear_interrupts();
  36. }
  37. private:
  38. LockRefPtr<ATAPort> m_port;
  39. };
  40. void ATAPort::fix_name_string_in_identify_device_block()
  41. {
  42. VERIFY(m_lock.is_locked());
  43. auto* wbuf = (u16*)m_ata_identify_data_buffer->data();
  44. auto* bbuf = m_ata_identify_data_buffer->data() + 27 * 2;
  45. for (size_t word_index = 27; word_index < 47; word_index++) {
  46. u16 data = wbuf[word_index];
  47. *(bbuf++) = MSB(data);
  48. *(bbuf++) = LSB(data);
  49. }
  50. }
  51. ErrorOr<void> ATAPort::detect_connected_devices()
  52. {
  53. MutexLocker locker(m_lock);
  54. for (size_t device_index = 0; device_index < max_possible_devices_connected(); device_index++) {
  55. TRY(device_select(device_index));
  56. auto device_presence = TRY(detect_presence_on_selected_device());
  57. if (!device_presence)
  58. continue;
  59. TaskFile identify_taskfile;
  60. memset(&identify_taskfile, 0, sizeof(TaskFile));
  61. identify_taskfile.command = ATA_CMD_IDENTIFY;
  62. auto buffer = UserOrKernelBuffer::for_kernel_buffer(m_ata_identify_data_buffer->data());
  63. {
  64. auto result = execute_polled_command(TransactionDirection::Read, LBAMode::None, identify_taskfile, buffer, 0, 256, 100, 100);
  65. if (result.is_error()) {
  66. continue;
  67. }
  68. }
  69. ATAIdentifyBlock volatile& identify_block = (ATAIdentifyBlock volatile&)(*m_ata_identify_data_buffer->data());
  70. u16 capabilities = identify_block.capabilities[0];
  71. StringView device_name = StringView((char const*)const_cast<u16*>(identify_block.model_number), 40);
  72. fix_name_string_in_identify_device_block();
  73. u64 max_addressable_block = identify_block.max_28_bit_addressable_logical_sector;
  74. dbgln("ATAPort: device found: Name={}, Capacity={}, Capabilities={:#04x}", device_name.trim_whitespace(), max_addressable_block * 512, capabilities);
  75. // If the drive is so old that it doesn't support LBA, ignore it.
  76. if (!(capabilities & ATA_CAP_LBA)) {
  77. dbgln("ATAPort: device found but without LBA support (what kind of dinosaur we see here?)");
  78. continue;
  79. }
  80. // if we support 48-bit LBA, use that value instead.
  81. if (identify_block.commands_and_feature_sets_supported[1] & (1 << 10))
  82. max_addressable_block = identify_block.user_addressable_logical_sectors_count;
  83. // FIXME: Don't assume all drives will have logical sector size of 512 bytes.
  84. ATADevice::Address address = { m_port_index, static_cast<u8>(device_index) };
  85. m_ata_devices.append(ATADiskDevice::create(m_parent_ata_controller, address, capabilities, 512, max_addressable_block));
  86. }
  87. return {};
  88. }
  89. LockRefPtr<StorageDevice> ATAPort::connected_device(size_t device_index) const
  90. {
  91. MutexLocker locker(m_lock);
  92. if (m_ata_devices.size() > device_index)
  93. return m_ata_devices[device_index];
  94. return {};
  95. }
  96. ErrorOr<void> ATAPort::start_request(ATADevice const& associated_device, AsyncBlockDeviceRequest& request)
  97. {
  98. MutexLocker locker(m_lock);
  99. VERIFY(m_current_request.is_null());
  100. VERIFY(pio_capable() || dma_capable());
  101. dbgln_if(ATA_DEBUG, "ATAPort::start_request");
  102. m_current_request = request;
  103. m_current_request_block_index = 0;
  104. m_current_request_flushing_cache = false;
  105. if (dma_capable()) {
  106. TRY(prepare_and_initiate_dma_transaction(associated_device));
  107. return {};
  108. }
  109. TRY(prepare_and_initiate_pio_transaction(associated_device));
  110. return {};
  111. }
  112. void ATAPort::complete_pio_transaction(AsyncDeviceRequest::RequestResult result)
  113. {
  114. VERIFY(m_current_request);
  115. // Now schedule reading back the buffer as soon as we leave the irq handler.
  116. // This is important so that we can safely write the buffer back,
  117. // which could cause page faults. Note that this may be called immediately
  118. // before Processor::deferred_call_queue returns!
  119. auto work_item_creation_result = g_io_work->try_queue([this, result]() {
  120. dbgln_if(ATA_DEBUG, "ATAPort::complete_pio_transaction result: {}", (int)result);
  121. MutexLocker locker(m_lock);
  122. VERIFY(m_current_request);
  123. auto current_request = m_current_request;
  124. m_current_request.clear();
  125. current_request->complete(result);
  126. });
  127. if (work_item_creation_result.is_error()) {
  128. auto current_request = m_current_request;
  129. m_current_request.clear();
  130. current_request->complete(AsyncDeviceRequest::OutOfMemory);
  131. }
  132. }
  133. void ATAPort::complete_dma_transaction(AsyncDeviceRequest::RequestResult result)
  134. {
  135. // NOTE: this may be called from the interrupt handler!
  136. VERIFY(m_current_request);
  137. VERIFY(m_lock.is_locked());
  138. // Now schedule reading back the buffer as soon as we leave the irq handler.
  139. // This is important so that we can safely write the buffer back,
  140. // which could cause page faults. Note that this may be called immediately
  141. // before Processor::deferred_call_queue returns!
  142. auto work_item_creation_result = g_io_work->try_queue([this, result]() {
  143. dbgln_if(ATA_DEBUG, "ATAPort::complete_dma_transaction result: {}", (int)result);
  144. MutexLocker locker(m_lock);
  145. if (!m_current_request)
  146. return;
  147. auto current_request = m_current_request;
  148. m_current_request.clear();
  149. if (result == AsyncDeviceRequest::Success) {
  150. {
  151. auto result = force_busmastering_status_clean();
  152. if (result.is_error()) {
  153. locker.unlock();
  154. current_request->complete(AsyncDeviceRequest::Failure);
  155. return;
  156. }
  157. }
  158. if (current_request->request_type() == AsyncBlockDeviceRequest::Read) {
  159. if (auto result = current_request->write_to_buffer(current_request->buffer(), m_dma_buffer_region->vaddr().as_ptr(), 512 * current_request->block_count()); result.is_error()) {
  160. locker.unlock();
  161. current_request->complete(AsyncDeviceRequest::MemoryFault);
  162. return;
  163. }
  164. }
  165. }
  166. locker.unlock();
  167. current_request->complete(result);
  168. });
  169. if (work_item_creation_result.is_error()) {
  170. auto current_request = m_current_request;
  171. m_current_request.clear();
  172. current_request->complete(AsyncDeviceRequest::OutOfMemory);
  173. }
  174. }
  175. static void print_ata_status(u8 status)
  176. {
  177. dbgln("ATAPort: print_status: DRQ={} BSY={}, DRDY={}, DSC={}, DF={}, CORR={}, IDX={}, ERR={}",
  178. (status & ATA_SR_DRQ) != 0,
  179. (status & ATA_SR_BSY) != 0,
  180. (status & ATA_SR_DRDY) != 0,
  181. (status & ATA_SR_DSC) != 0,
  182. (status & ATA_SR_DF) != 0,
  183. (status & ATA_SR_CORR) != 0,
  184. (status & ATA_SR_IDX) != 0,
  185. (status & ATA_SR_ERR) != 0);
  186. }
  187. static void try_disambiguate_ata_error(u8 error)
  188. {
  189. dbgln("ATAPort: Error cause:");
  190. switch (error) {
  191. case ATA_ER_BBK:
  192. dbgln("ATAPort: - Bad block");
  193. break;
  194. case ATA_ER_UNC:
  195. dbgln("ATAPort: - Uncorrectable data");
  196. break;
  197. case ATA_ER_MC:
  198. dbgln("ATAPort: - Media changed");
  199. break;
  200. case ATA_ER_IDNF:
  201. dbgln("ATAPort: - ID mark not found");
  202. break;
  203. case ATA_ER_MCR:
  204. dbgln("ATAPort: - Media change request");
  205. break;
  206. case ATA_ER_ABRT:
  207. dbgln("ATAPort: - Command aborted");
  208. break;
  209. case ATA_ER_TK0NF:
  210. dbgln("ATAPort: - Track 0 not found");
  211. break;
  212. case ATA_ER_AMNF:
  213. dbgln("ATAPort: - No address mark");
  214. break;
  215. default:
  216. dbgln("ATAPort: - No one knows");
  217. break;
  218. }
  219. }
  220. ErrorOr<bool> ATAPort::handle_interrupt_after_dma_transaction()
  221. {
  222. if (!dma_capable())
  223. return false;
  224. u8 bstatus = TRY(busmastering_status());
  225. if (!(bstatus & 0x4)) {
  226. // interrupt not from this device, ignore
  227. dbgln_if(ATA_DEBUG, "ATAPort: ignore interrupt");
  228. return false;
  229. }
  230. auto work_item_creation_result = g_ata_work->try_queue([this]() -> void {
  231. MutexLocker locker(m_lock);
  232. u8 status = task_file_status().release_value();
  233. m_entropy_source.add_random_event(status);
  234. // clear bus master interrupt status
  235. {
  236. auto result = force_busmastering_status_clean();
  237. if (result.is_error()) {
  238. complete_dma_transaction(AsyncDeviceRequest::Failure);
  239. return;
  240. }
  241. }
  242. SpinlockLocker lock(m_hard_lock);
  243. dbgln_if(ATA_DEBUG, "ATAPort: interrupt: DRQ={}, BSY={}, DRDY={}",
  244. (status & ATA_SR_DRQ) != 0,
  245. (status & ATA_SR_BSY) != 0,
  246. (status & ATA_SR_DRDY) != 0);
  247. if (!m_current_request) {
  248. dbgln("ATAPort: IRQ but no pending request!");
  249. return;
  250. }
  251. if (status & ATA_SR_ERR) {
  252. print_ata_status(status);
  253. auto device_error = task_file_error().release_value();
  254. dbgln("ATAPort: Error {:#02x}!", (u8)device_error);
  255. try_disambiguate_ata_error(device_error);
  256. complete_dma_transaction(AsyncDeviceRequest::Failure);
  257. return;
  258. }
  259. complete_dma_transaction(AsyncDeviceRequest::Success);
  260. return;
  261. });
  262. if (work_item_creation_result.is_error()) {
  263. auto current_request = m_current_request;
  264. m_current_request.clear();
  265. current_request->complete(AsyncDeviceRequest::OutOfMemory);
  266. return Error::from_errno(ENOMEM);
  267. }
  268. return true;
  269. }
  270. ErrorOr<void> ATAPort::prepare_and_initiate_dma_transaction(ATADevice const& associated_device)
  271. {
  272. VERIFY(m_lock.is_locked());
  273. VERIFY(!m_current_request.is_null());
  274. VERIFY(m_current_request->block_count() <= 256);
  275. // Note: We might be called here from an interrupt handler (like the page fault handler), so queue a read afterwards.
  276. auto work_item_creation_result = g_ata_work->try_queue([this, &associated_device]() -> void {
  277. MutexLocker locker(m_lock);
  278. dbgln_if(ATA_DEBUG, "ATAPort::prepare_and_initiate_dma_transaction ({} x {})", m_current_request->block_index(), m_current_request->block_count());
  279. VERIFY(!m_current_request.is_null());
  280. VERIFY(m_current_request->block_count() <= 256);
  281. {
  282. auto result = device_select(associated_device.ata_address().subport);
  283. if (result.is_error()) {
  284. complete_dma_transaction(AsyncDeviceRequest::Failure);
  285. return;
  286. }
  287. }
  288. if (m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write) {
  289. if (auto result = m_current_request->read_from_buffer(m_current_request->buffer(), m_dma_buffer_region->vaddr().as_ptr(), 512 * m_current_request->block_count()); result.is_error()) {
  290. complete_dma_transaction(AsyncDeviceRequest::MemoryFault);
  291. return;
  292. }
  293. }
  294. prdt().offset = m_dma_buffer_page->paddr().get();
  295. prdt().size = 512 * m_current_request->block_count();
  296. VERIFY(prdt().size <= PAGE_SIZE);
  297. SpinlockLocker hard_lock_locker(m_hard_lock);
  298. {
  299. auto result = stop_busmastering();
  300. if (result.is_error()) {
  301. complete_dma_transaction(AsyncDeviceRequest::Failure);
  302. return;
  303. }
  304. }
  305. if (m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write) {
  306. auto result = prepare_transaction_with_busmastering(TransactionDirection::Write, m_prdt_page->paddr());
  307. if (result.is_error()) {
  308. complete_dma_transaction(AsyncDeviceRequest::Failure);
  309. return;
  310. }
  311. } else {
  312. auto result = prepare_transaction_with_busmastering(TransactionDirection::Read, m_prdt_page->paddr());
  313. if (result.is_error()) {
  314. complete_dma_transaction(AsyncDeviceRequest::Failure);
  315. return;
  316. }
  317. }
  318. TaskFile taskfile;
  319. LBAMode lba_mode = LBAMode::TwentyEightBit;
  320. auto lba = m_current_request->block_index();
  321. if ((lba + m_current_request->block_count()) >= 0x10000000) {
  322. lba_mode = LBAMode::FortyEightBit;
  323. }
  324. memset(&taskfile, 0, sizeof(TaskFile));
  325. taskfile.lba_low[0] = (lba & 0x000000FF) >> 0;
  326. taskfile.lba_low[1] = (lba & 0x0000FF00) >> 8;
  327. taskfile.lba_low[2] = (lba & 0x00FF0000) >> 16;
  328. taskfile.lba_high[0] = (lba & 0xFF000000) >> 24;
  329. taskfile.lba_high[1] = (lba & 0xFF00000000ull) >> 32;
  330. taskfile.lba_high[2] = (lba & 0xFF0000000000ull) >> 40;
  331. taskfile.count = m_current_request->block_count();
  332. if (lba_mode == LBAMode::TwentyEightBit)
  333. taskfile.command = m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write ? ATA_CMD_WRITE_DMA : ATA_CMD_READ_DMA;
  334. else
  335. taskfile.command = m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write ? ATA_CMD_WRITE_DMA_EXT : ATA_CMD_READ_DMA_EXT;
  336. {
  337. auto result = load_taskfile_into_registers(taskfile, lba_mode, 1000);
  338. if (result.is_error()) {
  339. complete_dma_transaction(AsyncDeviceRequest::Failure);
  340. return;
  341. }
  342. }
  343. if (m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write) {
  344. auto result = start_busmastering(TransactionDirection::Write);
  345. if (result.is_error()) {
  346. complete_dma_transaction(AsyncDeviceRequest::Failure);
  347. return;
  348. }
  349. }
  350. else {
  351. auto result = start_busmastering(TransactionDirection::Read);
  352. if (result.is_error()) {
  353. complete_dma_transaction(AsyncDeviceRequest::Failure);
  354. return;
  355. }
  356. }
  357. });
  358. if (work_item_creation_result.is_error()) {
  359. auto current_request = m_current_request;
  360. m_current_request.clear();
  361. current_request->complete(AsyncDeviceRequest::OutOfMemory);
  362. return Error::from_errno(ENOMEM);
  363. }
  364. return {};
  365. }
  366. ErrorOr<void> ATAPort::prepare_and_initiate_pio_transaction(ATADevice const& associated_device)
  367. {
  368. VERIFY(m_lock.is_locked());
  369. VERIFY(!m_current_request.is_null());
  370. VERIFY(m_current_request->block_count() <= 256);
  371. dbgln_if(ATA_DEBUG, "ATAPort::prepare_and_initiate_pio_transaction ({} x {})", m_current_request->block_index(), m_current_request->block_count());
  372. // Note: We might be called here from an interrupt handler (like the page fault handler), so queue a read afterwards.
  373. auto work_item_creation_result = g_ata_work->try_queue([this, &associated_device]() -> void {
  374. MutexLocker locker(m_lock);
  375. {
  376. auto result = device_select(associated_device.ata_address().subport);
  377. if (result.is_error()) {
  378. complete_pio_transaction(AsyncDeviceRequest::Failure);
  379. return;
  380. }
  381. }
  382. for (size_t block_index = 0; block_index < m_current_request->block_count(); block_index++) {
  383. TaskFile taskfile;
  384. LBAMode lba_mode = LBAMode::TwentyEightBit;
  385. auto lba = m_current_request->block_index() + block_index;
  386. if (lba >= 0x10000000) {
  387. lba_mode = LBAMode::FortyEightBit;
  388. }
  389. memset(&taskfile, 0, sizeof(TaskFile));
  390. taskfile.lba_low[0] = (lba & 0x000000FF) >> 0;
  391. taskfile.lba_low[1] = (lba & 0x0000FF00) >> 8;
  392. taskfile.lba_low[2] = (lba & 0x00FF0000) >> 16;
  393. taskfile.lba_high[0] = (lba & 0xFF000000) >> 24;
  394. taskfile.lba_high[1] = (lba & 0xFF00000000ull) >> 32;
  395. taskfile.lba_high[2] = (lba & 0xFF0000000000ull) >> 40;
  396. taskfile.count = 1;
  397. if (lba_mode == LBAMode::TwentyEightBit)
  398. taskfile.command = m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write ? ATA_CMD_WRITE_PIO : ATA_CMD_READ_PIO;
  399. else
  400. taskfile.command = m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Write ? ATA_CMD_WRITE_PIO_EXT : ATA_CMD_READ_PIO_EXT;
  401. if (m_current_request->request_type() == AsyncBlockDeviceRequest::RequestType::Read) {
  402. auto result = execute_polled_command(TransactionDirection::Read, lba_mode, taskfile, m_current_request->buffer(), block_index, 256, 100, 100);
  403. if (result.is_error()) {
  404. complete_pio_transaction(AsyncDeviceRequest::Failure);
  405. return;
  406. }
  407. } else {
  408. auto result = execute_polled_command(TransactionDirection::Write, lba_mode, taskfile, m_current_request->buffer(), block_index, 256, 100, 100);
  409. if (result.is_error()) {
  410. complete_pio_transaction(AsyncDeviceRequest::Failure);
  411. return;
  412. }
  413. }
  414. }
  415. complete_pio_transaction(AsyncDeviceRequest::Success);
  416. });
  417. if (work_item_creation_result.is_error()) {
  418. auto current_request = m_current_request;
  419. m_current_request.clear();
  420. current_request->complete(AsyncDeviceRequest::OutOfMemory);
  421. return Error::from_errno(ENOMEM);
  422. }
  423. return {};
  424. }
  425. ErrorOr<void> ATAPort::execute_polled_command(TransactionDirection direction, LBAMode lba_mode, TaskFile const& taskfile, UserOrKernelBuffer& buffer, size_t block_offset, size_t words_count, size_t preparation_timeout_in_milliseconds, size_t completion_timeout_in_milliseconds)
  426. {
  427. // Disable interrupts temporarily, just in case we have that enabled,
  428. // remember the value to re-enable (and clean) later if needed.
  429. ATAPortInterruptDisabler disabler(*this);
  430. ATAPortInterruptCleaner cleaner(*this);
  431. MutexLocker locker(m_lock);
  432. {
  433. SpinlockLocker hard_locker(m_hard_lock);
  434. // Wait for device to be not busy or timeout
  435. TRY(wait_if_busy_until_timeout(preparation_timeout_in_milliseconds));
  436. // Send command, wait for result or timeout
  437. TRY(load_taskfile_into_registers(taskfile, lba_mode, preparation_timeout_in_milliseconds));
  438. size_t milliseconds_elapsed = 0;
  439. for (;;) {
  440. if (milliseconds_elapsed > completion_timeout_in_milliseconds)
  441. break;
  442. u8 status = task_file_status().release_value();
  443. if (status & ATA_SR_ERR) {
  444. return Error::from_errno(EINVAL);
  445. }
  446. if (!(status & ATA_SR_BSY) && (status & ATA_SR_DRQ)) {
  447. break;
  448. }
  449. microseconds_delay(1000);
  450. milliseconds_elapsed++;
  451. }
  452. if (milliseconds_elapsed > completion_timeout_in_milliseconds) {
  453. critical_dmesgln("ATAPort: device state unknown. Timeout exceeded.");
  454. return Error::from_errno(EINVAL);
  455. }
  456. }
  457. VERIFY_INTERRUPTS_ENABLED();
  458. if (direction == TransactionDirection::Read)
  459. TRY(read_pio_data_to_buffer(buffer, block_offset, words_count));
  460. else
  461. TRY(write_pio_data_from_buffer(buffer, block_offset, words_count));
  462. return {};
  463. }
  464. }