OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [hotplug/] [ibmphp_hpc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * IBM Hot Plug Controller Driver
3
 *
4
 * Written By: Jyoti Shah, IBM Corporation
5
 *
6
 * Copyright (C) 2001-2002 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/module.h>
33
#include <linux/pci.h>
34
#include <linux/smp_lock.h>
35
#include <linux/init.h>
36
#include "ibmphp.h"
37
 
38
static int to_debug = FALSE;
39
#define debug_polling(fmt, arg...)      do { if (to_debug) debug (fmt, arg); } while (0)
40
 
41
//----------------------------------------------------------------------------
42
// timeout values
43
//----------------------------------------------------------------------------
44
#define CMD_COMPLETE_TOUT_SEC   60      // give HPC 60 sec to finish cmd
45
#define HPC_CTLR_WORKING_TOUT   60      // give HPC 60 sec to finish cmd
46
#define HPC_GETACCESS_TIMEOUT   60      // seconds
47
#define POLL_INTERVAL_SEC       2       // poll HPC every 2 seconds
48
#define POLL_LATCH_CNT          5       // poll latch 5 times, then poll slots
49
 
50
//----------------------------------------------------------------------------
51
// Winnipeg Architected Register Offsets
52
//----------------------------------------------------------------------------
53
#define WPG_I2CMBUFL_OFFSET     0x08    // I2C Message Buffer Low
54
#define WPG_I2CMOSUP_OFFSET     0x10    // I2C Master Operation Setup Reg
55
#define WPG_I2CMCNTL_OFFSET     0x20    // I2C Master Control Register
56
#define WPG_I2CPARM_OFFSET      0x40    // I2C Parameter Register
57
#define WPG_I2CSTAT_OFFSET      0x70    // I2C Status Register
58
 
59
//----------------------------------------------------------------------------
60
// Winnipeg Store Type commands (Add this commands to the register offset)
61
//----------------------------------------------------------------------------
62
#define WPG_I2C_AND             0x1000  // I2C AND operation
63
#define WPG_I2C_OR              0x2000  // I2C OR operation
64
 
65
//----------------------------------------------------------------------------
66
// Command set for I2C Master Operation Setup Regisetr
67
//----------------------------------------------------------------------------
68
#define WPG_READATADDR_MASK     0x00010000      // read,bytes,I2C shifted,index
69
#define WPG_WRITEATADDR_MASK    0x40010000      // write,bytes,I2C shifted,index
70
#define WPG_READDIRECT_MASK     0x10010000
71
#define WPG_WRITEDIRECT_MASK    0x60010000
72
 
73
 
74
//----------------------------------------------------------------------------
75
// bit masks for I2C Master Control Register
76
//----------------------------------------------------------------------------
77
#define WPG_I2CMCNTL_STARTOP_MASK       0x00000002      // Start the Operation
78
 
79
//----------------------------------------------------------------------------
80
//
81
//----------------------------------------------------------------------------
82
#define WPG_I2C_IOREMAP_SIZE    0x2044  // size of linear address interval
83
 
84
//----------------------------------------------------------------------------
85
// command index
86
//----------------------------------------------------------------------------
87
#define WPG_1ST_SLOT_INDEX      0x01    // index - 1st slot for ctlr
88
#define WPG_CTLR_INDEX          0x0F    // index - ctlr
89
#define WPG_1ST_EXTSLOT_INDEX   0x10    // index - 1st ext slot for ctlr
90
#define WPG_1ST_BUS_INDEX       0x1F    // index - 1st bus for ctlr
91
 
92
//----------------------------------------------------------------------------
93
// macro utilities
94
//----------------------------------------------------------------------------
95
// if bits 20,22,25,26,27,29,30 are OFF return TRUE
96
#define HPC_I2CSTATUS_CHECK(s)  ((u8)((s & 0x00000A76) ? FALSE : TRUE))
97
 
98
//----------------------------------------------------------------------------
99
// global variables
100
//----------------------------------------------------------------------------
101
static int ibmphp_shutdown;
102
static int tid_poll;
103
static struct semaphore sem_hpcaccess;  // lock access to HPC
104
static struct semaphore semOperations;  // lock all operations and
105
                                        // access to data structures
106
static struct semaphore sem_exit;       // make sure polling thread goes away
107
//----------------------------------------------------------------------------
108
// local function prototypes
109
//----------------------------------------------------------------------------
110
static u8 i2c_ctrl_read (struct controller *, void *, u8);
111
static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
112
static u8 hpc_writecmdtoindex (u8, u8);
113
static u8 hpc_readcmdtoindex (u8, u8);
114
static void get_hpc_access (void);
115
static void free_hpc_access (void);
116
static void poll_hpc (void);
117
static int update_slot (struct slot *, u8);
118
static int process_changeinstatus (struct slot *, struct slot *);
119
static int process_changeinlatch (u8, u8, struct controller *);
120
static int hpc_poll_thread (void *);
121
static int hpc_wait_ctlr_notworking (int, struct controller *, void *, u8 *);
122
//----------------------------------------------------------------------------
123
 
124
 
125
/*----------------------------------------------------------------------
126
* Name:    ibmphp_hpc_initvars
127
*
128
* Action:  initialize semaphores and variables
129
*---------------------------------------------------------------------*/
130
void __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
*---------------------------------------------------------------------*/
150
static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
151
{
152
        u8 status;
153
        int i;
154
        void *wpg_addr;         // base addr + offset
155
        ulong wpg_data,         // data to/from WPG LOHI format
156
        ultemp, data;           // actual data HILO format
157
 
158
 
159
        debug_polling ("%s - Entry WPGBbar[%lx] index[%x] \n", __FUNCTION__, (ulong) 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 = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
169
                ultemp = ultemp >> 1;
170
                data |= (ultemp << 8);
171
 
172
                // fill in index
173
                data |= (ulong) index;
174
        } else if (ctlr_ptr->ctlr_type == 0x04) {
175
                data = WPG_READDIRECT_MASK;
176
 
177
                // fill in index
178
                ultemp = (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) 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
                long_delay (1 * HZ / 100);
210
                (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
                long_delay (1 * HZ / 100);
226
                (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
*---------------------------------------------------------------------*/
258
static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
259
{
260
        u8 rc;
261
        void *wpg_addr;         // base addr + offset
262
        ulong wpg_data,         // data to/from WPG LOHI format 
263
        ultemp, data;           // actual data HILO format
264
        int i;
265
 
266
 
267
        debug_polling ("%s - Entry WPGBbar[%lx] index[%x] cmd[%x]\n", __FUNCTION__, (ulong) 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 = (ulong) ctlr_ptr->u.wpeg_ctlr.i2c_addr;
280
                ultemp = ultemp >> 1;
281
                data |= (ultemp << 8);
282
 
283
                // fill in index
284
                data |= (ulong) index;
285
        } else if (ctlr_ptr->ctlr_type == 0x04) {
286
                data = WPG_WRITEDIRECT_MASK;
287
 
288
                // fill in index
289
                ultemp = (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMOSUP_OFFSET;
299
        writel (wpg_data, wpg_addr);
300
 
301
        //--------------------------------------------------------------------
302
        // WRITE - step 2 : clear the message buffer
303
        data = 0x00000000 | (ulong) cmd;
304
        wpg_data = swab32 (data);
305
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
        (ulong) wpg_addr = (ulong) WPGBbar + (ulong) WPG_I2CMCNTL_OFFSET + (ulong) 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
                long_delay (1 * HZ / 100);
321
                (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
                long_delay (1 * HZ / 100);
338
                (ulong) wpg_addr = (ulong) WPGBbar + (ulong) 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
//------------------------------------------------------------
357
static 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
//--------------------------------------------------------------
372
static 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
 
382
static 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
 
391
static 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
 
402
static u8 ctrl_read (struct controller *ctlr, void *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
 
422
static u8 ctrl_write (struct controller *ctlr, void *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
*---------------------------------------------------------------------*/
448
static 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
*---------------------------------------------------------------------*/
494
static 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
*---------------------------------------------------------------------*/
537
int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
538
{
539
        void *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[%lx] cmd[%x] pstatus[%lx]\n", __FUNCTION__, (ulong) pslot, cmd, (ulong) 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
*---------------------------------------------------------------------*/
676
int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
677
{
678
        void *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[%lx] cmd[%x]\n", __FUNCTION__, (ulong) 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
                                long_delay (1 * HZ);
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
*---------------------------------------------------------------------*/
779
static void get_hpc_access (void)
780
{
781
        down (&sem_hpcaccess);
782
}
783
 
784
/*----------------------------------------------------------------------
785
* Name:    free_hpc_access()
786
*---------------------------------------------------------------------*/
787
void 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
*---------------------------------------------------------------------*/
797
void ibmphp_lock_operations (void)
798
{
799
        down (&semOperations);
800
        to_debug = TRUE;
801
}
802
 
803
/*----------------------------------------------------------------------
804
* Name:    ibmphp_unlock_operations()
805
*---------------------------------------------------------------------*/
806
void 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
820
static 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
                        long_delay (POLL_INTERVAL_SEC * HZ);
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
                set_current_state (TASK_INTERRUPTIBLE);
913
                schedule_timeout (HZ/10);
914
        }
915
        up (&sem_exit);
916
        debug ("%s - Exit\n", __FUNCTION__);
917
}
918
 
919
 
920
/* ----------------------------------------------------------------------
921
 *  Name:    ibmphp_hpc_fillhpslotinfo(hotplug_slot * phpslot)
922
 *
923
 *  Action:  fill out the hotplug_slot info
924
 *
925
 *  Input:   pointer to hotplug_slot
926
 *
927
 *  Return
928
 *  Value:   0 or error codes
929
 *-----------------------------------------------------------------------*/
930
int ibmphp_hpc_fillhpslotinfo (struct hotplug_slot *phpslot)
931
{
932
        int rc = 0;
933
        struct slot *pslot;
934
 
935
        if (phpslot && phpslot->private) {
936
                pslot = (struct slot *) phpslot->private;
937
                rc = update_slot (pslot, (u8) TRUE);
938
                if (!rc) {
939
 
940
                        // power - enabled:1  not:0
941
                        phpslot->info->power_status = SLOT_POWER (pslot->status);
942
 
943
                        // attention - off:0, on:1, blinking:2
944
                        phpslot->info->attention_status = SLOT_ATTN (pslot->status, pslot->ext_status);
945
 
946
                        // latch - open:1 closed:0
947
                        phpslot->info->latch_status = SLOT_LATCH (pslot->status);
948
 
949
                        // pci board - present:1 not:0
950
                        if (SLOT_PRESENT (pslot->status))
951
                                phpslot->info->adapter_status = 1;
952
                        else
953
                                phpslot->info->adapter_status = 0;
954
/*
955
                        if (pslot->bus_on->supported_bus_mode
956
                                && (pslot->bus_on->supported_speed == BUS_SPEED_66))
957
                                phpslot->info->max_bus_speed_status = BUS_SPEED_66PCIX;
958
                        else
959
                                phpslot->info->max_bus_speed_status = pslot->bus_on->supported_speed;
960
*/              } else
961
                        rc = -EINVAL;
962
        } else
963
                rc = -EINVAL;
964
 
965
        return rc;
966
}
967
 
968
/*----------------------------------------------------------------------
969
* Name:    update_slot
970
*
971
* Action:  fill out slot status and extended status, controller status
972
*
973
* Input:   pointer to slot struct
974
*---------------------------------------------------------------------*/
975
static int update_slot (struct slot *pslot, u8 update)
976
{
977
        int rc = 0;
978
 
979
        debug ("%s - Entry pslot[%lx]\n", __FUNCTION__, (ulong) pslot);
980
        rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
981
        debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
982
        return rc;
983
}
984
 
985
/*----------------------------------------------------------------------
986
* Name:    process_changeinstatus
987
*
988
* Action:  compare old and new slot status, process the change in status
989
*
990
* Input:   pointer to slot struct, old slot struct
991
*
992
* Return   0 or error codes
993
* Value:
994
*
995
* Side
996
* Effects: None.
997
*
998
* Notes:
999
*---------------------------------------------------------------------*/
1000
static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
1001
{
1002
        u8 status;
1003
        int rc = 0;
1004
        u8 disable = FALSE;
1005
        u8 update = FALSE;
1006
 
1007
        debug ("process_changeinstatus - Entry pslot[%lx], poldslot[%lx]\n", (ulong) pslot,
1008
               (ulong) poldslot);
1009
 
1010
        // bit 0 - HPC_SLOT_POWER
1011
        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
1012
                update = TRUE;
1013
 
1014
        // bit 1 - HPC_SLOT_CONNECT
1015
        // ignore
1016
 
1017
        // bit 2 - HPC_SLOT_ATTN
1018
        if ((pslot->status & 0x04) != (poldslot->status & 0x04))
1019
                update = TRUE;
1020
 
1021
        // bit 3 - HPC_SLOT_PRSNT2
1022
        // bit 4 - HPC_SLOT_PRSNT1
1023
        if (((pslot->status & 0x08) != (poldslot->status & 0x08))
1024
                || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
1025
                update = TRUE;
1026
 
1027
        // bit 5 - HPC_SLOT_PWRGD
1028
        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
1029
                // OFF -> ON: ignore, ON -> OFF: disable slot
1030
                if ((poldslot->status & 0x20) && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status)))
1031
                        disable = TRUE;
1032
 
1033
        // bit 6 - HPC_SLOT_BUS_SPEED
1034
        // ignore
1035
 
1036
        // bit 7 - HPC_SLOT_LATCH
1037
        if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
1038
                update = TRUE;
1039
                // OPEN -> CLOSE
1040
                if (pslot->status & 0x80) {
1041
                        if (SLOT_PWRGD (pslot->status)) {
1042
                                // power goes on and off after closing latch
1043
                                // check again to make sure power is still ON
1044
                                long_delay (1 * HZ);
1045
                                rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
1046
                                if (SLOT_PWRGD (status))
1047
                                        update = TRUE;
1048
                                else    // overwrite power in pslot to OFF
1049
                                        pslot->status &= ~HPC_SLOT_POWER;
1050
                        }
1051
                }
1052
                // CLOSE -> OPEN 
1053
                else if ((SLOT_PWRGD (poldslot->status) == HPC_SLOT_PWRGD_GOOD)
1054
                        && (SLOT_CONNECT (poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT (poldslot->status))) {
1055
                        disable = TRUE;
1056
                }
1057
                // else - ignore
1058
        }
1059
        // bit 4 - HPC_SLOT_BLINK_ATTN
1060
        if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
1061
                update = TRUE;
1062
 
1063
        if (disable) {
1064
                debug ("process_changeinstatus - disable slot\n");
1065
                pslot->flag = FALSE;
1066
                rc = ibmphp_disable_slot (pslot->hotplug_slot);
1067
        }
1068
 
1069
        if (update || disable) {
1070
                ibmphp_update_slot_info (pslot);
1071
        }
1072
 
1073
        debug ("%s - Exit rc[%d] disable[%x] update[%x]\n", __FUNCTION__, rc, disable, update);
1074
 
1075
        return rc;
1076
}
1077
 
1078
/*----------------------------------------------------------------------
1079
* Name:    process_changeinlatch
1080
*
1081
* Action:  compare old and new latch reg status, process the change
1082
*
1083
* Input:   old and current latch register status
1084
*
1085
* Return   0 or error codes
1086
* Value:
1087
*---------------------------------------------------------------------*/
1088
static int process_changeinlatch (u8 old, u8 new, struct controller *ctrl)
1089
{
1090
        struct slot myslot, *pslot;
1091
        u8 i;
1092
        u8 mask;
1093
        int rc = 0;
1094
 
1095
        debug ("%s - Entry old[%x], new[%x]\n", __FUNCTION__, old, new);
1096
        // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1097
 
1098
        for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1099
                mask = 0x01 << i;
1100
                if ((mask & old) != (mask & new)) {
1101
                        pslot = ibmphp_get_slot_from_physical_num (i);
1102
                        if (pslot) {
1103
                                memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
1104
                                rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
1105
                                debug ("%s - call process_changeinstatus for slot[%d]\n", __FUNCTION__, i);
1106
                                process_changeinstatus (pslot, &myslot);
1107
                        } else {
1108
                                rc = -EINVAL;
1109
                                err ("%s - Error bad pointer for slot[%d]\n", __FUNCTION__, i);
1110
                        }
1111
                }
1112
        }
1113
        debug ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
1114
        return rc;
1115
}
1116
 
1117
/*----------------------------------------------------------------------
1118
* Name:    hpc_poll_thread
1119
*
1120
* Action:  polling
1121
*
1122
* Return   0
1123
* Value:
1124
*---------------------------------------------------------------------*/
1125
static int hpc_poll_thread (void *data)
1126
{
1127
        debug ("%s - Entry\n", __FUNCTION__);
1128
        lock_kernel ();
1129
        daemonize ();
1130
        reparent_to_init ();
1131
 
1132
        //  New name
1133
        strcpy (current->comm, "hpc_poll");
1134
 
1135
        unlock_kernel ();
1136
 
1137
        poll_hpc ();
1138
 
1139
        tid_poll = 0;
1140
        debug ("%s - Exit\n", __FUNCTION__);
1141
        return 0;
1142
}
1143
 
1144
 
1145
/*----------------------------------------------------------------------
1146
* Name:    ibmphp_hpc_start_poll_thread
1147
*
1148
* Action:  start polling thread
1149
*---------------------------------------------------------------------*/
1150
int __init ibmphp_hpc_start_poll_thread (void)
1151
{
1152
        int rc = 0;
1153
 
1154
        debug ("%s - Entry\n", __FUNCTION__);
1155
 
1156
        tid_poll = kernel_thread (hpc_poll_thread, 0, 0);
1157
        if (tid_poll < 0) {
1158
                err ("%s - Error, thread not started\n", __FUNCTION__);
1159
                rc = -1;
1160
        }
1161
 
1162
        debug ("%s - Exit tid_poll[%d] rc[%d]\n", __FUNCTION__, tid_poll, rc);
1163
        return rc;
1164
}
1165
 
1166
/*----------------------------------------------------------------------
1167
* Name:    ibmphp_hpc_stop_poll_thread
1168
*
1169
* Action:  stop polling thread and cleanup
1170
*---------------------------------------------------------------------*/
1171
void __exit ibmphp_hpc_stop_poll_thread (void)
1172
{
1173
        debug ("%s - Entry\n", __FUNCTION__);
1174
 
1175
        ibmphp_shutdown = TRUE;
1176
        debug ("before locking operations \n");
1177
        ibmphp_lock_operations ();
1178
        debug ("after locking operations \n");
1179
 
1180
        // wait for poll thread to exit
1181
        debug ("before sem_exit down \n");
1182
        down (&sem_exit);
1183
        debug ("after sem_exit down \n");
1184
 
1185
        // cleanup
1186
        debug ("before free_hpc_access \n");
1187
        free_hpc_access ();
1188
        debug ("after free_hpc_access \n");
1189
        ibmphp_unlock_operations ();
1190
        debug ("after unlock operations \n");
1191
        up (&sem_exit);
1192
        debug ("after sem exit up\n");
1193
 
1194
        debug ("%s - Exit\n", __FUNCTION__);
1195
}
1196
 
1197
/*----------------------------------------------------------------------
1198
* Name:    hpc_wait_ctlr_notworking
1199
*
1200
* Action:  wait until the controller is in a not working state
1201
*
1202
* Return   0, HPC_ERROR
1203
* Value:
1204
*---------------------------------------------------------------------*/
1205
static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, void *wpg_bbar,
1206
                                    u8 * pstatus)
1207
{
1208
        int rc = 0;
1209
        u8 done = FALSE;
1210
 
1211
        debug_polling ("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1212
 
1213
        while (!done) {
1214
                *pstatus = ctrl_read (ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1215
                if (*pstatus == HPC_ERROR) {
1216
                        rc = HPC_ERROR;
1217
                        done = TRUE;
1218
                }
1219
                if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
1220
                        done = TRUE;
1221
                if (!done) {
1222
                        long_delay (1 * HZ);
1223
                        if (timeout < 1) {
1224
                                done = TRUE;
1225
                                err ("HPCreadslot - Error ctlr timeout\n");
1226
                                rc = HPC_ERROR;
1227
                        } else
1228
                                timeout--;
1229
                }
1230
        }
1231
        debug_polling ("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1232
        return rc;
1233
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.