<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>

<book id="Z85230Guide">
 <bookinfo>
  <title>Z8530 Programming Guide</title>
  
  <authorgroup>
   <author>
    <firstname>Alan</firstname>
    <surname>Cox</surname>
    <affiliation>
     <address>
      <email>alan@redhat.com</email>
     </address>
    </affiliation>
   </author>
  </authorgroup>

  <copyright>
   <year>2000</year>
   <holder>Alan Cox</holder>
  </copyright>

  <legalnotice>
   <para>
     This documentation is free software; you can redistribute
     it and/or modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later
     version.
   </para>
      
   <para>
     This program is distributed in the hope that it will be
     useful, but WITHOUT ANY WARRANTY; without even the implied
     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     See the GNU General Public License for more details.
   </para>
      
   <para>
     You should have received a copy of the GNU General Public
     License along with this program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
     MA 02111-1307 USA
   </para>
      
   <para>
     For more details see the file COPYING in the source
     distribution of Linux.
   </para>
  </legalnotice>
 </bookinfo>

<toc></toc>

  <chapter id="intro">
      <title>Introduction</title>
  <para>
	The Z85x30 family synchronous/asynchronous controller chips are
	used on a large number of cheap network interface cards. The
	kernel provides a core interface layer that is designed to make
	it easy to provide WAN services using this chip.
  </para>
  <para>
	The current driver only support synchronous operation. Merging the
	asynchronous driver support into this code to allow any Z85x30
	device to be used as both a tty interface and as a synchronous 
	controller is a project for Linux post the 2.4 release
  </para>
  <para>
	The support code handles most common card configurations and
	supports running both Cisco HDLC and Synchronous PPP. With extra
	glue the frame relay and X.25 protocols can also be used with this
	driver.
  </para>
  </chapter>
  
  <chapter id="Driver_Modes">
 	<title>Driver Modes</title>
  <para>
	The Z85230 driver layer can drive Z8530, Z85C30 and Z85230 devices
	in three different modes. Each mode can be applied to an individual
	channel on the chip (each chip has two channels).
  </para>
  <para>
	The PIO synchronous mode supports the most common Z8530 wiring. Here
	the chip is interface to the I/O and interrupt facilities of the
	host machine but not to the DMA subsystem. When running PIO the
	Z8530 has extremely tight timing requirements. Doing high speeds,
	even with a Z85230 will be tricky. Typically you should expect to
	achieve at best 9600 baud with a Z8C530 and 64Kbits with a Z85230.
  </para>
  <para>
	The DMA mode supports the chip when it is configured to use dual DMA
	channels on an ISA bus. The better cards tend to support this mode
	of operation for a single channel. With DMA running the Z85230 tops
	out when it starts to hit ISA DMA constraints at about 512Kbits. It
	is worth noting here that many PC machines hang or crash when the
	chip is driven fast enough to hold the ISA bus solid.
  </para>
  <para>
	Transmit DMA mode uses a single DMA channel. The DMA channel is used
	for transmission as the transmit FIFO is smaller than the receive
	FIFO. it gives better performance than pure PIO mode but is nowhere
	near as ideal as pure DMA mode. 
  </para>
  </chapter>

  <chapter id="Using_the_Z85230_driver">
 	<title>Using the Z85230 driver</title>
  <para>
	The Z85230 driver provides the back end interface to your board. To
	configure a Z8530 interface you need to detect the board and to 
	identify its ports and interrupt resources. It is also your problem
	to verify the resources are available.
  </para>
  <para>
	Having identified the chip you need to fill in a struct z8530_dev,
	which describes each chip. This object must exist until you finally
	shutdown the board. Firstly zero the active field. This ensures 
	nothing goes off without you intending it. The irq field should
	be set to the interrupt number of the chip. (Each chip has a single
	interrupt source rather than each channel). You are responsible
	for allocating the interrupt line. The interrupt handler should be
	set to <function>z8530_interrupt</function>. The device id should
	be set to the z8530_dev structure pointer. Whether the interrupt can
	be shared or not is board dependent, and up to you to initialise.
  </para>
  <para>
	The structure holds two channel structures. 
	Initialise chanA.ctrlio and chanA.dataio with the address of the
	control and data ports. You can or this with Z8530_PORT_SLEEP to
	indicate your interface needs the 5uS delay for chip settling done
	in software. The PORT_SLEEP option is architecture specific. Other
	flags may become available on future platforms, eg for MMIO.
	Initialise the chanA.irqs to &amp;z8530_nop to start the chip up
	as disabled and discarding interrupt events. This ensures that
	stray interrupts will be mopped up and not hang the bus. Set
	chanA.dev to point to the device structure itself. The
	private and name field you may use as you wish. The private field
	is unused by the Z85230 layer. The name is used for error reporting
	and it may thus make sense to make it match the network name.
  </para>
  <para>
	Repeat the same operation with the B channel if your chip has
	both channels wired to something useful. This isn't always the
	case. If it is not wired then the I/O values do not matter, but
	you must initialise chanB.dev.
  </para>
  <para>
	If your board has DMA facilities then initialise the txdma and
	rxdma fields for the relevant channels. You must also allocate the
	ISA DMA channels and do any necessary board level initialisation
	to configure them. The low level driver will do the Z8530 and
	DMA controller programming but not board specific magic.
  </para>
  <para>
	Having initialised the device you can then call
	<function>z8530_init</function>. This will probe the chip and 
	reset it into a known state. An identification sequence is then
	run to identify the chip type. If the checks fail to pass the
	function returns a non zero error code. Typically this indicates
	that the port given is not valid. After this call the
	type field of the z8530_dev structure is initialised to either
	Z8530, Z85C30 or Z85230 according to the chip found.
  </para>
  <para>
	Once you have called z8530_init you can also make use of the utility
	function <function>z8530_describe</function>. This provides a 
	consistent reporting format for the Z8530 devices, and allows all
	the drivers to provide consistent reporting.
  </para>
  </chapter>

  <chapter id="Attaching_Network_Interfaces">
 	<title>Attaching Network Interfaces</title>
  <para>
	If you wish to use the network interface facilities of the driver,
	then you need to attach a network device to each channel that is
	present and in use. In addition to use the SyncPPP and Cisco HDLC
	you need to follow some additional plumbing rules. They may seem 
	complex but a look at the example hostess_sv11 driver should
	reassure you.
  </para>
  <para>
	The network device used for each channel should be pointed to by
	the netdevice field of each channel. The dev-&gt; priv field of the
	network device points to your private data - you will need to be
	able to find your ppp device from this. In addition to use the
	sync ppp layer the private data must start with a void * pointer
	to the syncppp structures.
  </para>
  <para>
	The way most drivers approach this particular problem is to
	create a structure holding the Z8530 device definition and
	put that and the syncppp pointer into the private field of
	the network device. The network device fields of the channels
	then point back to the network devices. The ppp_device can also
	be put in the private structure conveniently.
  </para>
  <para>
	If you wish to use the synchronous ppp then you need to attach
	the syncppp layer to the network device. You should do this before
	you register the network device. The
	<function>sppp_attach</function> requires that the first void *
	pointer in your private data is pointing to an empty struct
	ppp_device. The function fills in the initial data for the
	ppp/hdlc layer.
  </para>
  <para>
	Before you register your network device you will also need to
	provide suitable handlers for most of the network device callbacks. 
	See the network device documentation for more details on this.
  </para>
  </chapter>

  <chapter id="Configuring_And_Activating_The_Port">
 	<title>Configuring And Activating The Port</title>
  <para>
	The Z85230 driver provides helper functions and tables to load the
	port registers on the Z8530 chips. When programming the register
	settings for a channel be aware that the documentation recommends
	initialisation orders. Strange things happen when these are not
	followed. 
  </para>
  <para>
	<function>z8530_channel_load</function> takes an array of
	pairs of initialisation values in an array of u8 type. The first
	value is the Z8530 register number. Add 16 to indicate the alternate
	register bank on the later chips. The array is terminated by a 255.
  </para>
  <para>
	The driver provides a pair of public tables. The
	z8530_hdlc_kilostream table is for the UK 'Kilostream' service and
	also happens to cover most other end host configurations. The
	z8530_hdlc_kilostream_85230 table is the same configuration using
	the enhancements of the 85230 chip. The configuration loaded is
	standard NRZ encoded synchronous data with HDLC bitstuffing. All
	of the timing is taken from the other end of the link.
  </para>
  <para>
	When writing your own tables be aware that the driver internally
	tracks register values. It may need to reload values. You should
	therefore be sure to set registers 1-7, 9-11, 14 and 15 in all
	configurations. Where the register settings depend on DMA selection
	the driver will update the bits itself when you open or close.
	Loading a new table with the interface open is not recommended.
  </para>
  <para>
	There are three standard configurations supported by the core
	code. In PIO mode the interface is programmed up to use
	interrupt driven PIO. This places high demands on the host processor
	to avoid latency. The driver is written to take account of latency
	issues but it cannot avoid latencies caused by other drivers,
	notably IDE in PIO mode. Because the drivers allocate buffers you
	must also prevent MTU changes while the port is open.
  </para>
  <para>
	Once the port is open it will call the rx_function of each channel
	whenever a completed packet arrived. This is invoked from
	interrupt context and passes you the channel and a network	
	buffer (struct sk_buff) holding the data. The data includes
	the CRC bytes so most users will want to trim the last two
	bytes before processing the data. This function is very timing
	critical. When you wish to simply discard data the support
	code provides the function <function>z8530_null_rx</function>
	to discard the data.
  </para>
  <para>
	To active PIO mode sending and receiving the <function>
	z8530_sync_open</function> is called. This expects to be passed
	the network device and the channel. Typically this is called from
	your network device open callback. On a failure a non zero error
	status is returned. The <function>z8530_sync_close</function> 
	function shuts down a PIO channel. This must be done before the 
	channel is opened again	and before the driver shuts down 
	and unloads.
  </para>
  <para>
	The ideal mode of operation is dual channel DMA mode. Here the
	kernel driver will configure the board for DMA in both directions.
	The driver also handles ISA DMA issues such as controller
	programming and the memory range limit for you. This mode is
	activated by calling the <function>z8530_sync_dma_open</function>
	function. On failure a non zero error value is returned.
	Once this mode is activated it can be shut down by calling the
	<function>z8530_sync_dma_close</function>. You must call the close
	function matching the open mode you used.
  </para>
  <para>
	The final supported mode uses a single DMA channel to drive the
	transmit side. As the Z85C30 has a larger FIFO on the receive
	channel	this tends to increase the maximum speed a little. 
	This is activated by calling the <function>z8530_sync_txdma_open
	</function>. This returns a non zero error code on failure. The
	<function>z8530_sync_txdma_close</function> function closes down
	the Z8530 interface from this mode.
  </para>
  </chapter>

  <chapter id="Network_Layer_Functions">
 	<title>Network Layer Functions</title>
  <para>
	The Z8530 layer provides functions to queue packets for
	transmission. The driver internally buffers the frame currently
	being transmitted and one further frame (in order to keep back
	to back transmission running). Any further buffering is up to
	the caller.
  </para>
  <para>
	The function <function>z8530_queue_xmit</function> takes a network
	buffer in sk_buff format and queues it for transmission. The
	caller must provide the entire packet with the exception of the
	bitstuffing and CRC. This is normally done by the caller via
	the syncppp interface layer. It returns 0 if the buffer has been 
        queued and non zero values  for queue full. If the function accepts 
	the buffer it becomes property of the Z8530 layer and the caller 
	should not free it. 
  </para>
  <para>
	The function <function>z8530_get_stats</function> returns a pointer
	to an internally maintained per interface statistics block. This
	provides most of the interface code needed to implement the network
	layer get_stats callback.
  </para>
  </chapter>

  <chapter id="Porting_The_Z8530_Driver">
     <title>Porting The Z8530 Driver</title>
  <para>
	The Z8530 driver is written to be portable. In DMA mode it makes
	assumptions about the use of ISA DMA. These are probably warranted
	in most cases as the Z85230 in particular was designed to glue to PC
	type machines. The PIO mode makes no real assumptions.
  </para>
  <para>
	Should you need to retarget the Z8530 driver to another architecture
	the only code that should need changing are the port I/O functions.
	At the moment these assume PC I/O port accesses. This may not be
	appropriate for all platforms. Replacing 
	<function>z8530_read_port</function> and <function>z8530_write_port
	</function> is intended to be all that is required to port this
	driver layer.
  </para>
  </chapter>

  <chapter id="bugs">
     <title>Known Bugs And Assumptions</title>
  <para>
  <variablelist>
    <varlistentry><term>Interrupt Locking</term>
    <listitem>
    <para>
	The locking in the driver is done via the global cli/sti lock. This
	makes for relatively poor SMP performance. Switching this to use a
	per device spin lock would probably materially improve performance.
    </para>
    </listitem></varlistentry>

    <varlistentry><term>Occasional Failures</term>
    <listitem>
    <para>
	We have reports of occasional failures when run for very long
	periods of time and the driver starts to receive junk frames. At
	the moment the cause of this is not clear.
    </para>
    </listitem></varlistentry>
  </variablelist>
	
  </para>
  </chapter>

  <chapter id="pubfunctions">
     <title>Public Functions Provided</title>
