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.


Merge branch 'devel'
[palacios.git] / palacios / src / devices / ramdisk.c
index 4d59b37..5879875 100644 (file)
@@ -1,31 +1,57 @@
-/*
- * Zheng Cui
- * cuizheng@cs.unm.edu
- * July 2008
+/* 
+ *
+ *   Copyright (C) 2002  MandrakeSoft S.A.
+ *
+ *     MandrakeSoft S.A.
+ *     43, rue d'Aboukir
+ *     75002 Paris - France
+ *     http://www.linux-mandrake.com/
+ *     http://www.mandrakesoft.com/
+ *
+ *   This library is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU Lesser General Public
+ *   License as published by the Free Software Foundation; either
+ *   version 2 of the License, or (at your option) any later version.
+ *
+ *   This library is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *   Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Major modifications made for the V3VEE project
+ * 
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico.  You can find out more at 
+ * http://www.v3vee.org
+ * 
+ * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
+ * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved for original changes
+ * 
  */
 
+
 #include <devices/ramdisk.h>
 #include <palacios/vmm.h>
 #include <devices/cdrom.h>
 #include <devices/ide.h>
-#include <devices/atapi.h>
 
-#ifdef DEBUG_RAMDISK
-//#define Ramdisk_Print(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
-#define Ramdisk_Print(_f, _a...) PrintTrace("\nramdisk.c " _f, ## _a)
-#else 
-#define Ramdisk_Print(_f, _a...)
+
+#ifndef TRACE_RAMDISK
+#undef PrintTrace
+#define PrintTrace(fmt, args...)
 #endif
 
-#define RD_PANIC(_f, _a...)     \
-  do {                       \
-    PrintDebug("ramdisk.c(%d) " _f, __LINE__, ## _a);  \
-      while(1);              \
-    }                        \
-   while(0)                                                            
-    
-#define RD_ERROR(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
 
+#ifndef DEBUG_RAMDISK
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
 
 
 
@@ -37,7 +63,7 @@
  */
 #define INDEX_PULSE_CYCLE 10
 
-#define MAX_ATA_CHANNEL 4
+
 
 
 #define INTR_REASON_BIT_ERR           0x01
 #define SEC_ADDR_REG_PORT     0x377
 
 
-
-
-
 #define PACKET_SIZE 12
 
 
 
-// FLAT MODE
-// Open a image. Returns non-negative if successful.
-//int open (const char* pathname);
-
-// Open an image with specific flags. Returns non-negative if successful.
-int rd_open (const char* pathname, int flags);
-
-// Close the image.
-void rd_close ();
-
-// Position ourselves. Return the resulting offset from the
-// beginning of the file.
-off_t rd_lseek (off_t offset, int whence);
-
-// Read count bytes to the buffer buf. Return the number of
-// bytes read (count).
-ssize_t rd_read (void* buf, size_t count);
-
-// Write count bytes from buf. Return the number of bytes
-// written (count).
-ssize_t rd_write (const void* buf, size_t count);
-
-
-
-struct  ramdisk_t {
-  struct channel_t channels[MAX_ATA_CHANNEL];
-};
-
-
-/*
- * Debug facilities
- */
-
-#define ATA_DETECT                     0xf0 //0X3E8
-#define ATA_RESET                      0xf1 //0X3E9
-#define ATA_CMD_DATA_IN                0xf2 //0X3EA
-#define ATA_CMD_DATA_OUT               0xf3 //0X3EB
-#define ATA_CMD_PACKET                 0xf4 //0X3EC
-#define ATAPI_GET_SENSE                0xf5 //0X3ED
-#define ATAPI_IS_READY                 0xf6 //0X3EE
-#define ATAPI_IS_CDROM                 0xf7 //0X3EF
-
-#define CDEMU_INIT                     0xf8 //0X2E8
-#define CDEMU_ISACTIVE                 0xf9 //0X2E9
-#define CDEMU_EMULATED_DRIVE           0xfa //0X2EA
-#define CDROM_BOOT                     0xfb //0X2EB
-
-
-#define HARD_DRIVE_POST                0xfc //0X2EC
-
-
-#define ATA_DEVICE_NO                  0xfd //0X2ED
-#define ATA_DEVICE_TYPE                0xfe //0X2ED
-
-#define INT13_HARDDISK                 0xff //0x2ef
-#define INT13_CDROM                    0xe0 //0x2f8
-#define INT13_CDEMU                    0xe1 //0x2f9
-#define INT13_ELTORITO                 0xe2 //0x2fa
-#define INT13_DISKETTE_FUNCTION        0xe3 //0x2fb
-
-
-
-
 static const char cdrom_str[] = "CD-ROM";
 static const char harddisk_str[] = "HARDDISK";
 static const char none_str[] = "NONE";
@@ -204,6 +164,13 @@ static inline void write_lba_mode(struct channel_t * channel, uchar_t value) {
 }
 
 
+static inline uint_t get_channel_no(struct ramdisk_t * ramdisk, struct channel_t * channel) {
+  return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t));
+}
+
+static inline uint_t get_drive_no(struct channel_t * channel, struct drive_t * drive) {
+  return (((uchar_t *)drive - (uchar_t*)(channel->drives)) /  sizeof(struct drive_t));
+}
 
 static inline struct drive_t * get_selected_drive(struct channel_t * channel) {
   return &(channel->drives[channel->drive_select]);
@@ -313,11 +280,34 @@ static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t *
 static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value);
 
 
+
+
+static int handle_atapi_packet_command(struct vm_device * dev, 
+                                      struct channel_t * channel, 
+                                      ushort_t val);
+
+static int rd_init_send_atapi_command(struct vm_device * dev, 
+                                     struct channel_t * channel, 
+                                     Bit8u command, int req_length, 
+                                     int alloc_length, bool lazy);
+
+static void rd_ready_to_send_atapi(struct vm_device * dev, 
+                                  struct channel_t * channel);
+
+static void rd_atapi_cmd_error(struct vm_device * dev, 
+                              struct channel_t * channel, 
+                              sense_t sense_key, asc_t asc);
+
+static void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel);
+static void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel);
+
+
+
 /*
  * Interrupt handling
  */
 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel);
-static void rd_lower_irq(struct vm_device *dev, Bit32u irq);
+static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel);
 
 
 
@@ -328,21 +318,86 @@ static void rd_lower_irq(struct vm_device *dev, Bit32u irq);
 
 
 #ifdef DEBUG_RAMDISK
-static void rd_print_state(struct ramdisk_t *ramdisk,  struct vm_device *dev)
+static void rd_print_state(struct ramdisk_t *ramdisk);
 static int check_bit_fields(struct controller_t * controller);
 #endif
+
+
 ////////////////////////////////////////////////////////////////////
 
 
 
 
 
