X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fatapi.h;h=b41e9dff5ee72a52d69092c7dc1f7167a03b27b9;hb=f7e83e5d2d00ba107ccda346da4660ab523471bb;hp=7d68c902efc5e4fd2d65ed88d51f86f574af422e;hpb=0139d9a5b6beca02fa6c5a44947e1326e2edee24;p=palacios.git diff --git a/palacios/src/devices/atapi.h b/palacios/src/devices/atapi.h index 7d68c90..b41e9df 100644 --- a/palacios/src/devices/atapi.h +++ b/palacios/src/devices/atapi.h @@ -75,9 +75,12 @@ static void atapi_setup_cmd_resp(struct ide_internal * ide, struct ide_channel * drive->irq_flags.c_d = 0; channel->status.busy = 0; - channel->status.data_req = 1; channel->status.error = 0; + if (drive->transfer_length > 0) { + channel->status.data_req = 1; + } + ide_raise_irq(ide, channel); } @@ -129,8 +132,9 @@ static void atapi_cmd_nop(struct ide_internal * ide, struct ide_channel * channe static int atapi_read_chunk(struct ide_internal * ide, struct ide_channel * channel) { struct ide_drive * drive = get_selected_drive(channel); - int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE, -drive->private_data); + int ret = drive->ops->read(drive->data_buf, + drive->current_lba * ATAPI_BLOCK_SIZE, + ATAPI_BLOCK_SIZE, drive->private_data); if (ret == -1) { PrintError("IDE: Error reading CD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba)); @@ -148,7 +152,7 @@ static int atapi_update_data_buf(struct ide_internal * ide, struct ide_channel * case 0x28: // read(10) case 0xa8: // read(12) - // Update lba address to point to next block + // Update lba address to point to next block drive->current_lba++; // read the next block @@ -170,7 +174,7 @@ static int atapi_read10(struct guest_info * core, uint32_t lba = be_to_le_32(cmd->lba); uint16_t xfer_len = be_to_le_16(cmd->xfer_len); - PrintDebug("READ10: XferLen=%d\n", xfer_len); + PrintDebug("READ10: XferLen=%d ; LBA=%x \n", xfer_len, lba ); /* Check if cd is ready * if not: atapi_cmd_error(... ATAPI_SEN_NOT_RDY, ASC_MEDIA_NOT_PRESENT) @@ -181,7 +185,7 @@ static int atapi_read10(struct guest_info * core, return 0; } - if (lba + xfer_len > drive->ops->get_capacity(drive->private_data)) { + if ((lba + xfer_len) > (drive->ops->get_capacity(drive->private_data) / ATAPI_BLOCK_SIZE)) { PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n", lba, xfer_len, lba + xfer_len, (uint32_t)drive->ops->get_capacity(drive->private_data)); @@ -190,8 +194,7 @@ static int atapi_read10(struct guest_info * core, return 0; } - // PrintDebug("Reading %d blocks from LBA 0x%x\n", xfer_len, lba); - + // PrintDebug("Reading %d blocks from LBA 0x%x\n", xfer_len, lba); drive->current_lba = lba; // Update the request length value in the cylinder registers @@ -244,7 +247,7 @@ static int atapi_get_capacity(struct ide_internal * ide, struct ide_channel * ch struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf); uint32_t capacity = drive->ops->get_capacity(drive->private_data); - resp->lba = le_to_be_32(capacity); + resp->lba = le_to_be_32((capacity / ATAPI_BLOCK_SIZE) - 1); resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE); atapi_setup_cmd_resp(ide, channel, sizeof(struct atapi_rd_capacity_resp)); @@ -267,6 +270,8 @@ static int atapi_get_config(struct ide_internal * ide, struct ide_channel * chan xfer_len = alloc_len; } + V3_Print("ATAPI Get config: xfer_len=%d\b", xfer_len); + atapi_setup_cmd_resp(ide, channel, xfer_len); return 0; @@ -460,6 +465,7 @@ static int atapi_mode_sense(struct ide_internal * ide, struct ide_channel * chan } + static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel) { struct ide_drive * drive = get_selected_drive(channel); struct atapi_inquiry_cmd * inquiry_cmd = (struct atapi_inquiry_cmd *)(drive->data_buf); @@ -492,6 +498,28 @@ static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel } +static int atapi_mech_status(struct ide_internal * ide, struct ide_channel * channel) { + struct ide_drive * drive = get_selected_drive(channel); + struct atapi_mech_status_cmd * status_cmd = (struct atapi_mech_status_cmd *)(drive->data_buf); + uint16_t alloc_len = be_to_le_16(status_cmd->alloc_len); + struct atapi_mech_status_resp * resp = (struct atapi_mech_status_resp *)(drive->data_buf); + int xfer_len = sizeof(struct atapi_mech_status_resp); + + memset(resp, 0, sizeof(struct atapi_mech_status_resp)); + + resp->lba = le_to_be_32(1); + resp->slot_table_len = le_to_be_16(0); + + if (alloc_len < xfer_len) { + xfer_len = alloc_len; + } + + atapi_setup_cmd_resp(ide, channel, xfer_len); + + return 0; +} + + static int atapi_cmd_is_data_op(uint8_t cmd) { switch (cmd) { case 0x28: // read (10) @@ -583,11 +611,18 @@ static int atapi_handle_packet(struct guest_info * core, struct ide_internal * i } break; + case 0xbd: // mechanism status + if (atapi_mech_status(ide, channel) == -1) { + PrintError("IDE: error in ATAPI Mechanism status query (%x)\n", cmd); + return -1; + } + break; + + case 0xa8: // read(12) case 0x1b: // start/stop drive - case 0xbd: // mechanism status case 0xbe: // read cd