Deleted Added
full compact
cardbus.c (110750) cardbus.c (110975)
1/*
2 * Copyright (c) 2000,2001 Jonathan Chen.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
1/*
2 * Copyright (c) 2000,2001 Jonathan Chen.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/cardbus/cardbus.c 110750 2003-02-12 05:57:02Z imp $
28 * $FreeBSD: head/sys/dev/cardbus/cardbus.c 110975 2003-02-16 02:06:50Z imp $
29 */
30
31/*
32 * Cardbus Bus Driver
33 *
34 * much of the bus code was stolen directly from sys/pci/pci.c
35 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>)
36 *

--- 9 unchanged lines hidden (view full) ---

46#include <sys/bus.h>
47#include <machine/bus.h>
48#include <sys/rman.h>
49#include <machine/resource.h>
50
51#include <sys/pciio.h>
52#include <dev/pci/pcivar.h>
53#include <dev/pci/pcireg.h>
29 */
30
31/*
32 * Cardbus Bus Driver
33 *
34 * much of the bus code was stolen directly from sys/pci/pci.c
35 * (Copyright (c) 1997, Stefan Esser <se@freebsd.org>)
36 *

--- 9 unchanged lines hidden (view full) ---

46#include <sys/bus.h>
47#include <machine/bus.h>
48#include <sys/rman.h>
49#include <machine/resource.h>
50
51#include <sys/pciio.h>
52#include <dev/pci/pcivar.h>
53#include <dev/pci/pcireg.h>
54#include <dev/pci/pci_private.h>
54
55#include <dev/cardbus/cardbusreg.h>
56#include <dev/cardbus/cardbusvar.h>
57#include <dev/cardbus/cardbus_cis.h>
58#include <dev/pccard/pccardvar.h>
59
60#include "power_if.h"
61#include "pcib_if.h"

--- 21 unchanged lines hidden (view full) ---

83 int type, int *rid, u_long start, u_long end, u_long count,
84 u_int flags);
85static int cardbus_attach(device_t cbdev);
86static int cardbus_attach_card(device_t cbdev);
87static int cardbus_child_location_str(device_t cbdev, device_t child,
88 char *, size_t len);
89static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child,
90 char *, size_t len);
55
56#include <dev/cardbus/cardbusreg.h>
57#include <dev/cardbus/cardbusvar.h>
58#include <dev/cardbus/cardbus_cis.h>
59#include <dev/pccard/pccardvar.h>
60
61#include "power_if.h"
62#include "pcib_if.h"

--- 21 unchanged lines hidden (view full) ---

84 int type, int *rid, u_long start, u_long end, u_long count,
85 u_int flags);
86static int cardbus_attach(device_t cbdev);
87static int cardbus_attach_card(device_t cbdev);
88static int cardbus_child_location_str(device_t cbdev, device_t child,
89 char *, size_t len);
90static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child,
91 char *, size_t len);
91static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child,
92 uint16_t bit);
93static void cardbus_delete_resource(device_t cbdev, device_t child,
94 int type, int rid);
95static void cardbus_delete_resource_method(device_t cbdev, device_t child,
96 int type, int rid);
97static int cardbus_detach(device_t cbdev);
98static int cardbus_detach_card(device_t cbdev);
99static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f,
100 pcicfgregs *cfg);
92static void cardbus_delete_resource(device_t cbdev, device_t child,
93 int type, int rid);
94static void cardbus_delete_resource_method(device_t cbdev, device_t child,
95 int type, int rid);
96static int cardbus_detach(device_t cbdev);
97static int cardbus_detach_card(device_t cbdev);
98static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f,
99 pcicfgregs *cfg);
101static void cardbus_disable_busmaster_method(device_t cbdev, device_t child);
102static void cardbus_disable_io_method(device_t cbdev, device_t child,
103 int space);
104static void cardbus_driver_added(device_t cbdev, driver_t *driver);
100static void cardbus_driver_added(device_t cbdev, driver_t *driver);
105static void cardbus_enable_busmaster_method(device_t cbdev, device_t child);
106static void cardbus_enable_io_method(device_t cbdev, device_t child,
107 int space);
108static int cardbus_freecfg(struct cardbus_devinfo *dinfo);
109static int cardbus_get_powerstate_method(device_t cbdev, device_t child);
110static int cardbus_get_resource(device_t cbdev, device_t child, int type,
111 int rid, u_long *startp, u_long *countp);
112static int cardbus_get_resource_method(device_t cbdev, device_t child,
113 int type, int rid, u_long *startp, u_long *countp);
101static int cardbus_get_resource(device_t cbdev, device_t child, int type,
102 int rid, u_long *startp, u_long *countp);
103static int cardbus_get_resource_method(device_t cbdev, device_t child,
104 int type, int rid, u_long *startp, u_long *countp);
114static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f,
115 pcicfgregs *cfg);
116static int cardbus_print_child(device_t cbdev, device_t child);
117static int cardbus_print_resources(struct resource_list *rl,
118 const char *name, int type, const char *format);
119static void cardbus_print_verbose(struct cardbus_devinfo *dinfo);
120static int cardbus_probe(device_t cbdev);
105static int cardbus_probe(device_t cbdev);
121static void cardbus_probe_nomatch(device_t cbdev, device_t child);
122static struct cardbus_devinfo *cardbus_read_device(device_t brdev, int b,
123 int s, int f);
124static void cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg);
125static uint32_t cardbus_read_config_method(device_t cbdev,
126 device_t child, int reg, int width);
127static int cardbus_read_ivar(device_t cbdev, device_t child, int which,
106static int cardbus_read_ivar(device_t cbdev, device_t child, int which,
128 u_long *result);
107 uintptr_t *result);
129static void cardbus_release_all_resources(device_t cbdev,
130 struct cardbus_devinfo *dinfo);
131static int cardbus_release_resource(device_t cbdev, device_t child,
132 int type, int rid, struct resource *r);
108static void cardbus_release_all_resources(device_t cbdev,
109 struct cardbus_devinfo *dinfo);
110static int cardbus_release_resource(device_t cbdev, device_t child,
111 int type, int rid, struct resource *r);
133static __inline void cardbus_set_command_bit(device_t cbdev, device_t child,
134 uint16_t bit);
135static int cardbus_set_powerstate_method(device_t cbdev, device_t child,
136 int state);
137static int cardbus_set_resource(device_t cbdev, device_t child, int type,
138 int rid, u_long start, u_long count, struct resource *res);
139static int cardbus_set_resource_method(device_t cbdev, device_t child,
140 int type, int rid, u_long start, u_long count);
141static int cardbus_setup_intr(device_t cbdev, device_t child,
142 struct resource *irq, int flags, driver_intr_t *intr,
143 void *arg, void **cookiep);
144static int cardbus_teardown_intr(device_t cbdev, device_t child,
145 struct resource *irq, void *cookie);
112static int cardbus_set_resource(device_t cbdev, device_t child, int type,
113 int rid, u_long start, u_long count, struct resource *res);
114static int cardbus_set_resource_method(device_t cbdev, device_t child,
115 int type, int rid, u_long start, u_long count);
116static int cardbus_setup_intr(device_t cbdev, device_t child,
117 struct resource *irq, int flags, driver_intr_t *intr,
118 void *arg, void **cookiep);
119static int cardbus_teardown_intr(device_t cbdev, device_t child,
120 struct resource *irq, void *cookie);
146static void cardbus_write_config_method(device_t cbdev, device_t child,
147 int reg, uint32_t val, int width);
148static int cardbus_write_ivar(device_t cbdev, device_t child, int which,
149 uintptr_t value);
150
151/************************************************************************/
152/* Probe/Attach */
153/************************************************************************/
154
155static int

