Changes in uspace/drv/pciintel/pci.c [ad6857c:41b56084] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/pciintel/pci.c
rad6857c r41b56084 1 1 /* 2 2 * Copyright (c) 2010 Lenka Trochtova 3 * Copyright (c) 2011 Jiri Svoboda4 3 * All rights reserved. 5 4 * … … 45 44 #include <ctype.h> 46 45 #include <macros.h> 47 #include <str_error.h> 48 49 #include <ddf/driver.h> 46 47 #include <driver.h> 50 48 #include <devman.h> 51 49 #include <ipc/devman.h> 52 50 #include <ipc/dev_iface.h> 53 #include <ipc/irc.h>54 #include <ipc/ns.h>55 #include <ipc/services.h>56 #include <sysinfo.h>57 51 #include <ops/hw_res.h> 58 52 #include <device/hw_res.h> … … 67 61 ((1 << 31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3)) 68 62 69 /** Obtain PCI function soft-state from DDF function node */ 70 #define PCI_FUN(fnode) ((pci_fun_t *) (fnode)->driver_data) 71 72 /** Obtain PCI bus soft-state from DDF device node */ 73 #define PCI_BUS(dnode) ((pci_bus_t *) (dnode)->driver_data) 74 75 /** Obtain PCI bus soft-state from function soft-state */ 76 #define PCI_BUS_FROM_FUN(fun) ((fun)->busptr) 77 78 static hw_resource_list_t *pciintel_get_resources(ddf_fun_t *fnode) 79 { 80 pci_fun_t *fun = PCI_FUN(fnode); 81 82 if (fun == NULL) 63 static hw_resource_list_t *pciintel_get_child_resources(device_t *dev) 64 { 65 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 66 67 if (dev_data == NULL) 83 68 return NULL; 84 return &fun->hw_resources; 85 } 86 87 static bool pciintel_enable_interrupt(ddf_fun_t *fnode) 88 { 89 /* This is an old ugly way, copied from ne2000 driver */ 90 assert(fnode); 91 pci_fun_t *dev_data = (pci_fun_t *) fnode->driver_data; 92 93 sysarg_t apic; 94 sysarg_t i8259; 95 int irc_phone = -1; 96 int irc_service = 0; 97 98 if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) { 99 irc_service = SERVICE_APIC; 100 } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) { 101 irc_service = SERVICE_I8259; 102 } 103 104 if (irc_service) { 105 while (irc_phone < 0) 106 irc_phone = service_connect_blocking(irc_service, 0, 0); 107 } else { 108 return false; 109 } 110 111 size_t i; 112 for (i = 0; i < dev_data->hw_resources.count; i++) { 113 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 114 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; 115 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq); 116 } 117 } 118 119 async_hangup(irc_phone); 120 return true; 121 } 122 123 static hw_res_ops_t pciintel_hw_res_ops = { 124 &pciintel_get_resources, 125 &pciintel_enable_interrupt 69 return &dev_data->hw_resources; 70 } 71 72 static bool pciintel_enable_child_interrupt(device_t *dev) 73 { 74 /* TODO */ 75 76 return false; 77 } 78 79 static hw_res_ops_t pciintel_child_hw_res_ops = { 80 &pciintel_get_child_resources, 81 &pciintel_enable_child_interrupt 126 82 }; 127 83 128 static d df_dev_ops_t pci_fun_ops;129 130 static int pci_add_device(d df_dev_t *);131 132 /** PCI bus driver standard operations*/84 static device_ops_t pci_child_ops; 85 86 static int pci_add_device(device_t *); 87 88 /** The pci bus driver's standard operations. */ 133 89 static driver_ops_t pci_ops = { 134 90 .add_device = &pci_add_device 135 91 }; 136 92 137 /** PCI bus driver structure*/93 /** The pci bus driver structure. */ 138 94 static driver_t pci_driver = { 139 95 .name = NAME, … … 141 97 }; 142 98 143 static pci_bus_t *pci_bus_new(void) 144 { 145 pci_bus_t *bus; 146 147 bus = (pci_bus_t *) calloc(1, sizeof(pci_bus_t)); 148 if (bus == NULL) 149 return NULL; 150 151 fibril_mutex_initialize(&bus->conf_mutex); 152 return bus; 153 } 154 155 static void pci_bus_delete(pci_bus_t *bus) 156 { 157 assert(bus != NULL); 158 free(bus); 159 } 160 161 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 162 { 163 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 164 165 fibril_mutex_lock(&bus->conf_mutex); 99 typedef struct pciintel_bus_data { 100 uint32_t conf_io_addr; 101 void *conf_data_port; 102 void *conf_addr_port; 103 fibril_mutex_t conf_mutex; 104 } pci_bus_data_t; 105 106 static pci_bus_data_t *create_pci_bus_data(void) 107 { 108 pci_bus_data_t *bus_data; 109 110 bus_data = (pci_bus_data_t *) malloc(sizeof(pci_bus_data_t)); 111 if (bus_data != NULL) { 112 memset(bus_data, 0, sizeof(pci_bus_data_t)); 113 fibril_mutex_initialize(&bus_data->conf_mutex); 114 } 115 116 return bus_data; 117 } 118 119 static void delete_pci_bus_data(pci_bus_data_t *bus_data) 120 { 121 free(bus_data); 122 } 123 124 static void pci_conf_read(device_t *dev, int reg, uint8_t *buf, size_t len) 125 { 126 assert(dev->parent != NULL); 127 128 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 129 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 130 131 fibril_mutex_lock(&bus_data->conf_mutex); 166 132 167 133 uint32_t conf_addr; 168 conf_addr = CONF_ADDR( fun->bus, fun->dev, fun->fn, reg);169 void *addr = bus ->conf_data_port + (reg & 3);170 171 pio_write_32(bus ->conf_addr_port, conf_addr);134 conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg); 135 void *addr = bus_data->conf_data_port + (reg & 3); 136 137 pio_write_32(bus_data->conf_addr_port, conf_addr); 172 138 173 139 switch (len) { … … 183 149 } 184 150 185 fibril_mutex_unlock(&bus->conf_mutex); 186 } 187 188 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 189 { 190 pci_bus_t *bus = PCI_BUS_FROM_FUN(fun); 191 192 fibril_mutex_lock(&bus->conf_mutex); 151 fibril_mutex_unlock(&bus_data->conf_mutex); 152 } 153 154 static void pci_conf_write(device_t *dev, int reg, uint8_t *buf, size_t len) 155 { 156 assert(dev->parent != NULL); 157 158 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 159 pci_bus_data_t *bus_data = (pci_bus_data_t *) dev->parent->driver_data; 160 161 fibril_mutex_lock(&bus_data->conf_mutex); 193 162 194 163 uint32_t conf_addr; 195 conf_addr = CONF_ADDR( fun->bus, fun->dev, fun->fn, reg);196 void *addr = bus ->conf_data_port + (reg & 3);197 198 pio_write_32(bus ->conf_addr_port, conf_addr);164 conf_addr = CONF_ADDR(dev_data->bus, dev_data->dev, dev_data->fn, reg); 165 void *addr = bus_data->conf_data_port + (reg & 3); 166 167 pio_write_32(bus_data->conf_addr_port, conf_addr); 199 168 200 169 switch (len) { … … 210 179 } 211 180 212 fibril_mutex_unlock(&bus ->conf_mutex);213 } 214 215 uint8_t pci_conf_read_8( pci_fun_t *fun, int reg)181 fibril_mutex_unlock(&bus_data->conf_mutex); 182 } 183 184 uint8_t pci_conf_read_8(device_t *dev, int reg) 216 185 { 217 186 uint8_t res; 218 pci_conf_read( fun, reg, &res, 1);187 pci_conf_read(dev, reg, &res, 1); 219 188 return res; 220 189 } 221 190 222 uint16_t pci_conf_read_16( pci_fun_t *fun, int reg)191 uint16_t pci_conf_read_16(device_t *dev, int reg) 223 192 { 224 193 uint16_t res; 225 pci_conf_read( fun, reg, (uint8_t *) &res, 2);194 pci_conf_read(dev, reg, (uint8_t *) &res, 2); 226 195 return res; 227 196 } 228 197 229 uint32_t pci_conf_read_32( pci_fun_t *fun, int reg)198 uint32_t pci_conf_read_32(device_t *dev, int reg) 230 199 { 231 200 uint32_t res; 232 pci_conf_read( fun, reg, (uint8_t *) &res, 4);201 pci_conf_read(dev, reg, (uint8_t *) &res, 4); 233 202 return res; 234 203 } 235 204 236 void pci_conf_write_8(pci_fun_t *fun, int reg, uint8_t val) 237 { 238 pci_conf_write(fun, reg, (uint8_t *) &val, 1); 239 } 240 241 void pci_conf_write_16(pci_fun_t *fun, int reg, uint16_t val) 242 { 243 pci_conf_write(fun, reg, (uint8_t *) &val, 2); 244 } 245 246 void pci_conf_write_32(pci_fun_t *fun, int reg, uint32_t val) 247 { 248 pci_conf_write(fun, reg, (uint8_t *) &val, 4); 249 } 250 251 void pci_fun_create_match_ids(pci_fun_t *fun) 252 { 205 void pci_conf_write_8(device_t *dev, int reg, uint8_t val) 206 { 207 pci_conf_write(dev, reg, (uint8_t *) &val, 1); 208 } 209 210 void pci_conf_write_16(device_t *dev, int reg, uint16_t val) 211 { 212 pci_conf_write(dev, reg, (uint8_t *) &val, 2); 213 } 214 215 void pci_conf_write_32(device_t *dev, int reg, uint32_t val) 216 { 217 pci_conf_write(dev, reg, (uint8_t *) &val, 4); 218 } 219 220 void create_pci_match_ids(device_t *dev) 221 { 222 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 223 match_id_t *match_id = NULL; 253 224 char *match_id_str; 254 int rc; 255 256 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 257 fun->vendor_id, fun->device_id); 258 259 if (match_id_str == NULL) { 260 printf(NAME ": out of memory creating match ID.\n"); 261 return; 262 } 263 264 rc = ddf_fun_add_match_id(fun->fnode, match_id_str, 90); 265 if (rc != EOK) { 266 printf(NAME ": error adding match ID: %s\n", 267 str_error(rc)); 268 } 269 225 226 match_id = create_match_id(); 227 if (match_id != NULL) { 228 asprintf(&match_id_str, "pci/ven=%04x&dev=%04x", 229 dev_data->vendor_id, dev_data->device_id); 230 match_id->id = match_id_str; 231 match_id->score = 90; 232 add_match_id(&dev->match_ids, match_id); 233 } 234 270 235 /* TODO add more ids (with subsys ids, using class id etc.) */ 271 236 } 272 237 273 void pci_add_range(pci_fun_t *fun, uint64_t range_addr, size_t range_size, 274 bool io) 275 { 276 hw_resource_list_t *hw_res_list = &fun->hw_resources; 238 void 239 pci_add_range(device_t *dev, uint64_t range_addr, size_t range_size, bool io) 240 { 241 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 242 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 277 243 hw_resource_t *hw_resources = hw_res_list->resources; 278 244 size_t count = hw_res_list->count; … … 299 265 * address add it to the devices hw resource list. 300 266 * 301 * @param fun PCI function267 * @param dev The pci device. 302 268 * @param addr The address of the BAR in the PCI configuration address space of 303 * the device 304 * @return The addr the address of the BAR which should be read next 269 * the device. 270 * @return The addr the address of the BAR which should be read next. 305 271 */ 306 int pci_read_bar( pci_fun_t *fun, int addr)307 { 272 int pci_read_bar(device_t *dev, int addr) 273 { 308 274 /* Value of the BAR */ 309 275 uint32_t val, mask; … … 319 285 320 286 /* Get the value of the BAR. */ 321 val = pci_conf_read_32(fun, addr); 322 323 #define IO_MASK (~0x3) 324 #define MEM_MASK (~0xf) 287 val = pci_conf_read_32(dev, addr); 325 288 326 289 io = (bool) (val & 1); 327 290 if (io) { 328 291 addrw64 = false; 329 mask = IO_MASK;330 292 } else { 331 mask = MEM_MASK;332 293 switch ((val >> 1) & 3) { 333 294 case 0: … … 344 305 345 306 /* Get the address mask. */ 346 pci_conf_write_32( fun, addr, 0xffffffff);347 mask &= pci_conf_read_32(fun, addr);307 pci_conf_write_32(dev, addr, 0xffffffff); 308 mask = pci_conf_read_32(dev, addr); 348 309 349 310 /* Restore the original value. */ 350 pci_conf_write_32( fun, addr, val);351 val = pci_conf_read_32( fun, addr);311 pci_conf_write_32(dev, addr, val); 312 val = pci_conf_read_32(dev, addr); 352 313 353 314 range_size = pci_bar_mask_to_size(mask); 354 315 355 316 if (addrw64) { 356 range_addr = ((uint64_t)pci_conf_read_32( fun, addr + 4) << 32) |317 range_addr = ((uint64_t)pci_conf_read_32(dev, addr + 4) << 32) | 357 318 (val & 0xfffffff0); 358 319 } else { … … 361 322 362 323 if (range_addr != 0) { 363 printf(NAME ": function %s : ", fun->fnode->name);324 printf(NAME ": device %s : ", dev->name); 364 325 printf("address = %" PRIx64, range_addr); 365 326 printf(", size = %x\n", (unsigned int) range_size); 366 327 } 367 328 368 pci_add_range( fun, range_addr, range_size, io);329 pci_add_range(dev, range_addr, range_size, io); 369 330 370 331 if (addrw64) … … 374 335 } 375 336 376 void pci_add_interrupt(pci_fun_t *fun, int irq) 377 { 378 hw_resource_list_t *hw_res_list = &fun->hw_resources; 337 void pci_add_interrupt(device_t *dev, int irq) 338 { 339 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 340 hw_resource_list_t *hw_res_list = &dev_data->hw_resources; 379 341 hw_resource_t *hw_resources = hw_res_list->resources; 380 342 size_t count = hw_res_list->count; … … 388 350 hw_res_list->count++; 389 351 390 printf(NAME ": function %s uses irq %x.\n", fun->fnode->name, irq);391 } 392 393 void pci_read_interrupt( pci_fun_t *fun)394 { 395 uint8_t irq = pci_conf_read_8( fun, PCI_BRIDGE_INT_LINE);352 printf(NAME ": device %s uses irq %x.\n", dev->name, irq); 353 } 354 355 void pci_read_interrupt(device_t *dev) 356 { 357 uint8_t irq = pci_conf_read_8(dev, PCI_BRIDGE_INT_LINE); 396 358 if (irq != 0xff) 397 pci_add_interrupt( fun, irq);359 pci_add_interrupt(dev, irq); 398 360 } 399 361 400 362 /** Enumerate (recursively) and register the devices connected to a pci bus. 401 363 * 402 * @param bus Host-to-PCI bridge403 * @param bus_num Bus number364 * @param parent The host-to-pci bridge device. 365 * @param bus_num The bus number. 404 366 */ 405 void pci_bus_scan(pci_bus_t *bus, int bus_num) 406 { 407 ddf_fun_t *fnode; 408 pci_fun_t *fun; 367 void pci_bus_scan(device_t *parent, int bus_num) 368 { 369 device_t *dev = create_device(); 370 pci_dev_data_t *dev_data = create_pci_dev_data(); 371 dev->driver_data = dev_data; 372 dev->parent = parent; 409 373 410 374 int child_bus = 0; 411 375 int dnum, fnum; 412 376 bool multi; 413 uint8_t header_type; 414 415 fun = pci_fun_new(bus); 377 uint8_t header_type; 416 378 417 379 for (dnum = 0; dnum < 32; dnum++) { 418 380 multi = true; 419 381 for (fnum = 0; multi && fnum < 8; fnum++) { 420 pci_fun_init(fun, bus_num, dnum, fnum);421 fun->vendor_id = pci_conf_read_16(fun,382 init_pci_dev_data(dev_data, bus_num, dnum, fnum); 383 dev_data->vendor_id = pci_conf_read_16(dev, 422 384 PCI_VENDOR_ID); 423 fun->device_id = pci_conf_read_16(fun,385 dev_data->device_id = pci_conf_read_16(dev, 424 386 PCI_DEVICE_ID); 425 if ( fun->vendor_id == 0xffff) {387 if (dev_data->vendor_id == 0xffff) { 426 388 /* 427 389 * The device is not present, go on scanning the … … 434 396 } 435 397 436 header_type = pci_conf_read_8( fun, PCI_HEADER_TYPE);398 header_type = pci_conf_read_8(dev, PCI_HEADER_TYPE); 437 399 if (fnum == 0) { 438 400 /* Is the device multifunction? */ … … 442 404 header_type = header_type & 0x7F; 443 405 444 char *fun_name = pci_fun_create_name(fun); 445 if (fun_name == NULL) { 446 printf(NAME ": out of memory.\n"); 447 return; 448 } 449 450 fnode = ddf_fun_create(bus->dnode, fun_inner, fun_name); 451 if (fnode == NULL) { 452 printf(NAME ": error creating function.\n"); 453 return; 454 } 455 456 free(fun_name); 457 fun->fnode = fnode; 458 459 pci_alloc_resource_list(fun); 460 pci_read_bars(fun); 461 pci_read_interrupt(fun); 462 463 fnode->ops = &pci_fun_ops; 464 fnode->driver_data = fun; 465 466 printf(NAME ": adding new function %s.\n", 467 fnode->name); 468 469 pci_fun_create_match_ids(fun); 470 471 if (ddf_fun_bind(fnode) != EOK) { 472 pci_clean_resource_list(fun); 473 clean_match_ids(&fnode->match_ids); 474 free((char *) fnode->name); 475 fnode->name = NULL; 406 create_pci_dev_name(dev); 407 408 pci_alloc_resource_list(dev); 409 pci_read_bars(dev); 410 pci_read_interrupt(dev); 411 412 dev->ops = &pci_child_ops; 413 414 printf(NAME ": adding new child device %s.\n", 415 dev->name); 416 417 create_pci_match_ids(dev); 418 419 if (child_device_register(dev, parent) != EOK) { 420 pci_clean_resource_list(dev); 421 clean_match_ids(&dev->match_ids); 422 free((char *) dev->name); 423 dev->name = NULL; 476 424 continue; 477 425 } … … 479 427 if (header_type == PCI_HEADER_TYPE_BRIDGE || 480 428 header_type == PCI_HEADER_TYPE_CARDBUS) { 481 child_bus = pci_conf_read_8( fun,429 child_bus = pci_conf_read_8(dev, 482 430 PCI_BRIDGE_SEC_BUS_NUM); 483 431 printf(NAME ": device is pci-to-pci bridge, " 484 432 "secondary bus number = %d.\n", bus_num); 485 433 if (child_bus > bus_num) 486 pci_bus_scan( bus, child_bus);434 pci_bus_scan(parent, child_bus); 487 435 } 488 436 489 fun = pci_fun_new(bus); 437 /* Alloc new aux. dev. structure. */ 438 dev = create_device(); 439 dev_data = create_pci_dev_data(); 440 dev->driver_data = dev_data; 441 dev->parent = parent; 490 442 } 491 443 } 492 444 493 if (fun->vendor_id == 0xffff) { 494 /* Free the auxiliary function structure. */ 495 pci_fun_delete(fun); 496 } 497 } 498 499 static int pci_add_device(ddf_dev_t *dnode) 500 { 501 pci_bus_t *bus = NULL; 502 ddf_fun_t *ctl = NULL; 503 bool got_res = false; 445 if (dev_data->vendor_id == 0xffff) { 446 delete_device(dev); 447 /* Free the auxiliary device structure. */ 448 delete_pci_dev_data(dev_data); 449 } 450 } 451 452 static int pci_add_device(device_t *dev) 453 { 504 454 int rc; 505 455 506 456 printf(NAME ": pci_add_device\n"); 507 dnode->parent_phone = -1; 508 509 bus = pci_bus_new(); 510 if (bus == NULL) { 457 458 pci_bus_data_t *bus_data = create_pci_bus_data(); 459 if (bus_data == NULL) { 511 460 printf(NAME ": pci_add_device allocation failed.\n"); 512 rc = ENOMEM; 513 goto fail; 514 } 515 bus->dnode = dnode; 516 dnode->driver_data = bus; 517 518 dnode->parent_phone = devman_parent_device_connect(dnode->handle, 461 return ENOMEM; 462 } 463 464 dev->parent_phone = devman_parent_device_connect(dev->handle, 519 465 IPC_FLAG_BLOCKING); 520 if (d node->parent_phone < 0) {466 if (dev->parent_phone < 0) { 521 467 printf(NAME ": pci_add_device failed to connect to the " 522 468 "parent's driver.\n"); 523 rc = dnode->parent_phone;524 goto fail;469 delete_pci_bus_data(bus_data); 470 return dev->parent_phone; 525 471 } 526 472 527 473 hw_resource_list_t hw_resources; 528 474 529 rc = hw_res_get_resource_list(d node->parent_phone, &hw_resources);475 rc = hw_res_get_resource_list(dev->parent_phone, &hw_resources); 530 476 if (rc != EOK) { 531 477 printf(NAME ": pci_add_device failed to get hw resources for " 532 478 "the device.\n"); 533 goto fail; 534 } 535 got_res = true; 479 delete_pci_bus_data(bus_data); 480 ipc_hangup(dev->parent_phone); 481 return rc; 482 } 536 483 537 484 printf(NAME ": conf_addr = %" PRIx64 ".\n", … … 542 489 assert(hw_resources.resources[0].res.io_range.size == 8); 543 490 544 bus ->conf_io_addr =491 bus_data->conf_io_addr = 545 492 (uint32_t) hw_resources.resources[0].res.io_range.address; 546 493 547 if (pio_enable((void *)(uintptr_t)bus ->conf_io_addr, 8,548 &bus ->conf_addr_port)) {494 if (pio_enable((void *)(uintptr_t)bus_data->conf_io_addr, 8, 495 &bus_data->conf_addr_port)) { 549 496 printf(NAME ": failed to enable configuration ports.\n"); 550 rc = EADDRNOTAVAIL; 551 goto fail; 552 } 553 bus->conf_data_port = (char *) bus->conf_addr_port + 4; 554 555 /* Make the bus device more visible. It has no use yet. */ 556 printf(NAME ": adding a 'ctl' function\n"); 557 558 ctl = ddf_fun_create(bus->dnode, fun_exposed, "ctl"); 559 if (ctl == NULL) { 560 printf(NAME ": error creating control function.\n"); 561 rc = ENOMEM; 562 goto fail; 563 } 564 565 rc = ddf_fun_bind(ctl); 566 if (rc != EOK) { 567 printf(NAME ": error binding control function.\n"); 568 goto fail; 569 } 570 571 /* Enumerate functions. */ 497 delete_pci_bus_data(bus_data); 498 ipc_hangup(dev->parent_phone); 499 hw_res_clean_resource_list(&hw_resources); 500 return EADDRNOTAVAIL; 501 } 502 bus_data->conf_data_port = (char *) bus_data->conf_addr_port + 4; 503 504 dev->driver_data = bus_data; 505 506 /* Enumerate child devices. */ 572 507 printf(NAME ": scanning the bus\n"); 573 pci_bus_scan( bus, 0);508 pci_bus_scan(dev, 0); 574 509 575 510 hw_res_clean_resource_list(&hw_resources); 576 511 577 512 return EOK; 578 579 fail:580 if (bus != NULL)581 pci_bus_delete(bus);582 if (dnode->parent_phone >= 0)583 async_hangup(dnode->parent_phone);584 if (got_res)585 hw_res_clean_resource_list(&hw_resources);586 if (ctl != NULL)587 ddf_fun_destroy(ctl);588 589 return rc;590 513 } 591 514 592 515 static void pciintel_init(void) 593 516 { 594 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 595 } 596 597 pci_fun_t *pci_fun_new(pci_bus_t *bus) 598 { 599 pci_fun_t *fun; 600 601 fun = (pci_fun_t *) calloc(1, sizeof(pci_fun_t)); 602 if (fun == NULL) 603 return NULL; 604 605 fun->busptr = bus; 606 return fun; 607 } 608 609 void pci_fun_init(pci_fun_t *fun, int bus, int dev, int fn) 610 { 611 fun->bus = bus; 612 fun->dev = dev; 613 fun->fn = fn; 614 } 615 616 void pci_fun_delete(pci_fun_t *fun) 617 { 618 assert(fun != NULL); 619 hw_res_clean_resource_list(&fun->hw_resources); 620 free(fun); 621 } 622 623 char *pci_fun_create_name(pci_fun_t *fun) 624 { 517 pci_child_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_child_hw_res_ops; 518 } 519 520 pci_dev_data_t *create_pci_dev_data(void) 521 { 522 pci_dev_data_t *res = (pci_dev_data_t *) malloc(sizeof(pci_dev_data_t)); 523 524 if (res != NULL) 525 memset(res, 0, sizeof(pci_dev_data_t)); 526 return res; 527 } 528 529 void init_pci_dev_data(pci_dev_data_t *dev_data, int bus, int dev, int fn) 530 { 531 dev_data->bus = bus; 532 dev_data->dev = dev; 533 dev_data->fn = fn; 534 } 535 536 void delete_pci_dev_data(pci_dev_data_t *dev_data) 537 { 538 if (dev_data != NULL) { 539 hw_res_clean_resource_list(&dev_data->hw_resources); 540 free(dev_data); 541 } 542 } 543 544 void create_pci_dev_name(device_t *dev) 545 { 546 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 625 547 char *name = NULL; 626 548 627 asprintf(&name, "%02x:%02x.%01x", fun->bus, fun->dev, 628 fun->fn); 629 return name; 630 } 631 632 bool pci_alloc_resource_list(pci_fun_t *fun) 633 { 634 fun->hw_resources.resources = 549 asprintf(&name, "%02x:%02x.%01x", dev_data->bus, dev_data->dev, 550 dev_data->fn); 551 dev->name = name; 552 } 553 554 bool pci_alloc_resource_list(device_t *dev) 555 { 556 pci_dev_data_t *dev_data = (pci_dev_data_t *)dev->driver_data; 557 558 dev_data->hw_resources.resources = 635 559 (hw_resource_t *) malloc(PCI_MAX_HW_RES * sizeof(hw_resource_t)); 636 return fun->hw_resources.resources != NULL; 637 } 638 639 void pci_clean_resource_list(pci_fun_t *fun) 640 { 641 if (fun->hw_resources.resources != NULL) { 642 free(fun->hw_resources.resources); 643 fun->hw_resources.resources = NULL; 644 } 645 } 646 647 /** Read the base address registers (BARs) of the function and add the addresses 648 * to its HW resource list. 560 return dev_data->hw_resources.resources != NULL; 561 } 562 563 void pci_clean_resource_list(device_t *dev) 564 { 565 pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data; 566 567 if (dev_data->hw_resources.resources != NULL) { 568 free(dev_data->hw_resources.resources); 569 dev_data->hw_resources.resources = NULL; 570 } 571 } 572 573 /** Read the base address registers (BARs) of the device and adds the addresses 574 * to its hw resource list. 649 575 * 650 * @param fun PCI function576 * @param dev the pci device. 651 577 */ 652 void pci_read_bars( pci_fun_t *fun)578 void pci_read_bars(device_t *dev) 653 579 { 654 580 /* … … 659 585 660 586 while (addr <= PCI_BASE_ADDR_5) 661 addr = pci_read_bar( fun, addr);587 addr = pci_read_bar(dev, addr); 662 588 } 663 589 664 590 size_t pci_bar_mask_to_size(uint32_t mask) 665 591 { 666 size_t size = mask & ~(mask - 1); 667 return size; 592 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 668 593 } 669 594 … … 672 597 printf(NAME ": HelenOS pci bus driver (intel method 1).\n"); 673 598 pciintel_init(); 674 return d df_driver_main(&pci_driver);599 return driver_main(&pci_driver); 675 600 } 676 601
Note:
See TracChangeset
for help on using the changeset viewer.