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