<!-- drivers/net/wan/z85230.c -->
<refentry id="API-z8530-interrupt">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_interrupt</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_interrupt</refname>
 <refpurpose>
  Handle an interrupt from a Z8530
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>irqreturn_t <function>z8530_interrupt </function></funcdef>
   <paramdef>int <parameter>irq</parameter></paramdef>
   <paramdef>void * <parameter>dev_id</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>irq</parameter></term>
   <listitem>
    <para>
     Interrupt number
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>dev_id</parameter></term>
   <listitem>
    <para>
     The Z8530 device that is interrupting.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   A Z85[2]30 device has stuck its hand in the air for attention.
   We scan both the channels on the chip for events and then call
   the channel specific call backs for each channel that has events.
   We have to use callback functions because the two channels can be
   in different modes.
   </para><para>

   Locking is done for the handlers. Note that locking is done
   at the chip level (the 5uS delay issue is per chip not per
   channel). c-&gt;lock for both channels points to dev-&gt;lock
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-open">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_open</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_open</refname>
 <refpurpose>
     Open a Z8530 channel for PIO
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_open </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     The network interface we are using
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to open in synchronous PIO mode
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Switch a Z8530 into synchronous mode without DMA assist. We
   raise the RTS/DTR and commence network operation.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-close">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_close</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_close</refname>
 <refpurpose>
     Close a PIO Z8530 channel
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_close </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     Network device to close
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to disassociate and move to idle
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Close down a Z8530 interface and switch its interrupt handlers
   to discard future events.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-dma-open">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_dma_open</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_dma_open</refname>
 <refpurpose>
     Open a Z8530 for DMA I/O
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_dma_open </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     The network device to attach
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to configure in sync DMA mode.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Set up a Z85x30 device for synchronous DMA in both directions. Two
   ISA DMA channels must be available for this to work. We assume ISA
   DMA driven I/O and PC limits on access.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-dma-close">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_dma_close</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_dma_close</refname>
 <refpurpose>
     Close down DMA I/O
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_dma_close </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     Network device to detach
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to move into discard mode
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Shut down a DMA mode synchronous interface. Halt the DMA, and
   free the buffers.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-txdma-open">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_txdma_open</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_txdma_open</refname>
 <refpurpose>
     Open a Z8530 for TX driven DMA
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_txdma_open </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     The network device to attach
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to configure in sync DMA mode.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Set up a Z85x30 device for synchronous DMA tranmission. One
   ISA DMA channel must be available for this to work. The receive
   side is run in PIO mode, but then it has the bigger FIFO.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-sync-txdma-close">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_sync_txdma_close</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_sync_txdma_close</refname>
 <refpurpose>
     Close down a TX driven DMA channel
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_sync_txdma_close </function></funcdef>
   <paramdef>struct net_device * <parameter>dev</parameter></paramdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     Network device to detach
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to move into discard mode
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Shut down a DMA/PIO split mode synchronous interface. Halt the DMA, 
   and  free the buffers.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-describe">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_describe</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_describe</refname>
 <refpurpose>
     Uniformly describe a Z8530 port
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_describe </function></funcdef>
   <paramdef>struct z8530_dev * <parameter>dev</parameter></paramdef>
   <paramdef>char * <parameter>mapping</parameter></paramdef>
   <paramdef>unsigned long <parameter>io</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     Z8530 device to describe
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>mapping</parameter></term>
   <listitem>
    <para>
     string holding mapping type (eg <quote>I/O</quote> or <quote>Mem</quote>)
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>io</parameter></term>
   <listitem>
    <para>
     the port value in question
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Describe a Z8530 in a standard format. We must pass the I/O as
   the port offset isnt predictable. The main reason for this function
   is to try and get a common format of report.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-init">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_init</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_init</refname>
 <refpurpose>
     Initialise a Z8530 device
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_init </function></funcdef>
   <paramdef>struct z8530_dev * <parameter>dev</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     Z8530 device to initialise.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Configure up a Z8530/Z85C30 or Z85230 chip. We check the device
   is present, identify the type and then program it to hopefully
   keep quite and behave. This matters a lot, a Z8530 in the wrong
   state will sometimes get into stupid modes generating 10Khz
   interrupt streams and the like.
   </para><para>

   We set the interrupt handler up to discard any events, in case
   we get them during reset or setp.
   </para><para>

   Return 0 for success, or a negative value indicating the problem
   in errno form.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-shutdown">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_shutdown</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_shutdown</refname>
 <refpurpose>
     Shutdown a Z8530 device
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_shutdown </function></funcdef>
   <paramdef>struct z8530_dev * <parameter>dev</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>dev</parameter></term>
   <listitem>
    <para>
     The Z8530 chip to shutdown
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   We set the interrupt handlers to silence any interrupts. We then 
   reset the chip and wait 100uS to be sure the reset completed. Just
   in case the caller then tries to do stuff.
   </para><para>

   This is called without the lock held
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-channel-load">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_channel_load</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_channel_load</refname>
 <refpurpose>
     Load channel data
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_channel_load </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>u8 * <parameter>rtable</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to configure
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>rtable</parameter></term>
   <listitem>
    <para>
     table of register, value pairs
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>FIXME</title>
<para>
   ioctl to allow user uploaded tables
   </para><para>

   Load a Z8530 channel up from the system data. We use +16 to 
   indicate the <quote>prime</quote> registers. The value 255 terminates the
   table.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-null-rx">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_null_rx</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_null_rx</refname>
 <refpurpose>
     Discard a packet
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_null_rx </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>struct sk_buff * <parameter>skb</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The channel the packet arrived on
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>skb</parameter></term>
   <listitem>
    <para>
     The buffer
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   We point the receive handler at this function when idle. Instead
   of syncppp processing the frames we get to throw them away.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-queue-xmit">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_queue_xmit</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_queue_xmit</refname>
 <refpurpose>
     Queue a packet
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_queue_xmit </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>struct sk_buff * <parameter>skb</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The channel to use
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>skb</parameter></term>
   <listitem>
    <para>
     The packet to kick down the channel
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Queue a packet for transmission. Because we have rather
   hard to hit interrupt latencies for the Z85230 per packet 
   even in DMA mode we do the flip to DMA buffer if needed here
   not in the IRQ.
   </para><para>

   Called from the network code. The lock is not held at this 
   point.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-get-stats">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_get_stats</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_get_stats</refname>
 <refpurpose>
     Get network statistics
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>struct net_device_stats * <function>z8530_get_stats </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The channel to use
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Get the statistics block. We keep the statistics in software as
   the chip doesn't do it for us.
   </para><para>

   Locking is ignored here - we could lock for a copy but its
   not likely to be that big an issue
