Changes in uspace/drv/bus/pci/pciintel/pci.c [6dbc500:c90aed4] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/pci/pciintel/pci.c
r6dbc500 rc90aed4 57 57 #include <ops/hw_res.h> 58 58 #include <device/hw_res.h> 59 #include <ops/pio_window.h>60 #include <device/pio_window.h>61 59 #include <ddi.h> 62 60 #include <pci_dev_iface.h> … … 143 141 } 144 142 145 static pio_window_t *pciintel_get_pio_window(ddf_fun_t *fnode)146 {147 pci_fun_t *fun = pci_fun(fnode);148 149 if (fun == NULL)150 return NULL;151 return &fun->pio_window;152 }153 154 155 143 static int pci_config_space_write_32(ddf_fun_t *fun, uint32_t address, 156 144 uint32_t data) … … 210 198 .get_resource_list = &pciintel_get_resources, 211 199 .enable_interrupt = &pciintel_enable_interrupt, 212 };213 214 static pio_window_ops_t pciintel_pio_window_ops = {215 .get_pio_window = &pciintel_get_pio_window216 200 }; 217 201 … … 227 211 static ddf_dev_ops_t pci_fun_ops = { 228 212 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 229 .interfaces[PIO_WINDOW_DEV_IFACE] = &pciintel_pio_window_ops,230 213 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 231 214 }; … … 250 233 static void pci_conf_read(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 251 234 { 235 pci_bus_t *bus = pci_bus_from_fun(fun); 236 237 fibril_mutex_lock(&bus->conf_mutex); 238 252 239 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 253 pci_bus_t *bus = pci_bus_from_fun(fun); 254 uint32_t val; 255 256 fibril_mutex_lock(&bus->conf_mutex); 257 240 void *addr = bus->conf_data_port + (reg & 3); 241 258 242 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 259 260 /* 261 * Always read full 32-bits from the PCI conf_data_port register and 262 * get the desired portion of it afterwards. Some architectures do not 263 * support shorter PIO reads offset from this register. 264 */ 265 val = uint32_t_le2host(pio_read_32(bus->conf_data_port)); 266 243 267 244 switch (len) { 268 245 case 1: 269 *buf = (uint8_t) (val >> ((reg & 3) * 8)); 246 /* No endianness change for 1 byte */ 247 buf[0] = pio_read_8(addr); 270 248 break; 271 249 case 2: 272 *((uint16_t *) buf) = (uint16_t) (val >> ((reg & 3)) * 8);250 ((uint16_t *) buf)[0] = uint16_t_le2host(pio_read_16(addr)); 273 251 break; 274 252 case 4: 275 *((uint32_t *) buf) = (uint32_t) val;253 ((uint32_t *) buf)[0] = uint32_t_le2host(pio_read_32(addr)); 276 254 break; 277 255 } … … 282 260 static void pci_conf_write(pci_fun_t *fun, int reg, uint8_t *buf, size_t len) 283 261 { 262 pci_bus_t *bus = pci_bus_from_fun(fun); 263 264 fibril_mutex_lock(&bus->conf_mutex); 265 284 266 const uint32_t conf_addr = CONF_ADDR(fun->bus, fun->dev, fun->fn, reg); 285 pci_bus_t *bus = pci_bus_from_fun(fun); 286 uint32_t val; 287 288 fibril_mutex_lock(&bus->conf_mutex); 289 290 /* 291 * Prepare to write full 32-bits to the PCI conf_data_port register. 292 * Some architectures do not support shorter PIO writes offset from this 293 * register. 294 */ 295 296 if (len < 4) { 297 /* 298 * We have fewer than full 32-bits, so we need to read the 299 * missing bits first. 300 */ 301 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 302 val = uint32_t_le2host(pio_read_32(bus->conf_data_port)); 303 } 267 void *addr = bus->conf_data_port + (reg & 3); 268 269 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr)); 304 270 305 271 switch (len) { 306 272 case 1: 307 val &= ~(0xffU << ((reg & 3) * 8));308 val |= *buf << ((reg & 3) * 8);273 /* No endianness change for 1 byte */ 274 pio_write_8(addr, buf[0]); 309 275 break; 310 276 case 2: 311 val &= ~(0xffffU << ((reg & 3) * 8)); 312 val |= *((uint16_t *) buf) << ((reg & 3) * 8); 277 pio_write_16(addr, host2uint16_t_le(((uint16_t *) buf)[0])); 313 278 break; 314 279 case 4: 315 val = *((uint32_t *) buf);280 pio_write_32(addr, host2uint32_t_le(((uint32_t *) buf)[0])); 316 281 break; 317 282 } 318 319 pio_write_32(bus->conf_addr_port, host2uint32_t_le(conf_addr));320 pio_write_32(bus->conf_data_port, host2uint32_t_le(val));321 283 322 284 fibril_mutex_unlock(&bus->conf_mutex); … … 471 433 { 472 434 /* Value of the BAR */ 473 uint32_t val; 474 uint32_t bar; 475 uint32_t mask; 476 435 uint32_t val, mask; 477 436 /* IO space address */ 478 437 bool io; … … 512 471 /* Get the address mask. */ 513 472 pci_conf_write_32(fun, addr, 0xffffffff); 514 bar = pci_conf_read_32(fun, addr); 515 516 /* 517 * Unimplemented BARs read back as all 0's. 518 */ 519 if (!bar) 520 return addr + (addrw64 ? 8 : 4); 521 522 mask &= bar; 523 473 mask &= pci_conf_read_32(fun, addr); 474 524 475 /* Restore the original value. */ 525 476 pci_conf_write_32(fun, addr, val); … … 569 520 { 570 521 uint8_t irq = pci_conf_read_8(fun, PCI_BRIDGE_INT_LINE); 571 uint8_t pin = pci_conf_read_8(fun, PCI_BRIDGE_INT_PIN); 572 573 if (pin != 0 && irq != 0xff) 522 if (irq != 0xff) 574 523 pci_add_interrupt(fun, irq); 575 524 } … … 634 583 pci_read_bars(fun); 635 584 pci_read_interrupt(fun); 636 637 /* Propagate the PIO window to the function. */638 fun->pio_window = bus->pio_win;639 585 640 586 ddf_fun_set_ops(fun->fnode, &pci_fun_ops); … … 667 613 static int pci_dev_add(ddf_dev_t *dnode) 668 614 { 669 hw_resource_list_t hw_resources;670 615 pci_bus_t *bus = NULL; 671 616 ddf_fun_t *ctl = NULL; … … 693 638 goto fail; 694 639 } 695 696 rc = pio_window_get(sess, &bus->pio_win); 697 if (rc != EOK) { 698 ddf_msg(LVL_ERROR, "pci_dev_add failed to get PIO window " 699 "for the device."); 700 goto fail; 701 } 640 641 hw_resource_list_t hw_resources; 702 642 703 643 rc = hw_res_get_resource_list(sess, &hw_resources); … … 789 729 { 790 730 ddf_log_init(NAME); 731 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 732 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops; 791 733 } 792 734
Note:
See TracChangeset
for help on using the changeset viewer.