Skip to content

Commit f67af8b

Browse files
committed
Trying to drain the cd-rom response queue on interrupts.
1 parent 2902876 commit f67af8b

File tree

1 file changed

+66
-61
lines changed

1 file changed

+66
-61
lines changed

src/mips/psyqo/src/cdrom-device.cpp

Lines changed: 66 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -64,82 +64,87 @@ void psyqo::CDRomDevice::ActionBase::queueCallbackFromISR(bool success) {
6464
}
6565

6666
void psyqo::CDRomDevice::irq() {
67-
Kernel::assert(m_action != nullptr, "CDRomDevice::irq() called with no action - spurious interrupt?");
68-
uint8_t cause = Hardware::CDRom::Cause;
69-
70-
if (cause & 7) {
71-
Hardware::CDRom::Cause = 7;
72-
}
67+
bool ranOnce = false;
68+
while (true) {
69+
uint8_t cause = Hardware::CDRom::Cause;
70+
if (ranOnce && ((cause & 15) == 0)) break;
71+
ranOnce = true;
72+
Kernel::assert(m_action != nullptr, "CDRomDevice::irq() called with no action - spurious interrupt?");
73+
74+
if (cause & 7) {
75+
Hardware::CDRom::Cause = 7;
76+
}
7377

74-
if (cause & 0x18) {
75-
Hardware::CDRom::Cause = 0x18;
76-
}
78+
if (cause & 0x18) {
79+
Hardware::CDRom::Cause = 0x18;
80+
}
7781

78-
bool callCallback = false;
79-
Response response;
80-
while ((Hardware::CDRom::Ctrl.access() & 0x20) && (response.size() < 16)) {
81-
response.push_back(Hardware::CDRom::Response);
82-
}
82+
bool callCallback = false;
83+
Response response;
84+
while ((Hardware::CDRom::Ctrl.access() & 0x20) && (response.size() < 16)) {
85+
response.push_back(Hardware::CDRom::Response);
86+
}
8387

8488
#ifdef DEBUG_CDROM_RESPONSES
85-
if (m_blocking) {
86-
ramsyscall_printf("Got CD-Rom response:");
87-
for (auto byte : response) {
88-
ramsyscall_printf(" %02x", byte);
89-
}
90-
syscall_puts("\n");
91-
} else {
92-
Kernel::queueCallbackFromISR([response]() {
89+
if (m_blocking) {
9390
ramsyscall_printf("Got CD-Rom response:");
9491
for (auto byte : response) {
9592
ramsyscall_printf(" %02x", byte);
9693
}
9794
syscall_puts("\n");
98-
});
99-
}
100-
#endif
101-
102-
switch (cause & 7) {
103-
case 1:
104-
callCallback = m_action->dataReady(response);
105-
break;
106-
case 2:
107-
callCallback = m_action->complete(response);
108-
break;
109-
case 3:
110-
callCallback = m_action->acknowledge(response);
111-
break;
112-
case 4:
113-
callCallback = m_action->end(response);
114-
break;
115-
case 5: {
116-
m_success = false;
117-
callCallback = true;
118-
#ifdef DEBUG_CDROM_ERRORS
119-
m_callback = [callback = eastl::move(m_callback), name = m_action->name(),
120-
response = eastl::move(response)](bool) {
121-
ramsyscall_printf("Got CD-Rom error during action %s:", name);
95+
} else {
96+
Kernel::queueCallbackFromISR([response]() {
97+
ramsyscall_printf("Got CD-Rom response:");
12298
for (auto byte : response) {
12399
ramsyscall_printf(" %02x", byte);
124100
}
125101
syscall_puts("\n");
126-
callback(false);
127-
};
102+
});
103+
}
128104
#endif
129-
} break;
130-
default:
131-
Kernel::abort("CDRomDevice::irq() invoked with unknown cause");
132-
break;
133-
}
134105

135-
if (callCallback) {
136-
Kernel::assert(!!m_callback, "Wrong CDRomDevice state");
137-
m_action = nullptr;
138-
if (m_blocking) {
139-
actionComplete();
140-
} else {
141-
eastl::atomic_signal_fence(eastl::memory_order_acquire);
142-
Kernel::queueCallbackFromISR([this]() { actionComplete(); });
106+
switch (cause & 7) {
107+
case 1:
108+
callCallback = m_action->dataReady(response);
109+
break;
110+
case 2:
111+
callCallback = m_action->complete(response);
112+
break;
113+
case 3:
114+
callCallback = m_action->acknowledge(response);
115+
break;
116+
case 4:
117+
callCallback = m_action->end(response);
118+
break;
119+
case 5: {
120+
m_success = false;
121+
callCallback = true;
122+
#ifdef DEBUG_CDROM_ERRORS
123+
m_callback = [callback = eastl::move(m_callback), name = m_action->name(),
124+
response = eastl::move(response)](bool) {
125+
ramsyscall_printf("Got CD-Rom error during action %s:", name);
126+
for (auto byte : response) {
127+
ramsyscall_printf(" %02x", byte);
128+
}
129+
syscall_puts("\n");
130+
callback(false);
131+
};
132+
#endif
133+
} break;
134+
default:
135+
Kernel::abort("CDRomDevice::irq() invoked with unknown cause");
136+
break;
137+
}
138+
139+
if (callCallback) {
140+
Kernel::assert(!!m_callback, "Wrong CDRomDevice state");
141+
m_action = nullptr;
142+
if (m_blocking) {
143+
actionComplete();
144+
} else {
145+
eastl::atomic_signal_fence(eastl::memory_order_acquire);
146+
Kernel::queueCallbackFromISR([this]() { actionComplete(); });
147+
}
143148
}
144149
}
145150
}

0 commit comments

Comments
 (0)