Update intpm driver.
PR: 11531 Submitted by: Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
This commit is contained in:
parent
49c36ff4f3
commit
b2dd339fdc
237
sys/pci/intpm.c
237
sys/pci/intpm.c
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: intpm.c,v 1.6 1999/04/24 20:14:02 peter Exp $
|
||||
* $Id: intpm.c,v 1.7 1999/05/06 22:04:21 peter Exp $
|
||||
*/
|
||||
|
||||
#include "pci.h"
|
||||
@ -31,11 +31,9 @@
|
||||
|
||||
#if NPCI > 0
|
||||
#if NINTPM >0
|
||||
/* I don't think the chip is used in other architecture. :-)*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
#include <machine/bus_pio.h>
|
||||
#include <machine/bus_memio.h>
|
||||
#include <machine/bus.h>
|
||||
@ -47,7 +45,8 @@
|
||||
#include <sys/conf.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/buf.h>
|
||||
|
||||
#include <sys/rman.h>
|
||||
#include <machine/resource.h>
|
||||
#include <dev/smbus/smbconf.h>
|
||||
|
||||
#include "smbus_if.h"
|
||||
@ -93,9 +92,8 @@ static void intsmb_start(device_t dev,u_char cmd,int nointr);
|
||||
static int intsmb_stop(device_t dev);
|
||||
static int intsmb_stop_poll(device_t dev);
|
||||
static int intsmb_free(device_t dev);
|
||||
static struct intpm_pci_softc *intpm_alloc(int unit);
|
||||
static const char* intpm_probe __P((pcici_t tag, pcidi_t type));
|
||||
static void intpm_attach __P((pcici_t config_id, int unit));
|
||||
static int intpm_probe (device_t dev);
|
||||
static int intpm_attach (device_t dev);
|
||||
static devclass_t intsmb_devclass;
|
||||
|
||||
static device_method_t intpm_methods[]={
|
||||
@ -118,14 +116,14 @@ static device_method_t intpm_methods[]={
|
||||
{0,0}
|
||||
};
|
||||
|
||||
static struct intpm_pci_softc{
|
||||
struct intpm_pci_softc{
|
||||
bus_space_tag_t smbst;
|
||||
bus_space_handle_t smbsh;
|
||||
bus_space_tag_t pmst;
|
||||
bus_space_handle_t pmsh;
|
||||
pcici_t cfg;
|
||||
device_t smbus;
|
||||
}intpm_pci[NINTPM];
|
||||
};
|
||||
|
||||
|
||||
struct intsmb_softc{
|
||||
@ -135,26 +133,26 @@ struct intsmb_softc{
|
||||
device_t smbus;
|
||||
int isbusy;
|
||||
};
|
||||
|
||||
static driver_t intpm_driver = {
|
||||
"intsmb",
|
||||
intpm_methods,
|
||||
DRIVER_TYPE_MISC,
|
||||
sizeof(struct intsmb_softc),
|
||||
};
|
||||
static u_long intpm_count ;
|
||||
|
||||
static struct pci_device intpm_device = {
|
||||
"intpm",
|
||||
intpm_probe,
|
||||
intpm_attach,
|
||||
&intpm_count
|
||||
static devclass_t intpm_devclass;
|
||||
static device_method_t intpm_pci_methods[] = {
|
||||
DEVMETHOD(device_probe,intpm_probe),
|
||||
DEVMETHOD(device_attach,intpm_attach),
|
||||
{0,0}
|
||||
};
|
||||
static driver_t intpm_pci_driver = {
|
||||
"intpm",
|
||||
intpm_pci_methods,
|
||||
DRIVER_TYPE_MISC,
|
||||
sizeof(struct intpm_pci_softc)
|
||||
};
|
||||
|
||||
#ifdef COMPAT_PCI_DRIVER
|
||||
COMPAT_PCI_DRIVER (intpm, intpm_device);
|
||||
#else
|
||||
DATA_SET (pcidevice_set, intpm_device);
|
||||
#endif /* COMPAT_PCI_DRIVER */
|
||||
|
||||
static int
|
||||
intsmb_probe(device_t dev)
|
||||
@ -171,7 +169,7 @@ static int
|
||||
intsmb_attach(device_t dev)
|
||||
{
|
||||
struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
|
||||
sc->pci_sc=&intpm_pci[device_get_unit(dev)];
|
||||
sc->pci_sc=device_get_softc(device_get_parent(dev));
|
||||
sc->isbusy=0;
|
||||
sc->sh=sc->pci_sc->smbsh;
|
||||
sc->st=sc->pci_sc->smbst;
|
||||
@ -211,6 +209,7 @@ intsmb_callback(device_t dev, int index, caddr_t data)
|
||||
/*counterpart of smbtx_smb_free*/
|
||||
static int
|
||||
intsmb_free(device_t dev){
|
||||
intrmask_t s;
|
||||
struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
|
||||
if((bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS)&
|
||||
PIIX4_SMBHSTSTAT_BUSY)
|
||||
@ -220,6 +219,7 @@ intsmb_free(device_t dev){
|
||||
#endif
|
||||
|| sc->isbusy)
|
||||
return EBUSY;
|
||||
s=splhigh();
|
||||
sc->isbusy=1;
|
||||
/*Disable Intrrupt in slave part*/
|
||||
#ifndef ENABLE_ALART
|
||||
@ -232,6 +232,7 @@ intsmb_free(device_t dev){
|
||||
PIIX4_SMBHSTSTAT_BUSC|
|
||||
PIIX4_SMBHSTSTAT_FAIL)
|
||||
);
|
||||
splx(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -240,13 +241,11 @@ intsmb_intr(device_t dev)
|
||||
{
|
||||
struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
|
||||
int status;
|
||||
intrmask_t s;
|
||||
status=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTSTS);
|
||||
if(status&PIIX4_SMBHSTSTAT_BUSY){
|
||||
return 1;
|
||||
|
||||
}
|
||||
s=splhigh();
|
||||
if(sc->isbusy&&(status&(PIIX4_SMBHSTSTAT_INTR|
|
||||
PIIX4_SMBHSTSTAT_ERR|
|
||||
PIIX4_SMBHSTSTAT_BUSC|
|
||||
@ -256,11 +255,9 @@ intsmb_intr(device_t dev)
|
||||
tmp=bus_space_read_1(sc->st,sc->sh,PIIX4_SMBHSTCNT);
|
||||
bus_space_write_1(sc->st,sc->sh,PIIX4_SMBHSTCNT,
|
||||
tmp&~PIIX4_SMBHSTCNT_INTREN);
|
||||
splx(s);
|
||||
wakeup(sc);
|
||||
return 0;
|
||||
}
|
||||
splx(s);
|
||||
return 1;/* Not Completed*/
|
||||
}
|
||||
static int
|
||||
@ -385,6 +382,7 @@ intsmb_stop_poll(device_t dev){
|
||||
static int
|
||||
intsmb_stop(device_t dev){
|
||||
int error;
|
||||
intrmask_t s;
|
||||
struct intsmb_softc *sc = (struct intsmb_softc *)device_get_softc(dev);
|
||||
if(cold){
|
||||
/*So that it can use device during probing device on SMBus.*/
|
||||
@ -411,10 +409,12 @@ intsmb_stop(device_t dev){
|
||||
}
|
||||
}
|
||||
/*Timeout Procedure*/
|
||||
s=splhigh();
|
||||
sc->isbusy=0;
|
||||
/*Re-enable supressed intrrupt from slave part*/
|
||||
bus_space_write_1(sc->st,sc->sh,
|
||||
PIIX4_SMBSLVCNT,PIIX4_SMBSLVCNT_ALTEN);
|
||||
splx(s);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
@ -644,121 +644,66 @@ intsmb_bread(device_t dev, u_char slave, char cmd, u_char count, char *buf)
|
||||
return (error);
|
||||
}
|
||||
|
||||
DRIVER_MODULE(intsmb, root , intpm_driver, intsmb_devclass, 0, 0);
|
||||
DRIVER_MODULE(intsmb, intpm , intpm_driver, intsmb_devclass, 0, 0);
|
||||
|
||||
|
||||
static void intpm_intr __P((void *arg));
|
||||
|
||||
static const char*
|
||||
intpm_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
struct _pcsid *ep =pci_ids;
|
||||
while (ep->type && ep->type != type)
|
||||
++ep;
|
||||
return (ep->desc);
|
||||
}
|
||||
|
||||
static struct intpm_pci_softc *intpm_alloc(int unit){
|
||||
if(unit<NINTPM)
|
||||
return &intpm_pci[unit];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*Same as pci_map_int but this ignores INTPIN*/
|
||||
static int force_pci_map_int(pcici_t cfg, pci_inthand_t *func, void *arg, unsigned *maskptr)
|
||||
{
|
||||
#ifdef APIC_IO
|
||||
int nextpin, muxcnt;
|
||||
#endif
|
||||
/* Spec sheet claims that it use IRQ 9*/
|
||||
int irq = 9;
|
||||
void *idesc;
|
||||
|
||||
idesc = inthand_add(NULL, irq, func, arg, maskptr, 0);
|
||||
if (idesc == 0)
|
||||
return 0;
|
||||
#ifdef APIC_IO
|
||||
nextpin = next_apic_irq(irq);
|
||||
|
||||
if (nextpin < 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Attempt handling of some broken mp tables.
|
||||
*
|
||||
* It's OK to yell (since the mp tables are broken).
|
||||
*
|
||||
* Hanging in the boot is not OK
|
||||
*/
|
||||
|
||||
muxcnt = 2;
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
while (muxcnt < 5 && nextpin >= 0) {
|
||||
muxcnt++;
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
}
|
||||
if (muxcnt >= 5) {
|
||||
printf("bogus MP table, more than 4 IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("bogus MP table, %d IO APIC pins connected to the same PCI device or ISA/EISA interrupt\n", muxcnt);
|
||||
|
||||
nextpin = next_apic_irq(irq);
|
||||
while (nextpin >= 0) {
|
||||
idesc = inthand_add(NULL, nextpin, func, arg, maskptr, 0);
|
||||
if (idesc == 0)
|
||||
return 0;
|
||||
printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
|
||||
nextpin = next_apic_irq(nextpin);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
static void
|
||||
intpm_attach(config_id, unit)
|
||||
pcici_t config_id;
|
||||
int unit;
|
||||
static int
|
||||
intpm_attach(device_t dev)
|
||||
{
|
||||
int value;
|
||||
|
||||
int unit=device_get_unit(dev);
|
||||
void *ih;
|
||||
int error;
|
||||
char * str;
|
||||
{
|
||||
struct intpm_pci_softc *sciic;
|
||||
device_t smbinterface;
|
||||
value=pci_cfgread(config_id,PCI_BASE_ADDR_SMB,4);
|
||||
sciic=intpm_alloc(unit);
|
||||
int rid;
|
||||
struct resource *res;
|
||||
|
||||
sciic=device_get_softc(dev);
|
||||
if(sciic==NULL){
|
||||
return;
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
sciic->smbst=(value&1)?I386_BUS_SPACE_IO:I386_BUS_SPACE_MEM;
|
||||
|
||||
/*Calling pci_map_port is better.But bus_space_handle_t !=
|
||||
* pci_port_t, so I don't call support routine while
|
||||
* bus_space_??? support routine will be appear.
|
||||
*/
|
||||
sciic->smbsh=value&(~1);
|
||||
if(sciic->smbsh==I386_BUS_SPACE_MEM){
|
||||
/*According to the spec, this will not occur*/
|
||||
int dummy;
|
||||
pci_map_mem(config_id,PCI_BASE_ADDR_SMB,&sciic->smbsh,&dummy);
|
||||
rid=PCI_BASE_ADDR_SMB;
|
||||
#if 0
|
||||
res=bus_alloc_resource(dev,SYS_RES_IOPORT,&rid,
|
||||
0,~0,1,RF_ACTIVE);
|
||||
if(res==NULL){
|
||||
device_printf(dev,"IO FAILED Trying Memory\n");
|
||||
res=bus_alloc_resource(dev,SYS_RES_MEMORY,&rid,0,~0,
|
||||
1,RF_ACTIVE);
|
||||
}
|
||||
printf("intpm%d: %s %x ",unit,
|
||||
(sciic->smbst==I386_BUS_SPACE_IO)?"I/O mapped":"Memory",
|
||||
sciic->smbsh);
|
||||
#ifndef NO_CHANGE_PCICONF
|
||||
pci_cfgwrite(config_id,PCIR_INTLINE,0x09,1);
|
||||
pci_cfgwrite(config_id,PCI_HST_CFG_SMB,
|
||||
PCI_INTR_SMB_IRQ9|PCI_INTR_SMB_ENABLE,1);
|
||||
#else
|
||||
/*Do as I tell!*/
|
||||
value=pci_read_config(dev,rid,4);
|
||||
res=bus_alloc_resource(dev,SYS_RES_IOPORT,&rid,value&(~1),
|
||||
(value&(~1))+256,256,RF_ACTIVE);
|
||||
#endif
|
||||
config_id->intline=pci_cfgread(config_id,PCIR_INTLINE,1);
|
||||
printf("ALLOCED IRQ %d ",config_id->intline);
|
||||
value=pci_cfgread(config_id,PCI_HST_CFG_SMB,1);
|
||||
if(res==NULL){
|
||||
device_printf(dev,"Could not allocate Bus space\n");
|
||||
return ENXIO;
|
||||
}
|
||||
sciic->smbst=rman_get_bustag(res);
|
||||
sciic->smbsh=rman_get_bushandle(res);
|
||||
|
||||
device_printf(dev,"%s %x\n",
|
||||
(sciic->smbst==I386_BUS_SPACE_IO)?
|
||||
"I/O mapped":"Memory",
|
||||
sciic->smbsh);
|
||||
|
||||
|
||||
#ifndef NO_CHANGE_PCICONF
|
||||
pci_write_config(dev,PCIR_INTLINE,0x9,1);
|
||||
pci_write_config(dev,PCI_HST_CFG_SMB,
|
||||
PCI_INTR_SMB_IRQ9|PCI_INTR_SMB_ENABLE,1);
|
||||
#endif
|
||||
value=pci_read_config(dev,PCI_HST_CFG_SMB,1);
|
||||
switch(value&0xe){
|
||||
case PCI_INTR_SMB_SMI:
|
||||
str="SMI";
|
||||
str="SMI";
|
||||
break;
|
||||
case PCI_INTR_SMB_IRQ9:
|
||||
str="IRQ 9";
|
||||
@ -766,22 +711,50 @@ intpm_attach(config_id, unit)
|
||||
default:
|
||||
str="BOGUS";
|
||||
}
|
||||
printf("intr %s %s ",str,((value&1)? "enabled":"disabled"));
|
||||
value=pci_cfgread(config_id,PCI_REVID_SMB,1);
|
||||
device_printf(dev,"intr %s %s ",str,((value&1)? "enabled":"disabled"));
|
||||
value=pci_read_config(dev,PCI_REVID_SMB,1);
|
||||
printf("revision %d\n",value);
|
||||
/*
|
||||
* Install intr HANDLER here
|
||||
*/
|
||||
if(force_pci_map_int(config_id,intpm_intr,sciic,&net_imask)==0){
|
||||
printf("intpm%d: Failed to map intr\n",unit);
|
||||
rid=0;
|
||||
res=bus_alloc_resource(dev,SYS_RES_IRQ,&rid,9,9,1,RF_SHAREABLE|RF_ACTIVE);
|
||||
if(res==NULL){
|
||||
device_printf(dev,"could not allocate irq");
|
||||
return ENOMEM;
|
||||
}
|
||||
error=bus_setup_intr(dev,res,(driver_intr_t *) intpm_intr,sciic,&ih);
|
||||
if(error){
|
||||
device_printf(dev,"Failed to map intr\n");
|
||||
return error;
|
||||
}
|
||||
smbinterface=device_add_child(root_bus,"intsmb",unit,NULL);
|
||||
smbinterface=device_add_child(dev,"intsmb",unit,NULL);
|
||||
if(!smbinterface){
|
||||
printf("intsmb%d:could not add SMBus device\n",unit);
|
||||
}
|
||||
device_probe_and_attach(smbinterface);
|
||||
}
|
||||
value=pci_cfgread(config_id,PCI_BASE_ADDR_PM,4);
|
||||
|
||||
value=pci_read_config(dev,PCI_BASE_ADDR_PM,4);
|
||||
printf("intpm%d: PM %s %x \n",unit,(value&1)?"I/O mapped":"Memory",value&0xfffe);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
static int
|
||||
intpm_probe(device_t dev)
|
||||
{
|
||||
struct _pcsid *ep =pci_ids;
|
||||
u_int32_t device_id=pci_get_devid(dev);
|
||||
while (ep->type && ep->type != device_id)
|
||||
++ep;
|
||||
if(ep->desc!=NULL){
|
||||
device_set_desc(dev,ep->desc);
|
||||
return 0;
|
||||
}else{
|
||||
return ENXIO;
|
||||
}
|
||||
}
|
||||
DRIVER_MODULE(intpm, pci , intpm_pci_driver, intpm_devclass, 0, 0);
|
||||
|
||||
static void intpm_intr(void *arg)
|
||||
{
|
||||
struct intpm_pci_softc *sc;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcisupport.c,v 1.101 1999/05/06 21:21:30 julian Exp $
|
||||
** $Id: pcisupport.c,v 1.102 1999/05/07 04:04:42 julian Exp $
|
||||
**
|
||||
** Device driver for DEC/INTEL PCI chipsets.
|
||||
**
|
||||
@ -1091,7 +1091,11 @@ chip_match(device_t dev)
|
||||
return ("Intel 82439TX System Controller (MTXC)");
|
||||
|
||||
case 0x71138086:
|
||||
#if NINTPM > 0
|
||||
return NULL;
|
||||
#else
|
||||
return ("Intel 82371AB Power management controller");
|
||||
#endif
|
||||
case 0x12378086:
|
||||
fixwsc_natoma(dev);
|
||||
return ("Intel 82440FX (Natoma) PCI and memory controller");
|
||||
|
Loading…
x
Reference in New Issue
Block a user