</para>
</refsect1>
</refentry>

  </chapter>

  <chapter id="intfunctions">
     <title>Internal Functions</title>
<!-- drivers/net/wan/z85230.c -->
<refentry id="API-z8530-read-port">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_read_port</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_read_port</refname>
 <refpurpose>
  Architecture specific interface function
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>z8530_read_port </function></funcdef>
   <paramdef>unsigned long <parameter>p</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>p</parameter></term>
   <listitem>
    <para>
     port to read
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Provided port access methods. The Comtrol SV11 requires no delays
   between accesses and uses PC I/O. Some drivers may need a 5uS delay
   </para><para>

   In the longer term this should become an architecture specific
   section so that this can become a generic driver interface for all
   platforms. For now we only handle PC I/O ports with or without the
   dread 5uS sanity delay.
   </para><para>

   The caller must hold sufficient locks to avoid violating the horrible
   5uS delay rule.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-write-port">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_write_port</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_write_port</refname>
 <refpurpose>
     Architecture specific interface function
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_write_port </function></funcdef>
   <paramdef>unsigned long <parameter>p</parameter></paramdef>
   <paramdef>u8 <parameter>d</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>p</parameter></term>
   <listitem>
    <para>
     port to write
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>d</parameter></term>
   <listitem>
    <para>
     value to write
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Write a value to a port with delays if need be. Note that the
   caller must hold locks to avoid read/writes from other contexts
   violating the 5uS rule
   </para><para>

   In the longer term this should become an architecture specific
   section so that this can become a generic driver interface for all
   platforms. For now we only handle PC I/O ports with or without the
   dread 5uS sanity delay.
