aboutsummaryrefslogtreecommitdiff
path: root/hw/scsi/esp.c
AgeCommit message (Collapse)Author
2023-10-03esp: restrict non-DMA transfer length to that of available dataMark Cave-Ayland
In the case where a SCSI layer transfer is incorrectly terminated, it is possible for a TI command to cause a SCSI buffer overflow due to the expected transfer data length being less than the available data in the FIFO. When this occurs the unsigned async_len variable underflows and becomes a large offset which writes past the end of the allocated SCSI buffer. Restrict the non-DMA transfer length to be the smallest of the expected transfer length and the available FIFO data to ensure that it is no longer possible for the SCSI buffer overflow to occur. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1810 Reviewed-by: Thomas Huth <thuth@redhat.com> Message-ID: <20230913204410.65650-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> (cherry picked from commit 77668e4b9bca03a856c27ba899a2513ddf52bb52) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2023-10-03esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux()Mark Cave-Ayland
The call to esp_dma_enable() was being made with the SYSBUS_ESP type instead of the ESP type. This meant that when GPIO 1 was being used to trigger a DMA request from an external DMA controller, the setting of ESPState's dma_enabled field would clobber unknown memory whilst the dma_cb callback pointer would typically return NULL so the DMA request would never start. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-ID: <20230913204410.65650-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> (cherry picked from commit b86dc5cb0b4105fa8ad29e822ab5d21c589c5ec5) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2022-11-11Fix several typos in documentation (found by codespell)Stefan Weil
Those typos are in files which are used to generate the QEMU manual. Signed-off-by: Stefan Weil <sw@weilnetz.de> Message-Id: <20221110190825.879620-1-sw@weilnetz.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Ani Sinha <ani@anisinha.ca> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Michael S. Tsirkin <mst@redhat.com> [thuth: update sentence in can.rst as suggested by Peter] Signed-off-by: Thomas Huth <thuth@redhat.com>
2022-10-18scsi: Use device_cold_reset() and bus_cold_reset()Peter Maydell
In the SCSI subsystem we currently use the legacy functions qdev_reset_all() and qbus_reset_all(). These perform a recursive reset, starting from either a qbus or a qdev. However they do not permit any of the devices in the tree to use three-phase reset, because device reset goes through the device_legacy_reset() function that only calls the single DeviceClass::reset method. Switch to using the device_cold_reset() and bus_cold_reset() functions. These also perform a recursive reset, where first the children are reset and then finally the parent, but they use the new (...in 2020...) Resettable mechanism, which supports both the old style single-reset method and also the new 3-phase reset handling. Since no devices attached to SCSI buses currently try to use 3-phase reset, this should be a no-behaviour-change commit which just reduces the use of a deprecated API. Commit created with: sed -i -e 's/qdev_reset_all/device_cold_reset/g;s/qbus_reset_all/bus_cold_reset/g' hw/scsi/*.c Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20221013160623.1296109-2-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-09-01scsi: Add buf_len parameter to scsi_req_new()John Millikin
When a SCSI command is received from the guest, the CDB length implied by the first byte might exceed the number of bytes the guest sent. In this case scsi_req_new() will read uninitialized data, causing unpredictable behavior. Adds the buf_len parameter to scsi_req_new() and plumbs it through the call stack. Signed-off-by: John Millikin <john@john-millikin.com> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1127 Message-Id: <20220817053458.698416-1-john@john-millikin.com> [Fill in correct length for adapters other than ESP. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-09-01esp: Handle CMD_BUSRESET by resetting the SCSI busJohn Millikin
Per investigation on the linked ticket, SunOS issues a SCSI bus reset to the ESP as part of its boot sequence. If this ESP command doesn't cause devices to assert sense flag UNIT ATTENTION, SunOS will consider the CD-ROM device to be non-compliant with Common Command Set (CCS). In this condition, the SunOS installer's early userspace doesn't set the installation source location to sr0 and the miniroot copy fails. Signed-off-by: John Millikin <john@john-millikin.com> Suggested-by: Bill Paul <noisetube@gmail.com> Buglink: https://gitlab.com/qemu-project/qemu/-/issues/1127 Message-Id: <20220817053846.699310-1-john@john-millikin.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2022-03-09esp: recreate ESPState current_req after migrationMark Cave-Ayland
Since PDMA reads/writes are driven by the guest, it is possible that migration can occur whilst a SCSIRequest is still active. Fortunately active SCSIRequests are already included in the migration stream and restarted post migration but this still leaves the reference in ESPState uninitialised. Implement the SCSIBusInfo .load_request callback to obtain a reference to the currently active SCSIRequest and use it to recreate ESPState current_req after migration. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220305155530.9265-11-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2022-03-09esp: include the current PDMA callback in the migration streamMark Cave-Ayland
This involves (re)adding a PDMA-specific subsection to hold the reference to the current PDMA callback. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220305155530.9265-10-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2022-03-09esp: convert ESPState pdma_cb from a function pointer to an integerMark Cave-Ayland
This prepares for the inclusion of the current PDMA callback in the migration stream since the callback is referenced by an integer instead of a function pointer. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220305155530.9265-9-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2022-03-09esp: introduce esp_pdma_cb() functionMark Cave-Ayland
This function is to be used to execute the current PDMA callback rather than dereferencing the ESPState pdma_cb function pointer directly. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220305155530.9265-8-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2022-03-09esp: introduce esp_set_pdma_cb() functionMark Cave-Ayland
This function is to be used to set the current PDMA callback rather than accessing the ESPState pdma_cb function pointer directly. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20220305155530.9265-7-mark.cave-ayland@ilande.co.uk> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2021-11-19esp: ensure that async_len is reset to 0 during esp_hard_reset()Mark Cave-Ayland
If a reset command is sent after data has been transferred into the SCSI buffer ensure that async_len is reset to 0. Otherwise a subsequent TI command assumes the SCSI buffer contains data to be transferred to the device causing it to dereference the stale async_buf pointer. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Fixes: https://gitlab.com/qemu-project/qemu/-/issues/724 Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-Id: <20211118100327.29061-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-11-02esp: ensure in-flight SCSI requests are always cancelledMark Cave-Ayland
There is currently a check in esp_select() to cancel any in-flight SCSI requests to ensure that issuing multiple select commands without continuing through the rest of the ESP state machine ignores all but the last SCSI request. This is also enforced through the addition of assert()s in esp_transfer_data() and scsi_read_data(). The get_cmd() function does not call esp_select() when TC == 0 which means it is possible for a fuzzer to trigger these assert()s by sending a select command when TC == 0 immediately after a valid SCSI CDB has been submitted. Since esp_select() is only called from get_cmd(), hoist the check to cancel in-flight SCSI requests from esp_select() into get_cmd() to ensure it is always called when executing a select command to initiate a new SCSI request. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Closes: https://gitlab.com/qemu-project/qemu/-/issues/662 Closes: https://gitlab.com/qemu-project/qemu/-/issues/663 Message-Id: <20211101183516.8455-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-09-30scsi: Replace scsi_bus_new() with scsi_bus_init(), scsi_bus_init_named()Peter Maydell
The function scsi_bus_new() creates a new SCSI bus; callers can either pass in a name argument to specify the name of the new bus, or they can pass in NULL to allow the bus to be given an automatically generated unique name. Almost all callers want to use the autogenerated name; the only exception is the virtio-scsi device. Taking a name argument that should almost always be NULL is an easy-to-misuse API design -- it encourages callers to think perhaps they should pass in some standard name like "scsi" or "scsi-bus". We don't do this anywhere for SCSI, but we do (incorrectly) do it for other bus types such as i2c. The function name also implies that it will return a newly allocated object, when it in fact does in-place allocation. We more commonly name such functions foo_init(), with foo_new() being the allocate-and-return variant. Replace all the scsi_bus_new() callsites with either: * scsi_bus_init() for the usual case where the caller wants an autogenerated bus name * scsi_bus_init_named() for the rare case where the caller needs to specify the bus name and document that for the _named() version it's then the caller's responsibility to think about uniqueness of bus names. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 20210923121153.23754-2-peter.maydell@linaro.org
2021-06-15esp: store lun coming from the MESSAGE OUT phasePaolo Bonzini
The LUN is selected with an IDENTIFY message, and persists until the next message out phase. Instead of passing it to do_busid_cmd, store it in ESPState. Because do_cmd can simply skip the message out phase if cmdfifo_cdb_offset is zero, it can now be used for the S without ATN cases as well. Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: fix migration version check in esp_is_version_5()Mark Cave-Ayland
Commit 4e78f3bf35 "esp: defer command completion interrupt on incoming data transfers" added a version check for use with VMSTATE_*_TEST macros to allow migration from older QEMU versions. Unfortunately the version check fails to work in its current form since if the VMStateDescription version_id is incremented, the test returns false and so the fields are not included in the outgoing migration stream. Change the version check to use >= rather == to ensure that migration works correctly when the ESPState VMStateDescription has version_id > 5. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Fixes: 4e78f3bf35 ("esp: defer command completion interrupt on incoming data transfers") Message-Id: <20210613102614.5438-1-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: correctly accumulate extended messages for PDMAMark Cave-Ayland
Commit 799d90d818 "esp: transition to message out phase after SATN and stop command" added logic to correctly handle extended messages for DMA requests but not for PDMA requests. Apply the same logic in esp_do_dma() to do_dma_pdma_cb() so that extended messages terminated with a PDMA request are accumulated correctly. This allows the ESP device to respond correctly to the SDTR negotiation initiated by the NetBSD ESP driver without causing errors and timeouts on boot. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20210519100803.10293-6-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: revert 75ef849696 "esp: correctly fill bus id with requested lun"Mark Cave-Ayland
This commit from nearly 10 years ago is now broken due to the improvements in esp emulation (or perhaps was never correct). It shows up as a bug in detecting the CDROM drive under MacOS. The error is caused by the MacOS CDROM driver sending this CDB with an "S without ATN" command and without DMA: 0x12 0x00 0x00 0x00 0x05 0x00 (INQUIRY) This is a valid INQUIRY command, however with this logic present the 3rd byte (0x0) is copied over the 1st byte (0x12) which silently converts the INQUIRY command to a TEST UNIT READY command before passing it to the QEMU SCSI layer. Since the TEST UNIT READY command has a zero length response the MacOS CDROM driver never receives a response and assumes the CDROM is not present. The logic was to ignore the IDENTIFY byte and copy the LUN over from the CDB, which did store the LUN in bits 5-7 of the second byte in olden times. This however is all obsolete, so just drop the code. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20210519100803.10293-5-mark.cave-ayland@ilande.co.uk> [Tweaked commit message. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: ensure PDMA write transfers are flushed from the FIFO to the target ↵Mark Cave-Ayland
immediately After each PDMA write transfer the MacOS CDROM driver waits until the FIFO is empty (i.e. its contents have been written out to the SCSI bus) by polling the FIFO count register until it reads 0. This doesn't work with the current PDMA write implementation which waits until either the FIFO is full or the transfer is complete before invoking the PDMA callback to process the FIFO contents. Change the PDMA write transfer logic so that the PDMA callback is invoked after each PDMA write to transfer the FIFO contents to the target buffer immediately, and hence avoid getting stuck in the FIFO count register polling loop. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20210519100803.10293-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: handle non-DMA transfers from the target one byte at a timeMark Cave-Ayland
The initial implementation of non-DMA transfers was based upon analysis of traces from the MacOS toolbox ROM for handling unaligned reads but missed one key aspect - during a non-DMA transfer from the target, the bus service interrupt should be raised for every single byte received from the bus and not just at either the end of the transfer or when the FIFO is full. Adjust the non-DMA code accordingly so that esp_do_nodma() is called for every byte received from the target. This also includes special handling for managing the change from DATA IN to STATUS phase as this needs to occur when the final byte is read out from the FIFO, and not at the end of the transfer of the last byte into the FIFO. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20210519100803.10293-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: allow non-DMA callback in esp_transfer_data() initial transferMark Cave-Ayland
The current implementation only resumes DMA transfers when incoming data is received from the target device, but this is also required for non-DMA transfers with the next set of non-DMA changes. Rather than duplicate the DMA/non-DMA dispatch logic in the initial transfer section, update the code so that the initial transfer section can just fallthrough to the main DMA/non-DMA dispatch logic. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Message-Id: <20210519100803.10293-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: only set ESP_RSEQ at the start of the select sequenceMark Cave-Ayland
When processing a command to select a target and send a CDB, the ESP device maintains a sequence step register so that if an error occurs the host can determine which part of the selection/CDB submission sequence failed. The old Linux 2.6 driver is really pedantic here: it checks the sequence step register even if a command succeeds and complains loudly on the console if the sequence step register doesn't match the expected bus phase and interrupt flags. This reason this mismatch occurs is because the ESP emulation currently doesn't update the bus phase until the next TI (Transfer Information) command and so the cleared sequence step register is considered invalid for the stale bus phase. Normally this isn't an issue as the host only checks the sequence step register if an error occurs but the old Linux 2.6 driver does this in several places causing a large stream of "esp0: STEP_ASEL for tgt 0" messages to appear on the console during the boot process. Fix this by not clearing the sequence step register when reading the interrupt register and clearing the DMA status, so the guest sees a valid sequence step and bus phase combination at the end of the command phase. No other change is required since the sequence step register is correctly updated throughout the selection/CDB submission sequence once one of the select commands is issued. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Fixes: 1b9e48a5bd ("esp: implement non-DMA transfers in PDMA mode") Message-Id: <20210518212511.21688-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-06-15esp: only assert INTR_DC interrupt flag if selection failsMark Cave-Ayland
The datasheet sequence tables confirm that when a target selection fails, only the INTR_DC interrupt flag should be asserted. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Fixes: cf47a41e05 ("esp: latch individual bits in ESP_RINTR register") Message-Id: <20210518212511.21688-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2021-04-12esp: ensure that do_cmd is set to zero before submitting an ESP select commandMark Cave-Ayland
When a CDB has been received and is about to be submitted to the SCSI layer via one of the ESP select commands, ensure that do_cmd is set to zero before executing the command. Otherwise a guest executing 2 valid CDBs in quick sequence can invoke the SCSI .transfer_data callback again before do_cmd is set to zero by the callback function triggering an assert at the start of esp_transfer_data(). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20210407195801.685-12-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: don't reset async_len directly in esp_select() if cancelling requestMark Cave-Ayland
Instead let the SCSI layer invoke the .cancel callback itself to cancel and reset the request state. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20210407195801.685-11-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: don't overflow cmdfifo if TC is larger than the cmdfifo sizeMark Cave-Ayland
If a guest transfers the message out/command phase data using DMA with a TC that is larger than the cmdfifo size then the cmdfifo overflows triggering an assert. Limit the size of the transfer to the free space available in cmdfifo. Buglink: https://bugs.launchpad.net/qemu/+bug/1919036 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-10-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: don't overflow cmdfifo in get_cmd()Mark Cave-Ayland
If the guest tries to read a CDB using DMA and cmdfifo is not empty then it is possible to overflow cmdfifo. Since this can only occur by issuing deliberately incorrect instruction sequences, ensure that the maximum length of the CDB transferred to cmdfifo is limited to the available free space within cmdfifo. Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-9-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: don't underflow cmdfifo in do_cmd()Mark Cave-Ayland
If the guest tries to execute a CDB when cmdfifo is not empty before the start of the message out phase then clearing the message out phase data will cause cmdfifo to underflow due to cmdfifo_cdb_offset being larger than the amount of data within. Since this can only occur by issuing deliberately incorrect instruction sequences, ensure that the maximum length of esp_fifo_pop_buf() is limited to the size of the data within cmdfifo. Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-8-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: ensure cmdfifo is not empty and current_dev is non-NULLMark Cave-Ayland
When about to execute a SCSI command, ensure that cmdfifo is not empty and current_dev is non-NULL. This can happen if the guest tries to execute a TI (Transfer Information) command without issuing one of the select commands first. Buglink: https://bugs.launchpad.net/qemu/+bug/1910723 Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-7-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: introduce esp_fifo_pop_buf() and use it instead of fifo8_pop_buf()Mark Cave-Ayland
The const pointer returned by fifo8_pop_buf() lies directly within the array used to model the FIFO. Building with address sanitizers enabled shows that if the caller expects a minimum number of bytes present then if the FIFO is nearly full, the caller may unexpectedly access past the end of the array. Introduce esp_fifo_pop_buf() which takes a destination buffer and performs a memcpy() in it to guarantee that the caller cannot overwrite the FIFO array and update all callers to use it. Similarly add underflow protection similar to esp_fifo_push() and esp_fifo_pop() so that instead of triggering an assert() the operation becomes a no-op. Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20210407195801.685-6-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: consolidate esp_cmdfifo_pop() into esp_fifo_pop()Mark Cave-Ayland
Each FIFO currently has its own pop functions with the only difference being the capacity check. The original reason for this was that the fifo8 implementation doesn't have a formal API for retrieving the FIFO capacity, however there are multiple examples within QEMU where the capacity field is accessed directly. Change esp_fifo_pop() to access the FIFO capacity directly and then consolidate esp_cmdfifo_pop() into esp_fifo_pop(). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-5-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: consolidate esp_cmdfifo_push() into esp_fifo_push()Mark Cave-Ayland
Each FIFO currently has its own push functions with the only difference being the capacity check. The original reason for this was that the fifo8 implementation doesn't have a formal API for retrieving the FIFO capacity, however there are multiple examples within QEMU where the capacity field is accessed directly. Change esp_fifo_push() to access the FIFO capacity directly and then consolidate esp_cmdfifo_push() into esp_fifo_push(). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-4-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: rework write_response() to avoid using the FIFO for DMA transactionsMark Cave-Ayland
The code for write_response() has always used the FIFO to store the data for the status/message in phases, even for DMA transactions. Switch to using a separate buffer that can be used directly for DMA transactions and restrict the FIFO use to the non-DMA case. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Alexander Bulekov <alxndr@bu.edu> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20210407195801.685-3-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: always check current_req is not NULL before use in DMA callbacksMark Cave-Ayland
After issuing a SCSI command the SCSI layer can call the SCSIBusInfo .cancel callback which resets both current_req and current_dev to NULL. If any data is left in the transfer buffer (async_len != 0) then the next TI (Transfer Information) command will attempt to reference the NULL pointer causing a segfault. Buglink: https://bugs.launchpad.net/qemu/+bug/1910723 Buglink: https://bugs.launchpad.net/qemu/+bug/1909247 Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Tested-by: Alexander Bulekov <alxndr@bu.edu> Message-Id: <20210407195801.685-2-mark.cave-ayland@ilande.co.uk>
2021-04-12esp: fix setting of ESPState mig_version_id when launching QEMU with -S optionMark Cave-Ayland
If QEMU is launched with the -S option then the ESPState mig_version_id property is left unset due to the ordering of the VMState fields in the VMStateDescription for sysbusespscsi and pciespscsi. If the VM is migrated and restored in this stopped state, the version tests in the vmstate_esp VMStateDescription and esp_post_load() become confused causing the migration to fail. Fix the ordering problem by moving the setting of mig_version_id to a common esp_pre_save() function which is invoked first by both sysbusespscsi and pciespscsi rather than at the point where ESPState is itself serialised into the migration stream. Buglink: https://bugs.launchpad.net/qemu/+bug/1922611 Fixes: 0bd005be78 ("esp: add vmstate_esp version to embedded ESPState") Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Thomas Huth <thuth@redhat.com> Message-Id: <20210407124842.32695-1-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: add support for unaligned accessesMark Cave-Ayland
When the MacOS toolbox ROM transfers data from a target device to an unaligned memory address, the first/last byte of a 16-bit transfer needs to be handled separately. This means that the first byte is preloaded into the FIFO before the transfer, or the last byte remains in the FIFO after the transfer. The result of this is that the PDMA routines must be updated so that the FIFO is loaded/unloaded if the last 16-bit word is used (rather than the last byte) and any remaining byte from a FIFO wraparound is handled correctly. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-43-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: implement non-DMA transfers in PDMA modeMark Cave-Ayland
The MacOS toolbox ROM uses non-DMA TI commands to handle the first/last byte of an unaligned 16-bit transfer to memory. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-42-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: add trivial implementation of the ESP_RFLAGS registerMark Cave-Ayland
The bottom 5 bits contain the number of bytes remaining in the FIFO which is trivial to implement with Fifo8 (the remaining bits are unimplemented and left as 0 for now). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-41-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: convert cmdbuf from array to Fifo8Mark Cave-Ayland
Rename ESP_CMDBUF_SZ to ESP_CMDFIFO_SZ and cmdbuf_cdb_offset to cmdfifo_cdb_offset to indicate that the command buffer type has changed from an array to a Fifo8. This also enables us to remove the ESPState field cmdlen since the command length is now simply the number of elements used in cmdfifo. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-40-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: convert ti_buf from array to Fifo8Mark Cave-Ayland
Rename TI_BUFSZ to ESP_FIFO_SZ since this constant is really describing the size of the FIFO and is not directly related to the TI size. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-39-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: transition to message out phase after SATN and stop commandMark Cave-Ayland
The SCSI bus should remain in the message out phase after the SATN and stop command rather than transitioning to the command phase. A new ESPState variable cmdbuf_cdb_offset is added which stores the offset of the CDB from the start of cmdbuf when accumulating extended message out phase data. Currently any extended message out data is discarded in do_cmd() before the CDB is processed in do_busid_cmd(). Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-38-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: add maxlen parameter to get_cmd()Mark Cave-Ayland
Some guests use a mixture of DMA and non-DMA transfers in combination with the SATN and stop command to transfer message out phase and command phase bytes to the target. Prepare for the next commit by adding a maxlen parameter to get_cmd() to allow partial transfers. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-37-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: raise interrupt after every non-DMA byte transferred to the FIFOMark Cave-Ayland
This matches the description in the datasheet and is required as support for non-DMA transfers is added. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-36-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: remove old deferred command completion mechanismMark Cave-Ayland
Commit ea84a44250 "scsi: esp: Defer command completion until previous interrupts have been handled" provided a mechanism to delay the command completion interrupt until ESP_RINTR is read after the command has completed. With the previous fixes for latching the ESP_RINTR bits and deferring the setting of the command completion interrupt for incoming data to the SCSI callback, this workaround is no longer required and can be removed. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-35-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: defer command completion interrupt on incoming data transfersMark Cave-Ayland
The MacOS toolbox ROM issues a command to the ESP controller as part of its "FAST" SCSI routines and then proceeds to read the incoming data soon after receiving the command completion interrupt. Unfortunately due to SCSI block transfers being asynchronous the incoming data may not yet be present causing an underflow error. Resolve this by waiting for the SCSI subsystem transfer_data callback before raising the command completion interrupt. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-34-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: latch individual bits in ESP_RINTR registerMark Cave-Ayland
Currently the ESP_RINTR register is set to a specific value as required within the ESP state machine. In order to implement the upcoming deferred interrupt functionality it is necessary to set individual bits within ESP_RINTR so that a deferred interrupt will not overwrite the value of any other interrupt bits. This also requires fixing up a few locations where the ESP_RINTR and ESP_RSEQ registers are set/reset unexpectedly. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-33-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: implement FIFO flush commandMark Cave-Ayland
At this point it is now possible to properly implement the FIFO flush command without causing guest errors. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-32-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: add 4 byte PDMA read and write transfersMark Cave-Ayland
The MacOS toolbox ROM performs 4 byte reads/writes when transferring data to and from the target. Since the SCSI bus is 16-bits wide, use the memory API to split a 4 byte access into 2 x 2 byte accesses. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-31-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: remove pdma_origin from ESPStateMark Cave-Ayland
Now that all data is transferred via the FIFO (ti_buf) there is no need to track the source buffer being used for the data transfer. This also eliminates the need for a separate subsection for PDMA state migration. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-30-mark.cave-ayland@ilande.co.uk>
2021-03-07esp: use FIFO for PDMA transfers between initiator and deviceMark Cave-Ayland
PDMA as implemented on the Quadra 800 uses DREQ to load data into the FIFO up to a maximum of 16 bytes at a time. The MacOS toolbox ROM requires this because it mixes FIFO and PDMA transfers whilst checking the FIFO status and counter registers to ensure success. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Laurent Vivier <laurent@vivier.eu> Message-Id: <20210304221103.6369-29-mark.cave-ayland@ilande.co.uk>