1 /* 2 * Standard PCI Hot Plug Driver 3 * 4 * Copyright (C) 1995,2001 Compaq Computer Corporation 5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 * Copyright (C) 2001 IBM Corp. 7 * Copyright (C) 2003-2004 Intel Corporation 8 * 9 * All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or (at 14 * your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 * NON INFRINGEMENT. See the GNU General Public License for more 20 * details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 26 * Send feedback to <greg@kroah.com>,<dely.l.sy@intel.com> 27 * 28 */ 29 30 #include <linux/config.h> 31 #include <linux/kernel.h> 32 #include <linux/module.h> 33 #include <linux/types.h> 34 #include <linux/slab.h> 35 #include <linux/vmalloc.h> 36 #include <linux/interrupt.h> 37 #include <linux/spinlock.h> 38 #include <linux/delay.h> 39 #include <linux/pci.h> 40 #include <asm/system.h> 41 #include "shpchp.h" 42 43 #ifdef DEBUG 44 #define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */ 45 #define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */ 46 #define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */ 47 #define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */ 48 #define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT) 49 #define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE) 50 /* Redefine this flagword to set debug level */ 51 #define DEBUG_LEVEL DBG_K_STANDARD 52 53 #define DEFINE_DBG_BUFFER char __dbg_str_buf[256]; 54 55 #define DBG_PRINT( dbg_flags, args... ) \ 56 do { \ 57 if ( DEBUG_LEVEL & ( dbg_flags ) ) \ 58 { \ 59 int len; \ 60 len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \ 61 __FILE__, __LINE__, __FUNCTION__ ); \ 62 sprintf( __dbg_str_buf + len, args ); \ 63 printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \ 64 } \ 65 } while (0) 66 67 #define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]"); 68 #define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]"); 69 #else 70 #define DEFINE_DBG_BUFFER 71 #define DBG_ENTER_ROUTINE 72 #define DBG_LEAVE_ROUTINE 73 #endif /* DEBUG */ 74 75 /* Slot Available Register I field definition */ 76 #define SLOT_33MHZ 0x0000001f 77 #define SLOT_66MHZ_PCIX 0x00001f00 78 #define SLOT_100MHZ_PCIX 0x001f0000 79 #define SLOT_133MHZ_PCIX 0x1f000000 80 81 /* Slot Available Register II field definition */ 82 #define SLOT_66MHZ 0x0000001f 83 #define SLOT_66MHZ_PCIX_266 0x00000f00 84 #define SLOT_100MHZ_PCIX_266 0x0000f000 85 #define SLOT_133MHZ_PCIX_266 0x000f0000 86 #define SLOT_66MHZ_PCIX_533 0x00f00000 87 #define SLOT_100MHZ_PCIX_533 0x0f000000 88 #define SLOT_133MHZ_PCIX_533 0xf0000000 89 90 91 /* Secondary Bus Configuration Register */ 92 /* For PI = 1, Bits 0 to 2 have been encoded as follows to show current bus speed/mode */ 93 #define PCI_33MHZ 0x0 94 #define PCI_66MHZ 0x1 95 #define PCIX_66MHZ 0x2 96 #define PCIX_100MHZ 0x3 97 #define PCIX_133MHZ 0x4 98 99 /* For PI = 2, Bits 0 to 3 have been encoded as follows to show current bus speed/mode */ 100 #define PCI_33MHZ 0x0 101 #define PCI_66MHZ 0x1 102 #define PCIX_66MHZ 0x2 103 #define PCIX_100MHZ 0x3 104 #define PCIX_133MHZ 0x4 105 #define PCIX_66MHZ_ECC 0x5 106 #define PCIX_100MHZ_ECC 0x6 107 #define PCIX_133MHZ_ECC 0x7 108 #define PCIX_66MHZ_266 0x9 109 #define PCIX_100MHZ_266 0xa 110 #define PCIX_133MHZ_266 0xb 111 #define PCIX_66MHZ_533 0x11 112 #define PCIX_100MHZ_533 0x12 113 #define PCIX_133MHZ_533 0x13 114 115 /* Slot Configuration */ 116 #define SLOT_NUM 0x0000001F 117 #define FIRST_DEV_NUM 0x00001F00 118 #define PSN 0x07FF0000 119 #define UPDOWN 0x20000000 120 #define MRLSENSOR 0x40000000 121 #define ATTN_BUTTON 0x80000000 122 123 /* Slot Status Field Definitions */ 124 /* Slot State */ 125 #define PWR_ONLY 0x0001 126 #define ENABLED 0x0002 127 #define DISABLED 0x0003 128 129 /* Power Indicator State */ 130 #define PWR_LED_ON 0x0004 131 #define PWR_LED_BLINK 0x0008 132 #define PWR_LED_OFF 0x000c 133 134 /* Attention Indicator State */ 135 #define ATTEN_LED_ON 0x0010 136 #define ATTEN_LED_BLINK 0x0020 137 #define ATTEN_LED_OFF 0x0030 138 139 /* Power Fault */ 140 #define pwr_fault 0x0040 141 142 /* Attention Button */ 143 #define ATTEN_BUTTON 0x0080 144 145 /* MRL Sensor */ 146 #define MRL_SENSOR 0x0100 147 148 /* 66 MHz Capable */ 149 #define IS_66MHZ_CAP 0x0200 150 151 /* PRSNT1#/PRSNT2# */ 152 #define SLOT_EMP 0x0c00 153 154 /* PCI-X Capability */ 155 #define NON_PCIX 0x0000 156 #define PCIX_66 0x1000 157 #define PCIX_133 0x3000 158 #define PCIX_266 0x4000 /* For PI = 2 only */ 159 #define PCIX_533 0x5000 /* For PI = 2 only */ 160 161 /* SHPC 'write' operations/commands */ 162 163 /* Slot operation - 0x00h to 0x3Fh */ 164 165 #define NO_CHANGE 0x00 166 167 /* Slot state - Bits 0 & 1 of controller command register */ 168 #define SET_SLOT_PWR 0x01 169 #define SET_SLOT_ENABLE 0x02 170 #define SET_SLOT_DISABLE 0x03 171 172 /* Power indicator state - Bits 2 & 3 of controller command register*/ 173 #define SET_PWR_ON 0x04 174 #define SET_PWR_BLINK 0x08 175 #define SET_PWR_OFF 0x0C 176 177 /* Attention indicator state - Bits 4 & 5 of controller command register*/ 178 #define SET_ATTN_ON 0x010 179 #define SET_ATTN_BLINK 0x020 180 #define SET_ATTN_OFF 0x030 181 182 /* Set bus speed/mode A - 0x40h to 0x47h */ 183 #define SETA_PCI_33MHZ 0x40 184 #define SETA_PCI_66MHZ 0x41 185 #define SETA_PCIX_66MHZ 0x42 186 #define SETA_PCIX_100MHZ 0x43 187 #define SETA_PCIX_133MHZ 0x44 188 #define RESERV_1 0x45 189 #define RESERV_2 0x46 190 #define RESERV_3 0x47 191 192 /* Set bus speed/mode B - 0x50h to 0x5fh */ 193 #define SETB_PCI_33MHZ 0x50 194 #define SETB_PCI_66MHZ 0x51 195 #define SETB_PCIX_66MHZ_PM 0x52 196 #define SETB_PCIX_100MHZ_PM 0x53 197 #define SETB_PCIX_133MHZ_PM 0x54 198 #define SETB_PCIX_66MHZ_EM 0x55 199 #define SETB_PCIX_100MHZ_EM 0x56 200 #define SETB_PCIX_133MHZ_EM 0x57 201 #define SETB_PCIX_66MHZ_266 0x58 202 #define SETB_PCIX_100MHZ_266 0x59 203 #define SETB_PCIX_133MHZ_266 0x5a 204 #define SETB_PCIX_66MHZ_533 0x5b 205 #define SETB_PCIX_100MHZ_533 0x5c 206 #define SETB_PCIX_133MHZ_533 0x5d 207 208 209 /* Power-on all slots - 0x48h */ 210 #define SET_PWR_ON_ALL 0x48 211 212 /* Enable all slots - 0x49h */ 213 #define SET_ENABLE_ALL 0x49 214 215 /* SHPC controller command error code */ 216 #define SWITCH_OPEN 0x1 217 #define INVALID_CMD 0x2 218 #define INVALID_SPEED_MODE 0x4 219 220 /* For accessing SHPC Working Register Set */ 221 #define DWORD_SELECT 0x2 222 #define DWORD_DATA 0x4 223 #define BASE_OFFSET 0x0 224 225 /* Field Offset in Logical Slot Register - byte boundary */ 226 #define SLOT_EVENT_LATCH 0x2 227 #define SLOT_SERR_INT_MASK 0x3 228 229 static spinlock_t hpc_event_lock; 230 231 DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ 232 static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ 233 static int ctlr_seq_num = 0; /* Controller sequenc # */ 234 static spinlock_t list_lock; 235 236 static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs); 237 238 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds); 239 240 /* This is the interrupt polling timeout function. */ 241 static void int_poll_timeout(unsigned long lphp_ctlr) 242 { 243 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *)lphp_ctlr; 244 245 DBG_ENTER_ROUTINE 246 247 if ( !php_ctlr ) { 248 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 249 return; 250 } 251 252 /* Poll for interrupt events. regs == NULL => polling */ 253 shpc_isr( 0, (void *)php_ctlr, NULL ); 254 255 init_timer(&php_ctlr->int_poll_timer); 256 if (!shpchp_poll_time) 257 shpchp_poll_time = 2; /* reset timer to poll in 2 secs if user doesn't specify at module installation*/ 258 259 start_int_poll_timer(php_ctlr, shpchp_poll_time); 260 261 return; 262 } 263 264 /* This function starts the interrupt polling timer. */ 265 static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int seconds) 266 { 267 if (!php_ctlr) { 268 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 269 return; 270 } 271 272 if ( ( seconds <= 0 ) || ( seconds > 60 ) ) 273 seconds = 2; /* Clamp to sane value */ 274 275 php_ctlr->int_poll_timer.function = &int_poll_timeout; 276 php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; /* Instance data */ 277 php_ctlr->int_poll_timer.expires = jiffies + seconds * HZ; 278 add_timer(&php_ctlr->int_poll_timer); 279 280 return; 281 } 282 283 static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd) 284 { 285 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 286 u16 cmd_status; 287 int retval = 0; 288 u16 temp_word; 289 int i; 290 291 DBG_ENTER_ROUTINE 292 293 if (!php_ctlr) { 294 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 295 return -1; 296 } 297 298 for (i = 0; i < 10; i++) { 299 cmd_status = readw(php_ctlr->creg + CMD_STATUS); 300 301 if (!(cmd_status & 0x1)) 302 break; 303 /* Check every 0.1 sec for a total of 1 sec*/ 304 msleep(100); 305 } 306 307 cmd_status = readw(php_ctlr->creg + CMD_STATUS); 308 309 if (cmd_status & 0x1) { 310 /* After 1 sec and and the controller is still busy */ 311 err("%s : Controller is still busy after 1 sec.\n", __FUNCTION__); 312 return -1; 313 } 314 315 ++t_slot; 316 temp_word = (t_slot << 8) | (cmd & 0xFF); 317 dbg("%s: t_slot %x cmd %x\n", __FUNCTION__, t_slot, cmd); 318 319 /* To make sure the Controller Busy bit is 0 before we send out the 320 * command. 321 */ 322 writew(temp_word, php_ctlr->creg + CMD); 323 dbg("%s: temp_word written %x\n", __FUNCTION__, temp_word); 324 325 DBG_LEAVE_ROUTINE 326 return retval; 327 } 328 329 static int hpc_check_cmd_status(struct controller *ctrl) 330 { 331 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; 332 u16 cmd_status; 333 int retval = 0; 334 335 DBG_ENTER_ROUTINE 336 337 if (!ctrl->hpc_ctlr_handle) { 338 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 339 return -1; 340 } 341 342 cmd_status = readw(php_ctlr->creg + CMD_STATUS) & 0x000F; 343 344 switch (cmd_status >> 1) { 345 case 0: 346 retval = 0; 347 break; 348 case 1: 349 retval = SWITCH_OPEN; 350 err("%s: Switch opened!\n", __FUNCTION__); 351 break; 352 case 2: 353 retval = INVALID_CMD; 354 err("%s: Invalid HPC command!\n", __FUNCTION__); 355 break; 356 case 4: 357 retval = INVALID_SPEED_MODE; 358 err("%s: Invalid bus speed/mode!\n", __FUNCTION__); 359 break; 360 default: 361 retval = cmd_status; 362 } 363 364 DBG_LEAVE_ROUTINE 365 return retval; 366 } 367 368 369 static int hpc_get_attention_status(struct slot *slot, u8 *status) 370 { 371 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 372 u32 slot_reg; 373 u16 slot_status; 374 u8 atten_led_state; 375 376 DBG_ENTER_ROUTINE 377 378 if (!slot->ctrl->hpc_ctlr_handle) { 379 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 380 return -1; 381 } 382 383 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 384 slot_status = (u16) slot_reg; 385 atten_led_state = (slot_status & 0x0030) >> 4; 386 387 switch (atten_led_state) { 388 case 0: 389 *status = 0xFF; /* Reserved */ 390 break; 391 case 1: 392 *status = 1; /* On */ 393 break; 394 case 2: 395 *status = 2; /* Blink */ 396 break; 397 case 3: 398 *status = 0; /* Off */ 399 break; 400 default: 401 *status = 0xFF; 402 break; 403 } 404 405 DBG_LEAVE_ROUTINE 406 return 0; 407 } 408 409 static int hpc_get_power_status(struct slot * slot, u8 *status) 410 { 411 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 412 u32 slot_reg; 413 u16 slot_status; 414 u8 slot_state; 415 int retval = 0; 416 417 DBG_ENTER_ROUTINE 418 419 if (!slot->ctrl->hpc_ctlr_handle) { 420 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 421 return -1; 422 } 423 424 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 425 slot_status = (u16) slot_reg; 426 slot_state = (slot_status & 0x0003); 427 428 switch (slot_state) { 429 case 0: 430 *status = 0xFF; 431 break; 432 case 1: 433 *status = 2; /* Powered only */ 434 break; 435 case 2: 436 *status = 1; /* Enabled */ 437 break; 438 case 3: 439 *status = 0; /* Disabled */ 440 break; 441 default: 442 *status = 0xFF; 443 break; 444 } 445 446 DBG_LEAVE_ROUTINE 447 return retval; 448 } 449 450 451 static int hpc_get_latch_status(struct slot *slot, u8 *status) 452 { 453 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 454 u32 slot_reg; 455 u16 slot_status; 456 457 DBG_ENTER_ROUTINE 458 459 if (!slot->ctrl->hpc_ctlr_handle) { 460 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 461 return -1; 462 } 463 464 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 465 slot_status = (u16)slot_reg; 466 467 *status = ((slot_status & 0x0100) == 0) ? 0 : 1; /* 0 -> close; 1 -> open */ 468 469 470 DBG_LEAVE_ROUTINE 471 return 0; 472 } 473 474 static int hpc_get_adapter_status(struct slot *slot, u8 *status) 475 { 476 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 477 u32 slot_reg; 478 u16 slot_status; 479 u8 card_state; 480 481 DBG_ENTER_ROUTINE 482 483 if (!slot->ctrl->hpc_ctlr_handle) { 484 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 485 return -1; 486 } 487 488 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 489 slot_status = (u16)slot_reg; 490 card_state = (u8)((slot_status & 0x0C00) >> 10); 491 *status = (card_state != 0x3) ? 1 : 0; 492 493 DBG_LEAVE_ROUTINE 494 return 0; 495 } 496 497 static int hpc_get_prog_int(struct slot *slot, u8 *prog_int) 498 { 499 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 500 501 DBG_ENTER_ROUTINE 502 503 if (!slot->ctrl->hpc_ctlr_handle) { 504 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 505 return -1; 506 } 507 508 *prog_int = readb(php_ctlr->creg + PROG_INTERFACE); 509 510 DBG_LEAVE_ROUTINE 511 return 0; 512 } 513 514 static int hpc_get_adapter_speed(struct slot *slot, enum pci_bus_speed *value) 515 { 516 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 517 u32 slot_reg; 518 u16 slot_status, sec_bus_status; 519 u8 m66_cap, pcix_cap, pi; 520 int retval = 0; 521 522 DBG_ENTER_ROUTINE 523 524 if (!slot->ctrl->hpc_ctlr_handle) { 525 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 526 return -1; 527 } 528 529 if (slot->hp_slot >= php_ctlr->num_slots) { 530 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 531 return -1; 532 } 533 534 pi = readb(php_ctlr->creg + PROG_INTERFACE); 535 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 536 dbg("%s: pi = %d, slot_reg = %x\n", __FUNCTION__, pi, slot_reg); 537 slot_status = (u16) slot_reg; 538 dbg("%s: slot_status = %x\n", __FUNCTION__, slot_status); 539 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); 540 541 pcix_cap = (u8) ((slot_status & 0x3000) >> 12); 542 dbg("%s: pcix_cap = %x\n", __FUNCTION__, pcix_cap); 543 m66_cap = (u8) ((slot_status & 0x0200) >> 9); 544 dbg("%s: m66_cap = %x\n", __FUNCTION__, m66_cap); 545 546 547 if (pi == 2) { 548 switch (pcix_cap) { 549 case 0: 550 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; 551 break; 552 case 1: 553 *value = PCI_SPEED_66MHz_PCIX; 554 break; 555 case 3: 556 *value = PCI_SPEED_133MHz_PCIX; 557 break; 558 case 4: 559 *value = PCI_SPEED_133MHz_PCIX_266; 560 break; 561 case 5: 562 *value = PCI_SPEED_133MHz_PCIX_533; 563 break; 564 case 2: /* Reserved */ 565 default: 566 *value = PCI_SPEED_UNKNOWN; 567 retval = -ENODEV; 568 break; 569 } 570 } else { 571 switch (pcix_cap) { 572 case 0: 573 *value = m66_cap ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; 574 break; 575 case 1: 576 *value = PCI_SPEED_66MHz_PCIX; 577 break; 578 case 3: 579 *value = PCI_SPEED_133MHz_PCIX; 580 break; 581 case 2: /* Reserved */ 582 default: 583 *value = PCI_SPEED_UNKNOWN; 584 retval = -ENODEV; 585 break; 586 } 587 } 588 589 dbg("Adapter speed = %d\n", *value); 590 591 DBG_LEAVE_ROUTINE 592 return retval; 593 } 594 595 static int hpc_get_mode1_ECC_cap(struct slot *slot, u8 *mode) 596 { 597 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 598 u16 sec_bus_status; 599 u8 pi; 600 int retval = 0; 601 602 DBG_ENTER_ROUTINE 603 604 if (!slot->ctrl->hpc_ctlr_handle) { 605 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 606 return -1; 607 } 608 609 pi = readb(php_ctlr->creg + PROG_INTERFACE); 610 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); 611 612 if (pi == 2) { 613 *mode = (sec_bus_status & 0x0100) >> 7; 614 } else { 615 retval = -1; 616 } 617 618 dbg("Mode 1 ECC cap = %d\n", *mode); 619 620 DBG_LEAVE_ROUTINE 621 return retval; 622 } 623 624 static int hpc_query_power_fault(struct slot * slot) 625 { 626 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 627 u32 slot_reg; 628 u16 slot_status; 629 u8 pwr_fault_state, status; 630 631 DBG_ENTER_ROUTINE 632 633 if (!slot->ctrl->hpc_ctlr_handle) { 634 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 635 return -1; 636 } 637 638 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*(slot->hp_slot)); 639 slot_status = (u16) slot_reg; 640 pwr_fault_state = (slot_status & 0x0040) >> 7; 641 status = (pwr_fault_state == 1) ? 0 : 1; 642 643 DBG_LEAVE_ROUTINE 644 /* Note: Logic 0 => fault */ 645 return status; 646 } 647 648 static int hpc_set_attention_status(struct slot *slot, u8 value) 649 { 650 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 651 u8 slot_cmd = 0; 652 int rc = 0; 653 654 if (!slot->ctrl->hpc_ctlr_handle) { 655 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 656 return -1; 657 } 658 659 if (slot->hp_slot >= php_ctlr->num_slots) { 660 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 661 return -1; 662 } 663 664 switch (value) { 665 case 0 : 666 slot_cmd = 0x30; /* OFF */ 667 break; 668 case 1: 669 slot_cmd = 0x10; /* ON */ 670 break; 671 case 2: 672 slot_cmd = 0x20; /* BLINK */ 673 break; 674 default: 675 return -1; 676 } 677 678 shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 679 680 return rc; 681 } 682 683 684 static void hpc_set_green_led_on(struct slot *slot) 685 { 686 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 687 u8 slot_cmd; 688 689 if (!slot->ctrl->hpc_ctlr_handle) { 690 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 691 return ; 692 } 693 694 if (slot->hp_slot >= php_ctlr->num_slots) { 695 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 696 return ; 697 } 698 699 slot_cmd = 0x04; 700 701 shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 702 703 return; 704 } 705 706 static void hpc_set_green_led_off(struct slot *slot) 707 { 708 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 709 u8 slot_cmd; 710 711 if (!slot->ctrl->hpc_ctlr_handle) { 712 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 713 return ; 714 } 715 716 if (slot->hp_slot >= php_ctlr->num_slots) { 717 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 718 return ; 719 } 720 721 slot_cmd = 0x0C; 722 723 shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 724 725 return; 726 } 727 728 static void hpc_set_green_led_blink(struct slot *slot) 729 { 730 struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 731 u8 slot_cmd; 732 733 if (!slot->ctrl->hpc_ctlr_handle) { 734 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 735 return ; 736 } 737 738 if (slot->hp_slot >= php_ctlr->num_slots) { 739 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 740 return ; 741 } 742 743 slot_cmd = 0x08; 744 745 shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 746 747 return; 748 } 749 750 int shpc_get_ctlr_slot_config(struct controller *ctrl, 751 int *num_ctlr_slots, /* number of slots in this HPC */ 752 int *first_device_num, /* PCI dev num of the first slot in this SHPC */ 753 int *physical_slot_num, /* phy slot num of the first slot in this SHPC */ 754 int *updown, /* physical_slot_num increament: 1 or -1 */ 755 int *flags) 756 { 757 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; 758 759 DBG_ENTER_ROUTINE 760 761 if (!ctrl->hpc_ctlr_handle) { 762 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 763 return -1; 764 } 765 766 *first_device_num = php_ctlr->slot_device_offset; /* Obtained in shpc_init() */ 767 *num_ctlr_slots = php_ctlr->num_slots; /* Obtained in shpc_init() */ 768 769 *physical_slot_num = (readl(php_ctlr->creg + SLOT_CONFIG) & PSN) >> 16; 770 dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); 771 *updown = ((readl(php_ctlr->creg + SLOT_CONFIG) & UPDOWN ) >> 29) ? 1 : -1; 772 773 DBG_LEAVE_ROUTINE 774 return 0; 775 } 776 777 static void hpc_release_ctlr(struct controller *ctrl) 778 { 779 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle; 780 struct php_ctlr_state_s *p, *p_prev; 781 782 DBG_ENTER_ROUTINE 783 784 if (!ctrl->hpc_ctlr_handle) { 785 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 786 return ; 787 } 788 789 if (shpchp_poll_mode) { 790 del_timer(&php_ctlr->int_poll_timer); 791 } else { 792 if (php_ctlr->irq) { 793 free_irq(php_ctlr->irq, ctrl); 794 php_ctlr->irq = 0; 795 pci_disable_msi(php_ctlr->pci_dev); 796 } 797 } 798 if (php_ctlr->pci_dev) { 799 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__); 800 iounmap(php_ctlr->creg); 801 release_mem_region(pci_resource_start(php_ctlr->pci_dev, 0), pci_resource_len(php_ctlr->pci_dev, 0)); 802 dbg("%s: before calling iounmap & release_mem_region\n", __FUNCTION__); 803 php_ctlr->pci_dev = NULL; 804 } 805 806 spin_lock(&list_lock); 807 p = php_ctlr_list_head; 808 p_prev = NULL; 809 while (p) { 810 if (p == php_ctlr) { 811 if (p_prev) 812 p_prev->pnext = p->pnext; 813 else 814 php_ctlr_list_head = p->pnext; 815 break; 816 } else { 817 p_prev = p; 818 p = p->pnext; 819 } 820 } 821 spin_unlock(&list_lock); 822 823 kfree(php_ctlr); 824 825 DBG_LEAVE_ROUTINE 826 827 } 828 829 static int hpc_power_on_slot(struct slot * slot) 830 { 831 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 832 u8 slot_cmd; 833 int retval = 0; 834 835 DBG_ENTER_ROUTINE 836 837 if (!slot->ctrl->hpc_ctlr_handle) { 838 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 839 return -1; 840 } 841 842 if (slot->hp_slot >= php_ctlr->num_slots) { 843 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 844 return -1; 845 } 846 slot_cmd = 0x01; 847 848 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 849 850 if (retval) { 851 err("%s: Write command failed!\n", __FUNCTION__); 852 return -1; 853 } 854 855 DBG_LEAVE_ROUTINE 856 857 return retval; 858 } 859 860 static int hpc_slot_enable(struct slot * slot) 861 { 862 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 863 u8 slot_cmd; 864 int retval = 0; 865 866 DBG_ENTER_ROUTINE 867 868 if (!slot->ctrl->hpc_ctlr_handle) { 869 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 870 return -1; 871 } 872 873 if (slot->hp_slot >= php_ctlr->num_slots) { 874 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 875 return -1; 876 } 877 /* 3A => Slot - Enable, Power Indicator - Blink, Attention Indicator - Off */ 878 slot_cmd = 0x3A; 879 880 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 881 882 if (retval) { 883 err("%s: Write command failed!\n", __FUNCTION__); 884 return -1; 885 } 886 887 DBG_LEAVE_ROUTINE 888 return retval; 889 } 890 891 static int hpc_slot_disable(struct slot * slot) 892 { 893 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 894 u8 slot_cmd; 895 int retval = 0; 896 897 DBG_ENTER_ROUTINE 898 899 if (!slot->ctrl->hpc_ctlr_handle) { 900 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 901 return -1; 902 } 903 904 if (slot->hp_slot >= php_ctlr->num_slots) { 905 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 906 return -1; 907 } 908 909 /* 1F => Slot - Disable, Power Indicator - Off, Attention Indicator - On */ 910 slot_cmd = 0x1F; 911 912 retval = shpc_write_cmd(slot, slot->hp_slot, slot_cmd); 913 914 if (retval) { 915 err("%s: Write command failed!\n", __FUNCTION__); 916 return -1; 917 } 918 919 DBG_LEAVE_ROUTINE 920 return retval; 921 } 922 923 static int hpc_enable_all_slots( struct slot *slot ) 924 { 925 int retval = 0; 926 927 DBG_ENTER_ROUTINE 928 929 if (!slot->ctrl->hpc_ctlr_handle) { 930 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 931 return -1; 932 } 933 934 retval = shpc_write_cmd(slot, 0, SET_ENABLE_ALL); 935 if (retval) { 936 err("%s: Write command failed!\n", __FUNCTION__); 937 return -1; 938 } 939 940 DBG_LEAVE_ROUTINE 941 942 return retval; 943 } 944 945 static int hpc_pwr_on_all_slots(struct slot *slot) 946 { 947 int retval = 0; 948 949 DBG_ENTER_ROUTINE 950 951 retval = shpc_write_cmd(slot, 0, SET_PWR_ON_ALL); 952 953 if (retval) { 954 err("%s: Write command failed!\n", __FUNCTION__); 955 return -1; 956 } 957 958 DBG_LEAVE_ROUTINE 959 return retval; 960 } 961 962 static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) 963 { 964 u8 slot_cmd; 965 u8 pi; 966 int retval = 0; 967 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 968 969 DBG_ENTER_ROUTINE 970 971 if (!slot->ctrl->hpc_ctlr_handle) { 972 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 973 return -1; 974 } 975 976 pi = readb(php_ctlr->creg + PROG_INTERFACE); 977 978 if (pi == 1) { 979 switch (value) { 980 case 0: 981 slot_cmd = SETA_PCI_33MHZ; 982 break; 983 case 1: 984 slot_cmd = SETA_PCI_66MHZ; 985 break; 986 case 2: 987 slot_cmd = SETA_PCIX_66MHZ; 988 break; 989 case 3: 990 slot_cmd = SETA_PCIX_100MHZ; 991 break; 992 case 4: 993 slot_cmd = SETA_PCIX_133MHZ; 994 break; 995 default: 996 slot_cmd = PCI_SPEED_UNKNOWN; 997 retval = -ENODEV; 998 return retval; 999 } 1000 } else { 1001 switch (value) { 1002 case 0: 1003 slot_cmd = SETB_PCI_33MHZ; 1004 break; 1005 case 1: 1006 slot_cmd = SETB_PCI_66MHZ; 1007 break; 1008 case 2: 1009 slot_cmd = SETB_PCIX_66MHZ_PM; 1010 break; 1011 case 3: 1012 slot_cmd = SETB_PCIX_100MHZ_PM; 1013 break; 1014 case 4: 1015 slot_cmd = SETB_PCIX_133MHZ_PM; 1016 break; 1017 case 5: 1018 slot_cmd = SETB_PCIX_66MHZ_EM; 1019 break; 1020 case 6: 1021 slot_cmd = SETB_PCIX_100MHZ_EM; 1022 break; 1023 case 7: 1024 slot_cmd = SETB_PCIX_133MHZ_EM; 1025 break; 1026 case 8: 1027 slot_cmd = SETB_PCIX_66MHZ_266; 1028 break; 1029 case 0x9: 1030 slot_cmd = SETB_PCIX_100MHZ_266; 1031 break; 1032 case 0xa: 1033 slot_cmd = SETB_PCIX_133MHZ_266; 1034 break; 1035 case 0xb: 1036 slot_cmd = SETB_PCIX_66MHZ_533; 1037 break; 1038 case 0xc: 1039 slot_cmd = SETB_PCIX_100MHZ_533; 1040 break; 1041 case 0xd: 1042 slot_cmd = SETB_PCIX_133MHZ_533; 1043 break; 1044 default: 1045 slot_cmd = PCI_SPEED_UNKNOWN; 1046 retval = -ENODEV; 1047 return retval; 1048 } 1049 1050 } 1051 retval = shpc_write_cmd(slot, 0, slot_cmd); 1052 if (retval) { 1053 err("%s: Write command failed!\n", __FUNCTION__); 1054 return -1; 1055 } 1056 1057 DBG_LEAVE_ROUTINE 1058 return retval; 1059 } 1060 1061 static irqreturn_t shpc_isr(int IRQ, void *dev_id, struct pt_regs *regs) 1062 { 1063 struct controller *ctrl = NULL; 1064 struct php_ctlr_state_s *php_ctlr; 1065 u8 schedule_flag = 0; 1066 u8 temp_byte; 1067 u32 temp_dword, intr_loc, intr_loc2; 1068 int hp_slot; 1069 1070 if (!dev_id) 1071 return IRQ_NONE; 1072 1073 if (!shpchp_poll_mode) { 1074 ctrl = (struct controller *)dev_id; 1075 php_ctlr = ctrl->hpc_ctlr_handle; 1076 } else { 1077 php_ctlr = (struct php_ctlr_state_s *) dev_id; 1078 ctrl = (struct controller *)php_ctlr->callback_instance_id; 1079 } 1080 1081 if (!ctrl) 1082 return IRQ_NONE; 1083 1084 if (!php_ctlr || !php_ctlr->creg) 1085 return IRQ_NONE; 1086 1087 /* Check to see if it was our interrupt */ 1088 intr_loc = readl(php_ctlr->creg + INTR_LOC); 1089 1090 if (!intr_loc) 1091 return IRQ_NONE; 1092 dbg("%s: shpc_isr proceeds\n", __FUNCTION__); 1093 dbg("%s: intr_loc = %x\n",__FUNCTION__, intr_loc); 1094 1095 if(!shpchp_poll_mode) { 1096 /* Mask Global Interrupt Mask - see implementation note on p. 139 */ 1097 /* of SHPC spec rev 1.0*/ 1098 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1099 dbg("%s: Before masking global interrupt, temp_dword = %x\n", 1100 __FUNCTION__, temp_dword); 1101 temp_dword |= 0x00000001; 1102 dbg("%s: After masking global interrupt, temp_dword = %x\n", 1103 __FUNCTION__, temp_dword); 1104 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1105 1106 intr_loc2 = readl(php_ctlr->creg + INTR_LOC); 1107 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 1108 } 1109 1110 if (intr_loc & 0x0001) { 1111 /* 1112 * Command Complete Interrupt Pending 1113 * RO only - clear by writing 0 to the Command Completion 1114 * Detect bit in Controller SERR-INT register 1115 */ 1116 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1117 dbg("%s: Before clearing CCIP, temp_dword = %x\n", 1118 __FUNCTION__, temp_dword); 1119 temp_dword &= 0xfffeffff; 1120 dbg("%s: After clearing CCIP, temp_dword = %x\n", 1121 __FUNCTION__, temp_dword); 1122 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1123 wake_up_interruptible(&ctrl->queue); 1124 } 1125 1126 if ((intr_loc = (intr_loc >> 1)) == 0) { 1127 /* Unmask Global Interrupt Mask */ 1128 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1129 dbg("%s: 1-Before unmasking global interrupt, temp_dword = %x\n", 1130 __FUNCTION__, temp_dword); 1131 temp_dword &= 0xfffffffe; 1132 dbg("%s: 1-After unmasking global interrupt, temp_dword = %x\n", 1133 __FUNCTION__, temp_dword); 1134 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1135 1136 return IRQ_NONE; 1137 } 1138 1139 for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { 1140 /* To find out which slot has interrupt pending */ 1141 if ((intr_loc >> hp_slot) & 0x01) { 1142 temp_dword = readl(php_ctlr->creg + SLOT1 + (4*hp_slot)); 1143 dbg("%s: Slot %x with intr, temp_dword = %x\n", 1144 __FUNCTION__, hp_slot, temp_dword); 1145 temp_byte = (temp_dword >> 16) & 0xFF; 1146 dbg("%s: Slot with intr, temp_byte = %x\n", 1147 __FUNCTION__, temp_byte); 1148 if ((php_ctlr->switch_change_callback) && (temp_byte & 0x08)) 1149 schedule_flag += php_ctlr->switch_change_callback( 1150 hp_slot, php_ctlr->callback_instance_id); 1151 if ((php_ctlr->attention_button_callback) && (temp_byte & 0x04)) 1152 schedule_flag += php_ctlr->attention_button_callback( 1153 hp_slot, php_ctlr->callback_instance_id); 1154 if ((php_ctlr->presence_change_callback) && (temp_byte & 0x01)) 1155 schedule_flag += php_ctlr->presence_change_callback( 1156 hp_slot , php_ctlr->callback_instance_id); 1157 if ((php_ctlr->power_fault_callback) && (temp_byte & 0x12)) 1158 schedule_flag += php_ctlr->power_fault_callback( 1159 hp_slot, php_ctlr->callback_instance_id); 1160 1161 /* Clear all slot events */ 1162 temp_dword = 0xe01f3fff; 1163 dbg("%s: Clearing slot events, temp_dword = %x\n", 1164 __FUNCTION__, temp_dword); 1165 writel(temp_dword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 1166 1167 intr_loc2 = readl(php_ctlr->creg + INTR_LOC); 1168 dbg("%s: intr_loc2 = %x\n",__FUNCTION__, intr_loc2); 1169 } 1170 } 1171 if (!shpchp_poll_mode) { 1172 /* Unmask Global Interrupt Mask */ 1173 temp_dword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1174 dbg("%s: 2-Before unmasking global interrupt, temp_dword = %x\n", 1175 __FUNCTION__, temp_dword); 1176 temp_dword &= 0xfffffffe; 1177 dbg("%s: 2-After unmasking global interrupt, temp_dword = %x\n", 1178 __FUNCTION__, temp_dword); 1179 writel(temp_dword, php_ctlr->creg + SERR_INTR_ENABLE); 1180 } 1181 1182 return IRQ_HANDLED; 1183 } 1184 1185 static int hpc_get_max_bus_speed (struct slot *slot, enum pci_bus_speed *value) 1186 { 1187 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 1188 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; 1189 int retval = 0; 1190 u8 pi; 1191 u32 slot_avail1, slot_avail2; 1192 int slot_num; 1193 1194 DBG_ENTER_ROUTINE 1195 1196 if (!slot->ctrl->hpc_ctlr_handle) { 1197 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 1198 return -1; 1199 } 1200 1201 if (slot->hp_slot >= php_ctlr->num_slots) { 1202 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 1203 return -1; 1204 } 1205 1206 pi = readb(php_ctlr->creg + PROG_INTERFACE); 1207 slot_avail1 = readl(php_ctlr->creg + SLOT_AVAIL1); 1208 slot_avail2 = readl(php_ctlr->creg + SLOT_AVAIL2); 1209 1210 if (pi == 2) { 1211 if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_533) >> 27) ) != 0 ) 1212 bus_speed = PCIX_133MHZ_533; 1213 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_533) >> 23) ) != 0 ) 1214 bus_speed = PCIX_100MHZ_533; 1215 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_533) >> 19) ) != 0 ) 1216 bus_speed = PCIX_66MHZ_533; 1217 else if ((slot_num = ((slot_avail2 & SLOT_133MHZ_PCIX_266) >> 15) ) != 0 ) 1218 bus_speed = PCIX_133MHZ_266; 1219 else if ((slot_num = ((slot_avail2 & SLOT_100MHZ_PCIX_266) >> 11) ) != 0 ) 1220 bus_speed = PCIX_100MHZ_266; 1221 else if ((slot_num = ((slot_avail2 & SLOT_66MHZ_PCIX_266) >> 7) ) != 0 ) 1222 bus_speed = PCIX_66MHZ_266; 1223 else if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 ) 1224 bus_speed = PCIX_133MHZ; 1225 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 ) 1226 bus_speed = PCIX_100MHZ; 1227 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 ) 1228 bus_speed = PCIX_66MHZ; 1229 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 ) 1230 bus_speed = PCI_66MHZ; 1231 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 ) 1232 bus_speed = PCI_33MHZ; 1233 else bus_speed = PCI_SPEED_UNKNOWN; 1234 } else { 1235 if ((slot_num = ((slot_avail1 & SLOT_133MHZ_PCIX) >> 23) ) != 0 ) 1236 bus_speed = PCIX_133MHZ; 1237 else if ((slot_num = ((slot_avail1 & SLOT_100MHZ_PCIX) >> 15) ) != 0 ) 1238 bus_speed = PCIX_100MHZ; 1239 else if ((slot_num = ((slot_avail1 & SLOT_66MHZ_PCIX) >> 7) ) != 0 ) 1240 bus_speed = PCIX_66MHZ; 1241 else if ((slot_num = (slot_avail2 & SLOT_66MHZ)) != 0 ) 1242 bus_speed = PCI_66MHZ; 1243 else if ((slot_num = (slot_avail1 & SLOT_33MHZ)) != 0 ) 1244 bus_speed = PCI_33MHZ; 1245 else bus_speed = PCI_SPEED_UNKNOWN; 1246 } 1247 1248 *value = bus_speed; 1249 dbg("Max bus speed = %d\n", bus_speed); 1250 DBG_LEAVE_ROUTINE 1251 return retval; 1252 } 1253 1254 static int hpc_get_cur_bus_speed (struct slot *slot, enum pci_bus_speed *value) 1255 { 1256 struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle; 1257 enum pci_bus_speed bus_speed = PCI_SPEED_UNKNOWN; 1258 u16 sec_bus_status; 1259 int retval = 0; 1260 u8 pi; 1261 1262 DBG_ENTER_ROUTINE 1263 1264 if (!slot->ctrl->hpc_ctlr_handle) { 1265 err("%s: Invalid HPC controller handle!\n", __FUNCTION__); 1266 return -1; 1267 } 1268 1269 if (slot->hp_slot >= php_ctlr->num_slots) { 1270 err("%s: Invalid HPC slot number!\n", __FUNCTION__); 1271 return -1; 1272 } 1273 1274 pi = readb(php_ctlr->creg + PROG_INTERFACE); 1275 sec_bus_status = readw(php_ctlr->creg + SEC_BUS_CONFIG); 1276 1277 if (pi == 2) { 1278 switch (sec_bus_status & 0x000f) { 1279 case 0: 1280 bus_speed = PCI_SPEED_33MHz; 1281 break; 1282 case 1: 1283 bus_speed = PCI_SPEED_66MHz; 1284 break; 1285 case 2: 1286 bus_speed = PCI_SPEED_66MHz_PCIX; 1287 break; 1288 case 3: 1289 bus_speed = PCI_SPEED_100MHz_PCIX; 1290 break; 1291 case 4: 1292 bus_speed = PCI_SPEED_133MHz_PCIX; 1293 break; 1294 case 5: 1295 bus_speed = PCI_SPEED_66MHz_PCIX_ECC; 1296 break; 1297 case 6: 1298 bus_speed = PCI_SPEED_100MHz_PCIX_ECC; 1299 break; 1300 case 7: 1301 bus_speed = PCI_SPEED_133MHz_PCIX_ECC; 1302 break; 1303 case 8: 1304 bus_speed = PCI_SPEED_66MHz_PCIX_266; 1305 break; 1306 case 9: 1307 bus_speed = PCI_SPEED_100MHz_PCIX_266; 1308 break; 1309 case 0xa: 1310 bus_speed = PCI_SPEED_133MHz_PCIX_266; 1311 break; 1312 case 0xb: 1313 bus_speed = PCI_SPEED_66MHz_PCIX_533; 1314 break; 1315 case 0xc: 1316 bus_speed = PCI_SPEED_100MHz_PCIX_533; 1317 break; 1318 case 0xd: 1319 bus_speed = PCI_SPEED_133MHz_PCIX_533; 1320 break; 1321 case 0xe: 1322 case 0xf: 1323 default: 1324 bus_speed = PCI_SPEED_UNKNOWN; 1325 break; 1326 } 1327 } else { 1328 /* In the case where pi is undefined, default it to 1 */ 1329 switch (sec_bus_status & 0x0007) { 1330 case 0: 1331 bus_speed = PCI_SPEED_33MHz; 1332 break; 1333 case 1: 1334 bus_speed = PCI_SPEED_66MHz; 1335 break; 1336 case 2: 1337 bus_speed = PCI_SPEED_66MHz_PCIX; 1338 break; 1339 case 3: 1340 bus_speed = PCI_SPEED_100MHz_PCIX; 1341 break; 1342 case 4: 1343 bus_speed = PCI_SPEED_133MHz_PCIX; 1344 break; 1345 case 5: 1346 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ 1347 break; 1348 case 6: 1349 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ 1350 break; 1351 case 7: 1352 bus_speed = PCI_SPEED_UNKNOWN; /* Reserved */ 1353 break; 1354 default: 1355 bus_speed = PCI_SPEED_UNKNOWN; 1356 break; 1357 } 1358 } 1359 1360 *value = bus_speed; 1361 dbg("Current bus speed = %d\n", bus_speed); 1362 DBG_LEAVE_ROUTINE 1363 return retval; 1364 } 1365 1366 static struct hpc_ops shpchp_hpc_ops = { 1367 .power_on_slot = hpc_power_on_slot, 1368 .slot_enable = hpc_slot_enable, 1369 .slot_disable = hpc_slot_disable, 1370 .enable_all_slots = hpc_enable_all_slots, 1371 .pwr_on_all_slots = hpc_pwr_on_all_slots, 1372 .set_bus_speed_mode = hpc_set_bus_speed_mode, 1373 .set_attention_status = hpc_set_attention_status, 1374 .get_power_status = hpc_get_power_status, 1375 .get_attention_status = hpc_get_attention_status, 1376 .get_latch_status = hpc_get_latch_status, 1377 .get_adapter_status = hpc_get_adapter_status, 1378 1379 .get_max_bus_speed = hpc_get_max_bus_speed, 1380 .get_cur_bus_speed = hpc_get_cur_bus_speed, 1381 .get_adapter_speed = hpc_get_adapter_speed, 1382 .get_mode1_ECC_cap = hpc_get_mode1_ECC_cap, 1383 .get_prog_int = hpc_get_prog_int, 1384 1385 .query_power_fault = hpc_query_power_fault, 1386 .green_led_on = hpc_set_green_led_on, 1387 .green_led_off = hpc_set_green_led_off, 1388 .green_led_blink = hpc_set_green_led_blink, 1389 1390 .release_ctlr = hpc_release_ctlr, 1391 .check_cmd_status = hpc_check_cmd_status, 1392 }; 1393 1394 int shpc_init(struct controller * ctrl, 1395 struct pci_dev * pdev, 1396 php_intr_callback_t attention_button_callback, 1397 php_intr_callback_t switch_change_callback, 1398 php_intr_callback_t presence_change_callback, 1399 php_intr_callback_t power_fault_callback) 1400 { 1401 struct php_ctlr_state_s *php_ctlr, *p; 1402 void *instance_id = ctrl; 1403 int rc; 1404 u8 hp_slot; 1405 static int first = 1; 1406 u32 shpc_cap_offset, shpc_base_offset; 1407 u32 tempdword, slot_reg; 1408 u16 vendor_id, device_id; 1409 u8 i; 1410 1411 DBG_ENTER_ROUTINE 1412 1413 spin_lock_init(&list_lock); 1414 php_ctlr = (struct php_ctlr_state_s *) kmalloc(sizeof(struct php_ctlr_state_s), GFP_KERNEL); 1415 1416 if (!php_ctlr) { /* allocate controller state data */ 1417 err("%s: HPC controller memory allocation error!\n", __FUNCTION__); 1418 goto abort; 1419 } 1420 1421 memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s)); 1422 1423 php_ctlr->pci_dev = pdev; /* save pci_dev in context */ 1424 1425 rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); 1426 dbg("%s: Vendor ID: %x\n",__FUNCTION__, vendor_id); 1427 if (rc) { 1428 err("%s: unable to read PCI configuration data\n", __FUNCTION__); 1429 goto abort_free_ctlr; 1430 } 1431 1432 rc = pci_read_config_word(pdev, PCI_DEVICE_ID, &device_id); 1433 dbg("%s: Device ID: %x\n",__FUNCTION__, device_id); 1434 if (rc) { 1435 err("%s: unable to read PCI configuration data\n", __FUNCTION__); 1436 goto abort_free_ctlr; 1437 } 1438 1439 if ((vendor_id == PCI_VENDOR_ID_AMD) || (device_id == PCI_DEVICE_ID_AMD_GOLAM_7450)) { 1440 shpc_base_offset = 0; /* amd shpc driver doesn't use this; assume 0 */ 1441 } else { 1442 if ((shpc_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC)) == 0) { 1443 err("%s : shpc_cap_offset == 0\n", __FUNCTION__); 1444 goto abort_free_ctlr; 1445 } 1446 dbg("%s: shpc_cap_offset = %x\n", __FUNCTION__, shpc_cap_offset); 1447 1448 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , BASE_OFFSET); 1449 if (rc) { 1450 err("%s : pci_word_config_byte failed\n", __FUNCTION__); 1451 goto abort_free_ctlr; 1452 } 1453 1454 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &shpc_base_offset); 1455 if (rc) { 1456 err("%s : pci_read_config_dword failed\n", __FUNCTION__); 1457 goto abort_free_ctlr; 1458 } 1459 1460 for (i = 0; i <= 14; i++) { 1461 rc = pci_write_config_byte(pdev, (u8)shpc_cap_offset + DWORD_SELECT , i); 1462 if (rc) { 1463 err("%s : pci_word_config_byte failed\n", __FUNCTION__); 1464 goto abort_free_ctlr; 1465 } 1466 1467 rc = pci_read_config_dword(pdev, (u8)shpc_cap_offset + DWORD_DATA, &tempdword); 1468 if (rc) { 1469 err("%s : pci_read_config_dword failed\n", __FUNCTION__); 1470 goto abort_free_ctlr; 1471 } 1472 dbg("%s: offset %d: tempdword %x\n", __FUNCTION__,i, tempdword); 1473 } 1474 } 1475 1476 if (first) { 1477 spin_lock_init(&hpc_event_lock); 1478 first = 0; 1479 } 1480 1481 dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number, PCI_SLOT(pdev->devfn), 1482 PCI_FUNC(pdev->devfn), pdev->irq); 1483 for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) 1484 if (pci_resource_len(pdev, rc) > 0) 1485 dbg("pci resource[%d] start=0x%lx(len=0x%lx), shpc_base_offset %x\n", rc, 1486 pci_resource_start(pdev, rc), pci_resource_len(pdev, rc), shpc_base_offset); 1487 1488 info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, 1489 pdev->subsystem_device); 1490 1491 if (pci_enable_device(pdev)) 1492 goto abort_free_ctlr; 1493 1494 if (!request_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0), MY_NAME)) { 1495 err("%s: cannot reserve MMIO region\n", __FUNCTION__); 1496 goto abort_free_ctlr; 1497 } 1498 1499 php_ctlr->creg = ioremap(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); 1500 if (!php_ctlr->creg) { 1501 err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, pci_resource_len(pdev, 0), 1502 pci_resource_start(pdev, 0) + shpc_base_offset); 1503 release_mem_region(pci_resource_start(pdev, 0) + shpc_base_offset, pci_resource_len(pdev, 0)); 1504 goto abort_free_ctlr; 1505 } 1506 dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); 1507 dbg("%s: physical addr %p\n", __FUNCTION__, (void*)pci_resource_start(pdev, 0)); 1508 1509 init_MUTEX(&ctrl->crit_sect); 1510 /* Setup wait queue */ 1511 init_waitqueue_head(&ctrl->queue); 1512 1513 /* Find the IRQ */ 1514 php_ctlr->irq = pdev->irq; 1515 dbg("HPC interrupt = %d\n", php_ctlr->irq); 1516 1517 /* Save interrupt callback info */ 1518 php_ctlr->attention_button_callback = attention_button_callback; 1519 php_ctlr->switch_change_callback = switch_change_callback; 1520 php_ctlr->presence_change_callback = presence_change_callback; 1521 php_ctlr->power_fault_callback = power_fault_callback; 1522 php_ctlr->callback_instance_id = instance_id; 1523 1524 /* Return PCI Controller Info */ 1525 php_ctlr->slot_device_offset = (readl(php_ctlr->creg + SLOT_CONFIG) & FIRST_DEV_NUM ) >> 8; 1526 php_ctlr->num_slots = readl(php_ctlr->creg + SLOT_CONFIG) & SLOT_NUM; 1527 dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); 1528 dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); 1529 1530 /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ 1531 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1532 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1533 tempdword = 0x0003000f; 1534 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); 1535 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1536 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1537 1538 /* Mask the MRL sensor SERR Mask of individual slot in 1539 * Slot SERR-INT Mask & clear all the existing event if any 1540 */ 1541 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { 1542 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); 1543 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, 1544 hp_slot, slot_reg); 1545 tempdword = 0xffff3fff; 1546 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 1547 } 1548 1549 if (shpchp_poll_mode) {/* Install interrupt polling code */ 1550 /* Install and start the interrupt polling timer */ 1551 init_timer(&php_ctlr->int_poll_timer); 1552 start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ 1553 } else { 1554 /* Installs the interrupt handler */ 1555 rc = pci_enable_msi(pdev); 1556 if (rc) { 1557 info("Can't get msi for the hotplug controller\n"); 1558 info("Use INTx for the hotplug controller\n"); 1559 dbg("%s: rc = %x\n", __FUNCTION__, rc); 1560 } else 1561 php_ctlr->irq = pdev->irq; 1562 1563 rc = request_irq(php_ctlr->irq, shpc_isr, SA_SHIRQ, MY_NAME, (void *) ctrl); 1564 dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); 1565 if (rc) { 1566 err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); 1567 goto abort_free_ctlr; 1568 } 1569 /* Execute OSHP method here */ 1570 } 1571 dbg("%s: Before adding HPC to HPC list\n", __FUNCTION__); 1572 1573 /* Add this HPC instance into the HPC list */ 1574 spin_lock(&list_lock); 1575 if (php_ctlr_list_head == 0) { 1576 php_ctlr_list_head = php_ctlr; 1577 p = php_ctlr_list_head; 1578 p->pnext = NULL; 1579 } else { 1580 p = php_ctlr_list_head; 1581 1582 while (p->pnext) 1583 p = p->pnext; 1584 1585 p->pnext = php_ctlr; 1586 } 1587 spin_unlock(&list_lock); 1588 1589 1590 ctlr_seq_num++; 1591 ctrl->hpc_ctlr_handle = php_ctlr; 1592 ctrl->hpc_ops = &shpchp_hpc_ops; 1593 1594 for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { 1595 slot_reg = readl(php_ctlr->creg + SLOT1 + 4*hp_slot ); 1596 dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, 1597 hp_slot, slot_reg); 1598 tempdword = 0xe01f3fff; 1599 writel(tempdword, php_ctlr->creg + SLOT1 + (4*hp_slot)); 1600 } 1601 if (!shpchp_poll_mode) { 1602 /* Unmask all general input interrupts and SERR */ 1603 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1604 tempdword = 0x0000000a; 1605 writel(tempdword, php_ctlr->creg + SERR_INTR_ENABLE); 1606 tempdword = readl(php_ctlr->creg + SERR_INTR_ENABLE); 1607 dbg("%s: SERR_INTR_ENABLE = %x\n", __FUNCTION__, tempdword); 1608 } 1609 1610 dbg("%s: Leaving shpc_init\n", __FUNCTION__); 1611 DBG_LEAVE_ROUTINE 1612 return 0; 1613 1614 /* We end up here for the many possible ways to fail this API. */ 1615 abort_free_ctlr: 1616 kfree(php_ctlr); 1617 abort: 1618 DBG_LEAVE_ROUTINE 1619 return -1; 1620 } 1621