code:
=============
eBPF verifier
=============

The safety of the eBPF program is determined in two steps.

First step does DAG check to disallow loops and other CFG validation.
In particular it will detect programs that have unreachable instructions.
(though classic BPF checker allows them)

Second step starts from the first insn and descends all possible paths.
It simulates execution of every insn and observes the state change of
registers and stack.

At the start of the program the register R1 contains a pointer to context
and has type PTR_TO_CTX.
If verifier sees an insn that does R2=R1, then R2 has now type
PTR_TO_CTX as well and can be used on the right hand side of expression.
If R1=PTR_TO_CTX and insn is R2=R1+R1, then R2=SCALAR_VALUE,
since addition of two valid pointers makes invalid pointer.
(In 'secure' mode verifier will reject any type of pointer arithmetic to make
sure that kernel addresses don't leak to unprivileged users)

If register was never written to, it's not readable::

  bpf_mov R0 = R2
  bpf_exit

will be rejected, since R2 is unreadable at the start of the program.

After kernel function call, R1-R5 are reset to unreadable and
R0 has a return type of the function.

Since R6-R9 are callee saved, their state is preserved across the call.

::

  bpf_mov R6 = 1
  bpf_call foo
  bpf_mov R0 = R6
  bpf_exit

is a correct program. If there was R1 instead of R6, it would have
been rejected.

load/store instructions are allowed only with registers of valid types, which
are PTR_TO_CTX, PTR_TO_MAP, PTR_TO_STACK. They are bounds and alignment checked.
For example::

 bpf_mov R1 = 1
 bpf_mov R2 = 2
 bpf_xadd *(u32 *)(R1 + 3) += R2
 bpf_exit

will be rejected, since R1 doesn't have a valid pointer type at the time of
execution of instruction bpf_xadd.

At the start R1 type is PTR_TO_CTX (a pointer to generic ``struct bpf_context``)
A callback is used to customize verifier to restrict eBPF program access to only
certain fields within ctx structure with specified size and alignment.

For example, the following insn::

  bpf_ld R0 = *(u32 *)(R6 + 8)

intends to load a word from address R6 + 8 and store it into R0
If R6=PTR_TO_CTX, via is_valid_access() callback the verifier will know
that offset 8 of size 4 bytes can be accessed for reading, otherwise
the verifier will reject the program.
If R6=PTR_TO_STACK, then access should be aligned and be within
stack bounds, which are [-MAX_BPF_STACK, 0). In this example offset is 8,
so it will fail verification, since it's out of bounds.

The verifier will allow eBPF program to read data from stack only after
it wrote into it.

Classic BPF verifier does similar check with M[0-15] memory slots.
For example::

  bpf_ld R0 = *(u32 *)(R10 - 4)
  bpf_exit

is invalid program.
Though R10 is correct read-only register and has type PTR_TO_STACK
and R10 - 4 is within stack bounds, there were no stores into that location.

Pointer register spill/fill is tracked as well, since four (R6-R9)
callee saved registers may not be enough for some programs.

Allowed function calls are customized with bpf_verifier_ops->get_func_proto()
The eBPF verifier will check that registers match argument constraints.
After the call register R0 will be set to return type of the function.

Function calls is a main mechanism to extend functionality of eBPF programs.
Socket filters may let programs to call one set of functions, whereas tracing
filters may allow completely different set.

If a function made accessible to eBPF program, it needs to be thought through
from safety point of view. The verifier will guarantee that the function is
called with valid arguments.

seccomp vs socket filters have different security restrictions for classic BPF.
Seccomp solves this by two stage verifier: classic BPF verifier is followed
by seccomp verifier. In case of eBPF one configurable verifier is shared for
all use cases.

See details of eBPF verifier in kernel/bpf/verifier.c

Register value tracking
=======================

In order to determine the safety of an eBPF program, the verifier must track
the range of possible values in each register and also in each stack slot.
This is done with ``struct bpf_reg_state``, defined in include/linux/
bpf_verifier.h, which unifies tracking of scalar and pointer values.  Each
register state has a type, which is either NOT_INIT (the register has not been
written to), SCALAR_VALUE (some value which is not usable as a pointer), or a
pointer type.  The types of pointers describe their base, as follows:

    PTR_TO_CTX
			Pointer to bpf_context.
    CONST_PTR_TO_MAP
			Pointer to struct bpf_map.  "Const" because arithmetic
			on these pointers is forbidden.
    PTR_TO_MAP_VALUE
			Pointer to the value stored in a map element.
    PTR_TO_MAP_VALUE_OR_NULL
			Either a pointer to a map value, or NULL; map accesses
			(see maps.rst) return this type, which becomes a
			PTR_TO_MAP_VALUE when checked != NULL. Arithmetic on
			these pointers is forbidden.
    PTR_TO_STACK
			Frame pointer.
    PTR_TO_PACKET
			skb->data.
    PTR_TO_PACKET_END
			skb->data + headlen; arithmetic forbidden.
    PTR_TO_SOCKET
			Pointer to struct bpf_sock_ops, implicitly refcounted.
    PTR_TO_SOCKET_OR_NULL
			Either a pointer to a socket, or NULL; socket lookup
			returns this type, which becomes a PTR_TO_SOCKET when
			checked != NULL. PTR_TO_SOCKET is reference-counted,
			so programs must release the reference through the
			socket release function before the end of the program.
			Arithmetic on these pointers is forbidden.

However, a pointer may be offset from this base (as a result of pointer
arithmetic), and this is tracked in two parts: the 'fixed offset' and 'variable
offset'.  The former is used when an exactly-known value (e.g. an immediate
operand) is added to a pointer, while the latter is used for values which are
not exactly known.  The variable offset is also used in SCALAR_VALUEs, to track
the range of possible values in the register.

The verifier's knowledge about the variable offset consists of:

* minimum and maximum values as unsigned
* minimum and maximum values as signed

* knowledge of the values of individual bits, in the form of a 'tnum': a u64
  'mask' and a u64 'value'.  1s in the mask represent bits whose value is unknown;
  1s in the value represent bits known to be 1.  Bits known to be 0 have 0 in both
  mask and value; no bit should ever be 1 in both.  For example, if a byte is read
  into a register from memory, the register's top 56 bits are known zero, while
  the low 8 are unknown - which is represented as the tnum (0x0; 0xff).  If we
  then OR this with 0x40, we get (0x40; 0xbf), then if we add 1 we get (0x0;
  0x1ff), because of potential carries.

Besides arithmetic, the register state can also be updated by conditional
branches.  For instance, if a SCALAR_VALUE is compared > 8, in the 'true' branch
it will have a umin_value (unsigned minimum value) of 9, whereas in the 'false'
branch it will have a umax_value of 8.  A signed compare (with BPF_JSGT or
BPF_JSGE) would instead update the signed minimum/maximum values.  Information
from the signed and unsigned bounds can be combined; for instance if a value is
first tested < 8 and then tested s> 4, the verifier will conclude that the value
is also > 4 and s< 8, since the bounds prevent crossing the sign boundary.

PTR_TO_PACKETs with a variable offset part have an 'id', which is common to all
pointers sharing that same variable offset.  This is important for packet range
checks: after adding a variable to a packet pointer register A, if you then copy
it to another register B and then add a constant 4 to A, both registers will
share the same 'id' but the A will have a fixed offset of +4.  Then if A is
bounds-checked and found to be less than a PTR_TO_PACKET_END, the register B is
now known to have a safe range of at least 4 bytes.  See 'Direct packet access',
below, for more on PTR_TO_PACKET ranges.

The 'id' field is also used on PTR_TO_MAP_VALUE_OR_NULL, common to all copies of
the pointer returned from a map lookup.  This means that when one copy is
checked and found to be non-NULL, all copies can become PTR_TO_MAP_VALUEs.
As well as range-checking, the tracked information is also used for enforcing
alignment of pointer accesses.  For instance, on most systems the packet pointer
is 2 bytes after a 4-byte alignment.  If a program adds 14 bytes to that to jump
over the Ethernet header, then reads IHL and addes (IHL * 4), the resulting
pointer will have a variable offset known to be 4n+2 for some n, so adding the 2
bytes (NET_IP_ALIGN) gives a 4-byte alignment and so word-sized accesses through
that pointer are safe.
The 'id' field is also used on PTR_TO_SOCKET and PTR_TO_SOCKET_OR_NULL, common
to all copies of the pointer returned from a socket lookup. This has similar
behaviour to the handling for PTR_TO_MAP_VALUE_OR_NULL->PTR_TO_MAP_VALUE, but
it also handles reference tracking for the pointer. PTR_TO_SOCKET implicitly
represents a reference to the corresponding ``struct sock``. To ensure that the
reference is not leaked, it is imperative to NULL-check the reference and in
the non-NULL case, and pass the valid reference to the socket release function.

Direct packet access
====================

In cls_bpf and act_bpf programs the verifier allows direct access to the packet
data via skb->data and skb->data_end pointers.
Ex::

    1:  r4 = *(u32 *)(r1 +80)  /* load skb->data_end */
    2:  r3 = *(u32 *)(r1 +76)  /* load skb->data */
    3:  r5 = r3
    4:  r5 += 14
    5:  if r5 > r4 goto pc+16
    R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp
    6:  r0 = *(u16 *)(r3 +12) /* access 12 and 13 bytes of the packet */

this 2byte load from the packet is safe to do, since the program author
did check ``if (skb->data + 14 > skb->data_end) goto err`` at insn #5 which
means that in the fall-through case the register R3 (which points to skb->data)
has at least 14 directly accessible bytes. The verifier marks it
as R3=pkt(id=0,off=0,r=14).
id=0 means that no additional variables were added to the register.
off=0 means that no additional constants were added.
r=14 is the range of safe access which means that bytes [R3, R3 + 14) are ok.
Note that R5 is marked as R5=pkt(id=0,off=14,r=14). It also points
to the packet data, but constant 14 was added to the register, so
it now points to ``skb->data + 14`` and accessible range is [R5, R5 + 14 - 14)
which is zero bytes.

More complex packet access may look like::

    R0=inv1 R1=ctx R3=pkt(id=0,off=0,r=14) R4=pkt_end R5=pkt(id=0,off=14,r=14) R10=fp
    6:  r0 = *(u8 *)(r3 +7) /* load 7th byte from the packet */
    7:  r4 = *(u8 *)(r3 +12)
    8:  r4 *= 14
    9:  r3 = *(u32 *)(r1 +76) /* load skb->data */
    10:  r3 += r4
    11:  r2 = r1
    12:  r2 <<= 48
    13:  r2 >>= 48
    14:  r3 += r2
    15:  r2 = r3
    16:  r2 += 8
    17:  r1 = *(u32 *)(r1 +80) /* load skb->data_end */
    18:  if r2 > r1 goto pc+2
    R0=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) R1=pkt_end R2=pkt(id=2,off=8,r=8) R3=pkt(id=2,off=0,r=8) R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)) R5=pkt(id=0,off=14,r=14) R10=fp
    19:  r1 = *(u8 *)(r3 +4)