--- 76 unchanged lines hidden (view full) ---

232 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1);
233 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1);
234 curr_bus_number += 3;
235 }
236 /* For each function, set it up and try to attach a driver to it */
237 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) {
238 int cardbusfunchigh = 0;
239 for (func = 0; func <= cardbusfunchigh; func++) {
121static int cardbus_write_ivar(device_t cbdev, device_t child, int which,
122 uintptr_t value);
123
124/************************************************************************/
125/* Probe/Attach */
126/************************************************************************/
127
128static int

--- 76 unchanged lines hidden (view full) ---

205 pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1);
206 pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1);
207 curr_bus_number += 3;
208 }
209 /* For each function, set it up and try to attach a driver to it */
210 for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) {
211 int cardbusfunchigh = 0;
212 for (func = 0; func <= cardbusfunchigh; func++) {
240 struct cardbus_devinfo *dinfo =
241 cardbus_read_device(brdev, bus, slot, func);
213 struct cardbus_devinfo *dinfo;
242
214
215 dinfo = (struct cardbus_devinfo *)
216 pci_read_device(brdev, bus, slot, func,
217 sizeof(struct cardbus_devinfo));
243 if (dinfo == NULL)
244 continue;
245 if (dinfo->pci.cfg.mfdev)
246 cardbusfunchigh = CARDBUS_FUNCMAX;
247
248 cardbus_device_setup_regs(brdev, bus, slot, func,
249 &dinfo->pci.cfg);
218 if (dinfo == NULL)
219 continue;
220 if (dinfo->pci.cfg.mfdev)
221 cardbusfunchigh = CARDBUS_FUNCMAX;
222
223 cardbus_device_setup_regs(brdev, bus, slot, func,
224 &dinfo->pci.cfg);
250 cardbus_print_verbose(dinfo);
225 pci_print_verbose(&dinfo->pci);
251 dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1);
252 if (!dinfo->pci.cfg.dev) {
253 DEVPRINTF((cbdev, "Cannot add child!\n"));
226 dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1);
227 if (!dinfo->pci.cfg.dev) {
228 DEVPRINTF((cbdev, "Cannot add child!\n"));
254 cardbus_freecfg(dinfo);
229 pci_freecfg((struct pci_devinfo *)dinfo);
255 continue;
256 }
257 resource_list_init(&dinfo->pci.resources);
258 device_set_ivars(dinfo->pci.cfg.dev, dinfo);
259 cardbus_do_cis(cbdev, dinfo->pci.cfg.dev);
260 if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0)
261 cardbus_release_all_resources(cbdev, dinfo);
262 else

