From 247d5ca75371bda0e217412d8574b2bc51e1b61c Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 8 Aug 2026 23:31:11 +0200 Subject: [PATCH 1/2] atapibasedevice: Clear BSY and signal interrupt on unsupported ATA command The default case in perform_command() set the ABRT/ERR flags but left BSY asserted and never fired the interrupt. Open Firmware therefore hung waiting on the ATAPI CD-ROM after issuing commands it does not support (e.g. 0xEC IDENTIFY_DEVICE during the boot device probe). --- devices/common/ata/atapibasedevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/devices/common/ata/atapibasedevice.cpp b/devices/common/ata/atapibasedevice.cpp index 3560f92500..5b6f7c289f 100644 --- a/devices/common/ata/atapibasedevice.cpp +++ b/devices/common/ata/atapibasedevice.cpp @@ -201,6 +201,8 @@ int AtapiBaseDevice::perform_command() { LOG_F(ERROR, "%s: unsupported command 0x%X", this->name.c_str(), this->r_command); this->r_error |= ATA_Error::ABRT; this->r_status |= ATA_Status::ERR; + this->r_status &= ~BSY; + this->update_intrq(1); } return 0; } From 3f1f2d718a8ff46c82727f7b588f9ceb967178e7 Mon Sep 17 00:00:00 2001 From: probonopd Date: Sat, 8 Aug 2026 23:31:19 +0200 Subject: [PATCH 2/2] scsicdrom: Register Apple features mode page (0x31) for ATAPI CD-ROM Move the Page 0x31 getter from ScsiCdrom into ScsiCdromCmds so it is also registered for the ATAPI CD-ROM, which Mac OS queries via MODE_SENSE. --- devices/common/scsi/scsicdrom.cpp | 28 ------------------------ devices/common/scsi/scsicdrom.h | 3 --- devices/common/scsi/scsicdromcmds.cpp | 31 +++++++++++++++++++++++++++ devices/common/scsi/scsicdromcmds.h | 3 +++ 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/devices/common/scsi/scsicdrom.cpp b/devices/common/scsi/scsicdrom.cpp index 1c4aace4b7..a10918c56b 100644 --- a/devices/common/scsi/scsicdrom.cpp +++ b/devices/common/scsi/scsicdrom.cpp @@ -47,8 +47,6 @@ ScsiCdrom::ScsiCdrom(std::string name, int my_id) : ScsiPhysDevice(name, my_id) this->set_vendor_id(my_vendor_id); this->set_product_id(my_product_id); this->set_revision_id(my_revision_id); - - this->add_page_getter(this, 49, &ScsiCdrom::get_apple_page_49); } void ScsiCdrom::process_command() { @@ -80,32 +78,6 @@ void ScsiCdrom::process_command() { // Apple SCSI/ATAPI driver requests this page in the case of a device error. // PearPC implements it under the name "Apple Features". // I couldn't find any drive whose firmware supports it. -int ScsiCdrom::get_apple_page_49(uint8_t subpage, uint8_t ctrl, uint8_t *out_ptr, - int avail_len) -{ - LOG_F(WARNING, "Page 0x31 requested"); - - if (subpage && subpage != 0xFFU) - return FORMAT_ERR_BAD_SUBPAGE; - - if (ctrl == 3) - return FORMAT_ERR_BAD_CONTROL; - - int page_size = 6; - - if (page_size > avail_len) - return FORMAT_ERR_DATA_TOO_BIG; - - std::memset(out_ptr, 0, page_size); - - out_ptr[0] = '.'; - out_ptr[1] = 'A'; - out_ptr[2] = 'p'; - out_ptr[3] = 'p'; - - return page_size; -} - void ScsiCdrom::mode_select_6(uint8_t param_len) { if (!param_len) diff --git a/devices/common/scsi/scsicdrom.h b/devices/common/scsi/scsicdrom.h index dc3aa8559b..a46a75c8ec 100644 --- a/devices/common/scsi/scsicdrom.h +++ b/devices/common/scsi/scsicdrom.h @@ -45,9 +45,6 @@ class ScsiCdrom : public ScsiPhysDevice, public ScsiCdromCmds { protected: bool is_device_ready() override { return this->is_ready; } - int get_apple_page_49(uint8_t subpage, uint8_t ctrl, uint8_t *out_ptr, - int avail_len); - void mode_select_6(uint8_t param_len); private: diff --git a/devices/common/scsi/scsicdromcmds.cpp b/devices/common/scsi/scsicdromcmds.cpp index c884ce1b49..e7f87c6634 100644 --- a/devices/common/scsi/scsicdromcmds.cpp +++ b/devices/common/scsi/scsicdromcmds.cpp @@ -36,6 +36,9 @@ ScsiCdromCmds::ScsiCdromCmds() { this->add_page_getter(this, ModePage::CDROM_CAPABILITIES, &ScsiCdromCmds::get_cd_capabilities_page); + + this->add_page_getter(this, ModePage::VENDOR_PAGE_31, + &ScsiCdromCmds::get_apple_page_49); } void ScsiCdromCmds::process_command() { @@ -223,6 +226,34 @@ int ScsiCdromCmds:: read_toc() { return ScsiPhase::DATA_IN; } +// Apple SCSI/ATAPI driver requests this page in the case of a device error. +// PearPC implements it under the name "Apple Features". +int ScsiCdromCmds::get_apple_page_49(uint8_t subpage, uint8_t ctrl, + uint8_t *out_ptr, int avail_len) +{ + LOG_F(WARNING, "Page 0x31 requested"); + + if (subpage && subpage != 0xFFU) + return FORMAT_ERR_BAD_SUBPAGE; + + if (ctrl == 3) + return FORMAT_ERR_BAD_CONTROL; + + int page_size = 6; + + if (page_size > avail_len) + return FORMAT_ERR_DATA_TOO_BIG; + + std::memset(out_ptr, 0, page_size); + + out_ptr[0] = '.'; + out_ptr[1] = 'A'; + out_ptr[2] = 'p'; + out_ptr[3] = 'p'; + + return page_size; +} + int ScsiCdromCmds::set_cd_speed() { phy_impl->set_status(ScsiStatus::GOOD); diff --git a/devices/common/scsi/scsicdromcmds.h b/devices/common/scsi/scsicdromcmds.h index b876f9d7b9..85a91db571 100644 --- a/devices/common/scsi/scsicdromcmds.h +++ b/devices/common/scsi/scsicdromcmds.h @@ -36,6 +36,9 @@ class ScsiCdromCmds : public ScsiBlockCmds, public CdromDrive { protected: virtual void process_command() override; + int get_apple_page_49(uint8_t subpage, uint8_t ctrl, + uint8_t *out_ptr, int avail_len); + int read_toc(); int set_cd_speed();