The state of the register R3 is R3=pkt(id=2,off=0,r=8)
id=2 means that two ``r3 += rX`` instructions were seen, so r3 points to some
offset within a packet and since the program author did
``if (r3 + 8 > r1) goto err`` at insn #18, the safe range is [R3, R3 + 8).
The verifier only allows 'add'/'sub' operations on packet registers. Any other
operation will set the register state to 'SCALAR_VALUE' and it won't be
available for direct packet access.

Operation ``r3 += rX`` may overflow and become less than original skb->data,
therefore the verifier has to prevent that.  So when it sees ``r3 += rX``
instruction and rX is more than 16-bit value, any subsequent bounds-check of r3
against skb->data_end will not give us 'range' information, so attempts to read
through the pointer will give "invalid access to packet" error.

Ex. after insn ``r4 = *(u8 *)(r3 +12)`` (insn #7 above) the state of r4 is
R4=inv(id=0,umax_value=255,var_off=(0x0; 0xff)) which means that upper 56 bits
of the register are guaranteed to be zero, and nothing is known about the lower
8 bits. After insn ``r4 *= 14`` the state becomes
R4=inv(id=0,umax_value=3570,var_off=(0x0; 0xfffe)), since multiplying an 8-bit
value by constant 14 will keep upper 52 bits as zero, also the least significant
bit will be zero as 14 is even.  Similarly ``r2 >>= 48`` will make
R2=inv(id=0,umax_value=65535,var_off=(0x0; 0xffff)), since the shift is not sign
extending.  This logic is implemented in adjust_reg_min_max_vals() function,
which calls adjust_ptr_min_max_vals() for adding pointer to scalar (or vice
versa) and adjust_scalar_min_max_vals() for operations on two scalars.

The end result is that bpf program author can access packet directly
using normal C code as::

  void *data = (void *)(long)skb->data;
  void *data_end = (void *)(long)skb->data_end;
  struct eth_hdr *eth = data;
  struct iphdr *iph = data + sizeof(*eth);
  struct udphdr *udp = data + sizeof(*eth) + sizeof(*iph);

  if (data + sizeof(*eth) + sizeof(*iph) + sizeof(*udp) > data_end)
	  return 0;
  if (eth->h_proto != htons(ETH_P_IP))
	  return 0;
  if (iph->protocol != IPPROTO_UDP || iph->ihl != 5)
	  return 0;
  if (udp->dest == 53 || udp->source == 9)
	  ...;

which makes such programs easier to write comparing to LD_ABS insn
and significantly faster.

Pruning
=======

The verifier does not actually walk all possible paths through the program.  For
each new branch to analyse, the verifier looks at all the states it's previously
been in when at this instruction.  If any of them contain the current state as a
subset, the branch is 'pruned' - that is, the fact that the previous state was
accepted implies the current state would be as well.  For instance, if in the
previous state, r1 held a packet-pointer, and in the current state, r1 holds a
packet-pointer with a range as long or longer and at least as strict an
alignment, then r1 is safe.  Similarly, if r2 was NOT_INIT before then it can't
have been used by any path from that point, so any value in r2 (including
another NOT_INIT) is safe.  The implementation is in the function regsafe().
Pruning considers not only the registers but also the stack (and any spilled
registers it may hold).  They must all be safe for the branch to be pruned.
This is implemented in states_equal().

Understanding eBPF verifier messages
====================================

The following are few examples of invalid eBPF programs and verifier error
messages as seen in the log:

Program with unreachable instructions::

  static struct bpf_insn prog[] = {
  BPF_EXIT_INSN(),
  BPF_EXIT_INSN(),
  };

Error::

  unreachable insn 1

Program that reads uninitialized register::

  BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
  BPF_EXIT_INSN(),

Error::

  0: (bf) r0 = r2
  R2 !read_ok

Program that doesn't initialize R0 before exiting::

  BPF_MOV64_REG(BPF_REG_2, BPF_REG_1),
  BPF_EXIT_INSN(),

Error::

  0: (bf) r2 = r1
  1: (95) exit
  R0 !read_ok

Program that accesses stack out of bounds::

    BPF_ST_MEM(BPF_DW, BPF_REG_10, 8, 0),
    BPF_EXIT_INSN(),

Error::

    0: (7a) *(u64 *)(r10 +8) = 0
    invalid stack off=8 size=8

Program that doesn't initialize stack before passing its address into function::

  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_LD_MAP_FD(BPF_REG_1, 0),
  BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  BPF_EXIT_INSN(),

Error::

  0: (bf) r2 = r10
  1: (07) r2 += -8
  2: (b7) r1 = 0x0
  3: (85) call 1
  invalid indirect read from stack off -8+0 size 8

Program that uses invalid map_fd=0 while calling to map_lookup_elem() function::

  BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_LD_MAP_FD(BPF_REG_1, 0),
  BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  BPF_EXIT_INSN(),

Error::

  0: (7a) *(u64 *)(r10 -8) = 0
  1: (bf) r2 = r10
  2: (07) r2 += -8
  3: (b7) r1 = 0x0
  4: (85) call 1
  fd 0 is not pointing to valid bpf_map

Program that doesn't check return value of map_lookup_elem() before accessing
map element::

  BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_LD_MAP_FD(BPF_REG_1, 0),
  BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
  BPF_EXIT_INSN(),

Error::

  0: (7a) *(u64 *)(r10 -8) = 0
  1: (bf) r2 = r10
  2: (07) r2 += -8
  3: (b7) r1 = 0x0
  4: (85) call 1
  5: (7a) *(u64 *)(r0 +0) = 0
  R0 invalid mem access 'map_value_or_null'

Program that correctly checks map_lookup_elem() returned value for NULL, but
accesses the memory with incorrect alignment::

  BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_LD_MAP_FD(BPF_REG_1, 0),
  BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
  BPF_ST_MEM(BPF_DW, BPF_REG_0, 4, 0),
  BPF_EXIT_INSN(),

Error::

  0: (7a) *(u64 *)(r10 -8) = 0
  1: (bf) r2 = r10
  2: (07) r2 += -8
  3: (b7) r1 = 1
  4: (85) call 1
  5: (15) if r0 == 0x0 goto pc+1
   R0=map_ptr R10=fp
  6: (7a) *(u64 *)(r0 +4) = 0
  misaligned access off 4 size 8

Program that correctly checks map_lookup_elem() returned value for NULL and
accesses memory with correct alignment in one side of 'if' branch, but fails
to do so in the other side of 'if' branch::

  BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_LD_MAP_FD(BPF_REG_1, 0),
  BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
  BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 0),
  BPF_EXIT_INSN(),
  BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 1),
  BPF_EXIT_INSN(),

Error::

  0: (7a) *(u64 *)(r10 -8) = 0
  1: (bf) r2 = r10
  2: (07) r2 += -8
  3: (b7) r1 = 1
  4: (85) call 1
  5: (15) if r0 == 0x0 goto pc+2
   R0=map_ptr R10=fp
  6: (7a) *(u64 *)(r0 +0) = 0
  7: (95) exit

  from 5 to 8: R0=imm0 R10=fp
  8: (7a) *(u64 *)(r0 +0) = 1
  R0 invalid mem access 'imm'

Program that performs a socket lookup then sets the pointer to NULL without
checking it::

  BPF_MOV64_IMM(BPF_REG_2, 0),
  BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_MOV64_IMM(BPF_REG_3, 4),
  BPF_MOV64_IMM(BPF_REG_4, 0),
  BPF_MOV64_IMM(BPF_REG_5, 0),
  BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
  BPF_MOV64_IMM(BPF_REG_0, 0),
  BPF_EXIT_INSN(),

Error::

  0: (b7) r2 = 0
  1: (63) *(u32 *)(r10 -8) = r2
  2: (bf) r2 = r10
  3: (07) r2 += -8
  4: (b7) r3 = 4
  5: (b7) r4 = 0
  6: (b7) r5 = 0
  7: (85) call bpf_sk_lookup_tcp#65
  8: (b7) r0 = 0
  9: (95) exit
  Unreleased reference id=1, alloc_insn=7

Program that performs a socket lookup but does not NULL-check the returned
value::

  BPF_MOV64_IMM(BPF_REG_2, 0),
  BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_2, -8),
  BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
  BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  BPF_MOV64_IMM(BPF_REG_3, 4),
  BPF_MOV64_IMM(BPF_REG_4, 0),
  BPF_MOV64_IMM(BPF_REG_5, 0),
  BPF_EMIT_CALL(BPF_FUNC_sk_lookup_tcp),
  BPF_EXIT_INSN(),

Error::

  0: (b7) r2 = 0
  1: (63) *(u32 *)(r10 -8) = r2
  2: (bf) r2 = r10
  3: (07) r2 += -8
  4: (b7) r3 = 4
  5: (b7) r4 = 0
  6: (b7) r5 = 0
  7: (85) call bpf_sk_lookup_tcp#65
  8: (95) exit
  Unreleased reference id=1, alloc_insn=7


code:
=======================
A Linux CD-ROM standard
=======================

:Author: David van Leeuwen <david@ElseWare.cistron.nl>
:Date: 12 March 1999
:Updated by: Erik Andersen (andersee@debian.org)
:Updated by: Jens Axboe (axboe@image.dk)

Introduction
============

Linux is probably the Unix-like operating system that supports
the widest variety of hardware devices. The reasons for this are
presumably

- The large list of hardware devices available for the many platforms
  that Linux now supports (i.e., i386-PCs, Sparc Suns, etc.)
- The open design of the operating system, such that anybody can write a
  driver for Linux.
- There is plenty of source code around as examples of how to write a driver.

The openness of Linux, and the many different types of available
hardware has allowed Linux to support many different hardware devices.
Unfortunately, the very openness that has allowed Linux to support
all these different devices has also allowed the behavior of each
device driver to differ significantly from one device to another.
This divergence of behavior has been very significant for CD-ROM
devices; the way a particular drive reacts to a `standard` *ioctl()*
call varies greatly from one device driver to another. To avoid making
their drivers totally inconsistent, the writers of Linux CD-ROM
drivers generally created new device drivers by understanding, copying,
and then changing an existing one. Unfortunately, this practice did not
maintain uniform behavior across all the Linux CD-ROM drivers.

This document describes an effort to establish Uniform behavior across
all the different CD-ROM device drivers for Linux. This document also
defines the various *ioctl()'s*, and how the low-level CD-ROM device
drivers should implement them. Currently (as of the Linux 2.1.\ *x*
development kernels) several low-level CD-ROM device drivers, including
both IDE/ATAPI and SCSI, now use this Uniform interface.

When the CD-ROM was developed, the interface between the CD-ROM drive
and the computer was not specified in the standards. As a result, many
different CD-ROM interfaces were developed. Some of them had their
own proprietary design (Sony, Mitsumi, Panasonic, Philips), other
manufacturers adopted an existing electrical interface and changed
the functionality (CreativeLabs/SoundBlaster, Teac, Funai) or simply
adapted their drives to one or more of the already existing electrical
interfaces (Aztech, Sanyo, Funai, Vertos, Longshine, Optics Storage and
most of the `NoName` manufacturers). In cases where a new drive really
brought its own interface or used its own command set and flow control
scheme, either a separate driver had to be written, or an existing
driver had to be enhanced. History has delivered us CD-ROM support for
many of these different interfaces. Nowadays, almost all new CD-ROM
drives are either IDE/ATAPI or SCSI, and it is very unlikely that any
manufacturer will create a new interface. Even finding drives for the
old proprietary interfaces is getting difficult.