--- 27 unchanged lines hidden (view full) ---

290 int status = device_get_state(devlist[tmp]);
291
292 if (dinfo->pci.cfg.dev != devlist[tmp])
293 device_printf(cbdev, "devinfo dev mismatch\n");
294 if (status == DS_ATTACHED || status == DS_BUSY)
295 device_detach(devlist[tmp]);
296 cardbus_release_all_resources(cbdev, dinfo);
297 device_delete_child(cbdev, devlist[tmp]);
230 continue;
231 }
232 resource_list_init(&dinfo->pci.resources);
233 device_set_ivars(dinfo->pci.cfg.dev, dinfo);
234 cardbus_do_cis(cbdev, dinfo->pci.cfg.dev);
235 if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0)
236 cardbus_release_all_resources(cbdev, dinfo);
237 else

--- 27 unchanged lines hidden (view full) ---

265 int status = device_get_state(devlist[tmp]);
266
267 if (dinfo->pci.cfg.dev != devlist[tmp])
268 device_printf(cbdev, "devinfo dev mismatch\n");
269 if (status == DS_ATTACHED || status == DS_BUSY)
270 device_detach(devlist[tmp]);
271 cardbus_release_all_resources(cbdev, dinfo);
272 device_delete_child(cbdev, devlist[tmp]);
298 cardbus_freecfg(dinfo);
273 pci_freecfg((struct pci_devinfo *)dinfo);
299 }
300 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
301 free(devlist, M_TEMP);
302 return (err);
303}
304
305static void
306cardbus_driver_added(device_t cbdev, driver_t *driver)

--- 17 unchanged lines hidden (view full) ---

324 }
325 if (i > 0 && i == numdevs)
326 POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev);
327 for (i = 0; i < numdevs; i++) {
328 dev = devlist[i];
329 if (device_get_state(dev) != DS_NOTPRESENT)
330 continue;
331 dinfo = device_get_ivars(dev);
274 }
275 POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev);
276 free(devlist, M_TEMP);
277 return (err);
278}
279
280static void
281cardbus_driver_added(device_t cbdev, driver_t *driver)

--- 17 unchanged lines hidden (view full) ---

