Connecting USB CD-ROM without media present now supported
TODO #1: implement seek timing similar to ATA/ATAPI TODO #2: implement asynchronus i/o in lowlevel cdrom
This commit is contained in:
parent
d591c1dd34
commit
39890d308d
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002-2013 The Bochs Project
|
||||
// Copyright (C) 2002-2014 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -69,11 +69,11 @@ bx_bool cdrom_base_c::insert_cdrom(const char *dev)
|
||||
|
||||
// Load CD-ROM. Returns 0 if CD is not ready.
|
||||
if (dev != NULL) path = strdup(dev);
|
||||
BX_INFO(("load cdrom with path=%s", path));
|
||||
BX_INFO(("load cdrom with path='%s'", path));
|
||||
// all platforms except win32
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
BX_ERROR(("open cd failed for %s: %s", path, strerror(errno)));
|
||||
BX_ERROR(("open cd failed for '%s': %s", path, strerror(errno)));
|
||||
return 0;
|
||||
}
|
||||
// do fstat to determine if it's a file or a device, then set using_file.
|
||||
|
@ -9,7 +9,7 @@
|
||||
//
|
||||
// Written by Paul Brook
|
||||
//
|
||||
// Copyright (C) 2007-2013 The Bochs Project
|
||||
// Copyright (C) 2007-2014 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -78,8 +78,8 @@ scsi_device_t::scsi_device_t(cdrom_base_c *_cdrom, int _tcq,
|
||||
dev = _dev;
|
||||
cluster_size = 4;
|
||||
locked = 0;
|
||||
inserted = 1;
|
||||
max_lba = cdrom->capacity() - 1;
|
||||
inserted = 0;
|
||||
max_lba = 0;
|
||||
sprintf(drive_serial_str, "%d", serial_number++);
|
||||
|
||||
put("SCSICD");
|
||||
@ -643,13 +643,13 @@ Bit32s scsi_device_t::scsi_send_command(Bit32u tag, Bit8u *buf, int lun)
|
||||
// The normal LEN field for this command is zero
|
||||
memset(outbuf, 0, 8);
|
||||
if (type == SCSIDEV_TYPE_CDROM) {
|
||||
nb_sectors = cdrom->capacity();
|
||||
nb_sectors = max_lba;
|
||||
} else {
|
||||
nb_sectors = hdimage->hd_size / 512;
|
||||
nb_sectors--;
|
||||
}
|
||||
/* Returned value is the address of the last sector. */
|
||||
if (nb_sectors) {
|
||||
nb_sectors--;
|
||||
outbuf[0] = (Bit8u)((nb_sectors >> 24) & 0xff);
|
||||
outbuf[1] = (Bit8u)((nb_sectors >> 16) & 0xff);
|
||||
outbuf[2] = (Bit8u)((nb_sectors >> 8) & 0xff);
|
||||
@ -693,6 +693,8 @@ Bit32s scsi_device_t::scsi_send_command(Bit32u tag, Bit8u *buf, int lun)
|
||||
int start_track, format, msf, toclen = 0;
|
||||
|
||||
if (type == SCSIDEV_TYPE_CDROM) {
|
||||
if (!inserted)
|
||||
goto notready;
|
||||
msf = buf[1] & 2;
|
||||
format = buf[2] & 0xf;
|
||||
start_track = buf[6];
|
||||
@ -754,9 +756,10 @@ Bit32s scsi_device_t::scsi_send_command(Bit32u tag, Bit8u *buf, int lun)
|
||||
|
||||
// Current/Max Cap Header
|
||||
if (type == SCSIDEV_TYPE_CDROM) {
|
||||
nb_sectors = cdrom->capacity();
|
||||
nb_sectors = max_lba;
|
||||
} else {
|
||||
nb_sectors = (hdimage->hd_size / 512);
|
||||
nb_sectors--;
|
||||
}
|
||||
/* Returned value is the address of the last sector. */
|
||||
outbuf[4] = (Bit8u)((nb_sectors >> 24) & 0xff);
|
||||
@ -794,4 +797,14 @@ Bit32s scsi_device_t::scsi_send_command(Bit32u tag, Bit8u *buf, int lun)
|
||||
}
|
||||
}
|
||||
|
||||
void scsi_device_t::set_inserted(bx_bool value)
|
||||
{
|
||||
inserted = value;
|
||||
if (inserted) {
|
||||
max_lba = cdrom->capacity() - 1;
|
||||
} else {
|
||||
max_lba = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BX_SUPPORT_PCI && BX_SUPPORT_PCIUSB
|
||||
|
@ -9,7 +9,7 @@
|
||||
//
|
||||
// Written by Paul Brook
|
||||
//
|
||||
// Copyright (C) 2007-2013 The Bochs Project
|
||||
// Copyright (C) 2007-2014 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -84,7 +84,7 @@ public:
|
||||
int scsi_write_data(Bit32u tag);
|
||||
Bit8u* scsi_get_buf(Bit32u tag);
|
||||
const char *get_serial_number() {return drive_serial_str;}
|
||||
void set_inserted(bx_bool value) {inserted = value;}
|
||||
void set_inserted(bx_bool value);
|
||||
bx_bool get_inserted() {return inserted;}
|
||||
|
||||
protected:
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
// Copyright (c) 2005 Fabrice Bellard
|
||||
// Copyright (C) 2009 Benjamin D Lunt (fys at frontiernet net)
|
||||
// 2009-2013 The Bochs Project
|
||||
// 2009-2014 The Bochs Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
@ -73,8 +73,10 @@ int bx_usb_devctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
|
||||
int ports;
|
||||
usb_device_c **device = (usb_device_c**)dev;
|
||||
const char *devname = NULL;
|
||||
size_t dnlen;
|
||||
|
||||
devname = ((bx_param_string_c*)portconf->get_by_name("device"))->getptr();
|
||||
dnlen = strlen(devname);
|
||||
if (!strcmp(devname, "mouse")) {
|
||||
type = USB_DEV_TYPE_MOUSE;
|
||||
*device = new usb_hid_device_c(type);
|
||||
@ -85,7 +87,7 @@ int bx_usb_devctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
|
||||
type = USB_DEV_TYPE_KEYPAD;
|
||||
*device = new usb_hid_device_c(type);
|
||||
} else if (!strncmp(devname, "disk", 4)) {
|
||||
if ((strlen(devname) > 5) && (devname[4] == ':')) {
|
||||
if ((dnlen > 5) && (devname[4] == ':')) {
|
||||
type = USB_DEV_TYPE_DISK;
|
||||
*device = new usb_msd_device_c(type, devname+5);
|
||||
} else {
|
||||
@ -93,9 +95,13 @@ int bx_usb_devctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
|
||||
return type;
|
||||
}
|
||||
} else if (!strncmp(devname, "cdrom", 5)) {
|
||||
if ((strlen(devname) > 6) && (devname[5] == ':')) {
|
||||
if ((dnlen == 5) || (devname[5] == ':')) {
|
||||
type = USB_DEV_TYPE_CDROM;
|
||||
*device = new usb_msd_device_c(type, devname+6);
|
||||
if (dnlen > 6) {
|
||||
*device = new usb_msd_device_c(type, devname+6);
|
||||
} else {
|
||||
*device = new usb_msd_device_c(type, devname+dnlen);
|
||||
}
|
||||
} else {
|
||||
hub->panic("USB device 'cdrom' needs a filename separated with a colon");
|
||||
return type;
|
||||
@ -103,7 +109,7 @@ int bx_usb_devctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
|
||||
} else if (!strncmp(devname, "hub", 3)) {
|
||||
type = USB_DEV_TYPE_HUB;
|
||||
ports = 4;
|
||||
if (strlen(devname) > 3) {
|
||||
if (dnlen > 3) {
|
||||
if (devname[3] == ':') {
|
||||
ports = atoi(&devname[4]);
|
||||
if ((ports < 2) || (ports > BX_N_USB_HUB_PORTS)) {
|
||||
@ -115,7 +121,7 @@ int bx_usb_devctl_c::init_device(bx_list_c *portconf, logfunctions *hub, void **
|
||||
}
|
||||
*device = new usb_hub_device_c(ports);
|
||||
} else if (!strncmp(devname, "printer", 7)) {
|
||||
if ((strlen(devname) > 8) && (devname[7] == ':')) {
|
||||
if ((dnlen > 8) && (devname[7] == ':')) {
|
||||
type = USB_DEV_TYPE_PRINTER;
|
||||
*device = new usb_printer_device_c(type, devname+8);
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
// Copyright (c) 2006 CodeSourcery.
|
||||
// Written by Paul Brook
|
||||
// Copyright (C) 2009-2013 The Bochs Project
|
||||
// Copyright (C) 2009-2014 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -180,7 +180,7 @@ usb_msd_device_c::usb_msd_device_c(usbdev_type type, const char *filename)
|
||||
"Status",
|
||||
"CD-ROM media status (inserted / ejected)",
|
||||
media_status_names,
|
||||
BX_EJECTED,
|
||||
BX_INSERTED,
|
||||
BX_EJECTED);
|
||||
status->set_handler(cd_param_handler);
|
||||
status->set_ask_format("Is the device inserted or ejected? [%s] ");
|
||||
@ -232,13 +232,12 @@ bx_bool usb_msd_device_c::init()
|
||||
sprintf(s.info_txt, "USB HD: path='%s', mode='%s'", s.fname, hdimage_mode_names[s.image_mode]);
|
||||
} else if (d.type == USB_DEV_TYPE_CDROM) {
|
||||
s.cdrom = DEV_hdimage_init_cdrom(s.fname);
|
||||
if (!s.cdrom->insert_cdrom()) {
|
||||
BX_ERROR(("could not open cdrom image file '%s'", s.fname));
|
||||
return 0;
|
||||
s.scsi_dev = new scsi_device_t(s.cdrom, 0, usb_msd_command_complete, (void*)this);
|
||||
if (set_inserted(1)) {
|
||||
sprintf(s.info_txt, "USB CD: path='%s'", s.fname);
|
||||
} else {
|
||||
s.scsi_dev = new scsi_device_t(s.cdrom, 0, usb_msd_command_complete, (void*)this);
|
||||
sprintf(s.info_txt, "USB CD: media not present");
|
||||
}
|
||||
sprintf(s.info_txt, "USB CD: path='%s'", s.fname);
|
||||
}
|
||||
s.scsi_dev->register_state(s.sr_list, "scsidev");
|
||||
s.mode = USB_MSDM_CBW;
|
||||
@ -649,20 +648,21 @@ void usb_msd_device_c::cancel_packet(USBPacket *p)
|
||||
s.scsi_len = 0;
|
||||
}
|
||||
|
||||
void usb_msd_device_c::set_inserted(bx_bool value)
|
||||
bx_bool usb_msd_device_c::set_inserted(bx_bool value)
|
||||
{
|
||||
const char *path;
|
||||
|
||||
if (value) {
|
||||
path = SIM->get_param_string("path", s.config)->getptr();
|
||||
if (!s.cdrom->insert_cdrom(path)) {
|
||||
SIM->get_param_bool("status", s.config)->set(0);
|
||||
return;
|
||||
SIM->get_param_enum("status", s.config)->set(BX_EJECTED);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
s.cdrom->eject_cdrom();
|
||||
}
|
||||
s.scsi_dev->set_inserted(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
bx_bool usb_msd_device_c::get_inserted()
|
||||
@ -689,7 +689,7 @@ const char *usb_msd_device_c::cd_param_string_handler(bx_param_string_c *param,
|
||||
param->set("none");
|
||||
}
|
||||
} else {
|
||||
SIM->get_param_bool("status", param->get_parent())->set(0);
|
||||
SIM->get_param_enum("status", param->get_parent())->set(BX_EJECTED);
|
||||
}
|
||||
} else {
|
||||
BX_PANIC(("cd_param_string_handler: cdrom not found"));
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
// Copyright (c) 2006 CodeSourcery.
|
||||
// Written by Paul Brook
|
||||
// Copyright (C) 2009-2013 The Bochs Project
|
||||
// Copyright (C) 2009-2014 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -44,7 +44,7 @@ public:
|
||||
virtual int handle_data(USBPacket *p);
|
||||
virtual void register_state_specific(bx_list_c *parent);
|
||||
virtual void cancel_packet(USBPacket *p);
|
||||
void set_inserted(bx_bool value);
|
||||
bx_bool set_inserted(bx_bool value);
|
||||
bx_bool get_inserted();
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user