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