return 0;
}
+static int atapi_get_config(struct vm_device * dev, struct ide_channel * channel) {
+ struct ide_drive * drive = get_selected_drive(channel);
+ struct atapi_config_cmd * cmd = (struct atapi_config_cmd *)(drive->data_buf);
+ uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
+ struct atapi_config_resp * resp = (struct atapi_config_resp *)(drive->data_buf);
+ int xfer_len = 8;
+
+ memset(resp, 0, sizeof(struct atapi_config_resp));
+
+ resp->data_len = le_to_be_32(xfer_len - 4);
+
+ if (alloc_len < xfer_len) {
+ xfer_len = alloc_len;
+ }
+
+ atapi_setup_cmd_resp(dev, channel, xfer_len);
+
+ return 0;
+}
+
static int atapi_read_toc(struct vm_device * dev, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_rd_toc_cmd * cmd = (struct atapi_rd_toc_cmd *)(drive->data_buf);
uint16_t alloc_len = be_to_le_16(cmd->alloc_len);
-
-
struct atapi_rd_toc_resp * resp = (struct atapi_rd_toc_resp *)(drive->data_buf);
- resp->data_len = 10;
+ int xfer_len = 12;
- return -1;
+ memset(resp, 0, sizeof(struct atapi_rd_toc_resp));
+
+ resp->data_len = le_to_be_16(10);
+ resp->first_track_num = 1;
+ resp->last_track_num = 1;
+
+ // we don't handle multi session
+ // we'll just treat it the same as single session
+ if ((cmd->format == 0) || (cmd->format == 1)) {
+ memset(&(resp->track_descs[0]), 0, 8);
+
+ if (alloc_len < xfer_len) {
+ xfer_len = alloc_len;
+ }
+
+ atapi_setup_cmd_resp(dev, channel, xfer_len);
+ } else {
+ PrintError("Unhandled Format (%d)\n", cmd->format);
+ return -1;
+ }
+ return 0;
}
}
break;
+ case 0x46: // get configuration
+ if (atapi_get_config(dev, channel) == -1) {
+ PrintError("IDE: Error getting CDROM Configuration (%x)\n", cmd);
+ return -1;
+ }
+ break;
+
+ case 0x51: // read disk info
+ // no-op to keep the Linux CD-ROM driver happy
+ PrintDebug("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
+ atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_INV_CMD_FIELD);
+ ide_raise_irq(dev, channel);
+ break;
+
+
+
case 0xa8: // read(12)
case 0x2b: // seek
case 0x1e: // lock door
case 0x42: // read sub-channel
- case 0x51: // read disk info
+
case 0x55: // mode select
case 0xba: // scan
case 0xbb: // set cd speed
case 0x4e: // stop play/scan
- case 0x46: // ???
+
case 0x4a: // ???
default:
PrintError("Unhandled ATAPI command %x\n", cmd);
// 32 bits access
drive_id->dword_io = 1;
+ // enable DMA access
+ drive_id->dma_enable = 1;
+
// enable LBA access
drive_id->lba_enable = 1;
+ drive_id->rw_multiples = 0x80ff;
// words 64-70, 54-58 valid
- drive_id->buf[53] = 0x0003;
+ drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
// copied from CFA540A
- drive_id->buf[63] = 0x0103; // variable (DMA stuff)
- drive_id->buf[64] = 0x0001; // PIO
+ // drive_id->buf[63] = 0x0103; // variable (DMA stuff)
+ drive_id->buf[63] = 0x0000; // variable (DMA stuff)
+ // drive_id->buf[64] = 0x0001; // PIO
drive_id->buf[65] = 0x00b4;
drive_id->buf[66] = 0x00b4;
drive_id->buf[67] = 0x012c;
drive_id->buf[71] = 30; // faked
drive_id->buf[72] = 30; // faked
- drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
+ // drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
+ drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
+
+ drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
}