299 }
300 if (i > 0 && i == numdevs)
301 POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev);
302 for (i = 0; i < numdevs; i++) {
303 dev = devlist[i];
304 if (device_get_state(dev) != DS_NOTPRESENT)
305 continue;
306 dinfo = device_get_ivars(dev);
332 cardbus_print_verbose(dinfo);
307 pci_print_verbose(&dinfo->pci);
333 resource_list_init(&dinfo->pci.resources);
334 cardbus_do_cis(cbdev, dev);
335 if (device_probe_and_attach(dev) != 0)
336 cardbus_release_all_resources(cbdev, dinfo);
337 }
338 free(devlist, M_TEMP);
339}
340
341/************************************************************************/
308 resource_list_init(&dinfo->pci.resources);
309 cardbus_do_cis(cbdev, dev);
310 if (device_probe_and_attach(dev) != 0)
311 cardbus_release_all_resources(cbdev, dinfo);
312 }
313 free(devlist, M_TEMP);
314}
315
316/************************************************************************/
342/* PCI-Like config reading (copied from pci.c */
343/************************************************************************/
344
345/* read configuration header into pcicfgrect structure */
346
347static void
348cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg)
349{
350#define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w)
351 int ptr, nextptr, ptrptr;
352
353 switch (cfg->hdrtype) {
354 case 0:
355 ptrptr = 0x34;
356 break;
357 case 2:
358 ptrptr = 0x14;
359 break;
360 default:
361 return; /* no extended capabilities support */
362 }
363 nextptr = REG(ptrptr, 1); /* sanity check? */
364
365 /*
366 * Read capability entries.
367 */
368 while (nextptr != 0) {
369 /* Sanity check */
370 if (nextptr > 255) {
371 printf("illegal PCI extended capability offset %d\n",
372 nextptr);
373 return;
374 }
375 /* Find the next entry */
376 ptr = nextptr;
377 nextptr = REG(ptr + 1, 1);
378
379 /* Process this entry */
380 switch (REG(ptr, 1)) {
381 case 0x01: /* PCI power management */
382 if (cfg->pp_cap == 0) {
383 cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2);
384 cfg->pp_status = ptr + PCIR_POWER_STATUS;
385 cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR;
386 if ((nextptr - ptr) > PCIR_POWER_DATA)
387 cfg->pp_data = ptr + PCIR_POWER_DATA;
388 }
389 break;
390 default:
391 break;
392 }
393 }
394#undef REG
395}
396
397/* extract header type specific config data */
398
399static void
400cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg)
401{
402#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w)
403 switch (cfg->hdrtype) {
404 case 0:
405 cfg->subvendor = REG(PCIR_SUBVEND_0, 2);
406 cfg->subdevice = REG(PCIR_SUBDEV_0, 2);
407 cfg->nummaps = PCI_MAXMAPS_0;
408 break;
409 case 1:
410 cfg->subvendor = REG(PCIR_SUBVEND_1, 2);
411 cfg->subdevice = REG(PCIR_SUBDEV_1, 2);
412 cfg->nummaps = PCI_MAXMAPS_1;
413 break;
414 case 2:
415 cfg->subvendor = REG(PCIR_SUBVEND_2, 2);
416 cfg->subdevice = REG(PCIR_SUBDEV_2, 2);
417 cfg->nummaps = PCI_MAXMAPS_2;
418 break;
419 }
420#undef REG
421}
422
423static struct cardbus_devinfo *
424cardbus_read_device(device_t brdev, int b, int s, int f)
425{
426#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w)
427 pcicfgregs *cfg = NULL;
428 struct cardbus_devinfo *devlist_entry = NULL;
429
430 if (REG(PCIR_DEVVENDOR, 4) != 0xffffffff) {
431 devlist_entry = malloc(sizeof(struct cardbus_devinfo),
432 M_DEVBUF, M_ZERO);
433 if (devlist_entry == NULL)
434 return (NULL);
435
436 cfg = &devlist_entry->pci.cfg;
437
438 cfg->bus = b;
439 cfg->slot = s;
440 cfg->func = f;
441 cfg->vendor = REG(PCIR_VENDOR, 2);
442 cfg->device = REG(PCIR_DEVICE, 2);
443 cfg->cmdreg = REG(PCIR_COMMAND, 2);
444 cfg->statreg = REG(PCIR_STATUS, 2);
445 cfg->baseclass = REG(PCIR_CLASS, 1);
446 cfg->subclass = REG(PCIR_SUBCLASS, 1);
447 cfg->progif = REG(PCIR_PROGIF, 1);
448 cfg->revid = REG(PCIR_REVID, 1);
449 cfg->hdrtype = REG(PCIR_HEADERTYPE, 1);
450 cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1);
451 cfg->lattimer = REG(PCIR_LATTIMER, 1);
452 cfg->intpin = REG(PCIR_INTPIN, 1);
453 cfg->intline = REG(PCIR_INTLINE, 1);
454
455 cfg->mingnt = REG(PCIR_MINGNT, 1);
456 cfg->maxlat = REG(PCIR_MAXLAT, 1);
457
458 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0;
459 cfg->hdrtype &= ~PCIM_MFDEV;
460
461 cardbus_hdrtypedata(brdev, b, s, f, cfg);
462
463 if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT)
464 cardbus_read_extcap(brdev, cfg);
465
466 devlist_entry->pci.conf.pc_sel.pc_bus = cfg->bus;
467 devlist_entry->pci.conf.pc_sel.pc_dev = cfg->slot;
468 devlist_entry->pci.conf.pc_sel.pc_func = cfg->func;
469 devlist_entry->pci.conf.pc_hdr = cfg->hdrtype;
470
471 devlist_entry->pci.conf.pc_subvendor = cfg->subvendor;
472 devlist_entry->pci.conf.pc_subdevice = cfg->subdevice;
473 devlist_entry->pci.conf.pc_vendor = cfg->vendor;
474 devlist_entry->pci.conf.pc_device = cfg->device;
475
476 devlist_entry->pci.conf.pc_class = cfg->baseclass;
477 devlist_entry->pci.conf.pc_subclass = cfg->subclass;
478 devlist_entry->pci.conf.pc_progif = cfg->progif;
479 devlist_entry->pci.conf.pc_revid = cfg->revid;
480 }
481 return (devlist_entry);
482#undef REG
483}
484
485/* free pcicfgregs structure and all depending data structures */
486
487static int
488cardbus_freecfg(struct cardbus_devinfo *dinfo)
489{
490 free(dinfo, M_DEVBUF);
491
492 return (0);
493}
494
495static void
496cardbus_print_verbose(struct cardbus_devinfo *dinfo)
497{
498 if (bootverbose || cardbus_debug > 0)
499 {
500 pcicfgregs *cfg = &dinfo->pci.cfg;
501
502 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
503 cfg->vendor, cfg->device, cfg->revid);
504 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
505 cfg->baseclass, cfg->subclass, cfg->progif,
506 cfg->hdrtype, cfg->mfdev);
507 printf("\tcmdreg=0x%04x, statreg=0x%04x, "
508 "cachelnsz=%d (dwords)\n",
509 cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
510 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), "
511 "maxlat=0x%02x (%d ns)\n",
512 cfg->lattimer, cfg->lattimer * 30,
513 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat,
514 cfg->maxlat * 250);
515 if (cfg->intpin > 0)
516 printf("\tintpin=%c, irq=%d\n",
517 cfg->intpin + 'a' - 1, cfg->intline);
518 }
519}
520
521/************************************************************************/
522/* Resources */
523/************************************************************************/
524
525static int
526cardbus_set_resource(device_t cbdev, device_t child, int type, int rid,
527 u_long start, u_long count, struct resource *res)
528{
529 struct cardbus_devinfo *dinfo;

--- 301 unchanged lines hidden (view full) ---

831}
832
833
834/************************************************************************/
835/* Other Bus Methods */
836/************************************************************************/
837
838static int
317/* Resources */
318/************************************************************************/
319
320static int
321cardbus_set_resource(device_t cbdev, device_t child, int type, int rid,
322 u_long start, u_long count, struct resource *res)
323{
324 struct cardbus_devinfo *dinfo;

--- 301 unchanged lines hidden (view full) ---

626}
627
628
629/************************************************************************/
630/* Other Bus Methods */
631/************************************************************************/
632
633static int
839cardbus_print_resources(struct resource_list *rl, const char *name,
840 int type, const char *format)
841{
842 struct resource_list_entry *rle;
843 int printed, retval;
844
845 printed = 0;
846 retval = 0;
847 /* Yes, this is kinda cheating */
848 SLIST_FOREACH(rle, rl, link) {
849 if (rle->type == type) {
850 if (printed == 0)
851 retval += printf(" %s ", name);
852 else if (printed > 0)
853 retval += printf(",");
854 printed++;
855 retval += printf(format, rle->start);
856 if (rle->count > 1) {
857 retval += printf("-");
858 retval += printf(format, rle->start +
859 rle->count - 1);
860 }
861 }
862 }
863 return retval;
864}
865
866static int
867cardbus_print_child(device_t cbdev, device_t child)
868{
869 struct cardbus_devinfo *dinfo;
870 struct resource_list *rl;
871 pcicfgregs *cfg;
872 int retval = 0;
873
874 dinfo = device_get_ivars(child);
875 cfg = &dinfo->pci.cfg;
876 rl = &dinfo->pci.resources;
877
878 retval += bus_print_child_header(cbdev, child);
879
880 retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx");
881 retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx");
882 retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld");
883 if (device_get_flags(cbdev))
884 retval += printf(" flags %#x", device_get_flags(cbdev));
885
886 retval += printf(" at device %d.%d", pci_get_slot(child),
887 pci_get_function(child));
888
889 retval += bus_print_child_footer(cbdev, child);
890
891 return (retval);
892}
893
894static void
895cardbus_probe_nomatch(device_t cbdev, device_t child)
896{
897 struct cardbus_devinfo *dinfo;
898 pcicfgregs *cfg;
899
900 dinfo = device_get_ivars(child);
901 cfg = &dinfo->pci.cfg;
902 device_printf(cbdev, "<unknown card>");
903 printf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device);
904 printf(" at %d.%d", pci_get_slot(child), pci_get_function(child));
905 if (cfg->intpin > 0 && cfg->intline != 255) {
906 printf(" irq %d", cfg->intline);
907 }
908 printf("\n");
909
910 return;
911}
912
913static int
914cardbus_child_location_str(device_t cbdev, device_t child, char *buf,
915 size_t buflen)
916{
917 struct cardbus_devinfo *dinfo;
918 pcicfgregs *cfg;
919
920 dinfo = device_get_ivars(child);
921 cfg = &dinfo->pci.cfg;

--- 13 unchanged lines hidden (view full) ---

935 cfg = &dinfo->pci.cfg;
936 snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x "
937 "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor,
938 cfg->subdevice);
939 return (0);
940}
941
942static int
634cardbus_child_location_str(device_t cbdev, device_t child, char *buf,
635 size_t buflen)
636{
637 struct cardbus_devinfo *dinfo;
638 pcicfgregs *cfg;
639
640 dinfo = device_get_ivars(child);
641 cfg = &dinfo->pci.cfg;

--- 13 unchanged lines hidden (view full) ---

655 cfg = &dinfo->pci.cfg;
656 snprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x "
657 "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor,
658 cfg->subdevice);
659 return (0);
660}
661
662static int
943cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result)
663cardbus_read_ivar(device_t cbdev, device_t child, int which, uintptr_t *result)
944{
945 struct cardbus_devinfo *dinfo;
946 pcicfgregs *cfg;
947
948 dinfo = device_get_ivars(child);
949 cfg = &dinfo->pci.cfg;
950
951 switch (which) {
952 case PCI_IVAR_ETHADDR:
953 /*
954 * The generic accessor doesn't deal with failure, so
955 * we set the return value, then return an error.
956 */
957 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) {
958 *((uint8_t **) result) = NULL;
959 return (EINVAL);
960 }
961 *((uint8_t **) result) = dinfo->funce.lan.nid;
962 break;
664{
665 struct cardbus_devinfo *dinfo;
666 pcicfgregs *cfg;
667
668 dinfo = device_get_ivars(child);
669 cfg = &dinfo->pci.cfg;
670
671 switch (which) {
672 case PCI_IVAR_ETHADDR:
673 /*
674 * The generic accessor doesn't deal with failure, so
675 * we set the return value, then return an error.
676 */
677 if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) {
678 *((uint8_t **) result) = NULL;
679 return (EINVAL);
680 }
681 *((uint8_t **) result) = dinfo->funce.lan.nid;
682 break;
963 case PCI_IVAR_SUBVENDOR:
964 *result = cfg->subvendor;
965 break;
966 case PCI_IVAR_SUBDEVICE:
967 *result = cfg->subdevice;
968 break;
969 case PCI_IVAR_VENDOR:
970 *result = cfg->vendor;
971 break;
972 case PCI_IVAR_DEVICE:
973 *result = cfg->device;
974 break;
975 case PCI_IVAR_DEVID:
976 *result = (cfg->device << 16) | cfg->vendor;
977 break;
978 case PCI_IVAR_CLASS:
979 *result = cfg->baseclass;
980 break;
981 case PCI_IVAR_SUBCLASS:
982 *result = cfg->subclass;
983 break;
984 case PCI_IVAR_PROGIF:
985 *result = cfg->progif;
986 break;
987 case PCI_IVAR_REVID:
988 *result = cfg->revid;
989 break;
990 case PCI_IVAR_INTPIN:
991 *result = cfg->intpin;
992 break;
993 case PCI_IVAR_IRQ:
994 *result = cfg->intline;
995 break;
996 case PCI_IVAR_BUS:
997 *result = cfg->bus;
998 break;
999 case PCI_IVAR_SLOT:
1000 *result = cfg->slot;
1001 break;
1002 case PCI_IVAR_FUNCTION:
1003 *result = cfg->func;
1004 break;
1005 default:
683 default:
1006 return ENOENT;
684 return (pci_read_ivar(cbdev, child, which, result));
1007 }
1008 return 0;
1009}
1010
1011static int
1012cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value)
1013{
685 }
686 return 0;
687}
688
689static int
690cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value)
691{
1014 struct cardbus_devinfo *dinfo;
1015 pcicfgregs *cfg;
1016
1017 dinfo = device_get_ivars(child);
1018 cfg = &dinfo->pci.cfg;
1019
1020 switch (which) {
1021 case PCI_IVAR_ETHADDR:
1022 case PCI_IVAR_SUBVENDOR:
1023 case PCI_IVAR_SUBDEVICE:
1024 case PCI_IVAR_VENDOR:
1025 case PCI_IVAR_DEVICE:
1026 case PCI_IVAR_DEVID:
1027 case PCI_IVAR_CLASS:
1028 case PCI_IVAR_SUBCLASS:
1029 case PCI_IVAR_PROGIF:
1030 case PCI_IVAR_REVID:
1031 case PCI_IVAR_INTPIN:
1032 case PCI_IVAR_IRQ:
1033 case PCI_IVAR_BUS:
1034 case PCI_IVAR_SLOT:
1035 case PCI_IVAR_FUNCTION:
1036 return EINVAL; /* disallow for now */
1037 default:
1038 return ENOENT;
1039 }
1040 return 0;
692 return(pci_write_ivar(cbdev, child, which, value));
1041}
1042
1043/************************************************************************/
1044/* Compatibility with PCI bus (XXX: Do we need this?) */
1045/************************************************************************/
1046
693}
694
695/************************************************************************/
696/* Compatibility with PCI bus (XXX: Do we need this?) */
697/************************************************************************/
698
1047/*
1048 * PCI power manangement
1049 */
1050static int
1051cardbus_set_powerstate_method(device_t cbdev, device_t child, int state)
1052{
1053 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1054 pcicfgregs *cfg = &dinfo->pci.cfg;
1055 uint16_t status;
1056 int result;
1057
1058 if (cfg->pp_cap != 0) {
1059 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2)
1060 & ~PCIM_PSTAT_DMASK;
1061 result = 0;
1062 switch (state) {
1063 case PCI_POWERSTATE_D0:
1064 status |= PCIM_PSTAT_D0;
1065 break;
1066 case PCI_POWERSTATE_D1:
1067 if (cfg->pp_cap & PCIM_PCAP_D1SUPP) {
1068 status |= PCIM_PSTAT_D1;
1069 } else {
1070 result = EOPNOTSUPP;
1071 }
1072 break;
1073 case PCI_POWERSTATE_D2:
1074 if (cfg->pp_cap & PCIM_PCAP_D2SUPP) {
1075 status |= PCIM_PSTAT_D2;
1076 } else {
1077 result = EOPNOTSUPP;
1078 }
1079 break;
1080 case PCI_POWERSTATE_D3:
1081 status |= PCIM_PSTAT_D3;
1082 break;
1083 default:
1084 result = EINVAL;
1085 }
1086 if (result == 0)
1087 PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status,
1088 status, 2);
1089 } else {
1090 result = ENXIO;
1091 }
1092 return (result);
1093}
1094
1095static int
1096cardbus_get_powerstate_method(device_t cbdev, device_t child)
1097{
1098 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1099 pcicfgregs *cfg = &dinfo->pci.cfg;
1100 uint16_t status;
1101 int result;
1102
1103 if (cfg->pp_cap != 0) {
1104 status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2);
1105 switch (status & PCIM_PSTAT_DMASK) {
1106 case PCIM_PSTAT_D0:
1107 result = PCI_POWERSTATE_D0;
1108 break;
1109 case PCIM_PSTAT_D1:
1110 result = PCI_POWERSTATE_D1;
1111 break;
1112 case PCIM_PSTAT_D2:
1113 result = PCI_POWERSTATE_D2;
1114 break;
1115 case PCIM_PSTAT_D3:
1116 result = PCI_POWERSTATE_D3;
1117 break;
1118 default:
1119 result = PCI_POWERSTATE_UNKNOWN;
1120 break;
1121 }
1122 } else {
1123 /* No support, device is always at D0 */
1124 result = PCI_POWERSTATE_D0;
1125 }
1126 return (result);
1127}
1128
1129static uint32_t
1130cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width)
1131{
1132 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1133 pcicfgregs *cfg = &dinfo->pci.cfg;
1134
1135 return PCIB_READ_CONFIG(device_get_parent(cbdev),
1136 cfg->bus, cfg->slot, cfg->func, reg, width);
1137}
1138
1139static void
1140cardbus_write_config_method(device_t cbdev, device_t child, int reg,
1141 uint32_t val, int width)
1142{
1143 struct cardbus_devinfo *dinfo = device_get_ivars(child);
1144 pcicfgregs *cfg = &dinfo->pci.cfg;
1145
1146 PCIB_WRITE_CONFIG(device_get_parent(cbdev),
1147 cfg->bus, cfg->slot, cfg->func, reg, val, width);
1148}
1149
1150static __inline void
1151cardbus_set_command_bit(device_t cbdev, device_t child, uint16_t bit)
1152{
1153 uint16_t command;
1154
1155 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1156 command |= bit;
1157 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1158}
1159
1160static __inline void
1161cardbus_clear_command_bit(device_t cbdev, device_t child, uint16_t bit)
1162{
1163 uint16_t command;
1164
1165 command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2);
1166 command &= ~bit;
1167 PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2);
1168}
1169
1170static void
1171cardbus_enable_busmaster_method(device_t cbdev, device_t child)
1172{
1173 cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1174}
1175
1176static void
1177cardbus_disable_busmaster_method(device_t cbdev, device_t child)
1178{
1179 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN);
1180}
1181
1182static void
1183cardbus_enable_io_method(device_t cbdev, device_t child, int space)
1184{
1185 switch (space) {
1186 case SYS_RES_IOPORT:
1187 cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1188 break;
1189 case SYS_RES_MEMORY:
1190 cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1191 break;
1192 }
1193}
1194
1195static void
1196cardbus_disable_io_method(device_t cbdev, device_t child, int space)
1197{
1198 switch (space) {
1199 case SYS_RES_IOPORT:
1200 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN);
1201 break;
1202 case SYS_RES_MEMORY:
1203 cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN);
1204 break;
1205 }
1206}
1207
1208static device_method_t cardbus_methods[] = {
1209 /* Device interface */
1210 DEVMETHOD(device_probe, cardbus_probe),
1211 DEVMETHOD(device_attach, cardbus_attach),
1212 DEVMETHOD(device_detach, cardbus_detach),
1213 DEVMETHOD(device_shutdown, bus_generic_shutdown),
1214 DEVMETHOD(device_suspend, cardbus_suspend),
1215 DEVMETHOD(device_resume, cardbus_resume),
1216
1217 /* Bus interface */
699static device_method_t cardbus_methods[] = {
700 /* Device interface */
701 DEVMETHOD(device_probe, cardbus_probe),
702 DEVMETHOD(device_attach, cardbus_attach),
703 DEVMETHOD(device_detach, cardbus_detach),
704 DEVMETHOD(device_shutdown, bus_generic_shutdown),
705 DEVMETHOD(device_suspend, cardbus_suspend),
706 DEVMETHOD(device_resume, cardbus_resume),
707
708 /* Bus interface */
1218 DEVMETHOD(bus_print_child, cardbus_print_child),
1219 DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch),
709 DEVMETHOD(bus_print_child, pci_print_child),
710 DEVMETHOD(bus_probe_nomatch, pci_probe_nomatch),
1220 DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
1221 DEVMETHOD(bus_write_ivar, cardbus_write_ivar),
1222 DEVMETHOD(bus_driver_added, cardbus_driver_added),
1223 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource),
1224 DEVMETHOD(bus_release_resource, cardbus_release_resource),
1225 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
1226 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
1227 DEVMETHOD(bus_setup_intr, cardbus_setup_intr),