+int v3_ramdisk_register_cdrom(struct vm_device * dev, uint_t busID, uint_t driveID, struct cdrom_ops* cd, void * private_data) {
+  struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
+  struct channel_t * channel = &(ramdisk->channels[busID]);
+  struct drive_t * drive = &(channel->drives[driveID]);
+  struct controller_t * controller = &(drive->controller);
+
+
+  
+  if (drive->device_type != IDE_NONE) {
+    PrintError("Device already registered at this location\n");
+    return -1;
+  }
+
+
+  channel->irq =  15;
+
+  // Make model string
+  strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
+
+  while (strlen((char *)(drive->model_no)) < 40) {
+    strcat ((char*)(drive->model_no), " ");
+  }
+  
+  PrintDebug("CDROM on target %d/%d\n", busID, driveID);
+  
+  drive->device_type = IDE_CDROM;
+  drive->cdrom.locked = 0;
+  drive->sense.sense_key = SENSE_NONE;
+  drive->sense.asc = 0;
+  drive->sense.ascq = 0;
+  
+  drive->private_data = private_data;
+
+
+#ifdef DEBUG_RAMDISK
+  if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) {
+    PrintError("interrupt reason: bit field error\n");
+    return INTR_REASON_BIT_ERR;
+  }
+#endif
+  
+  controller->sector_count = 0;
+
+  drive->cdrom.cd = cd;
+  
+  PrintDebug("\t\tCD on ata%d-%d: '%s'\n", 
+            busID, 
+            driveID, "");
+  
+  if(drive->cdrom.cd->insert_cdrom(drive->private_data)) {
+    PrintDebug("\t\tMedia present in CD-ROM drive\n");
+    drive->cdrom.ready = 1;
+    drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data);
+    PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity);
+  } else {                 
+    PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n");
+    drive->cdrom.ready = 0;
+  }
+  
+  return 0;
+}
+
+
 static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) {
   uint_t channel_num; 
   uint_t device;
   struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
 
-  Ramdisk_Print("[rd_init_harddrive]\n");
+  PrintDebug("[rd_init_harddrive]\n");
 
   for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) {
     memset((char *)(channels + channel_num), 0, sizeof(struct channel_t));
@@ -396,67 +451,12 @@ static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) {
         strcat ((char*)(drive->model_no), " ");
       }
 
-
-      
-      
-      if (channel_num == 1) {
-
-       channel->ioaddr1 = 0x170;
-       channel->ioaddr2 = 0x370;
-       channel->irq =  15;
-       channel->drive_select = 0;
-       
-       if (device == 0) {
-         // Make model string
-         strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
-         while (strlen((char *)(drive->model_no)) < 40) {
-           strcat ((char*)(drive->model_no), " ");
-         }
-         
-         Ramdisk_Print("CDROM on target %d/%d\n", channel, device);
-         
-         drive->device_type = IDE_CDROM;
-         drive->cdrom.locked = 0;
-         drive->sense.sense_key = SENSE_NONE;
-         drive->sense.asc = 0;
-         drive->sense.ascq = 0;
-         
-#ifdef RAMDISK_DEBUG
-         if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) {
-           Ramdisk_Print("interrupt reason: bit field error\n");
-           return INTR_REASON_BIT_ERR;
-         }
-#endif
-         
-         controller->sector_count = 0;
-
-         // allocate low level driver
-         drive->cdrom.cd = (struct cdrom_interface*)V3_Malloc(sizeof(struct cdrom_interface));
-         Ramdisk_Print("cd = %x\n", drive->cdrom.cd);
-         V3_ASSERT(drive->cdrom.cd != NULL);
-         
-         struct cdrom_interface * cdif = drive->cdrom.cd;
-         memset(cdif, 0, sizeof(struct cdrom_interface));
-         init_cdrom(cdif);
-         cdif->ops.init(cdif);
-
-         Ramdisk_Print("\t\tCD on ata%d-%d: '%s'\n",channel, device, "");
-         
-         if((drive->cdrom.cd->ops).insert_cdrom(cdif, NULL)) {
-           Ramdisk_Print("\t\tMedia present in CD-ROM drive\n");
-           drive->cdrom.ready = 1;
-           drive->cdrom.capacity = drive->cdrom.cd->ops.capacity(cdif);
-         } else {                  
-           Ramdisk_Print("\t\tCould not locate CD-ROM, continuing with media not present\n");
-           drive->cdrom.ready = 0;
-         }
-         
-       }//if device = 0
-      }//if channel = 0
     }//for device
   }//for channel
 
-
+#ifdef DEBUG_RAMDISK
+  rd_print_state(ramdisk);
+#endif
   return 0;
 }
 
@@ -481,7 +481,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
   struct channel_t * channel = NULL;
   struct drive_t * drive = NULL;
   struct controller_t * controller = NULL;
-  struct cdrom_interface *cdif = drive->cdrom.cd;
+
 
 
   if (is_primary_port(ramdisk, port)) {
@@ -497,6 +497,12 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
   controller = &(drive->controller);
 
 
+  PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d current cmd=0x%x\n", 
+            port, 
+            get_channel_no(ramdisk, channel),
+            get_drive_no(channel, drive), 
+            controller->current_command);
+
   switch (controller->current_command) {
   case 0xec:    // IDENTIFY DEVICE
   case 0xa1:
@@ -542,7 +548,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
       uint_t index = controller->buffer_index;
 
       
-      Ramdisk_Print("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", 
+      PrintTrace("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", 
                    drive->atapi.command, 
                    index, 
                    drive->cdrom.remaining_blocks);
@@ -551,34 +557,37 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
       if (index >= 2048) {
        
        if (index > 2048) {
-         RD_PANIC("\t\tindex > 2048 : 0x%x\n",index);
+         PrintError("\t\tindex > 2048 : 0x%x\n", index);
+         return -1;
        }
        
        switch (drive->atapi.command) {
        case 0x28: // read (10)
        case 0xa8: // read (12)
-         
-         if (!(drive->cdrom.ready)) {
-           RD_PANIC("\t\tRead with CDROM not ready\n");
-         } 
-         
-         drive->cdrom.cd->ops.read_block(cdif, controller->buffer,
-                                         drive->cdrom.next_lba);
-         drive->cdrom.next_lba++;
-         drive->cdrom.remaining_blocks--;
-         
-         
-         if (!(drive->cdrom.remaining_blocks)) {
-           Ramdisk_Print("\t\tLast READ block loaded {CDROM}\n");
-         } else {
-           Ramdisk_Print("\t\tREAD block loaded (%d remaining) {CDROM}\n",
-                         drive->cdrom.remaining_blocks);
+         {
+    
+           if (!(drive->cdrom.ready)) {
+             PrintError("\t\tRead with CDROM not ready\n");
+             return -1;
+           } 
+           
+           drive->cdrom.cd->read_block(drive->private_data, controller->buffer,
+                                       drive->cdrom.next_lba);
+           drive->cdrom.next_lba++;
+           drive->cdrom.remaining_blocks--;
+           
+           
+           if (!(drive->cdrom.remaining_blocks)) {
+             PrintDebug("\t\tLast READ block loaded {CDROM}\n");
+           } else {
+             PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n",
+                        drive->cdrom.remaining_blocks);
+           }
+           
+           // one block transfered, start at beginning
+           index = 0;
+           break;
          }
-         
-         // one block transfered, start at beginning
-         index = 0;
-         break;
-         
        default: // no need to load a new block
          break;
        }
@@ -624,7 +633,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
        if (drive->atapi.total_bytes_remaining > 0) {
          // one or more blocks remaining (works only for single block commands)
          
-         Ramdisk_Print("\t\tPACKET drq bytes read\n");
+         PrintDebug("\t\tPACKET drq bytes read\n");
          controller->interrupt_reason.i_o = 1;
          controller->status.busy = 0;
          controller->status.drq = 1;
@@ -639,7 +648,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
          rd_raise_interrupt(dev, channel);
        } else {
          // all bytes read
-         Ramdisk_Print("\t\tPACKET all bytes read\n");
+         PrintDebug("\t\tPACKET all bytes read\n");
          
          controller->interrupt_reason.i_o = 1;
          controller->interrupt_reason.c_d = 1;
@@ -657,7 +666,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de
     }
 
   default:
-    Ramdisk_Print("\t\tread need support more command: %02x\n", controller->current_command);
+    PrintError("\t\tunsupported command: %02x\n", controller->current_command);
     break;
   }
 
@@ -685,25 +694,36 @@ static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_d
   drive = get_selected_drive(channel);
   controller = &(drive->controller);
 
-  Ramdisk_Print("\t\twrite port 170\n");
-  
+
+  PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n", 
+            port, controller->current_command);
+
+
+  //PrintDebug("[write_data_handler]\n");
   switch (controller->current_command) {
   case 0x30: // WRITE SECTORS
-    RD_PANIC("\t\tneed to implement 0x30(write sector) to port 0x170\n");
+    PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port);
     return -1;
     
   case 0xa0: // PACKET
     
-    handle_atapi_packet_command(dev, channel, *(ushort_t *)src);
+    if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) {
+      PrintError("Error sending atapi packet command in PACKET write to data port\n");
+      return -1;
+    }
 
     return length;
     
   default:
