cardbus.c (82375) | cardbus.c (82378) |
---|---|
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 82375 2001-08-26 23:55:34Z jon $ | 28 * $FreeBSD: head/sys/dev/cardbus/cardbus.c 82378 2001-08-27 00:09:42Z jon $ |
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 * --- 7 unchanged lines hidden (view full) --- 44#include <sys/malloc.h> 45#include <sys/kernel.h> 46 47#include <sys/bus.h> 48#include <machine/bus.h> 49#include <sys/rman.h> 50#include <machine/resource.h> 51 | 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 * --- 7 unchanged lines hidden (view full) --- 44#include <sys/malloc.h> 45#include <sys/kernel.h> 46 47#include <sys/bus.h> 48#include <machine/bus.h> 49#include <sys/rman.h> 50#include <machine/resource.h> 51 |
52#include 53#include | 52#include <dev/pci/pcivar.h> 53#include <dev/pci/pcireg.h> |
54#include <sys/pciio.h> 55 56#include <dev/cardbus/cardbusreg.h> 57#include <dev/cardbus/cardbusvar.h> 58#include <dev/cardbus/cardbus_cis.h> 59 60#include "power_if.h" 61#include "card_if.h" --- 4 unchanged lines hidden (view full) --- 66#define DEVPRINTF(x) device_printf x 67#else 68#define DPRINTF(a) 69#define DEVPRINTF(x) 70#endif 71 72#if !defined(lint) 73static const char rcsid[] = | 54#include <sys/pciio.h> 55 56#include <dev/cardbus/cardbusreg.h> 57#include <dev/cardbus/cardbusvar.h> 58#include <dev/cardbus/cardbus_cis.h> 59 60#include "power_if.h" 61#include "card_if.h" --- 4 unchanged lines hidden (view full) --- 66#define DEVPRINTF(x) device_printf x 67#else 68#define DPRINTF(a) 69#define DEVPRINTF(x) 70#endif 71 72#if !defined(lint) 73static const char rcsid[] = |
74 "$FreeBSD: head/sys/dev/cardbus/cardbus.c 82375 2001-08-26 23:55:34Z jon $"; | 74 "$FreeBSD: head/sys/dev/cardbus/cardbus.c 82378 2001-08-27 00:09:42Z jon $"; |
75#endif 76 | 75#endif 76 |
77struct cardbus_quirk { 78 u_int32_t devid; /* Vendor/device of the card */ 79 int type; 80#define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */ 81 int arg1; 82 int arg2; 83}; 84 85struct cardbus_quirk cardbus_quirks[] = { 86 { 0 } 87}; 88 | |
89static int cardbus_probe(device_t cbdev); 90static int cardbus_attach(device_t cbdev); 91static int cardbus_detach(device_t cbdev); 92static void device_setup_regs(device_t brdev, int b, int s, int f, 93 pcicfgregs *cfg); 94static int cardbus_attach_card(device_t cbdev); 95static int cardbus_detach_card(device_t cbdev, int flags); 96static void cardbus_driver_added(device_t cbdev, driver_t *driver); | 77static int cardbus_probe(device_t cbdev); 78static int cardbus_attach(device_t cbdev); 79static int cardbus_detach(device_t cbdev); 80static void device_setup_regs(device_t brdev, int b, int s, int f, 81 pcicfgregs *cfg); 82static int cardbus_attach_card(device_t cbdev); 83static int cardbus_detach_card(device_t cbdev, int flags); 84static void cardbus_driver_added(device_t cbdev, driver_t *driver); |
97static struct cardbus_devinfo * cardbus_read_device(device_t brdev, int b, 98 int s, int f); | 85static void cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg); |
99static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f, 100 pcicfgregs *cfg); | 86static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f, 87 pcicfgregs *cfg); |
88static struct cardbus_devinfo *cardbus_read_device(device_t brdev, int b, 89 int s, int f); |
|
101static int cardbus_freecfg(struct cardbus_devinfo *dinfo); 102static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); 103static int cardbus_set_resource(device_t cbdev, device_t child, int type, | 90static int cardbus_freecfg(struct cardbus_devinfo *dinfo); 91static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); 92static int cardbus_set_resource(device_t cbdev, device_t child, int type, |
104 int rid, u_long start, u_long count); | 93 int rid, u_long start, u_long count, struct resource *res); |
105static int cardbus_get_resource(device_t cbdev, device_t child, int type, 106 int rid, u_long *startp, u_long *countp); 107static void cardbus_delete_resource(device_t cbdev, device_t child, 108 int type, int rid); 109static int cardbus_set_resource_method(device_t cbdev, device_t child, 110 int type, int rid, u_long start, u_long count); 111static int cardbus_get_resource_method(device_t cbdev, device_t child, 112 int type, int rid, u_long *startp, u_long *countp); 113static void cardbus_delete_resource_method(device_t cbdev, device_t child, 114 int type, int rid); | 94static int cardbus_get_resource(device_t cbdev, device_t child, int type, 95 int rid, u_long *startp, u_long *countp); 96static void cardbus_delete_resource(device_t cbdev, device_t child, 97 int type, int rid); 98static int cardbus_set_resource_method(device_t cbdev, device_t child, 99 int type, int rid, u_long start, u_long count); 100static int cardbus_get_resource_method(device_t cbdev, device_t child, 101 int type, int rid, u_long *startp, u_long *countp); 102static void cardbus_delete_resource_method(device_t cbdev, device_t child, 103 int type, int rid); |
115static int cardbus_add_map(device_t cbdev, device_t dev, pcicfgregs *cfg, 116 int reg); 117static void cardbus_add_resources(device_t dev, pcicfgregs* cfg); | |
118static void cardbus_release_all_resources(device_t cbdev, | 104static void cardbus_release_all_resources(device_t cbdev, |
119 struct resource_list *rl); 120static struct resource* cardbus_alloc_resource(device_t cbdev, device_t child, 121 int type, int* rid, u_long start, u_long end, u_long count, | 105 struct cardbus_devinfo *dinfo); 106static struct resource *cardbus_alloc_resource(device_t cbdev, device_t child, 107 int type, int *rid, u_long start, u_long end, u_long count, |
122 u_int flags); 123static int cardbus_release_resource(device_t cbdev, device_t child, 124 int type, int rid, struct resource *r); | 108 u_int flags); 109static int cardbus_release_resource(device_t cbdev, device_t child, 110 int type, int rid, struct resource *r); |
111static int cardbus_setup_intr(device_t cbdev, device_t child, 112 struct resource *irq, int flags, driver_intr_t *intr, 113 void *arg, void **cookiep); 114static int cardbus_teardown_intr(device_t cbdev, device_t child, 115 struct resource *irq, void *cookie); |
|
125static int cardbus_print_resources(struct resource_list *rl, 126 const char *name, int type, const char *format); 127static int cardbus_print_child(device_t cbdev, device_t child); 128static void cardbus_probe_nomatch(device_t cbdev, device_t child); 129static int cardbus_read_ivar(device_t cbdev, device_t child, int which, 130 u_long *result); 131static int cardbus_write_ivar(device_t cbdev, device_t child, int which, 132 uintptr_t value); | 116static int cardbus_print_resources(struct resource_list *rl, 117 const char *name, int type, const char *format); 118static int cardbus_print_child(device_t cbdev, device_t child); 119static void cardbus_probe_nomatch(device_t cbdev, device_t child); 120static int cardbus_read_ivar(device_t cbdev, device_t child, int which, 121 u_long *result); 122static int cardbus_write_ivar(device_t cbdev, device_t child, int which, 123 uintptr_t value); |
133static u_int32_t cardbus_read_config_method(device_t cbdev, | 124static int cardbus_set_powerstate_method(device_t cbdev, device_t child, 125 int state); 126static int cardbus_get_powerstate_method(device_t cbdev, device_t child); 127static u_int32_t cardbus_read_config_method(device_t cbdev, |
134 device_t child, int reg, int width); 135static void cardbus_write_config_method(device_t cbdev, device_t child, 136 int reg, u_int32_t val, int width); | 128 device_t child, int reg, int width); 129static void cardbus_write_config_method(device_t cbdev, device_t child, 130 int reg, u_int32_t val, int width); |
131static __inline void cardbus_set_command_bit(device_t cbdev, device_t child, 132 u_int16_t bit); 133static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child, 134 u_int16_t bit); 135static void cardbus_enable_busmaster_method(device_t cbdev, device_t child); 136static void cardbus_disable_busmaster_method(device_t cbdev, device_t child); 137static void cardbus_enable_io_method(device_t cbdev, device_t child, 138 int space); 139static void cardbus_disable_io_method(device_t cbdev, device_t child, 140 int space); |
|
137 138/************************************************************************/ 139/* Probe/Attach */ 140/************************************************************************/ 141 142static int 143cardbus_probe(device_t cbdev) 144{ --- 77 unchanged lines hidden (view full) --- 222 cardbus_print_verbose(dinfo); 223 dinfo->cfg.dev = device_add_child(cbdev, NULL, -1); 224 if (!dinfo->cfg.dev) { 225 DEVPRINTF((cbdev, "Cannot add child!\n")); 226 cardbus_freecfg(dinfo); 227 continue; 228 } 229 resource_list_init(&dinfo->resources); | 141 142/************************************************************************/ 143/* Probe/Attach */ 144/************************************************************************/ 145 146static int 147cardbus_probe(device_t cbdev) 148{ --- 77 unchanged lines hidden (view full) --- 226 cardbus_print_verbose(dinfo); 227 dinfo->cfg.dev = device_add_child(cbdev, NULL, -1); 228 if (!dinfo->cfg.dev) { 229 DEVPRINTF((cbdev, "Cannot add child!\n")); 230 cardbus_freecfg(dinfo); 231 continue; 232 } 233 resource_list_init(&dinfo->resources); |
234 SLIST_INIT(&dinfo->intrlist); |
|
230 device_set_ivars(dinfo->cfg.dev, dinfo); | 235 device_set_ivars(dinfo->cfg.dev, dinfo); |
231 cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg); | |
232 cardbus_do_cis(cbdev, dinfo->cfg.dev); 233 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 234 /* when fail, release all resources */ | 236 cardbus_do_cis(cbdev, dinfo->cfg.dev); 237 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { 238 /* when fail, release all resources */ |
235 cardbus_release_all_resources(dinfo->cfg.dev, 236 &dinfo->resources); | 239 cardbus_release_all_resources(cbdev, dinfo); |
237 } else 238 cardattached++; 239 } 240 } 241 242 if (cardattached > 0) 243 return 0; 244 POWER_DISABLE_SOCKET(brdev, cbdev); --- 21 unchanged lines hidden (view full) --- 266 267 for (tmp = 0; tmp < numdevs; tmp++) { 268 struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]); 269 int status = device_get_state(devlist[tmp]); 270 271 if (status == DS_ATTACHED || status == DS_BUSY) { 272 if (device_detach(dinfo->cfg.dev) == 0 || 273 flags & DETACH_FORCE) { | 240 } else 241 cardattached++; 242 } 243 } 244 245 if (cardattached > 0) 246 return 0; 247 POWER_DISABLE_SOCKET(brdev, cbdev); --- 21 unchanged lines hidden (view full) --- 269 270 for (tmp = 0; tmp < numdevs; tmp++) { 271 struct cardbus_devinfo *dinfo = device_get_ivars(devlist[tmp]); 272 int status = device_get_state(devlist[tmp]); 273 274 if (status == DS_ATTACHED || status == DS_BUSY) { 275 if (device_detach(dinfo->cfg.dev) == 0 || 276 flags & DETACH_FORCE) { |
274 cardbus_release_all_resources(dinfo->cfg.dev, 275 &dinfo->resources); | 277 cardbus_release_all_resources(cbdev, dinfo); |
276 device_delete_child(cbdev, devlist[tmp]); 277 } else { 278 err++; 279 } 280 cardbus_freecfg(dinfo); 281 } else { | 278 device_delete_child(cbdev, devlist[tmp]); 279 } else { 280 err++; 281 } 282 cardbus_freecfg(dinfo); 283 } else { |
284 cardbus_release_all_resources(cbdev, dinfo); |
|
282 device_delete_child(cbdev, devlist[tmp]); | 285 device_delete_child(cbdev, devlist[tmp]); |
286 cardbus_freecfg(dinfo); |
|
283 } 284 } 285 if (err == 0) 286 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 287 free(devlist, M_TEMP); 288 return err; 289} 290 291static void 292cardbus_driver_added(device_t cbdev, driver_t *driver) 293{ | 287 } 288 } 289 if (err == 0) 290 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); 291 free(devlist, M_TEMP); 292 return err; 293} 294 295static void 296cardbus_driver_added(device_t cbdev, driver_t *driver) 297{ |
298 /* XXX check if 16-bit or cardbus! */ |
|
294 int numdevs; 295 device_t *devlist; | 299 int numdevs; 300 device_t *devlist; |
296 device_t brdev = device_get_parent(cbdev); | |
297 int tmp, cardattached; 298 299 device_get_children(cbdev, &devlist, &numdevs); 300 301 cardattached = 0; 302 for (tmp = 0; tmp < numdevs; tmp++) { 303 if (device_get_state(devlist[tmp]) != DS_NOTPRESENT) 304 cardattached++; 305 } 306 | 301 int tmp, cardattached; 302 303 device_get_children(cbdev, &devlist, &numdevs); 304 305 cardattached = 0; 306 for (tmp = 0; tmp < numdevs; tmp++) { 307 if (device_get_state(devlist[tmp]) != DS_NOTPRESENT) 308 cardattached++; 309 } 310 |
307 if (cardattached == 0) 308 POWER_ENABLE_SOCKET(brdev, cbdev); | 311 if (cardattached == 0) { 312 free(devlist, M_TEMP); 313 CARD_REPROBE_CARD(device_get_parent(cbdev), cbdev); 314 return; 315 } 316 |
309 DEVICE_IDENTIFY(driver, cbdev); 310 for (tmp = 0; tmp < numdevs; tmp++) { 311 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT) { 312 struct cardbus_devinfo *dinfo; 313 dinfo = device_get_ivars(devlist[tmp]); | 317 DEVICE_IDENTIFY(driver, cbdev); 318 for (tmp = 0; tmp < numdevs; tmp++) { 319 if (device_get_state(devlist[tmp]) == DS_NOTPRESENT) { 320 struct cardbus_devinfo *dinfo; 321 dinfo = device_get_ivars(devlist[tmp]); |
322 cardbus_release_all_resources(cbdev, dinfo); |
|
314 resource_list_init(&dinfo->resources); | 323 resource_list_init(&dinfo->resources); |
315 cardbus_add_resources(dinfo->cfg.dev, &dinfo->cfg); | |
316 cardbus_do_cis(cbdev, dinfo->cfg.dev); 317 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { | 324 cardbus_do_cis(cbdev, dinfo->cfg.dev); 325 if (device_probe_and_attach(dinfo->cfg.dev) != 0) { |
318 cardbus_release_all_resources(dinfo->cfg.dev, 319 &dinfo->resources); | 326 cardbus_release_all_resources(cbdev, dinfo); |
320 } else 321 cardattached++; 322 } 323 } 324 | 327 } else 328 cardattached++; 329 } 330 } 331 |
325 if (cardattached == 0) 326 POWER_DISABLE_SOCKET(brdev, cbdev); | |
327 free(devlist, M_TEMP); 328} 329 330/************************************************************************/ 331/* PCI-Like config reading (copied from pci.c */ 332/************************************************************************/ 333 334/* read configuration header into pcicfgrect structure */ 335 | 332 free(devlist, M_TEMP); 333} 334 335/************************************************************************/ 336/* PCI-Like config reading (copied from pci.c */ 337/************************************************************************/ 338 339/* read configuration header into pcicfgrect structure */ 340 |
341static void 342cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg) 343{ 344#define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w) 345 int ptr, nextptr, ptrptr; 346 347 switch (cfg->hdrtype) { 348 case 0: 349 ptrptr = 0x34; 350 break; 351 case 2: 352 ptrptr = 0x14; 353 break; 354 default: 355 return; /* no extended capabilities support */ 356 } 357 nextptr = REG(ptrptr, 1); /* sanity check? */ 358 359 /* 360 * Read capability entries. 361 */ 362 while (nextptr != 0) { 363 /* Sanity check */ 364 if (nextptr > 255) { 365 printf("illegal PCI extended capability offset %d\n", 366 nextptr); 367 return; 368 } 369 /* Find the next entry */ 370 ptr = nextptr; 371 nextptr = REG(ptr + 1, 1); 372 373 /* Process this entry */ 374 switch (REG(ptr, 1)) { 375 case 0x01: /* PCI power management */ 376 if (cfg->pp_cap == 0) { 377 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2); 378 cfg->pp_status = ptr + PCIR_POWER_STATUS; 379 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR; 380 if ((nextptr - ptr) > PCIR_POWER_DATA) 381 cfg->pp_data = ptr + PCIR_POWER_DATA; 382 } 383 break; 384 default: 385 break; 386 } 387 } 388#undef REG 389} 390 391/* extract header type specific config data */ 392 393static void 394cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg) 395{ 396#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 397 switch (cfg->hdrtype) { 398 case 0: 399 cfg->subvendor = REG(PCIR_SUBVEND_0, 2); 400 cfg->subdevice = REG(PCIR_SUBDEV_0, 2); 401 cfg->nummaps = PCI_MAXMAPS_0; 402 break; 403 case 1: 404 cfg->subvendor = REG(PCIR_SUBVEND_1, 2); 405 cfg->subdevice = REG(PCIR_SUBDEV_1, 2); 406 cfg->nummaps = PCI_MAXMAPS_1; 407 break; 408 case 2: 409 cfg->subvendor = REG(PCIR_SUBVEND_2, 2); 410 cfg->subdevice = REG(PCIR_SUBDEV_2, 2); 411 cfg->nummaps = PCI_MAXMAPS_2; 412 break; 413 } 414#undef REG 415} 416 |
|
336static struct cardbus_devinfo * 337cardbus_read_device(device_t brdev, int b, int s, int f) 338{ 339#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 340 pcicfgregs *cfg = NULL; 341 struct cardbus_devinfo *devlist_entry = NULL; 342 | 417static struct cardbus_devinfo * 418cardbus_read_device(device_t brdev, int b, int s, int f) 419{ 420#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 421 pcicfgregs *cfg = NULL; 422 struct cardbus_devinfo *devlist_entry = NULL; 423 |
343 if (PCIB_READ_CONFIG(brdev, b, s, f, PCIR_DEVVENDOR, 4) != -1) { | 424 if (REG(PCIR_DEVVENDOR, 4) != -1) { |
344 devlist_entry = malloc(sizeof(struct cardbus_devinfo), 345 M_DEVBUF, M_WAITOK | M_ZERO); 346 if (devlist_entry == NULL) 347 return (NULL); 348 349 cfg = &devlist_entry->cfg; 350 351 cfg->bus = b; --- 7 unchanged lines hidden (view full) --- 359 cfg->subclass = REG(PCIR_SUBCLASS, 1); 360 cfg->progif = REG(PCIR_PROGIF, 1); 361 cfg->revid = REG(PCIR_REVID, 1); 362 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); 363 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); 364 cfg->lattimer = REG(PCIR_LATTIMER, 1); 365 cfg->intpin = REG(PCIR_INTPIN, 1); 366 cfg->intline = REG(PCIR_INTLINE, 1); | 425 devlist_entry = malloc(sizeof(struct cardbus_devinfo), 426 M_DEVBUF, M_WAITOK | M_ZERO); 427 if (devlist_entry == NULL) 428 return (NULL); 429 430 cfg = &devlist_entry->cfg; 431 432 cfg->bus = b; --- 7 unchanged lines hidden (view full) --- 440 cfg->subclass = REG(PCIR_SUBCLASS, 1); 441 cfg->progif = REG(PCIR_PROGIF, 1); 442 cfg->revid = REG(PCIR_REVID, 1); 443 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1); 444 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); 445 cfg->lattimer = REG(PCIR_LATTIMER, 1); 446 cfg->intpin = REG(PCIR_INTPIN, 1); 447 cfg->intline = REG(PCIR_INTLINE, 1); |
367#ifdef __alpha__ 368 alpha_platform_assign_pciintr(cfg); 369#endif | |
370 | 448 |
371#ifdef APIC_IO 372 if (cfg->intpin != 0) { 373 int airq; 374 375 airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); 376 if (airq >= 0) { 377 /* PCI specific entry found in MP table */ 378 if (airq != cfg->intline) { 379 undirect_pci_irq(cfg->intline); 380 cfg->intline = airq; 381 } 382 } else { 383 /* 384 * PCI interrupts might be redirected to the 385 * ISA bus according to some MP tables. Use the 386 * same methods as used by the ISA devices 387 * devices to find the proper IOAPIC int pin. 388 */ 389 airq = isa_apic_irq(cfg->intline); 390 if ((airq >= 0) && (airq != cfg->intline)) { 391 /* XXX: undirect_pci_irq() ? */ 392 undirect_isa_irq(cfg->intline); 393 cfg->intline = airq; 394 } 395 } 396 } 397#endif /* APIC_IO */ 398 | |
399 cfg->mingnt = REG(PCIR_MINGNT, 1); 400 cfg->maxlat = REG(PCIR_MAXLAT, 1); 401 402 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 403 cfg->hdrtype &= ~PCIM_MFDEV; 404 405 cardbus_hdrtypedata(brdev, b, s, f, cfg); 406 | 449 cfg->mingnt = REG(PCIR_MINGNT, 1); 450 cfg->maxlat = REG(PCIR_MAXLAT, 1); 451 452 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 453 cfg->hdrtype &= ~PCIM_MFDEV; 454 455 cardbus_hdrtypedata(brdev, b, s, f, cfg); 456 |
457 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) 458 cardbus_read_extcap(brdev, cfg); 459 |
|
407 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 408 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 409 devlist_entry->conf.pc_sel.pc_func = cfg->func; 410 devlist_entry->conf.pc_hdr = cfg->hdrtype; 411 412 devlist_entry->conf.pc_subvendor = cfg->subvendor; 413 devlist_entry->conf.pc_subdevice = cfg->subdevice; 414 devlist_entry->conf.pc_vendor = cfg->vendor; 415 devlist_entry->conf.pc_device = cfg->device; 416 417 devlist_entry->conf.pc_class = cfg->baseclass; 418 devlist_entry->conf.pc_subclass = cfg->subclass; 419 devlist_entry->conf.pc_progif = cfg->progif; 420 devlist_entry->conf.pc_revid = cfg->revid; 421 } 422 return (devlist_entry); 423#undef REG 424} 425 | 460 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 461 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 462 devlist_entry->conf.pc_sel.pc_func = cfg->func; 463 devlist_entry->conf.pc_hdr = cfg->hdrtype; 464 465 devlist_entry->conf.pc_subvendor = cfg->subvendor; 466 devlist_entry->conf.pc_subdevice = cfg->subdevice; 467 devlist_entry->conf.pc_vendor = cfg->vendor; 468 devlist_entry->conf.pc_device = cfg->device; 469 470 devlist_entry->conf.pc_class = cfg->baseclass; 471 devlist_entry->conf.pc_subclass = cfg->subclass; 472 devlist_entry->conf.pc_progif = cfg->progif; 473 devlist_entry->conf.pc_revid = cfg->revid; 474 } 475 return (devlist_entry); 476#undef REG 477} 478 |
426/* extract header type specific config data */ 427 428static void 429cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg) 430{ 431#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) 432 switch (cfg->hdrtype) { 433 case 0: 434 cfg->subvendor = REG(PCIR_SUBVEND_0, 2); 435 cfg->subdevice = REG(PCIR_SUBDEV_0, 2); 436 cfg->nummaps = PCI_MAXMAPS_0; 437 break; 438 case 1: 439 cfg->subvendor = REG(PCIR_SUBVEND_1, 2); 440 cfg->subdevice = REG(PCIR_SUBDEV_1, 2); 441 cfg->nummaps = PCI_MAXMAPS_1; 442 break; 443 case 2: 444 cfg->subvendor = REG(PCIR_SUBVEND_2, 2); 445 cfg->subdevice = REG(PCIR_SUBDEV_2, 2); 446 cfg->nummaps = PCI_MAXMAPS_2; 447 break; 448 } 449#undef REG 450} 451 | |
452/* free pcicfgregs structure and all depending data structures */ 453 454static int 455cardbus_freecfg(struct cardbus_devinfo *dinfo) 456{ 457 free(dinfo, M_DEVBUF); 458 459 return (0); 460} 461 462static void 463cardbus_print_verbose(struct cardbus_devinfo *dinfo) 464{ | 479/* free pcicfgregs structure and all depending data structures */ 480 481static int 482cardbus_freecfg(struct cardbus_devinfo *dinfo) 483{ 484 free(dinfo, M_DEVBUF); 485 486 return (0); 487} 488 489static void 490cardbus_print_verbose(struct cardbus_devinfo *dinfo) 491{ |
465 if (bootverbose) { | 492#ifndef CARDBUS_DEBUG 493 if (bootverbose) 494#endif /* CARDBUS_DEBUG */ 495 { |
466 pcicfgregs *cfg = &dinfo->cfg; 467 468 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 469 cfg->vendor, cfg->device, cfg->revid); 470 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 471 cfg->baseclass, cfg->subclass, cfg->progif, 472 cfg->hdrtype, cfg->mfdev); 473#ifdef CARDBUS_DEBUG --- 13 unchanged lines hidden (view full) --- 487} 488 489/************************************************************************/ 490/* Resources */ 491/************************************************************************/ 492 493static int 494cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, | 496 pcicfgregs *cfg = &dinfo->cfg; 497 498 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 499 cfg->vendor, cfg->device, cfg->revid); 500 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 501 cfg->baseclass, cfg->subclass, cfg->progif, 502 cfg->hdrtype, cfg->mfdev); 503#ifdef CARDBUS_DEBUG --- 13 unchanged lines hidden (view full) --- 517} 518 519/************************************************************************/ 520/* Resources */ 521/************************************************************************/ 522 523static int 524cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, |
495 u_long start, u_long count) | 525 u_long start, u_long count, struct resource *res) |
496{ | 526{ |
497 struct cardbus_devinfo *dinfo = device_get_ivars(child); 498 struct resource_list *rl = &dinfo->resources; 499 resource_list_add(rl, type, rid, start, start + count - 1, count); | 527 struct cardbus_devinfo *dinfo; 528 struct resource_list *rl; 529 struct resource_list_entry *rle; 530 531 if (device_get_parent(child) != cbdev) 532 return ENOENT; 533 534 dinfo = device_get_ivars(child); 535 rl = &dinfo->resources; 536 rle = resource_list_find(rl, type, rid); 537 if (rle == NULL) { 538 resource_list_add(rl, type, rid, start, start + count - 1, 539 count); 540 if (res != NULL) { 541 rle = resource_list_find(rl, type, rid); 542 rle->res = res; 543 } 544 } else { 545 if (rle->res == NULL) { 546 } else if (rle->res->r_dev == cbdev && 547 (!(rman_get_flags(rle->res) & RF_ACTIVE))) { 548 int f; 549 f = rman_get_flags(rle->res); 550 bus_release_resource(cbdev, type, rid, res); 551 rle->res = bus_alloc_resource(cbdev, type, &rid, 552 start, start + count - 1, 553 count, f); 554 } else { 555 device_printf(cbdev, "set_resource: resource busy\n"); 556 return EBUSY; 557 } 558 rle->start = start; 559 rle->end = start + count - 1; 560 rle->count = count; 561 if (res != NULL) 562 rle->res = res; 563 } |
500 if (device_get_parent(child) == cbdev) 501 pci_write_config(child, rid, start, 4); 502 return 0; 503} 504 505static int 506cardbus_get_resource(device_t cbdev, device_t child, int type, int rid, 507 u_long *startp, u_long *countp) 508{ | 564 if (device_get_parent(child) == cbdev) 565 pci_write_config(child, rid, start, 4); 566 return 0; 567} 568 569static int 570cardbus_get_resource(device_t cbdev, device_t child, int type, int rid, 571 u_long *startp, u_long *countp) 572{ |
509 struct cardbus_devinfo *dinfo = device_get_ivars(child); 510 struct resource_list *rl = &dinfo->resources; | 573 struct cardbus_devinfo *dinfo; 574 struct resource_list *rl; |
511 struct resource_list_entry *rle; | 575 struct resource_list_entry *rle; |
576 577 if (device_get_parent(child) != cbdev) 578 return ENOENT; 579 580 dinfo = device_get_ivars(child); 581 rl = &dinfo->resources; |
|
512 rle = resource_list_find(rl, type, rid); 513 if (!rle) 514 return ENOENT; 515 if (startp) 516 *startp = rle->start; 517 if (countp) 518 *countp = rle->count; 519 return 0; 520} 521 522static void 523cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid) 524{ | 582 rle = resource_list_find(rl, type, rid); 583 if (!rle) 584 return ENOENT; 585 if (startp) 586 *startp = rle->start; 587 if (countp) 588 *countp = rle->count; 589 return 0; 590} 591 592static void 593cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid) 594{ |
525 struct cardbus_devinfo *dinfo = device_get_ivars(child); 526 struct resource_list *rl = &dinfo->resources; | 595 struct cardbus_devinfo *dinfo; 596 struct resource_list *rl; |
527 struct resource_list_entry *rle; | 597 struct resource_list_entry *rle; |
598 599 if (device_get_parent(child) != cbdev) 600 return; 601 602 dinfo = device_get_ivars(child); 603 rl = &dinfo->resources; |
|
528 rle = resource_list_find(rl, type, rid); 529 if (rle) { | 604 rle = resource_list_find(rl, type, rid); 605 if (rle) { |
530 if (rle->res) 531 bus_generic_release_resource(cbdev, child, type, rid, 532 rle->res); | 606 if (rle->res) { 607 if (rle->res->r_dev != cbdev || 608 rman_get_flags(rle->res) & RF_ACTIVE) { 609 device_printf(cbdev, "delete_resource: " 610 "Resource still owned by child, oops. " 611 "(type=%d, rid=%d, addr=%lx)\n", 612 rle->type, rle->rid, 613 rman_get_start(rle->res)); 614 return; 615 } 616 bus_release_resource(cbdev, type, rid, rle->res); 617 } |
533 resource_list_delete(rl, type, rid); 534 } 535 if (device_get_parent(child) == cbdev) 536 pci_write_config(child, rid, 0, 4); 537} 538 539static int 540cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid, 541 u_long start, u_long count) 542{ 543 int ret; | 618 resource_list_delete(rl, type, rid); 619 } 620 if (device_get_parent(child) == cbdev) 621 pci_write_config(child, rid, 0, 4); 622} 623 624static int 625cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid, 626 u_long start, u_long count) 627{ 628 int ret; |
544 ret = cardbus_set_resource(cbdev, child, type, rid, start, count); | 629 ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL); |
545 if (ret != 0) 546 return ret; 547 return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid, 548 start, count); 549} 550 551static int 552cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid, --- 10 unchanged lines hidden (view full) --- 563static void 564cardbus_delete_resource_method(device_t cbdev, device_t child, 565 int type, int rid) 566{ 567 cardbus_delete_resource(cbdev, child, type, rid); 568 BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid); 569} 570 | 630 if (ret != 0) 631 return ret; 632 return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid, 633 start, count); 634} 635 636static int 637cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid, --- 10 unchanged lines hidden (view full) --- 648static void 649cardbus_delete_resource_method(device_t cbdev, device_t child, 650 int type, int rid) 651{ 652 cardbus_delete_resource(cbdev, child, type, rid); 653 BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid); 654} 655 |
571static int 572cardbus_add_map(device_t cbdev, device_t dev, pcicfgregs *cfg, int reg) 573{ 574 struct cardbus_devinfo *dinfo = device_get_ivars(dev); 575 struct resource_list *rl = &dinfo->resources; 576 struct resource_list_entry *rle; 577 struct resource *res; 578 device_t bdev = device_get_parent(cbdev); 579 u_int32_t size; 580 u_int32_t testval; 581 int type; 582 583 if (reg == CARDBUS_ROM_REG) 584 testval = CARDBUS_ROM_ADDRMASK; 585 else 586 testval = ~0; 587 588 PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 589 reg, testval, 4); 590 591 testval = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 592 reg, 4); 593 if (testval == ~0 || testval == 0) 594 return 0; 595 596 if ((testval&1) == 0) 597 type = SYS_RES_MEMORY; 598 else 599 type = SYS_RES_IOPORT; 600 601 size = CARDBUS_MAPREG_MEM_SIZE(testval); 602 res = bus_generic_alloc_resource(cbdev, dev, type, ®, 0, ~0, size, 603 rman_make_alignment_flags(size)); 604 if (res) { 605 u_int32_t start = rman_get_start(res); 606 u_int32_t end = rman_get_end(res); 607 cardbus_set_resource(cbdev, dev, type, reg, start,end-start+1); 608 rle = resource_list_find(rl, type, reg); 609 rle->res = res; 610 } else { 611 device_printf(dev, "Unable to add map %02x\n", reg); 612 type = 0; 613 } 614 return type; 615} 616 | |
617static void | 656static void |
618cardbus_add_resources(device_t dev, pcicfgregs* cfg) | 657cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo) |
619{ | 658{ |
620 device_t cbdev = device_get_parent(dev); 621 device_t bdev = device_get_parent(cbdev); 622 struct cardbus_devinfo *dinfo = device_get_ivars(dev); 623 struct resource_list *rl = &dinfo->resources; 624 struct cardbus_quirk *q; | |
625 struct resource_list_entry *rle; | 659 struct resource_list_entry *rle; |
626 struct resource *res; 627 int rid; 628 u_int command; 629 int type; 630 int types; 631 int i; | 660 struct cardbus_intrlist *ile; |
632 | 661 |
633 types = 0; 634 for (i = 0; i < cfg->nummaps; i++) { 635 type = cardbus_add_map(cbdev, dev, cfg, PCIR_MAPS + i*4); 636 types |= 0x1 << type; | 662 /* Remove any interrupt handlers */ 663 while (NULL != (ile = SLIST_FIRST(&dinfo->intrlist))) { 664 device_printf(cbdev, "release_all_resource: " 665 "intr handler still active, removing.\n"); 666 bus_teardown_intr(ile->dev, ile->irq, ile->cookie); 667 SLIST_REMOVE_HEAD(&dinfo->intrlist, link); 668 free(ile, M_DEVBUF); |
637 } | 669 } |
638 type = cardbus_add_map(cbdev, dev, cfg, CARDBUS_ROM_REG); 639 types |= 0x1 << type; | |
640 | 670 |
641 for (q = &cardbus_quirks[0]; q->devid; q++) { 642 if (q->devid == ((cfg->device << 16) | cfg->vendor) 643 && q->type == CARDBUS_QUIRK_MAP_REG) { 644 type = cardbus_add_map(cbdev, dev, cfg, q->arg1); 645 types |= 0x1 << type; | 671 /* Free all allocated resources */ 672 SLIST_FOREACH(rle, &dinfo->resources, link) { 673 if (rle->res) { 674 if (rle->res->r_dev != cbdev) 675 device_printf(cbdev, "release_all_resource: " 676 "Resource still owned by child, oops. " 677 "(type=%d, rid=%d, addr=%lx)\n", 678 rle->type, rle->rid, 679 rman_get_start(rle->res)); 680 BUS_RELEASE_RESOURCE(device_get_parent(cbdev), 681 rle->res->r_dev, 682 rle->type, rle->rid, 683 rle->res); 684 rle->res = NULL; 685 /* 686 * zero out config so the card won't acknowledge 687 * access to the space anymore 688 */ 689 pci_write_config(dinfo->cfg.dev, rle->rid, 0, 4); |
646 } 647 } | 690 } 691 } |
648 649 command = PCIB_READ_CONFIG(bdev, cfg->bus, cfg->slot, 650 cfg->func, PCIR_COMMAND, 2); 651 if ((types & (0x1 << SYS_RES_MEMORY)) != 0) 652 command |= PCIM_CMD_MEMEN; 653 if ((types & (0x1 << SYS_RES_IOPORT)) != 0) 654 command |= PCIM_CMD_PORTEN; 655 command |= PCIM_CMD_BUSMASTEREN; 656 PCIB_WRITE_CONFIG(bdev, cfg->bus, cfg->slot, cfg->func, 657 PCIR_COMMAND, command, 2); 658 659 rid = 0; 660 res = bus_generic_alloc_resource(cbdev, dev, SYS_RES_IRQ, 661 &rid, 0, ~0, 1, RF_SHAREABLE); 662 663 if (res == NULL) 664 panic("Cannot allocate IRQ for card\n"); 665 666 resource_list_add(rl, SYS_RES_IRQ, rid, 667 rman_get_start(res), rman_get_start(res), 1); 668 rle = resource_list_find(rl, SYS_RES_IRQ, rid); 669 rle->res = res; | 692 resource_list_free(&dinfo->resources); |
670} 671 | 693} 694 |
672static void 673cardbus_release_all_resources(device_t cbdev, struct resource_list *rl) | 695static struct resource * 696cardbus_alloc_resource(device_t cbdev, device_t child, int type, 697 int *rid, u_long start, u_long end, u_long count, u_int flags) |
674{ | 698{ |
675 struct resource_list_entry *rle; | 699 struct cardbus_devinfo *dinfo; 700 struct resource_list_entry *rle = 0; 701 int passthrough = (device_get_parent(child) != cbdev); |
676 | 702 |
677 SLIST_FOREACH(rle, rl, link) { 678 if (rle->res) { 679 bus_generic_release_resource(device_get_parent(cbdev), 680 cbdev, rle->type, rle->rid, 681 rle->res); 682 } | 703 if (passthrough) { 704 return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child, 705 type, rid, start, end, count, flags)); |
683 } | 706 } |
684} | |
685 | 707 |
686static struct resource* 687cardbus_alloc_resource(device_t cbdev, device_t child, int type, 688 int* rid, u_long start, u_long end, u_long count, u_int flags) 689{ 690 struct cardbus_devinfo *dinfo = device_get_ivars(child); 691 struct resource_list *rl = &dinfo->resources; 692 struct resource_list_entry *rle = NULL; 693 struct resource *res; | 708 dinfo = device_get_ivars(child); 709 rle = resource_list_find(&dinfo->resources, type, *rid); |
694 | 710 |
695 if (device_get_parent(child) == cbdev || child == cbdev) 696 rle = resource_list_find(rl, type, *rid); 697 if (rle) { 698 if (flags & RF_ACTIVE) { 699 if (bus_activate_resource(child, rle->type, *rid, 700 rle->res)) { 701 return NULL; 702 } 703 if (*rid == CARDBUS_ROM_REG) { 704 uint32_t rom_reg; | 711 if (!rle) 712 return NULL; /* no resource of that type/rid */ |
705 | 713 |
706 rom_reg = pci_read_config(child, *rid, 4); 707 rom_reg |= CARDBUS_ROM_ENABLE; 708 pci_write_config(child, *rid, rom_reg, 4); 709 } 710 } 711 return rle->res; /* XXX: check if range within start/end */ | 714 if (!rle->res) { 715 device_printf(cbdev, "WARNING: Resource not reserved by bus\n"); 716 return NULL; |
712 } else { | 717 } else { |
713 res = bus_generic_alloc_resource(cbdev, child, type, rid, 714 start, end, count, flags); 715 if (res) { 716 start = rman_get_start(res); 717 end = rman_get_end(res); 718 cardbus_set_resource(cbdev, child, type, *rid, start, 719 end-start+1); 720 rle = resource_list_find(rl, type, *rid); 721 rle->res = res; 722 return res; 723 } else { 724 device_printf(cbdev, "Resource Allocation Failed!\n"); | 718 /* Release the cardbus hold on the resource */ 719 if (rle->res->r_dev != cbdev) |
725 return NULL; | 720 return NULL; |
721 bus_release_resource(cbdev, type, *rid, rle->res); 722 rle->res = NULL; 723 switch (type) { 724 case SYS_RES_IOPORT: 725 case SYS_RES_MEMORY: 726 if (!(flags & RF_ALIGNMENT_MASK)) 727 flags |= rman_make_alignment_flags(rle->count); 728 break; 729 case SYS_RES_IRQ: 730 flags |= RF_SHAREABLE; 731 break; |
|
726 } | 732 } |
733 /* Allocate the resource to the child */ 734 return resource_list_alloc(&dinfo->resources, cbdev, child, 735 type, rid, rle->start, rle->end, rle->count, flags); |
|
727 } 728} 729 730static int 731cardbus_release_resource(device_t cbdev, device_t child, int type, int rid, 732 struct resource *r) 733{ | 736 } 737} 738 739static int 740cardbus_release_resource(device_t cbdev, device_t child, int type, int rid, 741 struct resource *r) 742{ |
743 struct cardbus_devinfo *dinfo; 744 int passthrough = (device_get_parent(child) != cbdev); 745 struct resource_list_entry *rle = 0; 746 int flags; 747 int ret; 748 749 if (passthrough) { 750 return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, 751 type, rid, r); 752 } 753 754 dinfo = device_get_ivars(child); |
|
734 /* 735 * According to the PCI 2.2 spec, devices may share an address 736 * decoder between memory mapped ROM access and memory 737 * mapped register access. To be safe, disable ROM access 738 * whenever it is released. 739 */ 740 if (rid == CARDBUS_ROM_REG) { 741 uint32_t rom_reg; 742 743 rom_reg = pci_read_config(child, rid, 4); 744 rom_reg &= ~CARDBUS_ROM_ENABLE; 745 pci_write_config(child, rid, rom_reg, 4); 746 } 747 | 755 /* 756 * According to the PCI 2.2 spec, devices may share an address 757 * decoder between memory mapped ROM access and memory 758 * mapped register access. To be safe, disable ROM access 759 * whenever it is released. 760 */ 761 if (rid == CARDBUS_ROM_REG) { 762 uint32_t rom_reg; 763 764 rom_reg = pci_read_config(child, rid, 4); 765 rom_reg &= ~CARDBUS_ROM_ENABLE; 766 pci_write_config(child, rid, rom_reg, 4); 767 } 768 |
748 return bus_deactivate_resource(child, type, rid, r); | 769 rle = resource_list_find(&dinfo->resources, type, rid); 770 771 if (!rle) { 772 device_printf(cbdev, "Allocated resource not found\n"); 773 return ENOENT; 774 } 775 if (!rle->res) { 776 device_printf(cbdev, "Allocated resource not recorded\n"); 777 return ENOENT; 778 } 779 780 ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, 781 type, rid, r); 782 switch (type) { 783 case SYS_RES_IOPORT: 784 case SYS_RES_MEMORY: 785 flags = rman_make_alignment_flags(rle->count); 786 break; 787 case SYS_RES_IRQ: 788 flags = RF_SHAREABLE; 789 break; 790 default: 791 flags = 0; 792 } 793 /* Restore cardbus hold on the resource */ 794 rle->res = bus_alloc_resource(cbdev, type, &rid, 795 rle->start, rle->end, rle->count, flags); 796 if (rle->res == NULL) 797 device_printf(cbdev, "release_resource: " 798 "unable to reacquire resource\n"); 799 return ret; |
749} 750 | 800} 801 |
802static int 803cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq, 804 int flags, driver_intr_t *intr, void *arg, void **cookiep) 805{ 806 int ret; 807 struct cardbus_intrlist *ile; 808 device_t cdev; 809 struct cardbus_devinfo *dinfo; 810 811 ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg, 812 cookiep); 813 if (ret != 0) 814 return ret; 815 816 for (cdev = child; cbdev != device_get_parent(cdev); 817 cdev = device_get_parent(cdev)) 818 /* NOTHING */; 819 dinfo = device_get_ivars(cdev); 820 821 /* record interrupt handler */ 822 ile = malloc(sizeof(struct cardbus_intrlist), M_DEVBUF, M_NOWAIT); 823 ile->dev = child; 824 ile->irq = irq; 825 ile->cookie = *cookiep; 826 827 SLIST_INSERT_HEAD(&dinfo->intrlist, ile, link); 828 return 0; 829} 830 831static int 832cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq, 833 void *cookie) 834{ 835 int ret; 836 struct cardbus_intrlist *ile; 837 device_t cdev; 838 struct cardbus_devinfo *dinfo; 839 840 ret = bus_generic_teardown_intr(cbdev, child, irq, cookie); 841 if (ret != 0) 842 return ret; 843 844 for (cdev = child; cbdev != device_get_parent(cdev); 845 cdev = device_get_parent(cdev)) 846 /* NOTHING */; 847 dinfo = device_get_ivars(cdev); 848 849 /* remove interrupt handler from record */ 850 SLIST_FOREACH(ile, &dinfo->intrlist, link) { 851 if (ile->irq == irq && ile->cookie == cookie) { 852 SLIST_REMOVE(&dinfo->intrlist, ile, cardbus_intrlist, 853 link); 854 free(ile, M_DEVBUF); 855 return 0; 856 } 857 } 858 device_printf(cbdev, "teardown_intr: intr handler not recorded.\n"); 859 return ENOENT; 860} 861 862 |
|
751/************************************************************************/ 752/* Other Bus Methods */ 753/************************************************************************/ 754 755static int 756cardbus_print_resources(struct resource_list *rl, const char *name, 757 int type, const char *format) 758{ --- 156 unchanged lines hidden (view full) --- 915 } 916 return 0; 917} 918 919/************************************************************************/ 920/* Compatibility with PCI bus (XXX: Do we need this?) */ 921/************************************************************************/ 922 | 863/************************************************************************/ 864/* Other Bus Methods */ 865/************************************************************************/ 866 867static int 868cardbus_print_resources(struct resource_list *rl, const char *name, 869 int type, const char *format) 870{ --- 156 unchanged lines hidden (view full) --- 1027 } 1028 return 0; 1029} 1030 1031/************************************************************************/ 1032/* Compatibility with PCI bus (XXX: Do we need this?) */ 1033/************************************************************************/ 1034 |
1035/* 1036 * PCI power manangement 1037 */ 1038static int 1039cardbus_set_powerstate_method(device_t cbdev, device_t child, int state) 1040{ 1041 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1042 pcicfgregs *cfg = &dinfo->cfg; 1043 u_int16_t status; 1044 int result; 1045 1046 if (cfg->pp_cap != 0) { 1047 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2) 1048 & ~PCIM_PSTAT_DMASK; 1049 result = 0; 1050 switch (state) { 1051 case PCI_POWERSTATE_D0: 1052 status |= PCIM_PSTAT_D0; 1053 break; 1054 case PCI_POWERSTATE_D1: 1055 if (cfg->pp_cap & PCIM_PCAP_D1SUPP) { 1056 status |= PCIM_PSTAT_D1; 1057 } else { 1058 result = EOPNOTSUPP; 1059 } 1060 break; 1061 case PCI_POWERSTATE_D2: 1062 if (cfg->pp_cap & PCIM_PCAP_D2SUPP) { 1063 status |= PCIM_PSTAT_D2; 1064 } else { 1065 result = EOPNOTSUPP; 1066 } 1067 break; 1068 case PCI_POWERSTATE_D3: 1069 status |= PCIM_PSTAT_D3; 1070 break; 1071 default: 1072 result = EINVAL; 1073 } 1074 if (result == 0) 1075 PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status, 1076 status, 2); 1077 } else { 1078 result = ENXIO; 1079 } 1080 return (result); 1081} 1082 1083static int 1084cardbus_get_powerstate_method(device_t cbdev, device_t child) 1085{ 1086 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1087 pcicfgregs *cfg = &dinfo->cfg; 1088 u_int16_t status; 1089 int result; 1090 1091 if (cfg->pp_cap != 0) { 1092 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2); 1093 switch (status & PCIM_PSTAT_DMASK) { 1094 case PCIM_PSTAT_D0: 1095 result = PCI_POWERSTATE_D0; 1096 break; 1097 case PCIM_PSTAT_D1: 1098 result = PCI_POWERSTATE_D1; 1099 break; 1100 case PCIM_PSTAT_D2: 1101 result = PCI_POWERSTATE_D2; 1102 break; 1103 case PCIM_PSTAT_D3: 1104 result = PCI_POWERSTATE_D3; 1105 break; 1106 default: 1107 result = PCI_POWERSTATE_UNKNOWN; 1108 break; 1109 } 1110 } else { 1111 /* No support, device is always at D0 */ 1112 result = PCI_POWERSTATE_D0; 1113 } 1114 return (result); 1115} 1116 |
|
923static u_int32_t 924cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width) 925{ 926 struct cardbus_devinfo *dinfo = device_get_ivars(child); 927 pcicfgregs *cfg = &dinfo->cfg; 928 929 return PCIB_READ_CONFIG(device_get_parent(cbdev), 930 cfg->bus, cfg->slot, cfg->func, reg, width); --- 5 unchanged lines hidden (view full) --- 936{ 937 struct cardbus_devinfo *dinfo = device_get_ivars(child); 938 pcicfgregs *cfg = &dinfo->cfg; 939 940 PCIB_WRITE_CONFIG(device_get_parent(cbdev), 941 cfg->bus, cfg->slot, cfg->func, reg, val, width); 942} 943 | 1117static u_int32_t 1118cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width) 1119{ 1120 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1121 pcicfgregs *cfg = &dinfo->cfg; 1122 1123 return PCIB_READ_CONFIG(device_get_parent(cbdev), 1124 cfg->bus, cfg->slot, cfg->func, reg, width); --- 5 unchanged lines hidden (view full) --- 1130{ 1131 struct cardbus_devinfo *dinfo = device_get_ivars(child); 1132 pcicfgregs *cfg = &dinfo->cfg; 1133 1134 PCIB_WRITE_CONFIG(device_get_parent(cbdev), 1135 cfg->bus, cfg->slot, cfg->func, reg, val, width); 1136} 1137 |
1138static __inline void 1139cardbus_set_command_bit(device_t cbdev, device_t child, u_int16_t bit) 1140{ 1141 u_int16_t command; 1142 1143 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1144 command |= bit; 1145 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1146} 1147 1148static __inline void 1149cardbus_clear_command_bit(device_t cbdev, device_t child, u_int16_t bit) 1150{ 1151 u_int16_t command; 1152 1153 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); 1154 command &= ~bit; 1155 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); 1156} 1157 1158static void 1159cardbus_enable_busmaster_method(device_t cbdev, device_t child) 1160{ 1161 cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1162} 1163 1164static void 1165cardbus_disable_busmaster_method(device_t cbdev, device_t child) 1166{ 1167 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); 1168} 1169 1170static void 1171cardbus_enable_io_method(device_t cbdev, device_t child, int space) 1172{ 1173 switch (space) { 1174 case SYS_RES_IOPORT: 1175 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1176 break; 1177 case SYS_RES_MEMORY: 1178 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1179 break; 1180 } 1181} 1182 1183static void 1184cardbus_disable_io_method(device_t cbdev, device_t child, int space) 1185{ 1186 switch (space) { 1187 case SYS_RES_IOPORT: 1188 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN); 1189 break; 1190 case SYS_RES_MEMORY: 1191 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN); 1192 break; 1193 } 1194} 1195 |
|
944static device_method_t cardbus_methods[] = { 945 /* Device interface */ 946 DEVMETHOD(device_probe, cardbus_probe), 947 DEVMETHOD(device_attach, cardbus_attach), 948 DEVMETHOD(device_detach, cardbus_detach), 949 DEVMETHOD(device_shutdown, bus_generic_shutdown), 950 DEVMETHOD(device_suspend, bus_generic_suspend), 951 DEVMETHOD(device_resume, bus_generic_resume), 952 953 /* Bus interface */ 954 DEVMETHOD(bus_print_child, cardbus_print_child), 955 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), 956 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 957 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 958 DEVMETHOD(bus_driver_added, cardbus_driver_added), 959 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 960 DEVMETHOD(bus_release_resource, cardbus_release_resource), 961 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 962 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), | 1196static device_method_t cardbus_methods[] = { 1197 /* Device interface */ 1198 DEVMETHOD(device_probe, cardbus_probe), 1199 DEVMETHOD(device_attach, cardbus_attach), 1200 DEVMETHOD(device_detach, cardbus_detach), 1201 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1202 DEVMETHOD(device_suspend, bus_generic_suspend), 1203 DEVMETHOD(device_resume, bus_generic_resume), 1204 1205 /* Bus interface */ 1206 DEVMETHOD(bus_print_child, cardbus_print_child), 1207 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), 1208 DEVMETHOD(bus_read_ivar, cardbus_read_ivar), 1209 DEVMETHOD(bus_write_ivar, cardbus_write_ivar), 1210 DEVMETHOD(bus_driver_added, cardbus_driver_added), 1211 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), 1212 DEVMETHOD(bus_release_resource, cardbus_release_resource), 1213 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1214 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), |
963 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 964 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 965 DEVMETHOD(bus_driver_added, bus_generic_driver_added), | 1215 DEVMETHOD(bus_setup_intr, cardbus_setup_intr), 1216 DEVMETHOD(bus_teardown_intr, cardbus_teardown_intr), |
966 967 DEVMETHOD(bus_set_resource, cardbus_set_resource_method), 968 DEVMETHOD(bus_get_resource, cardbus_get_resource_method), 969 DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method), 970 971 /* Card Interface */ 972 DEVMETHOD(card_attach_card, cardbus_attach_card), 973 DEVMETHOD(card_detach_card, cardbus_detach_card), 974 DEVMETHOD(card_cis_read, cardbus_cis_read), 975 DEVMETHOD(card_cis_free, cardbus_cis_free), 976 977 /* Cardbus/PCI interface */ 978 DEVMETHOD(pci_read_config, cardbus_read_config_method), 979 DEVMETHOD(pci_write_config, cardbus_write_config_method), | 1217 1218 DEVMETHOD(bus_set_resource, cardbus_set_resource_method), 1219 DEVMETHOD(bus_get_resource, cardbus_get_resource_method), 1220 DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method), 1221 1222 /* Card Interface */ 1223 DEVMETHOD(card_attach_card, cardbus_attach_card), 1224 DEVMETHOD(card_detach_card, cardbus_detach_card), 1225 DEVMETHOD(card_cis_read, cardbus_cis_read), 1226 DEVMETHOD(card_cis_free, cardbus_cis_free), 1227 1228 /* Cardbus/PCI interface */ 1229 DEVMETHOD(pci_read_config, cardbus_read_config_method), 1230 DEVMETHOD(pci_write_config, cardbus_write_config_method), |
1231 DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method), 1232 DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method), 1233 DEVMETHOD(pci_enable_io, cardbus_enable_io_method), 1234 DEVMETHOD(pci_disable_io, cardbus_disable_io_method), 1235 DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method), 1236 DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method), |
|
980 981 {0,0} 982}; 983 984static driver_t cardbus_driver = { 985 "cardbus", 986 cardbus_methods, 987 0 /* no softc */ 988}; 989 990static devclass_t cardbus_devclass; 991 992DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0); 993/* 994MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 995*/ | 1237 1238 {0,0} 1239}; 1240 1241static driver_t cardbus_driver = { 1242 "cardbus", 1243 cardbus_methods, 1244 0 /* no softc */ 1245}; 1246 1247static devclass_t cardbus_devclass; 1248 1249DRIVER_MODULE(cardbus, pccbb, cardbus_driver, cardbus_devclass, 0, 0); 1250/* 1251MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); 1252*/ |