d60b8a3096
support machines having multiple independently numbered PCI domains and don't support reenumeration without ambiguity amongst the devices as seen by the OS and represented by PCI location strings. This includes introducing a function pci_find_dbsf(9) which works like pci_find_bsf(9) but additionally takes a domain number argument and limiting pci_find_bsf(9) to only search devices in domain 0 (the only domain in single-domain systems). Bge(4) and ofw_pcibus(4) are changed to use pci_find_dbsf(9) instead of pci_find_bsf(9) in order to no longer report false positives when searching for siblings and dupe devices in the same domain respectively. Along with this change the sole host-PCI bridge driver converted to actually make use of PCI domain support is uninorth(4), the others continue to use domain 0 only for now and need to be converted as appropriate later on. Note that this means that the format of the location strings as used by pciconf(8) has been changed and that consumers of <sys/pciio.h> potentially need to be recompiled. Suggested by: jhb Reviewed by: grehan, jhb, marcel Approved by: re (kensmith), jhb (PCI maintainer hat)
174 lines
5.5 KiB
C
174 lines
5.5 KiB
C
/*-
|
|
* Copyright (c) 2003-2004 Warner Losh.
|
|
* Copyright (c) 2000,2001 Jonathan Chen.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
/*
|
|
* Structure definitions for the Cardbus Bridge driver
|
|
*/
|
|
|
|
struct cbb_intrhand {
|
|
driver_filter_t *filt;
|
|
driver_intr_t *intr;
|
|
void *arg;
|
|
struct cbb_softc *sc;
|
|
void *cookie;
|
|
};
|
|
|
|
struct cbb_reslist {
|
|
SLIST_ENTRY(cbb_reslist) link;
|
|
struct resource *res;
|
|
int type;
|
|
int rid;
|
|
/* note: unlike the regular resource list, there can be
|
|
* duplicate rid's in the same list. However, the
|
|
* combination of rid and res->r_dev should be unique.
|
|
*/
|
|
bus_addr_t cardaddr; /* for 16-bit pccard memory */
|
|
};
|
|
|
|
#define CBB_AUTO_OPEN_SMALLHOLE 0x100
|
|
#define CBB_NSLOTS 4
|
|
|
|
struct cbb_softc {
|
|
device_t dev;
|
|
struct exca_softc exca[CBB_NSLOTS];
|
|
struct resource *base_res;
|
|
struct resource *irq_res;
|
|
void *intrhand;
|
|
bus_space_tag_t bst;
|
|
bus_space_handle_t bsh;
|
|
uint32_t domain;
|
|
unsigned int pribus;
|
|
unsigned int secbus;
|
|
unsigned int subbus;
|
|
struct mtx mtx;
|
|
struct cv cv;
|
|
struct cv powercv;
|
|
int cardok;
|
|
u_int32_t flags;
|
|
#define CBB_16BIT_CARD 0x20000000
|
|
#define CBB_KTHREAD_RUNNING 0x40000000
|
|
#define CBB_KTHREAD_DONE 0x80000000
|
|
int chipset; /* chipset id */
|
|
#define CB_UNKNOWN 0 /* NOT Cardbus-PCI bridge */
|
|
#define CB_TI113X 1 /* TI PCI1130/1131 */
|
|
#define CB_TI12XX 2 /* TI PCI12xx/14xx/44xx/15xx/45xx */
|
|
#define CB_TI125X 3 /* TI PCI1250/1251(B)/1450 */
|
|
#define CB_RF5C47X 4 /* RICOH RF5C475/476/477 */
|
|
#define CB_RF5C46X 5 /* RICOH RF5C465/466/467 */
|
|
#define CB_CIRRUS 6 /* Cirrus Logic CLPD683x */
|
|
#define CB_TOPIC95 7 /* Toshiba ToPIC95 */
|
|
#define CB_TOPIC97 8 /* Toshiba ToPIC97/100 */
|
|
#define CB_O2MICRO 9 /* O2Micro chips */
|
|
SLIST_HEAD(, cbb_reslist) rl;
|
|
device_t cbdev;
|
|
struct proc *event_thread;
|
|
void (*chipinit)(struct cbb_softc *);
|
|
volatile int powerintr;
|
|
};
|
|
|
|
/* result of detect_card */
|
|
#define CARD_UKN_CARD 0x00
|
|
#define CARD_5V_CARD 0x01
|
|
#define CARD_3V_CARD 0x02
|
|
#define CARD_XV_CARD 0x04
|
|
#define CARD_YV_CARD 0x08
|
|
|
|
/* for power_socket */
|
|
#define CARD_VCC(X) (X)
|
|
#define CARD_VPP_VCC 0xf0
|
|
#define CARD_VCCMASK 0xf
|
|
#define CARD_VCCSHIFT 0
|
|
#define XV 2
|
|
#define YV 1
|
|
|
|
#define CARD_OFF (CARD_VCC(0))
|
|
|
|
extern int cbb_debug;
|
|
extern devclass_t cbb_devclass;
|
|
|
|
int cbb_activate_resource(device_t brdev, device_t child,
|
|
int type, int rid, struct resource *r);
|
|
struct resource *cbb_alloc_resource(device_t brdev, device_t child,
|
|
int type, int *rid, u_long start, u_long end, u_long count,
|
|
u_int flags);
|
|
void cbb_child_detached(device_t brdev, device_t child);
|
|
int cbb_child_present(device_t self);
|
|
int cbb_deactivate_resource(device_t brdev, device_t child,
|
|
int type, int rid, struct resource *r);
|
|
int cbb_detach(device_t brdev);
|
|
void cbb_disable_func_intr(struct cbb_softc *sc);
|
|
void cbb_driver_added(device_t brdev, driver_t *driver);
|
|
void cbb_event_thread(void *arg);
|
|
int cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid,
|
|
uint32_t cardaddr, uint32_t *deltap);
|
|
int cbb_pcic_set_res_flags(device_t brdev, device_t child, int type,
|
|
int rid, uint32_t flags);
|
|
int cbb_power(device_t brdev, int volts);
|
|
int cbb_power_enable_socket(device_t brdev, device_t child);
|
|
void cbb_power_disable_socket(device_t brdev, device_t child);
|
|
int cbb_read_ivar(device_t brdev, device_t child, int which,
|
|
uintptr_t *result);
|
|
int cbb_release_resource(device_t brdev, device_t child,
|
|
int type, int rid, struct resource *r);
|
|
int cbb_resume(device_t self);
|
|
int cbb_setup_intr(device_t dev, device_t child, struct resource *irq,
|
|
int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg,
|
|
void **cookiep);
|
|
int cbb_suspend(device_t self);
|
|
int cbb_teardown_intr(device_t dev, device_t child, struct resource *irq,
|
|
void *cookie);
|
|
int cbb_write_ivar(device_t brdev, device_t child, int which,
|
|
uintptr_t value);
|
|
|
|
/*
|
|
*/
|
|
static __inline void
|
|
cbb_set(struct cbb_softc *sc, uint32_t reg, uint32_t val)
|
|
{
|
|
bus_space_write_4(sc->bst, sc->bsh, reg, val);
|
|
}
|
|
|
|
static __inline uint32_t
|
|
cbb_get(struct cbb_softc *sc, uint32_t reg)
|
|
{
|
|
return (bus_space_read_4(sc->bst, sc->bsh, reg));
|
|
}
|
|
|
|
static __inline void
|
|
cbb_setb(struct cbb_softc *sc, uint32_t reg, uint32_t bits)
|
|
{
|
|
cbb_set(sc, reg, cbb_get(sc, reg) | bits);
|
|
}
|
|
|
|
static __inline void
|
|
cbb_clrb(struct cbb_softc *sc, uint32_t reg, uint32_t bits)
|
|
{
|
|
cbb_set(sc, reg, cbb_get(sc, reg) & ~bits);
|
|
}
|