</para>
</refsect1>
</refentry>

<refentry id="API-read-zsreg">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>read_zsreg</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>read_zsreg</refname>
 <refpurpose>
     Read a register from a Z85230
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>u8 <function>read_zsreg </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>u8 <parameter>reg</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to read from (2 per chip)
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>reg</parameter></term>
   <listitem>
    <para>
     Register to read
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>FIXME</title>
<para>
   Use a spinlock.
   </para><para>

   Most of the Z8530 registers are indexed off the control registers.
   A read is done by writing to the control register and reading the
   register back.  The caller must hold the lock
</para>
</refsect1>
</refentry>

<refentry id="API-read-zsdata">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>read_zsdata</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>read_zsdata</refname>
 <refpurpose>
     Read the data port of a Z8530 channel
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>u8 <function>read_zsdata </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to read the data port from
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   The data port provides fast access to some things. We still
   have all the 5uS delays to worry about.
</para>
</refsect1>
</refentry>

<refentry id="API-write-zsreg">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>write_zsreg</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>write_zsreg</refname>
 <refpurpose>
     Write to a Z8530 channel register
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>write_zsreg </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>u8 <parameter>reg</parameter></paramdef>
   <paramdef>u8 <parameter>val</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>reg</parameter></term>
   <listitem>
    <para>
     Register number
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>val</parameter></term>
   <listitem>
    <para>
     Value to write
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Write a value to an indexed register. The caller must hold the lock
   to honour the irritating delay rules. We know about register 0
   being fast to access.
   </para><para>

   Assumes c-&gt;lock is held.
