From: Jack Lange <jarusl@cs.northwestern.edu>
Date: Tue, 23 Jun 2009 19:21:43 +0000 (-0500)
Subject: added ATAPI inquiry command
X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=7b22bd6ad6a5bb413fd38e9ed7df668e34c052bb;p=palacios.git

added ATAPI inquiry command
---

diff --git a/palacios/src/devices/atapi-types.h b/palacios/src/devices/atapi-types.h
index 7635998..300e618 100644
--- a/palacios/src/devices/atapi-types.h
+++ b/palacios/src/devices/atapi-types.h
@@ -188,6 +188,72 @@ struct atapi_rd_toc_resp {
 } __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;
diff --git a/palacios/src/devices/atapi.h b/palacios/src/devices/atapi.h
index ec613d7..78e0751 100644
--- a/palacios/src/devices/atapi.h
+++ b/palacios/src/devices/atapi.h
@@ -404,6 +404,38 @@ static int atapi_mode_sense(struct vm_device * dev, struct ide_channel * channel
 }
 
 
+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];
@@ -468,14 +500,18 @@ static int atapi_handle_packet(struct vm_device * dev, struct ide_channel * chan
 	   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