Changeset b0f00a9 in mainline for uspace/drv/bus/pci/pciintel/pci.c
- Timestamp:
- 2011-11-06T22:21:05Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 898e847
- Parents:
- 2bdf8313 (diff), 7b5f4c9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - File:
-
- 1 moved
-
uspace/drv/bus/pci/pciintel/pci.c (moved) (moved from uspace/drv/pciintel/pci.c ) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/pci/pciintel/pci.c
r2bdf8313 rb0f00a9 52 52 #include <ipc/devman.h> 53 53 #include <ipc/dev_iface.h> 54 #include <ipc/irc.h> 55 #include <ns.h> 56 #include <ipc/services.h> 57 #include <sysinfo.h> 54 58 #include <ops/hw_res.h> 55 59 #include <device/hw_res.h> 56 60 #include <ddi.h> 57 61 #include <libarch/ddi.h> 62 #include <pci_dev_iface.h> 58 63 59 64 #include "pci.h" … … 72 77 /** Obtain PCI bus soft-state from function soft-state */ 73 78 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 79 80 /** Max is 47, align to something nice. */ 81 #define ID_MAX_STR_LEN 50 74 82 75 83 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) … … 84 92 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 85 93 { 86 /* TODO */ 87 88 return false; 94 /* This is an old ugly way, copied from ne2000 driver */ 95 assert(fnode); 96 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 97 98 sysarg_t apic; 99 sysarg_t i8259; 100 101 async_sess_t *irc_sess = NULL; 102 103 if (((sysinfo_get_value("apic", &apic) == EOK) && (apic)) 104 || ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259))) { 105 irc_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 106 SERVICE_IRC, 0, 0); 107 } 108 109 if (!irc_sess) 110 return false; 111 112 size_t i = 0; 113 hw_resource_list_t *res = &dev_data->hw_resources; 114 for (; i < res->count; i++) { 115 if (res->resources[i].type == INTERRUPT) { 116 const int irq = res->resources[i].res.interrupt.irq; 117 118 async_exch_t *exch = async_exchange_begin(irc_sess); 119 const int rc = 120 async_req_1_0(exch, IRC_ENABLE_INTERRUPT, irq); 121 async_exchange_end(exch); 122 123 if (rc != EOK) { 124 async_hangup(irc_sess); 125 return false; 126 } 127 } 128 } 129 130 async_hangup(irc_sess); 131 return true; 132 } 133 134 static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address, 135 uint32_t data) 136 { 137 if (address > 252) 138 return EINVAL; 139 pci_conf_write_32(PCI_FUN(fun), address, data); 140 return EOK; 141 } 142 143 static int pci_config_space_write_16( 144 ddf_fun_t *fun, uint32_t address, uint16_t data) 145 { 146 if (address > 254) 147 return EINVAL; 148 pci_conf_write_16(PCI_FUN(fun), address, data); 149 return EOK; 150 } 151 152 static int pci_config_space_write_8( 153 ddf_fun_t *fun, uint32_t address, uint8_t data) 154 { 155 if (address > 255) 156 return EINVAL; 157 pci_conf_write_8(PCI_FUN(fun), address, data); 158 return EOK; 159 } 160 161 static int pci_config_space_read_32( 162 ddf_fun_t *fun, uint32_t address, uint32_t *data) 163 { 164 if (address > 252) 165 return EINVAL; 166 *data = pci_conf_read_32(PCI_FUN(fun), address); 167 return EOK; 168 } 169 170 static int pci_config_space_read_16( 171 ddf_fun_t *fun, uint32_t address, uint16_t *data) 172 { 173 if (address > 254) 174 return EINVAL; 175 *data = pci_conf_read_16(PCI_FUN(fun), address); 176 return EOK; 177 } 178 179 static int pci_config_space_read_8( 180 ddf_fun_t *fun, uint32_t address, uint8_t *data) 181 { 182 if (address > 255) 183 return EINVAL; 184 *data = pci_conf_read_8(PCI_FUN(fun), address); 185 return EOK; 89 186 } 90 187 … … 94 191 }; 95 192 96 static ddf_dev_ops_t pci_fun_ops; 193 static pci_dev_iface_t pci_dev_ops = { 194 .config_space_read_8 = &pci_config_space_read_8, 195 .config_space_read_16 = &pci_config_space_read_16, 196 .config_space_read_32 = &pci_config_space_read_32, 197 .config_space_write_8 = &pci_config_space_write_8, 198 .config_space_write_16 = &pci_config_space_write_16, 199 .config_space_write_32 = &pci_config_space_write_32 200 }; 201 202 static ddf_dev_ops_t pci_fun_ops = { 203 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 204 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 205 }; 97 206 98 207 static int pci_add_device(ddf_dev_t *); 208 static int pci_fun_online(ddf_fun_t *); 209 static int pci_fun_offline(ddf_fun_t *); 99 210 100 211 /** PCI bus driver standard operations */ 101 212 static driver_ops_t pci_ops = { 102 .add_device = &pci_add_device 213 .add_device = &pci_add_device, 214 .fun_online = &pci_fun_online, 215 .fun_offline = &pci_fun_offline, 103 216 }; 104 217 … … 109 222 }; 110 223 111 static pci_bus_t *pci_bus_new(void)112 {113 pci_bus_t *bus;114 115 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t));116 if (bus == NULL)117 return NULL;118 119 fibril_mutex_initialize(&bus->conf_mutex);120 return bus;121 }122 123 static void pci_bus_delete(pci_bus_t *bus)124 {125 assert(bus != NULL);126 free(bus);127 }128 129 224 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 130 225 { … … 133 228 fibril_mutex_lock(&bus->conf_mutex); 134 229 135 uint32_t conf_addr; 136 conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 230 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 137 231 void *addr = bus->conf_data_port + (reg & 3); 138 232 … … 219 313 void pci_fun_create_match_ids(pci_fun_t *fun) 220 314 { 221 char *match_id_str;222 315 int rc; 223 224 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 316 char match_id_str[ID_MAX_STR_LEN]; 317 318 /* Vendor ID & Device ID, length(incl \0) 22 */ 319 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/ven=%04x&dev=%04x", 225 320 fun->vendor_id, fun->device_id); 226 227 if (match_id_str == NULL) { 228 ddf_msg(LVL_ERROR, "Out of memory creating match ID."); 229 return; 321 if (rc < 0) { 322 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 323 str_error(rc)); 230 324 } 231 325 232 326 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 233 327 if (rc != EOK) { 234 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", 328 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 329 } 330 331 /* Class, subclass, prog IF, revision, length(incl \0) 47 */ 332 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 333 "pci/class=%02x&subclass=%02x&progif=%02x&revision=%02x", 334 fun->class_code, fun->subclass_code, fun->prog_if, fun->revision); 335 if (rc < 0) { 336 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 235 337 str_error(rc)); 236 338 } 237 238 /* TODO add more ids (with subsys ids, using class id etc.) */ 339 340 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 70); 341 if (rc != EOK) { 342 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 343 } 344 345 /* Class, subclass, prog IF, length(incl \0) 35 */ 346 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 347 "pci/class=%02x&subclass=%02x&progif=%02x", 348 fun->class_code, fun->subclass_code, fun->prog_if); 349 if (rc < 0) { 350 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 351 str_error(rc)); 352 } 353 354 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 60); 355 if (rc != EOK) { 356 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 357 } 358 359 /* Class, subclass, length(incl \0) 25 */ 360 rc = snprintf(match_id_str, ID_MAX_STR_LEN, 361 "pci/class=%02x&subclass=%02x", 362 fun->class_code, fun->subclass_code); 363 if (rc < 0) { 364 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 365 str_error(rc)); 366 } 367 368 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 50); 369 if (rc != EOK) { 370 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 371 } 372 373 /* Class, length(incl \0) 13 */ 374 rc = snprintf(match_id_str, ID_MAX_STR_LEN, "pci/class=%02x", 375 fun->class_code); 376 if (rc < 0) { 377 ddf_msg(LVL_ERROR, "Failed creating match ID str: %s", 378 str_error(rc)); 379 } 380 381 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 40); 382 if (rc != EOK) { 383 ddf_msg(LVL_ERROR, "Failed adding match ID: %s", str_error(rc)); 384 } 385 386 /* TODO add subsys ids, but those exist only in header type 0 */ 239 387 } 240 388 … … 288 436 /* Get the value of the BAR. */ 289 437 val = pci_conf_read_32(fun, addr); 438 439 #define IO_MASK (~0x3) 440 #define MEM_MASK (~0xf) 290 441 291 442 io = (bool) (val & 1); 292 443 if (io) { 293 444 addrw64 = false; 445 mask = IO_MASK; 294 446 } else { 447 mask = MEM_MASK; 295 448 switch ((val >> 1) & 3) { 296 449 case 0: … … 308 461 /* Get the address mask. */ 309 462 pci_conf_write_32(fun, addr, 0xffffffff); 310 mask = pci_conf_read_32(fun, addr);463 mask &= pci_conf_read_32(fun, addr); 311 464 312 465 /* Restore the original value. */ … … 382 535 for (fnum = 0; multi && fnum < 8; fnum++) { 383 536 pci_fun_init(fun, bus_num, dnum, fnum); 384 fun->vendor_id = pci_conf_read_16(fun,385 PCI_VENDOR_ID);386 fun->device_id = pci_conf_read_16(fun,387 PCI_DEVICE_ID);388 537 if (fun->vendor_id == 0xffff) { 389 538 /* … … 412 561 413 562 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 563 free(fun_name); 414 564 if (fnode == NULL) { 415 565 ddf_msg(LVL_ERROR, "Failed creating function."); … … 417 567 } 418 568 419 free(fun_name);420 569 fun->fnode = fnode; 421 570 … … 469 618 470 619 ddf_msg(LVL_DEBUG, "pci_add_device"); 471 dnode->parent_ phone = -1;472 473 bus = pci_bus_new();620 dnode->parent_sess = NULL; 621 622 bus = ddf_dev_data_alloc(dnode, sizeof(pci_bus_t)); 474 623 if (bus == NULL) { 475 624 ddf_msg(LVL_ERROR, "pci_add_device allocation failed."); … … 477 626 goto fail; 478 627 } 628 fibril_mutex_initialize(&bus->conf_mutex); 629 479 630 bus->dnode = dnode; 480 631 dnode->driver_data = bus; 481 632 482 dnode->parent_ phone = devman_parent_device_connect(dnode->handle,483 IPC_FLAG_BLOCKING);484 if ( dnode->parent_phone < 0) {633 dnode->parent_sess = devman_parent_device_connect(EXCHANGE_SERIALIZE, 634 dnode->handle, IPC_FLAG_BLOCKING); 635 if (!dnode->parent_sess) { 485 636 ddf_msg(LVL_ERROR, "pci_add_device failed to connect to the " 486 "parent 'sdriver.");487 rc = dnode->parent_phone;637 "parent driver."); 638 rc = ENOENT; 488 639 goto fail; 489 640 } … … 491 642 hw_resource_list_t hw_resources; 492 643 493 rc = hw_res_get_resource_list(dnode->parent_ phone, &hw_resources);644 rc = hw_res_get_resource_list(dnode->parent_sess, &hw_resources); 494 645 if (rc != EOK) { 495 646 ddf_msg(LVL_ERROR, "pci_add_device failed to get hw resources " … … 542 693 543 694 fail: 544 if (bus != NULL) 545 pci_bus_delete(bus); 546 if (dnode->parent_phone >= 0) 547 async_hangup(dnode->parent_phone); 695 if (dnode->parent_sess) 696 async_hangup(dnode->parent_sess); 697 548 698 if (got_res) 549 699 hw_res_clean_resource_list(&hw_resources); 700 550 701 if (ctl != NULL) 551 702 ddf_fun_destroy(ctl); 552 703 553 704 return rc; 705 } 706 707 static int pci_fun_online(ddf_fun_t *fun) 708 { 709 ddf_msg(LVL_DEBUG, "pci_fun_online()"); 710 return ddf_fun_online(fun); 711 } 712 713 static int pci_fun_offline(ddf_fun_t *fun) 714 { 715 ddf_msg(LVL_DEBUG, "pci_fun_offline()"); 716 return ddf_fun_offline(fun); 554 717 } 555 718 … … 558 721 ddf_log_init(NAME, LVL_ERROR); 559 722 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 723 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 560 724 } 561 725 … … 577 741 fun->dev = dev; 578 742 fun->fn = fn; 743 fun->vendor_id = pci_conf_read_16(fun, PCI_VENDOR_ID); 744 fun->device_id = pci_conf_read_16(fun, PCI_DEVICE_ID); 745 fun->class_code = pci_conf_read_8(fun, PCI_BASE_CLASS); 746 fun->subclass_code = pci_conf_read_8(fun, PCI_SUB_CLASS); 747 fun->prog_if = pci_conf_read_8(fun, PCI_PROG_IF); 748 fun->revision = pci_conf_read_8(fun, PCI_REVISION_ID); 579 749 } 580 750 … … 597 767 bool pci_alloc_resource_list(pci_fun_t *fun) 598 768 { 599 fun->hw_resources.resources = 600 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 601 return fun->hw_resources.resources != NULL; 769 fun->hw_resources.resources = fun->resources; 770 return true; 602 771 } 603 772 604 773 void pci_clean_resource_list(pci_fun_t *fun) 605 774 { 606 if (fun->hw_resources.resources != NULL) { 607 free(fun->hw_resources.resources); 608 fun->hw_resources.resources = NULL; 609 } 775 fun->hw_resources.resources = NULL; 610 776 } 611 777 … … 629 795 size_t pci_bar_mask_to_size(uint32_t mask) 630 796 { 631 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 797 size_t size = mask & ~(mask - 1); 798 return size; 632 799 } 633 800
Note:
See TracChangeset
for help on using the changeset viewer.
