diff options
Diffstat (limited to 'sys/dev')
41 files changed, 515 insertions, 283 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index c0f17f6..500a072 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -1673,38 +1673,36 @@ acpi_probe_child(ACPI_HANDLE handle, UINT32 level, void *context, void **status) ACPI_OBJECT_TYPE type; ACPI_HANDLE h; device_t bus, child; + char *handle_str; int order; - char *handle_str, **search; - static char *scopes[] = {"\\_PR_", "\\_TZ_", "\\_SI_", "\\_SB_", NULL}; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); + if (acpi_disabled("children")) + return_ACPI_STATUS (AE_OK); + /* Skip this device if we think we'll have trouble with it. */ if (acpi_avoid(handle)) return_ACPI_STATUS (AE_OK); bus = (device_t)context; if (ACPI_SUCCESS(AcpiGetType(handle, &type))) { + handle_str = acpi_name(handle); switch (type) { case ACPI_TYPE_DEVICE: - case ACPI_TYPE_PROCESSOR: - case ACPI_TYPE_THERMAL: - case ACPI_TYPE_POWER: - if (acpi_disabled("children")) - break; - /* * Since we scan from \, be sure to skip system scope objects. - * At least \_SB and \_TZ are detected as devices (ACPI-CA bug?) + * \_SB_ and \_TZ_ are defined in ACPICA as devices to work around + * BIOS bugs. For example, \_SB_ is to allow \_SB._INI to be run + * during the intialization and \_TZ_ is to support Notify() on it. */ - handle_str = acpi_name(handle); - for (search = scopes; *search != NULL; search++) { - if (strcmp(handle_str, *search) == 0) - break; - } - if (*search != NULL) + if (strcmp(handle_str, "\\_SB_") == 0 || + strcmp(handle_str, "\\_TZ_") == 0) break; - + /* FALLTHROUGH */ + case ACPI_TYPE_PROCESSOR: + case ACPI_TYPE_THERMAL: + case ACPI_TYPE_POWER: /* * Create a placeholder device for this node. Sort the * placeholder so that the probe/attach passes will run diff --git a/sys/dev/acpica/acpi_pci_link.c b/sys/dev/acpica/acpi_pci_link.c index dcf101d..d5d2d82 100644 --- a/sys/dev/acpica/acpi_pci_link.c +++ b/sys/dev/acpica/acpi_pci_link.c @@ -268,6 +268,7 @@ link_add_crs(ACPI_RESOURCE *res, void *context) static ACPI_STATUS link_add_prs(ACPI_RESOURCE *res, void *context) { + ACPI_RESOURCE *tmp; struct link_res_request *req; struct link *link; UINT8 *irqs = NULL; @@ -321,12 +322,23 @@ link_add_prs(ACPI_RESOURCE *res, void *context) * Stash a copy of the resource for later use when doing * _SRS. */ - bcopy(res, &link->l_prs_template, sizeof(ACPI_RESOURCE)); + tmp = &link->l_prs_template; if (is_ext_irq) { + bcopy(res, tmp, ACPI_RS_SIZE(tmp->Data.ExtendedIrq)); + + /* + * XXX acpi_AppendBufferResource() cannot handle + * optional data. + */ + bzero(&tmp->Data.ExtendedIrq.ResourceSource, + sizeof(tmp->Data.ExtendedIrq.ResourceSource)); + tmp->Length = ACPI_RS_SIZE(tmp->Data.ExtendedIrq); + link->l_num_irqs = res->Data.ExtendedIrq.InterruptCount; ext_irqs = res->Data.ExtendedIrq.Interrupts; } else { + bcopy(res, tmp, ACPI_RS_SIZE(tmp->Data.Irq)); link->l_num_irqs = res->Data.Irq.InterruptCount; irqs = res->Data.Irq.Interrupts; } @@ -688,18 +700,17 @@ acpi_pci_link_add_reference(device_t dev, int index, device_t pcib, int slot, static ACPI_STATUS acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf) { - ACPI_RESOURCE *resource, *end, newres, *resptr; - ACPI_BUFFER crsbuf; + ACPI_RESOURCE *end, *res; ACPI_STATUS status; struct link *link; int i, in_dpf; /* Fetch the _CRS. */ ACPI_SERIAL_ASSERT(pci_link); - crsbuf.Pointer = NULL; - crsbuf.Length = ACPI_ALLOCATE_BUFFER; - status = AcpiGetCurrentResources(acpi_get_handle(sc->pl_dev), &crsbuf); - if (ACPI_SUCCESS(status) && crsbuf.Pointer == NULL) + srsbuf->Pointer = NULL; + srsbuf->Length = ACPI_ALLOCATE_BUFFER; + status = AcpiGetCurrentResources(acpi_get_handle(sc->pl_dev), srsbuf); + if (ACPI_SUCCESS(status) && srsbuf->Pointer == NULL) status = AE_NO_MEMORY; if (ACPI_FAILURE(status)) { if (bootverbose) @@ -710,14 +721,13 @@ acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf) } /* Fill in IRQ resources via link structures. */ - srsbuf->Pointer = NULL; link = sc->pl_links; i = 0; in_dpf = DPF_OUTSIDE; - resource = (ACPI_RESOURCE *)crsbuf.Pointer; - end = (ACPI_RESOURCE *)((char *)crsbuf.Pointer + crsbuf.Length); + res = (ACPI_RESOURCE *)srsbuf->Pointer; + end = (ACPI_RESOURCE *)((char *)srsbuf->Pointer + srsbuf->Length); for (;;) { - switch (resource->Type) { + switch (res->Type) { case ACPI_RESOURCE_TYPE_START_DEPENDENT: switch (in_dpf) { case DPF_OUTSIDE: @@ -731,67 +741,44 @@ acpi_pci_link_srs_from_crs(struct acpi_pci_link_softc *sc, ACPI_BUFFER *srsbuf) __func__); break; } - resptr = NULL; break; case ACPI_RESOURCE_TYPE_END_DEPENDENT: /* We are finished with DPF parsing. */ KASSERT(in_dpf != DPF_OUTSIDE, ("%s: end dpf when not parsing a dpf", __func__)); in_dpf = DPF_OUTSIDE; - resptr = NULL; break; case ACPI_RESOURCE_TYPE_IRQ: MPASS(i < sc->pl_num_links); - MPASS(link->l_prs_template.Type == ACPI_RESOURCE_TYPE_IRQ); - newres = link->l_prs_template; - resptr = &newres; - resptr->Data.Irq.InterruptCount = 1; + res->Data.Irq.InterruptCount = 1; if (PCI_INTERRUPT_VALID(link->l_irq)) { KASSERT(link->l_irq < NUM_ISA_INTERRUPTS, ("%s: can't put non-ISA IRQ %d in legacy IRQ resource type", __func__, link->l_irq)); - resptr->Data.Irq.Interrupts[0] = link->l_irq; + res->Data.Irq.Interrupts[0] = link->l_irq; } else - resptr->Data.Irq.Interrupts[0] = 0; + res->Data.Irq.Interrupts[0] = 0; link++; i++; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: MPASS(i < sc->pl_num_links); - MPASS(link->l_prs_template.Type == ACPI_RESOURCE_TYPE_EXTENDED_IRQ); - newres = link->l_prs_template; - resptr = &newres; - resptr->Data.ExtendedIrq.InterruptCount = 1; + res->Data.ExtendedIrq.InterruptCount = 1; if (PCI_INTERRUPT_VALID(link->l_irq)) - resptr->Data.ExtendedIrq.Interrupts[0] = + res->Data.ExtendedIrq.Interrupts[0] = link->l_irq; else - resptr->Data.ExtendedIrq.Interrupts[0] = 0; + res->Data.ExtendedIrq.Interrupts[0] = 0; link++; i++; break; - default: - resptr = resource; - } - if (resptr != NULL) { - status = acpi_AppendBufferResource(srsbuf, resptr); - if (ACPI_FAILURE(status)) { - device_printf(sc->pl_dev, - "Unable to build resources: %s\n", - AcpiFormatException(status)); - if (srsbuf->Pointer != NULL) - AcpiOsFree(srsbuf->Pointer); - AcpiOsFree(crsbuf.Pointer); - return (status); - } } - if (resource->Type == ACPI_RESOURCE_TYPE_END_TAG) + if (res->Type == ACPI_RESOURCE_TYPE_END_TAG) break; - resource = ACPI_NEXT_RESOURCE(resource); - if (resource >= end) + res = ACPI_NEXT_RESOURCE(res); + if (res >= end) break; } - AcpiOsFree(crsbuf.Pointer); return (AE_OK); } @@ -811,10 +798,11 @@ acpi_pci_link_srs_from_links(struct acpi_pci_link_softc *sc, /* Add a new IRQ resource from each link. */ link = &sc->pl_links[i]; - newres = link->l_prs_template; - if (newres.Type == ACPI_RESOURCE_TYPE_IRQ) { + if (link->l_prs_template.Type == ACPI_RESOURCE_TYPE_IRQ) { /* Build an IRQ resource. */ + bcopy(&link->l_prs_template, &newres, + ACPI_RS_SIZE(newres.Data.Irq)); newres.Data.Irq.InterruptCount = 1; if (PCI_INTERRUPT_VALID(link->l_irq)) { KASSERT(link->l_irq < NUM_ISA_INTERRUPTS, @@ -826,6 +814,8 @@ acpi_pci_link_srs_from_links(struct acpi_pci_link_softc *sc, } else { /* Build an ExtIRQ resuorce. */ + bcopy(&link->l_prs_template, &newres, + ACPI_RS_SIZE(newres.Data.ExtendedIrq)); newres.Data.ExtendedIrq.InterruptCount = 1; if (PCI_INTERRUPT_VALID(link->l_irq)) newres.Data.ExtendedIrq.Interrupts[0] = diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c index 288fd17..3ef31cf 100644 --- a/sys/dev/ata/ata-lowlevel.c +++ b/sys/dev/ata/ata-lowlevel.c @@ -833,12 +833,18 @@ ata_pio_read(struct ata_request *request, int length) struct ata_channel *ch = device_get_softc(request->parent); int size = min(request->transfersize, length); int resid; + uint8_t buf[2]; - if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) + if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) { ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int16_t)); - else + if (size & 1) { + ATA_IDX_INSW_STRM(ch, ATA_DATA, (void*)buf, 1); + ((uint8_t *)request->data + request->donecount + + (size & ~1))[0] = buf[0]; + } + } else ATA_IDX_INSL_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int32_t)); @@ -846,7 +852,7 @@ ata_pio_read(struct ata_request *request, int length) if (request->transfersize < length) { device_printf(request->parent, "WARNING - %s read data overrun %d>%d\n", ata_cmd2str(request), length, request->transfersize); - for (resid = request->transfersize; resid < length; + for (resid = request->transfersize + (size & 1); resid < length; resid += sizeof(int16_t)) ATA_IDX_INW(ch, ATA_DATA); } @@ -858,12 +864,18 @@ ata_pio_write(struct ata_request *request, int length) struct ata_channel *ch = device_get_softc(request->parent); int size = min(request->transfersize, length); int resid; + uint8_t buf[2]; - if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) + if (ch->flags & ATA_USE_16BIT || (size % sizeof(int32_t))) { ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int16_t)); - else + if (size & 1) { + buf[0] = ((uint8_t *)request->data + request->donecount + + (size & ~1))[0]; + ATA_IDX_OUTSW_STRM(ch, ATA_DATA, (void*)buf, 1); + } + } else ATA_IDX_OUTSL_STRM(ch, ATA_DATA, (void*)((uintptr_t)request->data+request->donecount), size / sizeof(int32_t)); @@ -871,7 +883,7 @@ ata_pio_write(struct ata_request *request, int length) if (request->transfersize < length) { device_printf(request->parent, "WARNING - %s write data underrun %d>%d\n", ata_cmd2str(request), length, request->transfersize); - for (resid = request->transfersize; resid < length; + for (resid = request->transfersize + (size & 1); resid < length; resid += sizeof(int16_t)) ATA_IDX_OUTW(ch, ATA_DATA, 0); } diff --git a/sys/dev/ata/chipsets/ata-intel.c b/sys/dev/ata/chipsets/ata-intel.c index ba602aa..22cb23b 100644 --- a/sys/dev/ata/chipsets/ata-intel.c +++ b/sys/dev/ata/chipsets/ata-intel.c @@ -315,7 +315,6 @@ ata_intel_ch_attach(device_t dev) map &= 0x03; if (map == 0x00) { ch->flags |= ATA_SATA; - smap[ch->unit] = (ch->unit == 0) ? 0x20 : 0x31; smap[0] = (ch->unit == 0) ? 0 : 1; smap[1] = (ch->unit == 0) ? 2 : 3; } else if (map == 0x02 && ch->unit == 0) { diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c index 48eec98..5501c13 100644 --- a/sys/dev/bwi/if_bwi.c +++ b/sys/dev/bwi/if_bwi.c @@ -511,8 +511,7 @@ bwi_attach(struct bwi_softc *sc) IEEE80211_C_SHPREAMBLE | IEEE80211_C_WPA | IEEE80211_C_BGSCAN | - IEEE80211_C_MONITOR | - IEEE80211_C_RATECTL; + IEEE80211_C_MONITOR; ic->ic_opmode = IEEE80211_M_STA; ieee80211_ifattach(ic, macaddr); diff --git a/sys/dev/bwn/if_bwn.c b/sys/dev/bwn/if_bwn.c index 8e3c8b9..587b734 100644 --- a/sys/dev/bwn/if_bwn.c +++ b/sys/dev/bwn/if_bwn.c @@ -1070,7 +1070,6 @@ bwn_attach_post(struct bwn_softc *sc) | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ | IEEE80211_C_BGSCAN /* capable of bg scanning */ | IEEE80211_C_TXPMGT /* capable of txpow mgt */ - | IEEE80211_C_RATECTL /* use ratectl */ ; ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; /* s/w bmiss */ diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index e5fa6d6..1d58ef8 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -584,7 +584,6 @@ iwn_attach(device_t dev) | IEEE80211_C_IBSS /* ibss/adhoc mode */ #endif | IEEE80211_C_WME /* WME */ - | IEEE80211_C_RATECTL /* use ratectl */ ; #if 0 /* HT */ /* XXX disable until HT channel setup works */ diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index cdf7bad..a339807 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -291,7 +291,6 @@ rt2560_attach(device_t dev, int id) #ifdef notyet | IEEE80211_C_TXFRAG /* handle tx frags */ #endif - | IEEE80211_C_RATECTL /* use ratectl */ ; bands = 0; diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index 04729be..9b77c23 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -294,7 +294,6 @@ rt2661_attach(device_t dev, int id) | IEEE80211_C_TXFRAG /* handle tx frags */ | IEEE80211_C_WME /* 802.11e */ #endif - | IEEE80211_C_RATECTL /* use ratectl */ ; bands = 0; diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 8fd20b6..95983af 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -123,6 +123,7 @@ __FBSDID("$FreeBSD$"); #include <sys/socket.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/sysctl.h> #include <sys/taskqueue.h> #include <net/if.h> @@ -281,6 +282,9 @@ static void re_clrwol (struct rl_softc *); static int re_diag (struct rl_softc *); #endif +static void re_add_sysctls (struct rl_softc *); +static int re_sysctl_stats (SYSCTL_HANDLER_ARGS); + static device_method_t re_methods[] = { /* Device interface */ DEVMETHOD(device_probe, re_probe), @@ -880,7 +884,7 @@ re_probe(device_t dev) uint16_t devid, vendor; uint16_t revid, sdevid; int i; - + vendor = pci_get_vendor(dev); devid = pci_get_device(dev); revid = pci_get_revid(dev); @@ -934,6 +938,7 @@ re_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) static int re_allocmem(device_t dev, struct rl_softc *sc) { + bus_addr_t lowaddr; bus_size_t rx_list_size, tx_list_size; int error; int i; @@ -947,10 +952,13 @@ re_allocmem(device_t dev, struct rl_softc *sc) * register should be set. However some RealTek chips are known * to be buggy on DAC handling, therefore disable DAC by limiting * DMA address space to 32bit. PCIe variants of RealTek chips - * may not have the limitation but I took safer path. + * may not have the limitation. */ + lowaddr = BUS_SPACE_MAXADDR; + if ((sc->rl_flags & RL_FLAG_PCIE) == 0) + lowaddr = BUS_SPACE_MAXADDR_32BIT; error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + lowaddr, BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->rl_parent_tag); if (error) { @@ -1080,6 +1088,35 @@ re_allocmem(device_t dev, struct rl_softc *sc) } } + /* Create DMA map for statistics. */ + error = bus_dma_tag_create(sc->rl_parent_tag, RL_DUMP_ALIGN, 0, + BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL, + sizeof(struct rl_stats), 1, sizeof(struct rl_stats), 0, NULL, NULL, + &sc->rl_ldata.rl_stag); + if (error) { + device_printf(dev, "could not create statistics DMA tag\n"); + return (error); + } + /* Allocate DMA'able memory for statistics. */ + error = bus_dmamem_alloc(sc->rl_ldata.rl_stag, + (void **)&sc->rl_ldata.rl_stats, + BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, + &sc->rl_ldata.rl_smap); + if (error) { + device_printf(dev, + "could not allocate statistics DMA memory\n"); + return (error); + } + /* Load the map for statistics. */ + sc->rl_ldata.rl_stats_addr = 0; + error = bus_dmamap_load(sc->rl_ldata.rl_stag, sc->rl_ldata.rl_smap, + sc->rl_ldata.rl_stats, sizeof(struct rl_stats), re_dma_map_addr, + &sc->rl_ldata.rl_stats_addr, BUS_DMA_NOWAIT); + if (error != 0 || sc->rl_ldata.rl_stats_addr == 0) { + device_printf(dev, "could not load statistics DMA memory\n"); + return (ENOMEM); + } + return (0); } @@ -1117,7 +1154,7 @@ re_attach(device_t dev) /* * Prefer memory space register mapping over IO space. * Because RTL8169SC does not seem to work when memory mapping - * is used always activate io mapping. + * is used always activate io mapping. */ if (devid == RT_DEVICEID_8169SC) prefer_iomap = 1; @@ -1370,6 +1407,7 @@ re_attach(device_t dev) error = re_allocmem(dev, sc); if (error) goto fail; + re_add_sysctls(sc); ifp = sc->rl_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { @@ -1599,22 +1637,26 @@ re_detach(device_t dev) /* Unload and free the RX DMA ring memory and map */ if (sc->rl_ldata.rl_rx_list_tag) { - bus_dmamap_unload(sc->rl_ldata.rl_rx_list_tag, - sc->rl_ldata.rl_rx_list_map); - bus_dmamem_free(sc->rl_ldata.rl_rx_list_tag, - sc->rl_ldata.rl_rx_list, - sc->rl_ldata.rl_rx_list_map); + if (sc->rl_ldata.rl_rx_list_map) + bus_dmamap_unload(sc->rl_ldata.rl_rx_list_tag, + sc->rl_ldata.rl_rx_list_map); + if (sc->rl_ldata.rl_rx_list_map && sc->rl_ldata.rl_rx_list) + bus_dmamem_free(sc->rl_ldata.rl_rx_list_tag, + sc->rl_ldata.rl_rx_list, + sc->rl_ldata.rl_rx_list_map); bus_dma_tag_destroy(sc->rl_ldata.rl_rx_list_tag); } /* Unload and free the TX DMA ring memory and map */ if (sc->rl_ldata.rl_tx_list_tag) { - bus_dmamap_unload(sc->rl_ldata.rl_tx_list_tag, - sc->rl_ldata.rl_tx_list_map); - bus_dmamem_free(sc->rl_ldata.rl_tx_list_tag, - sc->rl_ldata.rl_tx_list, - sc->rl_ldata.rl_tx_list_map); + if (sc->rl_ldata.rl_tx_list_map) + bus_dmamap_unload(sc->rl_ldata.rl_tx_list_tag, + sc->rl_ldata.rl_tx_list_map); + if (sc->rl_ldata.rl_tx_list_map && sc->rl_ldata.rl_tx_list) + bus_dmamem_free(sc->rl_ldata.rl_tx_list_tag, + sc->rl_ldata.rl_tx_list, + sc->rl_ldata.rl_tx_list_map); bus_dma_tag_destroy(sc->rl_ldata.rl_tx_list_tag); } @@ -1639,11 +1681,12 @@ re_detach(device_t dev) /* Unload and free the stats buffer and map */ if (sc->rl_ldata.rl_stag) { - bus_dmamap_unload(sc->rl_ldata.rl_stag, - sc->rl_ldata.rl_rx_list_map); - bus_dmamem_free(sc->rl_ldata.rl_stag, - sc->rl_ldata.rl_stats, - sc->rl_ldata.rl_smap); + if (sc->rl_ldata.rl_smap) + bus_dmamap_unload(sc->rl_ldata.rl_stag, + sc->rl_ldata.rl_smap); + if (sc->rl_ldata.rl_smap && sc->rl_ldata.rl_stats) + bus_dmamem_free(sc->rl_ldata.rl_stag, + sc->rl_ldata.rl_stats, sc->rl_ldata.rl_smap); bus_dma_tag_destroy(sc->rl_ldata.rl_stag); } @@ -2016,9 +2059,9 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp) if (rx_npktsp != NULL) *rx_npktsp = rx_npkts; if (maxpkt) - return(EAGAIN); + return (EAGAIN); - return(0); + return (0); } static void @@ -2107,7 +2150,7 @@ re_tick(void *xsc) * Reclaim transmitted frames here. Technically it is not * necessary to do here but it ensures periodic reclamation * regardless of Tx completion interrupt which seems to be - * lost on PCIe based controllers under certain situations. + * lost on PCIe based controllers under certain situations. */ re_txeof(sc); re_watchdog(sc); @@ -2835,7 +2878,7 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data) if (ifr->ifr_reqcap & IFCAP_POLLING) { error = ether_poll_register(re_poll, ifp); if (error) - return(error); + return (error); RL_LOCK(sc); /* Disable interrupts */ CSR_WRITE_2(sc, RL_IMR, 0x0000); @@ -3181,3 +3224,88 @@ re_clrwol(struct rl_softc *sc) v &= ~RL_CFG5_WOL_LANWAKE; CSR_WRITE_1(sc, RL_CFG5, v); } + +static void +re_add_sysctls(struct rl_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *children; + + ctx = device_get_sysctl_ctx(sc->rl_dev); + children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->rl_dev)); + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "stats", + CTLTYPE_INT | CTLFLAG_RW, sc, 0, re_sysctl_stats, "I", + "Statistics Information"); +} + +static int +re_sysctl_stats(SYSCTL_HANDLER_ARGS) +{ + struct rl_softc *sc; + struct rl_stats *stats; + int error, i, result; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + if (error || req->newptr == NULL) + return (error); + + if (result == 1) { + sc = (struct rl_softc *)arg1; + RL_LOCK(sc); + bus_dmamap_sync(sc->rl_ldata.rl_stag, + sc->rl_ldata.rl_smap, BUS_DMASYNC_PREREAD); + CSR_WRITE_4(sc, RL_DUMPSTATS_HI, + RL_ADDR_HI(sc->rl_ldata.rl_stats_addr)); + CSR_WRITE_4(sc, RL_DUMPSTATS_LO, + RL_ADDR_LO(sc->rl_ldata.rl_stats_addr)); + CSR_WRITE_4(sc, RL_DUMPSTATS_LO, + RL_ADDR_LO(sc->rl_ldata.rl_stats_addr | + RL_DUMPSTATS_START)); + for (i = RL_TIMEOUT; i > 0; i--) { + if ((CSR_READ_4(sc, RL_DUMPSTATS_LO) & + RL_DUMPSTATS_START) == 0) + break; + DELAY(1000); + } + bus_dmamap_sync(sc->rl_ldata.rl_stag, + sc->rl_ldata.rl_smap, BUS_DMASYNC_POSTREAD); + RL_UNLOCK(sc); + if (i == 0) { + device_printf(sc->rl_dev, + "DUMP statistics request timedout\n"); + return (ETIMEDOUT); + } + stats = sc->rl_ldata.rl_stats; + printf("%s statistics:\n", device_get_nameunit(sc->rl_dev)); + printf("Tx frames : %ju\n", + (uintmax_t)le64toh(stats->rl_tx_pkts)); + printf("Rx frames : %ju\n", + (uintmax_t)le64toh(stats->rl_rx_pkts)); + printf("Tx errors : %ju\n", + (uintmax_t)le64toh(stats->rl_tx_errs)); + printf("Rx errors : %u\n", + le32toh(stats->rl_rx_errs)); + printf("Rx missed frames : %u\n", + (uint32_t)le16toh(stats->rl_missed_pkts)); + printf("Rx frame alignment errs : %u\n", + (uint32_t)le16toh(stats->rl_rx_framealign_errs)); + printf("Tx single collisions : %u\n", + le32toh(stats->rl_tx_onecoll)); + printf("Tx multiple collisions : %u\n", + le32toh(stats->rl_tx_multicolls)); + printf("Rx unicast frames : %ju\n", + (uintmax_t)le64toh(stats->rl_rx_ucasts)); + printf("Rx broadcast frames : %ju\n", + (uintmax_t)le64toh(stats->rl_rx_bcasts)); + printf("Rx multicast frames : %u\n", + le32toh(stats->rl_rx_mcasts)); + printf("Tx aborts : %u\n", + (uint32_t)le16toh(stats->rl_tx_aborts)); + printf("Tx underruns : %u\n", + (uint32_t)le16toh(stats->rl_rx_underruns)); + } + + return (error); +} diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c index 8571458..06ac416 100644 --- a/sys/dev/usb/net/uhso.c +++ b/sys/dev/usb/net/uhso.c @@ -633,11 +633,10 @@ uhso_attach(device_t self) ht->ht_name[0] = 0; if (sc->sc_ttys == 1) - snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_unit); + snprintf(ht->ht_name, 32, "cuaU%d", ucom->sc_super->sc_unit); else { snprintf(ht->ht_name, 32, "cuaU%d.%d", - ucom->sc_unit - ucom->sc_local_unit, - ucom->sc_local_unit); + ucom->sc_super->sc_unit, ucom->sc_subunit); } desc = uhso_port_type[port]; @@ -666,7 +665,7 @@ uhso_detach(device_t self) usbd_transfer_unsetup(sc->sc_xfer, 3); usbd_transfer_unsetup(sc->sc_ctrl_xfer, UHSO_CTRL_MAX); if (sc->sc_ttys > 0) { - ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_ttys); + ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); for (i = 0; i < sc->sc_ttys; i++) { if (sc->sc_tty[i].ht_muxport != -1) { @@ -903,6 +902,7 @@ uhso_probe_iface(struct uhso_softc *sc, int index, device_printf(sc->sc_dev, "ucom_attach failed\n"); return (ENXIO); } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); mtx_lock(&sc->sc_mtx); usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); @@ -921,6 +921,7 @@ uhso_probe_iface(struct uhso_softc *sc, int index, device_printf(sc->sc_dev, "ucom_attach failed\n"); return (ENXIO); } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, sc->sc_dev); } else { UHSO_DPRINTF(0, "Unknown type %x\n", type); @@ -1448,11 +1449,11 @@ uhso_ucom_start_read(struct ucom_softc *ucom) { struct uhso_softc *sc = ucom->sc_parent; - UHSO_DPRINTF(3, "unit=%d, local_unit=%d\n", - ucom->sc_unit, ucom->sc_local_unit); + UHSO_DPRINTF(3, "unit=%d, subunit=%d\n", + ucom->sc_super->sc_unit, ucom->sc_subunit); if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { - sc->sc_tty[ucom->sc_local_unit].ht_open = 1; + sc->sc_tty[ucom->sc_subunit].ht_open = 1; usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); } else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { @@ -1470,9 +1471,9 @@ uhso_ucom_stop_read(struct ucom_softc *ucom) struct uhso_softc *sc = ucom->sc_parent; if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { - sc->sc_tty[ucom->sc_local_unit].ht_open = 0; + sc->sc_tty[ucom->sc_subunit].ht_open = 0; usbd_transfer_stop( - sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_READ]); + sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_READ]); } else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { sc->sc_tty[0].ht_open = 0; @@ -1488,15 +1489,15 @@ uhso_ucom_start_write(struct ucom_softc *ucom) struct uhso_softc *sc = ucom->sc_parent; if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { - UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_local_unit); + UHSO_DPRINTF(3, "local unit %d\n", ucom->sc_subunit); usbd_transfer_start(sc->sc_xfer[UHSO_MUX_ENDPT_INTR]); usbd_xfer_set_priv( - sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE], - &sc->sc_tty[ucom->sc_local_unit]); + sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE], + &sc->sc_tty[ucom->sc_subunit]); usbd_transfer_start( - sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]); + sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); } else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { @@ -1511,7 +1512,7 @@ uhso_ucom_stop_write(struct ucom_softc *ucom) if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_MUX) { usbd_transfer_stop( - sc->sc_tty[ucom->sc_local_unit].ht_xfer[UHSO_CTRL_WRITE]); + sc->sc_tty[ucom->sc_subunit].ht_xfer[UHSO_CTRL_WRITE]); } else if (UHSO_IFACE_USB_TYPE(sc->sc_type) & UHSO_IF_BULK) { usbd_transfer_stop(sc->sc_xfer[UHSO_BULK_ENDPT_WRITE]); diff --git a/sys/dev/usb/quirk/usb_quirk.c b/sys/dev/usb/quirk/usb_quirk.c index e375adc..c619a24 100644 --- a/sys/dev/usb/quirk/usb_quirk.c +++ b/sys/dev/usb/quirk/usb_quirk.c @@ -120,6 +120,7 @@ static struct usb_quirk_entry usb_quirks[USB_DEV_QUIRKS_MAX] = { USB_QUIRK(MGE, UPS2, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(APPLE, IPHONE, 0x0000, 0xffff, UQ_HID_IGNORE), USB_QUIRK(APPLE, IPHONE_3G, 0x0000, 0xffff, UQ_HID_IGNORE), + USB_QUIRK(MEGATEC, UPS, 0x0000, 0xffff, UQ_HID_IGNORE), /* Devices which should be ignored by both ukbd and uhid */ USB_QUIRK(CYPRESS, WISPY1A, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), USB_QUIRK(METAGEEK, WISPY1B, 0x0000, 0xffff, UQ_KBD_IGNORE, UQ_HID_IGNORE), diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 4bc42ae..9376e9e 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -411,7 +411,6 @@ static const struct usb_device_id u3g_devs[] = { U3G_DEV(QUALCOMMINC, E0078, 0), U3G_DEV(QUALCOMMINC, E0082, 0), U3G_DEV(QUALCOMMINC, E0086, 0), - U3G_DEV(QUALCOMMINC, E2000, U3GINIT_SCSIEJECT), U3G_DEV(QUALCOMMINC, E2002, 0), U3G_DEV(QUALCOMMINC, E2003, 0), U3G_DEV(QUALCOMMINC, MF626, 0), @@ -655,6 +654,12 @@ u3g_test_autoinst(void *arg, struct usb_device *udev, if (usbd_lookup_id_by_uaa(u3g_devs, sizeof(u3g_devs), uaa)) return; /* no device match */ + if (bootverbose) { + printf("Ejecting 0x%04x:0x%04x using method %ld\n", + uaa->info.idVendor, uaa->info.idProduct, + USB_GET_DRIVER_INFO(uaa)); + } + switch (USB_GET_DRIVER_INFO(uaa)) { case U3GINIT_HUAWEI: error = u3g_huawei_init(udev); @@ -669,7 +674,8 @@ u3g_test_autoinst(void *arg, struct usb_device *udev, error = usb_msc_eject(udev, 0, MSC_EJECT_REZERO); break; case U3GINIT_ZTESTOR: - error = usb_msc_eject(udev, 0, MSC_EJECT_ZTESTOR); + error = usb_msc_eject(udev, 0, MSC_EJECT_STOPUNIT); + error |= usb_msc_eject(udev, 0, MSC_EJECT_ZTESTOR); break; case U3GINIT_CMOTECH: error = usb_msc_eject(udev, 0, MSC_EJECT_CMOTECH); @@ -818,8 +824,10 @@ u3g_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); device_printf(dev, "Found %u port%s.\n", sc->sc_numports, sc->sc_numports > 1 ? "s":""); + return (0); detach: @@ -831,15 +839,15 @@ static int u3g_detach(device_t dev) { struct u3g_softc *sc = device_get_softc(dev); - uint8_t m; + uint8_t subunit; DPRINTF("sc=%p\n", sc); /* NOTE: It is not dangerous to detach more ports than attached! */ - ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, U3G_MAXPORTS); + ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); - for (m = 0; m != U3G_MAXPORTS; m++) - usbd_transfer_unsetup(sc->sc_xfer[m], U3G_N_TRANSFER); + for (subunit = 0; subunit != U3G_MAXPORTS; subunit++) + usbd_transfer_unsetup(sc->sc_xfer[subunit], U3G_N_TRANSFER); mtx_destroy(&sc->sc_mtx); return (0); @@ -851,7 +859,7 @@ u3g_start_read(struct ucom_softc *ucom) struct u3g_softc *sc = ucom->sc_parent; /* start read endpoint */ - usbd_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]); + usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]); return; } @@ -861,7 +869,7 @@ u3g_stop_read(struct ucom_softc *ucom) struct u3g_softc *sc = ucom->sc_parent; /* stop read endpoint */ - usbd_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_RD]); + usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_RD]); return; } @@ -870,7 +878,7 @@ u3g_start_write(struct ucom_softc *ucom) { struct u3g_softc *sc = ucom->sc_parent; - usbd_transfer_start(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]); + usbd_transfer_start(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]); return; } @@ -879,7 +887,7 @@ u3g_stop_write(struct ucom_softc *ucom) { struct u3g_softc *sc = ucom->sc_parent; - usbd_transfer_stop(sc->sc_xfer[ucom->sc_local_unit][U3G_BULK_WR]); + usbd_transfer_stop(sc->sc_xfer[ucom->sc_subunit][U3G_BULK_WR]); return; } diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c index 10476c2..de7f057 100644 --- a/sys/dev/usb/serial/uark.c +++ b/sys/dev/usb/serial/uark.c @@ -227,6 +227,8 @@ uark_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); /* success */ detach: @@ -239,7 +241,7 @@ uark_detach(device_t dev) { struct uark_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UARK_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c index 83ae1c9..8f1abec 100644 --- a/sys/dev/usb/serial/ubsa.c +++ b/sys/dev/usb/serial/ubsa.c @@ -331,6 +331,8 @@ ubsa_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -345,7 +347,7 @@ ubsa_detach(device_t dev) DPRINTF("sc=%p\n", sc); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UBSA_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c index 7119177..204be9b 100644 --- a/sys/dev/usb/serial/ubser.c +++ b/sys/dev/usb/serial/ubser.c @@ -296,6 +296,7 @@ ubser_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); mtx_lock(&sc->sc_mtx); usbd_xfer_set_stall(sc->sc_xfer[UBSER_BULK_DT_WR]); @@ -317,7 +318,7 @@ ubser_detach(device_t dev) DPRINTF("\n"); - ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numser); + ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UBSER_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index 3bcb49f..99c3ce7 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -354,6 +354,8 @@ uchcom_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -368,7 +370,7 @@ uchcom_detach(device_t dev) DPRINTFN(11, "\n"); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UCHCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c index decd03c..6f0db7d 100644 --- a/sys/dev/usb/serial/ucycom.c +++ b/sys/dev/usb/serial/ucycom.c @@ -272,13 +272,15 @@ ucycom_attach(device_t dev) } error = ucom_attach(&sc->sc_super_ucom, &sc->sc_ucom, 1, sc, &ucycom_callback, &sc->sc_mtx); - if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + if (urd_ptr) { free(urd_ptr, M_USBDEV); } + return (0); /* success */ detach: @@ -294,7 +296,7 @@ ucycom_detach(device_t dev) { struct ucycom_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UCYCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c index e7d5a9d..7da904e 100644 --- a/sys/dev/usb/serial/ufoma.c +++ b/sys/dev/usb/serial/ufoma.c @@ -450,6 +450,8 @@ ufoma_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + /*Sysctls*/ sctx = device_get_sysctl_ctx(dev); soid = device_get_sysctl_tree(dev); @@ -466,7 +468,7 @@ ufoma_attach(device_t dev) CTLFLAG_RW|CTLTYPE_STRING, sc, 0, ufoma_sysctl_open, "A", "Mode to transit when port is opened"); SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "comunit", - CTLFLAG_RD, &(sc->sc_ucom.sc_unit), 0, + CTLFLAG_RD, &(sc->sc_super_ucom.sc_unit), 0, "Unit number as USB serial"); return (0); /* success */ @@ -481,7 +483,7 @@ ufoma_detach(device_t dev) { struct ufoma_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_ctrl_xfer, UFOMA_CTRL_ENDPT_MAX); usbd_transfer_unsetup(sc->sc_bulk_xfer, UFOMA_BULK_ENDPT_MAX); diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index 64ddc00..5dd6d92 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -332,6 +332,8 @@ uftdi_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); /* success */ detach: @@ -344,7 +346,7 @@ uftdi_detach(device_t dev) { struct uftdi_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UFTDI_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c index dd69986..022e106 100644 --- a/sys/dev/usb/serial/ugensa.c +++ b/sys/dev/usb/serial/ugensa.c @@ -247,6 +247,8 @@ ugensa_attach(device_t dev) DPRINTF("attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); /* success */ detach: @@ -260,7 +262,7 @@ ugensa_detach(device_t dev) struct ugensa_softc *sc = device_get_softc(dev); uint8_t x; - ucom_detach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_niface); + ucom_detach(&sc->sc_super_ucom, sc->sc_ucom); for (x = 0; x < sc->sc_niface; x++) { usbd_transfer_unsetup(sc->sc_sub[x].sc_xfer, UGENSA_N_TRANSFER); diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c index 3bc915f..6d43858 100644 --- a/sys/dev/usb/serial/uipaq.c +++ b/sys/dev/usb/serial/uipaq.c @@ -1161,6 +1161,8 @@ uipaq_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -1173,7 +1175,7 @@ uipaq_detach(device_t dev) { struct uipaq_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UIPAQ_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index d05a9f9..c9f442f 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -297,6 +297,8 @@ umct_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); /* success */ detach: @@ -309,7 +311,7 @@ umct_detach(device_t dev) { struct umct_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UMCT_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index a7d00c9..73abf65 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -389,6 +389,8 @@ umodem_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -816,7 +818,7 @@ umodem_detach(device_t dev) DPRINTF("sc=%p\n", sc); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UMODEM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c index b79290b..79807a6 100644 --- a/sys/dev/usb/serial/umoscom.c +++ b/sys/dev/usb/serial/umoscom.c @@ -338,6 +338,8 @@ umoscom_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -351,7 +353,7 @@ umoscom_detach(device_t dev) { struct umoscom_softc *sc = device_get_softc(dev); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UMOSCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index 604b73d2..6a4b149 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -445,6 +445,8 @@ uplcom_attach(device_t dev) device_printf(dev, "init failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -459,7 +461,7 @@ uplcom_detach(device_t dev) DPRINTF("sc=%p\n", sc); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UPLCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c index 5404bd8..9e9900a 100644 --- a/sys/dev/usb/serial/usb_serial.c +++ b/sys/dev/usb/serial/usb_serial.c @@ -123,13 +123,16 @@ static unsigned int ucom_cons_tx_low = 0; static unsigned int ucom_cons_tx_high = 0; static int ucom_cons_unit = -1; +static int ucom_cons_subunit = 0; static int ucom_cons_baud = 9600; static struct ucom_softc *ucom_cons_softc = NULL; TUNABLE_INT("hw.usb.ucom.cons_unit", &ucom_cons_unit); SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_unit, CTLFLAG_RW, &ucom_cons_unit, 0, "console unit number"); - +TUNABLE_INT("hw.usb.ucom.cons_subunit", &ucom_cons_subunit); +SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_subunit, CTLFLAG_RW, + &ucom_cons_subunit, 0, "console subunit number"); TUNABLE_INT("hw.usb.ucom.cons_baud", &ucom_cons_baud); SYSCTL_INT(_hw_usb_ucom, OID_AUTO, cons_baud, CTLFLAG_RW, &ucom_cons_baud, 0, "console baud rate"); @@ -141,9 +144,9 @@ static usb_proc_callback_t ucom_cfg_line_state; static usb_proc_callback_t ucom_cfg_status_change; static usb_proc_callback_t ucom_cfg_param; -static uint8_t ucom_units_alloc(uint32_t, uint32_t *); -static void ucom_units_free(uint32_t, uint32_t); -static int ucom_attach_tty(struct ucom_softc *, uint32_t); +static int ucom_unit_alloc(void); +static void ucom_unit_free(int); +static int ucom_attach_tty(struct ucom_super_softc *, struct ucom_softc *); static void ucom_detach_tty(struct ucom_softc *); static void ucom_queue_command(struct ucom_softc *, usb_proc_callback_t *, struct termios *pt, @@ -176,84 +179,54 @@ static struct ttydevsw ucom_class = { MODULE_DEPEND(ucom, usb, 1, 1, 1); MODULE_VERSION(ucom, 1); -#define UCOM_UNIT_MAX 0x200 /* exclusive */ -#define UCOM_SUB_UNIT_MAX 0x100 /* exclusive */ +#define UCOM_UNIT_MAX 128 /* limits size of ucom_bitmap */ static uint8_t ucom_bitmap[(UCOM_UNIT_MAX + 7) / 8]; static struct mtx ucom_bitmap_mtx; MTX_SYSINIT(ucom_bitmap_mtx, &ucom_bitmap_mtx, "ucom bitmap", MTX_DEF); -static uint8_t -ucom_units_alloc(uint32_t sub_units, uint32_t *p_root_unit) +#define UCOM_TTY_PREFIX "U" + +/* + * Mark a unit number (the X in cuaUX) as in use. + * + * Note that devices using a different naming scheme (see ucom_tty_name() + * callback) still use this unit allocation. + */ +static int +ucom_unit_alloc(void) { - uint32_t n; - uint32_t o; - uint32_t x; - uint32_t max = UCOM_UNIT_MAX - (UCOM_UNIT_MAX % sub_units); - uint8_t error = 1; + int unit; mtx_lock(&ucom_bitmap_mtx); - for (n = 0; n < max; n += sub_units) { - - /* check for free consecutive bits */ - - for (o = 0; o < sub_units; o++) { - - x = n + o; - - if (ucom_bitmap[x / 8] & (1 << (x % 8))) { - goto skip; - } - } - - /* allocate */ - - for (o = 0; o < sub_units; o++) { - - x = n + o; - - ucom_bitmap[x / 8] |= (1 << (x % 8)); - } - - error = 0; - - break; - -skip: ; - } + for (unit = 0; unit < UCOM_UNIT_MAX; unit++) + if ((ucom_bitmap[unit / 8] & (1 << (unit % 8))) == 0) + break; mtx_unlock(&ucom_bitmap_mtx); - /* - * Always set the variable pointed to by "p_root_unit" so that - * the compiler does not think that it is used uninitialised: - */ - *p_root_unit = n; - - return (error); + if (unit == UCOM_UNIT_MAX) + return -1; + else + return unit; } +/* + * Mark the unit number as not in use. + */ static void -ucom_units_free(uint32_t root_unit, uint32_t sub_units) +ucom_unit_free(int unit) { - uint32_t x; - mtx_lock(&ucom_bitmap_mtx); - while (sub_units--) { - x = root_unit + sub_units; - ucom_bitmap[x / 8] &= ~(1 << (x % 8)); - } + ucom_bitmap[unit / 8] &= ~(1 << (unit % 8)); mtx_unlock(&ucom_bitmap_mtx); } /* - * "N" sub_units are setup at a time. All sub-units will - * be given sequential unit numbers. The number of - * sub-units can be used to differentiate among - * different types of devices. + * Setup a group of one or more serial ports. * * The mutex pointed to by "mtx" is applied before all * callbacks are called back. Also "mtx" must be applied @@ -261,47 +234,47 @@ ucom_units_free(uint32_t root_unit, uint32_t sub_units) */ int ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, - uint32_t sub_units, void *parent, + uint32_t subunits, void *parent, const struct ucom_callback *callback, struct mtx *mtx) { - uint32_t n; - uint32_t root_unit; + uint32_t subunit; int error = 0; if ((sc == NULL) || - (sub_units == 0) || - (sub_units > UCOM_SUB_UNIT_MAX) || + (subunits == 0) || (callback == NULL)) { return (EINVAL); } - /* XXX unit management does not really belong here */ - if (ucom_units_alloc(sub_units, &root_unit)) { + ssc->sc_unit = ucom_unit_alloc(); + if (ssc->sc_unit == -1) return (ENOMEM); - } error = usb_proc_create(&ssc->sc_tq, mtx, "ucom", USB_PRI_MED); if (error) { - ucom_units_free(root_unit, sub_units); + ucom_unit_free(ssc->sc_unit); return (error); } + ssc->sc_subunits = subunits; - for (n = 0; n != sub_units; n++, sc++) { - sc->sc_unit = root_unit + n; - sc->sc_local_unit = n; - sc->sc_super = ssc; - sc->sc_mtx = mtx; - sc->sc_parent = parent; - sc->sc_callback = callback; + for (subunit = 0; subunit < ssc->sc_subunits; subunit++) { + sc[subunit].sc_subunit = subunit; + sc[subunit].sc_super = ssc; + sc[subunit].sc_mtx = mtx; + sc[subunit].sc_parent = parent; + sc[subunit].sc_callback = callback; - error = ucom_attach_tty(sc, sub_units); + error = ucom_attach_tty(ssc, &sc[subunit]); if (error) { - ucom_detach(ssc, sc - n, n); - ucom_units_free(root_unit + n, sub_units - n); + ucom_detach(ssc, &sc[0]); return (error); } - sc->sc_flag |= UCOM_FLAG_ATTACHED; + sc[subunit].sc_flag |= UCOM_FLAG_ATTACHED; } + + DPRINTF("tp = %p, unit = %d, subunits = %d\n", + sc->sc_tty, ssc->sc_unit, ssc->sc_subunits); + return (0); } @@ -310,62 +283,51 @@ ucom_attach(struct ucom_super_softc *ssc, struct ucom_softc *sc, * the structure pointed to by "ssc" and "sc" is zero. */ void -ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc, - uint32_t sub_units) +ucom_detach(struct ucom_super_softc *ssc, struct ucom_softc *sc) { - uint32_t n; + uint32_t subunit; usb_proc_drain(&ssc->sc_tq); - for (n = 0; n != sub_units; n++, sc++) { - if (sc->sc_flag & UCOM_FLAG_ATTACHED) { + for (subunit = 0; subunit < ssc->sc_subunits; subunit++) { + if (sc[subunit].sc_flag & UCOM_FLAG_ATTACHED) { - ucom_detach_tty(sc); + ucom_detach_tty(&sc[subunit]); - ucom_units_free(sc->sc_unit, 1); - - /* avoid duplicate detach: */ - sc->sc_flag &= ~UCOM_FLAG_ATTACHED; + /* avoid duplicate detach */ + sc[subunit].sc_flag &= ~UCOM_FLAG_ATTACHED; } } + ucom_unit_free(ssc->sc_unit); usb_proc_free(&ssc->sc_tq); } static int -ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units) +ucom_attach_tty(struct ucom_super_softc *ssc, struct ucom_softc *sc) { struct tty *tp; - int error = 0; char buf[32]; /* temporary TTY device name buffer */ tp = tty_alloc_mutex(&ucom_class, sc, sc->sc_mtx); - if (tp == NULL) { - error = ENOMEM; - goto done; - } - DPRINTF("tp = %p, unit = %d\n", tp, sc->sc_unit); - - buf[0] = 0; /* set some default value */ + if (tp == NULL) + return (ENOMEM); /* Check if the client has a custom TTY name */ + buf[0] = '\0'; if (sc->sc_callback->ucom_tty_name) { sc->sc_callback->ucom_tty_name(sc, buf, - sizeof(buf), sc->sc_local_unit); + sizeof(buf), ssc->sc_unit, sc->sc_subunit); } if (buf[0] == 0) { /* Use default TTY name */ - if (sub_units > 1) { + if (ssc->sc_subunits > 1) { /* multiple modems in one */ - if (snprintf(buf, sizeof(buf), "U%u.%u", - sc->sc_unit - sc->sc_local_unit, - sc->sc_local_unit)) { - /* ignore */ - } + snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u.%u", + ssc->sc_unit, sc->sc_subunit); } else { /* single modem */ - if (snprintf(buf, sizeof(buf), "U%u", sc->sc_unit)) { - /* ignore */ - } + snprintf(buf, sizeof(buf), UCOM_TTY_PREFIX "%u", + ssc->sc_unit); } } tty_makedev(tp, NULL, "%s", buf); @@ -377,10 +339,12 @@ ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units) /* Check if this device should be a console */ if ((ucom_cons_softc == NULL) && - (sc->sc_unit == ucom_cons_unit)) { - + (ssc->sc_unit == ucom_cons_unit) && + (sc->sc_subunit == ucom_cons_subunit)) { struct termios t; + DPRINTF("unit %d subunit %d is console", ssc->sc_unit, sc->sc_subunit); + ucom_cons_softc = sc; memset(&t, 0, sizeof(t)); @@ -398,8 +362,8 @@ ucom_attach_tty(struct ucom_softc *sc, uint32_t sub_units) ucom_param(ucom_cons_softc->sc_tty, &t); mtx_unlock(ucom_cons_softc->sc_mtx); } -done: - return (error); + + return (0); } static void @@ -412,6 +376,7 @@ ucom_detach_tty(struct ucom_softc *sc) if (sc->sc_flag & UCOM_FLAG_CONSOLE) { mtx_lock(ucom_cons_softc->sc_mtx); ucom_close(ucom_cons_softc->sc_tty); + sc->sc_flag &= ~UCOM_FLAG_CONSOLE; mtx_unlock(ucom_cons_softc->sc_mtx); ucom_cons_softc = NULL; } @@ -447,6 +412,24 @@ ucom_detach_tty(struct ucom_softc *sc) cv_destroy(&sc->sc_cv); } +void +ucom_set_pnpinfo_usb(struct ucom_super_softc *ssc, device_t dev) +{ + char buf[64]; + uint8_t iface_index; + struct usb_attach_arg *uaa; + + snprintf(buf, sizeof(buf), "ttyname=%s%d ttyports=%d", + UCOM_TTY_PREFIX, ssc->sc_unit, ssc->sc_subunits); + + /* Store the PNP info in the first interface for the dev */ + uaa = device_get_ivars(dev); + iface_index = uaa->info.bIfaceIndex; + + if (usbd_set_pnpinfo(uaa->device, iface_index, buf) != 0) + device_printf(dev, "Could not set PNP info\n"); +} + static void ucom_queue_command(struct ucom_softc *sc, usb_proc_callback_t *fn, struct termios *pt, diff --git a/sys/dev/usb/serial/usb_serial.h b/sys/dev/usb/serial/usb_serial.h index 7f7590b..5b53b89 100644 --- a/sys/dev/usb/serial/usb_serial.h +++ b/sys/dev/usb/serial/usb_serial.h @@ -104,7 +104,7 @@ struct ucom_callback { void (*ucom_stop_read) (struct ucom_softc *); void (*ucom_start_write) (struct ucom_softc *); void (*ucom_stop_write) (struct ucom_softc *); - void (*ucom_tty_name) (struct ucom_softc *, char *pbuf, uint16_t buflen, uint16_t local_subunit); + void (*ucom_tty_name) (struct ucom_softc *, char *pbuf, uint16_t buflen, uint16_t unit, uint16_t subunit); void (*ucom_poll) (struct ucom_softc *); }; @@ -132,6 +132,8 @@ struct ucom_param_task { struct ucom_super_softc { struct usb_process sc_tq; + uint32_t sc_unit; + uint32_t sc_subunits; }; struct ucom_softc { @@ -160,8 +162,7 @@ struct ucom_softc { struct tty *sc_tty; struct mtx *sc_mtx; void *sc_parent; - uint32_t sc_unit; - uint32_t sc_local_unit; + uint32_t sc_subunit; uint16_t sc_portno; uint16_t sc_flag; #define UCOM_FLAG_RTS_IFLOW 0x01 /* use RTS input flow control */ @@ -191,8 +192,8 @@ struct ucom_softc { int ucom_attach(struct ucom_super_softc *, struct ucom_softc *, uint32_t, void *, const struct ucom_callback *callback, struct mtx *); -void ucom_detach(struct ucom_super_softc *, - struct ucom_softc *, uint32_t); +void ucom_detach(struct ucom_super_softc *, struct ucom_softc *); +void ucom_set_pnpinfo_usb(struct ucom_super_softc *, device_t); void ucom_status_change(struct ucom_softc *); uint8_t ucom_get_data(struct ucom_softc *, struct usb_page_cache *, uint32_t, uint32_t, uint32_t *); diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c index 7784dbd..327fb3b 100644 --- a/sys/dev/usb/serial/uslcom.c +++ b/sys/dev/usb/serial/uslcom.c @@ -324,6 +324,8 @@ uslcom_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -338,7 +340,7 @@ uslcom_detach(device_t dev) DPRINTF("sc=%p\n", sc); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, USLCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c index 96a3389..b4174e6 100644 --- a/sys/dev/usb/serial/uvisor.c +++ b/sys/dev/usb/serial/uvisor.c @@ -347,6 +347,8 @@ uvisor_attach(device_t dev) DPRINTF("ucom_attach failed\n"); goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + return (0); detach: @@ -361,7 +363,7 @@ uvisor_detach(device_t dev) DPRINTF("sc=%p\n", sc); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UVISOR_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c index f220587..865947c 100644 --- a/sys/dev/usb/serial/uvscom.c +++ b/sys/dev/usb/serial/uvscom.c @@ -321,6 +321,8 @@ uvscom_attach(device_t dev) if (error) { goto detach; } + ucom_set_pnpinfo_usb(&sc->sc_super_ucom, dev); + /* start interrupt pipe */ mtx_lock(&sc->sc_mtx); usbd_transfer_start(sc->sc_xfer[UVSCOM_INTR_DT_RD]); @@ -345,7 +347,7 @@ uvscom_detach(device_t dev) if (sc->sc_xfer[UVSCOM_INTR_DT_RD]) usbd_transfer_stop(sc->sc_xfer[UVSCOM_INTR_DT_RD]); - ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom, 1); + ucom_detach(&sc->sc_super_ucom, &sc->sc_ucom); usbd_transfer_unsetup(sc->sc_xfer, UVSCOM_N_TRANSFER); mtx_destroy(&sc->sc_mtx); diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 495bd82..95b0e9e 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -2426,14 +2426,13 @@ usb_notify_addq_compat(const char *type, struct usb_device *udev) #if USB_HAVE_UGEN "%s " #endif + "at port=%u " "vendor=0x%04x " "product=0x%04x " "devclass=0x%02x " "devsubclass=0x%02x " "sernum=\"%s\" " "release=0x%04x " - "at " - "port=%u " #if USB_HAVE_UGEN "on %s\n" #endif @@ -2442,13 +2441,13 @@ usb_notify_addq_compat(const char *type, struct usb_device *udev) #if USB_HAVE_UGEN udev->ugen_name, #endif + udev->port_no, UGETW(udev->ddesc.idVendor), UGETW(udev->ddesc.idProduct), udev->ddesc.bDeviceClass, udev->ddesc.bDeviceSubClass, usb_get_serial(udev), - UGETW(udev->ddesc.bcdDevice), - udev->port_no + UGETW(udev->ddesc.bcdDevice) #if USB_HAVE_UGEN , udev->parent_hub != NULL ? udev->parent_hub->ugen_name : @@ -2486,7 +2485,7 @@ usb_notify_addq(const char *type, struct usb_device *udev) "mode=%s " "port=%u " #if USB_HAVE_UGEN - "parent=%s\n" + "parent=%s" #endif "", #if USB_HAVE_UGEN @@ -2534,7 +2533,7 @@ usb_notify_addq(const char *type, struct usb_device *udev) "endpoints=%d " "intclass=0x%02x " "intsubclass=0x%02x " - "intprotocol=0x%02x\n", + "intprotocol=0x%02x", #if USB_HAVE_UGEN udev->ugen_name, #endif diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index 859af69..60767388 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -741,7 +741,7 @@ done: /*------------------------------------------------------------------------* * usbd_req_reset_port * - * This function will instruct an USB HUB to perform a reset sequence + * This function will instruct a USB HUB to perform a reset sequence * on the specified port number. * * Returns: @@ -793,12 +793,105 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) if (err) { goto done; } + /* check if reset is complete */ + if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) { + break; + } + /* check for timeout */ + if (n > 1000) { + n = 0; + break; + } + } + + /* clear port reset first */ + err = usbd_req_clear_port_feature( + udev, mtx, port, UHF_C_PORT_RESET); + if (err) { + goto done; + } + /* check for timeout */ + if (n == 0) { + err = USB_ERR_TIMEOUT; + goto done; + } +#ifdef USB_DEBUG + /* wait for the device to recover from reset */ + usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay)); +#else + /* wait for the device to recover from reset */ + usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY)); +#endif + +done: + DPRINTFN(2, "port %d reset returning error=%s\n", + port, usbd_errstr(err)); + return (err); +} + +/*------------------------------------------------------------------------* + * usbd_req_warm_reset_port + * + * This function will instruct an USB HUB to perform a warm reset + * sequence on the specified port number. This kind of reset is not + * mandatory for LOW-, FULL- and HIGH-speed USB HUBs and is targeted + * for SUPER-speed USB HUBs. + * + * Returns: + * 0: Success. The USB device should now be available again. + * Else: Failure. No USB device is present and the USB port should be + * disabled. + *------------------------------------------------------------------------*/ +usb_error_t +usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) +{ + struct usb_port_status ps; + usb_error_t err; + uint16_t n; + +#ifdef USB_DEBUG + uint16_t pr_poll_delay; + uint16_t pr_recovery_delay; + +#endif + err = usbd_req_set_port_feature(udev, mtx, port, UHF_BH_PORT_RESET); + if (err) { + goto done; + } +#ifdef USB_DEBUG + /* range check input parameters */ + pr_poll_delay = usb_pr_poll_delay; + if (pr_poll_delay < 1) { + pr_poll_delay = 1; + } else if (pr_poll_delay > 1000) { + pr_poll_delay = 1000; + } + pr_recovery_delay = usb_pr_recovery_delay; + if (pr_recovery_delay > 1000) { + pr_recovery_delay = 1000; + } +#endif + n = 0; + while (1) { +#ifdef USB_DEBUG + /* wait for the device to recover from reset */ + usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay)); + n += pr_poll_delay; +#else + /* wait for the device to recover from reset */ + usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY)); + n += USB_PORT_RESET_DELAY; +#endif + err = usbd_req_get_port_status(udev, mtx, &ps, port); + if (err) { + goto done; + } /* if the device disappeared, just give up */ if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) { goto done; } /* check if reset is complete */ - if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) { + if (UGETW(ps.wPortChange) & UPS_C_BH_PORT_RESET) { break; } /* check for timeout */ @@ -810,7 +903,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) /* clear port reset first */ err = usbd_req_clear_port_feature( - udev, mtx, port, UHF_C_PORT_RESET); + udev, mtx, port, UHF_C_BH_PORT_RESET); if (err) { goto done; } @@ -828,7 +921,7 @@ usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) #endif done: - DPRINTFN(2, "port %d reset returning error=%s\n", + DPRINTFN(2, "port %d warm reset returning error=%s\n", port, usbd_errstr(err)); return (err); } diff --git a/sys/dev/usb/usb_request.h b/sys/dev/usb/usb_request.h index 1ce8b56..12f373d 100644 --- a/sys/dev/usb/usb_request.h +++ b/sys/dev/usb/usb_request.h @@ -65,6 +65,8 @@ usb_error_t usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx, struct usb_port_status *ps, uint8_t port); usb_error_t usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port); +usb_error_t usbd_req_warm_reset_port(struct usb_device *udev, + struct mtx *mtx, uint8_t port); usb_error_t usbd_req_set_address(struct usb_device *udev, struct mtx *mtx, uint16_t addr); usb_error_t usbd_req_set_hub_feature(struct usb_device *udev, struct mtx *mtx, diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index be0cd7a..404ec18 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -2518,7 +2518,7 @@ product PHILIPS RT2870 0x200f RT2870 product PHILIPSSEMI HUB1122 0x1122 HUB /* Megatec */ -product MEGATEC UPS 0x5161 Protocol based UPS +product MEGATEC UPS 0x5161 Phoenixtec protocol based UPS /* P.I. Engineering products */ product PIENGINEERING PS2USB 0x020b PS2 to Mac USB Adapter @@ -2612,15 +2612,11 @@ product QISDA H20_2 0x4519 3G modem /* Qualcomm products */ product QUALCOMM CDMA_MSM 0x6000 CDMA Technologies MSM phone +product QUALCOMM2 MF330 0x6613 MF330 product QUALCOMM2 RWT_FCT 0x3100 RWT FCT-CDMA 2000 1xRTT modem product QUALCOMM2 CDMA_MSM 0x3196 CDMA Technologies MSM modem product QUALCOMM2 AC8700 0x6000 AC8700 -product QUALCOMM2 MF330 0x6613 MF330 product QUALCOMMINC CDMA_MSM 0x0001 CDMA Technologies MSM modem -product QUALCOMMINC ZTE_STOR 0x2000 USB ZTE Storage -product QUALCOMMINC AC8710 0xfff1 3G modem -product QUALCOMMINC AC2726 0xfff5 3G modem -product QUALCOMMINC AC8700 0xfffe CDMA 1xEVDO USB modem product QUALCOMMINC E0002 0x0002 3G modem product QUALCOMMINC E0003 0x0003 3G modem product QUALCOMMINC E0004 0x0004 3G modem @@ -2686,9 +2682,12 @@ product QUALCOMMINC E0076 0x0076 3G modem product QUALCOMMINC E0078 0x0078 3G modem product QUALCOMMINC E0082 0x0082 3G modem product QUALCOMMINC E0086 0x0086 3G modem -product QUALCOMMINC E2000 0x2000 3G modem +product QUALCOMMINC ZTE_STOR 0x2000 USB ZTE Storage product QUALCOMMINC E2002 0x2002 3G modem product QUALCOMMINC E2003 0x2003 3G modem +product QUALCOMMINC AC8710 0xfff1 3G modem +product QUALCOMMINC AC2726 0xfff5 3G modem +product QUALCOMMINC AC8700 0xfffe CDMA 1xEVDO USB modem /* Quanta products */ product QUANTA RW6815_1 0x00ce HP iPAQ rw6815 @@ -3270,9 +3269,6 @@ product UMEDIA AR5523_2_NF 0x3206 AR5523 (no firmware) /* Universal Access products */ product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter -/* Unknown vendors */ -product UNKNOWN5 USB2IDEBRIDGE 0x00ff USB 2.0 ATA/SATA Bridge - /* USI products */ product USI MC60 0x10c5 MC60 Serial diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 21961ce..c914d5e 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -496,7 +496,6 @@ rum_attach(device_t self) | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* bg scanning supported */ | IEEE80211_C_WPA /* 802.11i */ - | IEEE80211_C_RATECTL /* use ratectl */ ; bands = 0; diff --git a/sys/dev/usb/wlan/if_run.c b/sys/dev/usb/wlan/if_run.c index d6cbf3a..060eb81 100644 --- a/sys/dev/usb/wlan/if_run.c +++ b/sys/dev/usb/wlan/if_run.c @@ -632,8 +632,7 @@ run_attach(device_t self) IEEE80211_C_SHPREAMBLE | /* short preamble supported */ IEEE80211_C_SHSLOT | /* short slot time supported */ IEEE80211_C_WME | /* WME */ - IEEE80211_C_WPA | /* WPA1|WPA2(RSN) */ - IEEE80211_C_RATECTL; /* use ratectl */ + IEEE80211_C_WPA; /* WPA1|WPA2(RSN) */ ic->ic_cryptocaps = IEEE80211_CRYPTO_WEP | diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index aa2dcbd..3ebdafe 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -486,7 +486,6 @@ ural_attach(device_t self) | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* bg scanning supported */ | IEEE80211_C_WPA /* 802.11i */ - | IEEE80211_C_RATECTL /* use ratectl */ ; bands = 0; diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index e8d7b7e..677db54 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -397,7 +397,6 @@ zyd_attach(device_t dev) | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_BGSCAN /* capable of bg scanning */ | IEEE80211_C_WPA /* 802.11i */ - | IEEE80211_C_RATECTL /* use ratectl */ ; bands = 0; diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 26336bfc3..f6edc91 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -634,7 +634,6 @@ wpi_attach(device_t dev) | IEEE80211_C_WME /* 802.11e */ | IEEE80211_C_HOSTAP /* Host access point mode */ #endif - | IEEE80211_C_RATECTL /* use ratectl */ ; /* diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 0d77e12..d99109f 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -1461,7 +1461,7 @@ xl_attach(device_t dev) * control registers at all MII addresses. */ phy = MII_PHY_ANY; - if ((sc->xl_flags & XL_FLAG_PHYOK) != 0) + if ((sc->xl_flags & XL_FLAG_PHYOK) == 0) phy = 24; error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd, xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, 0); |