} __attribute__((packed));
+struct atapi_inquiry_cmd {
+ uint8_t atapi_cmd; // 0x12
+ uint8_t evpd : 1;
+ uint8_t obsolete : 1;
+ uint8_t rsvd : 3;
+ uint8_t lun : 3;
+ uint8_t pg_op_code;
+ uint16_t alloc_len;
+ uint8_t link : 1;
+ uint8_t flag : 1;
+ uint8_t naca : 1;
+ uint8_t rsvd5 : 3;
+ uint8_t vendor_specific : 2;
+} __attribute__((packed));
+
+
+struct atapi_inquiry_resp {
+#define DEV_TYPE_CDROM 0x05
+ uint8_t dev_type : 5;
+ uint8_t rsvd1 : 3; // not used in ATAPI
+ uint8_t rsvd2 : 7;
+ uint8_t removable_media : 1;
+ uint8_t version;
+ uint8_t resp_data_fmt : 4;
+ uint8_t atapi_trans_ver : 4;
+ uint8_t additional_len;
+ uint8_t protect : 1;
+ uint8_t rsvd3 : 2;
+ uint8_t spc_3pc : 1; // no idea
+ uint8_t tpgs : 2;
+ uint8_t acc : 1;
+ uint8_t sccs : 1;
+ uint8_t addr16 : 1;
+ uint8_t addr32 : 1;
+ uint8_t ack_req_q : 1;
+ uint8_t media_changer : 1;
+ uint8_t multi_port : 1;
+ uint8_t vs : 1;
+ uint8_t enc_services : 1;
+ uint8_t basic_queueing : 1;
+ uint8_t rsvd4;
+ uint8_t vs2 : 1;
+ uint8_t cmd_queue : 1;
+ uint8_t tran_dis : 1;
+ uint8_t linked : 1;
+ uint8_t sync : 1;
+ uint8_t wbus_16 : 1;
+ uint8_t wbus_32 : 1;
+ uint8_t rel_addr : 1;
+ uint8_t rsvd5;
+ uint8_t t10_vendor_id[8];
+ uint8_t product_id[16];
+ uint8_t product_rev[4];
+ /* We'll ignore these for now...
+ uint8_t vendor_specific[20];
+ uint8_t ius : 1;
+ uint8_t qas : 1;
+ uint8_t clocking : 2;
+ uint8_t rsvd6 : 4;
+ uint8_t rsvd7;
+ uint16_t version_desc[8];
+ */
+} __attribute__((packed));
+
+
+
struct atapi_error_recovery {
uint8_t page_code : 6;
uint8_t rsvd : 1;
}
+static int atapi_inquiry(struct vm_device * dev, 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);
+ uint16_t alloc_len = be_to_le_16(inquiry_cmd->alloc_len);
+ struct atapi_inquiry_resp * resp = (struct atapi_inquiry_resp *)(drive->data_buf);
+ int xfer_len = sizeof(struct atapi_inquiry_resp);
+ const char * vendor_id = "VTAB ";
+ const char * product_id = "Turbo CD-ROM ";
+ const char * product_rev = "1.0 ";
+
+ memset(resp, 0, sizeof(struct atapi_inquiry_resp));
+
+ resp->dev_type = DEV_TYPE_CDROM;
+ resp->removable_media = 1;
+ resp->resp_data_fmt = 0x1;
+ resp->atapi_trans_ver = 0x2;
+ resp->additional_len = 31;
+
+ memcpy(resp->t10_vendor_id, vendor_id, strlen(vendor_id));
+ memcpy(resp->product_id, product_id, strlen(product_id));
+ memcpy(resp->product_rev, product_rev, strlen(product_rev));
+
+ if (alloc_len < xfer_len) {
+ xfer_len = alloc_len;
+ }
+
+ atapi_setup_cmd_resp(dev, channel, xfer_len);
+
+ return 0;
+}
+
+
static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
uint8_t cmd = drive->data_buf[0];
ide_raise_irq(dev, channel);
break;
-
+ case 0x12: // inquiry
+ if (atapi_inquiry(dev, channel) == -1) {
+ PrintError("IDE: Error in ATAPI inquiry (%x)\n", cmd);
+ return -1;
+ }
+ break;
case 0xa8: // read(12)
case 0x1b: // start/stop drive
case 0xbd: // mechanism status
- case 0x12: // inquiry
case 0xbe: // read cd