Am 01.07.2013 um 02:13 hat Alexander Graf geschrieben:
> The DBDMA engine really just reads bytes from a producing device (IDE
> in our case) and shoves these bytes into memory. It doesn't care whether
> any alignment takes place or not.
> 
> Our code today however assumes that block accesses always happen on
> sector (512 byte) boundaries. This is a fair assumption for most cases.
> 
> However, Mac OS X really likes to do unaligned, incomplete accesses
> that it finishes with the next DMA request.
> 
> So we need to read / write the unaligned bits independent of the actual
> asynchronous request, because that one can only handle 512-byte-aligned
> data. We also need to cache these unaligned sectors until the next DMA
> request, at which point the data might be successfully flushed from the
> pipe.
> 
> Signed-off-by: Alexander Graf <ag...@suse.de>

> @@ -98,14 +122,40 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int 
> ret)
>  
>      /* launch next transfer */
>  
> -    MACIO_DPRINTF("io->len = %#x\n", io->len);
> +    /* 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 sector_num = (s->lba << 2) + (s->io_buffer_index >> 9);
> +        int nsector = io->len >> 9;
>  
> -    s->io_buffer_size = io->len;
> +        MACIO_DPRINTF("precopying unaligned %d bytes to %#lx\n",
> +                      unaligned, io->addr + io->len - unaligned);
> +
> +        bdrv_read(s->bs, sector_num + nsector, io->remainder, 1);

I haven't really reviewed the general logic, but not using the return
value of bdrv_read() and bdrv_write() is most definitely wrong, I/O can
fail. More instances of the same bug follow.

Kevin

Reply via email to