From owner-p4-projects@FreeBSD.ORG Wed Nov 19 11:31:00 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B51021065783; Wed, 19 Nov 2008 11:31:00 +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 5F7A61065781 for ; Wed, 19 Nov 2008 11:31:00 +0000 (UTC) (envelope-from zec@tel.fer.hr) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 491FD8FC12 for ; Wed, 19 Nov 2008 11:31:00 +0000 (UTC) (envelope-from zec@tel.fer.hr) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id mAJBV0Wu085443 for ; Wed, 19 Nov 2008 11:31:00 GMT (envelope-from zec@tel.fer.hr) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id mAJBUxok085437 for perforce@freebsd.org; Wed, 19 Nov 2008 11:30:59 GMT (envelope-from zec@tel.fer.hr) Date: Wed, 19 Nov 2008 11:30:59 GMT Message-Id: <200811191130.mAJBUxok085437@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to zec@tel.fer.hr using -f From: Marko Zec To: Perforce Change Reviews Cc: Subject: PERFORCE change 153209 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: Wed, 19 Nov 2008 11:31:01 -0000 http://perforce.freebsd.org/chv.cgi?CH=153209 Change 153209 by zec@zec_tca51 on 2008/11/19 11:30:05 IFC @ 153205 The tree is currently badly broken... Affected files ... .. //depot/projects/vimage/src/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#18 integrate .. //depot/projects/vimage/src/sys/dev/usb/rio500_usb.h#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/bluetooth/ng_ubt2.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/controller/ehci2.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/controller/ehci2.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/controller/uss820dci_pccard.c#3 delete .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_busdma.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_core.h#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_dev.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_dev.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_device.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_generic.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_generic.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_hub.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_request.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usb2_util.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/core/usbdevs#2 delete .. //depot/projects/vimage/src/sys/dev/usb2/image/uscanner2.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/include/Makefile#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/include/urio2_ioctl.h#2 delete .. //depot/projects/vimage/src/sys/dev/usb2/include/usb2_devid.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/include/usb2_devtable.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/include/usb2_ioctl.h#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/serial/ubsa2.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/serial/ugensa2.c#3 integrate .. //depot/projects/vimage/src/sys/dev/usb2/sound/uaudio2.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/storage/umass2.c#2 integrate .. //depot/projects/vimage/src/sys/dev/usb2/storage/urio2.c#2 integrate .. //depot/projects/vimage/src/sys/net/if.c#48 integrate .. //depot/projects/vimage/src/sys/net/if_ethersubr.c#31 integrate .. //depot/projects/vimage/src/sys/net/if_gif.c#21 integrate .. //depot/projects/vimage/src/sys/net/if_loop.c#31 integrate .. //depot/projects/vimage/src/sys/net/raw_cb.c#11 integrate .. //depot/projects/vimage/src/sys/net/route.c#33 integrate .. //depot/projects/vimage/src/sys/netinet/if_ether.c#28 integrate .. //depot/projects/vimage/src/sys/netinet/igmp.c#21 integrate .. //depot/projects/vimage/src/sys/netinet/in.c#20 integrate .. //depot/projects/vimage/src/sys/netinet/in_gif.c#15 integrate .. //depot/projects/vimage/src/sys/netinet/in_mcast.c#15 integrate .. //depot/projects/vimage/src/sys/netinet/in_pcb.c#40 integrate .. //depot/projects/vimage/src/sys/netinet/in_pcb.h#20 integrate .. //depot/projects/vimage/src/sys/netinet/in_proto.c#16 integrate .. //depot/projects/vimage/src/sys/netinet/in_rmx.c#23 integrate .. //depot/projects/vimage/src/sys/netinet/in_var.h#12 integrate .. //depot/projects/vimage/src/sys/netinet/ip_divert.c#19 integrate .. //depot/projects/vimage/src/sys/netinet/ip_fastfwd.c#15 integrate .. //depot/projects/vimage/src/sys/netinet/ip_icmp.c#22 integrate .. //depot/projects/vimage/src/sys/netinet/ip_icmp.h#2 integrate .. //depot/projects/vimage/src/sys/netinet/ip_input.c#39 integrate .. //depot/projects/vimage/src/sys/netinet/raw_ip.c#32 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_hostcache.c#29 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_input.c#44 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_output.c#26 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_reass.c#10 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_sack.c#15 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_subr.c#59 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_syncache.c#45 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_timewait.c#20 integrate .. //depot/projects/vimage/src/sys/netinet/tcp_var.h#26 integrate .. //depot/projects/vimage/src/sys/netinet/udp_usrreq.c#39 integrate .. //depot/projects/vimage/src/sys/netinet/vinet.h#34 integrate .. //depot/projects/vimage/src/sys/netinet6/frag6.c#22 integrate .. //depot/projects/vimage/src/sys/netinet6/icmp6.c#33 integrate .. //depot/projects/vimage/src/sys/netinet6/in6_ifattach.c#27 integrate .. //depot/projects/vimage/src/sys/netinet6/in6_proto.c#32 integrate .. //depot/projects/vimage/src/sys/netinet6/in6_rmx.c#23 integrate .. //depot/projects/vimage/src/sys/netinet6/in6_src.c#28 integrate .. //depot/projects/vimage/src/sys/netinet6/ip6_forward.c#17 integrate .. //depot/projects/vimage/src/sys/netinet6/ip6_input.c#38 integrate .. //depot/projects/vimage/src/sys/netinet6/ip6_mroute.c#19 integrate .. //depot/projects/vimage/src/sys/netinet6/mld6.c#18 integrate .. //depot/projects/vimage/src/sys/netinet6/nd6.c#35 integrate .. //depot/projects/vimage/src/sys/netinet6/nd6_nbr.c#26 integrate .. //depot/projects/vimage/src/sys/netinet6/nd6_rtr.c#21 integrate .. //depot/projects/vimage/src/sys/netinet6/raw_ip6.c#28 integrate .. //depot/projects/vimage/src/sys/netinet6/scope6.c#19 integrate .. //depot/projects/vimage/src/sys/netinet6/vinet6.h#25 integrate .. //depot/projects/vimage/src/sys/netipsec/ipsec.c#29 integrate .. //depot/projects/vimage/src/sys/netipsec/ipsec.h#11 integrate .. //depot/projects/vimage/src/sys/netipsec/key.c#28 integrate .. //depot/projects/vimage/src/sys/netipsec/keysock.c#18 integrate .. //depot/projects/vimage/src/sys/netipsec/xform_ah.c#20 integrate .. //depot/projects/vimage/src/sys/netipsec/xform_esp.c#19 integrate .. //depot/projects/vimage/src/sys/netipsec/xform_ipcomp.c#16 integrate .. //depot/projects/vimage/src/sys/netipsec/xform_ipip.c#20 integrate .. //depot/projects/vimage/src/sys/sys/vimage.h#70 integrate Differences ... ==== //depot/projects/vimage/src/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#18 (text+ko) ==== @@ -28,7 +28,7 @@ ***************************************************************************/ #include -__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c,v 1.26 2008/11/12 04:45:09 kmacy Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c,v 1.27 2008/11/19 09:39:34 zec Exp $"); #include #include @@ -154,7 +154,6 @@ #define TCP_CLOSE 2 #define TCP_DROP 3 - static void t3_send_reset(struct toepcb *toep); static void send_abort_rpl(struct mbuf *m, struct toedev *tdev, int rst_status); static inline void free_atid(struct t3cdev *cdev, unsigned int tid); ==== //depot/projects/vimage/src/sys/dev/usb/rio500_usb.h#3 (text+ko) ==== @@ -20,7 +20,7 @@ ---------------------------------------------------------------------- */ -/* $FreeBSD: src/sys/dev/usb/rio500_usb.h,v 1.3 2007/06/12 19:01:32 imp Exp $ */ +/* $FreeBSD: src/sys/dev/usb/rio500_usb.h,v 1.4 2008/11/19 08:56:35 alfred Exp $ */ #include #ifndef USB_VENDOR_DIAMOND @@ -32,7 +32,7 @@ struct RioCommand { - u_int16_t length; + uint16_t length; int request; int requesttype; int value; ==== //depot/projects/vimage/src/sys/dev/usb2/bluetooth/ng_ubt2.c#2 (text+ko) ==== @@ -28,7 +28,7 @@ * SUCH DAMAGE. * * $Id: ng_ubt.c,v 1.16 2003/10/10 19:15:06 max Exp $ - * $FreeBSD: src/sys/dev/usb2/bluetooth/ng_ubt2.c,v 1.1 2008/11/04 02:31:03 alfred Exp $ + * $FreeBSD: src/sys/dev/usb2/bluetooth/ng_ubt2.c,v 1.2 2008/11/19 08:56:35 alfred Exp $ */ #include @@ -365,6 +365,7 @@ DRIVER_MODULE(ng_ubt, ushub, ubt_driver, ubt_devclass, ubt_modevent, 0); MODULE_VERSION(ng_ubt, NG_BLUETOOTH_VERSION); MODULE_DEPEND(ng_ubt, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); +MODULE_DEPEND(ng_ubt, ng_hci, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION); MODULE_DEPEND(ng_ubt, usb2_bluetooth, 1, 1, 1); MODULE_DEPEND(ng_ubt, usb2_core, 1, 1, 1); ==== //depot/projects/vimage/src/sys/dev/usb2/controller/ehci2.c#3 (text+ko) ==== @@ -44,7 +44,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/usb2/controller/ehci2.c,v 1.2 2008/11/10 20:54:31 thompsa Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/usb2/controller/ehci2.c,v 1.3 2008/11/19 08:56:35 alfred Exp $"); #include #include @@ -183,6 +183,8 @@ usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1); hcr = EOREAD4(sc, EHCI_USBCMD); if (!(hcr & EHCI_CMD_HCRESET)) { + if (sc->sc_flags & EHCI_SCFLG_SETMODE) + EOWRITE4(sc, 0x68, 0x3); hcr = 0; break; } @@ -3301,7 +3303,16 @@ } v = EOREAD4(sc, EHCI_PORTSC(index)); DPRINTFN(9, "port status=0x%04x\n", v); - i = UPS_HIGH_SPEED; + if (sc->sc_flags & EHCI_SCFLG_FORCESPEED) { + if ((v & 0xc000000) == 0x8000000) + i = UPS_HIGH_SPEED; + else if ((v & 0xc000000) == 0x4000000) + i = UPS_LOW_SPEED; + else + i = 0; + } else { + i = UPS_HIGH_SPEED; + } if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS; if (v & EHCI_PS_PE) @@ -3378,7 +3389,8 @@ } /* Terminate reset sequence. */ - EOWRITE4(sc, port, v); + if (!(sc->sc_flags & EHCI_SCFLG_NORESTERM)) + EOWRITE4(sc, port, v); if (use_polling) { /* polling */ ==== //depot/projects/vimage/src/sys/dev/usb2/controller/ehci2.h#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb2/controller/ehci2.h,v 1.1 2008/11/04 02:31:03 alfred Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/controller/ehci2.h,v 1.2 2008/11/19 08:56:35 alfred Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -468,6 +468,12 @@ uint16_t sc_intr_stat[EHCI_VIRTUAL_FRAMELIST_COUNT]; uint16_t sc_id_vendor; /* vendor ID for root hub */ + uint16_t sc_flags; /* chip specific flags */ +#define EHCI_SCFLG_SETMODE 0x0001 /* set bridge mode again after init + * (Marvell) */ +#define EHCI_SCFLG_FORCESPEED 0x0002 /* force speed (Marvell) */ +#define EHCI_SCFLG_NORESTERM 0x0004 /* don't terminate reset sequence + * (Marvell) */ uint8_t sc_offs; /* offset to operational registers */ uint8_t sc_doorbell_disable; /* set on doorbell failure */ ==== //depot/projects/vimage/src/sys/dev/usb2/core/usb2_busdma.c#3 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb2/core/usb2_busdma.c,v 1.2 2008/11/10 20:54:31 thompsa Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/core/usb2_busdma.c,v 1.3 2008/11/19 08:56:35 alfred Exp $ */ /*- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. * @@ -602,6 +602,12 @@ uptag = pc->tag_parent; /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + + /* * Try to load memory into DMA. */ err = bus_dmamap_load( @@ -617,6 +623,12 @@ } else { /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + + /* * Try to load memory into DMA. The callback * will be called in all cases: */ @@ -644,6 +656,10 @@ void usb2_pc_cpu_invalidate(struct usb2_page_cache *pc) { + if (pc->page_offset_end == pc->page_offset_buf) { + /* nothing has been loaded into this page cache! */ + return; + } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); return; @@ -655,6 +671,10 @@ void usb2_pc_cpu_flush(struct usb2_page_cache *pc) { + if (pc->page_offset_end == pc->page_offset_buf) { + /* nothing has been loaded into this page cache! */ + return; + } bus_dmamap_sync(pc->tag, pc->map, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); return; @@ -958,6 +978,12 @@ if (size > 0) { + /* + * We have to unload the previous loaded DMA + * pages before trying to load a new one! + */ + bus_dmamap_unload(pc->tag, pc->map); + /* try to load memory into DMA using using no wait option */ if (bus_dmamap_load(pc->tag, pc->map, pc->buffer, size, NULL, BUS_DMA_NOWAIT)) { @@ -995,6 +1021,10 @@ len = pc->page_offset_end - pc->page_offset_buf; + if (len == 0) { + /* nothing has been loaded into this page cache */ + return; + } bus_dmamap_sync(pc->tag, pc->map, 0, len, BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); return; @@ -1010,6 +1040,10 @@ len = pc->page_offset_end - pc->page_offset_buf; + if (len == 0) { + /* nothing has been loaded into this page cache */ + return; + } bus_dmamap_sync(pc->tag, pc->map, 0, len, BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); return; @@ -1358,12 +1392,10 @@ while (nframes--) { - if (pc->page_offset_buf != pc->page_offset_end) { - if (pc->isread) { - usb2_pc_cpu_invalidate(pc); - } else { - usb2_pc_cpu_flush(pc); - } + if (pc->isread) { + usb2_pc_cpu_invalidate(pc); + } else { + usb2_pc_cpu_flush(pc); } pc++; } @@ -1394,11 +1426,8 @@ pc = xfer->frbuffers; while (nframes--) { - - if (pc->page_offset_buf != pc->page_offset_end) { - if (pc->isread) { - usb2_pc_cpu_invalidate(pc); - } + if (pc->isread) { + usb2_pc_cpu_invalidate(pc); } pc++; } ==== //depot/projects/vimage/src/sys/dev/usb2/core/usb2_core.h#3 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb2/core/usb2_core.h,v 1.2 2008/11/10 20:54:31 thompsa Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/core/usb2_core.h,v 1.3 2008/11/19 08:56:35 alfred Exp $ */ /*- * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. * @@ -159,12 +159,12 @@ #define usb2_callout_drain(c) callout_drain(&(c)->co) #define usb2_callout_pending(c) callout_pending(&(c)->co) -#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx) -#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx) -#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t) -#define USB_XFER_LOCK(_x) mtx_lock((_x)->xfer_mtx) -#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xfer_mtx) -#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xfer_mtx, _t) +#define USB_BUS_LOCK(_b) mtx_lock(&(_b)->bus_mtx) +#define USB_BUS_UNLOCK(_b) mtx_unlock(&(_b)->bus_mtx) +#define USB_BUS_LOCK_ASSERT(_b, _t) mtx_assert(&(_b)->bus_mtx, _t) +#define USB_XFER_LOCK(_x) mtx_lock((_x)->xfer_mtx) +#define USB_XFER_UNLOCK(_x) mtx_unlock((_x)->xfer_mtx) +#define USB_XFER_LOCK_ASSERT(_x, _t) mtx_assert((_x)->xfer_mtx, _t) /* structure prototypes */ struct file; @@ -401,13 +401,14 @@ struct usb2_fifo *rxfifo; struct usb2_fifo *txfifo; uint32_t devloc; /* original devloc */ - uint16_t bus_index; - uint8_t dev_index; - uint8_t iface_index; - uint8_t ep_index; - uint8_t is_read; - uint8_t is_write; - uint8_t is_uref; + uint16_t bus_index; /* bus index */ + uint8_t dev_index; /* device index */ + uint8_t iface_index; /* interface index */ + uint8_t fifo_index; /* FIFO index */ + uint8_t is_read; /* set if location has read access */ + uint8_t is_write; /* set if location has write access */ + uint8_t is_uref; /* set if USB refcount decr. needed */ + uint8_t is_usbfs; /* set if USB-FS is active */ }; /* external variables */ ==== //depot/projects/vimage/src/sys/dev/usb2/core/usb2_dev.c#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb2/core/usb2_dev.c,v 1.1 2008/11/04 02:31:03 alfred Exp $ */ +/* $FreeBSD: src/sys/dev/usb2/core/usb2_dev.c,v 1.2 2008/11/19 08:56:35 alfred Exp $ */ /*- * Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved. * @@ -464,21 +464,16 @@ struct usb2_fifo **ppf; struct usb2_fifo *f; int fflags; - uint8_t need_uref; + uint8_t dev_ep_index; if (fp) { - /* check if we need uref hint */ - need_uref = devloc ? 0 : 1; + /* check if we need uref */ + ploc->is_uref = devloc ? 0 : 1; /* get devloc - already verified */ devloc = USB_P2U(fp->f_data); /* get file flags */ fflags = fp->f_flag; - /* only ref FIFO */ - ploc->is_uref = 0; - /* devloc should be valid */ } else { - /* we need uref */ - need_uref = 1; /* only ref device */ fflags = 0; /* search for FIFO */ @@ -496,7 +491,7 @@ ploc->dev_index = (devloc / USB_BUS_MAX) % USB_DEV_MAX; ploc->iface_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX)) % USB_IFACE_MAX; - ploc->ep_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX * + ploc->fifo_index = (devloc / (USB_BUS_MAX * USB_DEV_MAX * USB_IFACE_MAX)); mtx_lock(&usb2_ref_lock); @@ -518,18 +513,6 @@ DPRINTFN(2, "no dev ref\n"); goto error; } - ploc->iface = usb2_get_iface(ploc->udev, ploc->iface_index); - if (ploc->ep_index != 0) { - /* non control endpoint - we need an interface */ - if (ploc->iface == NULL) { - DPRINTFN(2, "no iface\n"); - goto error; - } - if (ploc->iface->idesc == NULL) { - DPRINTFN(2, "no idesc\n"); - goto error; - } - } /* check if we are doing an open */ if (fp == NULL) { /* set defaults */ @@ -537,11 +520,18 @@ ploc->rxfifo = NULL; ploc->is_write = 0; ploc->is_read = 0; + ploc->is_usbfs = 0; + /* NOTE: variable overloading: */ + dev_ep_index = ploc->fifo_index; } else { + /* initialise "is_usbfs" flag */ + ploc->is_usbfs = 0; + dev_ep_index = 255; /* dummy */ + /* check for write */ if (fflags & FWRITE) { ppf = ploc->udev->fifo; - f = ppf[ploc->ep_index + USB_FIFO_TX]; + f = ppf[ploc->fifo_index + USB_FIFO_TX]; ploc->txfifo = f; ploc->is_write = 1; /* ref */ if ((f == NULL) || @@ -549,6 +539,15 @@ (f->curr_file != fp)) { goto error; } + /* check if USB-FS is active */ + if (f->fs_ep_max != 0) { + ploc->is_usbfs = 1; + } + /* + * Get real endpoint index associated with + * this FIFO: + */ + dev_ep_index = f->dev_ep_index; } else { ploc->txfifo = NULL; ploc->is_write = 0; /* no ref */ @@ -557,7 +556,7 @@ /* check for read */ if (fflags & FREAD) { ppf = ploc->udev->fifo; - f = ppf[ploc->ep_index + USB_FIFO_RX]; + f = ppf[ploc->fifo_index + USB_FIFO_RX]; ploc->rxfifo = f; ploc->is_read = 1; /* ref */ if ((f == NULL) || @@ -565,37 +564,46 @@ (f->curr_file != fp)) { goto error; } + /* check if USB-FS is active */ + if (f->fs_ep_max != 0) { + ploc->is_usbfs = 1; + } + /* + * Get real endpoint index associated with + * this FIFO: + */ + dev_ep_index = f->dev_ep_index; } else { ploc->rxfifo = NULL; ploc->is_read = 0; /* no ref */ } } + /* check if we require an interface */ + ploc->iface = usb2_get_iface(ploc->udev, ploc->iface_index); + if (dev_ep_index != 0) { + /* non control endpoint - we need an interface */ + if (ploc->iface == NULL) { + DPRINTFN(2, "no iface\n"); + goto error; + } + if (ploc->iface->idesc == NULL) { + DPRINTFN(2, "no idesc\n"); + goto error; + } + } /* when everything is OK we increment the refcounts */ if (ploc->is_write) { DPRINTFN(2, "ref write\n"); ploc->txfifo->refcount++; - if (ploc->txfifo->flag_no_uref == 0) { - /* we need extra locking */ - ploc->is_uref = 1; - } } if (ploc->is_read) { DPRINTFN(2, "ref read\n"); ploc->rxfifo->refcount++; - if (ploc->rxfifo->flag_no_uref == 0) { - /* we need extra locking */ - ploc->is_uref = 1; - } } if (ploc->is_uref) { - if (need_uref) { - DPRINTFN(2, "ref udev - needed\n"); - ploc->udev->refcount++; - } else { - DPRINTFN(2, "ref udev - not needed\n"); - ploc->is_uref = 0; - } + DPRINTFN(2, "ref udev - needed\n"); + ploc->udev->refcount++; } mtx_unlock(&usb2_ref_lock); @@ -616,6 +624,59 @@ } /*------------------------------------------------------------------------* + * usb2_uref_location + * + * This function is used to upgrade an USB reference to include the + * USB device reference on a USB location. + * + * Return values: + * 0: Success, refcount incremented on the given USB device. + * Else: Failure. + *------------------------------------------------------------------------*/ +static usb2_error_t +usb2_uref_location(struct usb2_location *ploc) +{ + /* + * Check if we already got an USB reference on this location: + */ + if (ploc->is_uref) { + return (0); /* success */ + } + mtx_lock(&usb2_ref_lock); + if (ploc->bus != devclass_get_softc(usb2_devclass_ptr, ploc->bus_index)) { + DPRINTFN(2, "bus changed at %u\n", ploc->bus_index); + goto error; + } + if (ploc->udev != ploc->bus->devices[ploc->dev_index]) { + DPRINTFN(2, "device changed at %u\n", ploc->dev_index); + goto error; + } + if (ploc->udev->refcount == USB_DEV_REF_MAX) { + DPRINTFN(2, "no dev ref\n"); + goto error; + } + DPRINTFN(2, "ref udev\n"); + ploc->udev->refcount++; + mtx_unlock(&usb2_ref_lock); + + /* set "uref" */ + ploc->is_uref = 1; + + /* + * We are about to alter the bus-state. Apply the + * required locks. + */ + sx_xlock(ploc->udev->default_sx + 1); + mtx_lock(&Giant); /* XXX */ + return (0); + +error: + mtx_unlock(&usb2_ref_lock); + DPRINTFN(2, "fail\n"); + return (USB_ERR_INVAL); +} + +/*------------------------------------------------------------------------* * usb2_unref_device * * This function will release the reference count by one unit for the @@ -672,7 +733,9 @@ struct usb2_fifo *f; struct usb2_pipe *pipe; uint8_t iface_index = ploc->iface_index; - uint8_t dev_ep_index = ploc->ep_index; + + /* NOTE: variable overloading: */ + uint8_t dev_ep_index = ploc->fifo_index; uint8_t n; uint8_t is_tx; uint8_t is_rx; @@ -770,9 +833,6 @@ f->methods = &usb2_ugen_methods; f->iface_index = iface_index; f->udev = udev; - if (dev_ep_index != 0) { - f->flag_no_uref = 1; - } mtx_lock(&usb2_ref_lock); udev->fifo[n + USB_FIFO_TX] = f; mtx_unlock(&usb2_ref_lock); @@ -798,9 +858,6 @@ f->methods = &usb2_ugen_methods; f->iface_index = iface_index; f->udev = udev; - if (dev_ep_index != 0) { - f->flag_no_uref = 1; - } mtx_lock(&usb2_ref_lock); udev->fifo[n + USB_FIFO_RX] = f; mtx_unlock(&usb2_ref_lock); @@ -1113,15 +1170,23 @@ struct usb2_interface *iface; int err; - iface = usb2_get_iface(udev, iface_index); - if (iface == NULL) { - return (EINVAL); + if (ep_index != 0) { + /* + * Non-control endpoints are always + * associated with an interface: + */ + iface = usb2_get_iface(udev, iface_index); + if (iface == NULL) { + return (EINVAL); + } + if (iface->idesc == NULL) { + return (EINVAL); + } + } else { + iface = NULL; } - if (iface->idesc == NULL) { - return (EINVAL); - } /* scan down the permissions tree */ - if ((ep_index != 0) && iface && + if ((iface != NULL) && (usb2_check_access(fflags, &iface->perm) == 0)) { /* we got access through the interface */ err = 0; @@ -1198,8 +1263,14 @@ DPRINTFN(2, "cannot ref device\n"); return (ENXIO); } + /* + * NOTE: Variable overloading. "usb2_fifo_create" will update + * the FIFO index. Right here we can assume that the + * "fifo_index" is the same like the endpoint number without + * direction mask, if the "fifo_index" is less than 16. + */ err = usb2_check_thread_perm(loc.udev, td, fflags, - loc.iface_index, loc.ep_index); + loc.iface_index, loc.fifo_index); /* check for error */ if (err) { @@ -1447,7 +1518,7 @@ DPRINTFN(2, "fflags=%u\n", fflags); - err = usb2_ref_device(fp, &loc, 0);; + err = usb2_ref_device(fp, &loc, 0 /* need uref */ );; /* restore some file variables */ fp->f_ops = usb2_old_f_ops; @@ -1512,7 +1583,7 @@ } break; default: - return (ENOTTY); + return (ENOIOCTL); } return (error); } @@ -1522,13 +1593,11 @@ struct ucred *cred, struct thread *td) { struct usb2_location loc; + struct usb2_fifo *f; int fflags; - int err_rx; - int err_tx; int err; - uint8_t is_common = 0; - err = usb2_ref_device(fp, &loc, 0);; + err = usb2_ref_device(fp, &loc, 1 /* no uref */ );; if (err) { return (ENXIO); } @@ -1536,43 +1605,31 @@ DPRINTFN(2, "fflags=%u, cmd=0x%lx\n", fflags, cmd); + f = NULL; /* set default value */ + err = ENOIOCTL; /* set default value */ + + if (fflags & FWRITE) { + f = loc.txfifo; + err = usb2_ioctl_f_sub(f, cmd, addr, td); + } if (fflags & FREAD) { - if (fflags & FWRITE) { - /* - * Make sure that the IOCTL is not - * duplicated: - */ - is_common = 1; - } - err_rx = usb2_ioctl_f_sub(loc.rxfifo, cmd, addr, td); - if (err_rx == ENOTTY) { - err_rx = (loc.rxfifo->methods->f_ioctl) ( - loc.rxfifo, cmd, addr, - is_common ? fflags : (fflags & ~FWRITE), td); - } - } else { - err_rx = 0; + f = loc.rxfifo; + err = usb2_ioctl_f_sub(f, cmd, addr, td); } - if (fflags & FWRITE) { - err_tx = usb2_ioctl_f_sub(loc.txfifo, cmd, addr, td); - if (err_tx == ENOTTY) { - if (is_common) - err_tx = 0; /* already handled this IOCTL */ - else - err_tx = (loc.txfifo->methods->f_ioctl) ( - loc.txfifo, cmd, addr, fflags & ~FREAD, td); + if (err == ENOIOCTL) { + err = (f->methods->f_ioctl) (f, cmd, addr, fflags, td); + if (err == ENOIOCTL) { + if (usb2_uref_location(&loc)) { + err = ENXIO; + goto done; + } + err = (f->methods->f_ioctl_post) (f, cmd, addr, fflags, td); } - } else { - err_tx = 0; } - - if (err_rx) { - err = err_rx; - } else if (err_tx) { - err = err_tx; - } else { - err = 0; /* no error */ + if (err == ENOIOCTL) { + err = ENOTTY; } +done: usb2_unref_device(&loc); return (err); } @@ -1594,7 +1651,6 @@ struct usb2_mbuf *m; int fflags; int revents; - uint8_t usbfs_active = 0; revents = usb2_ref_device(fp, &loc, 1 /* no uref */ );; if (revents) { @@ -1602,20 +1658,6 @@ } fflags = fp->f_flag; - /* figure out if the USB File System is active */ - - if (fflags & FWRITE) { - f = loc.txfifo; - if (f->fs_ep_max != 0) { - usbfs_active = 1; - } - } - if (fflags & FREAD) { - f = loc.rxfifo; - if (f->fs_ep_max != 0) { - usbfs_active = 1; - } - } /* Figure out who needs service */ if ((events & (POLLOUT | POLLWRNORM)) && @@ -1625,7 +1667,7 @@ mtx_lock(f->priv_mtx); - if (!usbfs_active) { + if (!loc.is_usbfs) { if (f->flag_iserror) { /* we got an error */ m = (void *)1; @@ -1664,7 +1706,7 @@ mtx_lock(f->priv_mtx); - if (!usbfs_active) { + if (!loc.is_usbfs) { if (f->flag_iserror) { /* we have and error */ m = (void *)1; @@ -1693,8 +1735,10 @@ f->flag_isselect = 1; selrecord(td, &f->selinfo); - /* start reading data */ - (f->methods->f_start_read) (f); + if (!loc.is_usbfs) { + /* start reading data */ + (f->methods->f_start_read) (f); + } } mtx_unlock(f->priv_mtx); @@ -1739,22 +1783,23 @@ mtx_lock(f->priv_mtx); + /* check for permanent read error */ if (f->flag_iserror) { err = EIO; goto done; } + /* check if USB-FS interface is active */ + if (loc.is_usbfs) { + /* + * The queue is used for events that should be + * retrieved using the "USB_FS_COMPLETE" ioctl. + */ + err = EINVAL; + goto done; + } while (uio->uio_resid > 0) { - if (f->fs_ep_max == 0) { - USB_IF_DEQUEUE(&f->used_q, m); - } else { - /* - * The queue is used for events that should be - * retrieved using the "USB_FS_COMPLETE" - * ioctl. - */ - m = NULL; - } + USB_IF_DEQUEUE(&f->used_q, m); if (m == NULL) { @@ -1777,9 +1822,16 @@ break; } continue; - } else { - tr_data = 1; + } + if (f->methods->f_filter_read) { + /* + * Sometimes it is convenient to process data at the + * expense of a userland process instead of a kernel + * process. + */ + (f->methods->f_filter_read) (f, m); } + tr_data = 1; io_len = MIN(m->cur_data_len, uio->uio_resid); @@ -1876,26 +1928,27 @@ mtx_lock(f->priv_mtx); + /* check for permanent write error */ if (f->flag_iserror) { err = EIO; goto done; } - if ((f->queue_data == NULL) && (f->fs_ep_max == 0)) { + /* check if USB-FS interface is active */ + if (loc.is_usbfs) { + /* + * The queue is used for events that should be + * retrieved using the "USB_FS_COMPLETE" ioctl. + */ + err = EINVAL; + goto done; + } + if (f->queue_data == NULL) { /* start write transfer, if not already started */ (f->methods->f_start_write) (f); } /* we allow writing zero length data */ do { - if (f->fs_ep_max == 0) { - USB_IF_DEQUEUE(&f->free_q, m); - } else { - /* - * The queue is used for events that should be - * retrieved using the "USB_FS_COMPLETE" - * ioctl. - */ - m = NULL; - } + USB_IF_DEQUEUE(&f->free_q, m); if (m == NULL) { @@ -1914,9 +1967,8 @@ break; } continue; - } else { - tr_data = 1; } + tr_data = 1; USB_MBUF_RESET(m); @@ -1933,10 +1985,19 @@ if (err) { USB_IF_ENQUEUE(&f->free_q, m); break; - } else { - USB_IF_ENQUEUE(&f->used_q, m); - (f->methods->f_start_write) (f); + } + if (f->methods->f_filter_write) { + /* + * 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); + + (f->methods->f_start_write) (f); + } while (uio->uio_resid > 0); done: mtx_unlock(f->priv_mtx); @@ -2066,7 +2127,7 @@ usb2_fifo_dummy_ioctl(struct usb2_fifo *fifo, u_long cmd, void *addr, int fflags, struct thread *td) { - return (ENOTTY); + return (ENOIOCTL); } >>> TRUNCATED FOR MAIL (1000 lines) <<<