</para>
</refsect1>
</refentry>

<refentry id="API-write-zsctrl">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>write_zsctrl</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>write_zsctrl</refname>
 <refpurpose>
     Write to a Z8530 control register
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>write_zsctrl </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>u8 <parameter>val</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>val</parameter></term>
   <listitem>
    <para>
     Value to write
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Write directly to the control register on the Z8530
</para>
</refsect1>
</refentry>

<refentry id="API-write-zsdata">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>write_zsdata</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>write_zsdata</refname>
 <refpurpose>
     Write to a Z8530 control register
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>write_zsdata </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>u8 <parameter>val</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>val</parameter></term>
   <listitem>
    <para>
     Value to write
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Write directly to the data register on the Z8530
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-flush-fifo">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_flush_fifo</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_flush_fifo</refname>
 <refpurpose>
     Flush on chip RX FIFO
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_flush_fifo </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Channel to flush
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Flush the receive FIFO. There is no specific option for this, we 
   blindly read bytes and discard them. Reading when there is no data
   is harmless. The 8530 has a 4 byte FIFO, the 85230 has 8 bytes.
   </para><para>

   All locking is handled for the caller. On return data may still be
   present if it arrived during the flush.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-rtsdtr">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_rtsdtr</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_rtsdtr</refname>
 <refpurpose>
     Control the outgoing DTS/RTS line
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_rtsdtr </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
   <paramdef>int <parameter>set</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to control;
    </para>
   </listitem>
  </varlistentry>
  <varlistentry>
   <term><parameter>set</parameter></term>
   <listitem>
    <para>
     1 to set, 0 to clear
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Sets or clears DTR/RTS on the requested line. All locking is handled
   by the caller. For now we assume all boards use the actual RTS/DTR
   on the chip. Apparently one or two don't. We'll scream about them
   later.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-rx">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_rx</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_rx</refname>
 <refpurpose>
     Handle a PIO receive event
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_rx </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to process
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Receive handler for receiving in PIO mode. This is much like the 
   async one but not quite the same or as complex
