diff options
Diffstat (limited to 'sys')
85 files changed, 795 insertions, 555 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index eba788f..738427f 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -1762,11 +1762,15 @@ void spinlock_enter(void) { struct thread *td; + register_t flags; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_flags = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + flags = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_flags = flags; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -1774,12 +1778,14 @@ void spinlock_exit(void) { struct thread *td; + register_t flags; td = curthread; critical_exit(); + flags = td->td_md.md_saved_flags; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_flags); + intr_restore(flags); } /* diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 3868428..f2951da 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -239,6 +239,9 @@ topo_probe_0x4(void) cpu_logical++; } + KASSERT(cpu_cores >= 1 && cpu_logical >= 1, + ("topo_probe_0x4 couldn't find BSP")); + cpu_cores /= cpu_logical; hyperthreading_cpus = cpu_logical; } @@ -310,7 +313,9 @@ topo_probe(void) return; logical_cpus_mask = 0; - if (cpu_vendor_id == CPU_VENDOR_AMD) + if (mp_ncpus <= 1) + cpu_cores = cpu_logical = 1; + else if (cpu_vendor_id == CPU_VENDOR_AMD) topo_probe_amd(); else if (cpu_vendor_id == CPU_VENDOR_INTEL) { /* @@ -332,10 +337,8 @@ topo_probe(void) * Fallback: assume each logical CPU is in separate * physical package. That is, no multi-core, no SMT. */ - if (cpu_cores == 0) - cpu_cores = 1; - if (cpu_logical == 0) - cpu_logical = 1; + if (cpu_cores == 0 || cpu_logical == 0) + cpu_cores = cpu_logical = 1; cpu_topo_probed = 1; } diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 32348d7..2d26f68 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -493,11 +493,15 @@ void spinlock_enter(void) { struct thread *td; + register_t cspr; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_cspr = disable_interrupts(I32_bit | F32_bit); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + cspr = disable_interrupts(I32_bit | F32_bit); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_cspr = cspr; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -505,12 +509,14 @@ void spinlock_exit(void) { struct thread *td; + register_t cspr; td = curthread; critical_exit(); + cspr = td->td_md.md_saved_cspr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - restore_interrupts(td->td_md.md_saved_cspr); + restore_interrupts(cspr); } /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 430a1b9..9a68adf 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -3627,6 +3627,14 @@ zfsdev_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, uint_t vec; int error; + /* + * Check if we have sufficient kernel memory allocated + * for the zfs_cmd_t request. Bail out if not so we + * will not access undefined memory region. + */ + if (IOCPARM_LEN(cmd) < sizeof(zfs_cmd_t)) + return (EINVAL); + vec = ZFS_IOC(cmd); if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 62bb465..459c786 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -287,15 +287,6 @@ ndis_create_sysctls(arg) TAILQ_INIT(&sc->ndis_cfglist_head); -#if __FreeBSD_version < 502113 - /* Create the sysctl tree. */ - - sc->ndis_tree = SYSCTL_ADD_NODE(&sc->ndis_ctx, - SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, - device_get_nameunit(sc->ndis_dev), CTLFLAG_RD, 0, - device_get_desc(sc->ndis_dev)); - -#endif /* Add the driver-specific registry keys. */ while(1) { @@ -310,11 +301,7 @@ ndis_create_sysctls(arg) /* See if we already have a sysctl with this name */ oidp = NULL; -#if __FreeBSD_version < 502113 - TAILQ_FOREACH(e, &sc->ndis_ctx, link) { -#else TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) { -#endif oidp = e->entry; if (strcasecmp(oidp->oid_name, vals->nc_cfgkey) == 0) break; @@ -395,18 +382,11 @@ ndis_add_sysctl(arg, key, desc, val, flag) TAILQ_INSERT_TAIL(&sc->ndis_cfglist_head, cfg, link); cfg->ndis_oid = -#if __FreeBSD_version < 502113 - SYSCTL_ADD_STRING(&sc->ndis_ctx, SYSCTL_CHILDREN(sc->ndis_tree), - OID_AUTO, cfg->ndis_cfg.nc_cfgkey, flag, - cfg->ndis_cfg.nc_val, sizeof(cfg->ndis_cfg.nc_val), - cfg->ndis_cfg.nc_cfgdesc); -#else SYSCTL_ADD_STRING(device_get_sysctl_ctx(sc->ndis_dev), SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ndis_dev)), OID_AUTO, cfg->ndis_cfg.nc_cfgkey, flag, cfg->ndis_cfg.nc_val, sizeof(cfg->ndis_cfg.nc_val), cfg->ndis_cfg.nc_cfgdesc); -#endif return (0); } @@ -428,11 +408,7 @@ ndis_flush_sysctls(arg) sc = arg; -#if __FreeBSD_version < 502113 - clist = &sc->ndis_ctx; -#else clist = device_get_sysctl_ctx(sc->ndis_dev); -#endif while (!TAILQ_EMPTY(&sc->ndis_cfglist_head)) { cfg = TAILQ_FIRST(&sc->ndis_cfglist_head); diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 558398d..a2905c2 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -639,11 +639,7 @@ NdisReadConfiguration(status, parm, cfg, key, type) * See if registry key is already in a list of known keys * included with the driver. */ -#if __FreeBSD_version < 502113 - TAILQ_FOREACH(e, &sc->ndis_ctx, link) { -#else TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) { -#endif oidp = e->entry; if (strcasecmp(oidp->oid_name, keystr) == 0) { if (strcmp((char *)oidp->oid_arg1, "UNSET") == 0) { @@ -746,11 +742,7 @@ NdisWriteConfiguration(status, cfg, key, parm) /* See if the key already exists. */ -#if __FreeBSD_version < 502113 - TAILQ_FOREACH(e, &sc->ndis_ctx, link) { -#else TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) { -#endif oidp = e->entry; if (strcasecmp(oidp->oid_name, keystr) == 0) { /* Found it, set the value. */ @@ -1318,23 +1310,11 @@ NdisReadNetworkAddress(status, addr, addrlen, adapter) return; } -#ifdef IFP2ENADDR - if (bcmp(IFP2ENADDR(sc->ifp), empty, ETHER_ADDR_LEN) == 0) -#elif __FreeBSD_version >= 700000 if (sc->ifp->if_addr == NULL || bcmp(IF_LLADDR(sc->ifp), empty, ETHER_ADDR_LEN) == 0) -#else - if (bcmp(sc->arpcom.ac_enaddr, empty, ETHER_ADDR_LEN) == 0) -#endif *status = NDIS_STATUS_FAILURE; else { -#ifdef IFP2ENADDR - *addr = IFP2ENADDR(sc->ifp); -#elif __FreeBSD_version >= 700000 *addr = IF_LLADDR(sc->ifp); -#else - *addr = sc->arpcom.ac_enaddr; -#endif *addrlen = ETHER_ADDR_LEN; *status = NDIS_STATUS_SUCCESS; } diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 714fcd8..04184ae 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -44,9 +44,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <sys/callout.h> -#if __FreeBSD_version > 502113 #include <sys/kdb.h> -#endif #include <sys/kernel.h> #include <sys/proc.h> #include <sys/condvar.h> @@ -2602,11 +2600,7 @@ ntoskrnl_finddev(dev, paddr, res) rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev); if (rl != NULL) { -#if __FreeBSD_version < 600022 - SLIST_FOREACH(rle, rl, link) { -#else STAILQ_FOREACH(rle, rl, link) { -#endif r = rle->res; if (r == NULL) @@ -2698,9 +2692,6 @@ ntoskrnl_workitem_thread(arg) KeReleaseSpinLock(&kq->kq_lock, irql); } -#if __FreeBSD_version < 502113 - mtx_lock(&Giant); -#endif kproc_exit(0); return; /* notreached */ } @@ -3429,9 +3420,6 @@ PsTerminateSystemThread(status) ntoskrnl_kth--; -#if __FreeBSD_version < 502113 - mtx_lock(&Giant); -#endif kproc_exit(0); return (0); /* notreached */ } @@ -3453,11 +3441,7 @@ static void DbgBreakPoint(void) { -#if __FreeBSD_version < 502113 - Debugger("DbgBreakPoint(): breakpoint"); -#else kdb_enter(KDB_WHY_NDIS, "DbgBreakPoint(): breakpoint"); -#endif } static void @@ -3697,14 +3681,9 @@ ntoskrnl_dpc_thread(arg) thread_lock(curthread); #ifdef NTOSKRNL_MULTIPLE_DPCS -#if __FreeBSD_version >= 502102 sched_bind(curthread, kq->kq_cpu); #endif -#endif sched_prio(curthread, PRI_MIN_KERN); -#if __FreeBSD_version < 600000 - curthread->td_base_pri = PRI_MIN_KERN; -#endif thread_unlock(curthread); while (1) { @@ -3737,9 +3716,6 @@ ntoskrnl_dpc_thread(arg) KeSetEvent(&kq->kq_done, IO_NO_INCREMENT, FALSE); } -#if __FreeBSD_version < 502113 - mtx_lock(&Giant); -#endif kproc_exit(0); return; /* notreached */ } diff --git a/sys/conf/files b/sys/conf/files index 6620ffe..ce2eb82 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -67,12 +67,12 @@ fdt_static_dtb.h optional fdt fdt_dtb_static \ compile-with "sh $S/tools/fdt/make_dtbh.sh ${FDT_DTS_FILE} ." \ no-obj no-implicit-rule before-depend \ clean "fdt_static_dtb.h" -p16v-alsa%diked.h optional snd_emu10kx pci \ +p16v-alsa%diked.h optional snd_emu10kx pci \ dependency "$S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h" \ compile-with "CC='${CC}' AWK=${AWK} sh $S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p16v-alsa.h p16v-alsa%diked.h" \ no-obj no-implicit-rule before-depend \ clean "p16v-alsa%diked.h" -p17v-alsa%diked.h optional snd_emu10kx pci \ +p17v-alsa%diked.h optional snd_emu10kx pci \ dependency "$S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h" \ compile-with "CC='${CC}' AWK=${AWK} sh $S/tools/sound/emu10k1-mkalsa.sh $S/gnu/dev/sound/pci/p17v-alsa.h p17v-alsa%diked.h" \ no-obj no-implicit-rule before-depend \ @@ -83,12 +83,12 @@ feeder_eq_gen.h optional sound \ no-obj no-implicit-rule before-depend \ clean "feeder_eq_gen.h" feeder_rate_gen.h optional sound \ - dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ + dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_rate_gen.h" snd_fxdiv_gen.h optional sound \ - dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ + dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ compile-with "${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \ no-obj no-implicit-rule before-depend \ clean "snd_fxdiv_gen.h" 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); diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c index 5ac52d4..44890aa 100644 --- a/sys/geom/geom_event.c +++ b/sys/geom/geom_event.c @@ -220,11 +220,12 @@ one_event(void) mtx_lock(&g_eventlock); TAILQ_REMOVE(&g_events, ep, events); ep->flag &= ~EV_INPROGRESS; - mtx_unlock(&g_eventlock); if (ep->flag & EV_WAKEUP) { ep->flag |= EV_DONE; + mtx_unlock(&g_eventlock); wakeup(ep); } else { + mtx_unlock(&g_eventlock); g_free(ep); } g_topology_unlock(); @@ -365,11 +366,14 @@ g_waitfor_event(g_event_t *func, void *arg, int flag, ...) va_end(ap); if (error) return (error); - do - tsleep(ep, PRIBIO, "g_waitfor_event", hz); - while (!(ep->flag & EV_DONE)); + + mtx_lock(&g_eventlock); + while (!(ep->flag & EV_DONE)) + msleep(ep, &g_eventlock, PRIBIO, "g_waitfor_event", hz); if (ep->flag & EV_CANCELED) error = EAGAIN; + mtx_unlock(&g_eventlock); + g_free(ep); return (error); } diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 255bec6..0fbd519 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1970,7 +1970,7 @@ add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp) return (1); #ifndef PAE - if (smap->base >= 0xffffffff) { + if (smap->base > 0xffffffff) { printf("%uK of memory above 4GB ignored\n", (u_int)(smap->length / 1024)); return (1); @@ -2997,11 +2997,15 @@ void spinlock_enter(void) { struct thread *td; + register_t flags; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_flags = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + flags = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_flags = flags; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -3009,12 +3013,14 @@ void spinlock_exit(void) { struct thread *td; + register_t flags; td = curthread; critical_exit(); + flags = td->td_md.md_saved_flags; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_flags); + intr_restore(flags); } #if defined(I586_CPU) && !defined(NO_F00F_HACK) diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index b99c19c..c4d2672 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -286,6 +286,9 @@ topo_probe_0x4(void) cpu_logical++; } + KASSERT(cpu_cores >= 1 && cpu_logical >= 1, + ("topo_probe_0x4 couldn't find BSP")); + cpu_cores /= cpu_logical; hyperthreading_cpus = cpu_logical; } @@ -357,7 +360,9 @@ topo_probe(void) return; logical_cpus_mask = 0; - if (cpu_vendor_id == CPU_VENDOR_AMD) + if (mp_ncpus <= 1) + cpu_cores = cpu_logical = 1; + else if (cpu_vendor_id == CPU_VENDOR_AMD) topo_probe_amd(); else if (cpu_vendor_id == CPU_VENDOR_INTEL) { /* @@ -379,10 +384,8 @@ topo_probe(void) * Fallback: assume each logical CPU is in separate * physical package. That is, no multi-core, no SMT. */ - if (cpu_cores == 0) - cpu_cores = 1; - if (cpu_logical == 0) - cpu_logical = 1; + if (cpu_cores == 0 || cpu_logical == 0) + cpu_cores = cpu_logical = 1; cpu_topo_probed = 1; } diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index ed00a04..119c36f 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -513,11 +513,15 @@ void spinlock_enter(void) { struct thread *td; + int intr; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_intr = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + intr = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_intr = intr; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -525,12 +529,14 @@ void spinlock_exit(void) { struct thread *td; + int intr; td = curthread; critical_exit(); + intr = td->td_md.md_saved_intr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_intr); + intr_restore(intr); } void diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 192ec60..1754f7b 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -195,7 +195,7 @@ deadlkres(void) panic("%s: possible deadlock detected on allproc_lock\n", __func__); tryl++; - pause("allproc_lock deadlkres", sleepfreq * hz); + pause("allproc", sleepfreq * hz); continue; } tryl = 0; @@ -288,7 +288,7 @@ deadlkres(void) sx_sunlock(&allproc_lock); /* Sleep for sleepfreq seconds. */ - pause("deadlkres", sleepfreq * hz); + pause("-", sleepfreq * hz); } } diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index f60af40..fa04087 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -214,8 +214,6 @@ kern_timeout_callwheel_init(void) /* * Start standard softclock thread. */ -void *softclock_ih; - static void start_softclock(void *dummy) { @@ -226,9 +224,8 @@ start_softclock(void *dummy) cc = CC_CPU(timeout_cpu); if (swi_add(&clk_intr_event, "clock", softclock, cc, SWI_CLOCK, - INTR_MPSAFE, &softclock_ih)) + INTR_MPSAFE, &cc->cc_cookie)) panic("died while creating standard software ithreads"); - cc->cc_cookie = softclock_ih; #ifdef SMP CPU_FOREACH(cpu) { if (cpu == timeout_cpu) diff --git a/sys/mips/cavium/octeon_ebt3000_cf.c b/sys/mips/cavium/octeon_ebt3000_cf.c index 3ab115f..7955d19 100644 --- a/sys/mips/cavium/octeon_ebt3000_cf.c +++ b/sys/mips/cavium/octeon_ebt3000_cf.c @@ -148,6 +148,8 @@ struct g_class g_cf_class = { .ioctl = cf_ioctl, }; +DECLARE_GEOM_CLASS(g_cf_class, g_cf); + /* Device methods */ static int cf_probe(device_t); static void cf_identify(driver_t *, device_t); diff --git a/sys/mips/cavium/octopci.c b/sys/mips/cavium/octopci.c index b8a3ac0..d065ae3 100644 --- a/sys/mips/cavium/octopci.c +++ b/sys/mips/cavium/octopci.c @@ -108,6 +108,8 @@ octopci_probe(device_t dev) { if (device_get_unit(dev) != 0) return (ENXIO); + if (octeon_has_feature(OCTEON_FEATURE_PCIE)) + return (ENXIO); /* XXX Check sysinfo flag. */ device_set_desc(dev, "Cavium Octeon PCI bridge"); return (0); diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 435b9b4..314bfd1 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -450,11 +450,15 @@ void spinlock_enter(void) { struct thread *td; + register_t intr; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_intr = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + intr = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_intr = intr; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -462,12 +466,14 @@ void spinlock_exit(void) { struct thread *td; + register_t intr; td = curthread; critical_exit(); + intr = td->td_md.md_saved_intr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_intr); + intr_restore(intr); } /* diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 6848824..409cf1d 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -486,9 +486,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, ieee80211_scan_vattach(vap); ieee80211_regdomain_vattach(vap); ieee80211_radiotap_vattach(vap); - - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR); + ieee80211_ratectl_set(vap, IEEE80211_RATECTL_NONE); return 0; } diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 2dc4871..2c1acff 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -817,8 +817,7 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, if (ieee80211_iserp_rateset(&ni->ni_rates)) ni->ni_flags |= IEEE80211_NODE_ERP; ieee80211_node_setuptxparms(ni); - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_init(ni); + ieee80211_ratectl_node_init(ni); return ieee80211_sta_join1(ieee80211_ref_node(ni)); } @@ -1038,8 +1037,7 @@ node_free(struct ieee80211_node *ni) { struct ieee80211com *ic = ni->ni_ic; - if (ni->ni_vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_deinit(ni); + ieee80211_ratectl_node_deinit(ni); ic->ic_node_cleanup(ni); ieee80211_ies_cleanup(&ni->ni_ies); ieee80211_psq_cleanup(&ni->ni_psq); @@ -1404,8 +1402,7 @@ ieee80211_fakeup_adhoc_node(struct ieee80211vap *vap, #endif } ieee80211_node_setuptxparms(ni); - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_init(ni); + ieee80211_ratectl_node_init(ni); if (ic->ic_newassoc != NULL) ic->ic_newassoc(ni, 1); /* XXX not right for 802.1x/WPA */ @@ -1475,8 +1472,7 @@ ieee80211_add_neighbor(struct ieee80211vap *vap, if (ieee80211_iserp_rateset(&ni->ni_rates)) ni->ni_flags |= IEEE80211_NODE_ERP; ieee80211_node_setuptxparms(ni); - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_init(ni); + ieee80211_ratectl_node_init(ni); if (ic->ic_newassoc != NULL) ic->ic_newassoc(ni, 1); /* XXX not right for 802.1x/WPA */ @@ -2345,8 +2341,7 @@ ieee80211_node_join(struct ieee80211_node *ni, int resp) ); ieee80211_node_setuptxparms(ni); - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_init(ni); + ieee80211_ratectl_node_init(ni); /* give driver a chance to setup state like ni_txrate */ if (ic->ic_newassoc != NULL) ic->ic_newassoc(ni, newassoc); diff --git a/sys/net80211/ieee80211_ratectl.c b/sys/net80211/ieee80211_ratectl.c index ea3d8d4..0ad46bd3 100644 --- a/sys/net80211/ieee80211_ratectl.c +++ b/sys/net80211/ieee80211_ratectl.c @@ -66,6 +66,14 @@ ieee80211_ratectl_unregister(int type) } void +ieee80211_ratectl_init(struct ieee80211vap *vap) +{ + if (vap->iv_rate == ratectls[IEEE80211_RATECTL_NONE]) + ieee80211_ratectl_set(vap, IEEE80211_RATECTL_AMRR); + vap->iv_rate->ir_init(vap); +} + +void ieee80211_ratectl_set(struct ieee80211vap *vap, int type) { if (type >= IEEE80211_RATECTL_MAX) diff --git a/sys/net80211/ieee80211_ratectl.h b/sys/net80211/ieee80211_ratectl.h index 87b2698..592405c 100644 --- a/sys/net80211/ieee80211_ratectl.h +++ b/sys/net80211/ieee80211_ratectl.h @@ -57,17 +57,12 @@ struct ieee80211_ratectl { void ieee80211_ratectl_register(int, const struct ieee80211_ratectl *); void ieee80211_ratectl_unregister(int); +void ieee80211_ratectl_init(struct ieee80211vap *); void ieee80211_ratectl_set(struct ieee80211vap *, int); MALLOC_DECLARE(M_80211_RATECTL); static void __inline -ieee80211_ratectl_init(struct ieee80211vap *vap) -{ - vap->iv_rate->ir_init(vap); -} - -static void __inline ieee80211_ratectl_deinit(struct ieee80211vap *vap) { vap->iv_rate->ir_deinit(vap); diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 5764fa0..f93c3ed 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -1597,8 +1597,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, IEEE80211_F_JOIN | IEEE80211_F_DOBRS); ieee80211_setup_basic_htrates(ni, htinfo); ieee80211_node_setuptxparms(ni); - if (vap->iv_caps & IEEE80211_C_RATECTL) - ieee80211_ratectl_node_init(ni); + ieee80211_ratectl_node_init(ni); } else { #ifdef IEEE80211_SUPPORT_SUPERG if (IEEE80211_ATH_CAP(vap, ni, IEEE80211_NODE_ATH)) diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index c80ee9e..eea8dbe 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -601,8 +601,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_C_MONITOR 0x00010000 /* CAPABILITY: monitor mode */ #define IEEE80211_C_DFS 0x00020000 /* CAPABILITY: DFS/radar avail*/ #define IEEE80211_C_MBSS 0x00040000 /* CAPABILITY: MBSS available */ -#define IEEE80211_C_RATECTL 0x00080000 /* CAPABILITY: use ratectl */ -/* 0x700000 available */ +/* 0x7c0000 available */ #define IEEE80211_C_WPA1 0x00800000 /* CAPABILITY: WPA1 avail */ #define IEEE80211_C_WPA2 0x01000000 /* CAPABILITY: WPA2 avail */ #define IEEE80211_C_WPA 0x01800000 /* CAPABILITY: WPA1+WPA2 avail*/ diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index f18236f..6d38388 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -178,16 +178,16 @@ arptimer(void *arg) LLE_REMREF(lle); (void) llentry_free(lle); ARPSTAT_INC(timeouts); - } + } else { #ifdef DIAGNOSTIC - else { struct sockaddr *l3addr = L3_ADDR(lle); log(LOG_INFO, "arptimer issue: %p, IPv4 address: \"%s\"\n", lle, inet_ntoa( ((const struct sockaddr_in *)l3addr)->sin_addr)); - } #endif + LLE_WUNLOCK(lle); + } } IF_AFDATA_UNLOCK(ifp); CURVNET_RESTORE(); diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c index 226965d..876e958 100644 --- a/sys/netinet/libalias/alias.c +++ b/sys/netinet/libalias/alias.c @@ -1665,7 +1665,6 @@ LibAliasRefreshModules(void) if (buf[i] == '#') continue; buf[len - 1] = '\0'; - printf("Loading %s\n", buf); LibAliasLoadModule(buf); } } diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 8dffd4d..e30f12b 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -3115,6 +3115,10 @@ process_chunk_drop(struct sctp_tcb *stcb, struct sctp_chunk_desc *desc, if ((tp1) && (tp1->sent < SCTP_DATAGRAM_ACKED)) { uint8_t *ddp; + if (((flg & SCTP_BADCRC) == 0) && + ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) { + return (0); + } if ((stcb->asoc.peers_rwnd == 0) && ((flg & SCTP_FROM_MIDDLE_BOX) == 0)) { SCTP_STAT_INCR(sctps_pdrpdiwnp); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index fb39917..1e68399 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -9927,7 +9927,7 @@ sctp_send_sack(struct sctp_tcb *stcb) caddr_t limit; uint32_t *dup; int limit_reached = 0; - unsigned int i, sel_start, siz, j, starting_index; + unsigned int i, sel_start, siz, j; unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space; int num_dups = 0; int space_req; @@ -9954,7 +9954,7 @@ sctp_send_sack(struct sctp_tcb *stcb) if (chk->rec.chunk_id.id == type) { /* Hmm, found a sack already on queue, remove it */ TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next); - asoc->ctrl_queue_cnt++; + asoc->ctrl_queue_cnt--; a_chk = chk; if (a_chk->data) { sctp_m_freem(a_chk->data); @@ -9993,15 +9993,13 @@ sctp_send_sack(struct sctp_tcb *stcb) a_chk->whoTo = NULL; if ((asoc->numduptsns) || - (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE) - ) { + (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) { /*- * Ok, we have some duplicates or the destination for the * sack is unreachable, lets see if we can select an * alternate than asoc->last_data_chunk_from */ - if ((!(asoc->last_data_chunk_from->dest_state & - SCTP_ADDR_NOT_REACHABLE)) && + if ((!(asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)) && (asoc->used_alt_onsack > asoc->numnets)) { /* We used an alt last time, don't this time */ a_chk->whoTo = NULL; @@ -10120,53 +10118,25 @@ sctp_send_sack(struct sctp_tcb *stcb) } } - if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) { - offset = 1; - /*- - * The base TSN is intialized to be the first TSN the peer - * will send us. If the cum-ack is behind this then when they - * send us the next in sequence it will mark the base_tsn bit. - * Thus we need to use the very first selector and the offset - * is 1. Our table is built for this case. - */ - starting_index = 0; + if (((type == SCTP_SELECTIVE_ACK) && + (((asoc->mapping_array[0] | asoc->nr_mapping_array[0]) & 0x01) == 0x00)) || + ((type == SCTP_NR_SELECTIVE_ACK) && + ((asoc->mapping_array[0] & 0x01) == 0x00))) { sel_start = 0; } else { - /*- - * we skip the first selector when the cum-ack is at or above the - * mapping array base. This is because the bits at the base or above - * are turned on and our first selector in the table assumes they are - * off. We thus will use the second selector (first is 0). We use - * the reverse of our macro to fix the offset, in bits, that our - * table is at. Note that this method assumes that the cum-tsn is - * within the first bit, i.e. its value is 0-7 which means the - * result to our offset will be either a 0 - -7. If the cumack - * is NOT in the first byte (0) (which it should be since we did - * a mapping array slide above) then we need to calculate the starting - * index i.e. which byte of the mapping array we should start at. We - * do this by dividing by 8 and pushing the remainder (mod) into offset. - * then we multiply the offset to be negative, since we need a negative - * offset into the selector table. - */ - SCTP_CALC_TSN_TO_GAP(offset, asoc->cumulative_tsn, asoc->mapping_array_base_tsn); - if (offset > 7) { - starting_index = offset / 8; - offset = offset % 8; - printf("Strange starting index is %d offset:%d (not 0/x)\n", - starting_index, offset); - } else { - starting_index = 0; - } - /* We need a negative offset in our table */ - offset *= -1; sel_start = 1; } + if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) { + offset = 1; + } else { + offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn; + } if (((type == SCTP_SELECTIVE_ACK) && compare_with_wrap(highest_tsn, asoc->cumulative_tsn, MAX_TSN)) || ((type == SCTP_NR_SELECTIVE_ACK) && compare_with_wrap(asoc->highest_tsn_inside_map, asoc->cumulative_tsn, MAX_TSN))) { /* we have a gap .. maybe */ - for (i = starting_index; i < siz; i++) { + for (i = 0; i < siz; i++) { if (type == SCTP_SELECTIVE_ACK) { selector = &sack_array[asoc->mapping_array[i] | asoc->nr_mapping_array[i]]; } else { @@ -10224,25 +10194,21 @@ sctp_send_sack(struct sctp_tcb *stcb) mergeable = 0; - if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn) + if (asoc->highest_tsn_inside_nr_map > asoc->mapping_array_base_tsn) { siz = (((asoc->highest_tsn_inside_nr_map - asoc->mapping_array_base_tsn) + 1) + 7) / 8; - else + } else { siz = (((MAX_TSN - asoc->mapping_array_base_tsn) + 1) + asoc->highest_tsn_inside_nr_map + 7) / 8; + } + if ((asoc->nr_mapping_array[0] & 0x01) == 0x00) { + sel_start = 0; + } else { + sel_start = 1; + } if (compare_with_wrap(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, MAX_TSN)) { offset = 1; - /*- - * cum-ack behind the mapping array, so we start and use all - * entries. - */ - sel_start = 0; } else { offset = asoc->mapping_array_base_tsn - asoc->cumulative_tsn; - /*- - * we skip the first one when the cum-ack is at or above the - * mapping array base. Note this only works if - */ - sel_start = 1; } if (compare_with_wrap(asoc->highest_tsn_inside_nr_map, asoc->cumulative_tsn, MAX_TSN)) { /* we have a gap .. maybe */ diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 4a3876f..2b9131f 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -3252,7 +3252,7 @@ again: nfhp->fh_fsid = nvp->v_mount->mnt_stat.f_fsid; if ((error1 = VOP_VPTOFH(nvp, &nfhp->fh_fid)) == 0) error1 = VOP_GETATTR(nvp, vap, cred); - if (vp == nvp) + if (!usevget && vp == nvp) vunref(nvp); else vput(nvp); diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index e01ef68..942aa45 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -2340,11 +2340,15 @@ void spinlock_enter(void) { struct thread *td; + register_t flags; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_flags = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + flags = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_flags = flags; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -2352,12 +2356,14 @@ void spinlock_exit(void) { struct thread *td; + register_t flags; td = curthread; critical_exit(); + flags = td->td_md.md_saved_flags; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_flags); + intr_restore(flags); } #if defined(I586_CPU) && !defined(NO_F00F_HACK) diff --git a/sys/pci/if_rlreg.h b/sys/pci/if_rlreg.h index 7d2c7e4..0b29474 100644 --- a/sys/pci/if_rlreg.h +++ b/sys/pci/if_rlreg.h @@ -723,19 +723,16 @@ struct rl_desc { * Statistics counter structure (8139C+ and 8169 only) */ struct rl_stats { - uint32_t rl_tx_pkts_lo; - uint32_t rl_tx_pkts_hi; - uint32_t rl_tx_errs_lo; - uint32_t rl_tx_errs_hi; - uint32_t rl_tx_errs; + uint64_t rl_tx_pkts; + uint64_t rl_rx_pkts; + uint64_t rl_tx_errs; + uint32_t rl_rx_errs; uint16_t rl_missed_pkts; uint16_t rl_rx_framealign_errs; uint32_t rl_tx_onecoll; uint32_t rl_tx_multicolls; - uint32_t rl_rx_ucasts_hi; - uint32_t rl_rx_ucasts_lo; - uint32_t rl_rx_bcasts_lo; - uint32_t rl_rx_bcasts_hi; + uint64_t rl_rx_ucasts; + uint64_t rl_rx_bcasts; uint32_t rl_rx_mcasts; uint16_t rl_tx_aborts; uint16_t rl_rx_underruns; @@ -769,6 +766,7 @@ struct rl_stats { #define RL_NTXSEGS 32 #define RL_RING_ALIGN 256 +#define RL_DUMP_ALIGN 64 #define RL_IFQ_MAXLEN 512 #define RL_TX_DESC_NXT(sc,x) ((x + 1) & ((sc)->rl_ldata.rl_tx_desc_cnt - 1)) #define RL_TX_DESC_PRV(sc,x) ((x - 1) & ((sc)->rl_ldata.rl_tx_desc_cnt - 1)) diff --git a/sys/powerpc/aim/copyinout.c b/sys/powerpc/aim/copyinout.c index 15623ed..3592691 100644 --- a/sys/powerpc/aim/copyinout.c +++ b/sys/powerpc/aim/copyinout.c @@ -102,11 +102,12 @@ set_user_sr(pmap_t pm, const void *addr) if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == slbv) return; - __asm __volatile ("isync; slbie %0; slbmte %1, %2; isync" :: - "r"(USER_ADDR), "r"(slbv), "r"(USER_SLB_SLBE)); + __asm __volatile("isync"); curthread->td_pcb->pcb_cpu.aim.usr_segm = (uintptr_t)addr >> ADDR_SR_SHFT; curthread->td_pcb->pcb_cpu.aim.usr_vsid = slbv; + __asm __volatile ("slbie %0; slbmte %1, %2; isync" :: + "r"(USER_ADDR), "r"(slbv), "r"(USER_SLB_SLBE)); } #else static __inline void @@ -116,14 +117,16 @@ set_user_sr(pmap_t pm, const void *addr) vsid = va_to_vsid(pm, (vm_offset_t)addr); + /* Mark segment no-execute */ + vsid |= SR_N; + /* If we have already set this VSID, we can just return */ if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == vsid) return; - /* Mark segment no-execute */ - vsid |= SR_N; - __asm __volatile("isync"); + curthread->td_pcb->pcb_cpu.aim.usr_segm = + (uintptr_t)addr >> ADDR_SR_SHFT; curthread->td_pcb->pcb_cpu.aim.usr_vsid = vsid; __asm __volatile("mtsr %0,%1; isync" :: "n"(USER_SR), "r"(vsid)); } diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 9dec1f7..0331b50 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -751,11 +751,15 @@ void spinlock_enter(void) { struct thread *td; + register_t msr; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_msr = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + msr = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_msr = msr; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -763,12 +767,14 @@ void spinlock_exit(void) { struct thread *td; + register_t msr; td = curthread; critical_exit(); + msr = td->td_md.md_saved_msr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_msr); + intr_restore(msr); } /* diff --git a/sys/powerpc/aim/swtch32.S b/sys/powerpc/aim/swtch32.S index 3b608f8..cd141aa 100644 --- a/sys/powerpc/aim/swtch32.S +++ b/sys/powerpc/aim/swtch32.S @@ -88,8 +88,6 @@ ENTRY(cpu_switch) stw %r16,PCB_CR(%r6) mflr %r16 /* Save the link register */ stw %r16,PCB_LR(%r6) - mfsr %r16,USER_SR /* Save USER_SR for copyin/out */ - stw %r16,PCB_AIM_USR_VSID(%r6) stw %r1,PCB_SP(%r6) /* Save the stack pointer */ stw %r2,PCB_TOC(%r6) /* Save the TOC pointer */ diff --git a/sys/powerpc/aim/swtch64.S b/sys/powerpc/aim/swtch64.S index f1af24e..dd76e0a 100644 --- a/sys/powerpc/aim/swtch64.S +++ b/sys/powerpc/aim/swtch64.S @@ -110,11 +110,6 @@ ENTRY(cpu_switch) std %r1,PCB_SP(%r6) /* Save the stack pointer */ std %r2,PCB_TOC(%r6) /* Save the TOC pointer */ - li %r15,0 /* Save user segment for copyin/out */ - li %r16,USER_SLB_SLOT - slbmfev %r15, %r16 - std %r15,PCB_AIM_USR_VSID(%r6) - mr %r14,%r3 /* Copy the old thread ptr... */ mr %r15,%r4 /* and the new thread ptr in scratch */ mr %r16,%r5 /* and the new lock */ diff --git a/sys/powerpc/aim/trap.c b/sys/powerpc/aim/trap.c index 22f55a7..fe2f795 100644 --- a/sys/powerpc/aim/trap.c +++ b/sys/powerpc/aim/trap.c @@ -455,6 +455,15 @@ syscall(struct trapframe *frame) td = PCPU_GET(curthread); td->td_frame = frame; +#ifdef __powerpc64__ + /* + * Speculatively restore last user SLB segment, which we know is + * invalid already, since we are likely to do copyin()/copyout(). + */ + __asm __volatile ("slbmte %0, %1; isync" :: + "r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE)); +#endif + error = syscallenter(td, &sa); syscallret(td, error, &sa); } @@ -532,13 +541,7 @@ trap_pfault(struct trapframe *frame, int user) map = &p->p_vmspace->vm_map; - #ifdef __powerpc64__ user_sr = td->td_pcb->pcb_cpu.aim.usr_segm; - #else - __asm ("mfsr %0, %1" - : "=r"(user_sr) - : "K"(USER_SR)); - #endif eva &= ADDR_PIDX | ADDR_POFF; eva |= user_sr << ADDR_SR_SHFT; } else { diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index c4b80cc..d216292 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -516,11 +516,15 @@ void spinlock_enter(void) { struct thread *td; + register_t msr; td = curthread; - if (td->td_md.md_spinlock_count == 0) - td->td_md.md_saved_msr = intr_disable(); - td->td_md.md_spinlock_count++; + if (td->td_md.md_spinlock_count == 0) { + msr = intr_disable(); + td->td_md.md_spinlock_count = 1; + td->td_md.md_saved_msr = msr; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -528,12 +532,14 @@ void spinlock_exit(void) { struct thread *td; + register_t msr; td = curthread; critical_exit(); + msr = td->td_md.md_saved_msr; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - intr_restore(td->td_md.md_saved_msr); + intr_restore(msr); } /* Shutdown the CPU as much as possible. */ diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 82643ab..0a40bad 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -224,9 +224,10 @@ spinlock_enter(void) if (td->td_md.md_spinlock_count == 0) { pil = rdpr(pil); wrpr(pil, 0, PIL_TICK); + td->td_md.md_spinlock_count = 1; td->td_md.md_saved_pil = pil; - } - td->td_md.md_spinlock_count++; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -234,12 +235,14 @@ void spinlock_exit(void) { struct thread *td; + register_t pil; td = curthread; critical_exit(); + pil = td->td_md.md_saved_pil; td->td_md.md_spinlock_count--; if (td->td_md.md_spinlock_count == 0) - wrpr(pil, td->td_md.md_saved_pil, 0); + wrpr(pil, pil, 0); } static phandle_t diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index d12e110..e56c094 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -1960,8 +1960,12 @@ pmap_is_modified(vm_page_t m) boolean_t pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr) { + boolean_t rv; - return (FALSE); + PMAP_LOCK(pmap); + rv = tsb_tte_lookup(pmap, addr) == NULL; + PMAP_UNLOCK(pmap); + return (rv); } /* diff --git a/sys/sun4v/sun4v/machdep.c b/sys/sun4v/sun4v/machdep.c index 3a80bee..43496e3 100644 --- a/sys/sun4v/sun4v/machdep.c +++ b/sys/sun4v/sun4v/machdep.c @@ -269,9 +269,10 @@ spinlock_enter(void) td = curthread; if (td->td_md.md_spinlock_count == 0) { pil = intr_disable(); + td->td_md.md_spinlock_count = 1; td->td_md.md_saved_pil = pil; - } - td->td_md.md_spinlock_count++; + } else + td->td_md.md_spinlock_count++; critical_enter(); } @@ -279,14 +280,14 @@ void spinlock_exit(void) { struct thread *td; + register_t pil; td = curthread; critical_exit(); + pil = td->td_md.md_saved_pil; td->td_md.md_spinlock_count--; - if (td->td_md.md_spinlock_count == 0) { - intr_restore(td->td_md.md_saved_pil); - } - + if (td->td_md.md_spinlock_count == 0) + intr_restore(pil); } unsigned diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h index c1df1c7..5c2f578 100644 --- a/sys/sys/interrupt.h +++ b/sys/sys/interrupt.h @@ -146,7 +146,6 @@ struct proc; extern struct intr_event *tty_intr_event; extern struct intr_event *clk_intr_event; -extern void *softclock_ih; extern void *vm_ih; /* Counts and names for statistics (defined in MD code). */ diff --git a/sys/teken/sequences b/sys/teken/sequences index cf720b0..a8ee528 100644 --- a/sys/teken/sequences +++ b/sys/teken/sequences @@ -106,6 +106,7 @@ C25ADFG Cons25 set adapter foreground ^[ [ = F r C25BLPD Cons25 set bell pitch duration ^[ [ = B r r C25CURS Cons25 set cursor type ^[ [ = S r C25MODE Cons25 set terminal mode ^[ [ = T r +C25SGR Cons25 set graphic rendition ^[ [ x r r C25VTSW Cons25 switch virtual terminal ^[ [ z r # VT52 compatibility diff --git a/sys/teken/teken_subr_compat.h b/sys/teken/teken_subr_compat.h index e937298..a79cdfb 100644 --- a/sys/teken/teken_subr_compat.h +++ b/sys/teken/teken_subr_compat.h @@ -88,6 +88,20 @@ teken_subr_cons25_set_bell_pitch_duration(teken_t *t, unsigned int pitch, } static void +teken_subr_cons25_set_graphic_rendition(teken_t *t, unsigned int cmd, + unsigned int param __unused) +{ + + switch (cmd) { + case 0: /* Reset. */ + t->t_curattr = t->t_defattr; + break; + default: + teken_printf("unsupported attribute %u\n", cmd); + } +} + +static void teken_subr_cons25_set_terminal_mode(teken_t *t, unsigned int mode) { diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 43e3703..1c0ef0f 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -930,15 +930,32 @@ startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait) { uma_keg_t keg; uma_slab_t tmps; + int pages, check_pages; keg = zone_first_keg(zone); + pages = howmany(bytes, PAGE_SIZE); + check_pages = pages - 1; + KASSERT(pages > 0, ("startup_alloc can't reserve 0 pages\n")); /* * Check our small startup cache to see if it has pages remaining. */ mtx_lock(&uma_boot_pages_mtx); - if ((tmps = LIST_FIRST(&uma_boot_pages)) != NULL) { - LIST_REMOVE(tmps, us_link); + + /* First check if we have enough room. */ + tmps = LIST_FIRST(&uma_boot_pages); + while (tmps != NULL && check_pages-- > 0) + tmps = LIST_NEXT(tmps, us_link); + if (tmps != NULL) { + /* + * It's ok to lose tmps references. The last one will + * have tmps->us_data pointing to the start address of + * "pages" contiguous pages of memory. + */ + while (pages-- > 0) { + tmps = LIST_FIRST(&uma_boot_pages); + LIST_REMOVE(tmps, us_link); + } mtx_unlock(&uma_boot_pages_mtx); *pflag = tmps->us_flags; return (tmps->us_data); @@ -950,7 +967,7 @@ startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait) * Now that we've booted reset these users to their real allocator. */ #ifdef UMA_MD_SMALL_ALLOC - keg->uk_allocf = uma_small_alloc; + keg->uk_allocf = (keg->uk_ppera > 1) ? page_alloc : uma_small_alloc; #else keg->uk_allocf = page_alloc; #endif @@ -1177,12 +1194,15 @@ keg_large_init(uma_keg_t keg) keg->uk_ppera = pages; keg->uk_ipers = 1; + keg->uk_rsize = keg->uk_size; + + /* We can't do OFFPAGE if we're internal, bail out here. */ + if (keg->uk_flags & UMA_ZFLAG_INTERNAL) + return; keg->uk_flags |= UMA_ZONE_OFFPAGE; if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0) keg->uk_flags |= UMA_ZONE_HASH; - - keg->uk_rsize = keg->uk_size; } static void @@ -1301,7 +1321,8 @@ keg_ctor(void *mem, int size, void *udata, int flags) #endif if (booted == 0) keg->uk_allocf = startup_alloc; - } + } else if (booted == 0 && (keg->uk_flags & UMA_ZFLAG_INTERNAL)) + keg->uk_allocf = startup_alloc; /* * Initialize keg's lock (shared among zones). @@ -1330,7 +1351,7 @@ keg_ctor(void *mem, int size, void *udata, int flags) if (totsize & UMA_ALIGN_PTR) totsize = (totsize & ~UMA_ALIGN_PTR) + (UMA_ALIGN_PTR + 1); - keg->uk_pgoff = UMA_SLAB_SIZE - totsize; + keg->uk_pgoff = (UMA_SLAB_SIZE * keg->uk_ppera) - totsize; if (keg->uk_flags & UMA_ZONE_REFCNT) totsize = keg->uk_pgoff + sizeof(struct uma_slab_refcnt) @@ -1346,7 +1367,7 @@ keg_ctor(void *mem, int size, void *udata, int flags) * mathematically possible for all cases, so we make * sure here anyway. */ - if (totsize > UMA_SLAB_SIZE) { + if (totsize > UMA_SLAB_SIZE * keg->uk_ppera) { printf("zone %s ipers %d rsize %d size %d\n", zone->uz_name, keg->uk_ipers, keg->uk_rsize, keg->uk_size); diff --git a/sys/x86/x86/nexus.c b/sys/x86/x86/nexus.c index c343730..8ed2c35 100644 --- a/sys/x86/x86/nexus.c +++ b/sys/x86/x86/nexus.c @@ -674,7 +674,7 @@ ram_attach(device_t dev) vm_paddr_t *p; caddr_t kmdp; uint32_t smapsize; - int error, i, rid; + int error, rid; /* Retrieve the system memory map from the loader. */ kmdp = preload_search_by_type("elf kernel"); @@ -694,15 +694,24 @@ ram_attach(device_t dev) if (smap->type != SMAP_TYPE_MEMORY || smap->length == 0) continue; +#ifdef __i386__ + /* + * Resources use long's to track resources, so + * we can't include memory regions above 4GB. + */ + if (smap->base > ~0ul) + continue; +#endif error = bus_set_resource(dev, SYS_RES_MEMORY, rid, smap->base, smap->length); if (error) - panic("ram_attach: resource %d failed set with %d", + panic( + "ram_attach: resource %d failed set with %d", rid, error); res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); if (res == NULL) - panic("ram_attach: resource %d failed to attach", + panic("ram_attach: resource %d failed to attach", rid); rid++; } @@ -710,34 +719,31 @@ ram_attach(device_t dev) } /* - * We use the dump_avail[] array rather than phys_avail[] for - * the memory map as phys_avail[] contains holes for kernel - * memory, page 0, the message buffer, and the dcons buffer. - * We test the end address in the loop instead of the start - * since the start address for the first segment is 0. - * - * XXX: It would be preferable to use the SMAP if it exists - * instead since if the SMAP is very fragmented we may not - * include some memory regions in dump_avail[] and phys_avail[]. + * If the system map is not available, fall back to using + * dump_avail[]. We use the dump_avail[] array rather than + * phys_avail[] for the memory map as phys_avail[] contains + * holes for kernel memory, page 0, the message buffer, and + * the dcons buffer. We test the end address in the loop + * instead of the start since the start address for the first + * segment is 0. */ - for (i = 0, p = dump_avail; p[1] != 0; i++, p += 2) { - rid = i; + for (rid = 0, p = dump_avail; p[1] != 0; rid++, p += 2) { #ifdef PAE /* * Resources use long's to track resources, so we can't * include memory regions above 4GB. */ - if (p[0] >= ~0ul) + if (p[0] > ~0ul) break; #endif error = bus_set_resource(dev, SYS_RES_MEMORY, rid, p[0], p[1] - p[0]); if (error) - panic("ram_attach: resource %d failed set with %d", i, + panic("ram_attach: resource %d failed set with %d", rid, error); res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0); if (res == NULL) - panic("ram_attach: resource %d failed to attach", i); + panic("ram_attach: resource %d failed to attach", rid); } return (0); } |