From owner-freebsd-current@FreeBSD.ORG Sun Jul 5 08:39:45 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 89DA61065672 for ; Sun, 5 Jul 2009 08:39:45 +0000 (UTC) (envelope-from hselasky@c2i.net) Received: from swip.net (mailfe06.swip.net [212.247.154.161]) by mx1.freebsd.org (Postfix) with ESMTP id D52998FC15 for ; Sun, 5 Jul 2009 08:39:44 +0000 (UTC) (envelope-from hselasky@c2i.net) X-Cloudmark-Score: 0.000000 [] X-Cloudmark-Analysis: v=1.0 c=1 a=BQeo18V-fugA:10 a=MXw7gxVQKqGXY79tIT8aFQ==:17 a=8kQB0OdkAAAA:8 a=q_pyG5KHjDeSI5tZlpUA:9 a=Hs_6fdvUTFY2Eg46FMaXpuLqehUA:4 a=9aOQ2cSd83gA:10 a=Apmh3L7rKdBIR0ouH8wA:9 a=0GkuctUUkaA5_SiZaQ8A:7 a=bz3TkzYc18S27zjSIMw4rX9E9JIA:4 Received: from [62.113.132.61] (account mc467741@c2i.net HELO laptop.adsl.tele2.no) by mailfe06.swip.net (CommuniGate Pro SMTP 5.2.13) with ESMTPA id 1271944512; Sun, 05 Jul 2009 10:39:43 +0200 From: Hans Petter Selasky To: freebsd-current@freebsd.org Date: Sun, 5 Jul 2009 10:39:18 +0200 User-Agent: KMail/1.11.4 (FreeBSD/8.0-CURRENT; KDE/4.2.4; i386; ; ) References: <20090703172600.1971111e@baby-jane.lamaiziere.net> <200907040945.41153.hselasky@c2i.net> <20090704164341.0acd0271@baby-jane.lamaiziere.net> In-Reply-To: <20090704164341.0acd0271@baby-jane.lamaiziere.net> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_3aGUKFo9aO8ZqtK" Message-Id: <200907051039.19584.hselasky@c2i.net> Cc: Patrick Lamaiziere Subject: Re: ulpt problem (USB_ERR_IOERROR) X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Jul 2009 08:39:45 -0000 --Boundary-00=_3aGUKFo9aO8ZqtK Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Saturday 04 July 2009 16:43:41 Patrick Lamaiziere wrote: > Le Sat, 4 Jul 2009 09:45:40 +0200, > > Hans Petter Selasky a =E9crit : > > > ulpt_write_callback:220: state=3D0x1 actlen=3D2889 > > > ulpt_write_callback:220: state=3D0x1 actlen=3D3023 > > > > These two lines are interesting. Are these printed when doing the > > same job? > > Yes. > Can you try the attached patch for 8-current. Please provide ulpt debug pri= nts=20 in either failing or succeeding case. cd /sys/dev/usb cat ulpt.diff | patch Build a new kernel and modules. =2D-HPS --Boundary-00=_3aGUKFo9aO8ZqtK Content-Type: text/x-patch; charset="iso-8859-1"; name="ulpt.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ulpt.diff" diff -u ./serial/ulpt.c ./serial/ulpt.c --- ./serial/ulpt.c 2009-06-24 12:59:19.000000000 +0200 +++ ./serial/ulpt.c 2009-07-05 10:19:31.000000000 +0200 @@ -110,6 +110,7 @@ struct ulpt_softc { struct usb_fifo_sc sc_fifo; struct usb_fifo_sc sc_fifo_noreset; + struct usb_fifo_sc sc_fifo_raw; struct mtx sc_mtx; struct usb_callout sc_watchdog; @@ -147,6 +148,7 @@ static usb_fifo_ioctl_t ulpt_ioctl; static usb_fifo_open_t ulpt_open; static usb_fifo_open_t unlpt_open; +static usb_fifo_open_t urlpt_open; static struct usb_fifo_methods ulpt_fifo_methods = { .f_close = &ulpt_close, @@ -170,6 +172,17 @@ .basename[0] = "unlpt", }; +static struct usb_fifo_methods urlpt_fifo_methods = { + .f_close = &ulpt_close, + .f_ioctl = &ulpt_ioctl, + .f_open = &urlpt_open, + .f_start_read = &ulpt_start_read, + .f_start_write = &ulpt_start_write, + .f_stop_read = &ulpt_stop_read, + .f_stop_write = &ulpt_stop_write, + .basename[0] = "urlpt", +}; + static void ulpt_reset(struct ulpt_softc *sc) { @@ -419,6 +432,28 @@ } static int +urlpt_open(struct usb_fifo *fifo, int fflags) +{ + struct ulpt_softc *sc = usb_fifo_softc(fifo); + + /* we assume that open is a serial process */ + + if (sc->sc_fflags == 0) { + + /* reset USB paralell port */ + + ulpt_reset(sc); + + /* set raw write mode */ + + if (fflags & FWRITE) { + usb_fifo_set_write_defrag(fifo, 0); + } + } + return (unlpt_open(fifo, fflags)); +} + +static int ulpt_open(struct usb_fifo *fifo, int fflags) { struct ulpt_softc *sc = usb_fifo_softc(fifo); @@ -426,7 +461,16 @@ /* we assume that open is a serial process */ if (sc->sc_fflags == 0) { + + /* reset USB paralell port */ + ulpt_reset(sc); + + /* set defrag write mode */ + + if (fflags & FWRITE) { + usb_fifo_set_write_defrag(fifo, 1); + } } return (unlpt_open(fifo, fflags)); } @@ -633,6 +677,13 @@ if (error) { goto detach; } + error = usb_fifo_attach(uaa->device, sc, &sc->sc_mtx, + &urlpt_fifo_methods, &sc->sc_fifo_raw, + unit, 0 - 1, uaa->info.bIfaceIndex, + UID_ROOT, GID_OPERATOR, 0644); + if (error) { + goto detach; + } /* start reading of status */ mtx_lock(&sc->sc_mtx); @@ -654,6 +705,7 @@ usb_fifo_detach(&sc->sc_fifo); usb_fifo_detach(&sc->sc_fifo_noreset); + usb_fifo_detach(&sc->sc_fifo_raw); mtx_lock(&sc->sc_mtx); usb_callout_stop(&sc->sc_watchdog); diff -u ./usb_busdma.c ./usb_busdma.c --- ./usb_busdma.c 2009-06-23 04:19:59.000000000 +0200 +++ ./usb_busdma.c 2009-06-29 13:10:45.000000000 +0200 @@ -359,7 +359,8 @@ if (bus_dma_tag_create ( /* parent */ udt->tag_parent->tag, /* alignment */ align, - /* boundary */ USB_PAGE_SIZE, + /* boundary */ (align == 1) ? + USB_PAGE_SIZE : 0, /* lowaddr */ (2ULL << (udt->tag_parent->dma_bits - 1)) - 1, /* highaddr */ BUS_SPACE_MAXADDR, /* filter */ NULL, diff -u ./usb_dev.c ./usb_dev.c --- ./usb_dev.c 2009-06-24 12:59:19.000000000 +0200 +++ ./usb_dev.c 2009-07-05 10:05:59.000000000 +0200 @@ -740,6 +740,8 @@ break; } } + /* reset have fragment flag */ + f->flag_have_fragment = 0; } /*------------------------------------------------------------------------* @@ -783,6 +785,16 @@ /* set flushing flag */ f->flag_flushing = 1; + /* get the last packet in */ + if (f->flag_have_fragment) { + struct usb_mbuf *m; + f->flag_have_fragment = 0; + USB_IF_DEQUEUE(&f->free_q, m); + if (m) { + USB_IF_ENQUEUE(&f->used_q, m); + } + } + /* start write transfer, if not already started */ (f->methods->f_start_write) (f); @@ -1303,6 +1315,7 @@ struct usb_cdev_privdata* cpd; struct usb_fifo *f; struct usb_mbuf *m; + uint8_t *pdata; int fflags; int resid; int io_len; @@ -1373,33 +1386,59 @@ } tr_data = 1; - USB_MBUF_RESET(m); - - io_len = MIN(m->cur_data_len, uio->uio_resid); - - m->cur_data_len = io_len; + if (f->flag_have_fragment == 0) { + USB_MBUF_RESET(m); + io_len = m->cur_data_len; + pdata = m->cur_data_ptr; + if (io_len > uio->uio_resid) + io_len = uio->uio_resid; + m->cur_data_len = io_len; + } else { + io_len = m->max_data_len - m->cur_data_len; + pdata = m->cur_data_ptr + io_len; + if (io_len > uio->uio_resid) + io_len = uio->uio_resid; + m->cur_data_len += io_len; + } DPRINTFN(2, "transfer %d bytes to %p\n", - io_len, m->cur_data_ptr); + io_len, pdata); - err = usb_fifo_uiomove(f, - m->cur_data_ptr, io_len, uio); + err = usb_fifo_uiomove(f, pdata, io_len, uio); if (err) { + f->flag_have_fragment = 0; USB_IF_ENQUEUE(&f->free_q, m); break; } - if (f->methods->f_filter_write) { + + /* check if the buffer is ready to be transmitted */ + + if ((f->flag_write_defrag == 0) || + (m->cur_data_len == m->max_data_len)) { + f->flag_have_fragment = 0; + /* - * Sometimes it is convenient to process data at the - * expense of a userland process instead of a kernel - * process. + * Check for write filter: + * + * Sometimes it is convenient to process data + * at the expense of a userland process + * instead of a kernel process. */ - (f->methods->f_filter_write) (f, m); - } - USB_IF_ENQUEUE(&f->used_q, m); + if (f->methods->f_filter_write) { + (f->methods->f_filter_write) (f, m); + } - (f->methods->f_start_write) (f); + /* Put USB mbuf in the used queue */ + USB_IF_ENQUEUE(&f->used_q, m); + + /* Start writing data, if not already started */ + (f->methods->f_start_write) (f); + } else { + /* Wait for more data or close */ + f->flag_have_fragment = 1; + USB_IF_PREPEND(&f->free_q, m); + } } while (uio->uio_resid > 0); done: @@ -2220,6 +2259,18 @@ f->flag_short = onoff; } +void +usb_fifo_set_write_defrag(struct usb_fifo *f, uint8_t onoff) +{ + if (f == NULL) + return; + + /* defrag written data */ + f->flag_write_defrag = onoff; + /* reset defrag state */ + f->flag_have_fragment = 0; +} + void * usb_fifo_softc(struct usb_fifo *f) { diff -u ./usb_dev.h ./usb_dev.h --- ./usb_dev.h 2009-06-24 12:59:19.000000000 +0200 +++ ./usb_dev.h 2009-07-05 10:36:50.000000000 +0200 @@ -130,6 +130,8 @@ uint8_t flag_short; /* set if short_ok or force_short * transfer flags should be set */ uint8_t flag_stall; /* set if clear stall should be run */ + uint8_t flag_write_defrag; /* set to defrag written data */ + uint8_t flag_have_fragment; /* set if defragging */ uint8_t iface_index; /* set to the interface we belong to */ uint8_t fifo_index; /* set to the FIFO index in "struct * usb_device" */ @@ -144,11 +146,9 @@ int usb_fifo_wait(struct usb_fifo *fifo); void usb_fifo_signal(struct usb_fifo *fifo); uint8_t usb_fifo_opened(struct usb_fifo *fifo); -void usb_fifo_free(struct usb_fifo *f); struct usb_symlink *usb_alloc_symlink(const char *target); void usb_free_symlink(struct usb_symlink *ps); int usb_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len); -void usb_fifo_set_close_zlp(struct usb_fifo *, uint8_t); #endif /* _USB_DEV_H_ */ diff -u ./usbdi.h ./usbdi.h --- ./usbdi.h 2009-06-28 08:48:04.000000000 +0200 +++ ./usbdi.h 2009-07-05 10:36:50.000000000 +0200 @@ -531,5 +531,8 @@ void usb_fifo_wakeup(struct usb_fifo *f); void usb_fifo_get_data_error(struct usb_fifo *fifo); void *usb_fifo_softc(struct usb_fifo *fifo); +void usb_fifo_set_close_zlp(struct usb_fifo *, uint8_t); +void usb_fifo_set_write_defrag(struct usb_fifo *, uint8_t); +void usb_fifo_free(struct usb_fifo *f); #endif /* _KERNEL */ #endif /* _USB_USBDI_H_ */ --Boundary-00=_3aGUKFo9aO8ZqtK--