diff mbox

[PULL,18/19] macio: move unaligned DMA write code into separate pmac_dma_write() function

Message ID 1432324792-9373-19-git-send-email-jsnow@redhat.com
State New
Headers show

Commit Message

John Snow May 22, 2015, 7:59 p.m. UTC
From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>

Similarly switch the macio IDE routines over to use the new function and
tidy-up the remaining code as required.

[Maintainer edit: printf format codes adjusted for 32/64bit. --js]

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Acked-by: John Snow <jsnow@redhat.com>
Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
 include/hw/ppc/mac_dbdma.h |   4 -
 2 files changed, 125 insertions(+), 147 deletions(-)

Comments

Aurelien Jarno July 27, 2015, 10 p.m. UTC | #1
On 2015-05-22 15:59, John Snow wrote:
> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> 
> Similarly switch the macio IDE routines over to use the new function and
> tidy-up the remaining code as required.
> 
> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> Acked-by: John Snow <jsnow@redhat.com>
> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
>  include/hw/ppc/mac_dbdma.h |   4 -
>  2 files changed, 125 insertions(+), 147 deletions(-)

This patch has removed TRIM support without any obvious reason, and
without mentioning it in the changelog. As a consequence guests with
TRIM enabled now fail to boot:

| [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
| [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
| [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
| [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
| [   46.917219] ata1.00: status: { DRDY }
| [   51.957389] ata1.00: qc timeout (cmd 0xec)
| [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
| [   51.958551] ata1.00: revalidation failed (errno=-5)
| [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
| [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
| [   61.981669] ata1: soft resetting link
| [   62.137894] ata1.00: configured for MWDMA2
| [   62.138294] ata1.00: device reported invalid CHS sector 0
| [   62.139045] sd 0:0:0:0: [sda]  
| [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
| [   62.139243] sd 0:0:0:0: [sda]  
| [   62.139346] Sense Key : Aborted Command [current] [descriptor]
| [   62.139581] Descriptor sense data with sense descriptors (in hex):
| [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
| [   62.139812]         00 00 00 00 
| [   62.139897] sd 0:0:0:0: [sda]  
| [   62.140009] Add. Sense: No additional sense information
| [   62.140115] sd 0:0:0:0: [sda] CDB: 
| [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
| [   62.140661] end_request: I/O error, dev sda, sector 62914632
| [   62.141270] ata1: EH complete
Mark Cave-Ayland July 28, 2015, 8:52 a.m. UTC | #2
On 27/07/15 23:00, Aurelien Jarno wrote:

> On 2015-05-22 15:59, John Snow wrote:
>> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>
>> Similarly switch the macio IDE routines over to use the new function and
>> tidy-up the remaining code as required.
>>
>> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
>>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> Acked-by: John Snow <jsnow@redhat.com>
>> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
>>  include/hw/ppc/mac_dbdma.h |   4 -
>>  2 files changed, 125 insertions(+), 147 deletions(-)
> 
> This patch has removed TRIM support without any obvious reason, and
> without mentioning it in the changelog. As a consequence guests with
> TRIM enabled now fail to boot:
> 
> | [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
> | [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
> | [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
> | [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
> | [   46.917219] ata1.00: status: { DRDY }
> | [   51.957389] ata1.00: qc timeout (cmd 0xec)
> | [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
> | [   51.958551] ata1.00: revalidation failed (errno=-5)
> | [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
> | [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
> | [   61.981669] ata1: soft resetting link
> | [   62.137894] ata1.00: configured for MWDMA2
> | [   62.138294] ata1.00: device reported invalid CHS sector 0
> | [   62.139045] sd 0:0:0:0: [sda]  
> | [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> | [   62.139243] sd 0:0:0:0: [sda]  
> | [   62.139346] Sense Key : Aborted Command [current] [descriptor]
> | [   62.139581] Descriptor sense data with sense descriptors (in hex):
> | [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
> | [   62.139812]         00 00 00 00 
> | [   62.139897] sd 0:0:0:0: [sda]  
> | [   62.140009] Add. Sense: No additional sense information
> | [   62.140115] sd 0:0:0:0: [sda] CDB: 
> | [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
> | [   62.140661] end_request: I/O error, dev sda, sector 62914632
> | [   62.141270] ata1: EH complete

Hi Aurelien,

Thanks for the heads-up. I have a fairly comprehensive suite of various
OS test images I use for OpenBIOS testing and evidently not a single one
of them issues a TRIM command as I don't see any regressions here. Can
you point me towards the particular test image you are using?


ATB,

Mark.
Aurelien Jarno July 28, 2015, 6:02 p.m. UTC | #3
On 2015-07-28 09:52, Mark Cave-Ayland wrote:
> On 27/07/15 23:00, Aurelien Jarno wrote:
> 
> > On 2015-05-22 15:59, John Snow wrote:
> >> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >>
> >> Similarly switch the macio IDE routines over to use the new function and
> >> tidy-up the remaining code as required.
> >>
> >> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
> >>
> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >> Acked-by: John Snow <jsnow@redhat.com>
> >> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> >> ---
> >>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
> >>  include/hw/ppc/mac_dbdma.h |   4 -
> >>  2 files changed, 125 insertions(+), 147 deletions(-)
> > 
> > This patch has removed TRIM support without any obvious reason, and
> > without mentioning it in the changelog. As a consequence guests with
> > TRIM enabled now fail to boot:
> > 
> > | [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
> > | [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
> > | [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
> > | [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
> > | [   46.917219] ata1.00: status: { DRDY }
> > | [   51.957389] ata1.00: qc timeout (cmd 0xec)
> > | [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
> > | [   51.958551] ata1.00: revalidation failed (errno=-5)
> > | [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
> > | [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
> > | [   61.981669] ata1: soft resetting link
> > | [   62.137894] ata1.00: configured for MWDMA2
> > | [   62.138294] ata1.00: device reported invalid CHS sector 0
> > | [   62.139045] sd 0:0:0:0: [sda]  
> > | [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> > | [   62.139243] sd 0:0:0:0: [sda]  
> > | [   62.139346] Sense Key : Aborted Command [current] [descriptor]
> > | [   62.139581] Descriptor sense data with sense descriptors (in hex):
> > | [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
> > | [   62.139812]         00 00 00 00 
> > | [   62.139897] sd 0:0:0:0: [sda]  
> > | [   62.140009] Add. Sense: No additional sense information
> > | [   62.140115] sd 0:0:0:0: [sda] CDB: 
> > | [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
> > | [   62.140661] end_request: I/O error, dev sda, sector 62914632
> > | [   62.141270] ata1: EH complete
> 
> Hi Aurelien,
> 
> Thanks for the heads-up. I have a fairly comprehensive suite of various
> OS test images I use for OpenBIOS testing and evidently not a single one
> of them issues a TRIM command as I don't see any regressions here. Can
> you point me towards the particular test image you are using?

You need a Linux based image, with a relatively recent kernel (3.2 is
ok). The disk image has to be created with -drive file=...,discard=unmap
for the TRIM feature to be advertised in the guest. Finally you need to
run the command "fstrim /" or mount a partition or the swap with the
option discard.

As a summary:
- wget https://people.debian.org/~aurel32/qemu/powerpc/debian_wheezy_powerpc_standard.qcow2
- qemu-system-ppc -snapshot -drive file=debian_wheezy_powerpc_standard.qcow2,discard=unmap 
- in the image, login as root (password root) and run fstrim /.

I have looked a bit at the code, and it looks like we have to provide a
function similar to pmac_dma_read/write for the TRIM. I'll look at it a
bit more in details and I will try to provide a patch, but it's probably
won't be before the week-end.

Aurelien
Kevin Wolf July 30, 2015, 10:10 a.m. UTC | #4
Am 28.07.2015 um 10:52 hat Mark Cave-Ayland geschrieben:
> On 27/07/15 23:00, Aurelien Jarno wrote:
> 
> > On 2015-05-22 15:59, John Snow wrote:
> >> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >>
> >> Similarly switch the macio IDE routines over to use the new function and
> >> tidy-up the remaining code as required.
> >>
> >> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
> >>
> >> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> >> Acked-by: John Snow <jsnow@redhat.com>
> >> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
> >> Signed-off-by: John Snow <jsnow@redhat.com>
> >> ---
> >>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
> >>  include/hw/ppc/mac_dbdma.h |   4 -
> >>  2 files changed, 125 insertions(+), 147 deletions(-)
> > 
> > This patch has removed TRIM support without any obvious reason, and
> > without mentioning it in the changelog. As a consequence guests with
> > TRIM enabled now fail to boot:
> > 
> > | [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
> > | [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
> > | [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
> > | [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
> > | [   46.917219] ata1.00: status: { DRDY }
> > | [   51.957389] ata1.00: qc timeout (cmd 0xec)
> > | [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
> > | [   51.958551] ata1.00: revalidation failed (errno=-5)
> > | [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
> > | [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
> > | [   61.981669] ata1: soft resetting link
> > | [   62.137894] ata1.00: configured for MWDMA2
> > | [   62.138294] ata1.00: device reported invalid CHS sector 0
> > | [   62.139045] sd 0:0:0:0: [sda]  
> > | [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> > | [   62.139243] sd 0:0:0:0: [sda]  
> > | [   62.139346] Sense Key : Aborted Command [current] [descriptor]
> > | [   62.139581] Descriptor sense data with sense descriptors (in hex):
> > | [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
> > | [   62.139812]         00 00 00 00 
> > | [   62.139897] sd 0:0:0:0: [sda]  
> > | [   62.140009] Add. Sense: No additional sense information
> > | [   62.140115] sd 0:0:0:0: [sda] CDB: 
> > | [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
> > | [   62.140661] end_request: I/O error, dev sda, sector 62914632
> > | [   62.141270] ata1: EH complete
> 
> Hi Aurelien,
> 
> Thanks for the heads-up. I have a fairly comprehensive suite of various
> OS test images I use for OpenBIOS testing and evidently not a single one
> of them issues a TRIM command as I don't see any regressions here. Can
> you point me towards the particular test image you are using?

It would probably be useful to add qtest cases for this controller so
that you don't have to run all of these test images. Generally, I won't
run your OS test images, but it's unlikely that anything covered by
qtest breaks accidentally as all subsystem maintainers routinely run it.

Kevin
John Snow July 31, 2015, 8:37 p.m. UTC | #5
On 07/28/2015 04:52 AM, Mark Cave-Ayland wrote:
> On 27/07/15 23:00, Aurelien Jarno wrote:
> 
>> On 2015-05-22 15:59, John Snow wrote:
>>> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>>
>>> Similarly switch the macio IDE routines over to use the new function and
>>> tidy-up the remaining code as required.
>>>
>>> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
>>>
>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>> Acked-by: John Snow <jsnow@redhat.com>
>>> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>> ---
>>>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
>>>  include/hw/ppc/mac_dbdma.h |   4 -
>>>  2 files changed, 125 insertions(+), 147 deletions(-)
>>
>> This patch has removed TRIM support without any obvious reason, and
>> without mentioning it in the changelog. As a consequence guests with
>> TRIM enabled now fail to boot:
>>
>> | [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
>> | [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
>> | [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
>> | [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
>> | [   46.917219] ata1.00: status: { DRDY }
>> | [   51.957389] ata1.00: qc timeout (cmd 0xec)
>> | [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
>> | [   51.958551] ata1.00: revalidation failed (errno=-5)
>> | [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
>> | [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
>> | [   61.981669] ata1: soft resetting link
>> | [   62.137894] ata1.00: configured for MWDMA2
>> | [   62.138294] ata1.00: device reported invalid CHS sector 0
>> | [   62.139045] sd 0:0:0:0: [sda]  
>> | [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
>> | [   62.139243] sd 0:0:0:0: [sda]  
>> | [   62.139346] Sense Key : Aborted Command [current] [descriptor]
>> | [   62.139581] Descriptor sense data with sense descriptors (in hex):
>> | [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
>> | [   62.139812]         00 00 00 00 
>> | [   62.139897] sd 0:0:0:0: [sda]  
>> | [   62.140009] Add. Sense: No additional sense information
>> | [   62.140115] sd 0:0:0:0: [sda] CDB: 
>> | [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
>> | [   62.140661] end_request: I/O error, dev sda, sector 62914632
>> | [   62.141270] ata1: EH complete
> 
> Hi Aurelien,
> 
> Thanks for the heads-up. I have a fairly comprehensive suite of various
> OS test images I use for OpenBIOS testing and evidently not a single one
> of them issues a TRIM command as I don't see any regressions here. Can
> you point me towards the particular test image you are using?
> 
> 
> ATB,
> 
> Mark.
> 

Hi Mark:

This series also exposes to me (unfortunately) the fact that we aren't
unmapping the memory space we're picking up for the DMA.

It wouldn't be too hard to unmap in the pmac_ide_transfer_cb with
something like ...

dma_memory_unmap(&address_space_memory, XXXX, io->len, s->dma_cmd ==
IDE_DMA_READ ? DMA_DIRECTION_FROM_DEVICE : DMA_DIRECTION_TO_DEVICE, io->len)

As the XXXX is the dead giveaway, though, we've actually leaked the
pointer -- we've given it to qemu_iovec_add, but I don't think there's a
way to get it back, so we'll need to stash it /somewhere/.

In DBDMA_io ?

--js
Mark Cave-Ayland Aug. 1, 2015, 11:21 a.m. UTC | #6
On 28/07/15 19:02, Aurelien Jarno wrote:

>> Thanks for the heads-up. I have a fairly comprehensive suite of various
>> OS test images I use for OpenBIOS testing and evidently not a single one
>> of them issues a TRIM command as I don't see any regressions here. Can
>> you point me towards the particular test image you are using?
> 
> You need a Linux based image, with a relatively recent kernel (3.2 is
> ok). The disk image has to be created with -drive file=...,discard=unmap
> for the TRIM feature to be advertised in the guest. Finally you need to
> run the command "fstrim /" or mount a partition or the swap with the
> option discard.
> 
> As a summary:
> - wget https://people.debian.org/~aurel32/qemu/powerpc/debian_wheezy_powerpc_standard.qcow2
> - qemu-system-ppc -snapshot -drive file=debian_wheezy_powerpc_standard.qcow2,discard=unmap 
> - in the image, login as root (password root) and run fstrim /.
> 
> I have looked a bit at the code, and it looks like we have to provide a
> function similar to pmac_dma_read/write for the TRIM. I'll look at it a
> bit more in details and I will try to provide a patch, but it's probably
> won't be before the week-end.

I should add that regardless of whether the TRIM patch is applied or
not, the wheezy image reports DMA timeout errors which I don't see in
the squeeze or lenny images:


[    5.420949] ata2.00: configured for MWDMA2
[    5.451070] rtc-generic rtc-generic: setting system clock to
2015-08-01 11:13:25 UTC (1438427605)
[    5.461100] Initializing network drop monitor service
[    5.480460] scsi 1:0:0:0: CD-ROM            QEMU     QEMU DVD-ROM
 2.3. PQ: 0 ANSI: 5
[    5.540013] Freeing unused kernel memory: 244k freed
[    6.677779] udevd[46]: starting version 175
[    8.548044] ne2k-pci.c:v1.03 9/22/2003 D. Becker/P. Gortmaker
[    8.761179] eth0: RealTek RTL-8029 found at 0x400, IRQ 23,
52:54:00:12:34:56.
[   10.300003] sd 0:0:0:0: [sda] 52428800 512-byte logical blocks: (26.8
GB/25.0 GiB)
[   10.359219] pata-macio 0.00021000:ata-4: timeout flushing DMA
[   10.400935] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[   10.412768] ata2.00: BMDMA stat 0x6
[   10.421732] sr 1:0:0:0: CDB: Mode Sense(10): 5a 00 2a 00 00 00 00 00
80 00
[   10.430301] ata2.00: cmd a0/01:00:00:80:00/00:00:00:00:00/a0 tag 0
dma 16512 in
[   10.430334]          res 50/00:03:00:80:00/00:00:00:00:00/a0 Emask
0x20 (host bus error)
[   10.459348] ata2.00: status: { DRDY }
[   10.516892] sd 0:0:0:0: [sda] Write Protect is off
[   10.524614] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
[   10.545353] sd 0:0:0:0: [sda] Write cache: enabled, read cache:
enabled, doesn't support DPO or FUA
[   10.655885] ata2.00: configured for MWDMA2
[   10.665041] ata2: EH complete

and:

[   14.016326] PM: Hibernation image partition 8:4 present
[   14.016380] PM: Looking for hibernation image.
[   14.020555] PM: Image not found (code -22)
[   14.020642] PM: Hibernation image not present or could not be loaded.
[   14.513667] EXT4-fs (sda3): mounted filesystem with ordered data
mode. Opts: (null)
[   24.750778] udevd[252]: starting version 175
[   31.040517] pata-macio 0.00021000:ata-4: timeout flushing DMA
[   31.528077] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[   31.546115] ata2.00: BMDMA stat 0x6
[   31.562905] sr 1:0:0:0: [sr0] CDB: Get configuration: 46 00 00 00 00
00 00 00 10 00
[   31.572557] ata2.00: cmd a0/01:00:00:10:00/00:00:00:00:00/a0 tag 0
dma 16400 in
[   31.572589]          res 50/00:03:00:10:00/00:00:00:00:00/a0 Emask
0x20 (host bus error)
[   31.597940] ata2.00: status: { DRDY }
[   32.139342] ata2.00: configured for MWDMA2
[   32.148769] ata2: EH complete


I'll have a quick look with debugging enabled to see if I can spot
anything obvious.


ATB,

Mark.
Aurelien Jarno Aug. 1, 2015, 12:37 p.m. UTC | #7
On 2015-08-01 12:21, Mark Cave-Ayland wrote:
> On 28/07/15 19:02, Aurelien Jarno wrote:
> 
> >> Thanks for the heads-up. I have a fairly comprehensive suite of various
> >> OS test images I use for OpenBIOS testing and evidently not a single one
> >> of them issues a TRIM command as I don't see any regressions here. Can
> >> you point me towards the particular test image you are using?
> > 
> > You need a Linux based image, with a relatively recent kernel (3.2 is
> > ok). The disk image has to be created with -drive file=...,discard=unmap
> > for the TRIM feature to be advertised in the guest. Finally you need to
> > run the command "fstrim /" or mount a partition or the swap with the
> > option discard.
> > 
> > As a summary:
> > - wget https://people.debian.org/~aurel32/qemu/powerpc/debian_wheezy_powerpc_standard.qcow2
> > - qemu-system-ppc -snapshot -drive file=debian_wheezy_powerpc_standard.qcow2,discard=unmap 
> > - in the image, login as root (password root) and run fstrim /.
> > 
> > I have looked a bit at the code, and it looks like we have to provide a
> > function similar to pmac_dma_read/write for the TRIM. I'll look at it a
> > bit more in details and I will try to provide a patch, but it's probably
> > won't be before the week-end.
> 
> I should add that regardless of whether the TRIM patch is applied or
> not, the wheezy image reports DMA timeout errors which I don't see in
> the squeeze or lenny images:
> 
> 
> [    5.420949] ata2.00: configured for MWDMA2
> [    5.451070] rtc-generic rtc-generic: setting system clock to
> 2015-08-01 11:13:25 UTC (1438427605)
> [    5.461100] Initializing network drop monitor service
> [    5.480460] scsi 1:0:0:0: CD-ROM            QEMU     QEMU DVD-ROM
>  2.3. PQ: 0 ANSI: 5
> [    5.540013] Freeing unused kernel memory: 244k freed
> [    6.677779] udevd[46]: starting version 175
> [    8.548044] ne2k-pci.c:v1.03 9/22/2003 D. Becker/P. Gortmaker
> [    8.761179] eth0: RealTek RTL-8029 found at 0x400, IRQ 23,
> 52:54:00:12:34:56.
> [   10.300003] sd 0:0:0:0: [sda] 52428800 512-byte logical blocks: (26.8
> GB/25.0 GiB)
> [   10.359219] pata-macio 0.00021000:ata-4: timeout flushing DMA
> [   10.400935] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
> [   10.412768] ata2.00: BMDMA stat 0x6
> [   10.421732] sr 1:0:0:0: CDB: Mode Sense(10): 5a 00 2a 00 00 00 00 00
> 80 00
> [   10.430301] ata2.00: cmd a0/01:00:00:80:00/00:00:00:00:00/a0 tag 0
> dma 16512 in
> [   10.430334]          res 50/00:03:00:80:00/00:00:00:00:00/a0 Emask
> 0x20 (host bus error)
> [   10.459348] ata2.00: status: { DRDY }
> [   10.516892] sd 0:0:0:0: [sda] Write Protect is off
> [   10.524614] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
> [   10.545353] sd 0:0:0:0: [sda] Write cache: enabled, read cache:
> enabled, doesn't support DPO or FUA
> [   10.655885] ata2.00: configured for MWDMA2
> [   10.665041] ata2: EH complete
> 
> and:
> 
> [   14.016326] PM: Hibernation image partition 8:4 present
> [   14.016380] PM: Looking for hibernation image.
> [   14.020555] PM: Image not found (code -22)
> [   14.020642] PM: Hibernation image not present or could not be loaded.
> [   14.513667] EXT4-fs (sda3): mounted filesystem with ordered data
> mode. Opts: (null)
> [   24.750778] udevd[252]: starting version 175
> [   31.040517] pata-macio 0.00021000:ata-4: timeout flushing DMA
> [   31.528077] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
> [   31.546115] ata2.00: BMDMA stat 0x6
> [   31.562905] sr 1:0:0:0: [sr0] CDB: Get configuration: 46 00 00 00 00
> 00 00 00 10 00
> [   31.572557] ata2.00: cmd a0/01:00:00:10:00/00:00:00:00:00/a0 tag 0
> dma 16400 in
> [   31.572589]          res 50/00:03:00:10:00/00:00:00:00:00/a0 Emask
> 0x20 (host bus error)
> [   31.597940] ata2.00: status: { DRDY }
> [   32.139342] ata2.00: configured for MWDMA2
> [   32.148769] ata2: EH complete
> 
> 
> I'll have a quick look with debugging enabled to see if I can spot
> anything obvious.

ata2.00 is actually the CD-ROM drive. I have the same issue there,
except here, and there are even more messages when mounting the drive.
That said, it seems to work correctly anyway.
Mark Cave-Ayland Aug. 1, 2015, 4:09 p.m. UTC | #8
On 01/08/15 13:37, Aurelien Jarno wrote:

> On 2015-08-01 12:21, Mark Cave-Ayland wrote:
>> On 28/07/15 19:02, Aurelien Jarno wrote:
>>
>>>> Thanks for the heads-up. I have a fairly comprehensive suite of various
>>>> OS test images I use for OpenBIOS testing and evidently not a single one
>>>> of them issues a TRIM command as I don't see any regressions here. Can
>>>> you point me towards the particular test image you are using?
>>>
>>> You need a Linux based image, with a relatively recent kernel (3.2 is
>>> ok). The disk image has to be created with -drive file=...,discard=unmap
>>> for the TRIM feature to be advertised in the guest. Finally you need to
>>> run the command "fstrim /" or mount a partition or the swap with the
>>> option discard.
>>>
>>> As a summary:
>>> - wget https://people.debian.org/~aurel32/qemu/powerpc/debian_wheezy_powerpc_standard.qcow2
>>> - qemu-system-ppc -snapshot -drive file=debian_wheezy_powerpc_standard.qcow2,discard=unmap 
>>> - in the image, login as root (password root) and run fstrim /.
>>>
>>> I have looked a bit at the code, and it looks like we have to provide a
>>> function similar to pmac_dma_read/write for the TRIM. I'll look at it a
>>> bit more in details and I will try to provide a patch, but it's probably
>>> won't be before the week-end.
>>
>> I should add that regardless of whether the TRIM patch is applied or
>> not, the wheezy image reports DMA timeout errors which I don't see in
>> the squeeze or lenny images:
>>
>>
>> [    5.420949] ata2.00: configured for MWDMA2
>> [    5.451070] rtc-generic rtc-generic: setting system clock to
>> 2015-08-01 11:13:25 UTC (1438427605)
>> [    5.461100] Initializing network drop monitor service
>> [    5.480460] scsi 1:0:0:0: CD-ROM            QEMU     QEMU DVD-ROM
>>  2.3. PQ: 0 ANSI: 5
>> [    5.540013] Freeing unused kernel memory: 244k freed
>> [    6.677779] udevd[46]: starting version 175
>> [    8.548044] ne2k-pci.c:v1.03 9/22/2003 D. Becker/P. Gortmaker
>> [    8.761179] eth0: RealTek RTL-8029 found at 0x400, IRQ 23,
>> 52:54:00:12:34:56.
>> [   10.300003] sd 0:0:0:0: [sda] 52428800 512-byte logical blocks: (26.8
>> GB/25.0 GiB)
>> [   10.359219] pata-macio 0.00021000:ata-4: timeout flushing DMA
>> [   10.400935] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
>> [   10.412768] ata2.00: BMDMA stat 0x6
>> [   10.421732] sr 1:0:0:0: CDB: Mode Sense(10): 5a 00 2a 00 00 00 00 00
>> 80 00
>> [   10.430301] ata2.00: cmd a0/01:00:00:80:00/00:00:00:00:00/a0 tag 0
>> dma 16512 in
>> [   10.430334]          res 50/00:03:00:80:00/00:00:00:00:00/a0 Emask
>> 0x20 (host bus error)
>> [   10.459348] ata2.00: status: { DRDY }
>> [   10.516892] sd 0:0:0:0: [sda] Write Protect is off
>> [   10.524614] sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00
>> [   10.545353] sd 0:0:0:0: [sda] Write cache: enabled, read cache:
>> enabled, doesn't support DPO or FUA
>> [   10.655885] ata2.00: configured for MWDMA2
>> [   10.665041] ata2: EH complete
>>
>> and:
>>
>> [   14.016326] PM: Hibernation image partition 8:4 present
>> [   14.016380] PM: Looking for hibernation image.
>> [   14.020555] PM: Image not found (code -22)
>> [   14.020642] PM: Hibernation image not present or could not be loaded.
>> [   14.513667] EXT4-fs (sda3): mounted filesystem with ordered data
>> mode. Opts: (null)
>> [   24.750778] udevd[252]: starting version 175
>> [   31.040517] pata-macio 0.00021000:ata-4: timeout flushing DMA
>> [   31.528077] ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
>> [   31.546115] ata2.00: BMDMA stat 0x6
>> [   31.562905] sr 1:0:0:0: [sr0] CDB: Get configuration: 46 00 00 00 00
>> 00 00 00 10 00
>> [   31.572557] ata2.00: cmd a0/01:00:00:10:00/00:00:00:00:00/a0 tag 0
>> dma 16400 in
>> [   31.572589]          res 50/00:03:00:10:00/00:00:00:00:00/a0 Emask
>> 0x20 (host bus error)
>> [   31.597940] ata2.00: status: { DRDY }
>> [   32.139342] ata2.00: configured for MWDMA2
>> [   32.148769] ata2: EH complete
>>
>>
>> I'll have a quick look with debugging enabled to see if I can spot
>> anything obvious.
> 
> ata2.00 is actually the CD-ROM drive. I have the same issue there,
> except here, and there are even more messages when mounting the drive.
> That said, it seems to work correctly anyway.

I've worked out what is going on here (it's the non-block transfers) and
have a fix that looks good on my test images here. John/Aurelien, please
can you test on your setups to make sure that everything still works for
you?


ATB,

Mark.
Mark Cave-Ayland Aug. 2, 2015, 1:02 p.m. UTC | #9
On 31/07/15 21:37, John Snow wrote:

> On 07/28/2015 04:52 AM, Mark Cave-Ayland wrote:
>> On 27/07/15 23:00, Aurelien Jarno wrote:
>>
>>> On 2015-05-22 15:59, John Snow wrote:
>>>> From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>>>
>>>> Similarly switch the macio IDE routines over to use the new function and
>>>> tidy-up the remaining code as required.
>>>>
>>>> [Maintainer edit: printf format codes adjusted for 32/64bit. --js]
>>>>
>>>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>>>> Acked-by: John Snow <jsnow@redhat.com>
>>>> Message-id: 1425939893-14404-3-git-send-email-mark.cave-ayland@ilande.co.uk
>>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>>> ---
>>>>  hw/ide/macio.c             | 268 +++++++++++++++++++++------------------------
>>>>  include/hw/ppc/mac_dbdma.h |   4 -
>>>>  2 files changed, 125 insertions(+), 147 deletions(-)
>>>
>>> This patch has removed TRIM support without any obvious reason, and
>>> without mentioning it in the changelog. As a consequence guests with
>>> TRIM enabled now fail to boot:
>>>
>>> | [   46.916047] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
>>> | [   46.916545] ata1.00: failed command: DATA SET MANAGEMENT
>>> | [   46.916794] ata1.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
>>> | [   46.916794]          res 40/00:01:00:00:00/00:00:00:00:00/e0 Emask 0x20 (host bus error)
>>> | [   46.917219] ata1.00: status: { DRDY }
>>> | [   51.957389] ata1.00: qc timeout (cmd 0xec)
>>> | [   51.958076] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
>>> | [   51.958551] ata1.00: revalidation failed (errno=-5)
>>> | [   56.996713] ata1: link is slow to respond, please be patient (ready=0)
>>> | [   61.981042] ata1: device not ready (errno=-16), forcing hardreset
>>> | [   61.981669] ata1: soft resetting link
>>> | [   62.137894] ata1.00: configured for MWDMA2
>>> | [   62.138294] ata1.00: device reported invalid CHS sector 0
>>> | [   62.139045] sd 0:0:0:0: [sda]  
>>> | [   62.139128] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
>>> | [   62.139243] sd 0:0:0:0: [sda]  
>>> | [   62.139346] Sense Key : Aborted Command [current] [descriptor]
>>> | [   62.139581] Descriptor sense data with sense descriptors (in hex):
>>> | [   62.139670]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00 
>>> | [   62.139812]         00 00 00 00 
>>> | [   62.139897] sd 0:0:0:0: [sda]  
>>> | [   62.140009] Add. Sense: No additional sense information
>>> | [   62.140115] sd 0:0:0:0: [sda] CDB: 
>>> | [   62.140204] Write same(16): 93 08 00 00 00 00 03 c0 00 48 00 3f ff b8 00 00
>>> | [   62.140661] end_request: I/O error, dev sda, sector 62914632
>>> | [   62.141270] ata1: EH complete
>>
>> Hi Aurelien,
>>
>> Thanks for the heads-up. I have a fairly comprehensive suite of various
>> OS test images I use for OpenBIOS testing and evidently not a single one
>> of them issues a TRIM command as I don't see any regressions here. Can
>> you point me towards the particular test image you are using?
>>
>>
>> ATB,
>>
>> Mark.
>>
> 
> Hi Mark:
> 
> This series also exposes to me (unfortunately) the fact that we aren't
> unmapping the memory space we're picking up for the DMA.

Indeed I think you're right - it seems that for unaligned cases
dma_memory_map() can create a bounce region rather than providing a
pointer to the memory directly. I'm not exactly sure that we're
triggering this at the moment since I don't see memory usage ballooning
during use, but it's something that should be done for consistency (not
least that the unmap call marks the DMA memory as dirty).

> It wouldn't be too hard to unmap in the pmac_ide_transfer_cb with
> something like ...
> 
> dma_memory_unmap(&address_space_memory, XXXX, io->len, s->dma_cmd ==
> IDE_DMA_READ ? DMA_DIRECTION_FROM_DEVICE : DMA_DIRECTION_TO_DEVICE, io->len)
> 
> As the XXXX is the dead giveaway, though, we've actually leaked the
> pointer -- we've given it to qemu_iovec_add, but I don't think there's a
> way to get it back, so we'll need to stash it /somewhere/.
> 
> In DBDMA_io ?

That sounds like a reasonable approach. I'm extremely low on QEMU cycle
for the next 2 weeks or so, but if you post something I'll try my best
to review it.


ATB,

Mark.
diff mbox

Patch

diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 037db8b..585a27b 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -144,6 +144,101 @@  static void pmac_dma_read(BlockBackend *blk,
     m->aiocb = blk_aio_readv(blk, sector_num, &io->iov, nsector, cb, io);
 }
 
+static void pmac_dma_write(BlockBackend *blk,
+                         int64_t sector_num, int nb_sectors,
+                         void (*cb)(void *opaque, int ret), void *opaque)
+{
+    DBDMA_io *io = opaque;
+    MACIOIDEState *m = io->opaque;
+    IDEState *s = idebus_active_if(&m->bus);
+    dma_addr_t dma_addr, dma_len;
+    void *mem;
+    int nsector, remainder;
+    int extra = 0;
+
+    qemu_iovec_destroy(&io->iov);
+    qemu_iovec_init(&io->iov, io->len / MACIO_PAGE_SIZE + 1);
+
+    if (io->remainder_len > 0) {
+        /* Return remainder of request */
+        int transfer = MIN(io->remainder_len, io->len);
+
+        MACIO_DPRINTF("--- processing write remainder %x\n", transfer);
+        cpu_physical_memory_read(io->addr,
+                                 &io->remainder + (0x200 - transfer),
+                                 transfer);
+
+        io->remainder_len -= transfer;
+        io->len -= transfer;
+        io->addr += transfer;
+
+        s->io_buffer_index += transfer;
+        s->io_buffer_size -= transfer;
+
+        if (io->remainder_len != 0) {
+            /* Still waiting for remainder */
+            return;
+        }
+
+        MACIO_DPRINTF("--> prepending bounce buffer with size 0x200\n");
+
+        /* Sector transfer complete - prepend to request */
+        qemu_iovec_add(&io->iov, &io->remainder, 0x200);
+        extra = 1;
+    }
+
+    if (s->drive_kind == IDE_CD) {
+        sector_num = (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9);
+    } else {
+        sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
+    }
+
+    nsector = (io->len >> 9);
+    remainder = io->len - (nsector << 9);
+
+    MACIO_DPRINTF("--- DMA write transfer - addr: %" HWADDR_PRIx " len: %x\n",
+                  io->addr, io->len);
+    MACIO_DPRINTF("xxx remainder: %x\n", remainder);
+    MACIO_DPRINTF("xxx sector_num: %"PRIx64"   nsector: %x\n",
+                  sector_num, nsector);
+
+    dma_addr = io->addr;
+    dma_len = io->len;
+    mem = dma_memory_map(&address_space_memory, dma_addr, &dma_len,
+                         DMA_DIRECTION_TO_DEVICE);
+
+    if (!remainder) {
+        MACIO_DPRINTF("--- DMA write aligned - addr: %" HWADDR_PRIx
+                      " len: %x\n", io->addr, io->len);
+        qemu_iovec_add(&io->iov, mem, io->len);
+    } else {
+        /* Write up to last complete sector */
+        MACIO_DPRINTF("--- DMA write unaligned - addr: %" HWADDR_PRIx
+                      " len: %x\n", io->addr, (nsector << 9));
+        qemu_iovec_add(&io->iov, mem, (nsector << 9));
+
+        MACIO_DPRINTF("--- DMA write read    - bounce addr: %p "
+                      "remainder_len: %x\n", &io->remainder, remainder);
+        cpu_physical_memory_read(io->addr + (nsector << 9), &io->remainder,
+                                 remainder);
+
+        io->remainder_len = 0x200 - remainder;
+
+        MACIO_DPRINTF("xxx remainder_len: %x\n", io->remainder_len);
+    }
+
+    s->io_buffer_size -= ((nsector + extra) << 9);
+    s->io_buffer_index += ((nsector + extra) << 9);
+
+    io->len = 0;
+
+    MACIO_DPRINTF("--- Block write transfer   - sector_num: %"PRIx64"  "
+                  "nsector: %x\n", sector_num, nsector + extra);
+
+    m->aiocb = blk_aio_writev(blk, sector_num, &io->iov, nsector + extra, cb,
+                              io);
+}
+
 static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
 {
     DBDMA_io *io = opaque;
@@ -218,24 +313,19 @@  static void pmac_ide_transfer_cb(void *opaque, int ret)
     DBDMA_io *io = opaque;
     MACIOIDEState *m = io->opaque;
     IDEState *s = idebus_active_if(&m->bus);
-    int n = 0;
     int64_t sector_num;
-    int unaligned;
+    int nsector, remainder;
+
+    MACIO_DPRINTF("pmac_ide_transfer_cb\n");
 
     if (ret < 0) {
         MACIO_DPRINTF("DMA error\n");
         m->aiocb = NULL;
-        qemu_sglist_destroy(&s->sg);
         ide_dma_error(s);
         io->remainder_len = 0;
         goto done;
     }
 
-    if (--io->requests) {
-        /* More requests still in flight */
-        return;
-    }
-
     if (!m->dma_active) {
         MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",
                       s->nsector, io->len, s->status);
@@ -244,155 +334,48 @@  static void pmac_ide_transfer_cb(void *opaque, int ret)
         return;
     }
 
-    sector_num = ide_get_sector(s);
-    MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size);
-    if (s->io_buffer_size > 0) {
-        m->aiocb = NULL;
-        qemu_sglist_destroy(&s->sg);
-        n = (s->io_buffer_size + 0x1ff) >> 9;
-        sector_num += n;
-        ide_set_sector(s, sector_num);
-        s->nsector -= n;
-    }
-
-    if (io->finish_remain_read) {
-        /* Finish a stale read from the last iteration */
-        io->finish_remain_read = false;
-        cpu_physical_memory_write(io->finish_addr, io->remainder,
-                                  io->finish_len);
-    }
-
-    MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d "
-                  "sector_num: %" PRId64 "\n",
-                  io->remainder_len, io->len, s->nsector, sector_num);
-    if (io->remainder_len && io->len) {
-        /* guest wants the rest of its previous transfer */
-        int remainder_len = MIN(io->remainder_len, io->len);
-        uint8_t *p = &io->remainder[0x200 - remainder_len];
-
-        MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\n",
-                      remainder_len, io->addr);
-
-        switch (s->dma_cmd) {
-        case IDE_DMA_READ:
-            cpu_physical_memory_write(io->addr, p, remainder_len);
-            break;
-        case IDE_DMA_WRITE:
-            cpu_physical_memory_read(io->addr, p, remainder_len);
-            break;
-        case IDE_DMA_TRIM:
-            break;
-        }
-        io->addr += remainder_len;
-        io->len -= remainder_len;
-        io->remainder_len -= remainder_len;
-
-        if (s->dma_cmd == IDE_DMA_WRITE && !io->remainder_len) {
-            io->requests++;
-            qemu_iovec_reset(&io->iov);
-            qemu_iovec_add(&io->iov, io->remainder, 0x200);
-
-            m->aiocb = blk_aio_writev(s->blk, sector_num - 1, &io->iov, 1,
-                                      pmac_ide_transfer_cb, io);
-        }
-    }
-
-    if (s->nsector == 0 && !io->remainder_len) {
+    if (s->io_buffer_size <= 0) {
         MACIO_DPRINTF("end of transfer\n");
         s->status = READY_STAT | SEEK_STAT;
         ide_set_irq(s->bus);
         m->dma_active = false;
+        goto done;
     }
 
     if (io->len == 0) {
-        MACIO_DPRINTF("end of DMA\n");
+        MACIO_DPRINTF("End of DMA transfer\n");
         goto done;
     }
 
-    /* launch next transfer */
+    /* Calculate number of sectors */
+    sector_num = ide_get_sector(s) + (s->io_buffer_index >> 9);
+    nsector = (io->len + 0x1ff) >> 9;
+    remainder = io->len & 0x1ff;
 
-    s->io_buffer_index = 0;
-    s->io_buffer_size = MIN(io->len, s->nsector * 512);
+    s->nsector -= nsector;
 
-    /* handle unaligned accesses first, get them over with and only do the
-       remaining bulk transfer using our async DMA helpers */
-    unaligned = io->len & 0x1ff;
-    if (unaligned) {
-        int nsector = io->len >> 9;
-
-        MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n",
-                      unaligned, io->addr + io->len - unaligned);
-
-        switch (s->dma_cmd) {
-        case IDE_DMA_READ:
-            io->requests++;
-            io->finish_addr = io->addr + io->len - unaligned;
-            io->finish_len = unaligned;
-            io->finish_remain_read = true;
-            qemu_iovec_reset(&io->iov);
-            qemu_iovec_add(&io->iov, io->remainder, 0x200);
-
-            m->aiocb = blk_aio_readv(s->blk, sector_num + nsector, &io->iov, 1,
-                                     pmac_ide_transfer_cb, io);
-            break;
-        case IDE_DMA_WRITE:
-            /* cache the contents in our io struct */
-            cpu_physical_memory_read(io->addr + io->len - unaligned,
-                                     io->remainder + io->remainder_len,
-                                     unaligned);
-            break;
-        case IDE_DMA_TRIM:
-            break;
-        }
-    }
-
-    MACIO_DPRINTF("io->len = %#x\n", io->len);
-
-    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
-                     &address_space_memory);
-    qemu_sglist_add(&s->sg, io->addr, io->len);
-    io->addr += io->len + unaligned;
-    io->remainder_len = (0x200 - unaligned) & 0x1ff;
-    MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len);
-
-    /* Only subsector reads happening */
-    if (!io->len) {
-        if (!io->requests) {
-            io->requests++;
-            pmac_ide_transfer_cb(opaque, ret);
-        }
-        return;
-    }
-
-    io->len = 0;
-
-    MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n",
-                  sector_num, n, s->nsector, s->dma_cmd);
+    MACIO_DPRINTF("nsector: %d   remainder: %x\n", nsector, remainder);
+    MACIO_DPRINTF("sector: %"PRIx64"   %x\n", sector_num, nsector);
 
     switch (s->dma_cmd) {
     case IDE_DMA_READ:
-        m->aiocb = dma_blk_read(s->blk, &s->sg, sector_num,
-                                pmac_ide_transfer_cb, io);
+        pmac_dma_read(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
         break;
     case IDE_DMA_WRITE:
-        m->aiocb = dma_blk_write(s->blk, &s->sg, sector_num,
-                                 pmac_ide_transfer_cb, io);
+        pmac_dma_write(s->blk, sector_num, nsector, pmac_ide_transfer_cb, io);
         break;
     case IDE_DMA_TRIM:
-        m->aiocb = dma_blk_io(s->blk, &s->sg, sector_num,
-                              ide_issue_trim, pmac_ide_transfer_cb, io,
-                              DMA_DIRECTION_TO_DEVICE);
+        MACIO_DPRINTF("TRIM command issued!");
         break;
     }
 
-    io->requests++;
     return;
 
 done:
     if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
         block_acct_done(blk_get_stats(s->blk), &s->acct);
     }
-    io->dma_end(io);
+    io->dma_end(opaque);
 }
 
 static void pmac_ide_transfer(DBDMA_io *io)
@@ -408,8 +391,6 @@  static void pmac_ide_transfer(DBDMA_io *io)
 
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
-    } else {
-        s->io_buffer_size = 0;
     }
 
     switch (s->dma_cmd) {
@@ -425,7 +406,6 @@  static void pmac_ide_transfer(DBDMA_io *io)
         break;
     }
 
-    io->requests++;
     pmac_ide_transfer_cb(io, 0);
 }
 
@@ -585,22 +565,24 @@  static void ide_dbdma_start(IDEDMA *dma, IDEState *s,
     DBDMA_io *io;
     int i;
 
+    s->io_buffer_index = 0;
     if (s->drive_kind == IDE_CD) {
-        s->io_buffer_index = 0;
         s->io_buffer_size = s->packet_transfer_size;
+    } else {
+        s->io_buffer_size = s->nsector * 0x200;
+    }
 
-        MACIO_DPRINTF("\n\n------------ IDE transfer\n");
-        MACIO_DPRINTF("buffer_size: %x   buffer_index: %x\n",
-                      s->io_buffer_size, s->io_buffer_index);
-        MACIO_DPRINTF("lba: %x    size: %x\n", s->lba, s->io_buffer_size);
-        MACIO_DPRINTF("-------------------------\n");
+    MACIO_DPRINTF("\n\n------------ IDE transfer\n");
+    MACIO_DPRINTF("buffer_size: %x   buffer_index: %x\n",
+                  s->io_buffer_size, s->io_buffer_index);
+    MACIO_DPRINTF("lba: %x    size: %x\n", s->lba, s->io_buffer_size);
+    MACIO_DPRINTF("-------------------------\n");
 
-        for (i = 0; i < DBDMA_CHANNELS; i++) {
-            io = &dbdma->channels[i].io;
+    for (i = 0; i < DBDMA_CHANNELS; i++) {
+        io = &dbdma->channels[i].io;
 
-            if (io->opaque == m) {
-                io->remainder_len = 0;
-            }
+        if (io->opaque == m) {
+            io->remainder_len = 0;
         }
     }
 
diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h
index d7db06c..c580327 100644
--- a/include/hw/ppc/mac_dbdma.h
+++ b/include/hw/ppc/mac_dbdma.h
@@ -43,10 +43,6 @@  struct DBDMA_io {
     uint8_t remainder[0x200];
     int remainder_len;
     QEMUIOVector iov;
-    bool finish_remain_read;
-    hwaddr finish_addr;
-    hwaddr finish_len;
-    int requests;
 };
 
 /*