Deleted Added
full compact
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, &reg, 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*/