</para>
</refsect1>
<refsect1>
<title>Note</title>
<para>
   Its intended that this handler can easily be separated from
   the main code to run realtime. That'll be needed for some machines
   (eg to ever clock 64kbits on a sparc ;)).
   </para><para>

   The RT_LOCK macros don't do anything now. Keep the code covered
   by them as short as possible in all circumstances - clocks cost
   baud. The interrupt handler is assumed to be atomic w.r.t. to
   other code - this is true in the RT case too.
   </para><para>

   We only cover the sync cases for this. If you want 2Mbit async
   do it yourself but consider medical assistance first. This non DMA 
   synchronous mode is portable code. The DMA mode assumes PCI like 
   ISA DMA
   </para><para>

   Called with the device lock held
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-tx">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_tx</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_tx</refname>
 <refpurpose>
     Handle a PIO transmit event
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_tx </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to process
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Z8530 transmit interrupt handler for the PIO mode. The basic
   idea is to attempt to keep the FIFO fed. We fill as many bytes
   in as possible, its quite possible that we won't keep up with the
   data rate otherwise.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-status">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_status</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_status</refname>
 <refpurpose>
     Handle a PIO status exception
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_status </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>chan</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>chan</parameter></term>
   <listitem>
    <para>
     Z8530 channel to process
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   A status event occurred in PIO synchronous mode. There are several
   reasons the chip will bother us here. A transmit underrun means we
   failed to feed the chip fast enough and just broke a packet. A DCD
   change is a line up or down. We communicate that back to the protocol
   layer for synchronous PPP to renegotiate.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-dma-rx">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_dma_rx</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_dma_rx</refname>
 <refpurpose>
     Handle a DMA RX event
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_dma_rx </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>chan</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>chan</parameter></term>
   <listitem>
    <para>
     Channel to handle
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Non bus mastering DMA interfaces for the Z8x30 devices. This
   is really pretty PC specific. The DMA mode means that most receive
   events are handled by the DMA hardware. We get a kick here only if
   a frame ended.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-dma-tx">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_dma_tx</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_dma_tx</refname>
 <refpurpose>
     Handle a DMA TX event
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_dma_tx </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>chan</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>chan</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to handle
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   We have received an interrupt while doing DMA transmissions. It
   shouldn't happen. Scream loudly if it does.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-dma-status">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_dma_status</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_dma_status</refname>
 <refpurpose>
     Handle a DMA status exception
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_dma_status </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>chan</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>chan</parameter></term>
   <listitem>
    <para>
     Z8530 channel to process
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   A status event occurred on the Z8530. We receive these for two reasons
   when in DMA mode. Firstly if we finished a packet transfer we get one
   and kick the next packet out. Secondly we may see a DCD change and
   have to poke the protocol layer.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-rx-clear">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_rx_clear</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_rx_clear</refname>
 <refpurpose>
     Handle RX events from a stopped chip
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_rx_clear </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to shut up
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Receive interrupt vectors for a Z8530 that is in 'parked' mode.
   For machines with PCI Z85x30 cards, or level triggered interrupts
   (eg the MacII) we must clear the interrupt cause or die.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-tx-clear">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_tx_clear</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_tx_clear</refname>
 <refpurpose>
     Handle TX events from a stopped chip
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_tx_clear </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     Z8530 channel to shut up
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Transmit interrupt vectors for a Z8530 that is in 'parked' mode.
   For machines with PCI Z85x30 cards, or level triggered interrupts
   (eg the MacII) we must clear the interrupt cause or die.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-status-clear">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_status_clear</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_status_clear</refname>
 <refpurpose>
     Handle status events from a stopped chip
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_status_clear </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>chan</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>chan</parameter></term>
   <listitem>
    <para>
     Z8530 channel to shut up
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Status interrupt vectors for a Z8530 that is in 'parked' mode.
   For machines with PCI Z85x30 cards, or level triggered interrupts
   (eg the MacII) we must clear the interrupt cause or die.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-tx-begin">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_tx_begin</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_tx_begin</refname>
 <refpurpose>
     Begin packet transmission
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_tx_begin </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The Z8530 channel to kick
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   This is the speed sensitive side of transmission. If we are called
   and no buffer is being transmitted we commence the next buffer. If
   nothing is queued we idle the sync. 