--- 7 unchanged lines hidden (view full) ---

1235
1236 /* Card Interface */
1237 DEVMETHOD(card_attach_card, cardbus_attach_card),
1238 DEVMETHOD(card_detach_card, cardbus_detach_card),
1239 DEVMETHOD(card_cis_read, cardbus_cis_read),
1240 DEVMETHOD(card_cis_free, cardbus_cis_free),
1241
1242 /* Cardbus/PCI interface */
711 DEVMETHOD(bus_read_ivar, cardbus_read_ivar),
712 DEVMETHOD(bus_write_ivar, cardbus_write_ivar),
713 DEVMETHOD(bus_driver_added, cardbus_driver_added),
714 DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource),
715 DEVMETHOD(bus_release_resource, cardbus_release_resource),
716 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
717 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
718 DEVMETHOD(bus_setup_intr, cardbus_setup_intr),

--- 7 unchanged lines hidden (view full) ---

726
727 /* Card Interface */
728 DEVMETHOD(card_attach_card, cardbus_attach_card),
729 DEVMETHOD(card_detach_card, cardbus_detach_card),
730 DEVMETHOD(card_cis_read, cardbus_cis_read),
731 DEVMETHOD(card_cis_free, cardbus_cis_free),
732
733 /* Cardbus/PCI interface */
1243 DEVMETHOD(pci_read_config, cardbus_read_config_method),
1244 DEVMETHOD(pci_write_config, cardbus_write_config_method),
1245 DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method),
1246 DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method),
1247 DEVMETHOD(pci_enable_io, cardbus_enable_io_method),
1248 DEVMETHOD(pci_disable_io, cardbus_disable_io_method),
1249 DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method),
1250 DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method),
734 DEVMETHOD(pci_read_config, pci_read_config_method),
735 DEVMETHOD(pci_write_config, pci_write_config_method),
736 DEVMETHOD(pci_enable_busmaster, pci_enable_busmaster_method),
737 DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
738 DEVMETHOD(pci_enable_io, pci_enable_io_method),
739 DEVMETHOD(pci_disable_io, pci_disable_io_method),
740 DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method),
741 DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
1251
1252 {0,0}
1253};
1254
1255static driver_t cardbus_driver = {
1256 "cardbus",
1257 cardbus_methods,
1258 0 /* no softc */
1259};
1260
1261static devclass_t cardbus_devclass;
1262
1263DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
1264MODULE_VERSION(cardbus, 1);
1265MODULE_DEPEND(cardbus, exca, 1, 1, 1);
1266/*
1267MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
1268*/
742
743 {0,0}
744};
745
746static driver_t cardbus_driver = {
747 "cardbus",
748 cardbus_methods,
749 0 /* no softc */
750};
751
752static devclass_t cardbus_devclass;
753
754DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0);
755MODULE_VERSION(cardbus, 1);
756MODULE_DEPEND(cardbus, exca, 1, 1, 1);
757/*
758MODULE_DEPEND(cardbus, pccbb, 1, 1, 1);
759*/