-    RD_PANIC("\t\tIO write(0x%x): current command is %02xh\n", 
-            port, controller->current_command);
+    PrintError("\t\tIO write(0x%x): current command is %02xh\n", 
+              port, controller->current_command);
 
     return -1;
   }
+
+
+  return -1;
 }
 
 
@@ -719,10 +739,7 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_
   struct controller_t * controller = NULL;
 
 
-  if (length != 1) {
-    PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
-    return -1;
-  }
+
 
   if (is_primary_port(ramdisk, port)) {
     channel = &(ramdisk->channels[0]);
@@ -736,8 +753,14 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_
   drive = get_selected_drive(channel);
   controller = &(drive->controller);
 
+  PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n", 
+            port, get_channel_no(ramdisk, channel), 
+            channel->drive_select);
+
 
   if (num_drives_on_channel(channel) == 0) {
+    PrintDebug("Setting value to zero because 0 devices on channel\n");
     // (mch) Just return zero for these registers
     memset(dst, 0, length);
 
@@ -751,7 +774,8 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_
                   (controller->status.corrected_data << 2)  |
                   (controller->status.index_pulse << 1)     |
                   (controller->status.err) );
-   
+
+
     memcpy(dst, &val, length);
 
     controller->status.index_pulse_count++;
@@ -764,9 +788,11 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_
   }
   
   if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) {
-    rd_lower_irq(dev, channel->irq);
+    rd_lower_irq(dev, channel);
   }
   
+  PrintDebug("\t\tRead STATUS = 0x%x\n", *(uchar_t *)dst);
+
   return length;
   
 }
@@ -780,7 +806,7 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
   uchar_t value = *(uchar_t *)src;
 
   if (length != 1) {
-    PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
+    PrintError("Invalid Command port write length: %d (port=%d)\n", length, port);
     return -1;
   }
 
@@ -797,7 +823,54 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
   controller = &(drive->controller);
 
 
+  PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
+            port, get_channel_no(ramdisk, channel), 
+            get_drive_no(channel, drive), 
+            value);
+
   switch (value) {
+#if 0
+  case 0xec: // IDENTIFY DEVICE
+    {
+
+      if (drive->device_type == IDE_NONE) {
+       PrintError("\t\tError: disk ata%d-%d not present, aborting\n", 
+                  get_channel_no(ramdisk, channel), 
+                  get_drive_no(channel, drive));
+       rd_command_aborted(dev, channel, value);
+       break;
+      } else if (drive->device_type == IDE_CDROM) {
+       PrintDebug("Identifying CDROM...Going to abort????\n");
+       controller->head_no        = 0;
+       controller->sector_count   = 1;
+       controller->sector_no      = 1;
+       controller->cylinder_no    = 0xeb14;
+       rd_command_aborted(dev, channel, 0xec);
+      } else {
+       PrintError("\t\tError: Want to identify HDD!!\n");
+       /*
+         SELECTED_CONTROLLER(channel).current_command = value;
+         SELECTED_CONTROLLER(channel).error_register = 0;
+         
+         // See ATA/ATAPI-4, 8.12
+         SELECTED_CONTROLLER(channel).status.busy  = 0;
+         SELECTED_CONTROLLER(channel).status.drive_ready = 1;
+         SELECTED_CONTROLLER(channel).status.write_fault = 0;
+         SELECTED_CONTROLLER(channel).status.drq   = 1;
+         SELECTED_CONTROLLER(channel).status.err   = 0;
+         
+         SELECTED_CONTROLLER(channel).status.seek_complete = 1;
+         SELECTED_CONTROLLER(channel).status.corrected_data = 0;
+         
+         SELECTED_CONTROLLER(channel).buffer_index = 0;
+         raise_interrupt(channel);
+         identify_drive(channel);
+       */
+      }
+
+    break;
+    }
+#endif
     // ATAPI commands
   case 0xa1: // IDENTIFY PACKET DEVICE
     {
@@ -818,6 +891,9 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
        rd_raise_interrupt(dev, channel);
        rd_identify_ATAPI_drive(dev, channel);
       } else {
+       PrintError("Identifying non cdrom device not supported - ata %d/%d\n", 
+                  get_channel_no(ramdisk, channel),
+                  get_drive_no(channel, drive));
        rd_command_aborted(dev, channel, 0xa1);
       }
       break;
@@ -842,12 +918,7 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de
        controller->status.busy = 0;
        controller->status.write_fault = 0;
 
-
-typedef struct  {
-  unsigned cylinders;
-  unsigned heads;
-  unsigned sectors;
-} device_image_t;      // serv bit??
+       // serv bit??
        controller->status.drq = 1;
        controller->status.err = 0;
        
@@ -855,16 +926,21 @@ typedef struct  {
        controller->current_command = value;
        controller->buffer_index = 0;
       } else {
+       PrintError("Sending packet to non cdrom device not supported\n");
        rd_command_aborted (dev, channel, 0xa0);
       }
       break;
     }
   default:
-    PrintError("\t\tneed translate command %2x\n", value);
-    return -1;
+    PrintError("\t\tneed translate command %2x - ata %d\%d\n", value, 
+              get_channel_no(ramdisk, channel), 
+              get_drive_no(channel, drive));
+    //return -1;
+    /* JRL THIS NEEDS TO CHANGE */
+    return length;
 
   }
-  return 0;
+  return length;
 }
 
 
@@ -897,11 +973,21 @@ static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_d
   controller = &(get_selected_drive(channel)->controller);
 
 
+  PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
+            port, get_channel_no(ramdisk, channel), 
+            channel->drive_select, 
+            value);
+
   // (mch) Even if device 1 was selected, a write to this register
   // goes to device 0 (if device 1 is absent)
   
   prev_control_reset = controller->control.reset;
 
+
+  if (value & 0x04) {
+    PrintDebug("RESET Signaled\n");
+  }
+
   master_drive->controller.control.reset         = value & 0x04;
   slave_drive->controller.control.reset         = value & 0x04;
 
@@ -909,16 +995,16 @@ static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_d
   master_drive->controller.control.disable_irq = value & 0x02;
   slave_drive->controller.control.disable_irq = value & 0x02;
   
