pci.c (ced8202c20f01f6cad37c7903cb713442b2709aa) | pci.c (7ba175ac230fa3957177fd7b7accfb6ffdcc7dd1) |
---|---|
1/* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 39 unchanged lines hidden (view full) --- 48#include <vm/vm_extern.h> 49 50#include <sys/bus.h> 51#include <machine/bus.h> 52#include <sys/rman.h> 53#include <machine/resource.h> 54 55#include <sys/pciio.h> | 1/* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 3 * Copyright (c) 2000, Michael Smith <msmith@freebsd.org> 4 * Copyright (c) 2000, BSDi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 39 unchanged lines hidden (view full) --- 48#include <vm/vm_extern.h> 49 50#include <sys/bus.h> 51#include <machine/bus.h> 52#include <sys/rman.h> 53#include <machine/resource.h> 54 55#include <sys/pciio.h> |
56#include <pci/pcireg.h> 57#include <pci/pcivar.h> | 56#include <dev/pci/pcireg.h> 57#include <dev/pci/pcivar.h> 58#include <dev/pci/pci_private.h> |
58 59#include "pcib_if.h" 60#include "pci_if.h" 61 62static u_int32_t pci_mapbase(unsigned mapreg); 63static int pci_maptype(unsigned mapreg); 64static int pci_mapsize(unsigned testval); 65static int pci_maprange(unsigned mapreg); 66static void pci_fixancient(pcicfgregs *cfg); 67static void pci_hdrtypedata(device_t pcib, int b, int s, int f, 68 pcicfgregs *cfg); | 59 60#include "pcib_if.h" 61#include "pci_if.h" 62 63static u_int32_t pci_mapbase(unsigned mapreg); 64static int pci_maptype(unsigned mapreg); 65static int pci_mapsize(unsigned testval); 66static int pci_maprange(unsigned mapreg); 67static void pci_fixancient(pcicfgregs *cfg); 68static void pci_hdrtypedata(device_t pcib, int b, int s, int f, 69 pcicfgregs *cfg); |
69static struct pci_devinfo *pci_read_device(device_t pcib, int b, int s, int f); | |
70static void pci_read_extcap(device_t pcib, pcicfgregs *cfg); 71 | 70static void pci_read_extcap(device_t pcib, pcicfgregs *cfg); 71 |
72static void pci_print_verbose(struct pci_devinfo *dinfo); | |
73static int pci_porten(device_t pcib, int b, int s, int f); 74static int pci_memen(device_t pcib, int b, int s, int f); 75static int pci_add_map(device_t pcib, int b, int s, int f, int reg, 76 struct resource_list *rl); 77static void pci_add_resources(device_t pcib, int b, int s, int f, 78 device_t dev); 79static void pci_add_children(device_t dev, int busno); 80static int pci_probe(device_t dev); | 72static int pci_porten(device_t pcib, int b, int s, int f); 73static int pci_memen(device_t pcib, int b, int s, int f); 74static int pci_add_map(device_t pcib, int b, int s, int f, int reg, 75 struct resource_list *rl); 76static void pci_add_resources(device_t pcib, int b, int s, int f, 77 device_t dev); 78static void pci_add_children(device_t dev, int busno); 79static int pci_probe(device_t dev); |
81static int pci_print_child(device_t dev, device_t child); 82static void pci_probe_nomatch(device_t dev, device_t child); | |
83static int pci_describe_parse_line(char **ptr, int *vendor, 84 int *device, char **desc); 85static char *pci_describe_device(device_t dev); | 80static int pci_describe_parse_line(char **ptr, int *vendor, 81 int *device, char **desc); 82static char *pci_describe_device(device_t dev); |
86static int pci_read_ivar(device_t dev, device_t child, int which, 87 uintptr_t *result); 88static int pci_write_ivar(device_t dev, device_t child, int which, 89 uintptr_t value); 90static struct resource *pci_alloc_resource(device_t dev, device_t child, 91 int type, int *rid, u_long start, 92 u_long end, u_long count, u_int flags); 93static void pci_delete_resource(device_t dev, device_t child, 94 int type, int rid); 95static struct resource_list *pci_get_resource_list (device_t dev, device_t child); 96static u_int32_t pci_read_config_method(device_t dev, device_t child, 97 int reg, int width); 98static void pci_write_config_method(device_t dev, device_t child, 99 int reg, u_int32_t val, int width); 100static void pci_enable_busmaster_method(device_t dev, 101 device_t child); 102static void pci_disable_busmaster_method(device_t dev, 103 device_t child); 104static void pci_enable_io_method(device_t dev, device_t child, 105 int space); 106static void pci_disable_io_method(device_t dev, device_t child, 107 int space); 108static int pci_set_powerstate_method(device_t dev, device_t child, 109 int state); 110static int pci_get_powerstate_method(device_t dev, device_t child); | |
111static int pci_modevent(module_t mod, int what, void *arg); 112 113static device_method_t pci_methods[] = { 114 /* Device interface */ 115 DEVMETHOD(device_probe, pci_probe), 116 DEVMETHOD(device_attach, bus_generic_attach), 117 DEVMETHOD(device_shutdown, bus_generic_shutdown), 118 DEVMETHOD(device_suspend, bus_generic_suspend), --- 213 unchanged lines hidden (view full) --- 332 cfg->nummaps = PCI_MAXMAPS_2; 333 break; 334 } 335#undef REG 336} 337 338/* read configuration header into pcicfgregs structure */ 339 | 83static int pci_modevent(module_t mod, int what, void *arg); 84 85static device_method_t pci_methods[] = { 86 /* Device interface */ 87 DEVMETHOD(device_probe, pci_probe), 88 DEVMETHOD(device_attach, bus_generic_attach), 89 DEVMETHOD(device_shutdown, bus_generic_shutdown), 90 DEVMETHOD(device_suspend, bus_generic_suspend), --- 213 unchanged lines hidden (view full) --- 304 cfg->nummaps = PCI_MAXMAPS_2; 305 break; 306 } 307#undef REG 308} 309 310/* read configuration header into pcicfgregs structure */ 311 |
340static struct pci_devinfo * | 312struct pci_devinfo * |
341pci_read_device(device_t pcib, int b, int s, int f) 342{ 343#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) 344 pcicfgregs *cfg = NULL; 345 struct pci_devinfo *devlist_entry; 346 struct devlist *devlist_head; 347 348 devlist_head = &pci_devq; --- 106 unchanged lines hidden (view full) --- 455 break; 456 default: 457 break; 458 } 459 } 460#undef REG 461} 462 | 313pci_read_device(device_t pcib, int b, int s, int f) 314{ 315#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w) 316 pcicfgregs *cfg = NULL; 317 struct pci_devinfo *devlist_entry; 318 struct devlist *devlist_head; 319 320 devlist_head = &pci_devq; --- 106 unchanged lines hidden (view full) --- 427 break; 428 default: 429 break; 430 } 431 } 432#undef REG 433} 434 |
463#if 0 | |
464/* free pcicfgregs structure and all depending data structures */ 465 | 435/* free pcicfgregs structure and all depending data structures */ 436 |
466static int | 437int |
467pci_freecfg(struct pci_devinfo *dinfo) 468{ 469 struct devlist *devlist_head; 470 471 devlist_head = &pci_devq; 472 | 438pci_freecfg(struct pci_devinfo *dinfo) 439{ 440 struct devlist *devlist_head; 441 442 devlist_head = &pci_devq; 443 |
473 if (dinfo->cfg.map != NULL) 474 free(dinfo->cfg.map, M_DEVBUF); | |
475 /* XXX this hasn't been tested */ 476 STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links); 477 free(dinfo, M_DEVBUF); 478 479 /* increment the generation count */ 480 pci_generation++; 481 482 /* we're losing one device */ 483 pci_numdevs--; 484 return (0); 485} | 444 /* XXX this hasn't been tested */ 445 STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links); 446 free(dinfo, M_DEVBUF); 447 448 /* increment the generation count */ 449 pci_generation++; 450 451 /* we're losing one device */ 452 pci_numdevs--; 453 return (0); 454} |
486#endif | |
487 488/* 489 * PCI power manangement 490 */ | 455 456/* 457 * PCI power manangement 458 */ |
491static int | 459int |
492pci_set_powerstate_method(device_t dev, device_t child, int state) 493{ 494 struct pci_devinfo *dinfo = device_get_ivars(child); 495 pcicfgregs *cfg = &dinfo->cfg; 496 u_int16_t status; 497 int result; 498 499 if (cfg->pp_cap != 0) { --- 26 unchanged lines hidden (view full) --- 526 if (result == 0) 527 PCI_WRITE_CONFIG(dev, child, cfg->pp_status, status, 2); 528 } else { 529 result = ENXIO; 530 } 531 return(result); 532} 533 | 460pci_set_powerstate_method(device_t dev, device_t child, int state) 461{ 462 struct pci_devinfo *dinfo = device_get_ivars(child); 463 pcicfgregs *cfg = &dinfo->cfg; 464 u_int16_t status; 465 int result; 466 467 if (cfg->pp_cap != 0) { --- 26 unchanged lines hidden (view full) --- 494 if (result == 0) 495 PCI_WRITE_CONFIG(dev, child, cfg->pp_status, status, 2); 496 } else { 497 result = ENXIO; 498 } 499 return(result); 500} 501 |
534static int | 502int |
535pci_get_powerstate_method(device_t dev, device_t child) 536{ 537 struct pci_devinfo *dinfo = device_get_ivars(child); 538 pcicfgregs *cfg = &dinfo->cfg; 539 u_int16_t status; 540 int result; 541 542 if (cfg->pp_cap != 0) { --- 41 unchanged lines hidden (view full) --- 584{ 585 u_int16_t command; 586 587 command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2); 588 command &= ~bit; 589 PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2); 590} 591 | 503pci_get_powerstate_method(device_t dev, device_t child) 504{ 505 struct pci_devinfo *dinfo = device_get_ivars(child); 506 pcicfgregs *cfg = &dinfo->cfg; 507 u_int16_t status; 508 int result; 509 510 if (cfg->pp_cap != 0) { --- 41 unchanged lines hidden (view full) --- 552{ 553 u_int16_t command; 554 555 command = PCI_READ_CONFIG(dev, child, PCIR_COMMAND, 2); 556 command &= ~bit; 557 PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2); 558} 559 |
592static void | 560void |
593pci_enable_busmaster_method(device_t dev, device_t child) 594{ 595 pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN); 596} 597 | 561pci_enable_busmaster_method(device_t dev, device_t child) 562{ 563 pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN); 564} 565 |
598static void | 566void |
599pci_disable_busmaster_method(device_t dev, device_t child) 600{ 601 pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN); 602} 603 | 567pci_disable_busmaster_method(device_t dev, device_t child) 568{ 569 pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN); 570} 571 |
604static void | 572void |
605pci_enable_io_method(device_t dev, device_t child, int space) 606{ 607 switch(space) { 608 case SYS_RES_IOPORT: 609 pci_set_command_bit(dev, child, PCIM_CMD_PORTEN); 610 break; 611 case SYS_RES_MEMORY: 612 pci_set_command_bit(dev, child, PCIM_CMD_MEMEN); 613 break; 614 } 615} 616 | 573pci_enable_io_method(device_t dev, device_t child, int space) 574{ 575 switch(space) { 576 case SYS_RES_IOPORT: 577 pci_set_command_bit(dev, child, PCIM_CMD_PORTEN); 578 break; 579 case SYS_RES_MEMORY: 580 pci_set_command_bit(dev, child, PCIM_CMD_MEMEN); 581 break; 582 } 583} 584 |
617static void | 585void |
618pci_disable_io_method(device_t dev, device_t child, int space) 619{ 620 switch(space) { 621 case SYS_RES_IOPORT: 622 pci_clear_command_bit(dev, child, PCIM_CMD_PORTEN); 623 break; 624 case SYS_RES_MEMORY: 625 pci_clear_command_bit(dev, child, PCIM_CMD_MEMEN); 626 break; 627 } 628} 629 630/* 631 * New style pci driver. Parent device is either a pci-host-bridge or a 632 * pci-pci-bridge. Both kinds are represented by instances of pcib. 633 */ 634 | 586pci_disable_io_method(device_t dev, device_t child, int space) 587{ 588 switch(space) { 589 case SYS_RES_IOPORT: 590 pci_clear_command_bit(dev, child, PCIM_CMD_PORTEN); 591 break; 592 case SYS_RES_MEMORY: 593 pci_clear_command_bit(dev, child, PCIM_CMD_MEMEN); 594 break; 595 } 596} 597 598/* 599 * New style pci driver. Parent device is either a pci-host-bridge or a 600 * pci-pci-bridge. Both kinds are represented by instances of pcib. 601 */ 602 |
635static void | 603void |
636pci_print_verbose(struct pci_devinfo *dinfo) 637{ 638 if (bootverbose) { 639 pcicfgregs *cfg = &dinfo->cfg; 640 641 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 642 cfg->vendor, cfg->device, cfg->revid); 643 printf("\tbus=%d, slot=%d, func=%d\n", --- 216 unchanged lines hidden (view full) --- 860 pci_vendordata[pci_vendordata_size] = '\n'; 861 } 862 once++; 863 } 864 865 return 0; 866} 867 | 604pci_print_verbose(struct pci_devinfo *dinfo) 605{ 606 if (bootverbose) { 607 pcicfgregs *cfg = &dinfo->cfg; 608 609 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 610 cfg->vendor, cfg->device, cfg->revid); 611 printf("\tbus=%d, slot=%d, func=%d\n", --- 216 unchanged lines hidden (view full) --- 828 pci_vendordata[pci_vendordata_size] = '\n'; 829 } 830 once++; 831 } 832 833 return 0; 834} 835 |
868static int | 836int |
869pci_print_child(device_t dev, device_t child) 870{ 871 struct pci_devinfo *dinfo; 872 struct resource_list *rl; 873 pcicfgregs *cfg; 874 int retval = 0; 875 876 dinfo = device_get_ivars(child); --- 74 unchanged lines hidden (view full) --- 951 {PCIC_SERIALBUS, PCIS_SERIALBUS_ACCESS, "AccessBus"}, 952 {PCIC_SERIALBUS, PCIS_SERIALBUS_SSA, "SSA"}, 953 {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"}, 954 {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"}, 955 {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"}, 956 {0, 0, NULL} 957}; 958 | 837pci_print_child(device_t dev, device_t child) 838{ 839 struct pci_devinfo *dinfo; 840 struct resource_list *rl; 841 pcicfgregs *cfg; 842 int retval = 0; 843 844 dinfo = device_get_ivars(child); --- 74 unchanged lines hidden (view full) --- 919 {PCIC_SERIALBUS, PCIS_SERIALBUS_ACCESS, "AccessBus"}, 920 {PCIC_SERIALBUS, PCIS_SERIALBUS_SSA, "SSA"}, 921 {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"}, 922 {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"}, 923 {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"}, 924 {0, 0, NULL} 925}; 926 |
959static void | 927void |
960pci_probe_nomatch(device_t dev, device_t child) 961{ 962 int i; 963 char *cp, *scp, *device; 964 965 /* 966 * Look for a listing for this device in a loaded device database. 967 */ --- 145 unchanged lines hidden (view full) --- 1113 out: 1114 if (vp != NULL) 1115 free(vp, M_DEVBUF); 1116 if (dp != NULL) 1117 free(dp, M_DEVBUF); 1118 return(desc); 1119} 1120 | 928pci_probe_nomatch(device_t dev, device_t child) 929{ 930 int i; 931 char *cp, *scp, *device; 932 933 /* 934 * Look for a listing for this device in a loaded device database. 935 */ --- 145 unchanged lines hidden (view full) --- 1081 out: 1082 if (vp != NULL) 1083 free(vp, M_DEVBUF); 1084 if (dp != NULL) 1085 free(dp, M_DEVBUF); 1086 return(desc); 1087} 1088 |
1121static int | 1089int |
1122pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 1123{ 1124 struct pci_devinfo *dinfo; 1125 pcicfgregs *cfg; 1126 1127 dinfo = device_get_ivars(child); 1128 cfg = &dinfo->cfg; 1129 --- 41 unchanged lines hidden (view full) --- 1171 *result = cfg->func; 1172 break; 1173 default: 1174 return ENOENT; 1175 } 1176 return 0; 1177} 1178 | 1090pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 1091{ 1092 struct pci_devinfo *dinfo; 1093 pcicfgregs *cfg; 1094 1095 dinfo = device_get_ivars(child); 1096 cfg = &dinfo->cfg; 1097 --- 41 unchanged lines hidden (view full) --- 1139 *result = cfg->func; 1140 break; 1141 default: 1142 return ENOENT; 1143 } 1144 return 0; 1145} 1146 |
1179static int | 1147int |
1180pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 1181{ 1182 struct pci_devinfo *dinfo; 1183 pcicfgregs *cfg; 1184 1185 dinfo = device_get_ivars(child); 1186 cfg = &dinfo->cfg; 1187 --- 15 unchanged lines hidden (view full) --- 1203 return EINVAL; /* disallow for now */ 1204 1205 default: 1206 return ENOENT; 1207 } 1208 return 0; 1209} 1210 | 1148pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 1149{ 1150 struct pci_devinfo *dinfo; 1151 pcicfgregs *cfg; 1152 1153 dinfo = device_get_ivars(child); 1154 cfg = &dinfo->cfg; 1155 --- 15 unchanged lines hidden (view full) --- 1171 return EINVAL; /* disallow for now */ 1172 1173 default: 1174 return ENOENT; 1175 } 1176 return 0; 1177} 1178 |
1211static struct resource * | 1179struct resource * |
1212pci_alloc_resource(device_t dev, device_t child, int type, int *rid, 1213 u_long start, u_long end, u_long count, u_int flags) 1214{ 1215 struct pci_devinfo *dinfo = device_get_ivars(child); 1216 struct resource_list *rl = &dinfo->resources; 1217 pcicfgregs *cfg = &dinfo->cfg; 1218 1219 /* --- 16 unchanged lines hidden (view full) --- 1236 } 1237 } 1238 } 1239 1240 return resource_list_alloc(rl, dev, child, type, rid, 1241 start, end, count, flags); 1242} 1243 | 1180pci_alloc_resource(device_t dev, device_t child, int type, int *rid, 1181 u_long start, u_long end, u_long count, u_int flags) 1182{ 1183 struct pci_devinfo *dinfo = device_get_ivars(child); 1184 struct resource_list *rl = &dinfo->resources; 1185 pcicfgregs *cfg = &dinfo->cfg; 1186 1187 /* --- 16 unchanged lines hidden (view full) --- 1204 } 1205 } 1206 } 1207 1208 return resource_list_alloc(rl, dev, child, type, rid, 1209 start, end, count, flags); 1210} 1211 |
1244static void | 1212void |
1245pci_delete_resource(device_t dev, device_t child, int type, int rid) 1246{ | 1213pci_delete_resource(device_t dev, device_t child, int type, int rid) 1214{ |
1247 printf("pci_delete_resource: PCI resources can not be deleted\n"); | 1215 struct pci_devinfo *dinfo; 1216 struct resource_list *rl; 1217 struct resource_list_entry *rle; 1218 1219 if (device_get_parent(child) != dev) 1220 return; 1221 1222 dinfo = device_get_ivars(child); 1223 rl = &dinfo->resources; 1224 rle = resource_list_find(rl, type, rid); 1225 if (rle) { 1226 if (rle->res) { 1227 if (rle->res->r_dev != dev || 1228 rman_get_flags(rle->res) & RF_ACTIVE) { 1229 device_printf(dev, "delete_resource: " 1230 "Resource still owned by child, oops. " 1231 "(type=%d, rid=%d, addr=%lx)\n", 1232 rle->type, rle->rid, 1233 rman_get_start(rle->res)); 1234 return; 1235 } 1236 bus_release_resource(dev, type, rid, rle->res); 1237 } 1238 resource_list_delete(rl, type, rid); 1239 } 1240 /* I don't understand the next line */ 1241 pci_write_config(child, rid, 0, 4); 1242 BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid); |
1248} 1249 | 1243} 1244 |
1250static struct resource_list * | 1245struct resource_list * |
1251pci_get_resource_list (device_t dev, device_t child) 1252{ 1253 struct pci_devinfo * dinfo = device_get_ivars(child); 1254 struct resource_list * rl = &dinfo->resources; 1255 1256 if (!rl) 1257 return (NULL); 1258 1259 return (rl); 1260} 1261 | 1246pci_get_resource_list (device_t dev, device_t child) 1247{ 1248 struct pci_devinfo * dinfo = device_get_ivars(child); 1249 struct resource_list * rl = &dinfo->resources; 1250 1251 if (!rl) 1252 return (NULL); 1253 1254 return (rl); 1255} 1256 |
1262static u_int32_t | 1257u_int32_t |
1263pci_read_config_method(device_t dev, device_t child, int reg, int width) 1264{ 1265 struct pci_devinfo *dinfo = device_get_ivars(child); 1266 pcicfgregs *cfg = &dinfo->cfg; 1267 1268 return PCIB_READ_CONFIG(device_get_parent(dev), 1269 cfg->bus, cfg->slot, cfg->func, 1270 reg, width); 1271} 1272 | 1258pci_read_config_method(device_t dev, device_t child, int reg, int width) 1259{ 1260 struct pci_devinfo *dinfo = device_get_ivars(child); 1261 pcicfgregs *cfg = &dinfo->cfg; 1262 1263 return PCIB_READ_CONFIG(device_get_parent(dev), 1264 cfg->bus, cfg->slot, cfg->func, 1265 reg, width); 1266} 1267 |
1273static void | 1268void |
1274pci_write_config_method(device_t dev, device_t child, int reg, 1275 u_int32_t val, int width) 1276{ 1277 struct pci_devinfo *dinfo = device_get_ivars(child); 1278 pcicfgregs *cfg = &dinfo->cfg; 1279 1280 PCIB_WRITE_CONFIG(device_get_parent(dev), 1281 cfg->bus, cfg->slot, cfg->func, --- 18 unchanged lines hidden --- | 1269pci_write_config_method(device_t dev, device_t child, int reg, 1270 u_int32_t val, int width) 1271{ 1272 struct pci_devinfo *dinfo = device_get_ivars(child); 1273 pcicfgregs *cfg = &dinfo->cfg; 1274 1275 PCIB_WRITE_CONFIG(device_get_parent(dev), 1276 cfg->bus, cfg->slot, cfg->func, --- 18 unchanged lines hidden --- |