X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Framdisk.c;h=a723429ec964963c67039622ce72bf12e52b76e7;hb=1e9b1f02c9d9e59ecdca1b5aa3d31129cb20dc49;hp=05d93331bc23cc8e47382fc0dfda2f8d2cc09e86;hpb=6eecf583b522147ef13faabb634562f6f23bb712;p=palacios.git diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c index 05d9333..a723429 100644 --- a/palacios/src/devices/ramdisk.c +++ b/palacios/src/devices/ramdisk.c @@ -1,18 +1,56 @@ -/* - * 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 + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved for original changes + * */ + #include #include #include #include -#include + + +#ifndef TRACE_RAMDISK +#undef PrintTrace +#define PrintTrace(fmt, args...) +#endif + #ifndef DEBUG_RAMDISK #undef PrintDebug -#define PrintDebug(_f, _a...) +#define PrintDebug(fmt, args...) #endif @@ -61,33 +99,6 @@ #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); - - - - - /* * Debug facilities */ @@ -329,7 +340,7 @@ static void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * c * 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); @@ -343,12 +354,77 @@ static void rd_lower_irq(struct vm_device *dev, Bit32u irq); 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; @@ -408,65 +484,6 @@ 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), " "); - } - - PrintDebug("CDROM on target %d/%d\n", channel_num, 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 DEBUG_RAMDISK - if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) { - PrintDebug("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)); - PrintDebug("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); - - PrintDebug("\t\tCD on ata%d-%d: '%s'\n", - channel_num, - device, ""); - - if((drive->cdrom.cd->ops).insert_cdrom(cdif, NULL)) { - PrintDebug("\t\tMedia present in CD-ROM drive\n"); - drive->cdrom.ready = 1; - drive->cdrom.capacity = drive->cdrom.cd->ops.capacity(cdif); - } else { - PrintDebug("\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 @@ -513,7 +530,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de controller = &(drive->controller); - PrintDebug("[read_data_handler] IO Read at 0x%x, on drive %d/%d (current_cmd = 0x%02x)\n", + PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d (current_cmd = 0x%02x)\n", port, get_channel_no(ramdisk, channel), get_drive_no(channel, drive), @@ -564,7 +581,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de uint_t index = controller->buffer_index; - PrintDebug("\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); @@ -581,15 +598,14 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de case 0x28: // read (10) case 0xa8: // read (12) { - struct cdrom_interface * cdif = drive->cdrom.cd; - + if (!(drive->cdrom.ready)) { PrintError("\t\tRead with CDROM not ready\n"); return -1; } - drive->cdrom.cd->ops.read_block(cdif, controller->buffer, - drive->cdrom.next_lba); + drive->cdrom.cd->read_block(drive->private_data, controller->buffer, + drive->cdrom.next_lba); drive->cdrom.next_lba++; drive->cdrom.remaining_blocks--; @@ -683,7 +699,7 @@ static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_de } default: - PrintDebug("\t\tread need support more command: %02x\n", controller->current_command); + PrintError("\t\tunsupported command: %02x\n", controller->current_command); break; } @@ -722,6 +738,7 @@ static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_d case 0xa0: // PACKET 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; } @@ -771,6 +788,7 @@ static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_ 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); @@ -797,7 +815,7 @@ 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); } return length; @@ -832,10 +850,52 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", port, get_channel_no(ramdisk, channel), - channel->drive_select, + 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 { @@ -856,6 +916,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; @@ -888,13 +951,18 @@ static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_de 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 length; @@ -989,7 +1057,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)) { @@ -1257,14 +1325,20 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v } write_lba_mode(channel, (value >> 6) & 1); - drive->cdrom.cd->lba = (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) { - PrintDebug("\t\tError: device set to %d which does not exist! channel = 0x%x\n", + 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 @@ -1275,7 +1349,7 @@ static int write_general_port(ushort_t port, void * src, uint_t length, struct v } default: PrintError("\t\thard drive: io write to unhandled port 0x%x (value = %c)\n", port, value); - return -1; + //return -1; } return length; @@ -1286,30 +1360,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); - PrintDebug("[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; - PrintDebug("\t\tRaising interrupt %d {%s}\n\n", irq, device_type_to_str(drive->device_type)); + 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 { - PrintDebug("\t\tirq is disabled\n"); + PrintError("\t\tRaising irq but irq is disabled\n"); } return; } -static void rd_lower_irq(struct vm_device *dev, Bit32u irq) // __attribute__(regparm(1)) -{ - PrintDebug("[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); } @@ -1327,7 +1398,7 @@ 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); @@ -1352,9 +1423,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); } @@ -1367,6 +1440,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann int alloc_length = controller->buffer[4]; 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; } @@ -1405,25 +1479,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); @@ -1441,6 +1518,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann } 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; } @@ -1474,6 +1552,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann { 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; } @@ -1486,6 +1565,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann { 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; } @@ -1532,7 +1612,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann default: { // not implemeted by this device - PrintDebug("\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); @@ -1561,6 +1641,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, @@ -1579,15 +1660,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); @@ -1598,13 +1681,14 @@ 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: { - PrintError("Should not get here!\n"); + PrintError("Unsupported Mode sense value\n"); return -1; break; } @@ -1616,6 +1700,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann uint8_t alloc_length = controller->buffer[4]; 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; } @@ -1654,6 +1739,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann { // no allocation length??? 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; } @@ -1673,6 +1759,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); } @@ -1687,6 +1774,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); } @@ -1705,23 +1793,29 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann int i; 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 { + { + 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 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; } @@ -1743,6 +1837,7 @@ 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); } @@ -1762,19 +1857,25 @@ 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); - PrintDebug("\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; @@ -1787,8 +1888,10 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann // handle command 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); @@ -1799,18 +1902,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); @@ -1824,6 +1929,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); } @@ -1846,6 +1952,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 { @@ -1864,6 +1971,7 @@ int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * chann } 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); @@ -1873,6 +1981,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; @@ -1891,7 +2000,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; @@ -1999,13 +2108,15 @@ int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channe void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sense_t sense_key, asc_t asc) { - struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data); struct drive_t * drive = &(channel->drives[channel->drive_select]); struct controller_t * controller = &(drive->controller); - PrintDebug("[rd_atapi_cmd_error]\n"); - PrintDebug("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", + + 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; @@ -2188,8 +2299,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); - PrintDebug("[rd_command_aborted]\n"); - PrintDebug("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type)); + 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; @@ -2580,6 +2691,7 @@ static void trace_info(ushort_t port, void *src, uint_t length) { #endif + static int check_bit_fields(struct controller_t * controller) { //Check bit fields controller->sector_count = 0; @@ -2608,4 +2720,5 @@ static int check_bit_fields(struct controller_t * controller) { return 0; } + #endif