pppac(4): destroy sessions the same way as pppx(4) does
We destroy pppx(4) related sessions while we performing PIPEXDSESSION command. But with pppac(4) we set session's state to PIPEX_STATE_CLOSE_WAIT2 and we wait garbage collector to do destruction. We removed `pipex{in,out}q'. So we can safe destroy session in any time. I propose to make pppac(4) session destruction path the same as pppx(4) does. Now we destroy them while performing PIPEXDSESSION commad too. Also there is no in-kernel garbage collector for pppac(4) sessions. yasuoka@ pointed me that npppd(8) should kill expired sessions. This not only makes pppac(4) closer to pppx(4) but simplify code and allow us to make safe pppx(4) session processing by pipex_timer(). So this is preparation step to restore in-kernel timeout for pppx(4) too. Index: sys/net/pipex.c === RCS file: /cvs/src/sys/net/pipex.c,v retrieving revision 1.124 diff -u -p -r1.124 pipex.c --- sys/net/pipex.c 12 Aug 2020 08:41:39 - 1.124 +++ sys/net/pipex.c 12 Aug 2020 09:07:12 - @@ -536,29 +536,6 @@ out: return error; } -int -pipex_notify_close_session(struct pipex_session *session) -{ - NET_ASSERT_LOCKED(); - session->state = PIPEX_STATE_CLOSE_WAIT; - session->stat.idle_time = 0; - LIST_INSERT_HEAD(_close_wait_list, session, state_list); - - return (0); -} - -int -pipex_notify_close_session_all(void) -{ - struct pipex_session *session; - - NET_ASSERT_LOCKED(); - LIST_FOREACH(session, _session_list, session_list) - if (session->state == PIPEX_STATE_OPENED) - pipex_notify_close_session(session); - return (0); -} - Static int pipex_close_session(struct pipex_session_close_req *req, struct pipex_iface_context *iface) @@ -573,13 +550,9 @@ pipex_close_session(struct pipex_session if (session->pipex_iface != iface) return (EINVAL); - /* remove from close_wait list */ - if (session->state == PIPEX_STATE_CLOSE_WAIT) - LIST_REMOVE(session, state_list); - /* get statistics before destroy the session */ req->pcr_stat = session->stat; - session->state = PIPEX_STATE_CLOSED; + pipex_destroy_session(session); return (0); } @@ -739,47 +712,25 @@ pipex_timer_stop(void) Static void pipex_timer(void *ignored_arg) { - struct pipex_session *session, *session_tmp; + struct pipex_session *session; timeout_add_sec(_timer_ch, pipex_prune); NET_LOCK(); /* walk through */ - LIST_FOREACH_SAFE(session, _session_list, session_list, - session_tmp) { - switch (session->state) { - case PIPEX_STATE_OPENED: - if (session->timeout_sec == 0) - continue; - - session->stat.idle_time++; - if (session->stat.idle_time < session->timeout_sec) - continue; - - pipex_notify_close_session(session); - break; - - case PIPEX_STATE_CLOSE_WAIT: - case PIPEX_STATE_CLOSE_WAIT2: - /* Wait PIPEXDSESSION from userland */ - session->stat.idle_time++; - if (session->stat.idle_time < PIPEX_CLOSE_TIMEOUT) - continue; - - if (session->state == PIPEX_STATE_CLOSE_WAIT) - LIST_REMOVE(session, state_list); - session->state = PIPEX_STATE_CLOSED; - /* FALLTHROUGH */ + LIST_FOREACH(session, _session_list, session_list) { + if (session->state != PIPEX_STATE_OPENED) + continue; + if (session->timeout_sec == 0) + continue; - case PIPEX_STATE_CLOSED: - pipex_destroy_session(session); - break; + session->stat.idle_time++; + if (session->stat.idle_time < session->timeout_sec) + continue; - default: - break; - } + session->state = PIPEX_STATE_CLOSE_WAIT; + LIST_INSERT_HEAD(_close_wait_list, session, state_list); } - NET_UNLOCK(); } Index: sys/net/pipex.h === RCS file: /cvs/src/sys/net/pipex.h,v retrieving revision 1.27 diff -u -p -r1.27 pipex.h --- sys/net/pipex.h 4 Aug 2020 09:32:05 - 1.27 +++ sys/net/pipex.h 12 Aug 2020 09:07:13 - @@ -197,9 +197,6 @@ void pipex_init (void); void pipex_iface_init (struct pipex_iface_context *, u_int); void pipex_iface_fini (struct pipex_iface_context *); -int
Re: wireguard listen in other rdomain?
On Tue, Aug 11, 2020 at 05:46:05PM -0500, Abel Abraham Camarillo Ojeda wrote: > Hi to all, > > (unsure if this if for tech@ or misc@) > > I'm using wireguard interfaces but I see that no matter what > domain I put the interface: > > # ifconfig wg0 rdomain X > > It always listens in rdomain 0 (default), > is this expected?, is there any way to listen in another rdomain? > I want to expose several wg interfaces all listening in same port but > there's not option to listen in another ip address: > > wgport port > Set the UDP port that the tunnel operates on. The interface > will > bind to INADDR_ANY and IN6ADDR_ANY_INIT. If no port is > configured, one will be chosen automatically. > > I tried creating several wg interfaces with different wgport and using > pf udp redirections but source address selection gets very messy... > > Ideas? Did you try 'ifconfig wg0 wgrtable X' already?
Re: pppx(4): move ifnet out of KERNEL_LOCK()
Updated to the recent source. The diff is OK'ed by yasuoka@. Also I did what mpi@ requested. Should I still wait? Index: sys/net/if_pppx.c === RCS file: /cvs/src/sys/net/if_pppx.c,v retrieving revision 1.100 diff -u -p -r1.100 if_pppx.c --- sys/net/if_pppx.c 12 Aug 2020 08:41:39 - 1.100 +++ sys/net/if_pppx.c 12 Aug 2020 11:08:12 - @@ -191,7 +191,7 @@ int pppx_set_session_descr(struct pppx_ struct pipex_session_descr_req *); void pppx_if_destroy(struct pppx_dev *, struct pppx_if *); -void pppx_if_start(struct ifnet *); +void pppx_if_qstart(struct ifqueue *); intpppx_if_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); intpppx_if_ioctl(struct ifnet *, u_long, caddr_t); @@ -683,13 +683,12 @@ pppx_add_session(struct pppx_dev *pxd, s snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d", "pppx", unit); ifp->if_mtu = req->pr_peer_mru; /* XXX */ ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST | IFF_UP; - ifp->if_xflags = IFXF_CLONED; - ifp->if_start = pppx_if_start; + ifp->if_xflags = IFXF_CLONED | IFXF_MPSAFE; + ifp->if_qstart = pppx_if_qstart; ifp->if_output = pppx_if_output; ifp->if_ioctl = pppx_if_ioctl; ifp->if_rtrequest = p2p_rtrequest; ifp->if_type = IFT_PPP; - ifq_set_maxlen(>if_snd, 1); ifp->if_softc = pxi; /* ifp->if_rdomain = req->pr_rdomain; */ @@ -864,26 +863,21 @@ pppx_if_destroy(struct pppx_dev *pxd, st } void -pppx_if_start(struct ifnet *ifp) +pppx_if_qstart(struct ifqueue *ifq) { + struct ifnet *ifp = ifq->ifq_if; struct pppx_if *pxi = (struct pppx_if *)ifp->if_softc; struct mbuf *m; int proto; - if (!ISSET(ifp->if_flags, IFF_RUNNING)) - return; - - for (;;) { - m = ifq_dequeue(>if_snd); - - if (m == NULL) - break; - + NET_LOCK(); + while ((m = ifq_dequeue(ifq)) != NULL) { proto = *mtod(m, int *); m_adj(m, sizeof(proto)); pipex_ppp_output(m, pxi->pxi_session, proto); } + NET_UNLOCK(); } int
Re: pipex "idle-timeout" work with pppx(4).
On Wed, Aug 12, 2020 at 11:17:29AM +0900, YASUOKA Masahiko wrote: > On Tue, 11 Aug 2020 23:06:45 +0300 > Vitaliy Makkoveev wrote: > > We removed `pipex{in,out}q'. So now we can destroy pppac(4) session just > > like we do in pppx(4) case. Also there is no reason to allow > > pipex_timer() to destroy sessions - userland will do this by > > PIPEXDSESSION. This permit us to use existing pipex_get_closed() for > > both pppac(4) and pppx(4) without any modifications. > > > > So, I propose pipex_close_session() and pipex_timer() be like below. > > It doesn't seem to fix "idle-timeout". > Yes it's not. It's "pre-" step which makes following fix easier. We don't need to mark pppx(4) sessions because there is no special cases for them. We just need to kill pppx(4) related "pr_timeout_sec != 0" checks and call pipex_get_closed() by pppx_get_closed(). > > We simplify pppac(4) session destruction. We unify behavior with pppx(4) > > - we killing session just now. There is no reason to modify > > pipex_get_closed() and pipex_link_session(). pppx(4) related sessions > > can be processed by pipex_timer(). There is no performance impact. > > We need to modify pppx_get_closed() to implement idle-timeout. > > > Do you like this? We can do two diffs. The first to unify destruction > > and the second to re-enable in-kernel timeout for pppx(4) and revert man > > pages modifications. > > I have no objection to your "unify destruction". > > I'll rebase my diff after that work. Thanks. I posted "unify destruction" here [1]. 1. https://marc.info/?l=openbsd-tech=159722447900893=2
Re: ldapd: adding bsd.schema
On 8/2/20 9:34 AM, Aisha Tammy wrote: > On 7/26/20 5:25 PM, Aisha Tammy wrote: >> On 7/26/20 5:21 PM, Aisha Tammy wrote: >>> Hi, >>> Am reviving an old thread from >>> https://marc.info/?l=openbsd-tech=152663835315469=4 >>> (i did cc reyk@ sorry if it is noise) >>> >>> For some reason seems like the patch didn't go through... >>> >>> I am reattaching it here, maybe someone can take a look and >>> see if it can be merged ? >>> Getting sshPublicKey would be really nice! >>> >>> Aisha >>> >> >> >> reattaching it because thunderbird >> > > Bump, can anyone see if this is fine ? > > Thanks, > Aisha > Another bump. Aisha
Re: ldapd: adding bsd.schema
On Tue, Aug 11, 2020 at 10:22:51PM -0400, Aisha Tammy wrote: > Another bump. I think this is useful and am ok with this. Are there any concerns? If not, I'm going to commit it tomorrow. Index: etc/examples/ldapd.conf === RCS file: /cvs/src/etc/examples/ldapd.conf,v retrieving revision 1.1 diff -u -p -u -p -r1.1 ldapd.conf --- etc/examples/ldapd.conf 11 Jul 2014 21:20:10 - 1.1 +++ etc/examples/ldapd.conf 18 May 2018 10:09:45 - @@ -3,6 +3,7 @@ schema "/etc/ldap/core.schema" schema "/etc/ldap/inetorgperson.schema" schema "/etc/ldap/nis.schema" +schema "/etc/ldap/bsd.schema" listen on lo0 listen on "/var/run/ldapi" Index: usr.sbin/ldapd/Makefile === RCS file: /cvs/src/usr.sbin/ldapd/Makefile,v retrieving revision 1.15 diff -u -p -u -p -r1.15 Makefile --- usr.sbin/ldapd/Makefile 20 Jan 2017 11:55:08 - 1.15 +++ usr.sbin/ldapd/Makefile 18 May 2018 10:09:45 - @@ -17,7 +17,8 @@ CFLAGS+= -Wshadow -Wpointer-arith -Wcast CFLAGS+= -Wsign-compare CLEANFILES+= y.tab.h parse.c -SCHEMA_FILES= core.schema \ +SCHEMA_FILES= bsd.schema \ + core.schema \ inetorgperson.schema \ nis.schema Index: usr.sbin/ldapd/schema/bsd.schema === RCS file: usr.sbin/ldapd/schema/bsd.schema diff -N usr.sbin/ldapd/schema/bsd.schema --- /dev/null 1 Jan 1970 00:00:00 - +++ usr.sbin/ldapd/schema/bsd.schema18 May 2018 10:09:45 - @@ -0,0 +1,17 @@ +attributetype ( 1.3.6.1.4.1.30155.115.2 NAME 'shadowPassword' + DESC 'POSIX hashed password' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.30155.115.3 NAME 'sshPublicKey' + DESC 'SSH public key' + EQUALITY caseExactIA5Match + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +objectclass ( 1.3.6.1.4.1.30155.115.1 NAME 'bsdAccount' + SUP top + AUXILIARY + DESC 'Abstraction of an account with OpenBSD attributes' + MUST ( uid ) + MAY ( shadowPassword $ shadowExpire $ modifyTimestamp $ userClass $ + sshPublicKey ))
Re: pipex "idle-timeout" work with pppx(4).
Hi, On Wed, 12 Aug 2020 12:38:39 +0300 Vitaliy Makkoveev wrote: > We don't need to mark pppx(4) sessions because there is no special cases > for them. We just need to kill pppx(4) related "pr_timeout_sec != 0" > checks and call pipex_get_closed() by pppx_get_closed(). How do you implement that by calling pipex_get_closed() by pppx_get_closed()? PIPEXGCLOSED is to pick up expired sessions which is associated with the character device (/dev/{pppx,pppac}0). In pppac(4) case, the character device is the same object of the interface pppac. But pppx(4) is not the same. pipex_session has no direct referece to the device. This is why my diff was modifying pipex_get_closed().
Re: pipex "idle-timeout" work with pppx(4).
On Wed, Aug 12, 2020 at 09:07:15PM +0900, YASUOKA Masahiko wrote: > Hi, > > On Wed, 12 Aug 2020 12:38:39 +0300 > Vitaliy Makkoveev wrote: > > We don't need to mark pppx(4) sessions because there is no special cases > > for them. We just need to kill pppx(4) related "pr_timeout_sec != 0" > > checks and call pipex_get_closed() by pppx_get_closed(). > > How do you implement that by calling pipex_get_closed() by > pppx_get_closed()? > > > PIPEXGCLOSED is to pick up expired sessions which is associated with > the character device (/dev/{pppx,pppac}0). In pppac(4) case, the > character device is the same object of the interface pppac. But > pppx(4) is not the same. pipex_session has no direct referece to the > device. This is why my diff was modifying pipex_get_closed(). > You are right. I have my own tree where I divided pppx(4) sessions and iface_context. So in my tree I have one `pipex_iface_context' in `struct pppx_dev' and the usage of most pppx(4) is identical to pppac(4). Sorry, I forgot that it's not shared yet :( You are right, pppx_get_closed() still needs to do it's own `pipex_close_wait_list' walkthrough.
Re: ldapd: adding bsd.schema
Hi, On Wed, 12 Aug 2020 09:00:18 +0200 Theo Buehler wrote: > On Tue, Aug 11, 2020 at 10:22:51PM -0400, Aisha Tammy wrote: > > Another bump. > > I think this is useful and am ok with this. > > Are there any concerns? If not, I'm going to commit it tomorrow. for an sshPublicKey attribute, there's a “openssh-lpk” schema which seems to be in common use. It's defined as # octetString SYNTAX attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' DESC 'OpenSSH Public key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) # printableString SYNTAX yes|no objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY DESC 'OpenSSH LPK objectclass' MUST uid MAY sshPublicKey ) though there are versions of the “ldapPublicKey” definitions with both uid and sshPublicKye in the MUST and both in the MAY clause. The “both MAY” version is imho more flexible. The original mail proposing bsd.schema seems to have added both “shadowPassword” and “bsdaccount” more as an afterthought, it seems. Best regards Robert > > Index: etc/examples/ldapd.conf > === > RCS file: /cvs/src/etc/examples/ldapd.conf,v > retrieving revision 1.1 > diff -u -p -u -p -r1.1 ldapd.conf > --- etc/examples/ldapd.conf 11 Jul 2014 21:20:10 - > 1.1 +++ etc/examples/ldapd.conf 18 May 2018 10:09:45 - > @@ -3,6 +3,7 @@ > schema "/etc/ldap/core.schema" > schema "/etc/ldap/inetorgperson.schema" > schema "/etc/ldap/nis.schema" > +schema "/etc/ldap/bsd.schema" > > listen on lo0 > listen on "/var/run/ldapi" > Index: usr.sbin/ldapd/Makefile > === > RCS file: /cvs/src/usr.sbin/ldapd/Makefile,v > retrieving revision 1.15 > diff -u -p -u -p -r1.15 Makefile > --- usr.sbin/ldapd/Makefile 20 Jan 2017 11:55:08 - > 1.15 +++ usr.sbin/ldapd/Makefile 18 May 2018 10:09:45 - > @@ -17,7 +17,8 @@ CFLAGS+=-Wshadow -Wpointer-arith -Wcast > CFLAGS+= -Wsign-compare > CLEANFILES+= y.tab.h parse.c > > -SCHEMA_FILES=core.schema \ > +SCHEMA_FILES=bsd.schema \ > + core.schema \ > inetorgperson.schema \ > nis.schema > > Index: usr.sbin/ldapd/schema/bsd.schema > === > RCS file: usr.sbin/ldapd/schema/bsd.schema > diff -N usr.sbin/ldapd/schema/bsd.schema > --- /dev/null 1 Jan 1970 00:00:00 - > +++ usr.sbin/ldapd/schema/bsd.schema 18 May 2018 10:09:45 - > @@ -0,0 +1,17 @@ > +attributetype ( 1.3.6.1.4.1.30155.115.2 NAME 'shadowPassword' > + DESC 'POSIX hashed password' > + EQUALITY caseExactIA5Match > + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) > + > +attributetype ( 1.3.6.1.4.1.30155.115.3 NAME 'sshPublicKey' > + DESC 'SSH public key' > + EQUALITY caseExactIA5Match > + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) > + > +objectclass ( 1.3.6.1.4.1.30155.115.1 NAME 'bsdAccount' > + SUP top > + AUXILIARY > + DESC 'Abstraction of an account with OpenBSD attributes' > + MUST ( uid ) > + MAY ( shadowPassword $ shadowExpire $ modifyTimestamp $ > userClass $ > + sshPublicKey )) >
getitimer(2), setitimer(2): merge critical sections
Hi, Things in getitimer(2) and setitimer(2) have been rearranged adequately. Their critical sections are ready to be combined. Merging these critical sections is necessary to make getitimer(2) and setitimer(2) MP-safe. They are not ready to run without the kernel lock just yet, but this diff is a prerequisite. Everything up until now was done to make this patch less painful. So, this patch: We introduce a new kernel subroutine, "setitimer()", that does all of the common, error-free work for both getitimer(2) and setitimer(2). The high-level steps are as follows: - convert input from itimerval to itimerspec - enter the critical section - read the timer's current value - (ITIMER_REAL) do timeout_add(9)/timeout_del(9) - (ITIMER_REAL) convert input from relative to absolute time - write the timer's new value - leave the critical section - (ITIMER_REAL) convert output from absolute to relative time - convert output from itimerspec to itimerval All of this code has been moved more-or-less verbatim from sys_getitimer() and sys_setitimer() and interleaved within the new subroutine around a single critical section. Meanwhile, sys_getitimer() and sys_setitimer() are left to handle all of the error-prone work: copyin(9), input validation, and copyout(9). The changes in sys_getitimer() are straightforward. All of its common code folds neatly into the new subroutine without any changes to the surrounding code. sys_setitimer() is trickier because it doesn't use SCARG directly. I've introduced additional itimerval pointers to keep changes minimal here. However, I think it would benefit from the direct use of SCARG to distinguish userspace addresses from kernel stack addresses. That can wait until later, though. sys_setitimer() now performs its own copyout(9) instead of relying on sys_getitimer() to do it implicitly. This adds a bit of additional code but I would rather see the syscall do copyout(9) explicitly. There is one behavior change: in the setitimer(2) swap case it is now possible to EFAULT on copyout(9) *after* you have written the new timer value and (possibly) started the ITIMER_REAL timeout. For example, the following code now yields EFAULT even though a new oneshot timer has been started successfully. struct itimerval new; int error; new.it_value.tv_sec = 1; new.it_value.tv_usec = 0; timerclear(_interval); error = setitimer(ITIMER_REAL, , 0xdeadbeef); if (error) warn("setitimer"); I don't think there is a way to avoid this without introducing a bunch of extra complexity. The critical section is protected by a mutex and copyout(9) can sleep, so we have to wait until we leave the critical section to copyout(9). If we leave the mutex to do the copyout(9) before writing the new timer value then the swap is no longer atomic. Of course, this is not an issue *now*, but when the syscalls are unlocked you will lose atomicity. Personally I don't think this is a huge deal. If you're getting EFAULT there is a bigger problem in your code. Thoughts? ok? Index: kern_time.c === RCS file: /cvs/src/sys/kern/kern_time.c,v retrieving revision 1.140 diff -u -p -r1.140 kern_time.c --- kern_time.c 12 Aug 2020 15:31:27 - 1.140 +++ kern_time.c 12 Aug 2020 18:44:08 - @@ -491,7 +491,7 @@ out: struct mutex itimer_mtx = MUTEX_INITIALIZER(IPL_CLOCK); /* - * Get value of an interval timer. The process virtual and + * Get and/or set value of an interval timer. The process virtual and * profiling virtual time timers are kept internally in the * way they are specified externally: in time until they expire. * @@ -509,6 +509,63 @@ struct mutex itimer_mtx = MUTEX_INITIALI * real time timers .it_interval. Rather, we compute the next time in * absolute time the timer should go off. */ +void +setitimer(int which, struct itimerval *itv, struct itimerval *olditv) +{ + struct itimerspec its, oldits; + struct itimerspec *itimer; + struct process *pr; + int timo; + + KASSERT(which >= ITIMER_REAL && which <= ITIMER_PROF); + + pr = curproc->p_p; + itimer = >ps_timer[which]; + + if (itv != NULL) { + TIMEVAL_TO_TIMESPEC(>it_value, _value); + TIMEVAL_TO_TIMESPEC(>it_interval, _interval); + } + + if (which != ITIMER_REAL) + mtx_enter(_mtx); + + if (olditv != NULL) + oldits = *itimer; + if (itv != NULL) { + if (which == ITIMER_REAL) { + struct timespec cts; + getnanouptime(); + if (timespecisset(_value)) { + timo = tstohz(_value); + timeout_add(>ps_realit_to, timo); + timespecadd(_value, , _value); + } else +
sdmmc(4) HS200 support
This diff lays the groundwork for HS200 mode for eMMC. This mode supports data transfer modes of up to 200 MB/s. The crucial bit here is that using this mode requires tuning which is done by calling a chip-specific execute_tuning function. I have an implementation for amlmmc(4) that seems to work which I'll send in a separate diff. The diff also adds some bits to support higher speed modes for SD cards, but those aren't hooked up yet. I'll leave that for a future diff. I'll probably look into adding support for sdhc(4) in the near future as well. Don't expect enormous speed increases from this; most eMMC chips I've seen are not actually limited by the tramsfer speed. But for amlmmc(4) this makes a difference since the DDR52 mode isn't reliable. Tested on the Odroid-N2, Odroid-C4 and an amd64 netbook that uses eMMC. ok? Index: dev/sdmmc/sdhc.c === RCS file: /cvs/src/sys/dev/sdmmc/sdhc.c,v retrieving revision 1.68 diff -u -p -r1.68 sdhc.c --- dev/sdmmc/sdhc.c14 Jun 2020 18:37:16 - 1.68 +++ dev/sdmmc/sdhc.c12 Aug 2020 18:52:05 - @@ -121,26 +121,18 @@ void sdhc_dump_regs(struct sdhc_host *); #endif struct sdmmc_chip_functions sdhc_functions = { - /* host controller reset */ - sdhc_host_reset, - /* host controller capabilities */ - sdhc_host_ocr, - sdhc_host_maxblklen, - /* card detection */ - sdhc_card_detect, - /* bus power and clock frequency */ - sdhc_bus_power, - sdhc_bus_clock, - sdhc_bus_width, - /* command execution */ - sdhc_exec_command, - /* card interrupt */ - sdhc_card_intr_mask, - sdhc_card_intr_ack, - /* UHS functions */ - sdhc_signal_voltage, - /* hibernate */ - sdhc_hibernate_init, + .host_reset = sdhc_host_reset, + .host_ocr = sdhc_host_ocr, + .host_maxblklen = sdhc_host_maxblklen, + .card_detect = sdhc_card_detect, + .bus_power = sdhc_bus_power, + .bus_clock = sdhc_bus_clock, + .bus_width = sdhc_bus_width, + .exec_command = sdhc_exec_command, + .card_intr_mask = sdhc_card_intr_mask, + .card_intr_ack = sdhc_card_intr_ack, + .signal_voltage = sdhc_signal_voltage, + .hibernate_init = sdhc_hibernate_init, }; struct cfdriver sdhc_cd = { Index: dev/sdmmc/sdmmc_mem.c === RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_mem.c,v retrieving revision 1.33 diff -u -p -r1.33 sdmmc_mem.c --- dev/sdmmc/sdmmc_mem.c 4 Jun 2018 13:33:10 - 1.33 +++ dev/sdmmc/sdmmc_mem.c 12 Aug 2020 18:52:05 - @@ -70,6 +70,34 @@ int sdmmc_mem_write_block_subr(struct sd #define DPRINTF(s) /**/ #endif +const struct { + const char *name; + int v; + int freq; +} switch_group0_functions[] = { + /* Default/SDR12 */ + { "Default/SDR12", 0, 25000 }, + + /* High-Speed/SDR25 */ + { "High-Speed/SDR25", SMC_CAPS_SD_HIGHSPEED, 5 }, + + /* SDR50 */ + { "SDR50", SMC_CAPS_UHS_SDR50, 10 }, + + /* SDR104 */ + { "SDR104", SMC_CAPS_UHS_SDR104,208000 }, + + /* DDR50 */ + { "DDR50", SMC_CAPS_UHS_DDR50, 5 }, +}; + +const int sdmmc_mmc_timings[] = { + [SDMMC_TIMING_LEGACY] = 26000, + [SDMMC_TIMING_HIGHSPEED]= 52000, + [SDMMC_TIMING_MMC_DDR52]= 52000, + [SDMMC_TIMING_MMC_HS200]= 20 +}; + /* * Initialize SD/MMC memory cards and memory in SDIO "combo" cards. */ @@ -581,6 +609,41 @@ sdmmc_be512_to_bitfield512(sdmmc_bitfiel } int +sdmmc_mem_execute_tuning(struct sdmmc_softc *sc, struct sdmmc_function *sf) +{ + int timing = -1; + + if (ISSET(sc->sc_flags, SMF_SD_MODE)) { + if (!ISSET(sc->sc_flags, SMF_UHS_MODE)) + return 0; + + switch (sf->csd.tran_speed) { + case 10: + timing = SDMMC_TIMING_UHS_SDR50; + break; + case 208000: + timing = SDMMC_TIMING_UHS_SDR104; + break; + default: + return 0; + } + } else { + switch (sf->csd.tran_speed) { + case 20: + timing = SDMMC_TIMING_MMC_HS200; + break; + default: + return 0; + } + } + + DPRINTF(("%s: execute tuning for timing %d\n", SDMMCDEVNAME(sc), + timing)); + + return sdmmc_chip_execute_tuning(sc->sct, sc->sch, timing); +} + +int sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) { int support_func, best_func, error; @@ -647,6 +710,8 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc