PERFORCE change 153209 for review

Marko Zec zec at FreeBSD.org
Wed Nov 19 03:31:01 PST 2008


http://perforce.freebsd.org/chv.cgi?CH=153209

Change 153209 by zec at 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 <sys/cdefs.h>
-__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 <sys/param.h>
 #include <sys/systm.h>
@@ -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 <sys/ioccom.h>
 #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 <dev/usb2/include/usb2_devid.h>
@@ -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 <sys/cdefs.h>
-__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 <dev/usb2/include/usb2_standard.h>
 #include <dev/usb2/include/usb2_mfunc.h>
@@ -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) <<<


More information about the p4-projects mailing list