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