Added seek emulation for USB disk write commands (async mode required).

Fixed MSD status handling (required for seek emulation).
This commit is contained in:
Volker Ruppert 2015-10-22 18:13:59 +00:00
parent 3c7260a01b
commit fcf9b8285b
3 changed files with 18 additions and 17 deletions

View File

@ -461,7 +461,11 @@ void scsi_device_t::scsi_write_data(Bit32u tag)
} }
if (type == SCSIDEV_TYPE_DISK) { if (type == SCSIDEV_TYPE_DISK) {
if ((r->buf_len / 512) > 0) { if ((r->buf_len / 512) > 0) {
seek_complete(r); if ((r->async_mode) && (r->seek_pending == 2)) {
start_seek(r);
} else if (!r->seek_pending) {
seek_complete(r);
}
} else { } else {
scsi_write_complete(r, 0); scsi_write_complete(r, 0);
} }
@ -834,6 +838,8 @@ Bit32s scsi_device_t::scsi_send_command(Bit32u tag, Bit8u *buf, int lun, bx_bool
r->sector = lba; r->sector = lba;
r->sector_count = len; r->sector_count = len;
r->write_cmd = 1; r->write_cmd = 1;
r->seek_pending = 2;
r->async_mode = async;
break; break;
case 0x35: case 0x35:
BX_DEBUG(("Syncronise cache (sector " FMT_LL "d, count %d)", lba, len)); BX_DEBUG(("Syncronise cache (sector " FMT_LL "d, count %d)", lba, len));

View File

@ -692,13 +692,6 @@ int usb_msd_device_c::handle_data(USBPacket *p)
switch (s.mode) { switch (s.mode) {
case USB_MSDM_DATAOUT: case USB_MSDM_DATAOUT:
if ((s.data_len > 0) && (len == 13)) {
s.usb_len = len;
s.usb_buf = data;
send_status();
ret = 13;
break;
}
if (s.data_len != 0 || len < 13) if (s.data_len != 0 || len < 13)
goto fail; goto fail;
usb_defer_packet(p, this); usb_defer_packet(p, this);
@ -712,9 +705,7 @@ int usb_msd_device_c::handle_data(USBPacket *p)
if (len < 13) if (len < 13)
return ret; return ret;
s.usb_len = len; send_status(p);
s.usb_buf = data;
send_status();
s.mode = USB_MSDM_CBW; s.mode = USB_MSDM_CBW;
ret = 13; ret = 13;
break; break;
@ -787,15 +778,15 @@ void usb_msd_device_c::copy_data()
} }
} }
void usb_msd_device_c::send_status() void usb_msd_device_c::send_status(USBPacket *p)
{ {
struct usb_msd_csw csw; struct usb_msd_csw csw;
csw.sig = htod32(0x53425355); csw.sig = htod32(0x53425355);
csw.tag = htod32(s.tag); csw.tag = htod32(s.tag);
csw.residue = s.residue; csw.residue = htod32(s.residue);
csw.status = s.result; csw.status = s.result;
memcpy(s.usb_buf, &csw, 13); memcpy(p->data, &csw, BX_MIN(p->len, 13));
} }
void usb_msd_device_c::usb_msd_command_complete(void *this_ptr, int reason, Bit32u tag, Bit32u arg) void usb_msd_device_c::usb_msd_command_complete(void *this_ptr, int reason, Bit32u tag, Bit32u arg)
@ -816,8 +807,12 @@ void usb_msd_device_c::command_complete(int reason, Bit32u tag, Bit32u arg)
s.residue = s.data_len; s.residue = s.data_len;
s.result = arg != 0; s.result = arg != 0;
if (s.packet) { if (s.packet) {
if (s.data_len == 0 && s.mode == USB_MSDM_DATAOUT) { if ((s.data_len == 0) && (s.mode == USB_MSDM_DATAOUT)) {
send_status(); send_status(p);
s.mode = USB_MSDM_CBW;
usb_dump_packet(p->data, p->len);
} else if (s.mode == USB_MSDM_CSW) {
send_status(p);
s.mode = USB_MSDM_CBW; s.mode = USB_MSDM_CBW;
} else { } else {
if (s.data_len) { if (s.data_len) {

View File

@ -52,7 +52,7 @@ public:
protected: protected:
void copy_data(); void copy_data();
void send_status(); void send_status(USBPacket *p);
static void usb_msd_command_complete(void *this_ptr, int reason, Bit32u tag, Bit32u arg); static void usb_msd_command_complete(void *this_ptr, int reason, Bit32u tag, Bit32u arg);
void command_complete(int reason, Bit32u tag, Bit32u arg); void command_complete(int reason, Bit32u tag, Bit32u arg);