When (in the 1.3.70's) I looked at the existing software interface,
which was expressed through `cdrom.h`, it appeared to be a rather wild
set of commands and data formats [#f1]_. It seemed that many
features of the software interface had been added to accommodate the
capabilities of a particular drive, in an *ad hoc* manner. More
importantly, it appeared that the behavior of the `standard` commands
was different for most of the different drivers: e. g., some drivers
close the tray if an *open()* call occurs when the tray is open, while
others do not. Some drivers lock the door upon opening the device, to
prevent an incoherent file system, but others don't, to allow software
ejection. Undoubtedly, the capabilities of the different drives vary,
but even when two drives have the same capability their drivers'
behavior was usually different.

.. [#f1]
   I cannot recollect what kernel version I looked at, then,
   presumably 1.2.13 and 1.3.34 --- the latest kernel that I was
   indirectly involved in.

I decided to start a discussion on how to make all the Linux CD-ROM
drivers behave more uniformly. I began by contacting the developers of
the many CD-ROM drivers found in the Linux kernel. Their reactions
encouraged me to write the Uniform CD-ROM Driver which this document is
intended to describe. The implementation of the Uniform CD-ROM Driver is
in the file `cdrom.c`. This driver is intended to be an additional software
layer that sits on top of the low-level device drivers for each CD-ROM drive.
By adding this additional layer, it is possible to have all the different
CD-ROM devices behave **exactly** the same (insofar as the underlying
hardware will allow).

The goal of the Uniform CD-ROM Driver is **not** to alienate driver developers
whohave not yet taken steps to support this effort. The goal of Uniform CD-ROM
Driver is simply to give people writing application programs for CD-ROM drives
**one** Linux CD-ROM interface with consistent behavior for all
CD-ROM devices. In addition, this also provides a consistent interface
between the low-level device driver code and the Linux kernel. Care
is taken that 100% compatibility exists with the data structures and
programmer's interface defined in `cdrom.h`. This guide was written to
help CD-ROM driver developers adapt their code to use the Uniform CD-ROM
Driver code defined in `cdrom.c`.

Personally, I think that the most important hardware interfaces are
the IDE/ATAPI drives and, of course, the SCSI drives, but as prices
of hardware drop continuously, it is also likely that people may have
more than one CD-ROM drive, possibly of mixed types. It is important
that these drives behave in the same way. In December 1994, one of the
cheapest CD-ROM drives was a Philips cm206, a double-speed proprietary
drive. In the months that I was busy writing a Linux driver for it,
proprietary drives became obsolete and IDE/ATAPI drives became the
standard. At the time of the last update to this document (November
1997) it is becoming difficult to even **find** anything less than a
16 speed CD-ROM drive, and 24 speed drives are common.

.. _cdrom_api:

Standardizing through another software level
============================================

At the time this document was conceived, all drivers directly
implemented the CD-ROM *ioctl()* calls through their own routines. This
led to the danger of different drivers forgetting to do important things
like checking that the user was giving the driver valid data. More
importantly, this led to the divergence of behavior, which has already
been discussed.

For this reason, the Uniform CD-ROM Driver was created to enforce consistent
CD-ROM drive behavior, and to provide a common set of services to the various
low-level CD-ROM device drivers. The Uniform CD-ROM Driver now provides another
software-level, that separates the *ioctl()* and *open()* implementation
from the actual hardware implementation. Note that this effort has
made few changes which will affect a user's application programs. The
greatest change involved moving the contents of the various low-level
CD-ROM drivers\' header files to the kernel's cdrom directory. This was
done to help ensure that the user is only presented with only one cdrom
interface, the interface defined in `cdrom.h`.

CD-ROM drives are specific enough (i. e., different from other
block-devices such as floppy or hard disc drives), to define a set
of common **CD-ROM device operations**, *<cdrom-device>_dops*.
These operations are different from the classical block-device file
operations, *<block-device>_fops*.

The routines for the Uniform CD-ROM Driver interface level are implemented
in the file `cdrom.c`. In this file, the Uniform CD-ROM Driver interfaces
with the kernel as a block device by registering the following general
*struct file_operations*::

	struct file_operations cdrom_fops = {
		NULL,			/* lseek */
		block _read ,		/* read--general block-dev read */
		block _write,		/* write--general block-dev write */
		NULL,			/* readdir */
		NULL,			/* select */
		cdrom_ioctl,		/* ioctl */
		NULL,			/* mmap */
		cdrom_open,		/* open */
		cdrom_release,		/* release */
		NULL,			/* fsync */
		NULL,			/* fasync */
		NULL			/* revalidate */
	};

Every active CD-ROM device shares this *struct*. The routines
declared above are all implemented in `cdrom.c`, since this file is the
place where the behavior of all CD-ROM-devices is defined and
standardized. The actual interface to the various types of CD-ROM
hardware is still performed by various low-level CD-ROM-device
drivers. These routines simply implement certain **capabilities**
that are common to all CD-ROM (and really, all removable-media
devices).

Registration of a low-level CD-ROM device driver is now done through
the general routines in `cdrom.c`, not through the Virtual File System
(VFS) any more. The interface implemented in `cdrom.c` is carried out
through two general structures that contain information about the
capabilities of the driver, and the specific drives on which the
driver operates. The structures are:

cdrom_device_ops
  This structure contains information about the low-level driver for a
  CD-ROM device. This structure is conceptually connected to the major
  number of the device (although some drivers may have different
  major numbers, as is the case for the IDE driver).

cdrom_device_info
  This structure contains information about a particular CD-ROM drive,
  such as its device name, speed, etc. This structure is conceptually
  connected to the minor number of the device.

Registering a particular CD-ROM drive with the Uniform CD-ROM Driver
is done by the low-level device driver though a call to::

	register_cdrom(struct cdrom_device_info * <device>_info)

The device information structure, *<device>_info*, contains all the
information needed for the kernel to interface with the low-level
CD-ROM device driver. One of the most important entries in this
structure is a pointer to the *cdrom_device_ops* structure of the
low-level driver.

The device operations structure, *cdrom_device_ops*, contains a list
of pointers to the functions which are implemented in the low-level
device driver. When `cdrom.c` accesses a CD-ROM device, it does it
through the functions in this structure. It is impossible to know all
the capabilities of future CD-ROM drives, so it is expected that this
list may need to be expanded from time to time as new technologies are
developed. For example, CD-R and CD-R/W drives are beginning to become
popular, and support will soon need to be added for them. For now, the
current *struct* is::

	struct cdrom_device_ops {
		int (*open)(struct cdrom_device_info *, int)
		void (*release)(struct cdrom_device_info *);
		int (*drive_status)(struct cdrom_device_info *, int);
		unsigned int (*check_events)(struct cdrom_device_info *,
					     unsigned int, int);
		int (*media_changed)(struct cdrom_device_info *, int);
		int (*tray_move)(struct cdrom_device_info *, int);
		int (*lock_door)(struct cdrom_device_info *, int);
		int (*select_speed)(struct cdrom_device_info *, int);
		int (*get_last_session) (struct cdrom_device_info *,
					 struct cdrom_multisession *);
		int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *);
		int (*reset)(struct cdrom_device_info *);
		int (*audio_ioctl)(struct cdrom_device_info *,
				   unsigned int, void *);
		const int capability;		/* capability flags */
		int (*generic_packet)(struct cdrom_device_info *,
				      struct packet_command *);
	};

When a low-level device driver implements one of these capabilities,
it should add a function pointer to this *struct*. When a particular
function is not implemented, however, this *struct* should contain a
NULL instead. The *capability* flags specify the capabilities of the
CD-ROM hardware and/or low-level CD-ROM driver when a CD-ROM drive
is registered with the Uniform CD-ROM Driver.

Note that most functions have fewer parameters than their
*blkdev_fops* counterparts. This is because very little of the
information in the structures *inode* and *file* is used. For most
drivers, the main parameter is the *struct* *cdrom_device_info*, from
which the major and minor number can be extracted. (Most low-level
CD-ROM drivers don't even look at the major and minor number though,
since many of them only support one device.) This will be available
through *dev* in *cdrom_device_info* described below.

The drive-specific, minor-like information that is registered with
`cdrom.c`, currently contains the following fields::

  struct cdrom_device_info {
	const struct cdrom_device_ops * ops;	/* device operations for this major */
	struct list_head list;			/* linked list of all device_info */
	struct gendisk * disk;			/* matching block layer disk */
	void *  handle;				/* driver-dependent data */

	int mask;				/* mask of capability: disables them */
	int speed;				/* maximum speed for reading data */
	int capacity;				/* number of discs in a jukebox */

	unsigned int options:30;		/* options flags */
	unsigned mc_flags:2;			/*  media-change buffer flags */
	unsigned int vfs_events;		/*  cached events for vfs path */
	unsigned int ioctl_events;		/*  cached events for ioctl path */
	int use_count;				/*  number of times device is opened */
	char name[20];				/*  name of the device type */

	__u8 sanyo_slot : 2;			/*  Sanyo 3-CD changer support */
	__u8 keeplocked : 1;			/*  CDROM_LOCKDOOR status */
	__u8 reserved : 5;			/*  not used yet */
	int cdda_method;			/*  see CDDA_* flags */
	__u8 last_sense;			/*  saves last sense key */
	__u8 media_written;			/*  dirty flag, DVD+RW bookkeeping */
	unsigned short mmc3_profile;		/*  current MMC3 profile */
	int for_data;				/*  unknown:TBD */
	int (*exit)(struct cdrom_device_info *);/*  unknown:TBD */
	int mrw_mode_page;			/*  which MRW mode page is in use */
  };

Using this *struct*, a linked list of the registered minor devices is
built, using the *next* field. The device number, the device operations
struct and specifications of properties of the drive are stored in this
structure.

The *mask* flags can be used to mask out some of the capabilities listed
in *ops->capability*, if a specific drive doesn't support a feature
of the driver. The value *speed* specifies the maximum head-rate of the
drive, measured in units of normal audio speed (176kB/sec raw data or
150kB/sec file system data). The parameters are declared *const*
because they describe properties of the drive, which don't change after
registration.

A few registers contain variables local to the CD-ROM drive. The
flags *options* are used to specify how the general CD-ROM routines
should behave. These various flags registers should provide enough
flexibility to adapt to the different users' wishes (and **not** the
`arbitrary` wishes of the author of the low-level device driver, as is
the case in the old scheme). The register *mc_flags* is used to buffer
the information from *media_changed()* to two separate queues. Other
data that is specific to a minor drive, can be accessed through *handle*,
which can point to a data structure specific to the low-level driver.
The fields *use_count*, *next*, *options* and *mc_flags* need not be
initialized.

The intermediate software layer that `cdrom.c` forms will perform some
additional bookkeeping. The use count of the device (the number of
processes that have the device opened) is registered in *use_count*. The
function *cdrom_ioctl()* will verify the appropriate user-memory regions
for read and write, and in case a location on the CD is transferred,
it will `sanitize` the format by making requests to the low-level
drivers in a standard format, and translating all formats between the
user-software and low level drivers. This relieves much of the drivers'
memory checking and format checking and translation. Also, the necessary
structures will be declared on the program stack.

The implementation of the functions should be as defined in the
following sections. Two functions **must** be implemented, namely
*open()* and *release()*. Other functions may be omitted, their
corresponding capability flags will be cleared upon registration.
Generally, a function returns zero on success and negative on error. A
function call should return only after the command has completed, but of
course waiting for the device should not use processor time.

::

	int open(struct cdrom_device_info *cdi, int purpose)

*Open()* should try to open the device for a specific *purpose*, which
can be either:

- Open for reading data, as done by `mount()` (2), or the
  user commands `dd` or `cat`.
- Open for *ioctl* commands, as done by audio-CD playing programs.

Notice that any strategic code (closing tray upon *open()*, etc.) is
done by the calling routine in `cdrom.c`, so the low-level routine
should only be concerned with proper initialization, such as spinning
up the disc, etc.

::

	void release(struct cdrom_device_info *cdi)

Device-specific actions should be taken such as spinning down the device.
However, strategic actions such as ejection of the tray, or unlocking
the door, should be left over to the general routine *cdrom_release()*.
This is the only function returning type *void*.

.. _cdrom_drive_status:

::

	int drive_status(struct cdrom_device_info *cdi, int slot_nr)

The function *drive_status*, if implemented, should provide
information on the status of the drive (not the status of the disc,
which may or may not be in the drive). If the drive is not a changer,
*slot_nr* should be ignored. In `cdrom.h` the possibilities are listed::

	CDS_NO_INFO		/* no information available */
	CDS_NO_DISC		/* no disc is inserted, tray is closed */
	CDS_TRAY_OPEN		/* tray is opened */
	CDS_DRIVE_NOT_READY	/* something is wrong, tray is moving? */
	CDS_DISC_OK		/* a disc is loaded and everything is fine */

::

	int tray_move(struct cdrom_device_info *cdi, int position)

This function, if implemented, should control the tray movement. (No
other function should control this.) The parameter *position* controls
the desired direction of movement:

- 0 Close tray
- 1 Open tray

This function returns 0 upon success, and a non-zero value upon
error. Note that if the tray is already in the desired position, no
action need be taken, and the return value should be 0.

::

	int lock_door(struct cdrom_device_info *cdi, int lock)

This function (and no other code) controls locking of the door, if the
drive allows this. The value of *lock* controls the desired locking
state:

- 0 Unlock door, manual opening is allowed
- 1 Lock door, tray cannot be ejected manually

This function returns 0 upon success, and a non-zero value upon
error. Note that if the door is already in the requested state, no
action need be taken, and the return value should be 0.

::

	int select_speed(struct cdrom_device_info *cdi, int speed)

Some CD-ROM drives are capable of changing their head-speed. There
are several reasons for changing the speed of a CD-ROM drive. Badly
pressed CD-ROM s may benefit from less-than-maximum head rate. Modern
CD-ROM drives can obtain very high head rates (up to *24x* is
common). It has been reported that these drives can make reading
errors at these high speeds, reducing the speed can prevent data loss
in these circumstances. Finally, some of these drives can
make an annoyingly loud noise, which a lower speed may reduce.

This function specifies the speed at which data is read or audio is
played back. The value of *speed* specifies the head-speed of the
drive, measured in units of standard cdrom speed (176kB/sec raw data
or 150kB/sec file system data). So to request that a CD-ROM drive
operate at 300kB/sec you would call the CDROM_SELECT_SPEED *ioctl*
with *speed=2*. The special value `0` means `auto-selection`, i. e.,
maximum data-rate or real-time audio rate. If the drive doesn't have
this `auto-selection` capability, the decision should be made on the
current disc loaded and the return value should be positive. A negative
return value indicates an error.

::

	int get_last_session(struct cdrom_device_info *cdi,
			     struct cdrom_multisession *ms_info)

This function should implement the old corresponding *ioctl()*. For
device *cdi->dev*, the start of the last session of the current disc
should be returned in the pointer argument *ms_info*. Note that
routines in `cdrom.c` have sanitized this argument: its requested
format will **always** be of the type *CDROM_LBA* (linear block
addressing mode), whatever the calling software requested. But
sanitization goes even further: the low-level implementation may
return the requested information in *CDROM_MSF* format if it wishes so
(setting the *ms_info->addr_format* field appropriately, of
course) and the routines in `cdrom.c` will make the transformation if
necessary. The return value is 0 upon success.

::

	int get_mcn(struct cdrom_device_info *cdi,
		    struct cdrom_mcn *mcn)

Some discs carry a `Media Catalog Number` (MCN), also called
`Universal Product Code` (UPC). This number should reflect the number
that is generally found in the bar-code on the product. Unfortunately,
the few discs that carry such a number on the disc don't even use the
same format. The return argument to this function is a pointer to a
pre-declared memory region of type *struct cdrom_mcn*. The MCN is
expected as a 13-character string, terminated by a null-character.

::

	int reset(struct cdrom_device_info *cdi)

This call should perform a hard-reset on the drive (although in
circumstances that a hard-reset is necessary, a drive may very well not
listen to commands anymore). Preferably, control is returned to the
caller only after the drive has finished resetting. If the drive is no
longer listening, it may be wise for the underlying low-level cdrom
driver to time out.

::

	int audio_ioctl(struct cdrom_device_info *cdi,
			unsigned int cmd, void *arg)

Some of the CD-ROM-\ *ioctl()*\ 's defined in `cdrom.h` can be
implemented by the routines described above, and hence the function
*cdrom_ioctl* will use those. However, most *ioctl()*\ 's deal with
audio-control. We have decided to leave these to be accessed through a
single function, repeating the arguments *cmd* and *arg*. Note that
the latter is of type *void*, rather than *unsigned long int*.
The routine *cdrom_ioctl()* does do some useful things,
though. It sanitizes the address format type to *CDROM_MSF* (Minutes,
Seconds, Frames) for all audio calls. It also verifies the memory
location of *arg*, and reserves stack-memory for the argument. This
makes implementation of the *audio_ioctl()* much simpler than in the
old driver scheme. For example, you may look up the function
*cm206_audio_ioctl()* `cm206.c` that should be updated with
this documentation.

An unimplemented ioctl should return *-ENOSYS*, but a harmless request
(e. g., *CDROMSTART*) may be ignored by returning 0 (success). Other
errors should be according to the standards, whatever they are. When
an error is returned by the low-level driver, the Uniform CD-ROM Driver
tries whenever possible to return the error code to the calling program.
(We may decide to sanitize the return value in *cdrom_ioctl()* though, in
order to guarantee a uniform interface to the audio-player software.)

::

	int dev_ioctl(struct cdrom_device_info *cdi,
		      unsigned int cmd, unsigned long arg)

Some *ioctl()'s* seem to be specific to certain CD-ROM drives. That is,
they are introduced to service some capabilities of certain drives. In
fact, there are 6 different *ioctl()'s* for reading data, either in some
particular kind of format, or audio data. Not many drives support
reading audio tracks as data, I believe this is because of protection
of copyrights of artists. Moreover, I think that if audio-tracks are
supported, it should be done through the VFS and not via *ioctl()'s*. A
problem here could be the fact that audio-frames are 2352 bytes long,
so either the audio-file-system should ask for 75264 bytes at once
(the least common multiple of 512 and 2352), or the drivers should
bend their backs to cope with this incoherence (to which I would be
opposed). Furthermore, it is very difficult for the hardware to find
the exact frame boundaries, since there are no synchronization headers
in audio frames. Once these issues are resolved, this code should be
standardized in `cdrom.c`.

Because there are so many *ioctl()'s* that seem to be introduced to
satisfy certain drivers [#f2]_, any non-standard *ioctl()*\ s
are routed through the call *dev_ioctl()*. In principle, `private`
*ioctl()*\ 's should be numbered after the device's major number, and not
the general CD-ROM *ioctl* number, `0x53`. Currently the
non-supported *ioctl()'s* are:

	CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, CDROMREADRAW,
	CDROMREADCOOKED, CDROMSEEK, CDROMPLAY-BLK and CDROM-READALL

.. [#f2]

   Is there software around that actually uses these? I'd be interested!

.. _cdrom_capabilities:

CD-ROM capabilities
-------------------

Instead of just implementing some *ioctl* calls, the interface in
`cdrom.c` supplies the possibility to indicate the **capabilities**
of a CD-ROM drive. This can be done by ORing any number of
capability-constants that are defined in `cdrom.h` at the registration
phase. Currently, the capabilities are any of::

	CDC_CLOSE_TRAY		/* can close tray by software control */
	CDC_OPEN_TRAY		/* can open tray */
	CDC_LOCK		/* can lock and unlock the door */
	CDC_SELECT_SPEED	/* can select speed, in units of * sim*150 ,kB/s */
	CDC_SELECT_DISC		/* drive is juke-box */
	CDC_MULTI_SESSION	/* can read sessions *> rm1* */
	CDC_MCN			/* can read Media Catalog Number */
	CDC_MEDIA_CHANGED	/* can report if disc has changed */
	CDC_PLAY_AUDIO		/* can perform audio-functions (play, pause, etc) */
	CDC_RESET		/* hard reset device */
	CDC_IOCTLS		/* driver has non-standard ioctls */
	CDC_DRIVE_STATUS	/* driver implements drive status */

The capability flag is declared *const*, to prevent drivers from
accidentally tampering with the contents. The capability flags actually
inform `cdrom.c` of what the driver can do. If the drive found
by the driver does not have the capability, is can be masked out by
the *cdrom_device_info* variable *mask*. For instance, the SCSI CD-ROM
driver has implemented the code for loading and ejecting CD-ROM's, and
hence its corresponding flags in *capability* will be set. But a SCSI
CD-ROM drive might be a caddy system, which can't load the tray, and
hence for this drive the *cdrom_device_info* struct will have set
the *CDC_CLOSE_TRAY* bit in *mask*.

In the file `cdrom.c` you will encounter many constructions of the type::

	if (cdo->capability & ~cdi->mask & CDC _<capability>) ...

There is no *ioctl* to set the mask... The reason is that
I think it is better to control the **behavior** rather than the
**capabilities**.

Options
-------

A final flag register controls the **behavior** of the CD-ROM
drives, in order to satisfy different users' wishes, hopefully
independently of the ideas of the respective author who happened to
have made the drive's support available to the Linux community. The
current behavior options are::

	CDO_AUTO_CLOSE	/* try to close tray upon device open() */
	CDO_AUTO_EJECT	/* try to open tray on last device close() */
	CDO_USE_FFLAGS	/* use file_pointer->f_flags to indicate purpose for open() */
	CDO_LOCK	/* try to lock door if device is opened */
	CDO_CHECK_TYPE	/* ensure disc type is data if opened for data */

The initial value of this register is
`CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK`, reflecting my own view on user
interface and software standards. Before you protest, there are two
new *ioctl()'s* implemented in `cdrom.c`, that allow you to control the
behavior by software. These are::

	CDROM_SET_OPTIONS	/* set options specified in (int)arg */
	CDROM_CLEAR_OPTIONS	/* clear options specified in (int)arg */

One option needs some more explanation: *CDO_USE_FFLAGS*. In the next
newsection we explain what the need for this option is.

A software package `setcd`, available from the Debian distribution
and `sunsite.unc.edu`, allows user level control of these flags.

The need to know the purpose of opening the CD-ROM device
=========================================================

Traditionally, Unix devices can be used in two different `modes`,
either by reading/writing to the device file, or by issuing
controlling commands to the device, by the device's *ioctl()*
call. The problem with CD-ROM drives, is that they can be used for
two entirely different purposes. One is to mount removable
file systems, CD-ROM's, the other is to play audio CD's. Audio commands
are implemented entirely through *ioctl()\'s*, presumably because the
first implementation (SUN?) has been such. In principle there is
nothing wrong with this, but a good control of the `CD player` demands
that the device can **always** be opened in order to give the
*ioctl* commands, regardless of the state the drive is in.

On the other hand, when used as a removable-media disc drive (what the
original purpose of CD-ROM s is) we would like to make sure that the
disc drive is ready for operation upon opening the device. In the old
scheme, some CD-ROM drivers don't do any integrity checking, resulting
in a number of i/o errors reported by the VFS to the kernel when an
attempt for mounting a CD-ROM on an empty drive occurs. This is not a
particularly elegant way to find out that there is no CD-ROM inserted;
it more-or-less looks like the old IBM-PC trying to read an empty floppy
drive for a couple of seconds, after which the system complains it
can't read from it. Nowadays we can **sense** the existence of a
removable medium in a drive, and we believe we should exploit that
fact. An integrity check on opening of the device, that verifies the
availability of a CD-ROM and its correct type (data), would be
desirable.

These two ways of using a CD-ROM drive, principally for data and
secondarily for playing audio discs, have different demands for the
behavior of the *open()* call. Audio use simply wants to open the
device in order to get a file handle which is needed for issuing
*ioctl* commands, while data use wants to open for correct and
reliable data transfer. The only way user programs can indicate what
their *purpose* of opening the device is, is through the *flags*
parameter (see `open(2)`). For CD-ROM devices, these flags aren't
implemented (some drivers implement checking for write-related flags,
but this is not strictly necessary if the device file has correct
permission flags). Most option flags simply don't make sense to
CD-ROM devices: *O_CREAT*, *O_NOCTTY*, *O_TRUNC*, *O_APPEND*, and
*O_SYNC* have no meaning to a CD-ROM.

We therefore propose to use the flag *O_NONBLOCK* to indicate
that the device is opened just for issuing *ioctl*
commands. Strictly, the meaning of *O_NONBLOCK* is that opening and
subsequent calls to the device don't cause the calling process to
wait. We could interpret this as don't wait until someone has
inserted some valid data-CD-ROM. Thus, our proposal of the
implementation for the *open()* call for CD-ROM s is:

- If no other flags are set than *O_RDONLY*, the device is opened
  for data transfer, and the return value will be 0 only upon successful
  initialization of the transfer. The call may even induce some actions
  on the CD-ROM, such as closing the tray.
- If the option flag *O_NONBLOCK* is set, opening will always be
  successful, unless the whole device doesn't exist. The drive will take
  no actions whatsoever.

And what about standards?
-------------------------

You might hesitate to accept this proposal as it comes from the
Linux community, and not from some standardizing institute. What
about SUN, SGI, HP and all those other Unix and hardware vendors?
Well, these companies are in the lucky position that they generally
control both the hardware and software of their supported products,
and are large enough to set their own standard. They do not have to
deal with a dozen or more different, competing hardware
configurations\ [#f3]_.

.. [#f3]

   Incidentally, I think that SUN's approach to mounting CD-ROM s is very
   good in origin: under Solaris a volume-daemon automatically mounts a
   newly inserted CD-ROM under `/cdrom/*<volume-name>*`.

   In my opinion they should have pushed this
   further and have **every** CD-ROM on the local area network be
   mounted at the similar location, i. e., no matter in which particular
   machine you insert a CD-ROM, it will always appear at the same
   position in the directory tree, on every system. When I wanted to
   implement such a user-program for Linux, I came across the
   differences in behavior of the various drivers, and the need for an
   *ioctl* informing about media changes.

We believe that using *O_NONBLOCK* to indicate that a device is being opened
for *ioctl* commands only can be easily introduced in the Linux
community. All the CD-player authors will have to be informed, we can
even send in our own patches to the programs. The use of *O_NONBLOCK*
has most likely no influence on the behavior of the CD-players on
other operating systems than Linux. Finally, a user can always revert
to old behavior by a call to
*ioctl(file_descriptor, CDROM_CLEAR_OPTIONS, CDO_USE_FFLAGS)*.

The preferred strategy of *open()*
----------------------------------

The routines in `cdrom.c` are designed in such a way that run-time
configuration of the behavior of CD-ROM devices (of **any** type)
can be carried out, by the *CDROM_SET/CLEAR_OPTIONS* *ioctls*. Thus, various
modes of operation can be set:

`CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK`
   This is the default setting. (With *CDO_CHECK_TYPE* it will be better, in
   the future.) If the device is not yet opened by any other process, and if
   the device is being opened for data (*O_NONBLOCK* is not set) and the
   tray is found to be open, an attempt to close the tray is made. Then,
   it is verified that a disc is in the drive and, if *CDO_CHECK_TYPE* is
   set, that it contains tracks of type `data mode 1`. Only if all tests
   are passed is the return value zero. The door is locked to prevent file
   system corruption. If the drive is opened for audio (*O_NONBLOCK* is
   set), no actions are taken and a value of 0 will be returned.

`CDO_AUTO_CLOSE | CDO_AUTO_EJECT | CDO_LOCK`
   This mimics the behavior of the current sbpcd-driver. The option flags are
   ignored, the tray is closed on the first open, if necessary. Similarly,
   the tray is opened on the last release, i. e., if a CD-ROM is unmounted,
   it is automatically ejected, such that the user can replace it.

We hope that these option can convince everybody (both driver
maintainers and user program developers) to adopt the new CD-ROM
driver scheme and option flag interpretation.

Description of routines in `cdrom.c`
====================================

Only a few routines in `cdrom.c` are exported to the drivers. In this
new section we will discuss these, as well as the functions that `take
over` the CD-ROM interface to the kernel. The header file belonging
to `cdrom.c` is called `cdrom.h`. Formerly, some of the contents of this
file were placed in the file `ucdrom.h`, but this file has now been
merged back into `cdrom.h`.

::

	struct file_operations cdrom_fops

The contents of this structure were described in cdrom_api_.
A pointer to this structure is assigned to the *fops* field
of the *struct gendisk*.

::

	int register_cdrom(struct cdrom_device_info *cdi)

This function is used in about the same way one registers *cdrom_fops*
with the kernel, the device operations and information structures,
as described in cdrom_api_, should be registered with the
Uniform CD-ROM Driver::

	register_cdrom(&<device>_info);

This function returns zero upon success, and non-zero upon
failure. The structure *<device>_info* should have a pointer to the
driver's *<device>_dops*, as in::

	struct cdrom_device_info <device>_info = {
		<device>_dops;
		...
	}

Note that a driver must have one static structure, *<device>_dops*, while
it may have as many structures *<device>_info* as there are minor devices
active. *Register_cdrom()* builds a linked list from these.

::

	void unregister_cdrom(struct cdrom_device_info *cdi)

Unregistering device *cdi* with minor number *MINOR(cdi->dev)* removes
the minor device from the list. If it was the last registered minor for
the low-level driver, this disconnects the registered device-operation
routines from the CD-ROM interface. This function returns zero upon
success, and non-zero upon failure.

::

	int cdrom_open(struct inode * ip, struct file * fp)

This function is not called directly by the low-level drivers, it is
listed in the standard *cdrom_fops*. If the VFS opens a file, this
function becomes active. A strategy is implemented in this routine,
taking care of all capabilities and options that are set in the
*cdrom_device_ops* connected to the device. Then, the program flow is
transferred to the device_dependent *open()* call.

::

	void cdrom_release(struct inode *ip, struct file *fp)

This function implements the reverse-logic of *cdrom_open()*, and then
calls the device-dependent *release()* routine. When the use-count has
reached 0, the allocated buffers are flushed by calls to *sync_dev(dev)*
and *invalidate_buffers(dev)*.

.. _cdrom_ioctl:

::

	int cdrom_ioctl(struct inode *ip, struct file *fp,
			unsigned int cmd, unsigned long arg)

This function handles all the standard *ioctl* requests for CD-ROM
devices in a uniform way. The different calls fall into three
categories: *ioctl()'s* that can be directly implemented by device
operations, ones that are routed through the call *audio_ioctl()*, and
the remaining ones, that are presumable device-dependent. Generally, a
negative return value indicates an error.

Directly implemented *ioctl()'s*
--------------------------------

The following `old` CD-ROM *ioctl()*\ 's are implemented by directly
calling device-operations in *cdrom_device_ops*, if implemented and
not masked:

`CDROMMULTISESSION`
	Requests the last session on a CD-ROM.
`CDROMEJECT`
	Open tray.
`CDROMCLOSETRAY`
	Close tray.
`CDROMEJECT_SW`
	If *arg\not=0*, set behavior to auto-close (close
	tray on first open) and auto-eject (eject on last release), otherwise
	set behavior to non-moving on *open()* and *release()* calls.
`CDROM_GET_MCN`
	Get the Media Catalog Number from a CD.

*Ioctl*s routed through *audio_ioctl()*
---------------------------------------

The following set of *ioctl()'s* are all implemented through a call to
the *cdrom_fops* function *audio_ioctl()*. Memory checks and
allocation are performed in *cdrom_ioctl()*, and also sanitization of
address format (*CDROM_LBA*/*CDROM_MSF*) is done.

`CDROMSUBCHNL`
	Get sub-channel data in argument *arg* of type
	`struct cdrom_subchnl *`.
`CDROMREADTOCHDR`
	Read Table of Contents header, in *arg* of type
	`struct cdrom_tochdr *`.
`CDROMREADTOCENTRY`
	Read a Table of Contents entry in *arg* and specified by *arg*
	of type `struct cdrom_tocentry *`.
`CDROMPLAYMSF`
	Play audio fragment specified in Minute, Second, Frame format,
	delimited by *arg* of type `struct cdrom_msf *`.
`CDROMPLAYTRKIND`
	Play audio fragment in track-index format delimited by *arg*
	of type `struct cdrom_ti *`.
`CDROMVOLCTRL`
	Set volume specified by *arg* of type `struct cdrom_volctrl *`.
`CDROMVOLREAD`
	Read volume into by *arg* of type `struct cdrom_volctrl *`.
`CDROMSTART`
	Spin up disc.
`CDROMSTOP`
	Stop playback of audio fragment.
`CDROMPAUSE`
	Pause playback of audio fragment.
`CDROMRESUME`
	Resume playing.

New *ioctl()'s* in `cdrom.c`
----------------------------

The following *ioctl()'s* have been introduced to allow user programs to
control the behavior of individual CD-ROM devices. New *ioctl*
commands can be identified by the underscores in their names.

`CDROM_SET_OPTIONS`
	Set options specified by *arg*. Returns the option flag register
	after modification. Use *arg = \rm0* for reading the current flags.
`CDROM_CLEAR_OPTIONS`
	Clear options specified by *arg*. Returns the option flag register
	after modification.
`CDROM_SELECT_SPEED`
	Select head-rate speed of disc specified as by *arg* in units
	of standard cdrom speed (176\,kB/sec raw data or
	150kB/sec file system data). The value 0 means `auto-select`,
	i. e., play audio discs at real time and data discs at maximum speed.
	The value *arg* is checked against the maximum head rate of the
	drive found in the *cdrom_dops*.
`CDROM_SELECT_DISC`
	Select disc numbered *arg* from a juke-box.

	First disc is numbered 0. The number *arg* is checked against the
	maximum number of discs in the juke-box found in the *cdrom_dops*.
`CDROM_MEDIA_CHANGED`
	Returns 1 if a disc has been changed since the last call.
	For juke-boxes, an extra argument *arg*
	specifies the slot for which the information is given. The special
	value *CDSL_CURRENT* requests that information about the currently
	selected slot be returned.
`CDROM_TIMED_MEDIA_CHANGE`
	Checks whether the disc has been changed since a user supplied time
	and returns the time of the last disc change.

	*arg* is a pointer to a *cdrom_timed_media_change_info* struct.
	*arg->last_media_change* may be set by calling code to signal
	the timestamp of the last known media change (by the caller).
	Upon successful return, this ioctl call will set
	*arg->last_media_change* to the latest media change timestamp (in ms)
	known by the kernel/driver and set *arg->has_changed* to 1 if
	that timestamp is more recent than the timestamp set by the caller.
`CDROM_DRIVE_STATUS`
	Returns the status of the drive by a call to
	*drive_status()*. Return values are defined in cdrom_drive_status_.
	Note that this call doesn't return information on the
	current playing activity of the drive; this can be polled through
	an *ioctl* call to *CDROMSUBCHNL*. For juke-boxes, an extra argument
	*arg* specifies the slot for which (possibly limited) information is
	given. The special value *CDSL_CURRENT* requests that information
	about the currently selected slot be returned.
`CDROM_DISC_STATUS`
	Returns the type of the disc currently in the drive.
	It should be viewed as a complement to *CDROM_DRIVE_STATUS*.
	This *ioctl* can provide *some* information about the current
	disc that is inserted in the drive. This functionality used to be
	implemented in the low level drivers, but is now carried out
	entirely in Uniform CD-ROM Driver.

	The history of development of the CD's use as a carrier medium for
	various digital information has lead to many different disc types.
	This *ioctl* is useful only in the case that CDs have \emph {only
	one} type of data on them. While this is often the case, it is
	also very common for CDs to have some tracks with data, and some
	tracks with audio. Because this is an existing interface, rather
	than fixing this interface by changing the assumptions it was made
	under, thereby breaking all user applications that use this
	function, the Uniform CD-ROM Driver implements this *ioctl* as
	follows: If the CD in question has audio tracks on it, and it has
	absolutely no CD-I, XA, or data tracks on it, it will be reported
	as *CDS_AUDIO*. If it has both audio and data tracks, it will
	return *CDS_MIXED*. If there are no audio tracks on the disc, and
	if the CD in question has any CD-I tracks on it, it will be
	reported as *CDS_XA_2_2*. Failing that, if the CD in question
	has any XA tracks on it, it will be reported as *CDS_XA_2_1*.
	Finally, if the CD in question has any data tracks on it,
	it will be reported as a data CD (*CDS_DATA_1*).

	This *ioctl* can return::

		CDS_NO_INFO	/* no information available */
		CDS_NO_DISC	/* no disc is inserted, or tray is opened */
		CDS_AUDIO	/* Audio disc (2352 audio bytes/frame) */
		CDS_DATA_1	/* data disc, mode 1 (2048 user bytes/frame) */
		CDS_XA_2_1	/* mixed data (XA), mode 2, form 1 (2048 user bytes) */
		CDS_XA_2_2	/* mixed data (XA), mode 2, form 1 (2324 user bytes) */
		CDS_MIXED	/* mixed audio/data disc */

	For some information concerning frame layout of the various disc
	types, see a recent version of `cdrom.h`.

`CDROM_CHANGER_NSLOTS`
	Returns the number of slots in a juke-box.
`CDROMRESET`
	Reset the drive.
`CDROM_GET_CAPABILITY`
	Returns the *capability* flags for the drive. Refer to section
	cdrom_capabilities_ for more information on these flags.
`CDROM_LOCKDOOR`
	 Locks the door of the drive. `arg == 0` unlocks the door,
	 any other value locks it.
`CDROM_DEBUG`
	 Turns on debugging info. Only root is allowed to do this.
	 Same semantics as CDROM_LOCKDOOR.

Device dependent *ioctl()'s*
----------------------------

Finally, all other *ioctl()'s* are passed to the function *dev_ioctl()*,
if implemented. No memory allocation or verification is carried out.

How to update your driver
=========================

- Make a backup of your current driver.
- Get hold of the files `cdrom.c` and `cdrom.h`, they should be in
  the directory tree that came with this documentation.
- Make sure you include `cdrom.h`.
- Change the 3rd argument of *register_blkdev* from `&<your-drive>_fops`
  to `&cdrom_fops`.
- Just after that line, add the following to register with the Uniform
  CD-ROM Driver::

	register_cdrom(&<your-drive>_info);*

  Similarly, add a call to *unregister_cdrom()* at the appropriate place.
- Copy an example of the device-operations *struct* to your
  source, e. g., from `cm206.c` *cm206_dops*, and change all
  entries to names corresponding to your driver, or names you just
  happen to like. If your driver doesn't support a certain function,
  make the entry *NULL*. At the entry *capability* you should list all
  capabilities your driver currently supports. If your driver
  has a capability that is not listed, please send me a message.
- Copy the *cdrom_device_info* declaration from the same example
  driver, and modify the entries according to your needs. If your
  driver dynamically determines the capabilities of the hardware, this
  structure should also be declared dynamically.
- Implement all functions in your `<device>_dops` structure,
  according to prototypes listed in  `cdrom.h`, and specifications given
  in cdrom_api_. Most likely you have already implemented
  the code in a large part, and you will almost certainly need to adapt the
  prototype and return values.
- Rename your `<device>_ioctl()` function to *audio_ioctl* and
  change the prototype a little. Remove entries listed in the first
  part in cdrom_ioctl_, if your code was OK, these are
  just calls to the routines you adapted in the previous step.
- You may remove all remaining memory checking code in the
  *audio_ioctl()* function that deals with audio commands (these are
  listed in the second part of cdrom_ioctl_. There is no
  need for memory allocation either, so most *case*s in the *switch*
  statement look similar to::

	case CDROMREADTOCENTRY:
		get_toc_entry\bigl((struct cdrom_tocentry *) arg);

- All remaining *ioctl* cases must be moved to a separate
  function, *<device>_ioctl*, the device-dependent *ioctl()'s*. Note that
  memory checking and allocation must be kept in this code!
- Change the prototypes of *<device>_open()* and
  *<device>_release()*, and remove any strategic code (i. e., tray
  movement, door locking, etc.).
- Try to recompile the drivers. We advise you to use modules, both
  for `cdrom.o` and your driver, as debugging is much easier this
  way.

Thanks
======

Thanks to all the people involved. First, Erik Andersen, who has
taken over the torch in maintaining `cdrom.c` and integrating much
CD-ROM-related code in the 2.1-kernel. Thanks to Scott Snyder and
Gerd Knorr, who were the first to implement this interface for SCSI
and IDE-CD drivers and added many ideas for extension of the data
structures relative to kernel~2.0. Further thanks to Heiko Eißfeldt,
Thomas Quinot, Jon Tombs, Ken Pizzini, Eberhard Mönkeberg and Andrew Kroll,
the Linux CD-ROM device driver developers who were kind
enough to give suggestions and criticisms during the writing. Finally
of course, I want to thank Linus Torvalds for making this possible in
the first place.

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

=====
cdrom
=====

.. toctree::
    :maxdepth: 1

    cdrom-standard
    packet-writing

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
==============
Packet writing
==============

Getting started quick
---------------------

- Select packet support in the block device section and UDF support in
  the file system section.

- Compile and install kernel and modules, reboot.

- You need the udftools package (pktsetup, mkudffs, cdrwtool).
  Download from https://github.com/pali/udftools

- Grab a new CD-RW disc and format it (assuming CD-RW is hdc, substitute
  as appropriate)::

	# cdrwtool -d /dev/hdc -q

- Setup your writer::

	# pktsetup dev_name /dev/hdc

- Now you can mount /dev/pktcdvd/dev_name and copy files to it. Enjoy::

	# mount /dev/pktcdvd/dev_name /cdrom -t udf -o rw,noatime

Packet writing for DVD-RW media
-------------------------------

DVD-RW discs can be written to much like CD-RW discs if they are in
the so called "restricted overwrite" mode. To put a disc in restricted
overwrite mode, run::

	# dvd+rw-format /dev/hdc

You can then use the disc the same way you would use a CD-RW disc::

	# pktsetup dev_name /dev/hdc
	# mount /dev/pktcdvd/dev_name /cdrom -t udf -o rw,noatime

Packet writing for DVD+RW media
-------------------------------

According to the DVD+RW specification, a drive supporting DVD+RW discs
shall implement "true random writes with 2KB granularity", which means
that it should be possible to put any filesystem with a block size >=
2KB on such a disc. For example, it should be possible to do::

	# dvd+rw-format /dev/hdc   (only needed if the disc has never
	                            been formatted)
	# mkudffs /dev/hdc
	# mount /dev/hdc /cdrom -t udf -o rw,noatime

However, some drives don't follow the specification and expect the
host to perform aligned writes at 32KB boundaries. Other drives do
follow the specification, but suffer bad performance problems if the
writes are not 32KB aligned.

Both problems can be solved by using the pktcdvd driver, which always
generates aligned writes::

	# dvd+rw-format /dev/hdc
	# pktsetup dev_name /dev/hdc
	# mkudffs /dev/pktcdvd/dev_name
	# mount /dev/pktcdvd/dev_name /cdrom -t udf -o rw,noatime

Packet writing for DVD-RAM media
--------------------------------

DVD-RAM discs are random writable, so using the pktcdvd driver is not
necessary. However, using the pktcdvd driver can improve performance
in the same way it does for DVD+RW media.

Notes
-----

- CD-RW media can usually not be overwritten more than about 1000
  times, so to avoid unnecessary wear on the media, you should always
  use the noatime mount option.

- Defect management (ie automatic remapping of bad sectors) has not
  been implemented yet, so you are likely to get at least some
  filesystem corruption if the disc wears out.

- Since the pktcdvd driver makes the disc appear as a regular block
  device with a 2KB block size, you can put any filesystem you like on
  the disc. For example, run::

	# /sbin/mke2fs /dev/pktcdvd/dev_name

  to create an ext2 filesystem on the disc.

Using the pktcdvd sysfs interface
---------------------------------

Since Linux 2.6.20, the pktcdvd module has a sysfs interface
and can be controlled by it. For example the "pktcdvd" tool uses
this interface. (see http://tom.ist-im-web.de/linux/software/pktcdvd )

"pktcdvd" works similar to "pktsetup", e.g.::

	# pktcdvd -a dev_name /dev/hdc
	# mkudffs /dev/pktcdvd/dev_name
	# mount -t udf -o rw,noatime /dev/pktcdvd/dev_name /dvdram
	# cp files /dvdram
	# umount /dvdram
	# pktcdvd -r dev_name

For a description of the sysfs interface look into the file:

  Documentation/ABI/testing/sysfs-class-pktcdvd

Using the pktcdvd debugfs interface
-----------------------------------

To read pktcdvd device infos in human readable form, do::

	# cat /sys/kernel/debug/pktcdvd/pktcdvd[0-7]/info

For a description of the debugfs interface look into the file:

  Documentation/ABI/testing/debugfs-pktcdvd

Links
-----

See http://fy.chalmers.se/~appro/linux/DVD+RW/ for more information
about DVD writing.


code:
# -*- coding: utf-8 -*-
#
# The Linux Kernel documentation build configuration file, created by
# sphinx-quickstart on Fri Feb 12 13:51:46 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

import sys
import os
import sphinx
import shutil

# helper
# ------

def have_command(cmd):
    """Search ``cmd`` in the ``PATH`` environment.

    If found, return True.
    If not found, return False.
    """
    return shutil.which(cmd) is not None

# Get Sphinx version
major, minor, patch = sphinx.version_info[:3]

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('sphinx'))
from load_config import loadConfig

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
needs_sphinx = '1.7'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = ['kerneldoc', 'rstFlatTable', 'kernel_include',
              'kfigure', 'sphinx.ext.ifconfig', 'automarkup',
              'maintainers_include', 'sphinx.ext.autosectionlabel',
              'kernel_abi', 'kernel_feat']

if major >= 3:
    if (major > 3) or (minor > 0 or patch >= 2):
        # Sphinx c function parser is more pedantic with regards to type
        # checking. Due to that, having macros at c:function cause problems.
        # Those needed to be scaped by using c_id_attributes[] array
        c_id_attributes = [
            # GCC Compiler types not parsed by Sphinx:
            "__restrict__",

            # include/linux/compiler_types.h:
            "__iomem",
            "__kernel",
            "noinstr",
            "notrace",
            "__percpu",
            "__rcu",
            "__user",

            # include/linux/compiler_attributes.h:
            "__alias",
            "__aligned",
            "__aligned_largest",
            "__always_inline",
            "__assume_aligned",
            "__cold",
            "__attribute_const__",
            "__copy",
            "__pure",
            "__designated_init",
            "__visible",
            "__printf",
            "__scanf",
            "__gnu_inline",
            "__malloc",
            "__mode",
            "__no_caller_saved_registers",
            "__noclone",
            "__nonstring",
            "__noreturn",
            "__packed",
            "__pure",
            "__section",
            "__always_unused",
            "__maybe_unused",
            "__used",
            "__weak",
            "noinline",
            "__fix_address",

            # include/linux/memblock.h:
            "__init_memblock",
            "__meminit",

            # include/linux/init.h:
            "__init",
            "__ref",

            # include/linux/linkage.h:
            "asmlinkage",
        ]

else:
    extensions.append('cdomain')

# Ensure that autosectionlabel will produce unique names
autosectionlabel_prefix_document = True
autosectionlabel_maxdepth = 2

# Load math renderer:
# For html builder, load imgmath only when its dependencies are met.
# mathjax is the default math renderer since Sphinx 1.8.
have_latex =  have_command('latex')
have_dvipng = have_command('dvipng')
load_imgmath = have_latex and have_dvipng

# Respect SPHINX_IMGMATH (for html docs only)
if 'SPHINX_IMGMATH' in os.environ:
    env_sphinx_imgmath = os.environ['SPHINX_IMGMATH']
    if 'yes' in env_sphinx_imgmath:
        load_imgmath = True
    elif 'no' in env_sphinx_imgmath:
        load_imgmath = False
    else:
        sys.stderr.write("Unknown env SPHINX_IMGMATH=%s ignored.\n" % env_sphinx_imgmath)

# Always load imgmath for Sphinx <1.8 or for epub docs
load_imgmath = (load_imgmath or (major == 1 and minor < 8)
                or 'epub' in sys.argv)

if load_imgmath:
    extensions.append("sphinx.ext.imgmath")
    math_renderer = 'imgmath'
else:
    math_renderer = 'mathjax'

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'

# The encoding of source files.
#source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = 'index'

# General information about the project.
project = 'The Linux Kernel'
copyright = 'The kernel development community'
author = 'The kernel development community'

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# In a normal build, version and release are are set to KERNELVERSION and
# KERNELRELEASE, respectively, from the Makefile via Sphinx command line
# arguments.
#
# The following code tries to extract the information by reading the Makefile,
# when Sphinx is run directly (e.g. by Read the Docs).
try:
    makefile_version = None
    makefile_patchlevel = None
    for line in open('../Makefile'):
        key, val = [x.strip() for x in line.split('=', 2)]
        if key == 'VERSION':
            makefile_version = val
        elif key == 'PATCHLEVEL':
            makefile_patchlevel = val
        if makefile_version and makefile_patchlevel:
            break
except:
    pass
finally:
    if makefile_version and makefile_patchlevel:
        version = release = makefile_version + '.' + makefile_patchlevel
    else:
        version = release = "unknown version"

#
# HACK: there seems to be no easy way for us to get at the version and
# release information passed in from the makefile...so go pawing through the
# command-line options and find it for ourselves.
#
def get_cline_version():
    c_version = c_release = ''
    for arg in sys.argv:
        if arg.startswith('version='):
            c_version = arg[8:]
        elif arg.startswith('release='):
            c_release = arg[8:]
    if c_version:
        if c_release:
            return c_version + '-' + c_release
        return c_version
    return version # Whatever we came up with before

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'en'

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ['output']

# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'

# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
#keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False

primary_domain = 'c'
highlight_language = 'none'

# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.

# Default theme
html_theme = 'alabaster'
html_css_files = []

if "DOCS_THEME" in os.environ:
    html_theme = os.environ["DOCS_THEME"]

if html_theme == 'sphinx_rtd_theme' or html_theme == 'sphinx_rtd_dark_mode':
    # Read the Docs theme
    try:
        import sphinx_rtd_theme
        html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]

        # Add any paths that contain custom static files (such as style sheets) here,
        # relative to this directory. They are copied after the builtin static files,
        # so a file named "default.css" will overwrite the builtin "default.css".
        html_css_files = [
            'theme_overrides.css',
        ]

        # Read the Docs dark mode override theme
        if html_theme == 'sphinx_rtd_dark_mode':
            try:
                import sphinx_rtd_dark_mode
                extensions.append('sphinx_rtd_dark_mode')
            except ImportError:
                html_theme == 'sphinx_rtd_theme'

        if html_theme == 'sphinx_rtd_theme':
                # Add color-specific RTD normal mode
                html_css_files.append('theme_rtd_colors.css')

        html_theme_options = {
            'navigation_depth': -1,
        }

    except ImportError:
        html_theme = 'alabaster'

if "DOCS_CSS" in os.environ:
    css = os.environ["DOCS_CSS"].split(" ")

    for l in css:
        html_css_files.append(l)

if major <= 1 and minor < 8:
    html_context = {
        'css_files': [],
    }

    for l in html_css_files:
        html_context['css_files'].append('_static/' + l)

if  html_theme == 'alabaster':
    html_theme_options = {
        'description': get_cline_version(),
        'page_width': '65em',
        'sidebar_width': '15em',
        'font_size': 'inherit',
        'font_family': 'serif',
    }

sys.stderr.write("Using %s theme\n" % html_theme)

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['sphinx-static']

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
html_use_smartypants = False

# Custom sidebar templates, maps document names to template names.
# Note that the RTD theme ignores this
html_sidebars = { '**': ["about.html", 'searchbox.html', 'localtoc.html', 'sourcelink.html']}

# Output file base name for HTML help builder.
htmlhelp_basename = 'TheLinuxKerneldoc'

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    'papersize': 'a4paper',

    # The font size ('10pt', '11pt' or '12pt').
    'pointsize': '11pt',

    # Latex figure (float) alignment
    #'figure_align': 'htbp',

    # Don't mangle with UTF-8 chars
    'inputenc': '',
    'utf8extra': '',

    # Set document margins
    'sphinxsetup': '''
        hmargin=0.5in, vmargin=1in,
        parsedliteralwraps=true,
        verbatimhintsturnover=false,
    ''',

    # For CJK One-half spacing, need to be in front of hyperref
    'extrapackages': r'\usepackage{setspace}',

    # Additional stuff for the LaTeX preamble.
    'preamble': '''
        % Use some font with UTF-8 support with XeLaTeX
        \\usepackage{fontspec}
        \\setsansfont{DejaVu Sans}
        \\setromanfont{DejaVu Serif}
        \\setmonofont{DejaVu Sans Mono}
    ''',
}

# Fix reference escape troubles with Sphinx 1.4.x
if major == 1:
    latex_elements['preamble']  += '\\renewcommand*{\\DUrole}[2]{ #2 }\n'

# Load kerneldoc specific LaTeX settings
latex_elements['preamble'] += '''
        % Load kerneldoc specific LaTeX settings
	\\input{kerneldoc-preamble.sty}
'''

# With Sphinx 1.6, it is possible to change the Bg color directly
# by using:
#	\definecolor{sphinxnoteBgColor}{RGB}{204,255,255}
#	\definecolor{sphinxwarningBgColor}{RGB}{255,204,204}
#	\definecolor{sphinxattentionBgColor}{RGB}{255,255,204}
#	\definecolor{sphinximportantBgColor}{RGB}{192,255,204}
#
# However, it require to use sphinx heavy box with:
#
#	\renewenvironment{sphinxlightbox} {%
#		\\begin{sphinxheavybox}
#	}
#		\\end{sphinxheavybox}
#	}
#
# Unfortunately, the implementation is buggy: if a note is inside a
# table, it isn't displayed well. So, for now, let's use boring
# black and white notes.

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
# Sorted in alphabetical order
latex_documents = [
]

# Add all other index files from Documentation/ subdirectories
for fn in os.listdir('.'):
    doc = os.path.join(fn, "index")
    if os.path.exists(doc + ".rst"):
        has = False
        for l in latex_documents:
            if l[0] == doc:
                has = True
                break
        if not has:
            latex_documents.append((doc, fn + '.tex',
                                    'Linux %s Documentation' % fn.capitalize(),
                                    'The kernel development community',
                                    'manual'))

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False

# If true, show page references after internal links.
#latex_show_pagerefs = False

# If true, show URL addresses after external links.
#latex_show_urls = False

# Documents to append as an appendix to all manuals.
#latex_appendices = []

# If false, no module index is generated.
#latex_domain_indices = True

# Additional LaTeX stuff to be copied to build directory
latex_additional_files = [
    'sphinx/kerneldoc-preamble.sty',
]

# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
    (master_doc, 'thelinuxkernel', 'The Linux Kernel Documentation',
     [author], 1)
]

# If true, show URL addresses after external links.
#man_show_urls = False

# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (master_doc, 'TheLinuxKernel', 'The Linux Kernel Documentation',
     author, 'TheLinuxKernel', 'One line description of project.',
     'Miscellaneous'),
]

# -- Options for Epub output ----------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright

# A list of files that should not be packed into the epub file.
epub_exclude_files = ['search.html']

#=======
# rst2pdf
#
# Grouping the document tree into PDF files. List of tuples
# (source start file, target name, title, author, options).
#
# See the Sphinx chapter of https://ralsina.me/static/manual.pdf
#
# FIXME: Do not add the index file here; the result will be too big. Adding
# multiple PDF files here actually tries to get the cross-referencing right
# *between* PDF files.
pdf_documents = [
    ('kernel-documentation', u'Kernel', u'Kernel', u'J. Random Bozo'),
]

# kernel-doc extension configuration for running Sphinx directly (e.g. by Read
# the Docs). In a normal build, these are supplied from the Makefile via command
# line arguments.
kerneldoc_bin = '../scripts/kernel-doc'
kerneldoc_srctree = '..'

# ------------------------------------------------------------------------------
# Since loadConfig overwrites settings from the global namespace, it has to be
# the last statement in the conf.py file
# ------------------------------------------------------------------------------
loadConfig(globals())


code:
Assembler Annotations
=====================

Copyright (c) 2017-2019 Jiri Slaby

This document describes the new macros for annotation of data and code in
assembly. In particular, it contains information about ``SYM_FUNC_START``,
``SYM_FUNC_END``, ``SYM_CODE_START``, and similar.

Rationale
---------
Some code like entries, trampolines, or boot code needs to be written in
assembly. The same as in C, such code is grouped into functions and
accompanied with data. Standard assemblers do not force users into precisely
marking these pieces as code, data, or even specifying their length.
Nevertheless, assemblers provide developers with such annotations to aid
debuggers throughout assembly. On top of that, developers also want to mark
some functions as *global* in order to be visible outside of their translation
units.

Over time, the Linux kernel has adopted macros from various projects (like
``binutils``) to facilitate such annotations. So for historic reasons,
developers have been using ``ENTRY``, ``END``, ``ENDPROC``, and other
annotations in assembly.  Due to the lack of their documentation, the macros
are used in rather wrong contexts at some locations. Clearly, ``ENTRY`` was
intended to denote the beginning of global symbols (be it data or code).
``END`` used to mark the end of data or end of special functions with
*non-standard* calling convention. In contrast, ``ENDPROC`` should annotate
only ends of *standard* functions.

When these macros are used correctly, they help assemblers generate a nice
object with both sizes and types set correctly. For example, the result of
``arch/x86/lib/putuser.S``::

   Num:    Value          Size Type    Bind   Vis      Ndx Name
    25: 0000000000000000    33 FUNC    GLOBAL DEFAULT    1 __put_user_1
    29: 0000000000000030    37 FUNC    GLOBAL DEFAULT    1 __put_user_2
    32: 0000000000000060    36 FUNC    GLOBAL DEFAULT    1 __put_user_4
    35: 0000000000000090    37 FUNC    GLOBAL DEFAULT    1 __put_user_8

This is not only important for debugging purposes. When there are properly
annotated objects like this, tools can be run on them to generate more useful
information. In particular, on properly annotated objects, ``objtool`` can be
run to check and fix the object if needed. Currently, ``objtool`` can report
missing frame pointer setup/destruction in functions. It can also
automatically generate annotations for the ORC unwinder
(Documentation/x86/orc-unwinder.rst)
for most code. Both of these are especially important to support reliable
stack traces which are in turn necessary for kernel live patching
(Documentation/livepatch/livepatch.rst).

Caveat and Discussion
---------------------
As one might realize, there were only three macros previously. That is indeed
insufficient to cover all the combinations of cases:

* standard/non-standard function
* code/data
* global/local symbol

There was a discussion_ and instead of extending the current ``ENTRY/END*``
macros, it was decided that brand new macros should be introduced instead::

    So how about using macro names that actually show the purpose, instead
    of importing all the crappy, historic, essentially randomly chosen
    debug symbol macro names from the binutils and older kernels?

.. _discussion: https://lore.kernel.org/r/20170217104757.28588-1-jslaby@suse.cz

Macros Description
------------------

The new macros are prefixed with the ``SYM_`` prefix and can be divided into
three main groups:

1. ``SYM_FUNC_*`` -- to annotate C-like functions. This means functions with
   standard C calling conventions. For example, on x86, this means that the
   stack contains a return address at the predefined place and a return from
   the function can happen in a standard way. When frame pointers are enabled,
   save/restore of frame pointer shall happen at the start/end of a function,
   respectively, too.

   Checking tools like ``objtool`` should ensure such marked functions conform
   to these rules. The tools can also easily annotate these functions with
   debugging information (like *ORC data*) automatically.

2. ``SYM_CODE_*`` -- special functions called with special stack. Be it
   interrupt handlers with special stack content, trampolines, or startup
   functions.

   Checking tools mostly ignore checking of these functions. But some debug
   information still can be generated automatically. For correct debug data,
   this code needs hints like ``UNWIND_HINT_REGS`` provided by developers.

3. ``SYM_DATA*`` -- obviously data belonging to ``.data`` sections and not to
   ``.text``. Data do not contain instructions, so they have to be treated
   specially by the tools: they should not treat the bytes as instructions,
   nor assign any debug information to them.

Instruction Macros
~~~~~~~~~~~~~~~~~~
This section covers ``SYM_FUNC_*`` and ``SYM_CODE_*`` enumerated above.

``objtool`` requires that all code must be contained in an ELF symbol. Symbol
names that have a ``.L`` prefix do not emit symbol table entries. ``.L``
prefixed symbols can be used within a code region, but should be avoided for
denoting a range of code via ``SYM_*_START/END`` annotations.

* ``SYM_FUNC_START`` and ``SYM_FUNC_START_LOCAL`` are supposed to be **the
  most frequent markings**. They are used for functions with standard calling
  conventions -- global and local. Like in C, they both align the functions to
  architecture specific ``__ALIGN`` bytes. There are also ``_NOALIGN`` variants
  for special cases where developers do not want this implicit alignment.

  ``SYM_FUNC_START_WEAK`` and ``SYM_FUNC_START_WEAK_NOALIGN`` markings are
  also offered as an assembler counterpart to the *weak* attribute known from
  C.

  All of these **shall** be coupled with ``SYM_FUNC_END``. First, it marks
  the sequence of instructions as a function and computes its size to the
  generated object file. Second, it also eases checking and processing such
  object files as the tools can trivially find exact function boundaries.

  So in most cases, developers should write something like in the following
  example, having some asm instructions in between the macros, of course::

    SYM_FUNC_START(memset)
        ... asm insns ...
    SYM_FUNC_END(memset)

  In fact, this kind of annotation corresponds to the now deprecated ``ENTRY``
  and ``ENDPROC`` macros.

* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can
  be used to define multiple names for a function. The typical use is::

    SYM_FUNC_START(__memset)
        ... asm insns ...
    SYN_FUNC_END(__memset)
    SYM_FUNC_ALIAS(memset, __memset)

  In this example, one can call ``__memset`` or ``memset`` with the same
  result, except the debug information for the instructions is generated to
  the object file only once -- for the non-``ALIAS`` case.

* ``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in
  special cases -- if you know what you are doing. This is used exclusively
  for interrupt handlers and similar where the calling convention is not the C
  one. ``_NOALIGN`` variants exist too. The use is the same as for the ``FUNC``
  category above::

    SYM_CODE_START_LOCAL(bad_put_user)
        ... asm insns ...
    SYM_CODE_END(bad_put_user)

  Again, every ``SYM_CODE_START*`` **shall** be coupled by ``SYM_CODE_END``.

  To some extent, this category corresponds to deprecated ``ENTRY`` and
  ``END``. Except ``END`` had several other meanings too.

* ``SYM_INNER_LABEL*`` is used to denote a label inside some
  ``SYM_{CODE,FUNC}_START`` and ``SYM_{CODE,FUNC}_END``.  They are very similar
  to C labels, except they can be made global. An example of use::

    SYM_CODE_START(ftrace_caller)
        /* save_mcount_regs fills in first two parameters */
        ...

    SYM_INNER_LABEL(ftrace_caller_op_ptr, SYM_L_GLOBAL)
        /* Load the ftrace_ops into the 3rd parameter */
        ...

    SYM_INNER_LABEL(ftrace_call, SYM_L_GLOBAL)
        call ftrace_stub
        ...
        retq
    SYM_CODE_END(ftrace_caller)

Data Macros
~~~~~~~~~~~
Similar to instructions, there is a couple of macros to describe data in the
assembly.

* ``SYM_DATA_START`` and ``SYM_DATA_START_LOCAL`` mark the start of some data
  and shall be used in conjunction with either ``SYM_DATA_END``, or
  ``SYM_DATA_END_LABEL``. The latter adds also a label to the end, so that
  people can use ``lstack`` and (local) ``lstack_end`` in the following
  example::

    SYM_DATA_START_LOCAL(lstack)
        .skip 4096
    SYM_DATA_END_LABEL(lstack, SYM_L_LOCAL, lstack_end)

* ``SYM_DATA`` and ``SYM_DATA_LOCAL`` are variants for simple, mostly one-line
  data::

    SYM_DATA(HEAP,     .long rm_heap)
    SYM_DATA(heap_end, .long rm_stack)

  In the end, they expand to ``SYM_DATA_START`` with ``SYM_DATA_END``
  internally.

Support Macros
~~~~~~~~~~~~~~
All the above reduce themselves to some invocation of ``SYM_START``,
``SYM_END``, or ``SYM_ENTRY`` at last. Normally, developers should avoid using
these.

Further, in the above examples, one could see ``SYM_L_LOCAL``. There are also
``SYM_L_GLOBAL`` and ``SYM_L_WEAK``. All are intended to denote linkage of a
symbol marked by them. They are used either in ``_LABEL`` variants of the
earlier macros, or in ``SYM_START``.

Overriding Macros
~~~~~~~~~~~~~~~~~
Architecture can also override any of the macros in their own
``asm/linkage.h``, including macros specifying the type of a symbol
(``SYM_T_FUNC``, ``SYM_T_OBJECT``, and ``SYM_T_NONE``).  As every macro
described in this file is surrounded by ``#ifdef`` + ``#endif``, it is enough
to define the macros differently in the aforementioned architecture-dependent
header.