Revision b42ec42d hw/ide.c
b/hw/ide.c | ||
---|---|---|
3429 | 3429 |
|
3430 | 3430 |
typedef struct MACIOIDEState { |
3431 | 3431 |
IDEState ide_if[2]; |
3432 |
void *dbdma; |
|
3433 | 3432 |
int stream_index; |
3434 | 3433 |
} MACIOIDEState; |
3435 | 3434 |
|
3436 |
static int pmac_atapi_read(DBDMA_transfer *info, DBDMA_transfer_cb cb)
|
|
3435 |
static void pmac_atapi_read(DBDMA_io *io)
|
|
3437 | 3436 |
{ |
3438 |
MACIOIDEState *m = info->opaque;
|
|
3437 |
MACIOIDEState *m = io->opaque; |
|
3439 | 3438 |
IDEState *s = m->ide_if->cur_drive; |
3440 |
int ret; |
|
3441 |
|
|
3442 |
if (s->lba == -1) |
|
3443 |
return 0; |
|
3444 |
|
|
3445 |
info->buf_pos = 0; |
|
3439 |
int ret, len; |
|
3446 | 3440 |
|
3447 |
while (info->buf_pos < info->len && s->packet_transfer_size > 0) { |
|
3441 |
while (io->len > 0 && |
|
3442 |
s->packet_transfer_size > 0) { |
|
3448 | 3443 |
|
3449 |
ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size); |
|
3444 |
len = s->cd_sector_size; |
|
3445 |
ret = cd_read_sector(s->bs, s->lba, s->io_buffer, len); |
|
3450 | 3446 |
if (ret < 0) { |
3447 |
io->dma_end(io); |
|
3451 | 3448 |
ide_transfer_stop(s); |
3452 | 3449 |
ide_atapi_io_error(s, ret); |
3453 |
return info->buf_pos;
|
|
3450 |
return; |
|
3454 | 3451 |
} |
3455 | 3452 |
|
3456 |
info->buf = s->io_buffer + m->stream_index; |
|
3457 |
|
|
3458 |
info->buf_len = s->cd_sector_size; |
|
3459 |
if (info->buf_pos + info->buf_len > info->len) |
|
3460 |
info->buf_len = info->len - info->buf_pos; |
|
3453 |
if (len > io->len) |
|
3454 |
len = io->len; |
|
3461 | 3455 |
|
3462 |
cb(info); |
|
3456 |
cpu_physical_memory_write(io->addr, |
|
3457 |
s->io_buffer + m->stream_index, len); |
|
3463 | 3458 |
|
3464 | 3459 |
/* db-dma can ask for 512 bytes whereas block size is 2048... */ |
3465 | 3460 |
|
3466 |
m->stream_index += info->buf_len;
|
|
3461 |
m->stream_index += len; |
|
3467 | 3462 |
s->lba += m->stream_index / s->cd_sector_size; |
3468 | 3463 |
m->stream_index %= s->cd_sector_size; |
3469 | 3464 |
|
3470 |
info->buf_pos += info->buf_len; |
|
3471 |
s->packet_transfer_size -= info->buf_len; |
|
3465 |
io->len -= len; |
|
3466 |
io->addr += len; |
|
3467 |
s->packet_transfer_size -= len; |
|
3472 | 3468 |
} |
3469 |
|
|
3470 |
if (io->len <= 0) |
|
3471 |
io->dma_end(io); |
|
3472 |
|
|
3473 | 3473 |
if (s->packet_transfer_size <= 0) { |
3474 | 3474 |
s->status = READY_STAT | SEEK_STAT; |
3475 | 3475 |
s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO |
3476 | 3476 |
| ATAPI_INT_REASON_CD; |
3477 | 3477 |
ide_set_irq(s); |
3478 | 3478 |
} |
3479 |
|
|
3480 |
return info->buf_pos; |
|
3481 | 3479 |
} |
3482 | 3480 |
|
3483 |
static int pmac_ide_transfer(DBDMA_transfer *info, |
|
3484 |
DBDMA_transfer_cb cb) |
|
3481 |
static void pmac_ide_transfer(DBDMA_io *io) |
|
3485 | 3482 |
{ |
3486 |
MACIOIDEState *m = info->opaque;
|
|
3483 |
MACIOIDEState *m = io->opaque; |
|
3487 | 3484 |
IDEState *s = m->ide_if->cur_drive; |
3488 | 3485 |
int64_t sector_num; |
3489 | 3486 |
int ret, n; |
3487 |
int len; |
|
3490 | 3488 |
|
3491 |
if (s->is_cdrom) |
|
3492 |
return pmac_atapi_read(info, cb); |
|
3489 |
if (s->is_cdrom) { |
|
3490 |
pmac_atapi_read(io); |
|
3491 |
return; |
|
3492 |
} |
|
3493 | 3493 |
|
3494 |
info->buf = s->io_buffer; |
|
3495 |
info->buf_pos = 0; |
|
3496 |
while (info->buf_pos < info->len && s->nsector > 0) { |
|
3494 |
while (io->len > 0 && s->nsector > 0) { |
|
3497 | 3495 |
|
3498 | 3496 |
sector_num = ide_get_sector(s); |
3499 | 3497 |
|
... | ... | |
3501 | 3499 |
if (n > IDE_DMA_BUF_SECTORS) |
3502 | 3500 |
n = IDE_DMA_BUF_SECTORS; |
3503 | 3501 |
|
3504 |
info->buf_len = n << 9;
|
|
3505 |
if (info->buf_pos + info->buf_len > info->len)
|
|
3506 |
info->buf_len = info->len - info->buf_pos;
|
|
3507 |
n = info->buf_len >> 9;
|
|
3502 |
len = n << 9; |
|
3503 |
if (len > io->len)
|
|
3504 |
len = io->len;
|
|
3505 |
n = (len + 511) >> 9;
|
|
3508 | 3506 |
|
3509 | 3507 |
if (s->is_read) { |
3510 | 3508 |
ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); |
3511 |
if (ret == 0) |
|
3512 |
cb(info); |
|
3509 |
cpu_physical_memory_write(io->addr, s->io_buffer, len); |
|
3513 | 3510 |
} else { |
3514 |
cb(info);
|
|
3511 |
cpu_physical_memory_read(io->addr, s->io_buffer, len);
|
|
3515 | 3512 |
ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); |
3516 | 3513 |
} |
3517 | 3514 |
|
3518 | 3515 |
if (ret != 0) { |
3516 |
io->dma_end(io); |
|
3519 | 3517 |
ide_rw_error(s); |
3520 |
return info->buf_pos;
|
|
3518 |
return; |
|
3521 | 3519 |
} |
3522 | 3520 |
|
3523 |
info->buf_pos += n << 9; |
|
3521 |
io->len -= len; |
|
3522 |
io->addr += len; |
|
3524 | 3523 |
ide_set_sector(s, sector_num + n); |
3525 | 3524 |
s->nsector -= n; |
3526 | 3525 |
} |
3527 | 3526 |
|
3527 |
if (io->len <= 0) |
|
3528 |
io->dma_end(io); |
|
3529 |
|
|
3528 | 3530 |
if (s->nsector <= 0) { |
3529 | 3531 |
s->status = READY_STAT | SEEK_STAT; |
3530 | 3532 |
ide_set_irq(s); |
3531 | 3533 |
} |
3532 | 3534 |
|
3533 |
return info->buf_pos;
|
|
3535 |
return; |
|
3534 | 3536 |
} |
3535 | 3537 |
|
3536 | 3538 |
/* PowerMac IDE memory IO */ |
... | ... | |
3709 | 3711 |
d = qemu_mallocz(sizeof(MACIOIDEState)); |
3710 | 3712 |
ide_init2(d->ide_if, hd_table[0], hd_table[1], irq); |
3711 | 3713 |
|
3712 |
if (dbdma) { |
|
3713 |
d->dbdma = dbdma; |
|
3714 |
if (dbdma) |
|
3714 | 3715 |
DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, d); |
3715 |
} |
|
3716 | 3716 |
|
3717 | 3717 |
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, |
3718 | 3718 |
pmac_ide_write, d); |
Also available in: Unified diff