cardbus.c (110750) | cardbus.c (110975) |
---|---|
1/* 2 * Copyright (c) 2000,2001 Jonathan Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * | 1/* 2 * Copyright (c) 2000,2001 Jonathan Chen. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/sys/dev/cardbus/cardbus.c 110750 2003-02-12 05:57:02Z imp $ | 28 * $FreeBSD: head/sys/dev/cardbus/cardbus.c 110975 2003-02-16 02:06:50Z imp $ |
29 */ 30 31/* 32 * Cardbus Bus Driver 33 * 34 * much of the bus code was stolen directly from sys/pci/pci.c 35 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>) 36 * --- 9 unchanged lines hidden (view full) --- 46#include <sys/bus.h> 47#include <machine/bus.h> 48#include <sys/rman.h> 49#include <machine/resource.h> 50 51#include <sys/pciio.h> 52#include <dev/pci/pcivar.h> 53#include <dev/pci/pcireg.h> | 29 */ 30 31/* 32 * Cardbus Bus Driver 33 * 34 * much of the bus code was stolen directly from sys/pci/pci.c 35 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>) 36 * --- 9 unchanged lines hidden (view full) --- 46#include <sys/bus.h> 47#include <machine/bus.h> 48#include <sys/rman.h> 49#include <machine/resource.h> 50 51#include <sys/pciio.h> 52#include <dev/pci/pcivar.h> 53#include <dev/pci/pcireg.h> |
54#include <dev/pci/pci_private.h> |
|
54 55#include <dev/cardbus/cardbusreg.h> 56#include <dev/cardbus/cardbusvar.h> 57#include <dev/cardbus/cardbus_cis.h> 58#include <dev/pccard/pccardvar.h> 59 60#include "power_if.h" 61#include "pcib_if.h" --- 21 unchanged lines hidden (view full) --- 83 int type, int *rid, u_long start, u_long end, u_long count, 84 u_int flags); 85static int cardbus_attach(device_t cbdev); 86static int cardbus_attach_card(device_t cbdev); 87static int cardbus_child_location_str(device_t cbdev, device_t child, 88 char *, size_t len); 89static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child, 90 char *, size_t len); | 55 56#include <dev/cardbus/cardbusreg.h> 57#include <dev/cardbus/cardbusvar.h> 58#include <dev/cardbus/cardbus_cis.h> 59#include <dev/pccard/pccardvar.h> 60 61#include "power_if.h" 62#include "pcib_if.h" --- 21 unchanged lines hidden (view full) --- 84 int type, int *rid, u_long start, u_long end, u_long count, 85 u_int flags); 86static int cardbus_attach(device_t cbdev); 87static int cardbus_attach_card(device_t cbdev); 88static int cardbus_child_location_str(device_t cbdev, device_t child, 89 char *, size_t len); 90static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child, 91 char *, size_t len); |
91static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child, 92 uint16_t bit); | |
93static void cardbus_delete_resource(device_t cbdev, device_t child, 94 int type, int rid); 95static void cardbus_delete_resource_method(device_t cbdev, device_t child, 96 int type, int rid); 97static int cardbus_detach(device_t cbdev); 98static int cardbus_detach_card(device_t cbdev); 99static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f, 100 pcicfgregs *cfg); | 92static void cardbus_delete_resource(device_t cbdev, device_t child, 93 int type, int rid); 94static void cardbus_delete_resource_method(device_t cbdev, device_t child, 95 int type, int rid); 96static int cardbus_detach(device_t cbdev); 97static int cardbus_detach_card(device_t cbdev); 98static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f, 99 pcicfgregs *cfg); |
101static void cardbus_disable_busmaster_method(device_t cbdev, device_t child); 102static void cardbus_disable_io_method(device_t cbdev, device_t child, 103 int space); | |
104static void cardbus_driver_added(device_t cbdev, driver_t *driver); | 100static void cardbus_driver_added(device_t cbdev, driver_t *driver); |
105static void cardbus_enable_busmaster_method(device_t cbdev, device_t child); 106static void cardbus_enable_io_method(device_t cbdev, device_t child, 107 int space); 108static int cardbus_freecfg(struct cardbus_devinfo *dinfo); 109static int cardbus_get_powerstate_method(device_t cbdev, device_t child); | |
110static int cardbus_get_resource(device_t cbdev, device_t child, int type, 111 int rid, u_long *startp, u_long *countp); 112static int cardbus_get_resource_method(device_t cbdev, device_t child, 113 int type, int rid, u_long *startp, u_long *countp); | 101static int cardbus_get_resource(device_t cbdev, device_t child, int type, 102 int rid, u_long *startp, u_long *countp); 103static int cardbus_get_resource_method(device_t cbdev, device_t child, 104 int type, int rid, u_long *startp, u_long *countp); |
114static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f, 115 pcicfgregs *cfg); 116static int cardbus_print_child(device_t cbdev, device_t child); 117static int cardbus_print_resources(struct resource_list *rl, 118 const char *name, int type, const char *format); 119static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); | |
120static int cardbus_probe(device_t cbdev); | 105static int cardbus_probe(device_t cbdev); |
121static void cardbus_probe_nomatch(device_t cbdev, device_t child); 122static struct cardbus_devinfo *cardbus_read_device(device_t brdev, int b, 123 int s, int f); 124static void cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg); 125static uint32_t cardbus_read_config_method(device_t cbdev, 126 device_t child, int reg, int width); | |
127static int cardbus_read_ivar(device_t cbdev, device_t child, int which, | 106static int cardbus_read_ivar(device_t cbdev, device_t child, int which, |
128 u_long *result); | 107 uintptr_t *result); |
129static void cardbus_release_all_resources(device_t cbdev, 130 struct cardbus_devinfo *dinfo); 131static int cardbus_release_resource(device_t cbdev, device_t child, 132 int type, int rid, struct resource *r); | 108static void cardbus_release_all_resources(device_t cbdev, 109 struct cardbus_devinfo *dinfo); 110static int cardbus_release_resource(device_t cbdev, device_t child, 111 int type, int rid, struct resource *r); |
133static __inline void cardbus_set_command_bit(device_t cbdev, device_t child, 134 uint16_t bit); 135static int cardbus_set_powerstate_method(device_t cbdev, device_t child, 136 int state); | |
137static int cardbus_set_resource(device_t cbdev, device_t child, int type, 138 int rid, u_long start, u_long count, struct resource *res); 139static int cardbus_set_resource_method(device_t cbdev, device_t child, 140 int type, int rid, u_long start, u_long count); 141static int cardbus_setup_intr(device_t cbdev, device_t child, 142 struct resource *irq, int flags, driver_intr_t *intr, 143 void *arg, void **cookiep); 144static int cardbus_teardown_intr(device_t cbdev, device_t child, 145 struct resource *irq, void *cookie); | 112static int cardbus_set_resource(device_t cbdev, device_t child, int type, 113 int rid, u_long start, u_long count, struct resource *res); 114static int cardbus_set_resource_method(device_t cbdev, device_t child, 115 int type, int rid, u_long start, u_long count); 116static int cardbus_setup_intr(device_t cbdev, device_t child, 117 struct resource *irq, int flags, driver_intr_t *intr, 118 void *arg, void **cookiep); 119static int cardbus_teardown_intr(device_t cbdev, device_t child, 120 struct resource *irq, void *cookie); |
146static void cardbus_write_config_method(device_t cbdev, device_t child, 147 int reg, uint32_t val, int width); | |
148static int cardbus_write_ivar(device_t cbdev, device_t child, int which, 149 uintptr_t value); 150 151/************************************************************************/ 152/* Probe/Attach */ 153/************************************************************************/ 154 155static int --- 76 unchanged lines hidden (view full) --- 232 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1); 233 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1); 234 curr_bus_number += 3; 235 } 236 /* For each function, set it up and try to attach a driver to it */ 237 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) { 238 int cardbusfunchigh = 0; 239 for (func = 0; func <= cardbusfunchigh; func++) { | 121static int cardbus_write_ivar(device_t cbdev, device_t child, int which, 122 uintptr_t value); 123 124/************************************************************************/ 125/* Probe/Attach */ 126/************************************************************************/ 127 128static int --- 76 unchanged lines hidden (view full) --- 205 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1); 206 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1); 207 curr_bus_number += 3; 208 } 209 /* For each function, set it up and try to attach a driver to it */ 210 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) { 211 int cardbusfunchigh = 0; 212 for (func = 0; func <= cardbusfunchigh; func++) { |
240 struct cardbus_devinfo *dinfo = 241 cardbus_read_device(brdev, bus, slot, func); | 213 struct cardbus_devinfo *dinfo; |
242 | 214 |
215 dinfo = (struct cardbus_devinfo *) 216 pci_read_device(brdev, bus, slot, func, 217 sizeof(struct cardbus_devinfo)); |
|
243 if (dinfo == NULL) 244 continue; 245 if (dinfo->pci.cfg.mfdev) 246 cardbusfunchigh = CARDBUS_FUNCMAX; 247 248 cardbus_device_setup_regs(brdev, bus, slot, func, 249 &dinfo->pci.cfg); | 218 if (dinfo == NULL) 219 continue; 220 if (dinfo->pci.cfg.mfdev) 221 cardbusfunchigh = CARDBUS_FUNCMAX; 222 223 cardbus_device_setup_regs(brdev, bus, slot, func, 224 &dinfo->pci.cfg); |
250 cardbus_print_verbose(dinfo); | 225 pci_print_verbose(&dinfo->pci); |
251 dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1); 252 if (!dinfo->pci.cfg.dev) { 253 DEVPRINTF((cbdev, "Cannot add child!\n")); | 226 dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1); 227 if (!dinfo->pci.cfg.dev) { 228 DEVPRINTF((cbdev, "Cannot add child!\n")); |
254 cardbus_freecfg(dinfo); | 229 pci_freecfg((struct pci_devinfo *)dinfo); |
255 continue; 256 } 257 resource_list_init(&dinfo->pci.resources); 258 device_set_ivars(dinfo->pci.cfg.dev, dinfo); 259 cardbus_do_cis(cbdev, dinfo->pci.cfg.dev); 260 if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0) 261 cardbus_release_all_resources(cbdev, dinfo); 262 else --- 27 unchanged lines hidden (view full) --- 290 int status = device_get_state(devlist[tmp]); 291 292 if (dinfo->pci.cfg.dev != devlist[tmp]) 293 device_printf(cbdev, "devinfo dev mismatch\n"); 294 if (status == DS_ATTACHED || status == DS_BUSY) 295 device_detach(devlist[tmp]); 296 cardbus_release_all_resources(cbdev, dinfo); 297 device_delete_child(cbdev, devlist[tmp]); | 230 continue; 231 } 232 resource_list_init(&dinfo->pci.resources); 233 device_set_ivars(dinfo->pci.cfg.dev, dinfo); 234 cardbus_do_cis(cbdev, dinfo->pci.cfg.dev); 235 if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0) 236 cardbus_release_all_resources(cbdev, dinfo); 237 else --- 27 unchanged lines hidden (view full) --- 265 int status = device_get_state(devlist[tmp]); 266 267 if (dinfo->pci.cfg.dev != devlist[tmp]) 268 device_printf(cbdev, "devinfo dev mismatch\n"); 269 if (status == DS_ATTACHED || status == DS_BUSY) 270 device_detach(devlist[tmp]); 271 cardbus_release_all_resources(cbdev, dinfo); 272 device_delete_child(cbdev, devlist[tmp]); |
298 cardbus_freecfg(dinfo); | 273 pci_freecfg((struct pci_devinfo *)dinfo); |
299 } 300 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 301 free(devlist, M_TEMP); 302 return (err); 303} 304 305static void 306cardbus_driver_added(device_t cbdev, driver_t *driver) --- 17 unchanged lines hidden (view full) --- 324 } 325 if (i > 0 && i == numdevs) 326 POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev); 327 for (i = 0; i < numdevs; i++) { 328 dev = devlist[i]; 329 if (device_get_state(dev) != DS_NOTPRESENT) 330 continue; 331 dinfo = device_get_ivars(dev); | 274 } 275 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 276 free(devlist, M_TEMP); 277 return (err); 278} 279 280static void 281cardbus_driver_added(device_t cbdev, driver_t *driver) --- 17 unchanged lines hidden (view full) --- 299 } 300 if (i > 0 && i == numdevs) 301 POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev); 302 for (i = 0; i < numdevs; i++) { 303 dev = devlist[i]; 304 if (device_get_state(dev) != DS_NOTPRESENT) 305 continue; 306 dinfo = device_get_ivars(dev); |
332 cardbus_print_verbose(dinfo); | 307 pci_print_verbose(&dinfo->pci); |
333 resource_list_init(&dinfo->pci.resources); 334 cardbus_do_cis(cbdev, dev); 335 if (device_probe_and_attach(dev) != 0) 336 cardbus_release_all_resources(cbdev, dinfo); 337 } 338 free(devlist, M_TEMP); 339} 340 341/************************************************************************/ | 308 resource_list_init(&dinfo->pci.resources); 309 cardbus_do_cis(cbdev, dev); 310 if (device_probe_and_attach(dev) != 0) 311 cardbus_release_all_resources(cbdev, dinfo); 312 } 313 free(devlist, M_TEMP); 314} 315 316/************************************************************************/ |
342/* PCI-Like config reading (copied from pci.c */ 343/************************************************************************/ 344 345/* read configuration header into pcicfgrect structure */ 346 347static void 348cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg) 349{ 350#define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w) 351 int ptr, nextptr, ptrptr; 352 353 switch (cfg->hdrtype) { 354 case 0: 355 ptrptr = 0x34; 356 break; 357 case 2: 358 ptrptr = 0x14; 359 break; 360 default: 361 return; /* no extended capabilities support */ 362 } 363 nextptr = REG(ptrptr, 1); /* sanity check? */ 364 365 /* 366 * Read capability entries. 367 */ 368 while (nextptr != 0) { 369 /* Sanity check */ 370 if (nextptr > 255) { 371 printf("illegal PCI extended capability offset %d\n", 372 nextptr); 373 return; 374 } 375 /* Find the next entry */ 376 ptr = nextptr; 377 nextptr = REG(ptr + 1, 1); 378 379 /* Process this entry */ 380 switch (REG(ptr, 1)) { 381 case 0x01: /* PCI power management */ 382 if (cfg->pp_cap == 0) { 383 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2); 384 cfg->pp_status = ptr + PCIR_POWER_STATUS; 385 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR; 386 if ((nextptr - ptr) > PCIR_POWER_DATA) 387 cfg->pp_data = ptr + PCIR_POWER_DATA; 388 } 389 break; 390 default: 391 break; 392 } 393 } 394#undef REG 395} 396 397/* extract header type specific config data */ 398 399static void 400cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg) 401{ 402#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 403 switch (cfg->hdrtype) { 404 case 0: 405 cfg->subvendor = REG(PCIR_SUBVEND_0, 2); 406 cfg->subdevice = REG(PCIR_SUBDEV_0, 2); 407 cfg->nummaps = PCI_MAXMAPS_0; 408 break; 409 case 1: 410 cfg->subvendor = REG(PCIR_SUBVEND_1, 2); 411 cfg->subdevice = REG(PCIR_SUBDEV_1, 2); 412 cfg->nummaps = PCI_MAXMAPS_1; 413 break; 414 case 2: 415 cfg->subvendor = REG(PCIR_SUBVEND_2, 2); 416 cfg->subdevice = REG(PCIR_SUBDEV_2, 2); 417 cfg->nummaps = PCI_MAXMAPS_2; 418 break; 419 } 420#undef REG 421} 422 423static struct cardbus_devinfo * 424cardbus_read_device(device_t brdev, int b, int s, int f) 425{ 426#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 427 pcicfgregs *cfg = NULL; 428 struct cardbus_devinfo *devlist_entry = NULL; 429 430 if (REG(PCIR_DEVVENDOR, 4) != 0xffffffff) { 431 devlist_entry = malloc(sizeof(struct cardbus_devinfo), 432 M_DEVBUF, M_ZERO); 433 if (devlist_entry == NULL) 434 return (NULL); 435 436 cfg = &devlist_entry->pci.cfg; 437 438 cfg->bus = b; 439 cfg->slot = s; 440 cfg->func = f; 441 cfg->vendor = REG(PCIR_VENDOR, 2); 442 cfg->device = REG(PCIR_DEVICE, 2); 443 cfg->cmdreg = REG(PCIR_COMMAND, 2); 444 cfg->statreg = REG(PCIR_STATUS, 2); 445 cfg->baseclass = REG(PCIR_CLASS, 1); 446 cfg->subclass = REG(PCIR_SUBCLASS, 1); 447 cfg->progif = REG(PCIR_PROGIF, 1); 448 cfg->revid = REG(PCIR_REVID, 1); 449 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); 450 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); 451 cfg->lattimer = REG(PCIR_LATTIMER, 1); 452 cfg->intpin = REG(PCIR_INTPIN, 1); 453 cfg->intline = REG(PCIR_INTLINE, 1); 454 455 cfg->mingnt = REG(PCIR_MINGNT, 1); 456 cfg->maxlat = REG(PCIR_MAXLAT, 1); 457 458 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 459 cfg->hdrtype &= ~PCIM_MFDEV; 460 461 cardbus_hdrtypedata(brdev, b, s, f, cfg); 462 463 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) 464 cardbus_read_extcap(brdev, cfg); 465 466 devlist_entry->pci.conf.pc_sel.pc_bus = cfg->bus; 467 devlist_entry->pci.conf.pc_sel.pc_dev = cfg->slot; 468 devlist_entry->pci.conf.pc_sel.pc_func = cfg->func; 469 devlist_entry->pci.conf.pc_hdr = cfg->hdrtype; 470 471 devlist_entry->pci.conf.pc_subvendor = cfg->subvendor; 472 devlist_entry->pci.conf.pc_subdevice = cfg->subdevice; 473 devlist_entry->pci.conf.pc_vendor = cfg->vendor; 474 devlist_entry->pci.conf.pc_device = cfg->device; 475 476 devlist_entry->pci.conf.pc_class = cfg->baseclass; 477 devlist_entry->pci.conf.pc_subclass = cfg->subclass; 478 devlist_entry->pci.conf.pc_progif = cfg->progif; 479 devlist_entry->pci.conf.pc_revid = cfg->revid; 480 } 481 return (devlist_entry); 482#undef REG 483} 484 485/* free pcicfgregs structure and all depending data structures */ 486 487static int 488cardbus_freecfg(struct cardbus_devinfo *dinfo) 489{ 490 free(dinfo, M_DEVBUF); 491 492 return (0); 493} 494 495static void 496cardbus_print_verbose(struct cardbus_devinfo *dinfo) 497{ 498 if (bootverbose || cardbus_debug > 0) 499 { 500 pcicfgregs *cfg = &dinfo->pci.cfg; 501 502 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 503 cfg->vendor, cfg->device, cfg->revid); 504 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 505 cfg->baseclass, cfg->subclass, cfg->progif, 506 cfg->hdrtype, cfg->mfdev); 507 printf("\tcmdreg=0x%04x, statreg=0x%04x, " 508 "cachelnsz=%d (dwords)\n", 509 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 510 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), " 511 "maxlat=0x%02x (%d ns)\n", 512 cfg->lattimer, cfg->lattimer * 30, 513 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, 514 cfg->maxlat * 250); 515 if (cfg->intpin > 0) 516 printf("\tintpin=%c, irq=%d\n", 517 cfg->intpin + 'a' - 1, cfg->intline); 518 } 519} 520 521/************************************************************************/ | |
522/* Resources */ 523/************************************************************************/ 524 525static int 526cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, 527 u_long start, u_long count, struct resource *res) 528{ 529 struct cardbus_devinfo *dinfo; --- 301 unchanged lines hidden (view full) --- 831} 832 833 834/************************************************************************/ 835/* Other Bus Methods */ 836/************************************************************************/ 837 838static int | 317/* Resources */ 318/************************************************************************/ 319 320static int 321cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, 322 u_long start, u_long count, struct resource *res) 323{ 324 struct cardbus_devinfo *dinfo; --- 301 unchanged lines hidden (view full) --- 626} 627 628 629/************************************************************************/ 630/* Other Bus Methods */ 631/************************************************************************/ 632 633static int |
839cardbus_print_resources(struct resource_list *rl, const char *name, 840 int type, const char *format) 841{ 842 struct resource_list_entry *rle; 843 int printed, retval; 844 845 printed = 0; 846 retval = 0; 847 /* Yes, this is kinda cheating */ 848 SLIST_FOREACH(rle, rl, link) { 849 if (rle->type == type) { 850 if (printed == 0) 851 retval += printf(" %s ", name); 852 else if (printed > 0) 853 retval += printf(","); 854 printed++; 855 retval += printf(format, rle->start); 856 if (rle->count > 1) { 857 retval += printf("-"); 858 retval += printf(format, rle->start + 859 rle->count - 1); 860 } 861 } 862 } 863 return retval; 864} 865 866static int 867cardbus_print_child(device_t cbdev, device_t child) 868{ 869 struct cardbus_devinfo *dinfo; 870 struct resource_list *rl; 871 pcicfgregs *cfg; 872 int retval = 0; 873 874 dinfo = device_get_ivars(child); 875 cfg = &dinfo->pci.cfg; 876 rl = &dinfo->pci.resources; 877 878 retval += bus_print_child_header(cbdev, child); 879 880 retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 881 retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx"); 882 retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 883 if (device_get_flags(cbdev)) 884 retval += printf(" flags %#x", device_get_flags(cbdev)); 885 886 retval += printf(" at device %d.%d", pci_get_slot(child), 887 pci_get_function(child)); 888 889 retval += bus_print_child_footer(cbdev, child); 890 891 return (retval); 892} 893 894static void 895cardbus_probe_nomatch(device_t cbdev, device_t child) 896{ 897 struct cardbus_devinfo *dinfo; 898 pcicfgregs *cfg; 899 900 dinfo = device_get_ivars(child); 901 cfg = &dinfo->pci.cfg; 902 device_printf(cbdev, "<unknown card>"); 903 printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device); 904 printf(" at %d.%d", pci_get_slot(child), pci_get_function(child)); 905 if (cfg->intpin > 0 && cfg->intline != 255) { 906 printf(" irq %d", cfg->intline); 907 } 908 printf("\n"); 909 910 return; 911} 912 913static int | |
914cardbus_child_location_str(device_t cbdev, device_t child, char *buf, 915 size_t buflen) 916{ 917 struct cardbus_devinfo *dinfo; 918 pcicfgregs *cfg; 919 920 dinfo = device_get_ivars(child); 921 cfg = &dinfo->pci.cfg; --- 13 unchanged lines hidden (view full) --- 935 cfg = &dinfo->pci.cfg; 936 snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x " 937 "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor, 938 cfg->subdevice); 939 return (0); 940} 941 942static int | 634cardbus_child_location_str(device_t cbdev, device_t child, char *buf, 635 size_t buflen) 636{ 637 struct cardbus_devinfo *dinfo; 638 pcicfgregs *cfg; 639 640 dinfo = device_get_ivars(child); 641 cfg = &dinfo->pci.cfg; --- 13 unchanged lines hidden (view full) --- 655 cfg = &dinfo->pci.cfg; 656 snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x " 657 "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor, 658 cfg->subdevice); 659 return (0); 660} 661 662static int |
943cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) | 663cardbus_read_ivar(device_t cbdev, device_t child, int which, uintptr_t *result) |
944{ 945 struct cardbus_devinfo *dinfo; 946 pcicfgregs *cfg; 947 948 dinfo = device_get_ivars(child); 949 cfg = &dinfo->pci.cfg; 950 951 switch (which) { 952 case PCI_IVAR_ETHADDR: 953 /* 954 * The generic accessor doesn't deal with failure, so 955 * we set the return value, then return an error. 956 */ 957 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) { 958 *((uint8_t **) result) = NULL; 959 return (EINVAL); 960 } 961 *((uint8_t **) result) = dinfo->funce.lan.nid; 962 break; | 664{ 665 struct cardbus_devinfo *dinfo; 666 pcicfgregs *cfg; 667 668 dinfo = device_get_ivars(child); 669 cfg = &dinfo->pci.cfg; 670 671 switch (which) { 672 case PCI_IVAR_ETHADDR: 673 /* 674 * The generic accessor doesn't deal with failure, so 675 * we set the return value, then return an error. 676 */ 677 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) { 678 *((uint8_t **) result) = NULL; 679 return (EINVAL); 680 } 681 *((uint8_t **) result) = dinfo->funce.lan.nid; 682 break; |
963 case PCI_IVAR_SUBVENDOR: 964 *result = cfg->subvendor; 965 break; 966 case PCI_IVAR_SUBDEVICE: 967 *result = cfg->subdevice; 968 break; 969 case PCI_IVAR_VENDOR: 970 *result = cfg->vendor; 971 break; 972 case PCI_IVAR_DEVICE: 973 *result = cfg->device; 974 break; 975 case PCI_IVAR_DEVID: 976 *result = (cfg->device << 16) | cfg->vendor; 977 break; 978 case PCI_IVAR_CLASS: 979 *result = cfg->baseclass; 980 break; 981 case PCI_IVAR_SUBCLASS: 982 *result = cfg->subclass; 983 break; 984 case PCI_IVAR_PROGIF: 985 *result = cfg->progif; 986 break; 987 case PCI_IVAR_REVID: 988 *result = cfg->revid; 989 break; 990 case PCI_IVAR_INTPIN: 991 *result = cfg->intpin; 992 break; 993 case PCI_IVAR_IRQ: 994 *result = cfg->intline; 995 break; 996 case PCI_IVAR_BUS: 997 *result = cfg->bus; 998 break; 999 case PCI_IVAR_SLOT: 1000 *result = cfg->slot; 1001 break; 1002 case PCI_IVAR_FUNCTION: 1003 *result = cfg->func; 1004 break; | |
1005 default: | 683 default: |
1006 return ENOENT; | 684 return (pci_read_ivar(cbdev, child, which, result)); |
1007 } 1008 return 0; 1009} 1010 1011static int 1012cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value) 1013{ | 685 } 686 return 0; 687} 688 689static int 690cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value) 691{ |
1014 struct cardbus_devinfo *dinfo; 1015 pcicfgregs *cfg; 1016 1017 dinfo = device_get_ivars(child); 1018 cfg = &dinfo->pci.cfg; 1019 1020 switch (which) { 1021 case PCI_IVAR_ETHADDR: 1022 case PCI_IVAR_SUBVENDOR: 1023 case PCI_IVAR_SUBDEVICE: 1024 case PCI_IVAR_VENDOR: 1025 case PCI_IVAR_DEVICE: 1026 case PCI_IVAR_DEVID: 1027 case PCI_IVAR_CLASS: 1028 case PCI_IVAR_SUBCLASS: 1029 case PCI_IVAR_PROGIF: 1030 case PCI_IVAR_REVID: 1031 case PCI_IVAR_INTPIN: 1032 case PCI_IVAR_IRQ: 1033 case PCI_IVAR_BUS: 1034 case PCI_IVAR_SLOT: 1035 case PCI_IVAR_FUNCTION: 1036 return EINVAL; /* disallow for now */ 1037 default: 1038 return ENOENT; 1039 } 1040 return 0; | 692 return(pci_write_ivar(cbdev, child, which, value)); |
1041} 1042 1043/************************************************************************/ 1044/* Compatibility with PCI bus (XXX: Do we need this?) */ 1045/************************************************************************/ 1046 | 693} 694 695/************************************************************************/ 696/* Compatibility with PCI bus (XXX: Do we need this?) */ 697/************************************************************************/ 698 |
1047/* 1048 * PCI power manangement 1049 */ 1050static int 1051cardbus_set_powerstate_method(device_t cbdev, device_t child, int state) 1052{ 1053 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1054 pcicfgregs *cfg = &dinfo->pci.cfg; 1055 uint16_t status; 1056 int result; 1057 1058 if (cfg->pp_cap != 0) { 1059 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2) 1060 & ~PCIM_PSTAT_DMASK; 1061 result = 0; 1062 switch (state) { 1063 case PCI_POWERSTATE_D0: 1064 status |= PCIM_PSTAT_D0; 1065 break; 1066 case PCI_POWERSTATE_D1: 1067 if (cfg->pp_cap & PCIM_PCAP_D1SUPP) { 1068 status |= PCIM_PSTAT_D1; 1069 } else { 1070 result = EOPNOTSUPP; 1071 } 1072 break; 1073 case PCI_POWERSTATE_D2: 1074 if (cfg->pp_cap & PCIM_PCAP_D2SUPP) { 1075 status |= PCIM_PSTAT_D2; 1076 } else { 1077 result = EOPNOTSUPP; 1078 } 1079 break; 1080 case PCI_POWERSTATE_D3: 1081 status |= PCIM_PSTAT_D3; 1082 break; 1083 default: 1084 result = EINVAL; 1085 } 1086 if (result == 0) 1087 PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status, 1088 status, 2); 1089 } else { 1090 result = ENXIO; 1091 } 1092 return (result); 1093} 1094 1095static int 1096cardbus_get_powerstate_method(device_t cbdev, device_t child) 1097{ 1098 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1099 pcicfgregs *cfg = &dinfo->pci.cfg; 1100 uint16_t status; 1101 int result; 1102 1103 if (cfg->pp_cap != 0) { 1104 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2); 1105 switch (status & PCIM_PSTAT_DMASK) { 1106 case PCIM_PSTAT_D0: 1107 result = PCI_POWERSTATE_D0; 1108 break; 1109 case PCIM_PSTAT_D1: 1110 result = PCI_POWERSTATE_D1; 1111 break; 1112 case PCIM_PSTAT_D2: 1113 result = PCI_POWERSTATE_D2; 1114 break; 1115 case PCIM_PSTAT_D3: 1116 result = PCI_POWERSTATE_D3; 1117 break; 1118 default: 1119 result = PCI_POWERSTATE_UNKNOWN; 1120 break; 1121 } 1122 } else { 1123 /* No support, device is always at D0 */ 1124 result = PCI_POWERSTATE_D0; 1125 } 1126 return (result); 1127} 1128 1129static uint32_t 1130cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width) 1131{ 1132 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1133 pcicfgregs *cfg = &dinfo->pci.cfg; 1134 1135 return PCIB_READ_CONFIG(device_get_parent(cbdev), 1136 cfg->bus, cfg->slot, cfg->func, reg, width); 1137} 1138 1139static void 1140cardbus_write_config_method(device_t cbdev, device_t child, int reg, 1141 uint32_t val, int width) 1142{ 1143 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1144 pcicfgregs *cfg = &dinfo->pci.cfg; 1145 1146 PCIB_WRITE_CONFIG(device_get_parent(cbdev), 1147 cfg->bus, cfg->slot, cfg->func, reg, val, width); 1148} 1149 1150static __inline void 1151cardbus_set_command_bit(device_t cbdev, device_t child, uint16_t bit) 1152{ 1153 uint16_t command; 1154 1155 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1156 command |= bit; 1157 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1158} 1159 1160static __inline void 1161cardbus_clear_command_bit(device_t cbdev, device_t child, uint16_t bit) 1162{ 1163 uint16_t command; 1164 1165 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1166 command &= ~bit; 1167 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1168} 1169 1170static void 1171cardbus_enable_busmaster_method(device_t cbdev, device_t child) 1172{ 1173 cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1174} 1175 1176static void 1177cardbus_disable_busmaster_method(device_t cbdev, device_t child) 1178{ 1179 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1180} 1181 1182static void 1183cardbus_enable_io_method(device_t cbdev, device_t child, int space) 1184{ 1185 switch (space) { 1186 case SYS_RES_IOPORT: 1187 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1188 break; 1189 case SYS_RES_MEMORY: 1190 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1191 break; 1192 } 1193} 1194 1195static void 1196cardbus_disable_io_method(device_t cbdev, device_t child, int space) 1197{ 1198 switch (space) { 1199 case SYS_RES_IOPORT: 1200 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1201 break; 1202 case SYS_RES_MEMORY: 1203 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1204 break; 1205 } 1206} 1207 | |
1208static device_method_t cardbus_methods[] = { 1209 /* Device interface */ 1210 DEVMETHOD(device_probe, cardbus_probe), 1211 DEVMETHOD(device_attach, cardbus_attach), 1212 DEVMETHOD(device_detach, cardbus_detach), 1213 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1214 DEVMETHOD(device_suspend, cardbus_suspend), 1215 DEVMETHOD(device_resume, cardbus_resume), 1216 1217 /* Bus interface */ | 699static device_method_t cardbus_methods[] = { 700 /* Device interface */ 701 DEVMETHOD(device_probe, cardbus_probe), 702 DEVMETHOD(device_attach, cardbus_attach), 703 DEVMETHOD(device_detach, cardbus_detach), 704 DEVMETHOD(device_shutdown, bus_generic_shutdown), 705 DEVMETHOD(device_suspend, cardbus_suspend), 706 DEVMETHOD(device_resume, cardbus_resume), 707 708 /* Bus interface */ |
1218 DEVMETHOD(bus_print_child, cardbus_print_child), 1219 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), | 709 DEVMETHOD(bus_print_child, pci_print_child), 710 DEVMETHOD(bus_probe_nomatch, pci_probe_nomatch), |
1220 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 1221 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 1222 DEVMETHOD(bus_driver_added, cardbus_driver_added), 1223 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 1224 DEVMETHOD(bus_release_resource, cardbus_release_resource), 1225 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1226 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1227 DEVMETHOD(bus_setup_intr, cardbus_setup_intr), --- 7 unchanged lines hidden (view full) --- 1235 1236 /* Card Interface */ 1237 DEVMETHOD(card_attach_card, cardbus_attach_card), 1238 DEVMETHOD(card_detach_card, cardbus_detach_card), 1239 DEVMETHOD(card_cis_read, cardbus_cis_read), 1240 DEVMETHOD(card_cis_free, cardbus_cis_free), 1241 1242 /* Cardbus/PCI interface */ | 711 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 712 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 713 DEVMETHOD(bus_driver_added, cardbus_driver_added), 714 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 715 DEVMETHOD(bus_release_resource, cardbus_release_resource), 716 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 717 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 718 DEVMETHOD(bus_setup_intr, cardbus_setup_intr), --- 7 unchanged lines hidden (view full) --- 726 727 /* Card Interface */ 728 DEVMETHOD(card_attach_card, cardbus_attach_card), 729 DEVMETHOD(card_detach_card, cardbus_detach_card), 730 DEVMETHOD(card_cis_read, cardbus_cis_read), 731 DEVMETHOD(card_cis_free, cardbus_cis_free), 732 733 /* Cardbus/PCI interface */ |
1243 DEVMETHOD(pci_read_config, cardbus_read_config_method), 1244 DEVMETHOD(pci_write_config, cardbus_write_config_method), 1245 DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method), 1246 DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method), 1247 DEVMETHOD(pci_enable_io, cardbus_enable_io_method), 1248 DEVMETHOD(pci_disable_io, cardbus_disable_io_method), 1249 DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method), 1250 DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method), | 734 DEVMETHOD(pci_read_config, pci_read_config_method), 735 DEVMETHOD(pci_write_config, pci_write_config_method), 736 DEVMETHOD(pci_enable_busmaster, pci_enable_busmaster_method), 737 DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method), 738 DEVMETHOD(pci_enable_io, pci_enable_io_method), 739 DEVMETHOD(pci_disable_io, pci_disable_io_method), 740 DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method), 741 DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method), |
1251 1252 {0,0} 1253}; 1254 1255static driver_t cardbus_driver = { 1256 "cardbus", 1257 cardbus_methods, 1258 0 /* no softc */ 1259}; 1260 1261static devclass_t cardbus_devclass; 1262 1263DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0); 1264MODULE_VERSION(cardbus, 1); 1265MODULE_DEPEND(cardbus, exca, 1, 1, 1); 1266/* 1267MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 1268*/ | 742 743 {0,0} 744}; 745 746static driver_t cardbus_driver = { 747 "cardbus", 748 cardbus_methods, 749 0 /* no softc */ 750}; 751 752static devclass_t cardbus_devclass; 753 754DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0); 755MODULE_VERSION(cardbus, 1); 756MODULE_DEPEND(cardbus, exca, 1, 1, 1); 757/* 758MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 759*/ |