</para>
</refsect1>
<refsect1>
<title>Note</title>
<para>
   We are handling this code path in the interrupt path, keep it
   fast or bad things will happen.
   </para><para>

   Called with the lock held.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-tx-done">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_tx_done</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_tx_done</refname>
 <refpurpose>
     TX complete callback
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_tx_done </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The channel that completed a transmit.
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   This is called when we complete a packet send. We wake the queue,
   start the next packet going and then free the buffer of the existing
   packet. This code is fairly timing sensitive.
   </para><para>

   Called with the register lock held.
</para>
</refsect1>
</refentry>

<refentry id="API-z8530-rx-done">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>z8530_rx_done</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>z8530_rx_done</refname>
 <refpurpose>
     Receive completion callback
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>void <function>z8530_rx_done </function></funcdef>
   <paramdef>struct z8530_channel * <parameter>c</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>c</parameter></term>
   <listitem>
    <para>
     The channel that completed a receive
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   A new packet is complete. Our goal here is to get back into receive
   mode as fast as possible. On the Z85230 we could change to using
   ESCC mode, but on the older chips we have no choice. We flip to the
   new buffer immediately in DMA mode so that the DMA of the next
   frame can occur while we are copying the previous buffer to an sk_buff
   </para><para>

   Called with the lock held
