diff --git a/src/usb/usb_audio.c b/src/usb/usb_audio.c index 6bd8cecec2..b1b9065bdc 100644 --- a/src/usb/usb_audio.c +++ b/src/usb/usb_audio.c @@ -73,7 +73,7 @@ static const uint8_t bx_audio_config_descriptor[] = 0x24, /* u8 bDescriptor Type (CS_INTERFACE); */ 0x01, /* u8 bDescriptorSubType (HEADER); */ 0x00, 0x01, /* u16 bcdADC; */ - 0x09 + 0x0c + 0x0d + 0x09, 0x00, /* u16 wTotalLength; */ + 0x09 + 0x0c + 0x09 + 0x09, 0x00, /* u16 wTotalLength; */ 0x01, /* u8 bInCollection; */ 0x01, /* u8 baInterfaceNr; */ @@ -165,7 +165,7 @@ static const uint8_t bx_audio_config_descriptor[] = 0x25, /* u8 bDescriptorType; */ 0x01, /* u8 bDescriptorSubtype; */ // Reminder to ask the host to pad packets if this is not sufficient enough. - 0x00, /* u8 bmAttributes; */ + 0x80, /* u8 bmAttributes; */ 0x00, /* u8 bLockDelayUnits; */ 0x00, 0x00 /* u16 wLockDelay; */ }; @@ -232,6 +232,7 @@ usb_device_audio_handle_data(usb_device_c *device, USBPacket *p) // Null packets must be accepted as well. if (p->len > 0) fifo8_push_all(&usb_audio->audio_buf, p->data, p->len); + ret = p->len; } else { @@ -263,6 +264,8 @@ usb_device_audio_handle_iface_change(usb_device_c* device, int iface) usb_device_audio* usb_audio = (usb_device_audio*) device->priv; usb_audio->alt_iface_enabled = !!iface; + if (usb_audio->alt_iface_enabled == 0) + fifo8_drop(&usb_audio->audio_buf, fifo8_num_used(&usb_audio->audio_buf)); } /* @@ -406,6 +409,8 @@ usb_audio_get_buffer(int32_t *buffer, int len, void *priv) if (fifo8_num_used(&usb_audio->audio_buf) < (SOUNDBUFLEN * 2 * 2)) { + static int buffer_underrun = 0; + //pclog("USB Audio: Buffer underrun! (%d)\n", buffer_underrun++); return; } @@ -433,7 +438,7 @@ usb_audio_device_create(const device_t *info) usb_device_create(&usb_audio->device); usb_audio->device.type = 0; - usb_audio->device.minspeed = USB_SPEED_LOW; + usb_audio->device.minspeed = USB_SPEED_FULL; usb_audio->device.maxspeed = USB_SPEED_FULL; usb_audio->device.speed = usb_audio->device.minspeed; usb_audio->device.priv = usb_audio; @@ -453,6 +458,7 @@ usb_audio_device_create(const device_t *info) usb_audio->device.endpoint_info[1].max_burst_size = 0; usb_audio->device.connected = true; usb_audio->device.iface_alt = 1; + usb_audio->device.alt_iface_max = 1; usb_audio->device.handle_iface_change = usb_device_audio_handle_iface_change; usb_audio->device.handle_control = usb_device_audio_handle_control; @@ -464,7 +470,7 @@ usb_audio_device_create(const device_t *info) return NULL; } - fifo8_create(&usb_audio->audio_buf, 65536); + fifo8_create(&usb_audio->audio_buf, 65536 * 4); sound_add_handler(usb_audio_get_buffer, usb_audio); return usb_audio; diff --git a/src/usb/usb_common.c b/src/usb/usb_common.c index eaf8b7906a..41f0b519a8 100644 --- a/src/usb/usb_common.c +++ b/src/usb/usb_common.c @@ -363,7 +363,7 @@ int usb_device_handle_control_common(usb_device_c* device, int request, int valu BX_DEBUG(("USB_REQ_GET_INTERFACE:")); // with InterfaceRequest, the wValue field must be zero and wLength field must be 1 if ((value != device->iface_alt) || (length != 1)) { - //BX_ERROR(("USB_REQ_GET_INTERFACE: This type of request requires the wValue field to be zero and wLength field to be one.")); + BX_ERROR(("USB_REQ_GET_INTERFACE: This type of request requires the wValue field to be zero and wLength field to be one.")); } // all our devices only have one interface, and that value must be zero // if we ever add a device that has more than one interface (a video cam ?), we will need to modify this @@ -377,7 +377,7 @@ int usb_device_handle_control_common(usb_device_c* device, int request, int valu BX_DEBUG(("USB_REQ_SET_INTERFACE: value=%d", value)); // with InterfaceRequest, the wIndex and wLength fields must be zero if ((index != device->iface_alt) || (length != 0)) { - //BX_ERROR(("USB_REQ_SET_INTERFACE: This type of request requires the wIndex and wLength fields to be zero.")); + BX_ERROR(("USB_REQ_SET_INTERFACE: This type of request requires the wIndex and wLength fields to be zero.")); } // all our devices only have one interface, and that value must be zero // if we ever add a device that has more than one interface (a video cam ?), we will need to modify this @@ -674,6 +674,7 @@ int usb_device_handle_packet(usb_device_c* device, USBPacket *p) ret = USB_RET_STALL; break; } + //pclog("ret = %d\n", ret); return ret; } diff --git a/src/usb/usb_ohci_bochs.c b/src/usb/usb_ohci_bochs.c index 839f4e6198..6af0dcd00c 100644 --- a/src/usb/usb_ohci_bochs.c +++ b/src/usb/usb_ohci_bochs.c @@ -294,7 +294,7 @@ ohci_log(const char *fmt, ...) if (ohci_do_log) { va_start(ap, fmt); - pclog_ex(fmt, ap); + ohci_log_ex(fmt, ap); va_end(ap); } } @@ -305,7 +305,7 @@ ohci_log(const char *fmt, ...) #define BX_ERROR(x) ohci_log x ; ohci_log ("\n") #define BX_INFO(x) ohci_log x ; ohci_log ("\n") #define BX_DEBUG(x) ohci_log x ; ohci_log ("\n") -#define BX_PANIC(x) fatal x ; pclog ("\n") +#define BX_PANIC(x) fatal x ; ohci_log ("\n") #define DEV_MEM_WRITE_PHYSICAL(addr, size, data) dma_bm_write(addr, (uint8_t*)data, size, 4); #define DEV_MEM_READ_PHYSICAL(addr, size, data) dma_bm_read(addr, (uint8_t*)data, size, 4); @@ -1312,17 +1312,20 @@ int usb_ohci_process_iso_td(bx_ohci_core_t* hub, struct OHCI_ISO_TD *td, struct p = find_async_packet(&hub->packets, addr); completion = (p != NULL); if (completion && !p->done) { - return 0; + return 1; } starting_frame = ISO_TD_GET_SF(td); frame_count = ISO_TD_GET_FC(td); relative_frame_number = (int16_t)((uint16_t)(hub->op_regs.HcFmNumber) - (uint16_t)(starting_frame)); - if (relative_frame_number < 0) + if (relative_frame_number < 0){ + ohci_log("Relative frame number < 0\n"); return 1; + } else if (relative_frame_number > frame_count) { const uint32_t temp = ED_GET_HEADP(ed); + ohci_log("Relative frame number > Frame Count\n"); if (ISO_TD_GET_CC(td) == DataOverrun) return 1; else { @@ -1340,13 +1343,15 @@ int usb_ohci_process_iso_td(bx_ohci_core_t* hub, struct OHCI_ISO_TD *td, struct pid = USB_TOKEN_OUT; else if (ED_GET_D(ed) == 2) pid = USB_TOKEN_IN; - else if (ED_GET_D(ed) == 0) + else if (ED_GET_D(ed) == 0 || ED_GET_D(ed) == 3) pid = USB_TOKEN_SETUP; else return 1; - if (ISO_TD_GET_BE(td) == 0 || ISO_TD_GET_BP0(td) == 0) + if (ISO_TD_GET_BE(td) == 0 || ISO_TD_GET_BP0(td) == 0) { + ohci_log("Zero-ed BE/BP0\n"); return 1; + } start_offset = td->offset[relative_frame_number]; if (relative_frame_number < frame_count) { @@ -1357,11 +1362,13 @@ int usb_ohci_process_iso_td(bx_ohci_core_t* hub, struct OHCI_ISO_TD *td, struct if (!((start_offset >> 12) & 0xe) || ((relative_frame_number < frame_count) && - !((start_offset >> 12) & 0xe))) { + !((next_offset >> 12) & 0xe))) { + ohci_log("NOTACCESSED\n"); return 1; } if ((relative_frame_number < frame_count) && (start_offset > next_offset)) { + ohci_log("NOTACCESSED (2)\n"); return 1; } @@ -1388,6 +1395,7 @@ int usb_ohci_process_iso_td(bx_ohci_core_t* hub, struct OHCI_ISO_TD *td, struct } if (start_addr > end_addr) { + ohci_log("start_addr > end_addr\n"); return 1; } @@ -1459,6 +1467,7 @@ int usb_ohci_process_iso_td(bx_ohci_core_t* hub, struct OHCI_ISO_TD *td, struct } dma_bm_write(addr, (uint8_t*)td, sizeof(struct OHCI_ISO_TD), 4); + remove_async_packet(&hub->packets, p); return 1; } @@ -1656,7 +1665,7 @@ bool usb_ohci_process_ed(bx_ohci_core_t* hub, struct OHCI_ED *ed, const uint32_t if (ED_GET_F(ed)) { if (hub->op_regs.HcControl.ie) { // load and do a isochronous TD list - BX_DEBUG(("Found a valid ED that points to an isochronous TD")); + ohci_log("Found a valid ED that points to an isochronous TD\n"); while (!ED_GET_H(ed) && (ED_GET_HEADP(ed) != ED_GET_TAILP(ed))) { dma_bm_read(ED_GET_HEADP(ed), (uint8_t*)&cur_iso_td, sizeof(struct OHCI_ISO_TD), 4); if (usb_ohci_process_iso_td(hub, &cur_iso_td, ed)) diff --git a/src/usb/usb_uhci_bochs.c b/src/usb/usb_uhci_bochs.c index a505873b51..8a41b6f09b 100644 --- a/src/usb/usb_uhci_bochs.c +++ b/src/usb/usb_uhci_bochs.c @@ -1,3 +1,5 @@ +/* FIXME: Isochronous transfer work but cause massive problems in Windows 2000 and Windows 98 SE.*/ + #include #include #include @@ -202,7 +204,7 @@ const char *usb_speed[4] = { "high", // USB_SPEED_HIGH = 2 "super" // USB_SPEED_SUPER = 3 }; - +#define ENABLE_UHCI_LOG 1 #ifdef ENABLE_UHCI_LOG int uhci_do_log = ENABLE_UHCI_LOG; @@ -653,6 +655,9 @@ usb_uhci_do_transfer(bx_uhci_core_t *hub, uint32_t address, struct TD *td) BX_INFO(("UHCI Core: Reserved bit in the Link Pointer is not zero.")); } + if (td->dword1 & (1 << 25)) + BX_INFO(("UHCI Core: Encountered Isochronous Packet.\n")); + // the device should remain in a stall state until the next setup packet is recieved // For some reason, this doesn't work yet. // if (dev && dev->in_stall && (pid != USB_TOKEN_SETUP))