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