Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Updated NE2000 and RTL8139 to conform to interface changes
[palacios.git] / palacios / src / devices / atapi.h
index 7d68c90..b41e9df 100644 (file)
@@ -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