Update intpm driver.

PR:		11531
Submitted by:	Takanori Watanabe <takawata@shidahara1.planet.sci.kobe-u.ac.jp>
This commit is contained in:
Peter Wemm 1999-05-07 18:03:27 +00:00
parent 49c36ff4f3
commit b2dd339fdc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46651
2 changed files with 110 additions and 133 deletions

View file

@ -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;

View file

@ -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");