From owner-p4-projects@FreeBSD.ORG Tue Jul 7 18:35:52 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 185811065673; Tue, 7 Jul 2009 18:35:52 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CA4A81065670 for ; Tue, 7 Jul 2009 18:35:51 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B7A098FC0A for ; Tue, 7 Jul 2009 18:35:51 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n67IZpSf093690 for ; Tue, 7 Jul 2009 18:35:51 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n67IZpI9093688 for perforce@freebsd.org; Tue, 7 Jul 2009 18:35:51 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 7 Jul 2009 18:35:51 GMT Message-Id: <200907071835.n67IZpI9093688@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 165771 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 07 Jul 2009 18:35:53 -0000 http://perforce.freebsd.org/chv.cgi?CH=165771 Change 165771 by hselasky@hselasky_laptop001 on 2009/07/07 18:35:28 USB CORE: - add support for automatic defragging of written device data. - fix issue with CUPS and /dev/ulpt reported by Patrick Lamaiziere - a new device node, /dev/urlptX, has been created to preserve the old behaviour Affected files ... .. //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#16 edit .. //depot/projects/usb/src/sys/dev/usb/usb_dev.c#31 edit .. //depot/projects/usb/src/sys/dev/usb/usb_dev.h#16 edit .. //depot/projects/usb/src/sys/dev/usb/usbdi.h#11 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#16 (text+ko) ==== @@ -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,27 @@ } 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,8 +460,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 +675,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 +703,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); ==== //depot/projects/usb/src/sys/dev/usb/usb_dev.c#31 (text+ko) ==== @@ -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); + if (f->methods->f_filter_write) { + (f->methods->f_filter_write) (f, m); + } + + /* 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); } - USB_IF_ENQUEUE(&f->used_q, m); - - (f->methods->f_start_write) (f); } 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) { ==== //depot/projects/usb/src/sys/dev/usb/usb_dev.h#16 (text+ko) ==== @@ -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_ */ ==== //depot/projects/usb/src/sys/dev/usb/usbdi.h#11 (text+ko) ==== @@ -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_ */