1 /* 2 * Compaq Hot Plug Controller 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 * 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 <greg@kroah.com> 26 * 27 */ 28 29 #include <linux/module.h> 30 #include <linux/kernel.h> 31 #include <linux/types.h> 32 #include <linux/proc_fs.h> 33 #include <linux/slab.h> 34 #include <linux/workqueue.h> 35 #include <linux/pci.h> 36 #include <linux/pci_hotplug.h> 37 #include <linux/init.h> 38 #include <asm/uaccess.h> 39 #include "cpqphp.h" 40 #include "cpqphp_nvram.h" 41 42 43 #define ROM_INT15_PHY_ADDR 0x0FF859 44 #define READ_EV 0xD8A4 45 #define WRITE_EV 0xD8A5 46 47 struct register_foo { 48 union { 49 unsigned long lword; /* eax */ 50 unsigned short word; /* ax */ 51 52 struct { 53 unsigned char low; /* al */ 54 unsigned char high; /* ah */ 55 } byte; 56 } data; 57 58 unsigned char opcode; /* see below */ 59 unsigned long length; /* if the reg. is a pointer, how much data */ 60 } __attribute__ ((packed)); 61 62 struct all_reg { 63 struct register_foo eax_reg; 64 struct register_foo ebx_reg; 65 struct register_foo ecx_reg; 66 struct register_foo edx_reg; 67 struct register_foo edi_reg; 68 struct register_foo esi_reg; 69 struct register_foo eflags_reg; 70 } __attribute__ ((packed)); 71 72 73 struct ev_hrt_header { 74 u8 Version; 75 u8 num_of_ctrl; 76 u8 next; 77 }; 78 79 struct ev_hrt_ctrl { 80 u8 bus; 81 u8 device; 82 u8 function; 83 u8 mem_avail; 84 u8 p_mem_avail; 85 u8 io_avail; 86 u8 bus_avail; 87 u8 next; 88 }; 89 90 91 static u8 evbuffer_init; 92 static u8 evbuffer_length; 93 static u8 evbuffer[1024]; 94 95 static void __iomem *compaq_int15_entry_point; 96 97 /* lock for ordering int15_bios_call() */ 98 static spinlock_t int15_lock; 99 100 101 /* This is a series of function that deals with 102 * setting & getting the hotplug resource table in some environment variable. 103 */ 104 105 /* 106 * We really shouldn't be doing this unless there is a _very_ good reason to!!! 107 * greg k-h 108 */ 109 110 111 static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail) 112 { 113 u8 **tByte; 114 115 if ((*used + 1) > *avail) 116 return(1); 117 118 *((u8*)*p_buffer) = value; 119 tByte = (u8**)p_buffer; 120 (*tByte)++; 121 *used+=1; 122 return(0); 123 } 124 125 126 static u32 add_dword( u32 **p_buffer, u32 value, u32 *used, u32 *avail) 127 { 128 if ((*used + 4) > *avail) 129 return(1); 130 131 **p_buffer = value; 132 (*p_buffer)++; 133 *used+=4; 134 return(0); 135 } 136 137 138 /* 139 * check_for_compaq_ROM 140 * 141 * this routine verifies that the ROM OEM string is 'COMPAQ' 142 * 143 * returns 0 for non-Compaq ROM, 1 for Compaq ROM 144 */ 145 static int check_for_compaq_ROM (void __iomem *rom_start) 146 { 147 u8 temp1, temp2, temp3, temp4, temp5, temp6; 148 int result = 0; 149 150 temp1 = readb(rom_start + 0xffea + 0); 151 temp2 = readb(rom_start + 0xffea + 1); 152 temp3 = readb(rom_start + 0xffea + 2); 153 temp4 = readb(rom_start + 0xffea + 3); 154 temp5 = readb(rom_start + 0xffea + 4); 155 temp6 = readb(rom_start + 0xffea + 5); 156 if ((temp1 == 'C') && 157 (temp2 == 'O') && 158 (temp3 == 'M') && 159 (temp4 == 'P') && 160 (temp5 == 'A') && 161 (temp6 == 'Q')) { 162 result = 1; 163 } 164 dbg ("%s - returned %d\n", __func__, result); 165 return result; 166 } 167 168 169 static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size) 170 { 171 unsigned long flags; 172 int op = operation; 173 int ret_val; 174 175 if (!compaq_int15_entry_point) 176 return -ENODEV; 177 178 spin_lock_irqsave(&int15_lock, flags); 179 __asm__ ( 180 "xorl %%ebx,%%ebx\n" \ 181 "xorl %%edx,%%edx\n" \ 182 "pushf\n" \ 183 "push %%cs\n" \ 184 "cli\n" \ 185 "call *%6\n" 186 : "=c" (*buf_size), "=a" (ret_val) 187 : "a" (op), "c" (*buf_size), "S" (ev_name), 188 "D" (buffer), "m" (compaq_int15_entry_point) 189 : "%ebx", "%edx"); 190 spin_unlock_irqrestore(&int15_lock, flags); 191 192 return((ret_val & 0xFF00) >> 8); 193 } 194 195 196 /* 197 * load_HRT 198 * 199 * Read the hot plug Resource Table from NVRAM 200 */ 201 static int load_HRT (void __iomem *rom_start) 202 { 203 u32 available; 204 u32 temp_dword; 205 u8 temp_byte = 0xFF; 206 u32 rc; 207 208 if (!check_for_compaq_ROM(rom_start)) { 209 return -ENODEV; 210 } 211 212 available = 1024; 213 214 /* Now load the EV */ 215 temp_dword = available; 216 217 rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword); 218 219 evbuffer_length = temp_dword; 220 221 /* We're maintaining the resource lists so write FF to invalidate old 222 * info 223 */ 224 temp_dword = 1; 225 226 rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword); 227 228 return rc; 229 } 230 231 232 /* 233 * store_HRT 234 * 235 * Save the hot plug Resource Table in NVRAM 236 */ 237 static u32 store_HRT (void __iomem *rom_start) 238 { 239 u32 *buffer; 240 u32 *pFill; 241 u32 usedbytes; 242 u32 available; 243 u32 temp_dword; 244 u32 rc; 245 u8 loop; 246 u8 numCtrl = 0; 247 struct controller *ctrl; 248 struct pci_resource *resNode; 249 struct ev_hrt_header *p_EV_header; 250 struct ev_hrt_ctrl *p_ev_ctrl; 251 252 available = 1024; 253 254 if (!check_for_compaq_ROM(rom_start)) { 255 return(1); 256 } 257 258 buffer = (u32*) evbuffer; 259 260 if (!buffer) 261 return(1); 262 263 pFill = buffer; 264 usedbytes = 0; 265 266 p_EV_header = (struct ev_hrt_header *) pFill; 267 268 ctrl = cpqhp_ctrl_list; 269 270 /* The revision of this structure */ 271 rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available); 272 if (rc) 273 return(rc); 274 275 /* The number of controllers */ 276 rc = add_byte( &pFill, 1, &usedbytes, &available); 277 if (rc) 278 return(rc); 279 280 while (ctrl) { 281 p_ev_ctrl = (struct ev_hrt_ctrl *) pFill; 282 283 numCtrl++; 284 285 /* The bus number */ 286 rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available); 287 if (rc) 288 return(rc); 289 290 /* The device Number */ 291 rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available); 292 if (rc) 293 return(rc); 294 295 /* The function Number */ 296 rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available); 297 if (rc) 298 return(rc); 299 300 /* Skip the number of available entries */ 301 rc = add_dword( &pFill, 0, &usedbytes, &available); 302 if (rc) 303 return(rc); 304 305 /* Figure out memory Available */ 306 307 resNode = ctrl->mem_head; 308 309 loop = 0; 310 311 while (resNode) { 312 loop ++; 313 314 /* base */ 315 rc = add_dword( &pFill, resNode->base, &usedbytes, &available); 316 if (rc) 317 return(rc); 318 319 /* length */ 320 rc = add_dword( &pFill, resNode->length, &usedbytes, &available); 321 if (rc) 322 return(rc); 323 324 resNode = resNode->next; 325 } 326 327 /* Fill in the number of entries */ 328 p_ev_ctrl->mem_avail = loop; 329 330 /* Figure out prefetchable memory Available */ 331 332 resNode = ctrl->p_mem_head; 333 334 loop = 0; 335 336 while (resNode) { 337 loop ++; 338 339 /* base */ 340 rc = add_dword( &pFill, resNode->base, &usedbytes, &available); 341 if (rc) 342 return(rc); 343 344 /* length */ 345 rc = add_dword( &pFill, resNode->length, &usedbytes, &available); 346 if (rc) 347 return(rc); 348 349 resNode = resNode->next; 350 } 351 352 /* Fill in the number of entries */ 353 p_ev_ctrl->p_mem_avail = loop; 354 355 /* Figure out IO Available */ 356 357 resNode = ctrl->io_head; 358 359 loop = 0; 360 361 while (resNode) { 362 loop ++; 363 364 /* base */ 365 rc = add_dword( &pFill, resNode->base, &usedbytes, &available); 366 if (rc) 367 return(rc); 368 369 /* length */ 370 rc = add_dword( &pFill, resNode->length, &usedbytes, &available); 371 if (rc) 372 return(rc); 373 374 resNode = resNode->next; 375 } 376 377 /* Fill in the number of entries */ 378 p_ev_ctrl->io_avail = loop; 379 380 /* Figure out bus Available */ 381 382 resNode = ctrl->bus_head; 383 384 loop = 0; 385 386 while (resNode) { 387 loop ++; 388 389 /* base */ 390 rc = add_dword( &pFill, resNode->base, &usedbytes, &available); 391 if (rc) 392 return(rc); 393 394 /* length */ 395 rc = add_dword( &pFill, resNode->length, &usedbytes, &available); 396 if (rc) 397 return(rc); 398 399 resNode = resNode->next; 400 } 401 402 /* Fill in the number of entries */ 403 p_ev_ctrl->bus_avail = loop; 404 405 ctrl = ctrl->next; 406 } 407 408 p_EV_header->num_of_ctrl = numCtrl; 409 410 /* Now store the EV */ 411 412 temp_dword = usedbytes; 413 414 rc = access_EV(WRITE_EV, "CQTHPS", (u8*) buffer, &temp_dword); 415 416 dbg("usedbytes = 0x%x, length = 0x%x\n", usedbytes, temp_dword); 417 418 evbuffer_length = temp_dword; 419 420 if (rc) { 421 err(msg_unable_to_save); 422 return(1); 423 } 424 425 return(0); 426 } 427 428 429 void compaq_nvram_init (void __iomem *rom_start) 430 { 431 if (rom_start) { 432 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); 433 } 434 dbg("int15 entry = %p\n", compaq_int15_entry_point); 435 436 /* initialize our int15 lock */ 437 spin_lock_init(&int15_lock); 438 } 439 440 441 int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) 442 { 443 u8 bus, device, function; 444 u8 nummem, numpmem, numio, numbus; 445 u32 rc; 446 u8 *p_byte; 447 struct pci_resource *mem_node; 448 struct pci_resource *p_mem_node; 449 struct pci_resource *io_node; 450 struct pci_resource *bus_node; 451 struct ev_hrt_ctrl *p_ev_ctrl; 452 struct ev_hrt_header *p_EV_header; 453 454 if (!evbuffer_init) { 455 /* Read the resource list information in from NVRAM */ 456 if (load_HRT(rom_start)) 457 memset (evbuffer, 0, 1024); 458 459 evbuffer_init = 1; 460 } 461 462 /* If we saved information in NVRAM, use it now */ 463 p_EV_header = (struct ev_hrt_header *) evbuffer; 464 465 /* The following code is for systems where version 1.0 of this 466 * driver has been loaded, but doesn't support the hardware. 467 * In that case, the driver would incorrectly store something 468 * in NVRAM. 469 */ 470 if ((p_EV_header->Version == 2) || 471 ((p_EV_header->Version == 1) && !ctrl->push_flag)) { 472 p_byte = &(p_EV_header->next); 473 474 p_ev_ctrl = (struct ev_hrt_ctrl *) &(p_EV_header->next); 475 476 p_byte += 3; 477 478 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) 479 return 2; 480 481 bus = p_ev_ctrl->bus; 482 device = p_ev_ctrl->device; 483 function = p_ev_ctrl->function; 484 485 while ((bus != ctrl->bus) || 486 (device != PCI_SLOT(ctrl->pci_dev->devfn)) || 487 (function != PCI_FUNC(ctrl->pci_dev->devfn))) { 488 nummem = p_ev_ctrl->mem_avail; 489 numpmem = p_ev_ctrl->p_mem_avail; 490 numio = p_ev_ctrl->io_avail; 491 numbus = p_ev_ctrl->bus_avail; 492 493 p_byte += 4; 494 495 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) 496 return 2; 497 498 /* Skip forward to the next entry */ 499 p_byte += (nummem + numpmem + numio + numbus) * 8; 500 501 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) 502 return 2; 503 504 p_ev_ctrl = (struct ev_hrt_ctrl *) p_byte; 505 506 p_byte += 3; 507 508 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) 509 return 2; 510 511 bus = p_ev_ctrl->bus; 512 device = p_ev_ctrl->device; 513 function = p_ev_ctrl->function; 514 } 515 516 nummem = p_ev_ctrl->mem_avail; 517 numpmem = p_ev_ctrl->p_mem_avail; 518 numio = p_ev_ctrl->io_avail; 519 numbus = p_ev_ctrl->bus_avail; 520 521 p_byte += 4; 522 523 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) 524 return 2; 525 526 while (nummem--) { 527 mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); 528 529 if (!mem_node) 530 break; 531 532 mem_node->base = *(u32*)p_byte; 533 dbg("mem base = %8.8x\n",mem_node->base); 534 p_byte += 4; 535 536 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 537 kfree(mem_node); 538 return 2; 539 } 540 541 mem_node->length = *(u32*)p_byte; 542 dbg("mem length = %8.8x\n",mem_node->length); 543 p_byte += 4; 544 545 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 546 kfree(mem_node); 547 return 2; 548 } 549 550 mem_node->next = ctrl->mem_head; 551 ctrl->mem_head = mem_node; 552 } 553 554 while (numpmem--) { 555 p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); 556 557 if (!p_mem_node) 558 break; 559 560 p_mem_node->base = *(u32*)p_byte; 561 dbg("pre-mem base = %8.8x\n",p_mem_node->base); 562 p_byte += 4; 563 564 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 565 kfree(p_mem_node); 566 return 2; 567 } 568 569 p_mem_node->length = *(u32*)p_byte; 570 dbg("pre-mem length = %8.8x\n",p_mem_node->length); 571 p_byte += 4; 572 573 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 574 kfree(p_mem_node); 575 return 2; 576 } 577 578 p_mem_node->next = ctrl->p_mem_head; 579 ctrl->p_mem_head = p_mem_node; 580 } 581 582 while (numio--) { 583 io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); 584 585 if (!io_node) 586 break; 587 588 io_node->base = *(u32*)p_byte; 589 dbg("io base = %8.8x\n",io_node->base); 590 p_byte += 4; 591 592 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 593 kfree(io_node); 594 return 2; 595 } 596 597 io_node->length = *(u32*)p_byte; 598 dbg("io length = %8.8x\n",io_node->length); 599 p_byte += 4; 600 601 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 602 kfree(io_node); 603 return 2; 604 } 605 606 io_node->next = ctrl->io_head; 607 ctrl->io_head = io_node; 608 } 609 610 while (numbus--) { 611 bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); 612 613 if (!bus_node) 614 break; 615 616 bus_node->base = *(u32*)p_byte; 617 p_byte += 4; 618 619 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 620 kfree(bus_node); 621 return 2; 622 } 623 624 bus_node->length = *(u32*)p_byte; 625 p_byte += 4; 626 627 if (p_byte > ((u8*)p_EV_header + evbuffer_length)) { 628 kfree(bus_node); 629 return 2; 630 } 631 632 bus_node->next = ctrl->bus_head; 633 ctrl->bus_head = bus_node; 634 } 635 636 /* If all of the following fail, we don't have any resources for 637 * hot plug add 638 */ 639 rc = 1; 640 rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); 641 rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); 642 rc &= cpqhp_resource_sort_and_combine(&(ctrl->io_head)); 643 rc &= cpqhp_resource_sort_and_combine(&(ctrl->bus_head)); 644 645 if (rc) 646 return(rc); 647 } else { 648 if ((evbuffer[0] != 0) && (!ctrl->push_flag)) 649 return 1; 650 } 651 652 return 0; 653 } 654 655 656 int compaq_nvram_store (void __iomem *rom_start) 657 { 658 int rc = 1; 659 660 if (rom_start == NULL) 661 return -ENODEV; 662 663 if (evbuffer_init) { 664 rc = store_HRT(rom_start); 665 if (rc) { 666 err(msg_unable_to_save); 667 } 668 } 669 return rc; 670 } 671 672