14cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu/*
24cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * Copyright 2012, The Android Open Source Project
34cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu *
44cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * Licensed under the Apache License, Version 2.0 (the "License");
54cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * you may not use this file except in compliance with the License.
64cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * You may obtain a copy of the License at
74cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu *
84cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu *     http://www.apache.org/licenses/LICENSE-2.0
94cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu *
104cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * Unless required by applicable law or agreed to in writing, software
114cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * distributed under the License is distributed on an "AS IS" BASIS,
124cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * See the License for the specific language governing permissions and
144cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu * limitations under the License.
154cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu */
164cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
176433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsieh#include <portability.h>
184cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu#include <poll.h>
194cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu#include <poll_portable.h>
204cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
212928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney/*
222928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *_XOPEN_SOURCE added the ability to not only poll for data coming in or out
232928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * but now also the ability to poll for high priority input and output. Though
242928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * the normal priority is equivalent to the original I/O it was assigned new bits:
252928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *       POLLIN  Equivalent to POLLRDNORM
262928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *       POLLOUT Equivalent to POLLWRNORM
272928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
282928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * The Linux kernel sets both POLLIN and POLLRDNORM when data is available and sets
292928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * both POLLOUT and POLLWRNORM when data can be written; so the new priority BAND bits
302928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * just supplement the meaning of the prior POLLIN and POLLOUT bits as well as the
312928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * new POLLRDNORM and POLLWRNORM bits.
322928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
332928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * The DECNet Protocol can set the poll in  priority flag, POLLRDBAND.
342928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * ATM as well as a whole bunch of other protocols can set the poll out priority flag,
352928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * POLLWRBAND.
362928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
372928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * MIPS and SPARC likely assigned the new XOPEN poll out event flags in UNIX well before
382928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * UNIX was ported to X86.  It appears that Intel chose different bits and that was
392928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * established by Linus as the the generic case and later also chosen by ARM.
402928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
412928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *     POLLWRNORM:0x100 -  MIPS used POLLOUT:0x0004, which is equivalent in meaning.
422928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
432928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *     POLLWRBAND:0x200 -  MIPS used 0x0100. which is POLLWRNORM:0x100.
442928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
452928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * Summary:
462928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney * ========
472928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *    Both Normal and Priority flags can be mapped to MIPS flags (left to right below).
482928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *    Only the Priority poll out flag can be mapped back to portable because MIPS
492928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *    is using the same number as POLLOUT for POLLWRNORM (right to left below).
502928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
512928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *                    ARM/GENERIC/PORTABLE           MIPS
522928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *                    ====================          ======
532928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLIN          0x0001                      0x0001
542928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLPRI         0x0002                      0x0002
552928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLOUT         0x0004 <-----+              0x0004
562928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLERR         0x0008        \             0x0008
572928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLHUP         0x0010         \            0x0010
582928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLNVAL        0x0020          \           0x0020
592928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLRDNORM      0x0040           \          0x0040
602928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLRDBAND      0x0080            \         0x0080
612928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLWRNORM      0x0100  -----------+<---->  0x0004
622928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLWRBAND      0x0200 <----------------->  0x0100
632928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLMSG         0x0400                      0x0400
642928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLREMOVE      0x1000                      0x1000
652928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *      POLLRDHUP       0x2000                      0x2000
662928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *
672928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *  The loss of the high priority notice for the polling
682928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *  of output data is likely minor as it was only being used
692928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *  in DECNet. Also, the poll system call and device poll
702928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *  implementations processes POLLOUT and POLLWRNORM event
712928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney *  flags the same.
722928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney */
732928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney
744cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu#if POLLWRNORM_PORTABLE==POLLWRNORM
754cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu#error Bad build environment
764cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu#endif
774cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
784cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fustatic inline short mips_change_portable_events(short portable_events)
794cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu{
804cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    /* MIPS has different POLLWRNORM and POLLWRBAND. */
814cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    if (portable_events & POLLWRNORM_PORTABLE) {
824cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        portable_events &= ~POLLWRNORM_PORTABLE;
834cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        portable_events |= POLLWRNORM;
844cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    }
854cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    if (portable_events & POLLWRBAND_PORTABLE) {
864cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        portable_events &= ~POLLWRBAND_PORTABLE;
874cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        portable_events |= POLLWRBAND;
884cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    }
894cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
904cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    return portable_events;
914cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu}
924cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
934cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fustatic inline short change_mips_events(short mips_events)
944cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu{
952928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney    /*
962928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney     * MIPS POLLWRNORM equals MIPS POLLOUT, which is the same as POLLOUT_PORTABLE;
972928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney     * so we just map POLLWRBAND to POLLWRBAND_PORTABLE.
982928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney     */
994cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    if (mips_events & POLLWRBAND) {
1004cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        mips_events &= ~POLLWRBAND;
1014cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu        mips_events |= POLLWRBAND_PORTABLE;
1024cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    }
1034cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1044cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu    return mips_events;
1054cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu}
1064cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1074cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fuextern int poll(struct pollfd *, nfds_t, long);
1084cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1096433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsiehint WRAP(poll)(struct pollfd *fds, nfds_t nfds, long timeout)
1104cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu{
1114cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  nfds_t i;
1124cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  int ret;
1134cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1144cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  for (i = 0; i < nfds; i++)
1154cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu      fds->events = mips_change_portable_events(fds->events);
1164cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1176433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsieh  ret = REAL(poll)(fds, nfds, timeout);
1184cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1194cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  for (i = 0; i < nfds; i++) {
1204cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu      fds->events = change_mips_events(fds->events);
1214cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu      fds->revents = change_mips_events(fds->revents);
1224cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  }
1234cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu
1244cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu  return ret;
1254cd3283046090736ef32259fb5d38c9ba944d12fChao-Ying Fu}
126