linux/drivers/misc/pti.c
<<
>>
Prefs
   1/*
   2 *  pti.c - PTI driver for cJTAG data extration
   3 *
   4 *  Copyright (C) Intel 2010
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16 *
  17 * The PTI (Parallel Trace Interface) driver directs trace data routed from
  18 * various parts in the system out through the Intel Penwell PTI port and
  19 * out of the mobile device for analysis with a debugging tool
  20 * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
  21 * compact JTAG, standard.
  22 */
  23
  24#include <linux/init.h>
  25#include <linux/sched.h>
  26#include <linux/interrupt.h>
  27#include <linux/console.h>
  28#include <linux/kernel.h>
  29#include <linux/module.h>
  30#include <linux/tty.h>
  31#include <linux/tty_driver.h>
  32#include <linux/pci.h>
  33#include <linux/mutex.h>
  34#include <linux/miscdevice.h>
  35#include <linux/pti.h>
  36
  37#define DRIVERNAME              "pti"
  38#define PCINAME                 "pciPTI"
  39#define TTYNAME                 "ttyPTI"
  40#define CHARNAME                "pti"
  41#define PTITTY_MINOR_START      0
  42#define PTITTY_MINOR_NUM        2
  43#define MAX_APP_IDS             16   /* 128 channel ids / u8 bit size */
  44#define MAX_OS_IDS              16   /* 128 channel ids / u8 bit size */
  45#define MAX_MODEM_IDS           16   /* 128 channel ids / u8 bit size */
  46#define MODEM_BASE_ID           71   /* modem master ID address    */
  47#define CONTROL_ID              72   /* control master ID address  */
  48#define CONSOLE_ID              73   /* console master ID address  */
  49#define OS_BASE_ID              74   /* base OS master ID address  */
  50#define APP_BASE_ID             80   /* base App master ID address */
  51#define CONTROL_FRAME_LEN       32   /* PTI control frame maximum size */
  52#define USER_COPY_SIZE          8192 /* 8Kb buffer for user space copy */
  53#define APERTURE_14             0x3800000 /* offset to first OS write addr */
  54#define APERTURE_LEN            0x400000  /* address length */
  55
  56struct pti_tty {
  57        struct pti_masterchannel *mc;
  58};
  59
  60struct pti_dev {
  61        struct tty_port port;
  62        unsigned long pti_addr;
  63        unsigned long aperture_base;
  64        void __iomem *pti_ioaddr;
  65        u8 ia_app[MAX_APP_IDS];
  66        u8 ia_os[MAX_OS_IDS];
  67        u8 ia_modem[MAX_MODEM_IDS];
  68};
  69
  70/*
  71 * This protects access to ia_app, ia_os, and ia_modem,
  72 * which keeps track of channels allocated in
  73 * an aperture write id.
  74 */
  75static DEFINE_MUTEX(alloclock);
  76
  77static struct pci_device_id pci_ids[] __devinitconst = {
  78                {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
  79                {0}
  80};
  81
  82static struct tty_driver *pti_tty_driver;
  83static struct pti_dev *drv_data;
  84
  85static unsigned int pti_console_channel;
  86static unsigned int pti_control_channel;
  87
  88/**
  89 *  pti_write_to_aperture()- The private write function to PTI HW.
  90 *
  91 *  @mc: The 'aperture'. It's part of a write address that holds
  92 *       a master and channel ID.
  93 *  @buf: Data being written to the HW that will ultimately be seen
  94 *        in a debugging tool (Fido, Lauterbach).
  95 *  @len: Size of buffer.
  96 *
  97 *  Since each aperture is specified by a unique
  98 *  master/channel ID, no two processes will be writing
  99 *  to the same aperture at the same time so no lock is required. The
 100 *  PTI-Output agent will send these out in the order that they arrived, and
 101 *  thus, it will intermix these messages. The debug tool can then later
 102 *  regroup the appropriate message segments together reconstituting each
 103 *  message.
 104 */
 105static void pti_write_to_aperture(struct pti_masterchannel *mc,
 106                                  u8 *buf,
 107                                  int len)
 108{
 109        int dwordcnt;
 110        int final;
 111        int i;
 112        u32 ptiword;
 113        u32 __iomem *aperture;
 114        u8 *p = buf;
 115
 116        /*
 117         * calculate the aperture offset from the base using the master and
 118         * channel id's.
 119         */
 120        aperture = drv_data->pti_ioaddr + (mc->master << 15)
 121                + (mc->channel << 8);
 122
 123        dwordcnt = len >> 2;
 124        final = len - (dwordcnt << 2);      /* final = trailing bytes    */
 125        if (final == 0 && dwordcnt != 0) {  /* always need a final dword */
 126                final += 4;
 127                dwordcnt--;
 128        }
 129
 130        for (i = 0; i < dwordcnt; i++) {
 131                ptiword = be32_to_cpu(*(u32 *)p);
 132                p += 4;
 133                iowrite32(ptiword, aperture);
 134        }
 135
 136        aperture += PTI_LASTDWORD_DTS;  /* adding DTS signals that is EOM */
 137
 138        ptiword = 0;
 139        for (i = 0; i < final; i++)
 140                ptiword |= *p++ << (24-(8*i));
 141
 142        iowrite32(ptiword, aperture);
 143        return;
 144}
 145
 146/**
 147 *  pti_control_frame_built_and_sent()- control frame build and send function.
 148 *
 149 *  @mc: The master / channel structure on which the function
 150 *       built a control frame.
 151 *
 152 *  To be able to post process the PTI contents on host side, a control frame
 153 *  is added before sending any PTI content. So the host side knows on
 154 *  each PTI frame the name of the thread using a dedicated master / channel.
 155 *  The thread name is retrieved from the 'current' global variable.
 156 *  This function builds this frame and sends it to a master ID CONTROL_ID.
 157 *  The overhead is only 32 bytes since the driver only writes to HW
 158 *  in 32 byte chunks.
 159 */
 160
 161static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc)
 162{
 163        struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
 164                                              .channel = 0};
 165        const char *control_format = "%3d %3d %s";
 166        u8 control_frame[CONTROL_FRAME_LEN];
 167
 168        /*
 169         * Since we access the comm member in current's task_struct,
 170         * we only need to be as large as what 'comm' in that
 171         * structure is.
 172         */
 173        char comm[TASK_COMM_LEN];
 174
 175        if (!in_interrupt())
 176                get_task_comm(comm, current);
 177        else
 178                strncpy(comm, "Interrupt", TASK_COMM_LEN);
 179
 180        /* Absolutely ensure our buffer is zero terminated. */
 181        comm[TASK_COMM_LEN-1] = 0;
 182
 183        mccontrol.channel = pti_control_channel;
 184        pti_control_channel = (pti_control_channel + 1) & 0x7f;
 185
 186        snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
 187                mc->channel, comm);
 188        pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
 189}
 190
 191/**
 192 *  pti_write_full_frame_to_aperture()- high level function to
 193 *                                      write to PTI.
 194 *
 195 *  @mc:  The 'aperture'. It's part of a write address that holds
 196 *        a master and channel ID.
 197 *  @buf: Data being written to the HW that will ultimately be seen
 198 *        in a debugging tool (Fido, Lauterbach).
 199 *  @len: Size of buffer.
 200 *
 201 *  All threads sending data (either console, user space application, ...)
 202 *  are calling the high level function to write to PTI meaning that it is
 203 *  possible to add a control frame before sending the content.
 204 */
 205static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
 206                                                const unsigned char *buf,
 207                                                int len)
 208{
 209        pti_control_frame_built_and_sent(mc);
 210        pti_write_to_aperture(mc, (u8 *)buf, len);
 211}
 212
 213/**
 214 * get_id()- Allocate a master and channel ID.
 215 *
 216 * @id_array: an array of bits representing what channel
 217 *            id's are allocated for writing.
 218 * @max_ids:  The max amount of available write IDs to use.
 219 * @base_id:  The starting SW channel ID, based on the Intel
 220 *            PTI arch.
 221 *
 222 * Returns:
 223 *      pti_masterchannel struct with master, channel ID address
 224 *      0 for error
 225 *
 226 * Each bit in the arrays ia_app and ia_os correspond to a master and
 227 * channel id. The bit is one if the id is taken and 0 if free. For
 228 * every master there are 128 channel id's.
 229 */
 230static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
 231{
 232        struct pti_masterchannel *mc;
 233        int i, j, mask;
 234
 235        mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL);
 236        if (mc == NULL)
 237                return NULL;
 238
 239        /* look for a byte with a free bit */
 240        for (i = 0; i < max_ids; i++)
 241                if (id_array[i] != 0xff)
 242                        break;
 243        if (i == max_ids) {
 244                kfree(mc);
 245                return NULL;
 246        }
 247        /* find the bit in the 128 possible channel opportunities */
 248        mask = 0x80;
 249        for (j = 0; j < 8; j++) {
 250                if ((id_array[i] & mask) == 0)
 251                        break;
 252                mask >>= 1;
 253        }
 254
 255        /* grab it */
 256        id_array[i] |= mask;
 257        mc->master  = base_id;
 258        mc->channel = ((i & 0xf)<<3) + j;
 259        /* write new master Id / channel Id allocation to channel control */
 260        pti_control_frame_built_and_sent(mc);
 261        return mc;
 262}
 263
 264/*
 265 * The following three functions:
 266 * pti_request_mastercahannel(), mipi_release_masterchannel()
 267 * and pti_writedata() are an API for other kernel drivers to
 268 * access PTI.
 269 */
 270
 271/**
 272 * pti_request_masterchannel()- Kernel API function used to allocate
 273 *                              a master, channel ID address
 274 *                              to write to PTI HW.
 275 *
 276 * @type: 0- request Application  master, channel aperture ID write address.
 277 *        1- request OS master, channel aperture ID write
 278 *           address.
 279 *        2- request Modem master, channel aperture ID
 280 *           write address.
 281 *        Other values, error.
 282 *
 283 * Returns:
 284 *      pti_masterchannel struct
 285 *      0 for error
 286 */
 287struct pti_masterchannel *pti_request_masterchannel(u8 type)
 288{
 289        struct pti_masterchannel *mc;
 290
 291        mutex_lock(&alloclock);
 292
 293        switch (type) {
 294
 295        case 0:
 296                mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID);
 297                break;
 298
 299        case 1:
 300                mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID);
 301                break;
 302
 303        case 2:
 304                mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID);
 305                break;
 306        default:
 307                mc = NULL;
 308        }
 309
 310        mutex_unlock(&alloclock);
 311        return mc;
 312}
 313EXPORT_SYMBOL_GPL(pti_request_masterchannel);
 314
 315/**
 316 * pti_release_masterchannel()- Kernel API function used to release
 317 *                              a master, channel ID address
 318 *                              used to write to PTI HW.
 319 *
 320 * @mc: master, channel apeture ID address to be released.  This
 321 *      will de-allocate the structure via kfree().
 322 */
 323void pti_release_masterchannel(struct pti_masterchannel *mc)
 324{
 325        u8 master, channel, i;
 326
 327        mutex_lock(&alloclock);
 328
 329        if (mc) {
 330                master = mc->master;
 331                channel = mc->channel;
 332
 333                if (master == APP_BASE_ID) {
 334                        i = channel >> 3;
 335                        drv_data->ia_app[i] &=  ~(0x80>>(channel & 0x7));
 336                } else if (master == OS_BASE_ID) {
 337                        i = channel >> 3;
 338                        drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7));
 339                } else {
 340                        i = channel >> 3;
 341                        drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7));
 342                }
 343
 344                kfree(mc);
 345        }
 346
 347        mutex_unlock(&alloclock);
 348}
 349EXPORT_SYMBOL_GPL(pti_release_masterchannel);
 350
 351/**
 352 * pti_writedata()- Kernel API function used to write trace
 353 *                  debugging data to PTI HW.
 354 *
 355 * @mc:    Master, channel aperture ID address to write to.
 356 *         Null value will return with no write occurring.
 357 * @buf:   Trace debuging data to write to the PTI HW.
 358 *         Null value will return with no write occurring.
 359 * @count: Size of buf. Value of 0 or a negative number will
 360 *         return with no write occuring.
 361 */
 362void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count)
 363{
 364        /*
 365         * since this function is exported, this is treated like an
 366         * API function, thus, all parameters should
 367         * be checked for validity.
 368         */
 369        if ((mc != NULL) && (buf != NULL) && (count > 0))
 370                pti_write_to_aperture(mc, buf, count);
 371        return;
 372}
 373EXPORT_SYMBOL_GPL(pti_writedata);
 374
 375/**
 376 * pti_pci_remove()- Driver exit method to remove PTI from
 377 *                 PCI bus.
 378 * @pdev: variable containing pci info of PTI.
 379 */
 380static void __devexit pti_pci_remove(struct pci_dev *pdev)
 381{
 382        struct pti_dev *drv_data;
 383
 384        drv_data = pci_get_drvdata(pdev);
 385        if (drv_data != NULL) {
 386                pci_iounmap(pdev, drv_data->pti_ioaddr);
 387                pci_set_drvdata(pdev, NULL);
 388                kfree(drv_data);
 389                pci_release_region(pdev, 1);
 390                pci_disable_device(pdev);
 391        }
 392}
 393
 394/*
 395 * for the tty_driver_*() basic function descriptions, see tty_driver.h.
 396 * Specific header comments made for PTI-related specifics.
 397 */
 398
 399/**
 400 * pti_tty_driver_open()- Open an Application master, channel aperture
 401 * ID to the PTI device via tty device.
 402 *
 403 * @tty: tty interface.
 404 * @filp: filp interface pased to tty_port_open() call.
 405 *
 406 * Returns:
 407 *      int, 0 for success
 408 *      otherwise, fail value
 409 *
 410 * The main purpose of using the tty device interface is for
 411 * each tty port to have a unique PTI write aperture.  In an
 412 * example use case, ttyPTI0 gets syslogd and an APP aperture
 413 * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route
 414 * modem messages into PTI.  Modem trace data does not have to
 415 * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct
 416 * master IDs.  These messages go through the PTI HW and out of
 417 * the handheld platform and to the Fido/Lauterbach device.
 418 */
 419static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
 420{
 421        /*
 422         * we actually want to allocate a new channel per open, per
 423         * system arch.  HW gives more than plenty channels for a single
 424         * system task to have its own channel to write trace data. This
 425         * also removes a locking requirement for the actual write
 426         * procedure.
 427         */
 428        return tty_port_open(&drv_data->port, tty, filp);
 429}
 430
 431/**
 432 * pti_tty_driver_close()- close tty device and release Application
 433 * master, channel aperture ID to the PTI device via tty device.
 434 *
 435 * @tty: tty interface.
 436 * @filp: filp interface pased to tty_port_close() call.
 437 *
 438 * The main purpose of using the tty device interface is to route
 439 * syslog daemon messages to the PTI HW and out of the handheld platform
 440 * and to the Fido/Lauterbach device.
 441 */
 442static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
 443{
 444        tty_port_close(&drv_data->port, tty, filp);
 445}
 446
 447/**
 448 * pti_tty_intstall()- Used to set up specific master-channels
 449 *                     to tty ports for organizational purposes when
 450 *                     tracing viewed from debuging tools.
 451 *
 452 * @driver: tty driver information.
 453 * @tty: tty struct containing pti information.
 454 *
 455 * Returns:
 456 *      0 for success
 457 *      otherwise, error
 458 */
 459static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 460{
 461        int idx = tty->index;
 462        struct pti_tty *pti_tty_data;
 463        int ret = tty_init_termios(tty);
 464
 465        if (ret == 0) {
 466                tty_driver_kref_get(driver);
 467                tty->count++;
 468                driver->ttys[idx] = tty;
 469
 470                pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
 471                if (pti_tty_data == NULL)
 472                        return -ENOMEM;
 473
 474                if (idx == PTITTY_MINOR_START)
 475                        pti_tty_data->mc = pti_request_masterchannel(0);
 476                else
 477                        pti_tty_data->mc = pti_request_masterchannel(2);
 478
 479                if (pti_tty_data->mc == NULL) {
 480                        kfree(pti_tty_data);
 481                        return -ENXIO;
 482                }
 483                tty->driver_data = pti_tty_data;
 484        }
 485
 486        return ret;
 487}
 488
 489/**
 490 * pti_tty_cleanup()- Used to de-allocate master-channel resources
 491 *                    tied to tty's of this driver.
 492 *
 493 * @tty: tty struct containing pti information.
 494 */
 495static void pti_tty_cleanup(struct tty_struct *tty)
 496{
 497        struct pti_tty *pti_tty_data = tty->driver_data;
 498        if (pti_tty_data == NULL)
 499                return;
 500        pti_release_masterchannel(pti_tty_data->mc);
 501        kfree(pti_tty_data);
 502        tty->driver_data = NULL;
 503}
 504
 505/**
 506 * pti_tty_driver_write()-  Write trace debugging data through the char
 507 * interface to the PTI HW.  Part of the misc device implementation.
 508 *
 509 * @filp: Contains private data which is used to obtain
 510 *        master, channel write ID.
 511 * @data: trace data to be written.
 512 * @len:  # of byte to write.
 513 *
 514 * Returns:
 515 *      int, # of bytes written
 516 *      otherwise, error
 517 */
 518static int pti_tty_driver_write(struct tty_struct *tty,
 519        const unsigned char *buf, int len)
 520{
 521        struct pti_tty *pti_tty_data = tty->driver_data;
 522        if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) {
 523                pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len);
 524                return len;
 525        }
 526        /*
 527         * we can't write to the pti hardware if the private driver_data
 528         * and the mc address is not there.
 529         */
 530        else
 531                return -EFAULT;
 532}
 533
 534/**
 535 * pti_tty_write_room()- Always returns 2048.
 536 *
 537 * @tty: contains tty info of the pti driver.
 538 */
 539static int pti_tty_write_room(struct tty_struct *tty)
 540{
 541        return 2048;
 542}
 543
 544/**
 545 * pti_char_open()- Open an Application master, channel aperture
 546 * ID to the PTI device. Part of the misc device implementation.
 547 *
 548 * @inode: not used.
 549 * @filp:  Output- will have a masterchannel struct set containing
 550 *                 the allocated application PTI aperture write address.
 551 *
 552 * Returns:
 553 *      int, 0 for success
 554 *      otherwise, a fail value
 555 */
 556static int pti_char_open(struct inode *inode, struct file *filp)
 557{
 558        struct pti_masterchannel *mc;
 559
 560        /*
 561         * We really do want to fail immediately if
 562         * pti_request_masterchannel() fails,
 563         * before assigning the value to filp->private_data.
 564         * Slightly easier to debug if this driver needs debugging.
 565         */
 566        mc = pti_request_masterchannel(0);
 567        if (mc == NULL)
 568                return -ENOMEM;
 569        filp->private_data = mc;
 570        return 0;
 571}
 572
 573/**
 574 * pti_char_release()-  Close a char channel to the PTI device. Part
 575 * of the misc device implementation.
 576 *
 577 * @inode: Not used in this implementaiton.
 578 * @filp:  Contains private_data that contains the master, channel
 579 *         ID to be released by the PTI device.
 580 *
 581 * Returns:
 582 *      always 0
 583 */
 584static int pti_char_release(struct inode *inode, struct file *filp)
 585{
 586        pti_release_masterchannel(filp->private_data);
 587        filp->private_data = NULL;
 588        return 0;
 589}
 590
 591/**
 592 * pti_char_write()-  Write trace debugging data through the char
 593 * interface to the PTI HW.  Part of the misc device implementation.
 594 *
 595 * @filp:  Contains private data which is used to obtain
 596 *         master, channel write ID.
 597 * @data:  trace data to be written.
 598 * @len:   # of byte to write.
 599 * @ppose: Not used in this function implementation.
 600 *
 601 * Returns:
 602 *      int, # of bytes written
 603 *      otherwise, error value
 604 *
 605 * Notes: From side discussions with Alan Cox and experimenting
 606 * with PTI debug HW like Nokia's Fido box and Lauterbach
 607 * devices, 8192 byte write buffer used by USER_COPY_SIZE was
 608 * deemed an appropriate size for this type of usage with
 609 * debugging HW.
 610 */
 611static ssize_t pti_char_write(struct file *filp, const char __user *data,
 612                              size_t len, loff_t *ppose)
 613{
 614        struct pti_masterchannel *mc;
 615        void *kbuf;
 616        const char __user *tmp;
 617        size_t size = USER_COPY_SIZE;
 618        size_t n = 0;
 619
 620        tmp = data;
 621        mc = filp->private_data;
 622
 623        kbuf = kmalloc(size, GFP_KERNEL);
 624        if (kbuf == NULL)  {
 625                pr_err("%s(%d): buf allocation failed\n",
 626                        __func__, __LINE__);
 627                return -ENOMEM;
 628        }
 629
 630        do {
 631                if (len - n > USER_COPY_SIZE)
 632                        size = USER_COPY_SIZE;
 633                else
 634                        size = len - n;
 635
 636                if (copy_from_user(kbuf, tmp, size)) {
 637                        kfree(kbuf);
 638                        return n ? n : -EFAULT;
 639                }
 640
 641                pti_write_to_aperture(mc, kbuf, size);
 642                n  += size;
 643                tmp += size;
 644
 645        } while (len > n);
 646
 647        kfree(kbuf);
 648        return len;
 649}
 650
 651static const struct tty_operations pti_tty_driver_ops = {
 652        .open           = pti_tty_driver_open,
 653        .close          = pti_tty_driver_close,
 654        .write          = pti_tty_driver_write,
 655        .write_room     = pti_tty_write_room,
 656        .install        = pti_tty_install,
 657        .cleanup        = pti_tty_cleanup
 658};
 659
 660static const struct file_operations pti_char_driver_ops = {
 661        .owner          = THIS_MODULE,
 662        .write          = pti_char_write,
 663        .open           = pti_char_open,
 664        .release        = pti_char_release,
 665};
 666
 667static struct miscdevice pti_char_driver = {
 668        .minor          = MISC_DYNAMIC_MINOR,
 669        .name           = CHARNAME,
 670        .fops           = &pti_char_driver_ops
 671};
 672
 673/**
 674 * pti_console_write()-  Write to the console that has been acquired.
 675 *
 676 * @c:   Not used in this implementaiton.
 677 * @buf: Data to be written.
 678 * @len: Length of buf.
 679 */
 680static void pti_console_write(struct console *c, const char *buf, unsigned len)
 681{
 682        static struct pti_masterchannel mc = {.master  = CONSOLE_ID,
 683                                              .channel = 0};
 684
 685        mc.channel = pti_console_channel;
 686        pti_console_channel = (pti_console_channel + 1) & 0x7f;
 687
 688        pti_write_full_frame_to_aperture(&mc, buf, len);
 689}
 690
 691/**
 692 * pti_console_device()-  Return the driver tty structure and set the
 693 *                        associated index implementation.
 694 *
 695 * @c:     Console device of the driver.
 696 * @index: index associated with c.
 697 *
 698 * Returns:
 699 *      always value of pti_tty_driver structure when this function
 700 *      is called.
 701 */
 702static struct tty_driver *pti_console_device(struct console *c, int *index)
 703{
 704        *index = c->index;
 705        return pti_tty_driver;
 706}
 707
 708/**
 709 * pti_console_setup()-  Initialize console variables used by the driver.
 710 *
 711 * @c:     Not used.
 712 * @opts:  Not used.
 713 *
 714 * Returns:
 715 *      always 0.
 716 */
 717static int pti_console_setup(struct console *c, char *opts)
 718{
 719        pti_console_channel = 0;
 720        pti_control_channel = 0;
 721        return 0;
 722}
 723
 724/*
 725 * pti_console struct, used to capture OS printk()'s and shift
 726 * out to the PTI device for debugging.  This cannot be
 727 * enabled upon boot because of the possibility of eating
 728 * any serial console printk's (race condition discovered).
 729 * The console should be enabled upon when the tty port is
 730 * used for the first time.  Since the primary purpose for
 731 * the tty port is to hook up syslog to it, the tty port
 732 * will be open for a really long time.
 733 */
 734static struct console pti_console = {
 735        .name           = TTYNAME,
 736        .write          = pti_console_write,
 737        .device         = pti_console_device,
 738        .setup          = pti_console_setup,
 739        .flags          = CON_PRINTBUFFER,
 740        .index          = 0,
 741};
 742
 743/**
 744 * pti_port_activate()- Used to start/initialize any items upon
 745 * first opening of tty_port().
 746 *
 747 * @port- The tty port number of the PTI device.
 748 * @tty-  The tty struct associated with this device.
 749 *
 750 * Returns:
 751 *      always returns 0
 752 *
 753 * Notes: The primary purpose of the PTI tty port 0 is to hook
 754 * the syslog daemon to it; thus this port will be open for a
 755 * very long time.
 756 */
 757static int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
 758{
 759        if (port->tty->index == PTITTY_MINOR_START)
 760                console_start(&pti_console);
 761        return 0;
 762}
 763
 764/**
 765 * pti_port_shutdown()- Used to stop/shutdown any items upon the
 766 * last tty port close.
 767 *
 768 * @port- The tty port number of the PTI device.
 769 *
 770 * Notes: The primary purpose of the PTI tty port 0 is to hook
 771 * the syslog daemon to it; thus this port will be open for a
 772 * very long time.
 773 */
 774static void pti_port_shutdown(struct tty_port *port)
 775{
 776        if (port->tty->index == PTITTY_MINOR_START)
 777                console_stop(&pti_console);
 778}
 779
 780static const struct tty_port_operations tty_port_ops = {
 781        .activate = pti_port_activate,
 782        .shutdown = pti_port_shutdown,
 783};
 784
 785/*
 786 * Note the _probe() call sets everything up and ties the char and tty
 787 * to successfully detecting the PTI device on the pci bus.
 788 */
 789
 790/**
 791 * pti_pci_probe()- Used to detect pti on the pci bus and set
 792 *                  things up in the driver.
 793 *
 794 * @pdev- pci_dev struct values for pti.
 795 * @ent-  pci_device_id struct for pti driver.
 796 *
 797 * Returns:
 798 *      0 for success
 799 *      otherwise, error
 800 */
 801static int __devinit pti_pci_probe(struct pci_dev *pdev,
 802                const struct pci_device_id *ent)
 803{
 804        int retval = -EINVAL;
 805        int pci_bar = 1;
 806
 807        dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__,
 808                        __func__, __LINE__, pdev->vendor, pdev->device);
 809
 810        retval = misc_register(&pti_char_driver);
 811        if (retval) {
 812                pr_err("%s(%d): CHAR registration failed of pti driver\n",
 813                        __func__, __LINE__);
 814                pr_err("%s(%d): Error value returned: %d\n",
 815                        __func__, __LINE__, retval);
 816                return retval;
 817        }
 818
 819        retval = pci_enable_device(pdev);
 820        if (retval != 0) {
 821                dev_err(&pdev->dev,
 822                        "%s: pci_enable_device() returned error %d\n",
 823                        __func__, retval);
 824                return retval;
 825        }
 826
 827        drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
 828
 829        if (drv_data == NULL) {
 830                retval = -ENOMEM;
 831                dev_err(&pdev->dev,
 832                        "%s(%d): kmalloc() returned NULL memory.\n",
 833                        __func__, __LINE__);
 834                return retval;
 835        }
 836        drv_data->pti_addr = pci_resource_start(pdev, pci_bar);
 837
 838        retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
 839        if (retval != 0) {
 840                dev_err(&pdev->dev,
 841                        "%s(%d): pci_request_region() returned error %d\n",
 842                        __func__, __LINE__, retval);
 843                kfree(drv_data);
 844                return retval;
 845        }
 846        drv_data->aperture_base = drv_data->pti_addr+APERTURE_14;
 847        drv_data->pti_ioaddr =
 848                ioremap_nocache((u32)drv_data->aperture_base,
 849                APERTURE_LEN);
 850        if (!drv_data->pti_ioaddr) {
 851                pci_release_region(pdev, pci_bar);
 852                retval = -ENOMEM;
 853                kfree(drv_data);
 854                return retval;
 855        }
 856
 857        pci_set_drvdata(pdev, drv_data);
 858
 859        tty_port_init(&drv_data->port);
 860        drv_data->port.ops = &tty_port_ops;
 861
 862        tty_register_device(pti_tty_driver, 0, &pdev->dev);
 863        tty_register_device(pti_tty_driver, 1, &pdev->dev);
 864
 865        register_console(&pti_console);
 866
 867        return retval;
 868}
 869
 870static struct pci_driver pti_pci_driver = {
 871        .name           = PCINAME,
 872        .id_table       = pci_ids,
 873        .probe          = pti_pci_probe,
 874        .remove         = pti_pci_remove,
 875};
 876
 877/**
 878 *
 879 * pti_init()- Overall entry/init call to the pti driver.
 880 *             It starts the registration process with the kernel.
 881 *
 882 * Returns:
 883 *      int __init, 0 for success
 884 *      otherwise value is an error
 885 *
 886 */
 887static int __init pti_init(void)
 888{
 889        int retval = -EINVAL;
 890
 891        /* First register module as tty device */
 892
 893        pti_tty_driver = alloc_tty_driver(1);
 894        if (pti_tty_driver == NULL) {
 895                pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
 896                        __func__, __LINE__);
 897                return -ENOMEM;
 898        }
 899
 900        pti_tty_driver->owner                   = THIS_MODULE;
 901        pti_tty_driver->magic                   = TTY_DRIVER_MAGIC;
 902        pti_tty_driver->driver_name             = DRIVERNAME;
 903        pti_tty_driver->name                    = TTYNAME;
 904        pti_tty_driver->major                   = 0;
 905        pti_tty_driver->minor_start             = PTITTY_MINOR_START;
 906        pti_tty_driver->minor_num               = PTITTY_MINOR_NUM;
 907        pti_tty_driver->num                     = PTITTY_MINOR_NUM;
 908        pti_tty_driver->type                    = TTY_DRIVER_TYPE_SYSTEM;
 909        pti_tty_driver->subtype                 = SYSTEM_TYPE_SYSCONS;
 910        pti_tty_driver->flags                   = TTY_DRIVER_REAL_RAW |
 911                                                  TTY_DRIVER_DYNAMIC_DEV;
 912        pti_tty_driver->init_termios            = tty_std_termios;
 913
 914        tty_set_operations(pti_tty_driver, &pti_tty_driver_ops);
 915
 916        retval = tty_register_driver(pti_tty_driver);
 917        if (retval) {
 918                pr_err("%s(%d): TTY registration failed of pti driver\n",
 919                        __func__, __LINE__);
 920                pr_err("%s(%d): Error value returned: %d\n",
 921                        __func__, __LINE__, retval);
 922
 923                pti_tty_driver = NULL;
 924                return retval;
 925        }
 926
 927        retval = pci_register_driver(&pti_pci_driver);
 928
 929        if (retval) {
 930                pr_err("%s(%d): PCI registration failed of pti driver\n",
 931                        __func__, __LINE__);
 932                pr_err("%s(%d): Error value returned: %d\n",
 933                        __func__, __LINE__, retval);
 934
 935                tty_unregister_driver(pti_tty_driver);
 936                pr_err("%s(%d): Unregistering TTY part of pti driver\n",
 937                        __func__, __LINE__);
 938                pti_tty_driver = NULL;
 939                return retval;
 940        }
 941
 942        return retval;
 943}
 944
 945/**
 946 * pti_exit()- Unregisters this module as a tty and pci driver.
 947 */
 948static void __exit pti_exit(void)
 949{
 950        int retval;
 951
 952        tty_unregister_device(pti_tty_driver, 0);
 953        tty_unregister_device(pti_tty_driver, 1);
 954
 955        retval = tty_unregister_driver(pti_tty_driver);
 956        if (retval) {
 957                pr_err("%s(%d): TTY unregistration failed of pti driver\n",
 958                        __func__, __LINE__);
 959                pr_err("%s(%d): Error value returned: %d\n",
 960                        __func__, __LINE__, retval);
 961        }
 962
 963        pci_unregister_driver(&pti_pci_driver);
 964
 965        retval = misc_deregister(&pti_char_driver);
 966        if (retval) {
 967                pr_err("%s(%d): CHAR unregistration failed of pti driver\n",
 968                        __func__, __LINE__);
 969                pr_err("%s(%d): Error value returned: %d\n",
 970                        __func__, __LINE__, retval);
 971        }
 972
 973        unregister_console(&pti_console);
 974        return;
 975}
 976
 977module_init(pti_init);
 978module_exit(pti_exit);
 979
 980MODULE_LICENSE("GPL");
 981MODULE_AUTHOR("Ken Mills, Jay Freyensee");
 982MODULE_DESCRIPTION("PTI Driver");
 983
 984