The SCSI Status field ("Status Key" and "Additional Status Code" aka. ASC) was incorrectly passed from the SCSI layer to the ATA register layer, and ATAPI command "TEST UNIT READY" was not implemented correctly.
This led to Linux not properly detecting when no CD was inserted into the CD-ROM device, which led to error output in "hwinfo" like (it attempted to read a disk that's no inserted):
> root@debian-iscsi:~# hwinfo --cdrom
> > block.5.1: /dev/sr0 cache[ 78.371349] I/O error, dev sr0, sector 64 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 2
> [ 78.412349] I/O error, dev sr0, sector 64 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
> [ 78.412349] Buffer I/O error on dev sr0, logical block 16, async page read
> [ 78.448365] I/O error, dev sr0, sector 68 op 0x0:(READ) flags 0x0 phys_seg 1 prio class 2
> [ 78.448369] Buffer I/O error on dev sr0, logical block 17, async page read 08: SCSI 100.0: 10602 CD-ROM
This commit fixes that problem by now properly returning SCSI Sense and Additional Sense responses to the ATAPI host.
In the context of ATAPI there's only a single linked document in ide.js: https://www.t10.org/ftp/x3t9.2/document.87/87-106r0.txt.
This link points to "PROPOSAL FOR CD-ROM IN SCSI-2" from 1987 (!) and its content matches the current code in v86, which the SCSI-3 documents did not at all (only the command codes matched, but otherwise SCSI-3 is very different from SCSI-2).
In the original code, status register bit DSC (Drive Seek Complete, 0x10) is always set when completing without error, but ATA/ATAPI-6 specifies this bit to be command dependent. This PR now sets the status register exactly like it was before, just using named constants instead of magic numbers.
Also replaced most of the remaining magic number assignments to the ATA status register.
Renamed members that carry register values to better align with the actual wording in the ATA/ATAPI-6 standard.
Other changes in this commit include:
- added a bunch of named constants for ATA registers and their bits
- improved PCI configuration space setup
- renamed class IDEPCIAdapter to IDEController
Merged and improved on the work from JoeOsborn in respect to formatting in dbg_log() output.
Used register names from the standard for better readability of the output, and added a few missing logs.
In v86, the name "device" is already used in the context of PCI, and additionally, in the ATA/ATAPI standard the term "device" is used for disk drives.
The name used for this entity (IDEDevice) in the ATA/ATAPI standard is "channel", and since "channel" is not otherwise used in ide.js it seems right to rename IDEDevice to IDEChannel.
- immplemented Command and Status register requirements from the standard, ignored all others
- rearranged IDE register definitions, added a descriptive comment to each (standard lingo)
- fixed the EXECUTE DEVICE DIAGNOSTIC (90h) ATA command
Implement a single PCI IDE device in Compatibility Mode for up to 4 drives.
Changes to ide.js:
- added new exported class IDEPCIAdapter, the root class for up to 4 drives
- introduced new config scheme for IDEPCIAdapter (see comment about adapter_config)
- moved PCI-device related members from IDEDevice to IDEPCIAdapter
- rewrote constructor of IDEDevice (no longer exported)
- fixed (?) write-access to ata_port registers 1-6 (see comment below)
- added missing declarations for BAR2 and BAR3 in pci_bars[]
- made definition of the PCI configuration space a bit more more verbose
- renamed "master_port" to "bus_master_port" to avoid confusion
- added a few comments here and there
Regarding write-access to ata_port registers 1-6: It is not clear why these 6
functions simultaneously modify master and slave attributes instead of just
modifying this.current_interface (as is the case everywhere else in the code).
This patch changes that to use this.current_interface, experimental until
there is some explanation.
Also changed cpu.js to now use IDEPCIAdapter instead of IDEDevice.
TODO:
1. clear up the matter around write-access to ata_port registers 1-6
2. in ide.js, a single-device channel needs to be better supported, currently
the code reports a Hard-Disk device of size 0 for an unconnected slave drive,
and there must be a better way to signal this case.
3. in cpu.js, this.devices.hda and this.devices.cdrom point to a IDEDevice, they
should point to an IDEInterface for this.devices.hdb to make sense. This needs
to be better understood and fixed for slave drives to work.
4. getting some very early output under SeaBIOS, but the screen clears so quickly
that I cannot read it and it's also not printed to the serial console
Merged all functionally relevant changes, omitted:
1. Left out almost all of the "dbg_log()" changes, they're like 90% of the original PR and make the essential changes in the diffs a bit hard to read, these can be added back in at a later point in time.
2. Also left out the "wants_cdrom" option and implemented its desired effect with "cdrom: { ejected: true }" as was suggested.
3. The test "tests/api/cdrom-insert-eject.js" is also left out, can be added later back in.
This patch should behave like the last changeset from JoeOsborn in 2023.