</para>
</refsect1>
</refentry>

<refentry id="API-spans-boundary">
<refentryinfo>
 <title>LINUX</title>
 <productname>Kernel Hackers Manual</productname>
 <date>February 2008</date>
</refentryinfo>
<refmeta>
 <refentrytitle><phrase>spans_boundary</phrase></refentrytitle>
 <manvolnum>9</manvolnum>
 <refmiscinfo class="version">2.6.25-rc3</refmiscinfo>
</refmeta>
<refnamediv>
 <refname>spans_boundary</refname>
 <refpurpose>
     Check a packet can be ISA DMA'd
 </refpurpose>
</refnamediv>
<refsynopsisdiv>
 <title>Synopsis</title>
  <funcsynopsis><funcprototype>
   <funcdef>int <function>spans_boundary </function></funcdef>
   <paramdef>struct sk_buff * <parameter>skb</parameter></paramdef>
  </funcprototype></funcsynopsis>
</refsynopsisdiv>
<refsect1>
 <title>Arguments</title>
 <variablelist>
  <varlistentry>
   <term><parameter>skb</parameter></term>
   <listitem>
    <para>
     The buffer to check
    </para>
   </listitem>
  </varlistentry>
 </variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>
   Returns true if the buffer cross a DMA boundary on a PC. The poor
   thing can only DMA within a 64K block not across the edges of it.
</para>
</refsect1>
</refentry>

  </chapter>

</book>