-  Ramdisk_Print("\t\tadpater control reg: reset controller = %d\n",
+  PrintDebug("\t\tadpater control reg: reset controller = %d\n",
                (unsigned) (controller->control.reset) ? 1 : 0);
-  Ramdisk_Print("\t\tadpater control reg: disable_irq(X) = %d\n",
+  PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n",
                (unsigned) (controller->control.disable_irq) ? 1 : 0);
   
   if ((!prev_control_reset) && (controller->control.reset)) {
     uint_t id = 0;
 
     // transition from 0 to 1 causes all drives to reset
-    Ramdisk_Print("\t\thard drive: RESET\n");
+    PrintDebug("\t\thard drive: RESET\n");
     
     // (mch) Set BSY, drive not ready
     for (id = 0; id < 2; id++) {
@@ -951,7 +1037,7 @@ static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_d
       ctrl->control.disable_irq = 0;
     }
 
-    rd_lower_irq(dev, channel->irq);
+    rd_lower_irq(dev, channel);
 
   } else if ((controller->reset_in_progress) &&
             (!controller->control.reset)) {
@@ -977,7 +1063,7 @@ static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_d
       
       // Device signature
       if (drv->device_type == IDE_DISK) {
-       PrintDebug("\t\tdrive %d/%d is harddrive\n", channel, id);
+       PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id);
        ctrl->head_no        = 0;
        ctrl->sector_count   = 1;
        ctrl->sector_no      = 1;
@@ -1024,10 +1110,10 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
   controller = &(drive->controller);
 
 
-  Ramdisk_Print("[R_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", 
-               address, channel, 
-               drive_select, 
-               SELECTED_CONTROLLER(channel).current_command);
+  PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", 
+            port, get_channel_no(ramdisk, channel), 
+            channel->drive_select, 
+            controller->current_command);
   
 
   switch (port) {
@@ -1038,6 +1124,8 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
       
       controller->status.err = 0;
       
+      PrintDebug("\t\tRead FEATURES = 0x%x\n", val);
+
       *(uchar_t *)dst = val;
       return length;
       
@@ -1048,7 +1136,7 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
   case SEC_SECT_CNT_PORT:  // hard disk sector count / interrupt reason 0x1f2
     {
       uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count;
-
+      PrintDebug("\t\tRead SECTOR COUNT = 0x%x\n", val);
       *(uchar_t *)dst = val;
       return length;
 
@@ -1056,9 +1144,11 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
     }
   case PRI_SECT_ADDR1_PORT:
   case SEC_SECT_ADDR1_PORT: // sector number 0x1f3
-    {
+    { 
       uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no;
 
+      PrintDebug("\t\tRead SECTOR ADDR1 = 0x%x\n", val);
+
       *(uchar_t *)dst = val;
       return length;
 
@@ -1073,6 +1163,8 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
       // to detect the disks.... minix2 for example
       uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff);
 
+      PrintDebug("\t\tRead SECTOR ADDR2 = 0x%x\n", val);
+
       *(uchar_t *)dst = val;
       return length;
 
@@ -1087,6 +1179,8 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
       // to detect the disks.... minix2 for example
       uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8);
 
+      PrintDebug("\t\tRead SECTOR ADDR3 = 0x%x\n", val);
+
       *(uchar_t *)dst = val;
       return length;
 
@@ -1108,6 +1202,7 @@ static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm
                     (channel->drive_select << 4)      |
                     (controller->head_no << 0));
       
+      PrintDebug("\t\tRead DRIVE SELECT = 0x%x\n", val);
       *(uchar_t *)dst = val;
       return length;
 
@@ -1159,8 +1254,8 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v
   controller = &(drive->controller);
 
 
-  Ramdisk_Print("[W_handler] IO write to %x = %02x, channel = %d\n", 
-               port, (unsigned) value, channel);
+  PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n", 
+            port, value, get_channel_no(ramdisk, channel));
 
   switch (port) {
 
@@ -1205,26 +1300,36 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v
       // b4: DRV
       // b3..0 HD3..HD0
 
-      // 1x1xxxxx      
+      // 1x1xxxxx
+
+      PrintDebug("\tDrive Select value=%x\n", value);
+
       if ((value & 0xa0) != 0xa0) { 
-       Ramdisk_Print("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", address, (unsigned) value);
+       PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value);
       }
       
       write_head_no(channel, value & 0xf);
-      if (controller->lba_mode == 0 && ((value >> 6) & 1) == 1){
+      if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) {
        PrintDebug("\t\tenabling LBA mode\n");
       }
 
-      write_lba_mode(channel,(value >> 6) & 1);
-      drive->cdrom.cd->lba = (value >> 6) & 1;
-      
+      write_lba_mode(channel, (value >> 6) & 1);
+
+
+
+      if (drive->cdrom.cd) {
+       PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1);
+       drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1);
+      }
       
+
+      channel->drive_select = (value >> 4) & 0x01;
+      drive = get_selected_drive(channel);
+
       if (drive->device_type == IDE_NONE) {
-       channel->drive_select = (value >> 4) & 0x01;
-#ifdef DEBUG_RAMDISK
-       PrintDebug("\t\tError: device set to %d which does not exist! channel = 0x%x\n",
-                  channel->drive_select, channel);
-#endif
+       PrintError("\t\tError: device set to %d which does not exist! channel = 0x%x\n",
+                  channel->drive_select, get_channel_no(ramdisk, channel));
+
        controller->error_register = 0x04; // aborted
        controller->status.err = 1;
       }
@@ -1232,8 +1337,8 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v
       break;
     }
   default:
-    PrintError("\t\thard drive: io write to address %x  (value = %c)\n", port, value);
-    return -1;
+    PrintError("\t\thard drive: io write to unhandled port 0x%x  (value = %c)\n", port, value);
+    //return -1;
   }
 
   return length;
@@ -1244,30 +1349,27 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v
 
 
 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel) {
-  Bit32u irq;
   //  struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
   struct drive_t * drive = get_selected_drive(channel);
   struct controller_t * controller = &(drive->controller);
 
-  Ramdisk_Print("[raise_interrupt] disable_irq = %02x\n", controller->control.disable_irq);
+  PrintDebug("[raise_interrupt] disable_irq = 0x%02x\n", controller->control.disable_irq);
 
   if (!(controller->control.disable_irq)) {
-    irq = channel->irq; 
  
-    Ramdisk_Print("\t\tRaising interrupt %d {%s}\n\n", irq, SELECTED_TYPE_STRING(channel));
+    PrintDebug("\t\tRaising interrupt %d {%s}\n\n", channel->irq, device_type_to_str(drive->device_type));
 
-    dev->vm->vm_ops.raise_irq(dev->vm, irq);
+    v3_raise_irq(dev->vm, channel->irq);
   } else {
-    Ramdisk_Print("\t\tirq is disabled\n");
+    PrintDebug("\t\tRaising irq but irq is disabled\n");
   }
   
   return;
 }
 
-static void rd_lower_irq(struct vm_device *dev, Bit32u irq)  // __attribute__(regparm(1))
-{
-  Ramdisk_Print("[lower_irq] irq = %d\n", irq);
-  dev->vm->vm_ops.lower_irq(dev->vm, irq);
+static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel) {
+  PrintDebug("[lower_irq] irq = %d\n", channel->irq);
+  v3_lower_irq(dev->vm, channel->irq);
 }
 
 
