linux/drivers/tty/metag_da.c
<<
>>
Prefs
   1/*
   2 *  dashtty.c - tty driver for Dash channels interface.
   3 *
   4 *  Copyright (C) 2007,2008,2012 Imagination Technologies
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file COPYING in the main directory of this archive
   8 * for more details.
   9 *
  10 */
  11
  12#include <linux/atomic.h>
  13#include <linux/completion.h>
  14#include <linux/console.h>
  15#include <linux/delay.h>
  16#include <linux/export.h>
  17#include <linux/init.h>
  18#include <linux/kernel.h>
  19#include <linux/kthread.h>
  20#include <linux/moduleparam.h>
  21#include <linux/mutex.h>
  22#include <linux/sched.h>
  23#include <linux/serial.h>
  24#include <linux/slab.h>
  25#include <linux/spinlock.h>
  26#include <linux/string.h>
  27#include <linux/timer.h>
  28#include <linux/tty.h>
  29#include <linux/tty_driver.h>
  30#include <linux/tty_flip.h>
  31#include <linux/uaccess.h>
  32
  33#include <asm/da.h>
  34
  35/* Channel error codes */
  36#define CONAOK  0
  37#define CONERR  1
  38#define CONBAD  2
  39#define CONPRM  3
  40#define CONADR  4
  41#define CONCNT  5
  42#define CONCBF  6
  43#define CONCBE  7
  44#define CONBSY  8
  45
  46/* Default channel for the console */
  47#define CONSOLE_CHANNEL      1
  48
  49#define NUM_TTY_CHANNELS     6
  50
  51/* Auto allocate */
  52#define DA_TTY_MAJOR        0
  53
  54/* A speedy poll rate helps the userland debug process connection response.
  55 * But, if you set it too high then no other userland processes get much
  56 * of a look in.
  57 */
  58#define DA_TTY_POLL (HZ / 50)
  59
  60/*
  61 * A short put delay improves latency but has a high throughput overhead
  62 */
  63#define DA_TTY_PUT_DELAY (HZ / 100)
  64
  65static atomic_t num_channels_need_poll = ATOMIC_INIT(0);
  66
  67static struct timer_list poll_timer;
  68
  69static struct tty_driver *channel_driver;
  70
  71static struct timer_list put_timer;
  72static struct task_struct *dashtty_thread;
  73
  74/*
  75 * The console_poll parameter determines whether the console channel should be
  76 * polled for input.
  77 * By default the console channel isn't polled at all, in order to avoid the
  78 * overhead, but that means it isn't possible to have a login on /dev/console.
  79 */
  80static bool console_poll;
  81module_param(console_poll, bool, S_IRUGO);
  82
  83#define RX_BUF_SIZE 1024
  84
  85enum {
  86        INCHR = 1,
  87        OUTCHR,
  88        RDBUF,
  89        WRBUF,
  90        RDSTAT
  91};
  92
  93/**
  94 * struct dashtty_port - Wrapper struct for dashtty tty_port.
  95 * @port:               TTY port data
  96 * @rx_lock:            Lock for rx_buf.
  97 *                      This protects between the poll timer and user context.
  98 *                      It's also held during read SWITCH operations.
  99 * @rx_buf:             Read buffer
 100 * @xmit_lock:          Lock for xmit_*, and port.xmit_buf.
 101 *                      This protects between user context and kernel thread.
 102 *                      It's also held during write SWITCH operations.
 103 * @xmit_cnt:           Size of xmit buffer contents
 104 * @xmit_head:          Head of xmit buffer where data is written
 105 * @xmit_tail:          Tail of xmit buffer where data is read
 106 * @xmit_empty:         Completion for xmit buffer being empty
 107 */
 108struct dashtty_port {
 109        struct tty_port          port;
 110        spinlock_t               rx_lock;
 111        void                    *rx_buf;
 112        struct mutex             xmit_lock;
 113        unsigned int             xmit_cnt;
 114        unsigned int             xmit_head;
 115        unsigned int             xmit_tail;
 116        struct completion        xmit_empty;
 117};
 118
 119static struct dashtty_port dashtty_ports[NUM_TTY_CHANNELS];
 120
 121static atomic_t dashtty_xmit_cnt = ATOMIC_INIT(0);
 122static wait_queue_head_t dashtty_waitqueue;
 123
 124/*
 125 * Low-level DA channel access routines
 126 */
 127static int chancall(int in_bios_function, int in_channel,
 128                    int in_arg2, void *in_arg3,
 129                    void *in_arg4)
 130{
 131        register int   bios_function asm("D1Ar1") = in_bios_function;
 132        register int   channel       asm("D0Ar2") = in_channel;
 133        register int   arg2          asm("D1Ar3") = in_arg2;
 134        register void *arg3          asm("D0Ar4") = in_arg3;
 135        register void *arg4          asm("D1Ar5") = in_arg4;
 136        register int   bios_call     asm("D0Ar6") = 3;
 137        register int   result        asm("D0Re0");
 138
 139        asm volatile (
 140                "MSETL  [A0StP++], %6,%4,%2\n\t"
 141                "ADD    A0StP, A0StP, #8\n\t"
 142                "SWITCH #0x0C30208\n\t"
 143                "GETD   %0, [A0StP+#-8]\n\t"
 144                "SUB    A0StP, A0StP, #(4*6)+8\n\t"
 145                : "=d" (result)   /* outs */
 146                : "d" (bios_function),
 147                  "d" (channel),
 148                  "d" (arg2),
 149                  "d" (arg3),
 150                  "d" (arg4),
 151                  "d" (bios_call) /* ins */
 152                : "memory");
 153
 154        return result;
 155}
 156
 157/*
 158 * Attempts to fetch count bytes from channel and returns actual count.
 159 */
 160static int fetch_data(unsigned int channel)
 161{
 162        struct dashtty_port *dport = &dashtty_ports[channel];
 163        int received = 0;
 164
 165        spin_lock_bh(&dport->rx_lock);
 166        /* check the port isn't being shut down */
 167        if (!dport->rx_buf)
 168                goto unlock;
 169        if (chancall(RDBUF, channel, RX_BUF_SIZE,
 170                     (void *)dport->rx_buf, &received) == CONAOK) {
 171                if (received) {
 172                        int space;
 173                        unsigned char *cbuf;
 174
 175                        space = tty_prepare_flip_string(&dport->port, &cbuf,
 176                                                        received);
 177
 178                        if (space <= 0)
 179                                goto unlock;
 180
 181                        memcpy(cbuf, dport->rx_buf, space);
 182                        tty_flip_buffer_push(&dport->port);
 183                }
 184        }
 185unlock:
 186        spin_unlock_bh(&dport->rx_lock);
 187
 188        return received;
 189}
 190
 191/**
 192 * find_channel_to_poll() - Returns number of the next channel to poll.
 193 * Returns:     The number of the next channel to poll, or -1 if none need
 194 *              polling.
 195 */
 196static int find_channel_to_poll(void)
 197{
 198        static int last_polled_channel;
 199        int last = last_polled_channel;
 200        int chan;
 201        struct dashtty_port *dport;
 202
 203        for (chan = last + 1; ; ++chan) {
 204                if (chan >= NUM_TTY_CHANNELS)
 205                        chan = 0;
 206
 207                dport = &dashtty_ports[chan];
 208                if (dport->rx_buf) {
 209                        last_polled_channel = chan;
 210                        return chan;
 211                }
 212
 213                if (chan == last)
 214                        break;
 215        }
 216        return -1;
 217}
 218
 219/**
 220 * put_channel_data() - Write out a block of channel data.
 221 * @chan:       DA channel number.
 222 *
 223 * Write a single block of data out to the debug adapter. If the circular buffer
 224 * is wrapped then only the first block is written.
 225 *
 226 * Returns:     1 if the remote buffer was too full to accept data.
 227 *              0 otherwise.
 228 */
 229static int put_channel_data(unsigned int chan)
 230{
 231        struct dashtty_port *dport;
 232        struct tty_struct *tty;
 233        int number_written;
 234        unsigned int count = 0;
 235
 236        dport = &dashtty_ports[chan];
 237        mutex_lock(&dport->xmit_lock);
 238        if (dport->xmit_cnt) {
 239                count = min((unsigned int)(SERIAL_XMIT_SIZE - dport->xmit_tail),
 240                            dport->xmit_cnt);
 241                chancall(WRBUF, chan, count,
 242                         dport->port.xmit_buf + dport->xmit_tail,
 243                         &number_written);
 244                dport->xmit_cnt -= number_written;
 245                if (!dport->xmit_cnt) {
 246                        /* reset pointers to avoid wraps */
 247                        dport->xmit_head = 0;
 248                        dport->xmit_tail = 0;
 249                        complete(&dport->xmit_empty);
 250                } else {
 251                        dport->xmit_tail += number_written;
 252                        if (dport->xmit_tail >= SERIAL_XMIT_SIZE)
 253                                dport->xmit_tail -= SERIAL_XMIT_SIZE;
 254                }
 255                atomic_sub(number_written, &dashtty_xmit_cnt);
 256        }
 257        mutex_unlock(&dport->xmit_lock);
 258
 259        /* if we've made more data available, wake up tty */
 260        if (count && number_written) {
 261                tty = tty_port_tty_get(&dport->port);
 262                if (tty) {
 263                        tty_wakeup(tty);
 264                        tty_kref_put(tty);
 265                }
 266        }
 267
 268        /* did the write fail? */
 269        return count && !number_written;
 270}
 271
 272/**
 273 * put_data() - Kernel thread to write out blocks of channel data to DA.
 274 * @arg:        Unused.
 275 *
 276 * This kernel thread runs while @dashtty_xmit_cnt != 0, and loops over the
 277 * channels to write out any buffered data. If any of the channels stall due to
 278 * the remote buffer being full, a hold off happens to allow the debugger to
 279 * drain the buffer.
 280 */
 281static int put_data(void *arg)
 282{
 283        unsigned int chan, stall;
 284
 285        __set_current_state(TASK_RUNNING);
 286        while (!kthread_should_stop()) {
 287                /*
 288                 * For each channel see if there's anything to transmit in the
 289                 * port's xmit_buf.
 290                 */
 291                stall = 0;
 292                for (chan = 0; chan < NUM_TTY_CHANNELS; ++chan)
 293                        stall += put_channel_data(chan);
 294
 295                /*
 296                 * If some of the buffers are full, hold off for a short while
 297                 * to allow them to empty.
 298                 */
 299                if (stall)
 300                        msleep(25);
 301
 302                wait_event_interruptible(dashtty_waitqueue,
 303                                         atomic_read(&dashtty_xmit_cnt));
 304        }
 305
 306        return 0;
 307}
 308
 309/*
 310 *      This gets called every DA_TTY_POLL and polls the channels for data
 311 */
 312static void dashtty_timer(unsigned long ignored)
 313{
 314        int channel;
 315
 316        /* If there are no ports open do nothing and don't poll again. */
 317        if (!atomic_read(&num_channels_need_poll))
 318                return;
 319
 320        channel = find_channel_to_poll();
 321
 322        /* Did we find a channel to poll? */
 323        if (channel >= 0)
 324                fetch_data(channel);
 325
 326        mod_timer_pinned(&poll_timer, jiffies + DA_TTY_POLL);
 327}
 328
 329static void add_poll_timer(struct timer_list *poll_timer)
 330{
 331        setup_timer(poll_timer, dashtty_timer, 0);
 332        poll_timer->expires = jiffies + DA_TTY_POLL;
 333
 334        /*
 335         * Always attach the timer to the boot CPU. The DA channels are per-CPU
 336         * so all polling should be from a single CPU.
 337         */
 338        add_timer_on(poll_timer, 0);
 339}
 340
 341static int dashtty_port_activate(struct tty_port *port, struct tty_struct *tty)
 342{
 343        struct dashtty_port *dport = container_of(port, struct dashtty_port,
 344                                                  port);
 345        void *rx_buf;
 346
 347        /* Allocate the buffer we use for writing data */
 348        if (tty_port_alloc_xmit_buf(port) < 0)
 349                goto err;
 350
 351        /* Allocate the buffer we use for reading data */
 352        rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL);
 353        if (!rx_buf)
 354                goto err_free_xmit;
 355
 356        spin_lock_bh(&dport->rx_lock);
 357        dport->rx_buf = rx_buf;
 358        spin_unlock_bh(&dport->rx_lock);
 359
 360        /*
 361         * Don't add the poll timer if we're opening a console. This
 362         * avoids the overhead of polling the Dash but means it is not
 363         * possible to have a login on /dev/console.
 364         *
 365         */
 366        if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL])
 367                if (atomic_inc_return(&num_channels_need_poll) == 1)
 368                        add_poll_timer(&poll_timer);
 369
 370        return 0;
 371err_free_xmit:
 372        tty_port_free_xmit_buf(port);
 373err:
 374        return -ENOMEM;
 375}
 376
 377static void dashtty_port_shutdown(struct tty_port *port)
 378{
 379        struct dashtty_port *dport = container_of(port, struct dashtty_port,
 380                                                  port);
 381        void *rx_buf;
 382        unsigned int count;
 383
 384        /* stop reading */
 385        if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL])
 386                if (atomic_dec_and_test(&num_channels_need_poll))
 387                        del_timer_sync(&poll_timer);
 388
 389        mutex_lock(&dport->xmit_lock);
 390        count = dport->xmit_cnt;
 391        mutex_unlock(&dport->xmit_lock);
 392        if (count) {
 393                /*
 394                 * There's still data to write out, so wake and wait for the
 395                 * writer thread to drain the buffer.
 396                 */
 397                del_timer(&put_timer);
 398                wake_up_interruptible(&dashtty_waitqueue);
 399                wait_for_completion(&dport->xmit_empty);
 400        }
 401
 402        /* Null the read buffer (timer could still be running!) */
 403        spin_lock_bh(&dport->rx_lock);
 404        rx_buf = dport->rx_buf;
 405        dport->rx_buf = NULL;
 406        spin_unlock_bh(&dport->rx_lock);
 407        /* Free the read buffer */
 408        kfree(rx_buf);
 409
 410        /* Free the write buffer */
 411        tty_port_free_xmit_buf(port);
 412}
 413
 414static const struct tty_port_operations dashtty_port_ops = {
 415        .activate       = dashtty_port_activate,
 416        .shutdown       = dashtty_port_shutdown,
 417};
 418
 419static int dashtty_install(struct tty_driver *driver, struct tty_struct *tty)
 420{
 421        return tty_port_install(&dashtty_ports[tty->index].port, driver, tty);
 422}
 423
 424static int dashtty_open(struct tty_struct *tty, struct file *filp)
 425{
 426        return tty_port_open(tty->port, tty, filp);
 427}
 428
 429static void dashtty_close(struct tty_struct *tty, struct file *filp)
 430{
 431        return tty_port_close(tty->port, tty, filp);
 432}
 433
 434static void dashtty_hangup(struct tty_struct *tty)
 435{
 436        int channel;
 437        struct dashtty_port *dport;
 438
 439        channel = tty->index;
 440        dport = &dashtty_ports[channel];
 441
 442        /* drop any data in the xmit buffer */
 443        mutex_lock(&dport->xmit_lock);
 444        if (dport->xmit_cnt) {
 445                atomic_sub(dport->xmit_cnt, &dashtty_xmit_cnt);
 446                dport->xmit_cnt = 0;
 447                dport->xmit_head = 0;
 448                dport->xmit_tail = 0;
 449                complete(&dport->xmit_empty);
 450        }
 451        mutex_unlock(&dport->xmit_lock);
 452
 453        tty_port_hangup(tty->port);
 454}
 455
 456/**
 457 * dashtty_put_timer() - Delayed wake up of kernel thread.
 458 * @ignored:    unused
 459 *
 460 * This timer function wakes up the kernel thread if any data exists in the
 461 * buffers. It is used to delay the expensive writeout until the writer has
 462 * stopped writing.
 463 */
 464static void dashtty_put_timer(unsigned long ignored)
 465{
 466        if (atomic_read(&dashtty_xmit_cnt))
 467                wake_up_interruptible(&dashtty_waitqueue);
 468}
 469
 470static int dashtty_write(struct tty_struct *tty, const unsigned char *buf,
 471                         int total)
 472{
 473        int channel, count, block;
 474        struct dashtty_port *dport;
 475
 476        /* Determine the channel */
 477        channel = tty->index;
 478        dport = &dashtty_ports[channel];
 479
 480        /*
 481         * Write to output buffer.
 482         *
 483         * The reason that we asynchronously write the buffer is because if we
 484         * were to write the buffer synchronously then because DA channels are
 485         * per-CPU the buffer would be written to the channel of whatever CPU
 486         * we're running on.
 487         *
 488         * What we actually want to happen is have all input and output done on
 489         * one CPU.
 490         */
 491        mutex_lock(&dport->xmit_lock);
 492        /* work out how many bytes we can write to the xmit buffer */
 493        total = min(total, (int)(SERIAL_XMIT_SIZE - dport->xmit_cnt));
 494        atomic_add(total, &dashtty_xmit_cnt);
 495        dport->xmit_cnt += total;
 496        /* write the actual bytes (may need splitting if it wraps) */
 497        for (count = total; count; count -= block) {
 498                block = min(count, (int)(SERIAL_XMIT_SIZE - dport->xmit_head));
 499                memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block);
 500                dport->xmit_head += block;
 501                if (dport->xmit_head >= SERIAL_XMIT_SIZE)
 502                        dport->xmit_head -= SERIAL_XMIT_SIZE;
 503                buf += block;
 504        }
 505        count = dport->xmit_cnt;
 506        /* xmit buffer no longer empty? */
 507        if (count)
 508                reinit_completion(&dport->xmit_empty);
 509        mutex_unlock(&dport->xmit_lock);
 510
 511        if (total) {
 512                /*
 513                 * If the buffer is full, wake up the kthread, otherwise allow
 514                 * some more time for the buffer to fill up a bit before waking
 515                 * it.
 516                 */
 517                if (count == SERIAL_XMIT_SIZE) {
 518                        del_timer(&put_timer);
 519                        wake_up_interruptible(&dashtty_waitqueue);
 520                } else {
 521                        mod_timer(&put_timer, jiffies + DA_TTY_PUT_DELAY);
 522                }
 523        }
 524        return total;
 525}
 526
 527static int dashtty_write_room(struct tty_struct *tty)
 528{
 529        struct dashtty_port *dport;
 530        int channel;
 531        int room;
 532
 533        channel = tty->index;
 534        dport = &dashtty_ports[channel];
 535
 536        /* report the space in the xmit buffer */
 537        mutex_lock(&dport->xmit_lock);
 538        room = SERIAL_XMIT_SIZE - dport->xmit_cnt;
 539        mutex_unlock(&dport->xmit_lock);
 540
 541        return room;
 542}
 543
 544static int dashtty_chars_in_buffer(struct tty_struct *tty)
 545{
 546        struct dashtty_port *dport;
 547        int channel;
 548        int chars;
 549
 550        channel = tty->index;
 551        dport = &dashtty_ports[channel];
 552
 553        /* report the number of bytes in the xmit buffer */
 554        mutex_lock(&dport->xmit_lock);
 555        chars = dport->xmit_cnt;
 556        mutex_unlock(&dport->xmit_lock);
 557
 558        return chars;
 559}
 560
 561static const struct tty_operations dashtty_ops = {
 562        .install                = dashtty_install,
 563        .open                   = dashtty_open,
 564        .close                  = dashtty_close,
 565        .hangup                 = dashtty_hangup,
 566        .write                  = dashtty_write,
 567        .write_room             = dashtty_write_room,
 568        .chars_in_buffer        = dashtty_chars_in_buffer,
 569};
 570
 571static int __init dashtty_init(void)
 572{
 573        int ret;
 574        int nport;
 575        struct dashtty_port *dport;
 576
 577        if (!metag_da_enabled())
 578                return -ENODEV;
 579
 580        channel_driver = tty_alloc_driver(NUM_TTY_CHANNELS,
 581                                          TTY_DRIVER_REAL_RAW);
 582        if (IS_ERR(channel_driver))
 583                return PTR_ERR(channel_driver);
 584
 585        channel_driver->driver_name = "metag_da";
 586        channel_driver->name = "ttyDA";
 587        channel_driver->major = DA_TTY_MAJOR;
 588        channel_driver->minor_start = 0;
 589        channel_driver->type = TTY_DRIVER_TYPE_SERIAL;
 590        channel_driver->subtype = SERIAL_TYPE_NORMAL;
 591        channel_driver->init_termios = tty_std_termios;
 592        channel_driver->init_termios.c_cflag |= CLOCAL;
 593
 594        tty_set_operations(channel_driver, &dashtty_ops);
 595        for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
 596                dport = &dashtty_ports[nport];
 597                tty_port_init(&dport->port);
 598                dport->port.ops = &dashtty_port_ops;
 599                spin_lock_init(&dport->rx_lock);
 600                mutex_init(&dport->xmit_lock);
 601                /* the xmit buffer starts empty, i.e. completely written */
 602                init_completion(&dport->xmit_empty);
 603                complete(&dport->xmit_empty);
 604        }
 605
 606        setup_timer(&put_timer, dashtty_put_timer, 0);
 607
 608        init_waitqueue_head(&dashtty_waitqueue);
 609        dashtty_thread = kthread_create(put_data, NULL, "ttyDA");
 610        if (IS_ERR(dashtty_thread)) {
 611                pr_err("Couldn't create dashtty thread\n");
 612                ret = PTR_ERR(dashtty_thread);
 613                goto err_destroy_ports;
 614        }
 615        /*
 616         * Bind the writer thread to the boot CPU so it can't migrate.
 617         * DA channels are per-CPU and we want all channel I/O to be on a single
 618         * predictable CPU.
 619         */
 620        kthread_bind(dashtty_thread, 0);
 621        wake_up_process(dashtty_thread);
 622
 623        ret = tty_register_driver(channel_driver);
 624
 625        if (ret < 0) {
 626                pr_err("Couldn't install dashtty driver: err %d\n",
 627                       ret);
 628                goto err_stop_kthread;
 629        }
 630
 631        return 0;
 632
 633err_stop_kthread:
 634        kthread_stop(dashtty_thread);
 635err_destroy_ports:
 636        for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) {
 637                dport = &dashtty_ports[nport];
 638                tty_port_destroy(&dport->port);
 639        }
 640        put_tty_driver(channel_driver);
 641        return ret;
 642}
 643device_initcall(dashtty_init);
 644
 645#ifdef CONFIG_DA_CONSOLE
 646
 647static void dash_console_write(struct console *co, const char *s,
 648                               unsigned int count)
 649{
 650        int actually_written;
 651
 652        chancall(WRBUF, CONSOLE_CHANNEL, count, (void *)s, &actually_written);
 653}
 654
 655static struct tty_driver *dash_console_device(struct console *c, int *index)
 656{
 657        *index = c->index;
 658        return channel_driver;
 659}
 660
 661struct console dash_console = {
 662        .name = "ttyDA",
 663        .write = dash_console_write,
 664        .device = dash_console_device,
 665        .flags = CON_PRINTBUFFER,
 666        .index = 1,
 667};
 668
 669#endif
 670