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);
}
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));
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));
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
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));
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;
}
+
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);
}
+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)
}
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