Added seek emulation for USB disk write commands (async mode required).
Fixed MSD status handling (required for seek emulation).
This commit is contained in:
parent
3c7260a01b
commit
fcf9b8285b
@ -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));
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user