Serenity Operating System
1/*
2 * Copyright (c) 2020-2022, Liav A. <liavalb@hotmail.co.il>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <AK/OwnPtr.h>
8#include <AK/Types.h>
9#include <Kernel/Bus/PCI/API.h>
10#include <Kernel/Library/LockRefPtr.h>
11#include <Kernel/Sections.h>
12#include <Kernel/Storage/ATA/ATADiskDevice.h>
13#include <Kernel/Storage/ATA/GenericIDE/Channel.h>
14#include <Kernel/Storage/ATA/GenericIDE/Controller.h>
15
16namespace Kernel {
17
18UNMAP_AFTER_INIT NonnullLockRefPtr<IDEController> IDEController::initialize()
19{
20 return adopt_lock_ref(*new IDEController());
21}
22
23bool IDEController::reset()
24{
25 TODO();
26}
27
28bool IDEController::shutdown()
29{
30 TODO();
31}
32
33size_t IDEController::devices_count() const
34{
35 size_t count = 0;
36 for (u32 index = 0; index < 4; index++) {
37 if (!device(index).is_null())
38 count++;
39 }
40 return count;
41}
42
43void IDEController::start_request(ATADevice const& device, AsyncBlockDeviceRequest& request)
44{
45 auto& address = device.ata_address();
46 VERIFY(address.subport < 2);
47 switch (address.port) {
48 case 0: {
49 auto result = m_channels[0]->start_request(device, request);
50 // FIXME: Propagate errors properly
51 VERIFY(!result.is_error());
52 return;
53 }
54 case 1: {
55 auto result = m_channels[1]->start_request(device, request);
56 // FIXME: Propagate errors properly
57 VERIFY(!result.is_error());
58 return;
59 }
60 }
61 VERIFY_NOT_REACHED();
62}
63
64void IDEController::complete_current_request(AsyncDeviceRequest::RequestResult)
65{
66 VERIFY_NOT_REACHED();
67}
68
69UNMAP_AFTER_INIT IDEController::IDEController() = default;
70UNMAP_AFTER_INIT IDEController::~IDEController() = default;
71
72LockRefPtr<StorageDevice> IDEController::device_by_channel_and_position(u32 index) const
73{
74 switch (index) {
75 case 0:
76 return m_channels[0]->connected_device(0);
77 case 1:
78 return m_channels[0]->connected_device(1);
79 case 2:
80 return m_channels[1]->connected_device(0);
81 case 3:
82 return m_channels[1]->connected_device(1);
83 }
84 VERIFY_NOT_REACHED();
85}
86
87LockRefPtr<StorageDevice> IDEController::device(u32 index) const
88{
89 Vector<NonnullLockRefPtr<StorageDevice>> connected_devices;
90 for (size_t index = 0; index < 4; index++) {
91 auto checked_device = device_by_channel_and_position(index);
92 if (checked_device.is_null())
93 continue;
94 connected_devices.append(checked_device.release_nonnull());
95 }
96 if (index >= connected_devices.size())
97 return nullptr;
98 return connected_devices[index];
99}
100}