@@ -1284,18 +1386,14 @@ static void rd_lower_irq(struct vm_device *dev, Bit32u irq)  // __attribute__(re
 
 
 
-
-
-
-
-
 int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * channel, ushort_t value) {
-  //struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
+  struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
   struct drive_t * drive = get_selected_drive(channel);
   struct controller_t * controller = &(drive->controller);
 
   if (controller->buffer_index >= PACKET_SIZE) {
-    PrintError("ATAPI packet exceeded maximum length: buffer_index >= PACKET_SIZE\n");
+    PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n", 
+              controller->buffer_index);
     return -1;
   }
 
@@ -1314,9 +1412,11 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     switch (atapi_command) {
     case 0x00: // test unit ready
       {
+       PrintDebug("Testing unit ready\n");
        if (drive->cdrom.ready) {
          rd_atapi_cmd_nop(dev, channel);
        } else {
+         PrintError("CDROM not ready in test unit ready\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
        }
        
@@ -1327,7 +1427,11 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     case 0x03:  // request sense
       {
        int alloc_length = controller->buffer[4];
-       rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false);
+
+       if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) {
+         PrintError("Error sending atapi command in Request Sense\n");
+         return -1;
+       }
        
        // sense data
        controller->buffer[0] = 0x70 | (1 << 7);
@@ -1364,25 +1468,28 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
 
          rd_atapi_cmd_nop(dev, channel);
          rd_raise_interrupt(dev, channel);
+
        } else if (!LoEj && Start) { // start (spin up) the disc
          
-         drive->cdrom.cd->ops.start_cdrom(drive->cdrom.cd);
+         drive->cdrom.cd->start_cdrom(drive->private_data);
          
          PrintError("FIXME: ATAPI start disc not reading TOC\n");
          rd_atapi_cmd_nop(dev, channel);
          rd_raise_interrupt(dev, channel);
+
        } else if (LoEj && !Start) { // Eject the disc
          rd_atapi_cmd_nop(dev, channel);
-         
+         PrintDebug("Ejecting Disk\n");
          if (drive->cdrom.ready) {
            
-           drive->cdrom.cd->ops.eject_cdrom(drive->cdrom.cd);
+           drive->cdrom.cd->eject_cdrom(drive->private_data);
            
            drive->cdrom.ready = 0;
            //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
            //bx_gui->update_drive_status_buttons();
          }
          rd_raise_interrupt(dev, channel);
+
        } else { // Load the disc
          // My guess is that this command only closes the tray, that's a no-op for us
          rd_atapi_cmd_nop(dev, channel);
@@ -1395,10 +1502,14 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
        uint16_t alloc_length = rd_read_16bit(controller->buffer + 8);
        
        if (alloc_length == 0) {
-         RD_PANIC("Zero allocation length to MECHANISM STATUS not impl.\n");
+         PrintError("Zero allocation length to MECHANISM STATUS not impl.\n");
+         return -1;
        }
        
-       rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false);
+       if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) {
+         PrintError("Error sending atapi command in mechanism status\n");
+         return -1;
+       }
        
        controller->buffer[0] = 0; // reserved for non changers
        controller->buffer[1] = 0; // reserved for non changers
@@ -1428,7 +1539,11 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            switch (PageCode) {
            case 0x01: // error recovery
              {
-               rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false);
+               
+               if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) {
+                 PrintError("Error sending atapi command in mode sense error recovery\n");
+                 return -1;
+               }
                
                rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery),
                                          sizeof(struct error_recovery_t));
@@ -1437,7 +1552,12 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
              }
            case 0x2a: // CD-ROM capabilities & mech. status
              {
-               rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false);
+
+               if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) {
+                 PrintError("Error sending atapi command in CDROM caps/mech mode-sense\n");
+                 return -1;
+               }
+
                rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28);
                
                controller->buffer[8] = 0x2a;
@@ -1471,7 +1591,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            case 0x0e: // CD-ROM audio control
            case 0x3f: // all
              {
-               RD_ERROR("cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
+               PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
                         PageCode);
                rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
                                   ASC_INV_FIELD_IN_CMD_PACKET);
@@ -1481,7 +1601,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            default:
              {
                // not implemeted by this device
-               Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
+               PrintError("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
                              PC, PageCode);
                rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
                                   ASC_INV_FIELD_IN_CMD_PACKET);
@@ -1510,6 +1630,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            default:
              {
                // not implemeted by this device
+               PrintError("Changeable values of mode sense not supported by cdrom\n");
                PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
                           PC, PageCode);
                rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
@@ -1528,15 +1649,17 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            case 0x0e: // CD-ROM audio control
            case 0x2a: // CD-ROM capabilities & mech. status
            case 0x3f: // all
-             PrintError("cdrom: MODE SENSE (dflt), code=%x\n",
+             PrintError("Default values of mode sense not supported by cdrom\n");
+             PrintDebug("cdrom: MODE SENSE (dflt), code=%x\n",
                       PageCode);
              return -1;
              
            default:
              {
+               PrintError("Default values of mode sense not implemented in cdrom\n");
                // not implemeted by this device
-               PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
-                             PC, PageCode);
+               PrintDebug("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
+                          PC, PageCode);
                rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
                                   ASC_INV_FIELD_IN_CMD_PACKET);
                rd_raise_interrupt(dev, channel);
@@ -1547,13 +1670,15 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
          }
        case 0x3: // saved values not implemented
          {
+           PrintError("\t\tSaved values not implemented in mode sense\n");
            rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
            rd_raise_interrupt(dev, channel);
            break;
          }
        default:
          {
-           RD_PANIC("Should not get here!\n");
+           PrintError("Unsupported Mode sense value\n");
+           return -1;
            break;
          }
        }
@@ -1563,7 +1688,10 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
       { 
        uint8_t alloc_length = controller->buffer[4];
        
-       rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false);
+       if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) {
+         PrintError("Error sending atapi command in inquiry\n");
+         return -1;
+       }
        
        controller->buffer[0] = 0x05; // CD-ROM
        controller->buffer[1] = 0x80; // Removable
@@ -1599,7 +1727,10 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     case 0x25:  // read cd-rom capacity
       {
        // no allocation length???
-       rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false);
+       if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) {
+         PrintError("Error sending atapi command in read cdrom capacity\n");
+         return -1;
+       }
        
        if (drive->cdrom.ready) {
          uint32_t capacity = drive->cdrom.capacity;
@@ -1617,6 +1748,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
 
          rd_ready_to_send_atapi(dev, channel);
        } else {
+         PrintError("CDROM not ready in read cdrom capacity\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
        }
@@ -1631,6 +1763,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
          rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
          rd_raise_interrupt(dev, channel);
        } else {
+         PrintError("Drive not ready in read cd with CD present\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
        }
@@ -1639,7 +1772,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     case 0x43: // read toc
       { 
        if (drive->cdrom.ready) {
-         int toc_length;  
+         int toc_length = 0;  
          bool msf = (controller->buffer[1] >> 1) & 1;
          uint8_t starting_track = controller->buffer[6];
          
@@ -1647,23 +1780,39 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
          
          uint8_t format = (controller->buffer[9] >> 6);
          int i;
+
+         PrintDebug("Reading CDROM TOC: Format=%d (byte count=%d) (toc length:%d)\n", 
+                    format, controller->byte_count, toc_length);
+
          switch (format) {
          case 0:
-           
-           if (!(drive->cdrom.cd->ops.read_toc(drive->cdrom.cd, controller->buffer,
-                                               &toc_length, msf, starting_track))) {
-             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
-                                ASC_INV_FIELD_IN_CMD_PACKET);
-             rd_raise_interrupt(dev, channel);
-           } else {
-             rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false);
-             rd_ready_to_send_atapi(dev, channel);
+           {
+             if (!(drive->cdrom.cd->read_toc(drive->private_data, controller->buffer,
+                                             &toc_length, msf, starting_track))) {
+               PrintError("CDROM: Reading Table of Contents Failed\n");
+               rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
+                                  ASC_INV_FIELD_IN_CMD_PACKET);
+               rd_raise_interrupt(dev, channel);
+               break;
+             }
+
+
+             if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) {
+               PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
+               return -1;
+             }
+
+             rd_ready_to_send_atapi(dev, channel);    
+
+             break;
            }
-           break;
-           
          case 1:
            // multi session stuff. we ignore this and emulate a single session only
-           rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false);
+
+           if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) {
+             PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
+             return -1;
+           }
            
            controller->buffer[0] = 0;
            controller->buffer[1] = 0x0a;
