9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Lucas Francesco <lucas.francesco93@gmail.com>
To: 9front@9front.org
Subject: [9front] add lacking 9 section manpages
Date: Mon, 8 Nov 2021 20:44:54 -0300	[thread overview]
Message-ID: <CAF=5iUU2jk1RLoiyjFdxW8vBzdCmuThL98vWN+GSmX5q4-Wn6g@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 401 bytes --]

Hey all,

This patch adds some of the missing 9 section manpages, those were
included from https://github.com/0intro/plan9-contrib and not reviewed
around 9front's kernel functions and infra, but it should mostly be
accurate, i've at least not included stuff like kbdputc or ref which
are useless to us, but haven't reviewed the rest.

added: conf, devattach, dmainit, lock, newchan and qio

Uramekus

[-- Attachment #2.1: Type: text/plain, Size: 451 bytes --]

from postmaster@4ess:
The following attachment had content that we can't
prove to be harmless.  To avoid possible automatic
execution, we changed the content headers.
The original header was:

	Content-Type: text/x-patch; charset="US-ASCII"; 
	name="0001-include-missing-9-section-manpages.patch"
	Content-Disposition: attachment; 
	filename="0001-include-missing-9-section-manpages.patch"
	Content-Transfer-Encoding: base64
	Content-ID: <f_kvrb2sdg0>

[-- Attachment #2.2: 0001-include-missing-9-section-manpages.patch.suspect --]
[-- Type: application/octet-stream, Size: 38087 bytes --]

From 12bff7b15983b066f77d20c1a47cd0cdd921c3f9 Mon Sep 17 00:00:00 2001
From: Lucas Francesco <uramekus@cirno.dev>
Date: Mon, 8 Nov 2021 20:31:29 -0300
Subject: [PATCH 1/1] include missing 9 section manpages

those were included from https://github.com/0intro/plan9-contrib.git

things might not be accurate. but lack of lock(9) was annoying me a lot.
---
 sys/man/9/conf      | 340 +++++++++++++++++++++
 sys/man/9/devattach | 699 ++++++++++++++++++++++++++++++++++++++++++++
 sys/man/9/dmainit   |  86 ++++++
 sys/man/9/lock      | 106 +++++++
 sys/man/9/qio       | 480 ++++++++++++++++++++++++++++++
 5 files changed, 1711 insertions(+)
 create mode 100644 sys/man/9/conf
 create mode 100644 sys/man/9/devattach
 create mode 100644 sys/man/9/dmainit
 create mode 100644 sys/man/9/lock
 create mode 100644 sys/man/9/qio

diff --git a/sys/man/9/conf b/sys/man/9/conf
new file mode 100644
index 000000000..dbc13d88a
--- /dev/null
+++ b/sys/man/9/conf
@@ -0,0 +1,340 @@
+.TH CONF 9
+.SH NAME
+conf \- native and hosted kernel configuration file
+.SH DESCRIPTION
+Plan 9 kernels are built for a given target
+.I platform
+using platform-specific code in directory
+.BI /sys/src/9/ platform
+and portable code in
+.BR /sys/src/9/port ,
+.B /sys/src/9/ip
+and elsewhere.
+Existing
+.I platforms
+include
+.B alphapc
+for the DEC Alpha,
+.B iPAQ
+for the Compaq iPAQ,
+.B pc
+for the Intel x86,
+and
+.B ppc
+for the IBM/Motorola PowerPC.
+Each
+.I platform
+can have several different kernels with different configurations.
+A given configuration is built in the platform's directory using the
+.IR mk (1)
+command:
+.IP
+.EX
+mk 'CONF=\fIconf\fP'
+.EE
+.PP
+where
+.I conf
+is a text file that specifies drivers, protocols and other parameters for that
+particular kernel:
+a parts list.
+The result of a successful
+.I mk
+is
+an executable or bootable file with a name determined by the
+.IR platform 's
+.BR mkfile ,
+typically
+.BI 9 conf.
+.PP
+A kernel configuration file has several sections of the form
+.IP
+.EX
+.I "label"
+.IR "	item" " [ " "subitem ..." " ]"
+\&	...
+.EE
+.PP
+Each section begins with a
+.I label
+at the start of a line, which names a configuration
+category, followed by
+a list of each
+.I item
+to select from that category,
+one line per item, with white space (ie, blank or tab) at the start of the line.
+An
+.I item
+line can optionally list one or more
+.I subitems
+that must be included in the kernel to support it.
+A line that starts with a
+.L #
+is a comment.
+Empty lines are ignored.
+.PP
+.I Labels
+are chosen from the following set, listed in the order
+in which they conventionally appear in a configuration file:
+.TF etherxx
+.TP
+.B dev
+Device drivers
+.TP
+.B ip
+IP protocols (native kernels only) taken from
+.B ../ip
+.TP
+.B link
+Hardware-specific parts of device drivers.
+.TP
+.B misc
+Architecture-specific files; specific VGA and SCSI interfaces
+.TP
+.B lib
+Libraries to link with the kernel
+.TP
+.B port
+C code and declarations to include as-is in the generated configuration file
+.TP
+.B boot
+Configuration for
+.IR boot (8)
+.TP
+.B bootdir
+List of files and directories to put in the
+.B boot
+directory of
+.IR root (3).
+.PD
+.PP
+When an
+.I item
+is listed
+under a given
+.I label
+it causes a corresponding component to be included in the kernel.
+The details depend on the
+.IR label ,
+as discussed below.
+Each
+.I subitem
+represents a kernel subcomponent required by the corresponding
+.IR item .
+Both items and subitems can be either portable (platform-independent)
+or platform-specific.
+The source file for a given item or subitem
+is sought in the platform-directory
+(for platform-specific code), and
+in directories
+.BR ../port
+and
+.BR ../ip ,
+under control of the platform's
+.BR mkfile
+and
+.B ../port/portmkfile
+(which is included by
+.BR mkfile ).
+Resulting object files are left in the
+.I platform
+directory.
+.PP
+Outside the
+.B dev
+section,
+each item and subitem
+.I x
+causes the kernel image to include the code compiled from
+.IB x .c ,
+(or
+.IB x .s
+for assembly-language support),
+or
+.IB portdir / x .c ,
+where
+.I portdir
+is one of the portable directories mentioned above.
+In the
+.B dev
+section, an item
+.I x
+corresponds instead to the driver source file
+.BI dev x .c
+in the current (platform-specific)
+directory or a portable driver
+.IB portdir /dev x .c .
+Subitems are handled as in any other section.
+Typically they are auxiliary files that are needed by the associated driver.
+.PP
+For instance, in a native kernel
+the portable driver for the
+.B draw
+device uses platform-specific code from
+.BR screen.c .
+That can be represented as follows:
+.IP
+.EX
+dev
+	draw	screen
+.EE
+.PP
+Each item
+.I x
+in the
+.B ip
+section
+corresponds to a protocol implementation compiled from
+.BI ../ip/ x .c .
+Any subitems
+are dealt with in the same way as in the
+.B dev
+section.
+.PP
+The
+.B link
+section provides a way for hardware-specific
+parts of drivers to link at runtime to the hardware-invariant part of a device
+drivers.
+For each item
+.IR x ,
+the kernel will call the function
+.IB x link
+during its initialisation.
+Typically that function makes itself known to the device driver by
+calling a function provided by that driver,
+passing the address of a interface-specific data structure or linkage table.
+For example,
+.B ethersmc
+is an interface-specific component:
+.IP
+.EX
+link
+	\fR...\fP
+	ethersmc
+.EE
+.PP
+and its source file
+.B ethersmc.c
+provides a function
+.B ethersmclink
+that
+calls
+.B addethercard
+in the interface-invariant part of the driver,
+.BR devether.c :
+.IP
+.EX
+void
+ethersmclink(void)
+{
+	addethercard("smc91cXX", reset);
+}
+.EE
+.PP
+The
+.B boot
+section configures
+.IR boot (8),
+the first user program run by the kernel.
+Each line in the section names a possible boot method (see
+.IR boot (8)
+for the current list).
+The first will be the default.
+Also by default,
+.B /boot
+will run
+.B /bin/termrc
+from
+.IR cpurc (8),
+with
+.B bootdisk
+set to
+.BR #S/sdC0/ .
+To change the defaults, the line (or lines) containing a
+.B boot
+label can be given some options:
+.RS
+.TP
+.B "boot cpu"
+.br
+The kernel is a cpu server: run
+.B /bin/cpurc
+not
+.B /bin/termrc
+(see
+.IR cpurc (8)).
+.TP
+.BI "boot cpu boot " disk
+Use
+.I disk
+as the default
+.BR bootdisk .
+.RE
+.PP
+The
+.B lib
+section lists the libraries to include when linking the kernel,
+in an order that satisfies any dependencies amongst them.
+Each item
+.I x
+corresponds to
+.BI /$objtype/lib x .a ,
+a target-specific library
+produced by compiling the C source code in
+.BI /sys/src/lib item,
+where
+.B objtype
+is set in the platform's
+.B mkfile
+to the target system's object type
+(eg,
+.BR 386 ,
+.BR power ,
+etc).
+.PP
+An item in the
+.B bootdir
+section
+has one of the forms:
+.IP
+.EX
+.I name
+.I "source name"
+.EE
+.PP
+where
+.I name
+and
+.I source
+are path names (often absolute path names).
+The kernel's initial root file system (see
+.IR root (3))
+will contain a file or directory with the given
+.IR name .
+The contents will come from the file
+.I name
+(which must exist) unless an explicit
+.I source
+file is given.
+.PP
+The
+.B port
+section usually contains initialisations for kernel-specific values.
+The most common one is
+.IP
+.EX
+	int cpuserver = \fIn\fP;
+.EE
+.PP
+where
+.I n
+is non-zero for cpu servers and file servers, and zero otherwise.
+.SH FILES
+.B /sys/src/9/port/mkdevc
+.br
+.B /sys/src/9/port/mkdevlist
+.br
+.B /sys/src/9/port/mkroot
+.SH SEE ALSO
+.IR mk (1)
diff --git a/sys/man/9/devattach b/sys/man/9/devattach
new file mode 100644
index 000000000..671afe7bc
--- /dev/null
+++ b/sys/man/9/devattach
@@ -0,0 +1,699 @@
+.TH DEVATTACH 9
+.SH NAME
+devattach, devclone, devdir, devgen, devwalk, devdirread, devstat, devopen, devbread, devbwrite, devcreate, devremove, devwstat, devreset, devinit, devshutdown, openmode \- common device driver support
+.SH SYNOPSIS
+.nf
+.ta \w'\fLBlock* 'u +10n
+.B
+typedef int
+.B
+Devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
+.PP
+.B
+Chan*	devattach(int tc, char *spec)
+.PP
+.B
+Chan*	devclone(Chan *c)
+.PP
+.B
+void	devdir(Chan *c, Qid qid, char *n, long length,
+.B
+		char *user, long perm, Dir *dp)
+.PP
+.B
+int	devgen(Chan *c, char *name, Dirtab *tab, int ntab,
+.B
+		int i, Dir *dp)
+.PP
+.B
+Walkqid* devwalk(Chan *c, Chan *nc, char **name, int nname,
+.B
+		Dirtab *tab, int ntab, Devgen *gen)
+.PP
+.B
+void	devstat(Chan *c, uchar *db, int n, Dirtab *tab,
+.B
+		int ntab, Devgen *gen)
+.PP
+.B
+long	devdirread(Chan *c, char *d, long n, Dirtab *tab,
+.B
+		int ntab, Devgen *gen)
+.PP
+.B
+Chan*	devopen(Chan *c, int omode, Dirtab *tab,
+.B
+		int ntab, Devgen *gen)
+.PP
+.B
+Block*	devbread(Chan *c, long n, ulong offset)
+.PP
+.B
+long	devbwrite(Chan *c, Block *bp, ulong offset)
+.PP
+.B
+void	devcreate(Chan*, char*, int, ulong)
+.PP
+.B
+void	devremove(Chan*)
+.PP
+.B
+void	devwstat(Chan*, uchar*, int)
+.PP
+.B
+void	devreset(void)
+.PP
+.B
+void	devinit(void)
+.PP
+.B
+void	devshutdown(void)
+.PP
+.B
+int	openmode(ulong mode)
+.SH DESCRIPTION
+Device drivers call these functions to carry out essential tasks and default actions.
+They do most of the name space management
+for a driver that serves a simple name space
+(eg, data and control files),
+leaving the driver to concentrate on the device-specific details
+of the I/O requests.
+More complex drivers also make good use of them at the leaves
+of their name space, and to help manage the
+.B Chan
+structures correctly.
+.PP
+A device has an associated
+.IR type ,
+represented as a Unicode character (`rune') that identifies the device
+inside and outside the kernel.
+It appears as the value of the
+.B type
+field in the
+.B Dir
+resulting from a
+.IR stat (2)
+of any file provided by the device.
+A device is named outside the kernel using
+a path name starting with
+.B #
+followed by the device character
+(eg,
+.B c
+in
+.B #c
+for the console).
+Any subsequent characters before
+the next '/' or end of string is the `device specifier',
+interpreted solely by the device itself.
+.PP
+.I Devattach
+returns a new channel representing
+the root of the file tree
+corresponding to device type
+.IR tc ,
+with device specifier
+.IR spec .
+It is normally called by a driver's
+.I attach
+function (see
+.IR dev (9)).
+The
+.B qid
+for the new channel is
+.BR "(Qid){0,0,QTDIR}" ,
+suitable for a root directory for many devices, but
+a device driver is free to change it (provided the
+.B QTDIR
+bit remains in the
+.BR Qid.type ).
+.PP
+.I Devclone
+returns a new channel that is a copy of
+.IR c .
+An attempt to clone an open channel causes a
+.IR panic (9).
+.PP
+The
+.L Dir
+structure is shown below:
+.IP
+.EX
+typedef
+struct Dir
+{
+    /* system-modified data */
+    ushort  type;   /* server type */
+    uint    dev;    /* server subtype */
+    /* file data */
+    Qid     qid;    /* unique id from server */
+    ulong   mode;   /* permissions */
+    ulong   atime;  /* last read time */
+    ulong   mtime;  /* last write time */
+    vlong   length; /* file length */
+    char    *name;  /* last element of path */
+    char    *uid;   /* owner name */
+    char    *gid;   /* group name */
+    char    *muid;  /* last modifier name */
+} Dir;
+.EE
+.PP
+This
+.B Dir
+structure corresponds directly to the Limbo
+.B Dir
+adt described in
+.IR stat (2).
+.PP
+Given a channel and assorted other information, 
+.I devdir
+initialises a Dir structure at
+.IR dp .
+.I Devdir
+supplies the following data itself:
+.RS
+.TF length
+.TP
+.B atime
+last access time (set to current time)
+.TP
+.B mtime
+last modification time (set to kernel creation date)
+.TP
+.B gid
+group name (set to
+.IR eve (9))
+.TP
+.B length
+length in bytes (set to zero, which
+is normal for most devices)
+.RE
+.PD
+.PP
+Note that
+.I devdir
+assigns the values of
+.I name
+and
+.I user
+directly to fields of
+.BI * dp,
+and consequently those values must remain valid until the last use of
+.BI * dp.
+(Sometimes that requires the use of an auxiliary buffer, such as
+.BR up->genbuf .)
+If channel
+.I c
+corresponds to a file descriptor on which Styx is served,
+.I devdir
+sets both the flag bit
+.B QTMOUNT
+in
+.IB dp ->qid.type
+and the flag bit
+.B DMMOUNT
+in
+.IB dp ->mode
+(see
+.I export
+in
+.IR dial (2)
+and
+.I mount
+in
+.IR bind (2)).
+.PP
+A simple name space can be represented in a driver by an array of
+.B Dirtab
+structures.
+The array is typically static when the names and permissions
+are static, but can be dynamically allocated and initialised if required.
+The structure of
+.B Dirtab
+is shown below:
+.IP
+.EX
+typedef
+struct Dirtab
+{
+        char    name[KNAMELEN];
+        Qid     qid;
+        vlong   length;
+        long    perm;
+} Dirtab;
+.EE
+.PP
+The name
+.RB ` . '
+.I must
+appear as the first entry in a
+.B Dirtab
+if the default
+.I devgen
+function is used.
+On the other hand, the name
+.RB ` .. '
+must never appear in a
+.B Dirtab
+table.
+Drivers that support a directory hierarchy must walk up the hierarchy towards
+the root when their
+.I walk
+function receives
+.RB ` .. '
+as a file name component.
+The name
+.RB ` . '
+is never seen by a driver.
+.PP
+The
+.IR devdirread ,
+.IR devopen ,
+.IR devstat ,
+and
+.IR devwalk
+functions all take a
+.I gen
+function argument,
+of type
+.BR Devgen ,
+which they invoke to retrieve the items in
+a
+.B Chan
+that represents a directory.
+.I Gen
+takes a channel
+.I c
+(a directory),
+a file
+.I name
+(which is nil except during
+.IR devwalk ),
+an array of
+.B Dirtab
+structures
+.I tab
+of length
+.IR ntab ,
+and a table index
+.IR i .
+The functions calling
+.I gen
+expect it to place the
+.IR i 'th
+entry in the directory into
+.IR \f5*\fPdp .
+It should return 1
+if the call was successful,
+-1 if
+.I i
+is beyond the index of the last directory entry,
+or 0 if there is no entry at
+.IR i ,
+but there are entries beyond it.
+When
+.I i
+has the special value
+.B DEVDOTDOT
+then
+.I gen
+should set
+.IR \f5*\fPdp
+to reflect the parent of
+.IR c ;
+if
+.I c
+is a one-level device directory, then `..' is equivalent to `.'.
+Custom implementations of
+.I gen
+often ignore
+.IR devtab ,
+and instead return their own dynamically generated
+set of directory entries from some other source.
+Exceptionally, during
+.I devwalk
+a non-nil
+.I name
+is provided: it is the name being looked up, and a device-specific
+.I gen
+can short-circuit the search by returning -1 if the name does not exist,
+or filling in
+.IR \f5*\fPdp
+and returning 1 if it does exist.
+.PP
+The function
+.I devgen
+is compatible with
+.BR Devgen ;
+it returns the
+.IR i 'th
+entry in
+.IR devtab ,
+and can be used to provide a simple, static
+set of directory entries.
+.PP
+.I Devwalk
+walks channel
+.I c
+to the file in the device named by the path encoded in
+.IR name ,
+which is an array of strings of length
+.IR nname .
+It provides the interface to
+.IR walk (5)
+within the kernel, and that specification must be well understood to appreciate
+all the nuances of its interface.
+Fortunately, in nearly all device drivers, a device's
+.I walk
+function typically passes its parameters on to
+.I devwalk
+(adding the device's own
+.B Dirtab
+array as the the value of
+.IR tab ),
+and simply returning the result of
+.IR devwalk .
+.PP
+.I Devwalk
+walks
+.I c
+using the given set of names, and if the walk is successful, the
+channel
+.I nc
+will refer to the result of the walk
+(specifically,
+.IB nc ->qid
+is set to the Qid for the file).
+If
+.I nc
+is nil,
+.I devwalk
+will allocate a new channel itself, that is initially a clone of
+.IR c .
+As in
+.IR walk (5),
+.I devwalk
+can return a partial result,
+represented by
+a dynamically allocated value of the following structure:
+.IP
+.EX
+struct Walkqid
+{
+    Chan  *clone;
+    int   nqid;
+    Qid   qid[1];	/* actually nname in length */
+};
+.EE
+.PP
+The value must be freed after use.
+For each element of
+.I name ,
+.I devwalk
+passes
+the
+.I tab
+parameter to
+.I gen
+together with the currently-sought element of
+.IR name .
+If the first element is not found,
+.I devwalk
+returns nil; otherwise, it returns a
+.B Walkqid
+value in which
+.B nqid
+elements of the array
+.B qid
+are set to the qids (see
+.IR intro (5))
+of each valid element of
+.IR name .
+If all
+.I nname
+elements were successfully traversed, then
+.B nqid
+will have the value
+.IR nname ,
+and
+.B clone
+will refer to the result of the walk,
+which is either
+.I nc
+if given, or
+the new channel allocated by
+.IR devwalk .
+Otherwise, at least one element succeeded and
+.B nqid
+is less than
+.I nname
+and
+.B clone
+is nil.
+On an error or incomplete walk,
+the error string is set to the error that stopped the walk (eg,
+.B Enonexist
+or
+.BR Enotdir ).
+.PP
+.I Devstat
+fills the array of bytes
+.I db
+with data in the format produced by
+.IR stat (5)
+that describes the file
+referenced by channel
+.IR c ,
+which must have a corresponding entry
+returned by
+.IR gen
+(ie, an entry with matching
+.BR Qid.path ).
+If
+.I c
+is a communications channel connecting a Styx server to a current mount point,
+the
+.B DMMOUNT
+bit is set in the resulting
+.BR Dir.mode ,
+and
+.B QTMOUNT
+is set in
+.BR Dir.qid.type .
+As in
+.IR stat (5),
+the length of the data written to
+.I db
+varies; if more than
+.I n
+bytes are needed,
+.I devstat
+raises the
+.IR error (9)
+.BR Ebadarg .
+Otherwise, it returns the number of bytes in
+.I db
+actually used.
+.PP
+If an entry with the desired qid is not found in the table, but
+.I c
+corresponds to a directory
+(ie,
+.B QTDIR
+is set in
+.IR c\f5->qid.type\fP ),
+it is taken to be a
+.I stat
+of a notional directory containing the files listed in
+.IR tab .
+.I Dirstat
+then builds the corresponding Dir structure:
+its
+.B Dir.name
+is taken from
+.IR c\f5->path->elem\fP ;
+the length is
+.BI DIRLEN*nelem(tab) ;
+and
+.B Dir.perm
+is 0555 (read-execute for all).
+.PP
+.I Devdirread
+calls
+.I gen
+to obtain successive
+.B Dir
+structures representing entries in the open directory
+.IR c .
+These are converted to standard format (see
+.I convD2M
+in
+.IR fcall (2))
+and placed in the buffer
+.IR b .
+It returns the number of bytes in the result.
+At most
+.I n
+bytes will be returned, in multiples of
+.BR DIRLEN .
+Because the kernel maintains the current offset in
+.IR c ,
+successive calls to
+.I devdirread
+return successive directory components.
+.PP
+.I Devopen
+is called to check and complete a request to open channel
+.I c
+for I/O according to
+.IR omode
+(the open mode of
+.IR open (2)).
+It calls
+.I gen
+to obtain successive directory entries
+which it searches
+for a Qid matching that of
+.IR c ,
+and ensures that the current user has permission to open
+.I c
+with the given mode,
+.IR omode ,
+and that the mode itself is valid
+(see
+.I openmode
+below).
+Permission is checked against the permission in the
+matching entry.
+If no matching Qid is found, it is assumed
+that the notional parent directory of the files represented in
+.I tab
+is to be opened.
+Such a directory is deemed to have mode
+0555, allowing access by any user.
+A directory can only be opened for reading
+.RB ( OREAD ).
+.I Devopen
+returns the channel
+.I c
+on success.
+Last, it sets the bit
+.B COPEN
+in
+.B Chan.flag
+to mark
+.I c
+as open.
+This convention can always be relied upon by the driver's
+.I close
+function to tell if an open succeeded.
+On the otherhand,
+if the open request was unsuccessful,
+.I devopen
+raises an appropriate
+.IR error (9)
+and does not return.
+.PP
+.I Devbread
+returns a
+.B Block
+(see
+.IR allocb (9))
+containing up to
+.I n
+bytes read,
+using
+.BI "devtab[" c "->type]->read" ,
+from
+.I c
+starting at the given
+.IR offset .
+The read pointer in the returned
+.B Block
+points to the start of the data;
+the write pointer points to the next available byte.
+.PP
+.I Devbwrite
+writes the data in
+.B Block
+.I bp
+to the file
+.I c
+at the given
+.IR offset ,
+using the write function
+.BI "devtab[" c "->type]->write" .
+It then frees the block list
+.I bp
+before
+returning the number of bytes written.
+.PP
+Most built-in devices do not allow
+.IR create ,
+.IR remove
+or
+.I wstat
+on their files.
+.IR Devcreate ,
+.I devremove
+and
+.I devwstat
+are stubs that raise an
+.IR error (9),
+.BR Eperm .
+They can be named directly in a device driver's device
+switch (the
+.B Dev
+structure in
+.BR /sys/src/9/port/portdat.h :
+see
+.IR dev (9)).
+.PP
+.IR Devreset ,
+.I devinit
+and
+.I devshutdown
+are also stubs;
+they do nothing.
+A device driver puts them in its
+.B Dev
+structure when it need take no action on device reset, initialisation, or shut down.
+.PP
+.I Openmode
+is used by a driver that does not use
+.IR devopen ,
+to check the open mode it receives in its open
+routine.
+.I Openmode
+returns mode
+.IR o ,
+the mode parameter to
+.IR open (2)
+or
+.IR sys-create ,
+shorn of
+.BR OTRUNC
+and similar options,
+and reduced to one of
+.BR OREAD ,
+.BR OWRITE
+or
+.BR ORDWR .
+In particular,
+.B OEXEC
+becomes
+.B OREAD
+within the kernel.
+.I Openmode
+raises an
+.IR error (9)
+.B Ebadarg
+instead of returning, if
+.I o
+is an invalid mode (eg, reserved bits set).
+.SH SOURCE
+.B /sys/src/9/port/dev.c
+.SH SEE ALSO
+.IR allocb (9),
+.IR eve (9),
+.IR qio (9)
diff --git a/sys/man/9/dmainit b/sys/man/9/dmainit
new file mode 100644
index 000000000..59af14521
--- /dev/null
+++ b/sys/man/9/dmainit
@@ -0,0 +1,86 @@
+.TH DMAINIT 9
+.SH NAME
+dmainit, dmasetup, dmadone, dmaend, dmacount \- platform-specific DMA support
+.SH SYNOPSIS
+.ta \w'\fLushort 'u
+.B
+void	dmainit(int chan)
+.PP
+.B
+long	dmasetup(int chan, void *va, long len, int isread)
+.PP
+.B
+int	dmadone(int chan)
+.PP
+.B
+void	dmaend(int chan)
+.PP
+.B
+int	dmacount(int chan)
+.PP
+.SH DESCRIPTION
+These functions manage DMA on a bus that uses ISA-style DMA controllers.
+They were originally devised for the x86 platform, but the same interface, and similar code,
+is used by other platforms that use similar controllers.
+They compensate as best they can for the limitations of older DMA implementations
+(eg, alignment, boundary and length restrictions).
+There are 8 DMA channels:
+0 to 3 are byte-oriented; 4 to 7 are word-oriented (16-bit words).
+.PP
+.I Dmainit
+must be called early in a driver's initialisation to prepare
+.I chan
+for use.
+Amongst other things, it allocates a page-sized buffer to help circumvent hardware
+restrictions on DMA addressing.
+.PP
+.I Dmasetup
+prepares DMA channel
+.IR chan
+for a transfer between a device configured to use it
+and the virtual address
+.IR va .
+(The transfer is started by issuing a command to the device.)
+If
+.I va
+lies outside the kernel address space,
+the transfer crosses a 64k boundary,
+or exceeds the 16 Mbyte limit imposed by some DMA controllers,
+the transfer will be split into page-sized transfers using the buffer previously allocated by
+.IR dmainit .
+If
+.I isread
+is true (non-zero), data is to be transferred from
+.I chan
+to
+.IR va ;
+if false, data is transferred from
+.I va
+to
+.IR chan .
+In all cases,
+.I dmasetup
+returns the number of bytes to be transferred.
+That value (rather than
+.IR len )
+must be given to the device in the read or write request that starts the transfer.
+.PP
+.I Dmadone
+returns true (non-zero) if
+.I chan
+is idle.
+.PP
+.I Dmaend
+must be called at the end of every DMA operation.
+It disables
+.IR chan ,
+preventing further access to the previously associated memory and,
+if a low-memory buffer was required for input, transfers its contents
+to the appropriate part of the target buffer.
+.PP
+.I Dmacount
+returns the number of bytes that were last transferred by channel
+.IR chan .
+The count is always even for word-oriented DMA channels.
+.SH SOURCE
+.B /sys/src/9/pc/dma.c
diff --git a/sys/man/9/lock b/sys/man/9/lock
new file mode 100644
index 000000000..4df052e9c
--- /dev/null
+++ b/sys/man/9/lock
@@ -0,0 +1,106 @@
+.TH LOCK 9
+.SH NAME
+lock, canlock, ilock, iunlock, unlock \- spin locks
+.SH SYNOPSIS
+.ta \w'\fLvoid 'u
+.B
+void    lock(Lock *l)
+.PP
+.B
+int     canlock(Lock *l)
+.PP
+.B
+void    unlock(Lock *l)
+.PP
+.B
+void    ilock(Lock *l)
+.PP
+.B
+void    iunlock(Lock *l)
+.SH DESCRIPTION
+These primitives control access to shared
+resources using spin locks.
+They in turn are used to build higher-level synchronisation mechanisms
+such as those described in
+.IR sleep (9),
+.IR qlock (9)
+and
+.IR qio (9).
+They should be used only to protect short critical sections
+that update shared data structures.
+.PP
+.I Lock
+loops repeatedly attempting acquire the spin lock
+.I l
+until it succeeds.
+.I Lock
+should not be used to lock a structure shared with an interrupt handler
+unless interrupts are disabled by
+.IR splhi (9)
+before attempting the lock;
+it is better to use
+.IR ilock ,
+below.
+.PP
+.I Canlock
+is non-blocking.
+Only one attempt is made for the lock.
+It returns non-zero if the lock was successfully acquired; 0 otherwise.
+.PP
+.I Unlock
+releases the lock
+.IR l .
+A lock must be unlocked only by the locking process.
+.PP
+When called by a process, the functions above temporarily boost its priority
+to the highest priority,
+.BR PriLock ;
+its original priority is restored at the end of the critical section by
+.IR unlock .
+On a uniprocessor, if
+.I l
+is unavailable,
+.I lock
+can reschedule unless interrupts are disabled before entering
+.I lock
+or there is no current process (eg, when executing the scheduler).
+.PP
+.I Ilock
+disables interrupts before attempting to acquire the lock.
+It should be used to lock a resource shared between a process and an interrupt handler.
+On a uniprocessor, disabling interrupts is sufficient to exclude an interrupt handler
+from the critical section,
+and on a multiprocessor the spin lock excludes an interrupt handler running on another processor.
+.I Ilock
+never reschedules the caller, nor must a caller allow itself to be rescheduled
+(eg, by calling
+.IR sleep (9))
+before releasing the lock.
+.PP
+.I Iunlock
+releases a lock previously got by
+.IR ilock .
+.SH SOURCE
+.B /sys/src/9/port/taslock.c
+.br
+.B /sys/src/9/*/l.s
+.SH SEE ALSO
+.IR qlock (9)
+.SH DIAGNOSTICS
+The lock functions
+guard against the possibility of never acquiring the lock by capping the number of lock attempts.
+If the limit is reached, a message of
+the following form is written on the console:
+.IP
+.EX
+lock loop on \fIlock-address\fP key \fIkey-value\fP pc \fIcaller-pc\fP held by pc \fIlock-pc\fP
+.EE
+.PP
+Most lock loops represent deadlocks caused by failing to unlock a resource,
+attempting to lock (eg, by recursive call) a resource already held by the process,
+inconsistent locking and unlocking of nested resources, using a spin-lock
+to guard code that reschedules, using
+.I lock
+not
+.I ilock
+to interlock with an interrupt routine, and similar blunders.
diff --git a/sys/man/9/qio b/sys/man/9/qio
new file mode 100644
index 000000000..32e9b28fd
--- /dev/null
+++ b/sys/man/9/qio
@@ -0,0 +1,480 @@
+.TH QIO 9
+.SH NAME
+qio: qget, qdiscard, qconsume, qpass, qproduce, qcopy, qopen, qbread, qread, qbwrite, qwrite, qiwrite, qfree, qclose, qhangup, qreopen, qlen, qwindow, qcanread, qsetlimit, qnoblock, qflush, qfull \- queued I/O for devices
+.SH SYNOPSIS
+.ta \w'\fLQueue*  'u
+.B
+Queue*	qopen(int limit,int msg, void (*kick)(void*),void *arg)
+.PP
+.B
+void	qhangup(Queue *q, char *reason)
+.PP
+.B
+void	qclose(Queue *q)
+.PP
+.B
+void	qreopen(Queue *q)
+.PP
+.B
+void	qfree(Queue *q)
+.PP
+.B
+long	qbwrite(Queue *q, Block *b)
+.PP
+.B
+long	qwrite(Queue *q, void *buf, int len)
+.PP
+.B
+int	qpass(Queue *q, Block *b)
+.PP
+.B
+int	qpassnolim(Queue *q, Block *b)
+.PP
+.B
+int	qproduce(Queue *q, void	*buf, int len)
+.PP
+.B
+int	qiwrite(Queue *q, void *buf, int len)
+.PP
+.B
+Block*	qbread(Queue *q, int len)
+.PP
+.B
+long	qread(Queue *q, void *buf, int len)
+.PP
+.B
+Block*	qcopy(Queue *q, int len, ulong offset)
+.PP
+.B
+Block*	qget(Queue *q)
+.PP
+.B
+int	qconsume(Queue *q, void *buf, int len)
+.PP
+.B
+int	qdiscard(Queue *q, int len)
+.PP
+.B
+void	qflush(Queue *q)
+.PP
+.B
+int	qlen(Queue *q)
+.PP
+.B
+int	qwindow(Queue *q)
+.PP
+.B
+int	qcanread(Queue *q)
+.PP
+.B
+void	qsetlimit(Queue *q, int limit)
+.PP
+.B
+void	qnoblock(Queue *q, int nonblock)
+.PP
+.B
+int	qfull(Queue *q)
+.SH DESCRIPTION
+This suite of functions provides serial data buffering for device drivers.
+Data is stored in a
+.B Queue
+structure as a sequence of variable-sized
+.BR Blocks ;
+see
+.IR allocb (9).
+.PP
+.I Qopen
+initialises and returns a pointer to a new
+.BR Queue ,
+configuring it according to the following parameters:
+.TF limit
+.PD
+.TP
+.I limit
+Set the queue limit (high water mark) in bytes.
+.TP
+.I msg
+Set message mode if non-zero; otherwise, stream mode (discussed below).
+.TP
+.I kick
+Optional flow-control function called by
+.I qbread
+to restart writers, and by
+.I qbwrite
+(also
+.IR qiwrite )
+to restart readers.
+.TP
+.I arg
+Argument to pass to
+.I kick
+.PP
+.I Qhangup
+marks
+.I q
+as `hung up'
+for the given
+.IR reason
+.RB ( Ehungup
+by default).
+Subsequent attempts to write to the queue raise an
+.IR error (9).
+.I Qhangup
+does not flush the queue: subsequent read requests are
+handled normally until the queue empties.
+.I Qread
+and the other functions then return their conventional values
+for a hungup stream: 0, -1 or a null pointer, depending on the function.
+After a few such attempts by any process, an
+.IR error (9)
+is raised (typically
+.BR Ehungup )
+on each subsequent read.
+.PP
+If queued data is left unread, and not flushed by
+.I qflush
+or
+.IR qclose ,
+the data will again be readable following a subsequent
+.IR qreopen .
+.PP
+.I Qclose
+also marks a given
+.I q
+as `hung up',
+but removes and frees any queued data Blocks.
+.I Qclose
+ignores calls when
+.I q
+is null.
+.PP
+.I Qreopen
+makes a closed or hung up queue available for use again.
+The queue's data limit is reset to the
+.I limit
+value given when the queue was first created by
+.IR qopen ,
+cancelling the effect of any previous call to
+.IR qsetlimit .
+.PP
+.I Qfree
+closes
+.I q
+with
+.I qclose
+and frees it.
+The caller must ensure that no references remain;
+these functions do not keep a reference count.
+.SS "Flow control"
+The queue I/O routines provide a flow control mechanism to coordinate producers and consumers.
+Each queue has a limit on the number of bytes queued, its `high water mark',
+initially set when the queue is created, but adjustable by
+.IR qsetlimit ,
+below. 
+The low water mark is not set explicitly:
+it is always half the current queue limit.
+When the high water mark is exceeded, writes normally block until a reader drains the
+queue below its low water mark; the writer is then allowed to proceed.
+Conversely, readers normally block when the queue is empty, until a writer
+arrives with data, or the queue is closed.
+.PP
+A queue can be given a
+.I kick
+function when the queue is created by
+.IR qopen .
+The function is invoked by
+.IR qread
+and
+.IR qbread ,
+to prod an output routine when the queue falls below the low-water mark, and by
+.IR qwrite ,
+.IR qbwrite
+and
+.IR qiwrite ,
+to notify a reader that a queue is no longer empty.
+Because
+.I kick
+is called from the reading (or writing) process, or an interrupt handler, it
+must not block.
+.PP
+Interrupt handlers must not
+.IR sleep (9),
+and are therefore restricted to using only the non-blocking functions described below.
+.SS "Stream mode and message mode"
+In stream mode,
+no read will return more than one
+block
+of data, but
+a read can split a block that contains more data than requested, leaving the remainder
+in a new block at the front of the Queue.
+Writes of more than the maximum
+.B Block
+size (currently 128k bytes)
+are split into as many Blocks as required, each written separately to the queue,
+in order, but with possible flow-control between them.
+The queue is locked meanwhile, however, so that data from other writers is not intermingled.
+.PP
+In message mode, by contrast, a read will return at most
+one block's worth of data, but the remainder of a partially-read block will be discarded,
+not returned to the queue.
+If a write count exceeds the maximum
+.B Block
+size, the excess data is discarded:
+at most a single block can be queued.
+.PP
+The mode of the queue should be taken into account in the descriptions below
+of the following functions:
+.IR qwrite ,
+.IR qiwrite ,
+.IR qbread
+and
+.IR qconsume .
+No other functions are aware of the distinction.
+.SS "Write operations (flow controlled)"
+.I Qwrite
+copies
+.I len
+bytes of data from
+.I buf
+into one or more
+.B Blocks
+which it places on the
+.IR q .
+.I Qwrite
+always returns
+.IR len .
+It can implement message mode.
+.PP
+.I Qbwrite
+places the single Block
+.I b
+on the tail of
+.IR q ,
+waking any sleeping reader.
+If the queue is full, the
+writing process blocks until a reader
+has reduced the queued data to
+the low-water mark;
+if the queue is non-blocking
+(see
+.I qnoblock
+below),
+the data is discarded without notice.
+.I Qbwrite
+normally returns
+.IR len ,
+but raises an
+.IR error (9)
+if the queue is closed (see
+.I qhangup
+and
+.IR qclose ).
+The block
+.I b
+is always freed.
+Note that
+.I b
+can be empty (zero-length), to punctuate the data in a queue.
+.I Qbwrite
+cannot handle a list of Blocks;
+.I qpass
+must be used instead.
+.SS Non-blocking writes
+.PP
+.I Qproduce
+returns -1immediately  if
+.I q
+is full.
+Otherwise, it queues
+.I len
+bytes of data from
+.I buf
+in a single
+.B Block
+on
+.I q
+and returns the number of bytes written.
+.PP
+.I Qpass
+attempts to place the list of Blocks headed by
+.I b
+on
+.IR q ,
+returning the number of bytes written if successful.
+If
+.I q
+was full, it
+frees the Block list
+.I b
+and returns -1.
+.PP
+.I Qpassnolim
+puts the Block list
+.I b
+on
+.I q
+regardless of flow control; it returns the number of bytes in the list
+.IR b .
+.PP
+.I Qiwrite
+is a variant of
+.I qwrite
+used exclusively by the kernel print function,
+to allow printing by interrupt handlers;
+.I qiwrite
+could be used with care by other routines, but
+.IR qproduce
+is preferable.
+.I Qiwrite
+writes the
+.I len
+bytes of data at
+.I buf
+into the
+.I q
+without regard to flow control;
+the writer never blocks.
+The queue is assumed to be open.
+.I Qiwrite
+always returns
+.IR len .
+It can implement message mode.
+.SS "Read operations (flow controlled)"
+.I Qbread
+blocks until data arrives on
+.IR q ,
+then
+returns the first
+.BR Block ;
+it limits the data returned
+to
+.I len
+bytes (in the manner depending on the mode of
+.IR q ).
+It returns a null pointer if the queue has hung up.
+.PP
+.I Qread
+reads a Block of up to
+.I len
+bytes from
+.I q
+using
+.IR qbread ,
+and copies the data in the Block into
+.IR buf ,
+then frees the Block and returns
+the number of bytes read.
+.I Qread
+returns 0 on end of file or error (hangup).
+It can implement message mode.
+.PP
+.I Qcopy
+returns a Block with a copy of data from the queue (the data remains on the queue).
+The copy begins
+.I offset
+bytes into the queue's data and proceeds until
+.I len
+bytes have been copied or no more data remains.
+The Block's read and write pointers delimit the data copied into it.
+.I Qcopy
+can be used by a reliable transport protocol to copy a packet for transmission,
+leaving the data queued for possible retransmission, if unacknowledged.
+.SS Non-blocking reads
+.PP
+.I Qconsume
+returns -1 immediately if
+.I q
+is empty.
+Otherwise, it
+copies up to
+.I len
+bytes from the first
+.B Block
+on the queue into
+.IR buf ,
+returning the number of bytes copied.
+It can implement message mode.
+.PP
+.I Qget
+returns a null pointer immediately if
+.I q
+is empty or closed.
+Otherwise, it
+returns the first
+.B Block
+on the queue.
+.SS "Discard and flush"
+.I Qdiscard
+removes the first
+.I len
+data bytes from
+.IR q ;
+it returns the number of bytes actually discarded, in case
+the queue is shorter than
+.IR len .
+If the queue drains below the low-water mark,
+.I qdiscard
+wakes any sleeping writers.
+Since it does not block,
+.I qdiscard
+can safely be called from interrupt handlers.
+It is useful in transport protocol drivers to remove data from the queue
+once acknowledged.
+.PP
+.I Qflush
+discards all data waiting on
+.IR q ,
+waking any waiting writer.
+.SS "Queue status"
+The following functions return a Queue's status.
+Note that between a call to one of these functions and another operation,
+the state can change if a driver allows concurrent access by
+either another process or an interrupt handler.
+.PP
+.I Qlen
+returns the number of bytes queued on
+.IR q .
+.PP
+.I Qwindow
+returns the number of bytes that can be written before reaching the queue's high-water mark.
+A return of 0 means that a write operation will certainly block;
+a non-zero return gives no guarantees (see
+.IR qfull ,
+below).
+.PP
+.I Qcanread
+returns 1 if any data queued is queued. A subsequent read operation will not block.
+.PP
+.I Qfull
+returns non-zero if
+.I q
+is flow-controlled and a write would block or a non-blocking write would return an error.
+(Note that the implementation allows
+.I qwindow
+to return non-zero yet
+.I qfull
+to return true.)
+.SS "Queue control"
+.I Qsetlimit
+sets the high water mark for the queue to
+.IR limit .
+Note that
+.I qopen
+saves the initial queue limit.
+If the queue is closed and reopened (by
+.IR qreopen )
+that initial limit is restored.
+.PP
+.I Qnoblock
+sets or resets non-blocking mode.
+If
+.I nonblock
+is non-zero,
+the queue becomes non-blocking, and
+data written to a queue beyond its high water mark is discarded
+by calls that would otherwise block.
+.SH SOURCE
+.B /sys/src/9/port/qio.c
+.SH SEE ALSO
+.IR allocb (9),
+.IR ref (9)
-- 
2.33.1


             reply	other threads:[~2021-11-09  1:23 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-08 23:44 Lucas Francesco [this message]
2021-11-09  2:45 ` cinap_lenrek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAF=5iUU2jk1RLoiyjFdxW8vBzdCmuThL98vWN+GSmX5q4-Wn6g@mail.gmail.com' \
    --to=lucas.francesco93@gmail.com \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).