linux-bk/drivers/pci/hotplug/ibmphp_hpc.c
<<
>>
Prefs
   1/*
   2 * IBM Hot Plug Controller Driver
   3 *
   4 * Written By: Jyoti Shah, IBM Corporation
   5 *
   6 * Copyright (C) 2001-2003 IBM Corp.
   7 *
   8 * All rights reserved.
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or (at
  13 * your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful, but
  16 * WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  18 * NON INFRINGEMENT.  See the GNU General Public License for more
  19 * details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24 *
  25 * Send feedback to <gregkh@us.ibm.com>
  26 *                  <jshah@us.ibm.com>
  27 *
  28 */
  29
  30#include <linux/wait.h>
  31#include <linux/time.h>
  32#include <linux/delay.h>
  33#include <linux/module.h>
  34#include <linux/pci.h>
  35#include <linux/smp_lock.h>
  36#include <linux/init.h>
  37#include "ibmphp.h"
  38
  39static int to_debug = FALSE;
  40#define debug_polling(fmt, arg...)      do { if (to_debug) debug (fmt, arg); } while (0)
  41
  42//----------------------------------------------------------------------------
  43// timeout values
  44//----------------------------------------------------------------------------
  45#define CMD_COMPLETE_TOUT_SEC   60      // give HPC 60 sec to finish cmd
  46#define HPC_CTLR_WORKING_TOUT   60      // give HPC 60 sec to finish cmd
  47#define HPC_GETACCESS_TIMEOUT   60      // seconds
  48#define POLL_INTERVAL_SEC       2       // poll HPC every 2 seconds
  49#define POLL_LATCH_CNT          5       // poll latch 5 times, then poll slots
  50
  51//----------------------------------------------------------------------------
  52// Winnipeg Architected Register Offsets
  53//----------------------------------------------------------------------------
  54#define WPG_I2CMBUFL_OFFSET     0x08    // I2C Message Buffer Low
  55#define WPG_I2CMOSUP_OFFSET     0x10    // I2C Master Operation Setup Reg
  56#define WPG_I2CMCNTL_OFFSET     0x20    // I2C Master Control Register
  57#define WPG_I2CPARM_OFFSET      0x40    // I2C Parameter Register
  58#define WPG_I2CSTAT_OFFSET      0x70    // I2C Status Register
  59
  60//----------------------------------------------------------------------------
  61// Winnipeg Store Type commands (Add this commands to the register offset)
  62//----------------------------------------------------------------------------
  63#define WPG_I2C_AND             0x1000  // I2C AND operation
  64#define WPG_I2C_OR              0x2000  // I2C OR operation
  65
  66//----------------------------------------------------------------------------
  67// Command set for I2C Master Operation Setup Regisetr
  68//----------------------------------------------------------------------------
  69#define WPG_READATADDR_MASK     0x00010000      // read,bytes,I2C shifted,index
  70#define WPG_WRITEATADDR_MASK    0x40010000      // write,bytes,I2C shifted,index
  71#define WPG_READDIRECT_MASK     0x10010000
  72#define WPG_WRITEDIRECT_MASK    0x60010000
  73
  74
  75//----------------------------------------------------------------------------
  76// bit masks for I2C Master Control Register
  77//----------------------------------------------------------------------------
  78#define WPG_I2CMCNTL_STARTOP_MASK       0x00000002      // Start the Operation
  79
  80//----------------------------------------------------------------------------
  81//
  82//----------------------------------------------------------------------------
  83#define WPG_I2C_IOREMAP_SIZE    0x2044  // size of linear address interval
  84
  85//----------------------------------------------------------------------------
  86// command index
  87//----------------------------------------------------------------------------
  88#define WPG_1ST_SLOT_INDEX      0x01    // index - 1st slot for ctlr
  89#define WPG_CTLR_INDEX          0x0F    // index - ctlr
  90#define WPG_1ST_EXTSLOT_INDEX   0x10    // index - 1st ext slot for ctlr
  91#define WPG_1ST_BUS_INDEX       0x1F    // index - 1st bus for ctlr
  92
  93//----------------------------------------------------------------------------
  94// macro utilities
  95//----------------------------------------------------------------------------
  96// if bits 20,22,25,26,27,29,30 are OFF return TRUE
  97#define HPC_I2CSTATUS_CHECK(s)  ((u8)((s & 0x00000A76) ? FALSE : TRUE))
  98
  99//----------------------------------------------------------------------------
 100// global variables
 101//----------------------------------------------------------------------------
 102static int ibmphp_shutdown;
 103static int tid_poll;
 104static struct semaphore sem_hpcaccess;  // lock access to HPC
 105static struct semaphore semOperations;  // lock all operations and
 106                                        // access to data structures
 107static struct semaphore sem_exit;       // make sure polling thread goes away
 108//----------------------------------------------------------------------------
 109// local function prototypes
 110//----------------------------------------------------------------------------
 111static u8 i2c_ctrl_read (struct controller *, void __iomem *, u8);
 112static u8 i2c_ctrl_write (struct controller *, void __iomem *, u8, u8);
 113static u8 hpc_writecmdtoindex (u8, u8);
 114static u8 hpc_readcmdtoindex (u8, u8);
 115static void get_hpc_access (void);
 116static void free_hpc_access (void);
 117static void poll_hpc (void);
 118static int process_changeinstatus (struct slot *, struct slot *);
 119static int process_changeinlatch (u8, u8, struct controller *);
 120static int hpc_poll_thread (void *);
 121static int hpc_wait_ctlr_notworking (int, struct controller *, void __iomem *, u8 *);
 122//----------------------------------------------------------------------------
 123
 124
 125/*----------------------------------------------------------------------
 126* Name:    ibmphp_hpc_initvars
 127*
 128* Action:  initialize semaphores and variables
 129*---------------------------------------------------------------------*/
 130void __init ibmphp_hpc_initvars (void)
 131{
 132        debug ("%s - Entry\n", __FUNCTION__);
 133
 134        init_MUTEX (&sem_hpcaccess);
 135        init_MUTEX (&semOperations);
 136        init_MUTEX_LOCKED (&sem_exit);
 137        to_debug = FALSE;
 138        ibmphp_shutdown = FALSE;
 139        tid_poll = 0;
 140
 141        debug ("%s - Exit\n", __FUNCTION__);
 142}
 143
 144/*----------------------------------------------------------------------
 145* Name:    i2c_ctrl_read
 146*
 147* Action:  read from HPC over I2C
 148*
 149*---------------------------------------------------------------------*/
 150static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
 151{
 152        u8 status;
 153        int i;
 154        void __iomem *wpg_addr; // base addr + offset
 155        unsigned long wpg_data; // data to/from WPG LOHI format
 156        unsigned long ultemp;
 157        unsigned long data;     // actual data HILO format
 158
 159        debug_polling ("%s - Entry WPGBbar[%p] index[%x] \n", __FUNCTION__, WPGBbar, index);
 160
 161        //--------------------------------------------------------------------
 162        // READ - step 1
 163        // read at address, byte length, I2C address (shifted), index
 164        // or read direct, byte length, index
 165        if (ctlr_ptr->ctlr_type == 0x02) {
 166                data = WPG_READATADDR_MASK;
 167                // fill in I2C address
 168                ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
 169                ultemp = ultemp >> 1;
 170                data |= (ultemp << 8);
 171
 172                // fill in index
 173                data |= (unsigned long)index;
 174        } else if (ctlr_ptr->ctlr_type == 0x04) {
 175                data = WPG_READDIRECT_MASK;
 176
 177                // fill in index
 178                ultemp = (unsigned long)index;
 179                ultemp = ultemp << 8;
 180                data |= ultemp;
 181        } else {
 182                err ("this controller type is not supported \n");
 183                return HPC_ERROR;
 184        }
 185
 186        wpg_data = swab32 (data);       // swap data before writing
 187        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
 188        writel (wpg_data, wpg_addr);
 189
 190        //--------------------------------------------------------------------
 191        // READ - step 2 : clear the message buffer
 192        data = 0x00000000;
 193        wpg_data = swab32 (data);
 194        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 195        writel (wpg_data, wpg_addr);
 196
 197        //--------------------------------------------------------------------
 198        // READ - step 3 : issue start operation, I2C master control bit 30:ON
 199        //                 2020 : [20] OR operation at [20] offset 0x20
 200        data = WPG_I2CMCNTL_STARTOP_MASK;
 201        wpg_data = swab32 (data);
 202        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
 203        writel (wpg_data, wpg_addr);
 204
 205        //--------------------------------------------------------------------
 206        // READ - step 4 : wait until start operation bit clears
 207        i = CMD_COMPLETE_TOUT_SEC;
 208        while (i) {
 209                msleep(10);
 210                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
 211                wpg_data = readl (wpg_addr);
 212                data = swab32 (wpg_data);
 213                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
 214                        break;
 215                i--;
 216        }
 217        if (i == 0) {
 218                debug ("%s - Error : WPG timeout\n", __FUNCTION__);
 219                return HPC_ERROR;
 220        }
 221        //--------------------------------------------------------------------
 222        // READ - step 5 : read I2C status register
 223        i = CMD_COMPLETE_TOUT_SEC;
 224        while (i) {
 225                msleep(10);
 226                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
 227                wpg_data = readl (wpg_addr);
 228                data = swab32 (wpg_data);
 229                if (HPC_I2CSTATUS_CHECK (data))
 230                        break;
 231                i--;
 232        }
 233        if (i == 0) {
 234                debug ("ctrl_read - Exit Error:I2C timeout\n");
 235                return HPC_ERROR;
 236        }
 237
 238        //--------------------------------------------------------------------
 239        // READ - step 6 : get DATA
 240        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 241        wpg_data = readl (wpg_addr);
 242        data = swab32 (wpg_data);
 243
 244        status = (u8) data;
 245
 246        debug_polling ("%s - Exit index[%x] status[%x]\n", __FUNCTION__, index, status);
 247
 248        return (status);
 249}
 250
 251/*----------------------------------------------------------------------
 252* Name:    i2c_ctrl_write
 253*
 254* Action:  write to HPC over I2C
 255*
 256* Return   0 or error codes
 257*---------------------------------------------------------------------*/
 258static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
 259{
 260        u8 rc;
 261        void __iomem *wpg_addr; // base addr + offset
 262        unsigned long wpg_data; // data to/from WPG LOHI format 
 263        unsigned long ultemp;
 264        unsigned long data;     // actual data HILO format
 265        int i;
 266
 267        debug_polling ("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __FUNCTION__, WPGBbar, index, cmd);
 268
 269        rc = 0;
 270        //--------------------------------------------------------------------
 271        // WRITE - step 1
 272        // write at address, byte length, I2C address (shifted), index
 273        // or write direct, byte length, index
 274        data = 0x00000000;
 275
 276        if (ctlr_ptr->ctlr_type == 0x02) {
 277                data = WPG_WRITEATADDR_MASK;
 278                // fill in I2C address
 279                ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
 280                ultemp = ultemp >> 1;
 281                data |= (ultemp << 8);
 282
 283                // fill in index
 284                data |= (unsigned long)index;
 285        } else if (ctlr_ptr->ctlr_type == 0x04) {
 286                data = WPG_WRITEDIRECT_MASK;
 287
 288                // fill in index
 289                ultemp = (unsigned long)index;
 290                ultemp = ultemp << 8;
 291                data |= ultemp;
 292        } else {
 293                err ("this controller type is not supported \n");
 294                return HPC_ERROR;
 295        }
 296
 297        wpg_data = swab32 (data);       // swap data before writing
 298        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
 299        writel (wpg_data, wpg_addr);
 300
 301        //--------------------------------------------------------------------
 302        // WRITE - step 2 : clear the message buffer
 303        data = 0x00000000 | (unsigned long)cmd;
 304        wpg_data = swab32 (data);
 305        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 306        writel (wpg_data, wpg_addr);
 307
 308        //--------------------------------------------------------------------
 309        // WRITE - step 3 : issue start operation,I2C master control bit 30:ON
 310        //                 2020 : [20] OR operation at [20] offset 0x20
 311        data = WPG_I2CMCNTL_STARTOP_MASK;
 312        wpg_data = swab32 (data);
 313        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
 314        writel (wpg_data, wpg_addr);
 315
 316        //--------------------------------------------------------------------
 317        // WRITE - step 4 : wait until start operation bit clears
 318        i = CMD_COMPLETE_TOUT_SEC;
 319        while (i) {
 320                msleep(10);
 321                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
 322                wpg_data = readl (wpg_addr);
 323                data = swab32 (wpg_data);
 324                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
 325                        break;
 326                i--;
 327        }
 328        if (i == 0) {
 329                debug ("%s - Exit Error:WPG timeout\n", __FUNCTION__);
 330                rc = HPC_ERROR;
 331        }
 332
 333        //--------------------------------------------------------------------
 334        // WRITE - step 5 : read I2C status register
 335        i = CMD_COMPLETE_TOUT_SEC;
 336        while (i) {
 337                msleep(10);
 338                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
 339                wpg_data = readl (wpg_addr);
 340                data = swab32 (wpg_data);
 341                if (HPC_I2CSTATUS_CHECK (data))
 342                        break;
 343                i--;
 344        }
 345        if (i == 0) {
 346                debug ("ctrl_read - Error : I2C timeout\n");
 347                rc = HPC_ERROR;
 348        }
 349
 350        debug_polling ("%s Exit rc[%x]\n", __FUNCTION__, rc);
 351        return (rc);
 352}
 353
 354//------------------------------------------------------------
 355//  Read from ISA type HPC 
 356//------------------------------------------------------------
 357static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
 358{
 359        u16 start_address;
 360        u16 end_address;
 361        u8 data;
 362
 363        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 364        end_address = ctlr_ptr->u.isa_ctlr.io_end;
 365        data = inb (start_address + offset);
 366        return data;
 367}
 368
 369//--------------------------------------------------------------
 370// Write to ISA type HPC
 371//--------------------------------------------------------------
 372static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
 373{
 374        u16 start_address;
 375        u16 port_address;
 376        
 377        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 378        port_address = start_address + (u16) offset;
 379        outb (data, port_address);
 380}
 381
 382static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
 383{
 384        u8 data = 0x00;
 385        debug ("inside pci_ctrl_read\n");
 386        if (ctrl->ctrl_dev)
 387                pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
 388        return data;
 389}
 390
 391static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
 392{
 393        u8 rc = -ENODEV;
 394        debug ("inside pci_ctrl_write\n");
 395        if (ctrl->ctrl_dev) {
 396                pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
 397                rc = 0;
 398        }
 399        return rc;
 400}
 401
 402static u8 ctrl_read (struct controller *ctlr, void __iomem *base, u8 offset)
 403{
 404        u8 rc;
 405        switch (ctlr->ctlr_type) {
 406        case 0:
 407                rc = isa_ctrl_read (ctlr, offset);
 408                break;
 409        case 1:
 410                rc = pci_ctrl_read (ctlr, offset);
 411                break;
 412        case 2:
 413        case 4:
 414                rc = i2c_ctrl_read (ctlr, base, offset);
 415                break;
 416        default:
 417                return -ENODEV;
 418        }
 419        return rc;
 420}
 421
 422static u8 ctrl_write (struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 423{
 424        u8 rc = 0;
 425        switch (ctlr->ctlr_type) {
 426        case 0:
 427                isa_ctrl_write(ctlr, offset, data);
 428                break;
 429        case 1:
 430                rc = pci_ctrl_write (ctlr, offset, data);
 431                break;
 432        case 2:
 433        case 4:
 434                rc = i2c_ctrl_write(ctlr, base, offset, data);
 435                break;
 436        default:
 437                return -ENODEV;
 438        }
 439        return rc;
 440}
 441/*----------------------------------------------------------------------
 442* Name:    hpc_writecmdtoindex()
 443*
 444* Action:  convert a write command to proper index within a controller
 445*
 446* Return   index, HPC_ERROR
 447*---------------------------------------------------------------------*/
 448static u8 hpc_writecmdtoindex (u8 cmd, u8 index)
 449{
 450        u8 rc;
 451
 452        switch (cmd) {
 453        case HPC_CTLR_ENABLEIRQ:        // 0x00.N.15
 454        case HPC_CTLR_CLEARIRQ: // 0x06.N.15
 455        case HPC_CTLR_RESET:    // 0x07.N.15
 456        case HPC_CTLR_IRQSTEER: // 0x08.N.15
 457        case HPC_CTLR_DISABLEIRQ:       // 0x01.N.15
 458        case HPC_ALLSLOT_ON:    // 0x11.N.15
 459        case HPC_ALLSLOT_OFF:   // 0x12.N.15
 460                rc = 0x0F;
 461                break;
 462
 463        case HPC_SLOT_OFF:      // 0x02.Y.0-14
 464        case HPC_SLOT_ON:       // 0x03.Y.0-14
 465        case HPC_SLOT_ATTNOFF:  // 0x04.N.0-14
 466        case HPC_SLOT_ATTNON:   // 0x05.N.0-14
 467        case HPC_SLOT_BLINKLED: // 0x13.N.0-14
 468                rc = index;
 469                break;
 470
 471        case HPC_BUS_33CONVMODE:
 472        case HPC_BUS_66CONVMODE:
 473        case HPC_BUS_66PCIXMODE:
 474        case HPC_BUS_100PCIXMODE:
 475        case HPC_BUS_133PCIXMODE:
 476                rc = index + WPG_1ST_BUS_INDEX - 1;
 477                break;
 478
 479        default:
 480                err ("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
 481                rc = HPC_ERROR;
 482        }
 483
 484        return rc;
 485}
 486
 487/*----------------------------------------------------------------------
 488* Name:    hpc_readcmdtoindex()
 489*
 490* Action:  convert a read command to proper index within a controller
 491*
 492* Return   index, HPC_ERROR
 493*---------------------------------------------------------------------*/
 494static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
 495{
 496        u8 rc;
 497
 498        switch (cmd) {
 499        case READ_CTLRSTATUS:
 500                rc = 0x0F;
 501                break;
 502        case READ_SLOTSTATUS:
 503        case READ_ALLSTAT:
 504                rc = index;
 505                break;
 506        case READ_EXTSLOTSTATUS:
 507                rc = index + WPG_1ST_EXTSLOT_INDEX;
 508                break;
 509        case READ_BUSSTATUS:
 510                rc = index + WPG_1ST_BUS_INDEX - 1;
 511                break;
 512        case READ_SLOTLATCHLOWREG:
 513                rc = 0x28;
 514                break;
 515        case READ_REVLEVEL:
 516                rc = 0x25;
 517                break;
 518        case READ_HPCOPTIONS:
 519                rc = 0x27;
 520                break;
 521        default:
 522                rc = HPC_ERROR;
 523        }
 524        return rc;
 525}
 526
 527/*----------------------------------------------------------------------
 528* Name:    HPCreadslot()
 529*
 530* Action:  issue a READ command to HPC
 531*
 532* Input:   pslot   - can not be NULL for READ_ALLSTAT
 533*          pstatus - can be NULL for READ_ALLSTAT
 534*
 535* Return   0 or error codes
 536*---------------------------------------------------------------------*/
 537int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
 538{
 539        void __iomem *wpg_bbar = NULL;
 540        struct controller *ctlr_ptr;
 541        struct list_head *pslotlist;
 542        u8 index, status;
 543        int rc = 0;
 544        int busindex;
 545
 546        debug_polling ("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __FUNCTION__, pslot, cmd, pstatus);
 547
 548        if ((pslot == NULL)
 549            || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
 550                rc = -EINVAL;
 551                err ("%s - Error invalid pointer, rc[%d]\n", __FUNCTION__, rc);
 552                return rc;
 553        }
 554
 555        if (cmd == READ_BUSSTATUS) {
 556                busindex = ibmphp_get_bus_index (pslot->bus);
 557                if (busindex < 0) {
 558                        rc = -EINVAL;
 559                        err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
 560                        return rc;
 561                } else
 562                        index = (u8) busindex;
 563        } else
 564                index = pslot->ctlr_index;
 565
 566        index = hpc_readcmdtoindex (cmd, index);
 567
 568        if (index == HPC_ERROR) {
 569                rc = -EINVAL;
 570                err ("%s - Exit Error:invalid index, rc[%d]\n", __FUNCTION__, rc);
 571                return rc;
 572        }
 573
 574        ctlr_ptr = pslot->ctrl;
 575
 576        get_hpc_access ();
 577
 578        //--------------------------------------------------------------------
 579        // map physical address to logical address
 580        //--------------------------------------------------------------------
 581        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 582                wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 583
 584        //--------------------------------------------------------------------
 585        // check controller status before reading
 586        //--------------------------------------------------------------------
 587        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 588        if (!rc) {
 589                switch (cmd) {
 590                case READ_ALLSTAT:
 591                        // update the slot structure
 592                        pslot->ctrl->status = status;
 593                        pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
 594                        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 595                                                       &status);
 596                        if (!rc)
 597                                pslot->ext_status = ctrl_read (ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
 598
 599                        break;
 600
 601                case READ_SLOTSTATUS:
 602                        // DO NOT update the slot structure
 603                        *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 604                        break;
 605
 606                case READ_EXTSLOTSTATUS:
 607                        // DO NOT update the slot structure
 608                        *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 609                        break;
 610
 611                case READ_CTLRSTATUS:
 612                        // DO NOT update the slot structure
 613                        *pstatus = status;
 614                        break;
 615
 616                case READ_BUSSTATUS:
 617                        pslot->busstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 618                        break;
 619                case READ_REVLEVEL:
 620                        *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 621                        break;
 622                case READ_HPCOPTIONS:
 623                        *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 624                        break;
 625                case READ_SLOTLATCHLOWREG:
 626                        // DO NOT update the slot structure
 627                        *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, index);
 628                        break;
 629
 630                        // Not used
 631                case READ_ALLSLOT:
 632                        list_for_each (pslotlist, &ibmphp_slot_head) {
 633                                pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
 634                                index = pslot->ctlr_index;
 635                                rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr,
 636                                                                wpg_bbar, &status);
 637                                if (!rc) {
 638                                        pslot->status = ctrl_read (ctlr_ptr, wpg_bbar, index);
 639                                        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT,
 640                                                                        ctlr_ptr, wpg_bbar, &status);
 641                                        if (!rc)
 642                                                pslot->ext_status =
 643                                                    ctrl_read (ctlr_ptr, wpg_bbar,
 644                                                                index + WPG_1ST_EXTSLOT_INDEX);
 645                                } else {
 646                                        err ("%s - Error ctrl_read failed\n", __FUNCTION__);
 647                                        rc = -EINVAL;
 648                                        break;
 649                                }
 650                        }
 651                        break;
 652                default:
 653                        rc = -EINVAL;
 654                        break;
 655                }
 656        }
 657        //--------------------------------------------------------------------
 658        // cleanup
 659        //--------------------------------------------------------------------
 660        
 661        // remove physical to logical address mapping
 662        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 663                iounmap (wpg_bbar);
 664        
 665        free_hpc_access ();
 666
 667        debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
 668        return rc;
 669}
 670
 671/*----------------------------------------------------------------------
 672* Name:    ibmphp_hpc_writeslot()
 673*
 674* Action: issue a WRITE command to HPC
 675*---------------------------------------------------------------------*/
 676int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
 677{
 678        void __iomem *wpg_bbar = NULL;
 679        struct controller *ctlr_ptr;
 680        u8 index, status;
 681        int busindex;
 682        u8 done;
 683        int rc = 0;
 684        int timeout;
 685
 686        debug_polling ("%s - Entry pslot[%p] cmd[%x]\n", __FUNCTION__, pslot, cmd);
 687        if (pslot == NULL) {
 688                rc = -EINVAL;
 689                err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
 690                return rc;
 691        }
 692
 693        if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
 694                (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
 695                (cmd == HPC_BUS_133PCIXMODE)) {
 696                busindex = ibmphp_get_bus_index (pslot->bus);
 697                if (busindex < 0) {
 698                        rc = -EINVAL;
 699                        err ("%s - Exit Error:invalid bus, rc[%d]\n", __FUNCTION__, rc);
 700                        return rc;
 701                } else
 702                        index = (u8) busindex;
 703        } else
 704                index = pslot->ctlr_index;
 705
 706        index = hpc_writecmdtoindex (cmd, index);
 707
 708        if (index == HPC_ERROR) {
 709                rc = -EINVAL;
 710                err ("%s - Error Exit rc[%d]\n", __FUNCTION__, rc);
 711                return rc;
 712        }
 713
 714        ctlr_ptr = pslot->ctrl;
 715
 716        get_hpc_access ();
 717
 718        //--------------------------------------------------------------------
 719        // map physical address to logical address
 720        //--------------------------------------------------------------------
 721        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
 722                wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 723
 724                debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
 725                ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
 726                ctlr_ptr->u.wpeg_ctlr.i2c_addr);
 727        }
 728        //--------------------------------------------------------------------
 729        // check controller status before writing
 730        //--------------------------------------------------------------------
 731        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 732        if (!rc) {
 733
 734                ctrl_write (ctlr_ptr, wpg_bbar, index, cmd);
 735
 736                //--------------------------------------------------------------------
 737                // check controller is still not working on the command
 738                //--------------------------------------------------------------------
 739                timeout = CMD_COMPLETE_TOUT_SEC;
 740                done = FALSE;
 741                while (!done) {
 742                        rc = hpc_wait_ctlr_notworking (HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 743                                                        &status);
 744                        if (!rc) {
 745                                if (NEEDTOCHECK_CMDSTATUS (cmd)) {
 746                                        if (CTLR_FINISHED (status) == HPC_CTLR_FINISHED_YES)
 747                                                done = TRUE;
 748                                } else
 749                                        done = TRUE;
 750                        }
 751                        if (!done) {
 752                                msleep(1000);
 753                                if (timeout < 1) {
 754                                        done = TRUE;
 755                                        err ("%s - Error command complete timeout\n", __FUNCTION__);
 756                                        rc = -EFAULT;
 757                                } else
 758                                        timeout--;
 759                        }
 760                }
 761                ctlr_ptr->status = status;
 762        }
 763        // cleanup
 764
 765        // remove physical to logical address mapping
 766        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 767                iounmap (wpg_bbar);
 768        free_hpc_access ();
 769
 770        debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
 771        return rc;
 772}
 773
 774/*----------------------------------------------------------------------
 775* Name:    get_hpc_access()
 776*
 777* Action: make sure only one process can access HPC at one time
 778*---------------------------------------------------------------------*/
 779static void get_hpc_access (void)
 780{
 781        down (&sem_hpcaccess);
 782}
 783
 784/*----------------------------------------------------------------------
 785* Name:    free_hpc_access()
 786*---------------------------------------------------------------------*/
 787void free_hpc_access (void)
 788{
 789        up (&sem_hpcaccess);
 790}
 791
 792/*----------------------------------------------------------------------
 793* Name:    ibmphp_lock_operations()
 794*
 795* Action: make sure only one process can change the data structure
 796*---------------------------------------------------------------------*/
 797void ibmphp_lock_operations (void)
 798{
 799        down (&semOperations);
 800        to_debug = TRUE;
 801}
 802
 803/*----------------------------------------------------------------------
 804* Name:    ibmphp_unlock_operations()
 805*---------------------------------------------------------------------*/
 806void ibmphp_unlock_operations (void)
 807{
 808        debug ("%s - Entry\n", __FUNCTION__);
 809        up (&semOperations);
 810        to_debug = FALSE;
 811        debug ("%s - Exit\n", __FUNCTION__);
 812}
 813
 814/*----------------------------------------------------------------------
 815* Name:    poll_hpc()
 816*---------------------------------------------------------------------*/
 817#define POLL_LATCH_REGISTER     0
 818#define POLL_SLOTS              1
 819#define POLL_SLEEP              2
 820static void poll_hpc (void)
 821{
 822        struct slot myslot;
 823        struct slot *pslot = NULL;
 824        struct list_head *pslotlist;
 825        int rc;
 826        int poll_state = POLL_LATCH_REGISTER;
 827        u8 oldlatchlow = 0x00;
 828        u8 curlatchlow = 0x00;
 829        int poll_count = 0;
 830        u8 ctrl_count = 0x00;
 831
 832        debug ("%s - Entry\n", __FUNCTION__);
 833
 834        while (!ibmphp_shutdown) {
 835                if (ibmphp_shutdown) 
 836                        break;
 837                
 838                /* try to get the lock to do some kind of harware access */
 839                down (&semOperations);
 840
 841                switch (poll_state) {
 842                case POLL_LATCH_REGISTER: 
 843                        oldlatchlow = curlatchlow;
 844                        ctrl_count = 0x00;
 845                        list_for_each (pslotlist, &ibmphp_slot_head) {
 846                                if (ctrl_count >= ibmphp_get_total_controllers())
 847                                        break;
 848                                pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
 849                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 850                                        ctrl_count++;
 851                                        if (READ_SLOT_LATCH (pslot->ctrl)) {
 852                                                rc = ibmphp_hpc_readslot (pslot,
 853                                                                          READ_SLOTLATCHLOWREG,
 854                                                                          &curlatchlow);
 855                                                if (oldlatchlow != curlatchlow)
 856                                                        process_changeinlatch (oldlatchlow,
 857                                                                               curlatchlow,
 858                                                                               pslot->ctrl);
 859                                        }
 860                                }
 861                        }
 862                        ++poll_count;
 863                        poll_state = POLL_SLEEP;
 864                        break;
 865                case POLL_SLOTS:
 866                        list_for_each (pslotlist, &ibmphp_slot_head) {
 867                                pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
 868                                // make a copy of the old status
 869                                memcpy ((void *) &myslot, (void *) pslot,
 870                                        sizeof (struct slot));
 871                                rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
 872                                if ((myslot.status != pslot->status)
 873                                    || (myslot.ext_status != pslot->ext_status))
 874                                        process_changeinstatus (pslot, &myslot);
 875                        }
 876                        ctrl_count = 0x00;
 877                        list_for_each (pslotlist, &ibmphp_slot_head) {
 878                                if (ctrl_count >= ibmphp_get_total_controllers())
 879                                        break;
 880                                pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
 881                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 882                                        ctrl_count++;
 883                                        if (READ_SLOT_LATCH (pslot->ctrl))
 884                                                rc = ibmphp_hpc_readslot (pslot,
 885                                                                          READ_SLOTLATCHLOWREG,
 886                                                                          &curlatchlow);
 887                                }
 888                        }
 889                        ++poll_count;
 890                        poll_state = POLL_SLEEP;
 891                        break;
 892                case POLL_SLEEP:
 893                        /* don't sleep with a lock on the hardware */
 894                        up (&semOperations);
 895                        msleep(POLL_INTERVAL_SEC * 1000);
 896
 897                        if (ibmphp_shutdown) 
 898                                break;
 899                        
 900                        down (&semOperations);
 901                        
 902                        if (poll_count >= POLL_LATCH_CNT) {
 903                                poll_count = 0;
 904                                poll_state = POLL_SLOTS;
 905                        } else
 906                                poll_state = POLL_LATCH_REGISTER;
 907                        break;
 908                }       
 909                /* give up the harware semaphore */
 910                up (&semOperations);
 911                /* sleep for a short time just for good measure */
 912                msleep(100);
 913        }
 914        up (&sem_exit);
 915        debug ("%s - Exit\n", __FUNCTION__);
 916}
 917
 918
 919/*----------------------------------------------------------------------
 920* Name:    process_changeinstatus
 921*
 922* Action:  compare old and new slot status, process the change in status
 923*
 924* Input:   pointer to slot struct, old slot struct
 925*
 926* Return   0 or error codes
 927* Value:
 928*
 929* Side
 930* Effects: None.
 931*
 932* Notes:
 933*---------------------------------------------------------------------*/
 934static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
 935{
 936        u8 status;
 937        int rc = 0;
 938        u8 disable = FALSE;
 939        u8 update = FALSE;
 940
 941        debug ("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
 942
 943        // bit 0 - HPC_SLOT_POWER
 944        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
 945                update = TRUE;
 946
 947        // bit 1 - HPC_SLOT_CONNECT
 948        // ignore
 949
 950        // bit 2 - HPC_SLOT_ATTN
 951        if ((pslot->status & 0x04) != (poldslot->status & 0x04))
 952                update = TRUE;
 953
 954        // bit 3 - HPC_SLOT_PRSNT2
 955        // bit 4 - HPC_SLOT_PRSNT1
 956        if (((pslot->status & 0x08) != (poldslot->status & 0x08))
 957                || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
 958                update = TRUE;
 959
 960        // bit 5 - HPC_SLOT_PWRGD
 961        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
 962                // OFF -> ON: ignore, ON -> OFF: disable slot
 963                if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) 
 964                        disable = TRUE;
 965
 966        // bit 6 - HPC_SLOT_BUS_SPEED
 967        // ignore
 968
 969        // bit 7 - HPC_SLOT_LATCH
 970        if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
 971                update = TRUE;
 972                // OPEN -> CLOSE
 973                if (pslot->status & 0x80) {
 974                        if (SLOT_PWRGD (pslot->status)) {
 975                                // power goes on and off after closing latch
 976                                // check again to make sure power is still ON
 977                                msleep(1000);
 978                                rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
 979                                if (SLOT_PWRGD (status))
 980                                        update = TRUE;
 981                                else    // overwrite power in pslot to OFF
 982                                        pslot->status &= ~HPC_SLOT_POWER;
 983                        }
 984                }
 985                // CLOSE -> OPEN 
 986                else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
 987                        && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
 988                        disable = TRUE;
 989                }
 990                // else - ignore
 991        }
 992        // bit 4 - HPC_SLOT_BLINK_ATTN
 993        if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
 994                update = TRUE;
 995
 996        if (disable) {
 997                debug ("process_changeinstatus - disable slot\n");
 998                pslot->flag = FALSE;
 999                rc = ibmphp_do_disable_slot (pslot);
1000        }
1001
1002        if (update || disable) {
1003                ibmphp_update_slot_info (pslot);
1004        }
1005
1006        debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
1007
1008        return rc;
1009}
1010
1011/*----------------------------------------------------------------------
1012* Name:    process_changeinlatch
1013*
1014* Action:  compare old and new latch reg status, process the change
1015*
1016* Input:   old and current latch register status
1017*
1018* Return   0 or error codes
1019* Value:
1020*---------------------------------------------------------------------*/
1021static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
1022{
1023        struct slot myslot, *pslot;
1024        u8 i;
1025        u8 mask;
1026        int rc = 0;
1027
1028        debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
1029        // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1030
1031        for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1032                mask = 0x01 << i;
1033                if ((mask & old) != (mask & new)) {
1034                        pslot = ibmphp_get_slot_from_physical_num (i);
1035                        if (pslot) {
1036                                memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
1037                                rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
1038                                debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
1039                                process_changeinstatus (pslot, &myslot);
1040                        } else {
1041                                rc = -EINVAL;
1042                                err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
1043                        }
1044                }
1045        }
1046        debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
1047        return rc;
1048}
1049
1050/*----------------------------------------------------------------------
1051* Name:    hpc_poll_thread
1052*
1053* Action:  polling
1054*
1055* Return   0
1056* Value:
1057*---------------------------------------------------------------------*/
1058static int hpc_poll_thread (void *data)
1059{
1060        debug ("%s - Entry\n", __FUNCTION__);
1061
1062        daemonize("hpc_poll");
1063        allow_signal(SIGKILL);
1064
1065        poll_hpc ();
1066
1067        tid_poll = 0;
1068        debug ("%s - Exit\n", __FUNCTION__);
1069        return 0;
1070}
1071
1072
1073/*----------------------------------------------------------------------
1074* Name:    ibmphp_hpc_start_poll_thread
1075*
1076* Action:  start polling thread
1077*---------------------------------------------------------------------*/
1078int __init ibmphp_hpc_start_poll_thread (void)
1079{
1080        int rc = 0;
1081
1082        debug ("%s - Entry\n", __FUNCTION__);
1083
1084        tid_poll = kernel_thread (hpc_poll_thread, NULL, 0);
1085        if (tid_poll < 0) {
1086                err ("%s - Error, thread not started\n", __FUNCTION__);
1087                rc = -1;
1088        }
1089
1090        debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
1091        return rc;
1092}
1093
1094/*----------------------------------------------------------------------
1095* Name:    ibmphp_hpc_stop_poll_thread
1096*
1097* Action:  stop polling thread and cleanup
1098*---------------------------------------------------------------------*/
1099void __exit ibmphp_hpc_stop_poll_thread (void)
1100{
1101        debug ("%s - Entry\n", __FUNCTION__);
1102
1103        ibmphp_shutdown = TRUE;
1104        debug ("before locking operations \n");
1105        ibmphp_lock_operations ();
1106        debug ("after locking operations \n");
1107        
1108        // wait for poll thread to exit
1109        debug ("before sem_exit down \n");
1110        down (&sem_exit);
1111        debug ("after sem_exit down \n");
1112
1113        // cleanup
1114        debug ("before free_hpc_access \n");
1115        free_hpc_access ();
1116        debug ("after free_hpc_access \n");
1117        ibmphp_unlock_operations ();
1118        debug ("after unlock operations \n");
1119        up (&sem_exit);
1120        debug ("after sem exit up\n");
1121
1122        debug ("%s - Exit\n", __FUNCTION__);
1123}
1124
1125/*----------------------------------------------------------------------
1126* Name:    hpc_wait_ctlr_notworking
1127*
1128* Action:  wait until the controller is in a not working state
1129*
1130* Return   0, HPC_ERROR
1131* Value:
1132*---------------------------------------------------------------------*/
1133static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1134                                    u8 * pstatus)
1135{
1136        int rc = 0;
1137        u8 done = FALSE;
1138
1139        debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1140
1141        while (!done) {
1142                *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1143                if (*pstatus == HPC_ERROR) {
1144                        rc = HPC_ERROR;
1145                        done = TRUE;
1146                }
1147                if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
1148                        done = TRUE;
1149                if (!done) {
1150                        msleep(1000);
1151                        if (timeout < 1) {
1152                                done = TRUE;
1153                                err ("HPCreadslot - Error ctlr timeout\n");
1154                                rc = HPC_ERROR;
1155                        } else
1156                                timeout--;
1157                }
1158        }
1159        debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1160        return rc;
1161}
1162
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.