@@ -1683,11 +1832,12 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            return -1;
          }
        } else {
+         PrintError("CDROM not ready in read toc\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
        }
        break;
-      }  
+      }
     case 0x28: // read (10)
     case 0xa8: // read (12)
       { 
@@ -1702,29 +1852,41 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
        uint32_t lba = rd_read_32bit(controller->buffer + 2);
        
        if (!(drive->cdrom.ready)) {
+         PrintError("CDROM Error: Not Ready (ATA%d/%d)\n", 
+                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
          break;
        }
        
        if (transfer_length == 0) {
+         PrintError("READ(%d) with transfer length 0, ok\n", 
+                    (atapi_command == 0x28) ? 10 : 12);
          rd_atapi_cmd_nop(dev, channel);
          rd_raise_interrupt(dev, channel);
-         Ramdisk_Print("\t\tREAD(%d) with transfer length 0, ok\n", atapi_command==0x28?10:12);
          break;
        }
        
        if (lba + transfer_length > drive->cdrom.capacity) {
+         PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n",
+                    drive->cdrom.capacity,
+                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
          rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
          rd_raise_interrupt(dev, channel);
          break;
        }
        
-       Ramdisk_Print("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", atapi_command==0x28?10:12, lba, transfer_length);
+       PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", 
+                  (atapi_command == 0x28) ? 10 : 12, 
+                  lba, transfer_length);
        
        // handle command
-       rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048,
-                                  transfer_length * 2048, true);
+       if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048,
+                                      transfer_length * 2048, true) == -1) {
+         PrintError("CDROM Error: Atapi command send error\n");
+         return -1;
+       }
+
        drive->cdrom.remaining_blocks = transfer_length;
        drive->cdrom.next_lba = lba;
        rd_ready_to_send_atapi(dev, channel);
@@ -1735,18 +1897,20 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
        uint32_t lba = rd_read_32bit(controller->buffer + 2);
 
        if (!(drive->cdrom.ready)) {
+         PrintError("CDROM not ready in seek\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
          break;
        }
        
        if (lba > drive->cdrom.capacity) {
+         PrintError("LBA is greater than CDROM capacity in seek\n");
          rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
          rd_raise_interrupt(dev, channel);
          break;
        }
        
-       PrintDebug("\t\tcdrom: SEEK (ignored)\n");
+       PrintError("\t\tcdrom: SEEK (ignored)\n");
 
        rd_atapi_cmd_nop(dev, channel);
        rd_raise_interrupt(dev, channel);
@@ -1760,6 +1924,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
          drive->cdrom.locked = controller->buffer[4] & 1;
          rd_atapi_cmd_nop(dev, channel);
        } else {
+         PrintError("CD not ready in prevent/allow medium removal\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
        }
 
@@ -1782,6 +1947,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
          UNUSED(track_number);
        */
        if (!(drive->cdrom.ready)) {
+         PrintError("CDROM not ready in read sub-channel\n");
          rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
          rd_raise_interrupt(dev, channel);
        } else {
@@ -1799,7 +1965,10 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
            rd_raise_interrupt(dev, channel);
          }
          
-         rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false);
+         if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) {
+           PrintError("Error sending atapi command in read sub-channel\n");
+           return -1;
+         }
          rd_ready_to_send_atapi(dev, channel);
        }
        break;
@@ -1807,6 +1976,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     case 0x51:  // read disc info
       {
        // no-op to keep the Linux CD-ROM driver happy
+       PrintError("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
        rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
        rd_raise_interrupt(dev, channel);
        break;
@@ -1825,7 +1995,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
     case 0x46: // ???
     case 0x4a: // ???
       PrintError("ATAPI command 0x%x not implemented yet\n",
-              atapi_command);
+                atapi_command);
       rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
       rd_raise_interrupt(dev, channel);
       break;
@@ -1838,13 +2008,15 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann
       break;
     }
   }
+       
+             
   return 0;
 }
 
 
 
 
-void rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy)
+int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy)
 {
   struct drive_t * drive = &(channel->drives[channel->drive_select]);
   struct controller_t * controller = &(drive->controller);
@@ -1852,7 +2024,7 @@ void rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * chann
   // controller->byte_count is a union of controller->cylinder_no;
   // lazy is used to force a data read in the buffer at the next read.
   
-  Ramdisk_Print("[rd_init_send_atapi_cmd]\n");
+  PrintDebug("[rd_init_send_atapi_cmd]\n");
 
   if (controller->byte_count == 0xffff) {
     controller->byte_count = 0xfffe;
@@ -1861,20 +2033,22 @@ void rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * chann
   if ((controller->byte_count & 1) && 
       !(alloc_length <= controller->byte_count)) {
       
-    Ramdisk_Print("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", 
-                 controller->byte_count, 
-                 command, 
-                 controller->byte_count - 1);
+    PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", 
+              controller->byte_count, 
+              command, 
+              controller->byte_count - 1);
     
     controller->byte_count -= 1;
   }
   
   if (controller->byte_count == 0) {
-    RD_PANIC("\t\tATAPI command with zero byte count\n");
+    PrintError("\t\tATAPI command with zero byte count\n");
+    return -1;
   }
 
   if (alloc_length < 0) {
-    RD_PANIC("\t\tAllocation length < 0\n");
+    PrintError("\t\tAllocation length < 0\n");
+    return -1;
   }
 
   if (alloc_length == 0) {
@@ -1913,13 +2087,15 @@ void rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * chann
   // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
   // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
   // }
-}
 
+  return 0;
+}
 
 
- void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) {
-  Ramdisk_Print("[rd_ready_to_send_atapi]\n");
 
+void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) {
+  PrintDebug("[rd_ready_to_send_atapi]\n");
+  
   rd_raise_interrupt(dev, channel);
 }
 
@@ -1932,8 +2108,12 @@ void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sens
   struct drive_t * drive = &(channel->drives[channel->drive_select]);
   struct controller_t * controller = &(drive->controller);
 
-  Ramdisk_Print("[rd_atapi_cmd_error]\n");
-  Ramdisk_Print("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", channel, sense_key, asc);
+
+  struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
+  PrintError("[rd_atapi_cmd_error]\n");
+  PrintError("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", 
+            get_channel_no(ramdisk, channel), sense_key, asc);
+  
 
   controller->error_register = sense_key << 4;
   controller->interrupt_reason.i_o = 1;
