linux/drivers/staging/fwserial/fwserial.h
<<
>>
Prefs
   1#ifndef _FIREWIRE_FWSERIAL_H
   2#define _FIREWIRE_FWSERIAL_H
   3
   4#include <linux/kernel.h>
   5#include <linux/tty.h>
   6#include <linux/tty_driver.h>
   7#include <linux/tty_flip.h>
   8#include <linux/list.h>
   9#include <linux/firewire.h>
  10#include <linux/firewire-constants.h>
  11#include <linux/spinlock.h>
  12#include <linux/rcupdate.h>
  13#include <linux/mutex.h>
  14#include <linux/serial.h>
  15#include <linux/serial_reg.h>
  16#include <linux/module.h>
  17#include <linux/seq_file.h>
  18#include <linux/debugfs.h>
  19
  20#include "dma_fifo.h"
  21
  22#ifdef FWTTY_PROFILING
  23#define DISTRIBUTION_MAX_SIZE     8192
  24#define DISTRIBUTION_MAX_INDEX    (ilog2(DISTRIBUTION_MAX_SIZE) + 1)
  25static inline void profile_size_distrib(unsigned stat[], unsigned val)
  26{
  27        int n = (val) ? min(ilog2(val) + 1, DISTRIBUTION_MAX_INDEX) : 0;
  28        ++stat[n];
  29}
  30#else
  31#define DISTRIBUTION_MAX_INDEX    0
  32#define profile_size_distrib(st, n)
  33#endif
  34
  35/* Parameters for both VIRT_CABLE_PLUG & VIRT_CABLE_PLUG_RSP mgmt codes */
  36struct virt_plug_params {
  37        __be32  status_hi;
  38        __be32  status_lo;
  39        __be32  fifo_hi;
  40        __be32  fifo_lo;
  41        __be32  fifo_len;
  42};
  43
  44struct peer_work_params {
  45        union {
  46                struct virt_plug_params plug_req;
  47        };
  48};
  49
  50/**
  51 * fwtty_peer: structure representing local & remote unit devices
  52 * @unit: unit child device of fw_device node
  53 * @serial: back pointer to associated fw_serial aggregate
  54 * @guid: unique 64-bit guid for this unit device
  55 * @generation: most recent bus generation
  56 * @node_id: most recent node_id
  57 * @speed: link speed of peer (0 = S100, 2 = S400, ... 5 = S3200)
  58 * @mgmt_addr: bus addr region to write mgmt packets to
  59 * @status_addr: bus addr register to write line status to
  60 * @fifo_addr: bus addr region to write serial output to
  61 * @fifo_len:  max length for single write to fifo_addr
  62 * @list: link for insertion into fw_serial's peer_list
  63 * @rcu: for deferring peer reclamation
  64 * @lock: spinlock to synchonize changes to state & port fields
  65 * @work: only one work item can be queued at any one time
  66 *        Note: pending work is canceled prior to removal, so this
  67 *        peer is valid for at least the lifetime of the work function
  68 * @work_params: parameter block for work functions
  69 * @timer: timer for resetting peer state if remote request times out
  70 * @state: current state
  71 * @connect: work item for auto-connecting
  72 * @connect_retries: # of connections already attempted
  73 * @port: associated tty_port (usable if state == FWSC_ATTACHED)
  74 */
  75struct fwtty_peer {
  76        struct fw_unit          *unit;
  77        struct fw_serial        *serial;
  78        u64                     guid;
  79        int                     generation;
  80        int                     node_id;
  81        unsigned                speed;
  82        int                     max_payload;
  83        u64                     mgmt_addr;
  84
  85        /* these are usable only if state == FWSC_ATTACHED */
  86        u64                     status_addr;
  87        u64                     fifo_addr;
  88        int                     fifo_len;
  89
  90        struct list_head        list;
  91        struct rcu_head         rcu;
  92
  93        spinlock_t              lock;
  94        struct work_struct      work;
  95        struct peer_work_params work_params;
  96        struct timer_list       timer;
  97        int                     state;
  98        struct delayed_work     connect;
  99        int                     connect_retries;
 100
 101        struct fwtty_port       *port;
 102};
 103
 104#define to_peer(ptr, field)     (container_of(ptr, struct fwtty_peer, field))
 105
 106/* state values for fwtty_peer.state field */
 107enum fwtty_peer_state {
 108        FWPS_GONE,
 109        FWPS_NOT_ATTACHED,
 110        FWPS_ATTACHED,
 111        FWPS_PLUG_PENDING,
 112        FWPS_PLUG_RESPONDING,
 113        FWPS_UNPLUG_PENDING,
 114        FWPS_UNPLUG_RESPONDING,
 115
 116        FWPS_NO_MGMT_ADDR = -1,
 117};
 118
 119#define CONNECT_RETRY_DELAY     HZ
 120#define MAX_CONNECT_RETRIES     10
 121
 122/* must be holding peer lock for these state funclets */
 123static inline void peer_set_state(struct fwtty_peer *peer, int new)
 124{
 125        peer->state = new;
 126}
 127
 128static inline struct fwtty_port *peer_revert_state(struct fwtty_peer *peer)
 129{
 130        struct fwtty_port *port = peer->port;
 131
 132        peer->port = NULL;
 133        peer_set_state(peer, FWPS_NOT_ATTACHED);
 134        return port;
 135}
 136
 137struct fwserial_mgmt_pkt {
 138        struct {
 139                __be16          len;
 140                __be16          code;
 141        } hdr;
 142        union {
 143                struct virt_plug_params plug_req;
 144                struct virt_plug_params plug_rsp;
 145        };
 146} __packed;
 147
 148/* fwserial_mgmt_packet codes */
 149#define FWSC_RSP_OK                     0x0000
 150#define FWSC_RSP_NACK                   0x8000
 151#define FWSC_CODE_MASK                  0x0fff
 152
 153#define FWSC_VIRT_CABLE_PLUG            1
 154#define FWSC_VIRT_CABLE_UNPLUG          2
 155#define FWSC_VIRT_CABLE_PLUG_RSP        3
 156#define FWSC_VIRT_CABLE_UNPLUG_RSP      4
 157
 158/* 1 min. plug timeout -- suitable for userland authorization */
 159#define VIRT_CABLE_PLUG_TIMEOUT         (60 * HZ)
 160
 161struct stats {
 162        unsigned        xchars;
 163        unsigned        dropped;
 164        unsigned        tx_stall;
 165        unsigned        fifo_errs;
 166        unsigned        sent;
 167        unsigned        lost;
 168        unsigned        throttled;
 169        unsigned        watermark;
 170        unsigned        reads[DISTRIBUTION_MAX_INDEX + 1];
 171        unsigned        writes[DISTRIBUTION_MAX_INDEX + 1];
 172        unsigned        txns[DISTRIBUTION_MAX_INDEX + 1];
 173        unsigned        unthrottle[DISTRIBUTION_MAX_INDEX + 1];
 174};
 175
 176struct fwconsole_ops {
 177        void (*notify)(int code, void *data);
 178        void (*stats)(struct stats *stats, void *data);
 179        void (*proc_show)(struct seq_file *m, void *data);
 180};
 181
 182/* codes for console ops notify */
 183#define FWCON_NOTIFY_ATTACH             1
 184#define FWCON_NOTIFY_DETACH             2
 185
 186struct buffered_rx {
 187        struct list_head        list;
 188        size_t                  n;
 189        unsigned char           data[0];
 190};
 191
 192/**
 193 * fwtty_port: structure used to track/represent underlying tty_port
 194 * @port: underlying tty_port
 195 * @device: tty device
 196 * @index: index into port_table for this particular port
 197 *    note: minor = index + minor_start assigned by tty_alloc_driver()
 198 * @serial: back pointer to the containing fw_serial
 199 * @rx_handler: bus address handler for unique addr region used by remotes
 200 *              to communicate with this port. Every port uses
 201 *              fwtty_port_handler() for per port transactions.
 202 * @fwcon_ops: ops for attached fw_console (if any)
 203 * @con_data: private data for fw_console
 204 * @wait_tx: waitqueue for sleeping until writer/drain completes tx
 205 * @emit_breaks: delayed work responsible for generating breaks when the
 206 *               break line status is active
 207 * @cps : characters per second computed from the termios settings
 208 * @break_last: timestamp in jiffies from last emit_breaks
 209 * @hangup: work responsible for HUPing when carrier is dropped/lost
 210 * @mstatus: loose virtualization of LSR/MSR
 211 *         bits 15..0  correspond to TIOCM_* bits
 212 *         bits 19..16 reserved for mctrl
 213 *         bit 20      OOB_TX_THROTTLE
 214 *         bits 23..21 reserved
 215 *         bits 31..24 correspond to UART_LSR_* bits
 216 * @lock: spinlock for protecting concurrent access to fields below it
 217 * @mctrl: loose virtualization of MCR
 218 *         bits 15..0  correspond to TIOCM_* bits
 219 *         bit 16      OOB_RX_THROTTLE
 220 *         bits 19..17 reserved
 221 *         bits 31..20 reserved for mstatus
 222 * @drain: delayed work scheduled to ensure that writes are flushed.
 223 *         The work can race with the writer but concurrent sending is
 224 *         prevented with the IN_TX flag. Scheduled under lock to
 225 *         limit scheduling when fifo has just been drained.
 226 * @push: work responsible for pushing buffered rx to the ldisc.
 227 *        rx can become buffered if the tty buffer is filled before the
 228 *        ldisc throttles the sender.
 229 * @buf_list: list of buffered rx yet to be sent to ldisc
 230 * @buffered: byte count of buffered rx
 231 * @tx_fifo: fifo used to store & block-up writes for dma to remote
 232 * @max_payload: max bytes transmissable per dma (based on peer's max_payload)
 233 * @status_mask: UART_LSR_* bitmask significant to rx (based on termios)
 234 * @ignore_mask: UART_LSR_* bitmask of states to ignore (also based on termios)
 235 * @break_ctl: if set, port is 'sending break' to remote
 236 * @write_only: self-explanatory
 237 * @overrun: previous rx was lost (partially or completely)
 238 * @loopback: if set, port is in loopback mode
 239 * @flags: atomic bit flags
 240 *         bit 0: IN_TX - gate to allow only one cpu to send from the dma fifo
 241 *                        at a time.
 242 *         bit 1: STOP_TX - force tx to exit while sending
 243 * @peer: rcu-pointer to associated fwtty_peer (if attached)
 244 *        NULL if no peer attached
 245 * @icount: predefined statistics reported by the TIOCGICOUNT ioctl
 246 * @stats: additional statistics reported in /proc/tty/driver/firewire_serial
 247 */
 248struct fwtty_port {
 249        struct tty_port            port;
 250        struct device              *device;
 251        unsigned                   index;
 252        struct fw_serial           *serial;
 253        struct fw_address_handler  rx_handler;
 254
 255        struct fwconsole_ops       *fwcon_ops;
 256        void                       *con_data;
 257
 258        wait_queue_head_t          wait_tx;
 259        struct delayed_work        emit_breaks;
 260        unsigned                   cps;
 261        unsigned long              break_last;
 262
 263        struct work_struct         hangup;
 264
 265        unsigned                   mstatus;
 266
 267        spinlock_t                 lock;
 268        unsigned                   mctrl;
 269        struct delayed_work        drain;
 270        struct work_struct         push;
 271        struct list_head           buf_list;
 272        int                        buffered;
 273        struct dma_fifo            tx_fifo;
 274        int                        max_payload;
 275        unsigned                   status_mask;
 276        unsigned                   ignore_mask;
 277        unsigned                   break_ctl:1,
 278                                   write_only:1,
 279                                   overrun:1,
 280                                   loopback:1;
 281        unsigned long              flags;
 282
 283        struct fwtty_peer __rcu    *peer;
 284
 285        struct async_icount        icount;
 286        struct stats               stats;
 287};
 288
 289#define to_port(ptr, field)     (container_of(ptr, struct fwtty_port, field))
 290
 291/* bit #s for flags field */
 292#define IN_TX                      0
 293#define STOP_TX                    1
 294#define BUFFERING_RX               2
 295
 296/* bitmasks for special mctrl/mstatus bits */
 297#define OOB_RX_THROTTLE   0x00010000
 298#define MCTRL_RSRVD       0x000e0000
 299#define OOB_TX_THROTTLE   0x00100000
 300#define MSTATUS_RSRVD     0x00e00000
 301
 302#define MCTRL_MASK        (TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | TIOCM_OUT2 | \
 303                           TIOCM_LOOP | OOB_RX_THROTTLE | MCTRL_RSRVD)
 304
 305/* XXX even every 1/50th secs. may be unnecessarily accurate */
 306/* delay in jiffies between brk emits */
 307#define FREQ_BREAKS        (HZ / 50)
 308
 309/* Ports are allocated in blocks of num_ports for each fw_card */
 310#define MAX_CARD_PORTS           32     /* max # of ports per card */
 311#define MAX_TOTAL_PORTS          64     /* max # of ports total    */
 312
 313/* tuning parameters */
 314#define FWTTY_PORT_TXFIFO_LEN   4096
 315#define FWTTY_PORT_MAX_PEND_DMA    8    /* costs a cache line per pend */
 316#define DRAIN_THRESHOLD         1024
 317#define MAX_ASYNC_PAYLOAD       4096    /* ohci-defined limit          */
 318#define WRITER_MINIMUM           128
 319/* TODO: how to set watermark to AR context size? see fwtty_rx() */
 320#define HIGH_WATERMARK         32768    /* AR context is 32K           */
 321
 322/*
 323 * Size of bus addr region above 4GB used per port as the recv addr
 324 * - must be at least as big as the MAX_ASYNC_PAYLOAD
 325 */
 326#define FWTTY_PORT_RXFIFO_LEN   MAX_ASYNC_PAYLOAD
 327
 328/**
 329 * fw_serial: aggregate used to associate tty ports with specific fw_card
 330 * @card: fw_card associated with this fw_serial device (1:1 association)
 331 * @kref: reference-counted multi-port management allows delayed destroy
 332 * @self: local unit device as 'peer'. Not valid until local unit device
 333 *         is enumerated.
 334 * @list: link for insertion into fwserial_list
 335 * @peer_list: list of local & remote unit devices attached to this card
 336 * @ports: fixed array of tty_ports provided by this serial device
 337 */
 338struct fw_serial {
 339        struct fw_card    *card;
 340        struct kref       kref;
 341
 342        struct dentry     *debugfs;
 343        struct fwtty_peer *self;
 344
 345        struct list_head  list;
 346        struct list_head  peer_list;
 347
 348        struct fwtty_port *ports[MAX_CARD_PORTS];
 349};
 350
 351#define to_serial(ptr, field)   (container_of(ptr, struct fw_serial, field))
 352
 353#define TTY_DEV_NAME                "fwtty"     /* ttyFW was taken           */
 354static const char tty_dev_name[] =  TTY_DEV_NAME;
 355static const char loop_dev_name[] = "fwloop";
 356
 357extern struct tty_driver *fwtty_driver;
 358
 359struct fwtty_port *fwtty_port_get(unsigned index);
 360void fwtty_port_put(struct fwtty_port *port);
 361
 362static inline void fwtty_bind_console(struct fwtty_port *port,
 363                                      struct fwconsole_ops *fwcon_ops,
 364                                      void *data)
 365{
 366        port->con_data = data;
 367        port->fwcon_ops = fwcon_ops;
 368}
 369
 370/*
 371 * Returns the max send async payload size in bytes based on the unit device
 372 * link speed. Self-limiting asynchronous bandwidth (via reducing the payload)
 373 * is not necessary and does not work, because
 374 *   1) asynchronous traffic will absorb all available bandwidth (less that
 375 *      being used for isochronous traffic)
 376 *   2) isochronous arbitration always wins.
 377 */
 378static inline int link_speed_to_max_payload(unsigned speed)
 379{
 380        /* Max async payload is 4096 - see IEEE 1394-2008 tables 6-4, 16-18 */
 381        return min(512 << speed, 4096);
 382}
 383
 384#endif /* _FIREWIRE_FWSERIAL_H */
 385