Use the pci.c code wherever possible, rather than copying all the pci

code into cardbus and s/pci/cardbus.  This exposes a few pci_*
functions that are now static.

This work is similar to work Justin posted to the mobile list about a
year or two ago, which I have neglected since then.

This is a subset of his current work with the multiple inheritance
newbus architecutre.  When completed, that will eliminate the need for
pci/pci_private.h.

Similar work is needed for the cardbus_cis and pccard_cis code as well.
This commit is contained in:
Warner Losh 2002-02-27 05:09:14 +00:00
parent 76183f3453
commit 7ba175ac23
5 changed files with 220 additions and 1040 deletions

File diff suppressed because it is too large Load Diff

View File

@ -44,9 +44,9 @@
#include <machine/resource.h>
#include <sys/rman.h>
#include <sys/pciio.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <sys/pciio.h>
#include <dev/cardbus/cardbusreg.h>
#include <dev/cardbus/cardbusvar.h>
@ -318,7 +318,7 @@ DECODE_PROTOTYPE(bar)
:(dinfo->ibelow1mb&BARBIT(bar))?" (Below 1Mb)":""
));
resource_list_add(&dinfo->resources, type, bar, 0UL, ~0UL, len);
resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len);
}
return 0;
}
@ -614,15 +614,14 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
int rid, flags;
count = 0;
SLIST_FOREACH(rle, &dinfo->resources, link) {
SLIST_FOREACH(rle, &dinfo->pci.resources, link)
count++;
}
if (count == 0)
return 0;
barlist = malloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF,
M_WAITOK);
count = 0;
SLIST_FOREACH(rle, &dinfo->resources, link) {
SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
barlist[count] = rle;
if (rle->type == SYS_RES_IOPORT) {
io_size += rle->count;
@ -689,20 +688,22 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
DEVPRINTF((cbdev, "Cannot pre-allocate "
"prefetchable memory, will try as "
"non-prefetchable.\n"));
} else {
barlist[tmp]->start =
rman_get_start(barlist[tmp]->res);
barlist[tmp]->end =
rman_get_end(barlist[tmp]->res);
pci_write_config(child,
barlist[tmp]->rid,
barlist[tmp]->start, 4);
DEVPRINTF((cbdev, "Prefetchable memory "
"rid=%x at %lx-%lx\n",
barlist[tmp]->rid,
barlist[tmp]->start,
barlist[tmp]->end));
continue;
}
barlist[tmp]->start =
rman_get_start(barlist[tmp]->res);
barlist[tmp]->end =
rman_get_end(barlist[tmp]->res);
pci_write_config(child,
barlist[tmp]->rid,
barlist[tmp]->start, 4);
bus_release_resource(cbdev, SYS_RES_MEMORY,
barlist[tmp]->rid, barlist[tmp]->res);
DEVPRINTF((cbdev, "Prefetchable memory "
"rid=%x at %lx-%lx\n",
barlist[tmp]->rid,
barlist[tmp]->start,
barlist[tmp]->end));
}
}
}
@ -749,7 +750,7 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
if (barlist[tmp]->res == NULL) {
DEVPRINTF((cbdev, "Cannot pre-allocate "
"memory for cardbus device\n"));
return ENOMEM;
return (ENOMEM);
}
barlist[tmp]->start =
rman_get_start(barlist[tmp]->res);
@ -757,6 +758,9 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
barlist[tmp]->res);
pci_write_config(child, barlist[tmp]->rid,
barlist[tmp]->start, 4);
bus_release_resource(cbdev, SYS_RES_MEMORY,
barlist[tmp]->rid, barlist[tmp]->res);
barlist[tmp]->res = NULL;
DEVPRINTF((cbdev, "Non-prefetchable memory "
"rid=%x at %lx-%lx (%lx)\n",
barlist[tmp]->rid, barlist[tmp]->start,
@ -784,14 +788,15 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
* (XXX: Perhaps there might be a better way to do this?)
*/
rid = 0;
res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0,
(dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags);
res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, ~0UL,
io_size, flags);
start = rman_get_start(res);
end = rman_get_end(res);
DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end));
/*
* Now that we know the region is free, release it and hand it
* out piece by piece.
* out piece by piece. XXX Need to interlock with the RM
* so we don't race here.
*/
bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res);
for (tmp = 0; tmp < count; tmp++) {
@ -811,26 +816,27 @@ cardbus_alloc_resources(device_t cbdev, device_t child)
rman_get_start(barlist[tmp]->res);
barlist[tmp]->end =
rman_get_end(barlist[tmp]->res);
pci_write_config(child, barlist[tmp]->rid,
barlist[tmp]->start, 4);
DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
barlist[tmp]->rid, barlist[tmp]->start,
barlist[tmp]->end));
pci_write_config(child, barlist[tmp]->rid,
barlist[tmp]->start, 4);
bus_release_resource(cbdev, SYS_RES_IOPORT,
barlist[tmp]->rid, barlist[tmp]->res);
barlist[tmp]->res = NULL;
DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n",
barlist[tmp]->rid, barlist[tmp]->start,
barlist[tmp]->end));
}
}
}
/* Allocate IRQ */
/* XXX: Search CIS for IRQ description */
rid = 0;
res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1,
RF_SHAREABLE);
resource_list_add(&dinfo->resources, SYS_RES_IRQ, rid,
resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid,
rman_get_start(res), rman_get_end(res), 1);
rle = resource_list_find(&dinfo->resources, SYS_RES_IRQ, rid);
rle->res = res;
dinfo->cfg.intline = rman_get_start(res);
dinfo->pci.cfg.intline = rman_get_start(res);
pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1);
bus_release_resource(cbdev, SYS_RES_IRQ, rid, res);
return 0;
}
@ -848,7 +854,7 @@ cardbus_add_map(device_t cbdev, device_t child, int reg)
u_int32_t testval;
int type;
SLIST_FOREACH(rle, &dinfo->resources, link) {
SLIST_FOREACH(rle, &dinfo->pci.resources, link) {
if (rle->rid == reg)
return;
}
@ -872,7 +878,7 @@ cardbus_add_map(device_t cbdev, device_t child, int reg)
size = CARDBUS_MAPREG_MEM_SIZE(testval);
device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n",
reg, size);
resource_list_add(&dinfo->resources, type, reg, 0UL, ~0UL, size);
resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size);
}
static void
@ -888,12 +894,13 @@ cardbus_pickup_maps(device_t cbdev, device_t child)
* the driver in its CIS.
* XXX: should we do this or use quirks?
*/
for (reg = 0; reg < dinfo->cfg.nummaps; reg++) {
for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) {
cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4);
}
for (q = &cardbus_quirks[0]; q->devid; q++) {
if (q->devid == ((dinfo->cfg.device << 16) | dinfo->cfg.vendor)
if (q->devid == ((dinfo->pci.cfg.device << 16) |
dinfo->pci.cfg.vendor)
&& q->type == CARDBUS_QUIRK_MAP_REG) {
cardbus_add_map(cbdev, child, q->arg1);
}

View File

@ -31,21 +31,10 @@
/*
* Structure definitions for the Cardbus Bus driver
*/
struct cardbus_intrlist {
SLIST_ENTRY(cardbus_intrlist) link;
device_t dev;
struct resource *irq;
void *cookie;
};
struct cardbus_devinfo {
struct resource_list resources;
pcicfgregs cfg;
struct pci_conf conf;
u_int8_t mprefetchable; /* bit mask of prefetchable BARs */
u_int8_t mbelow1mb; /* bit mask of BARs which require below 1Mb */
u_int8_t ibelow1mb; /* bit mask of BARs which require below 1Mb */
#define BARBIT(RID) (1<<((RID)-CARDBUS_BASE0_REG)/4)
SLIST_HEAD(, cardbus_intrlist) intrlist;
struct pci_devinfo pci;
u_int8_t mprefetchable; /* bit mask of prefetchable BARs */
u_int8_t mbelow1mb; /* bit mask of BARs which require below 1Mb */
u_int8_t ibelow1mb; /* bit mask of BARs which require below 1Mb */
#define BARBIT(RID) (1<<((RID)-CARDBUS_BASE0_REG)/4)
};

View File

@ -53,8 +53,9 @@
#include <machine/resource.h>
#include <sys/pciio.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pci_private.h>
#include "pcib_if.h"
#include "pci_if.h"
@ -66,10 +67,8 @@ static int pci_maprange(unsigned mapreg);
static void pci_fixancient(pcicfgregs *cfg);
static void pci_hdrtypedata(device_t pcib, int b, int s, int f,
pcicfgregs *cfg);
static struct pci_devinfo *pci_read_device(device_t pcib, int b, int s, int f);
static void pci_read_extcap(device_t pcib, pcicfgregs *cfg);
static void pci_print_verbose(struct pci_devinfo *dinfo);
static int pci_porten(device_t pcib, int b, int s, int f);
static int pci_memen(device_t pcib, int b, int s, int f);
static int pci_add_map(device_t pcib, int b, int s, int f, int reg,
@ -78,36 +77,9 @@ static void pci_add_resources(device_t pcib, int b, int s, int f,
device_t dev);
static void pci_add_children(device_t dev, int busno);
static int pci_probe(device_t dev);
static int pci_print_child(device_t dev, device_t child);
static void pci_probe_nomatch(device_t dev, device_t child);
static int pci_describe_parse_line(char **ptr, int *vendor,
int *device, char **desc);
static char *pci_describe_device(device_t dev);
static int pci_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result);
static int pci_write_ivar(device_t dev, device_t child, int which,
uintptr_t value);
static struct resource *pci_alloc_resource(device_t dev, device_t child,
int type, int *rid, u_long start,
u_long end, u_long count, u_int flags);
static void pci_delete_resource(device_t dev, device_t child,
int type, int rid);
static struct resource_list *pci_get_resource_list (device_t dev, device_t child);
static u_int32_t pci_read_config_method(device_t dev, device_t child,
int reg, int width);
static void pci_write_config_method(device_t dev, device_t child,
int reg, u_int32_t val, int width);
static void pci_enable_busmaster_method(device_t dev,
device_t child);
static void pci_disable_busmaster_method(device_t dev,
device_t child);
static void pci_enable_io_method(device_t dev, device_t child,
int space);
static void pci_disable_io_method(device_t dev, device_t child,
int space);
static int pci_set_powerstate_method(device_t dev, device_t child,
int state);
static int pci_get_powerstate_method(device_t dev, device_t child);
static int pci_modevent(module_t mod, int what, void *arg);
static device_method_t pci_methods[] = {
@ -337,7 +309,7 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
/* read configuration header into pcicfgregs structure */
static struct pci_devinfo *
struct pci_devinfo *
pci_read_device(device_t pcib, int b, int s, int f)
{
#define REG(n, w) PCIB_READ_CONFIG(pcib, b, s, f, n, w)
@ -460,18 +432,15 @@ pci_read_extcap(device_t pcib, pcicfgregs *cfg)
#undef REG
}
#if 0
/* free pcicfgregs structure and all depending data structures */
static int
int
pci_freecfg(struct pci_devinfo *dinfo)
{
struct devlist *devlist_head;
devlist_head = &pci_devq;
if (dinfo->cfg.map != NULL)
free(dinfo->cfg.map, M_DEVBUF);
/* XXX this hasn't been tested */
STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
free(dinfo, M_DEVBUF);
@ -483,12 +452,11 @@ pci_freecfg(struct pci_devinfo *dinfo)
pci_numdevs--;
return (0);
}
#endif
/*
* PCI power manangement
*/
static int
int
pci_set_powerstate_method(device_t dev, device_t child, int state)
{
struct pci_devinfo *dinfo = device_get_ivars(child);
@ -531,7 +499,7 @@ pci_set_powerstate_method(device_t dev, device_t child, int state)
return(result);
}
static int
int
pci_get_powerstate_method(device_t dev, device_t child)
{
struct pci_devinfo *dinfo = device_get_ivars(child);
@ -589,19 +557,19 @@ pci_clear_command_bit(device_t dev, device_t child, u_int16_t bit)
PCI_WRITE_CONFIG(dev, child, PCIR_COMMAND, command, 2);
}
static void
void
pci_enable_busmaster_method(device_t dev, device_t child)
{
pci_set_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
}
static void
void
pci_disable_busmaster_method(device_t dev, device_t child)
{
pci_clear_command_bit(dev, child, PCIM_CMD_BUSMASTEREN);
}
static void
void
pci_enable_io_method(device_t dev, device_t child, int space)
{
switch(space) {
@ -614,7 +582,7 @@ pci_enable_io_method(device_t dev, device_t child, int space)
}
}
static void
void
pci_disable_io_method(device_t dev, device_t child, int space)
{
switch(space) {
@ -632,7 +600,7 @@ pci_disable_io_method(device_t dev, device_t child, int space)
* pci-pci-bridge. Both kinds are represented by instances of pcib.
*/
static void
void
pci_print_verbose(struct pci_devinfo *dinfo)
{
if (bootverbose) {
@ -865,7 +833,7 @@ pci_probe(device_t dev)
return 0;
}
static int
int
pci_print_child(device_t dev, device_t child)
{
struct pci_devinfo *dinfo;
@ -956,7 +924,7 @@ static struct
{0, 0, NULL}
};
static void
void
pci_probe_nomatch(device_t dev, device_t child)
{
int i;
@ -1118,7 +1086,7 @@ pci_describe_device(device_t dev)
return(desc);
}
static int
int
pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
struct pci_devinfo *dinfo;
@ -1176,7 +1144,7 @@ pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
return 0;
}
static int
int
pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
{
struct pci_devinfo *dinfo;
@ -1208,7 +1176,7 @@ pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
return 0;
}
static struct resource *
struct resource *
pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
@ -1241,13 +1209,40 @@ pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
start, end, count, flags);
}
static void
void
pci_delete_resource(device_t dev, device_t child, int type, int rid)
{
printf("pci_delete_resource: PCI resources can not be deleted\n");
struct pci_devinfo *dinfo;
struct resource_list *rl;
struct resource_list_entry *rle;
if (device_get_parent(child) != dev)
return;
dinfo = device_get_ivars(child);
rl = &dinfo->resources;
rle = resource_list_find(rl, type, rid);
if (rle) {
if (rle->res) {
if (rle->res->r_dev != dev ||
rman_get_flags(rle->res) & RF_ACTIVE) {
device_printf(dev, "delete_resource: "
"Resource still owned by child, oops. "
"(type=%d, rid=%d, addr=%lx)\n",
rle->type, rle->rid,
rman_get_start(rle->res));
return;
}
bus_release_resource(dev, type, rid, rle->res);
}
resource_list_delete(rl, type, rid);
}
/* I don't understand the next line */
pci_write_config(child, rid, 0, 4);
BUS_DELETE_RESOURCE(device_get_parent(dev), child, type, rid);
}
static struct resource_list *
struct resource_list *
pci_get_resource_list (device_t dev, device_t child)
{
struct pci_devinfo * dinfo = device_get_ivars(child);
@ -1259,7 +1254,7 @@ pci_get_resource_list (device_t dev, device_t child)
return (rl);
}
static u_int32_t
u_int32_t
pci_read_config_method(device_t dev, device_t child, int reg, int width)
{
struct pci_devinfo *dinfo = device_get_ivars(child);
@ -1270,7 +1265,7 @@ pci_read_config_method(device_t dev, device_t child, int reg, int width)
reg, width);
}
static void
void
pci_write_config_method(device_t dev, device_t child, int reg,
u_int32_t val, int width)
{

67
sys/dev/pci/pci_private.h Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 1997, Stefan Esser <se@freebsd.org>
* Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
* Copyright (c) 2000, BSDi
* 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 unmodified, 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 ``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 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$
*
*/
#ifndef _PCI_PRIVATE_H_
#define _PCI_PRIVATE_H_
/*
* Export definitions of the pci bus so that we can more easily share
* it with "subclass" busses. A more generic subclassing mechanism would
* be nice, but is not present in the tree at this time.
*/
int pci_print_child(device_t dev, device_t child);
void pci_probe_nomatch(device_t dev, device_t child);
int pci_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result);
int pci_write_ivar(device_t dev, device_t child, int which,
uintptr_t value);
int pci_set_powerstate_method(device_t dev, device_t child,
int state);
int pci_get_powerstate_method(device_t dev, device_t child);
u_int32_t pci_read_config_method(device_t dev, device_t child,
int reg, int width);
void pci_write_config_method(device_t dev, device_t child,
int reg, u_int32_t val, int width);
void pci_enable_busmaster_method(device_t dev, device_t child);
void pci_disable_busmaster_method(device_t dev, device_t child);
void pci_enable_io_method(device_t dev, device_t child, int space);
void pci_disable_io_method(device_t dev, device_t child, int space);
struct resource *pci_alloc_resource(device_t dev, device_t child,
int type, int *rid, u_long start, u_long end, u_long count,
u_int flags);
void pci_delete_resource(device_t dev, device_t child,
int type, int rid);
struct resource_list *pci_get_resource_list (device_t dev, device_t child);
struct pci_devinfo *pci_read_device(device_t pcib, int b, int s, int f);
void pci_print_verbose(struct pci_devinfo *dinfo);
int pci_freecfg(struct pci_devinfo *dinfo);
#endif /* _PCI_PRIVATE_H_ */