@@ -1957,7 +2137,7 @@ void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel)
   struct drive_t * drive = &(channel->drives[channel->drive_select]);
   struct controller_t * controller = &(drive->controller);
 
-  Ramdisk_Print("[rd_atapi_cmd_nop]\n");
+  PrintDebug("[rd_atapi_cmd_nop]\n");
   controller->interrupt_reason.i_o = 1;
   controller->interrupt_reason.c_d = 1;
   controller->interrupt_reason.rel = 0;
@@ -2093,7 +2273,7 @@ void rd_init_mode_sense_single(struct vm_device * dev,
   struct drive_t * drive = &(channel->drives[channel->drive_select]);
   struct controller_t * controller = &(drive->controller);
 
-  Ramdisk_Print("[rd_init_mode_sense_single]\n");
+  PrintDebug("[rd_init_mode_sense_single]\n");
 
   // Header
   controller->buffer[0] = (size + 6) >> 8;
@@ -2116,8 +2296,8 @@ static void rd_command_aborted(struct vm_device * dev,
   struct drive_t * drive = &(channel->drives[channel->drive_select]);
   struct controller_t * controller = &(drive->controller);
 
-  Ramdisk_Print("[rd_command_aborted]\n");
-  Ramdisk_Print("\t\taborting on command 0x%02x {%s}\n", value, SELECTED_TYPE_STRING(channel));
+  PrintError("[rd_command_aborted]\n");
+  PrintError("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type));
 
   controller->current_command = 0;
   controller->status.busy = 0;
@@ -2134,59 +2314,62 @@ static void rd_command_aborted(struct vm_device * dev,
 
 
 static int ramdisk_init_device(struct vm_device *dev) {
-  struct ramdisk_t *ramdisk_state = (struct ramdisk_t *)dev->private_data;
-
-  rd_init_hardware(ramdisk_state);
-
-
-  dev_hook_io(dev, PRI_CTRL_PORT, 
-             &read_status_port, &write_ctrl_port);
-
-  dev_hook_io(dev, PRI_DATA_PORT, 
-             &read_data_port, &write_data_port);
-  dev_hook_io(dev, PRI_FEATURES_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_SECT_CNT_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_SECT_ADDR1_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_SECT_ADDR2_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_SECT_ADDR3_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_DRV_SEL_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, PRI_CMD_PORT, 
-             &read_status_port, &write_cmd_port);
-
-
-  dev_hook_io(dev, SEC_CTRL_PORT, 
-             &read_status_port, &write_ctrl_port);
-
-  dev_hook_io(dev, SEC_DATA_PORT, 
-             &read_data_port, &write_data_port);
-  dev_hook_io(dev, SEC_FEATURES_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_SECT_CNT_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_SECT_ADDR1_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_SECT_ADDR2_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_SECT_ADDR3_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_DRV_SEL_PORT, 
-             &read_general_port, &write_general_port);
-  dev_hook_io(dev, SEC_CMD_PORT, 
-             &read_status_port, &write_cmd_port);
-
+  struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data;
+
+  PrintDebug("Initializing Ramdisk\n");
+
+
+  rd_init_hardware(ramdisk);
+
+
+  v3_dev_hook_io(dev, PRI_CTRL_PORT, 
+                &read_status_port, &write_ctrl_port);
+
+  v3_dev_hook_io(dev, PRI_DATA_PORT, 
+                &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_SECT_ADDR1_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_SECT_ADDR2_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_SECT_ADDR3_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_CMD_PORT, 
+                &read_status_port, &write_cmd_port);
+
+
+  v3_dev_hook_io(dev, SEC_CTRL_PORT, 
+                &read_status_port, &write_ctrl_port);
+
+  v3_dev_hook_io(dev, SEC_DATA_PORT, 
+                &read_data_port, &write_data_port);
+  v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_SECT_ADDR1_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_SECT_ADDR2_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_SECT_ADDR3_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
+                &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_CMD_PORT, 
+                &read_status_port, &write_cmd_port);
+  
   
 
-  dev_hook_io(dev, SEC_ADDR_REG_PORT, 
-             &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
+                &read_general_port, &write_general_port);
 
-  dev_hook_io(dev, PRI_ADDR_REG_PORT, 
-             &read_general_port, &write_general_port);
+  v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
+                &read_general_port, &write_general_port);
 
 
 
@@ -2196,8 +2379,8 @@ static int ramdisk_init_device(struct vm_device *dev) {
 
 
 static int ramdisk_deinit_device(struct vm_device *dev) {
-  struct ramdisk_t *ramdisk_state = (struct ramdisk_t *)(dev->private_data);
-  rd_close_harddrive(ramdisk_state);
+  struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
+  rd_close_harddrive(ramdisk);
   return 0;
 }
 
@@ -2212,16 +2395,16 @@ static struct vm_device_ops dev_ops = {
 
 
 
-struct vm_device *create_ramdisk()
+struct vm_device * v3_create_ramdisk()
 {
 
   struct ramdisk_t *ramdisk;
   ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));  
   V3_ASSERT(ramdisk != NULL);  
 
-  Ramdisk_Print("[create_ramdisk]\n");
+  PrintDebug("[create_ramdisk]\n");
 
-  struct vm_device *device = create_device("RAMDISK", &dev_ops, ramdisk);
+  struct vm_device * device = v3_create_device("RAMDISK", &dev_ops, ramdisk);
 
   return device;
 }
@@ -2229,37 +2412,39 @@ struct vm_device *create_ramdisk()
 
 
 
-#ifdef RAMDISK_DEBUG
-static void rd_print_state(struct ramdisk_t * ramdisk,  struct vm_device *dev) {
+#ifdef DEBUG_RAMDISK
+
+static void rd_print_state(struct ramdisk_t * ramdisk) {
   uchar_t channel; 
   uchar_t device;
   struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels));
 
+  /*
   for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) {
     memset((char *)(channels + channel), 0, sizeof(struct channel_t));
   }
+  */
+  PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels));
+  PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
+  PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
+  PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
+  PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
 
-  Ramdisk_Print("sizeof(*channels) = %d\n", sizeof(*channels));
-  Ramdisk_Print("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
-  Ramdisk_Print("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
-  Ramdisk_Print("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
-  Ramdisk_Print("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
 
-
-  Ramdisk_Print("sizeof(channles->drives[0].controller.status) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", 
                sizeof((channels->drives[0].controller.status)));
-  Ramdisk_Print("sizeof(channles->drives[0].controller.sector_count) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", 
                sizeof((channels->drives[0].controller.sector_count)));
-  Ramdisk_Print("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", 
                sizeof((channels->drives[0].controller.interrupt_reason)));
 
-  Ramdisk_Print("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", 
                sizeof((channels->drives[0].controller.cylinder_no)));
-  Ramdisk_Print("sizeof(channles->drives[0].controller.byte_count) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", 
                sizeof((channels->drives[0].controller.byte_count)));
 
 
-  Ramdisk_Print("sizeof(channles->drives[0].controller.control) = %d\n", 
+  PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", 
                sizeof((channels->drives[0].controller.control)));
 
 
@@ -2268,118 +2453,118 @@ static void rd_print_state(struct ramdisk_t * ramdisk,  struct vm_device *dev) {
     for (device = 0; device < 2; device++){
                   
       // Initialize controller state, even if device is not present
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.busy = %d\n",
+      PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n",
                    channel, device, 
                    channels[channel].drives[device].controller.status.busy);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.drive_ready = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.drive_ready);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.write_fault = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.write_fault);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.seek_complete = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.seek_complete);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.drq = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.drq);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.corrected_data = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.corrected_data);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.index_pulse);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.index_pulse_count);
