usb/94717: Reading from /dev/ulpt can break work of a UHCI hub
Alexey Illarionov
littlesavage at rambler.ru
Mon Mar 20 05:30:17 UTC 2006
>Number: 94717
>Category: usb
>Synopsis: Reading from /dev/ulpt can break work of a UHCI hub
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-usb
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Mar 20 05:30:14 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Alexey Illarionov
>Release:
>Organization:
>Environment:
FreeBSD ls.orionet.ru 6.1-PRERELEASE FreeBSD 6.1-PRERELEASE #5: Fri Mar 17 11:13:17 MSK 2006 alexey at ls.orionet.ru:/usr/obj/usr/src/sys/LS i386
>Description:
Reading from /dev/ulpt with the insufficient buffer can break work of a UHCI hub
I use a following configuration:
uhci0: <VIA 83C572 USB controller> port 0xcc00-0xcc1f irq 9 at device 7.2 on pci0
uhci0: [GIANT-LOCKED]
uhci0: LegSup = 0xa000
usb0: <VIA 83C572 USB controller> on uhci0
usb0: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub0: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
uhci1: <VIA 83C572 USB controller> port 0xd000-0xd01f irq 9 at device 7.3 on pci0
uhci1: [GIANT-LOCKED]
uhci1: LegSup = 0xa000
usb1: <VIA 83C572 USB controller> on uhci1
usb1: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub1: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub1: 2 ports with 2 removable, self powered
ums0: Microsoft Microsoft 3-Button Mouse with IntelliEye(TM), rev 1.10/3.00, addr 2, iclass 3/1
ums0: 3 buttons and Z dir.
ulpt0: Canon Canon CAPT USB Printer, rev 1.10/1.00, addr 3, iclass 7/1
ulpt0: using bi-directional mode
And test program:
#include <sys/types.h>
#include <sys/uio.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#define NBYTES 16
const char port[] = "/dev/ulpt0";
const char req[] = {0xa0, 0xa0, 0x04, 0x0};
int main()
{
int d;
size_t size;
char ack[100];
d = open(port, O_RDWR);
if (d < 0) {
perror("open error");
return 1;
}
size = write(d, req, sizeof(req));
if (size != sizeof(req)) {
perror("write error");
return 2;
}
size = read(d, ack, NBYTES);
if (size == -1){
perror("read error");
return 3;
}
printf("size: %i\n", size);
close(d);
return 0;
}
When NBYTES = 16, all work normally, printer return 16 bytes of data.
But if define NBYTES=4 (i.e. not enough size for store the
ack from the printer), then read() return input/output error and after
that both the USB mouse, and the printer will not work until reboot.
I get the same results at testing by other machine with a following
USB hardware:
uhci0: <Intel 82371AB/EB (PIIX4) USB controller> port 0xd000-0xd01f irq 11 at device 7.2 on pci0
uhci0: [GIANT-LOCKED]
usb0: <Intel 82371AB/EB (PIIX4) USB controller> on uhci0
usb0: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub0: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
I get the same results at testing by other machine with a following
USB hardware:
uhci0: <Intel 82371AB/EB (PIIX4) USB controller> port 0xd000-0xd01f irq 11 at device 7.2 on pci0
uhci0: [GIANT-LOCKED]
usb0: <Intel 82371AB/EB (PIIX4) USB controller> on uhci0
usb0: USB revision 1.0
usbd_get_string: getting lang failed, using 0
uhub0: Intel UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
By the third machine with OHCI controller (ATI SB400 USB Controller)
it is little bit better. read() returns input/output error, but
the hub is not disconnected.
The debugging information from first configuration:
ulptread
ulptread: transfer 4 bytes
usbd_bulk_transfer: start transfer 4 bytes
usbd_transfer: xfer=0xc1ac0a00, flags=5, pipe=0xc1a74b00, running=0
usbd_dump_queue: pipe=0xc1a74b00
usb_insert_transfer: pipe=0xc1a74b00 running=0 timeout=0
uhci_device_bulk_start: xfer=0xc1ac0a00 len=4 flags=5 ii=0xc1ac0a70
uhci_alloc_std_chain: addr=2 endpt=2 len=4 speed=2 flags=0x5
uhci_alloc_std_chain: maxp=64 ntd=1
uhci_alloc_std_chain: nexttog=1
uhci_device_bulk_transfer: data(1)
TD(0xc1630ee0) at 0f8a4ee0 = link=0x00000005 status=0x398003ff token=0x00610269 buffer=0x0f66a000
5<T,VF> 398003ff<ACTIVE,IOC,SPD>,errcnt=3,actlen=0 pid=69,addr=2,endpt=2,D=0,maxlen=4
uhci_add_bulk: sqh=0xc1631d40
uhci_start_loop: add
uhci_device_bulk_transfer: data(2)
TD(0xc1630ee0) at 0f8a4ee0 = link=0x00000005 status=0x398003ff token=0x00610269 buffer=0x0f66a000
5<T,VF> 398003ff<ACTIVE,IOC,SPD>,errcnt=3,actlen=0 pid=69,addr=2,endpt=2,D=0,maxlen=4
uhci_intr: real interrupt
usb0: uhci_intr1
usb0 regs: cmd=0081, sts=0003, intr=000f, frnum=03f7, flbase=00208000, sof=0040, portsc1=0495, portsc2=05a5
usb_schedsoftintr: polling=0
usb0: uhci_softintr (0)
uhci_check_intr: ii=0xc1ac0a70
uhci_check_intr: ii=0xc1ac0a70 done
uhci_idone: ii=0xc1ac0a70
uhci_idone: ii=0xc1ac0a70, xfer=0xc1ac0a00, pipe=0xc1a74b00 ready
TD(0xc1630ee0) at 0f8a4ee0 = link=0x00000005 status=0x19500003 token=0x00610269 buffer=0x0f66a000
5<T,VF> 19500003<BABBLE,STALLED,IOC>,errcnt=3,actlen=4 pid=69,addr=2,endpt=2,D=0,maxlen=4
uhci_idone: actlen=4, status=0x500000
uhci_idone: error, addr=2, endpt=0x82, status 0x500000<BABBLE,STALLED>
usb_transfer_complete: pipe=0xc1a74b00 xfer=0xc1ac0a00 status=13 actlen=4
usb_transfer_complete: repeat=0 new head=0
uhci_device_bulk_done: xfer=0xc1ac0a00 ii=0xc1ac0a70 sc=0xc15f7000 upipe=0xc1a74b00
uhci_remove_bulk: sqh=0xc1631d40
uhci_end_loop: remove
uhci_find_prev_qh: pqh=0xc1632fc0 sqh=0xc1631d40
uhci_device_bulk_done: length=4
usbd_start_next: pipe=0xc1a74b00, xfer=0
uhci_idone: ii=0xc1ac0a70 done
uhci_check_intr: ii=0xc1627670
uhci_check_intr: active ii=0xc1627670
uhci_check_intr: ii=0xc1627670 std=0xc1630f40 still active
usb0: uhci_intr: exit
uhci_intr: real interrupt
usb1: uhci_intr1
usb1 regs: cmd=0081, sts=0000, intr=000f, frnum=019f, flbase=0f67f000, sof=0040, portsc1=0480, portsc2=0480
usbd_bulk_transfer: transferred 4
usbd_bulk_transfer: error=13
usbd_clear_endpoint_stall
usbd_alloc_xfer() = 0xc1ac0c00
usbd_transfer: xfer=0xc1ac0c00, flags=2, pipe=0xc1adb600, running=0
usbd_dump_queue: pipe=0xc1adb600
usb_insert_transfer: pipe=0xc1adb600 running=0 timeout=5000
uhci_device_control type=0x02, request=0x01, wValue=0x0000, wIndex=0x0082 len=0, addr=2, endpt=0
uhci_device_request: before transfer
TD(0xc1630f20) at 0f8a4f20 = link=0x0f8a4f04 status=0x18800000 token=0x00e0022d buffer=0x0f8c3e80
f8a4f04<VF> 18800000<ACTIVE>,errcnt=3,actlen=1 pid=2d,addr=2,endpt=0,D=0,maxlen=8
TD(0xc1630f00) at 0f8a4f00 = link=0x00000001 status=0x19800000 token=0xffe80269 buffer=0x00000000
1<T> 19800000<ACTIVE,IOC>,errcnt=3,actlen=1 pid=69,addr=2,endpt=0,D=1,maxlen=0
uhci_add_ctrl: sqh=0xc1631d60
uhci_enter_ctl_q: follow from [0]
TD(0xc1633fc0) at 0f967fc0 = link=0x0f8c6f62 status=0x02000000 token=0x00000000 buffer=0x00000000
f8c6f62<Q> 2000000<ISO>,errcnt=0,actlen=1 pid=00,addr=0,endpt=0,D=0,maxlen=1
QH(0xc1632f60) at 0f8c6f60: hlink=0f965f22 elink=00000001
QH(0xc1632f60) at 0f8c6f60: hlink=0f965f22 elink=00000001
QH(0xc1631f20) at 0f965f20: hlink=0f8c6f82 elink=0f8a4f40
QH(0xc1632f80) at 0f8c6f80: hlink=0f8c6fa2 elink=00000001
QH(0xc1632fc0) at 0f8c6fc0: hlink=0f8c6fe2 elink=00000001
QH(0xc1632fe0) at 0f8c6fe0: hlink=00000001 elink=0f967fe0
Enqueued QH:
QH(0xc1631d60) at 0f965d60: hlink=0f8c6fc2 elink=0f8a4f20
TD(0xc1630f20) at 0f8a4f20 = link=0x0f8a4f04 status=0x18800000 token=0x00e0022d buffer=0x0f8c3e80
f8a4f04<VF> 18800000<ACTIVE>,errcnt=3,actlen=1 pid=2d,addr=2,endpt=0,D=0,maxlen=8
TD(0xc1630f00) at 0f8a4f00 = link=0x00000001 status=0x19800000 token=0xffe80269 buffer=0x00000000
1<T> 19800000<ACTIVE,IOC>,errcnt=3,actlen=1 pid=69,addr=2,endpt=0,D=1,maxlen=0
uhci_timeout: uxfer=0xc1ac0c00
usb_add_task: task=0xc1ac0c88
usb_task_thread: woke up task=0xc1ac0c88
uhci_timeout_task: xfer=0xc1ac0c00
uhci_abort_xfer: xfer=0xc1ac0c00, status=15
uhci_abort_xfer: stop ii=0xc1ac0c70
usb_schedsoftintr: polling=0
usb0: uhci_softintr (0)
uhci_check_intr: ii=0xc1ac0c70
uhci_check_intr: aborted xfer=0xc1ac0c00
uhci_check_intr: ii=0xc1627670
uhci_check_intr: active ii=0xc1627670
uhci_check_intr: ii=0xc1627670 std=0xc1630f40 still active
uhci_abort_xfer: callback
usb_transfer_complete: pipe=0xc1adb600 xfer=0xc1ac0c00 status=15 actlen=0
usb_transfer_complete: repeat=0 new head=0
uhci_remove_hs_ctrl: sqh=0xc1631d60
uhci_find_prev_qh: pqh=0xc1632fa0 sqh=0xc1631d60
uhci_device_ctrl_done: length=0
usbd_start_next: pipe=0xc1adb600, xfer=0
usbd_free_xfer: 0xc1ac0c00
ulptread: error=13
usbd_ar_pipe: pipe=0xc1829480
usbd_dump_queue: pipe=0xc1829480
usbd_free_xfer: 0xc1ac0b00
usb_freemem: large free
usb_block_freemem: size=4096
usbd_ar_pipe: pipe=0xc1a74b00
usbd_dump_queue: pipe=0xc1a74b00
usbd_free_xfer: 0xc1ac0a00
usb_freemem: large free
usb_block_freemem: size=4096
ulptclose: closed
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-usb
mailing list