-      Ramdisk_Print("channels[%d].drives[%d].controller.status.err = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.status.err);
 
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.error_register = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.error_register);
-      Ramdisk_Print("channels[%d].drives[%d].controller.head_no = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.head_no);
-      Ramdisk_Print("channels[%d].drives[%d].controller.sector_count = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.sector_count);
-      Ramdisk_Print("channels[%d].drives[%d].controller.sector_no = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.sector_no);
-      Ramdisk_Print("channels[%d].drives[%d].controller.cylinder_no = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.cylinder_no);
-      Ramdisk_Print("channels[%d].drives[%d].controller.current_command = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.current_command);
-      Ramdisk_Print("channels[%d].drives[%d].controller.buffer_index = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.buffer_index);
 
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.control.reset = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.control.reset);
-      Ramdisk_Print("channels[%d].drives[%d].controller.control.disable_irq = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.control.disable_irq);
 
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.reset_in_progress = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.reset_in_progress);
-      Ramdisk_Print("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.sectors_per_block); 
-      Ramdisk_Print("channels[%d].drives[%d].controller.lba_mode = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.lba_mode); 
-      Ramdisk_Print("channels[%d].drives[%d].controller.features = %d\n", 
+      PrintDebug("channels[%d].drives[%d].controller.features = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.features); 
 
 
-      Ramdisk_Print("channels[%d].drives[%d].model_no = %s\n", 
+      PrintDebug("channels[%d].drives[%d].model_no = %s\n", 
                    channel, device, 
                    channels[channel].drives[device].model_no); 
-      Ramdisk_Print("channels[%d].drives[%d].device_type = %d\n", 
+      PrintDebug("channels[%d].drives[%d].device_type = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].device_type); 
-      Ramdisk_Print("channels[%d].drives[%d].cdrom.locked = %d\n", 
+      PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].cdrom.locked); 
-      Ramdisk_Print("channels[%d].drives[%d].sense.sense_key = %d\n", 
+      PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].sense.sense_key); 
-      Ramdisk_Print("channels[%d].drives[%d].sense.asc = %d\n", 
+      PrintDebug("channels[%d].drives[%d].sense.asc = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].sense.asc); 
-      Ramdisk_Print("channels[%d].drives[%d].sense.ascq = %d\n", 
+      PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].sense.ascq); 
 
 
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.interrupt_reason.c_d);
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.interrupt_reason.i_o);
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.interrupt_reason.rel);
 
-      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", 
+      PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", 
                    channel, device, 
                    channels[channel].drives[device].controller.interrupt_reason.tag);
 
-      Ramdisk_Print("channels[%d].drives[%d].cdrom.ready = %d\n", 
+      PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n", 
                    channel, device, 
                    channels[channel].drives[device].cdrom.ready);
       
@@ -2391,120 +2576,7 @@ static void rd_print_state(struct ramdisk_t * ramdisk,  struct vm_device *dev) {
 
 
 
-static void trace_info(ushort_t port, void *src, uint_t length) {
-
-  switch(port){
-
-  case 0x3e8:
-    if (length == 1 && *((uchar_t*) src) == ATA_DETECT)
-      Ramdisk_Print("ata_detect()\n");
-    break;
-
-  case 0x3e9:
-    if (length == 1 && *((uchar_t*) src) == ATA_RESET)
-      Ramdisk_Print("ata_reset()\n");
-    break;
-
-  case 0x3ea:
-    if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_IN)
-      Ramdisk_Print("ata_cmd_data_in()\n");
-    break;
-
-  case 0x3eb:
-    if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_OUT)
-      Ramdisk_Print("ata_cmd_data_out()\n");
-    break;
-
-  case 0x3ec:
-    if (length == 1 && *((uchar_t*) src) == ATA_CMD_PACKET)
-      Ramdisk_Print("ata_cmd_packet()\n");
-    break;
-
-  case 0x3ed:
-    if (length == 1 && *((uchar_t*) src) == ATAPI_GET_SENSE)
-      Ramdisk_Print("atapi_get_sense()\n");
-    break;
-
-  case 0x3ee:
-    if (length == 1 && *((uchar_t*) src) == ATAPI_IS_READY)
-      Ramdisk_Print("atapi_is_ready()\n");
-    break;
-
-  case 0x3ef:
-    if (length == 1 && *((uchar_t*) src) == ATAPI_IS_CDROM)
-      Ramdisk_Print("atapi_is_cdrom()\n");
-    break;
-
-
-  case 0x2e8:
-    if (length == 1 && *((uchar_t*) src) == CDEMU_INIT)
-      Ramdisk_Print("cdemu_init()\n");
-    break;
-
-  case 0x2e9:
-    if (length == 1 && *((uchar_t*) src) == CDEMU_ISACTIVE)
-      Ramdisk_Print("cdemu_isactive()\n");
-    break;
-
-  case 0x2ea:
-    if (length == 1 && *((uchar_t*) src) == CDEMU_EMULATED_DRIVE)
-      Ramdisk_Print("cdemu_emulated_drive()\n");
-    break;
-
-  case 0x2eb:
-    if (length == 1 && *((uchar_t*) src) == CDROM_BOOT)
-      Ramdisk_Print("cdrom_boot()\n");
-    break;
-
-  case 0x2ec:
-    if (length == 1 && *((uchar_t*) src) == HARD_DRIVE_POST)
-      Ramdisk_Print("ata_hard_drive_post()\n");
-    break;
-
-  case 0x2ed:
-    if (length == 1)
-      Ramdisk_Print("ata_device_no(%d)\n", *((uchar_t*) src));
-    break;
-
-  case 0x2ee:
-    if (length == 1)
-      Ramdisk_Print("ata_device_type(%d)\n", *((uchar_t*) src));
-    break;
-
-  case 0x2ef:
-    if (length == 1 && *((uchar_t*) src) == INT13_HARDDISK)
-      Ramdisk_Print("int13_harddrive()\n");
-    break;
-
-  case 0x2f8:
-    if (length == 1 && *((uchar_t*) src) == INT13_CDROM)
-      Ramdisk_Print("int13_cdrom()\n");
-    break;
-
-  case 0x2f9:
-    if (length == 1 && *((uchar_t*) src) == INT13_CDEMU)
-      Ramdisk_Print("int13_cdemu()\n");
-    break;
-
-  case 0x2fa:
-    if (length == 1 && *((uchar_t*) src) == INT13_ELTORITO)
-      Ramdisk_Print("int13_eltorito()\n");
-    break;
-
-  case 0x2fb:
-    if (length == 1 && *((uchar_t*) src) == INT13_DISKETTE_FUNCTION)
-      Ramdisk_Print("int13_diskette_function()\n");
-    break;
-
-
-  default:
-    break;
-  }
-}
-
-
-
-static  int check_bit_fields(struct controller_t * controller) {
+static int check_bit_fields(struct controller_t * controller) {
   //Check bit fields
   controller->sector_count = 0;
   controller->interrupt_reason.c_d = 1;
@@ -2532,4 +2604,5 @@ static  int check_bit_fields(struct controller_t * controller) {
   
   return 0;
 }
+
 #endif