Subject: -current kernel build fails (unofficial patches)c
To: None <port-macppc@NetBSD.org>
From: dixie <dixieml@imap.cc>
List: port-macppc
Date: 08/02/2005 00:15:33
This is a multi-part message in MIME format.
--------------040300030605080708010009
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Hi list,
I was trying to build a 3.99.7 kernel after having applied the patch 
supplied by Michael on December 2004 concerning hw sensors (see 
http://mail-index.netbsd.org/port-macppc/2004/12/15/0014.html)
I've been using that patch since 3.99.5 and all worked fine, now the 
build process terminate with some warnings on adt7467.c:



horus# make
#   compile  HORUS/adt7467.o
cc -mno-strict-align -msoft-float -Wa,-maltivec -ffreestanding -O2 
-Wreturn-type -Werror -Wall -Wno-main -Wno-format-zero-length 
-Wpointer-arith -Wmissing-prototypes -Wstrict-prototypes -Wreturn-type 
-Wswitch -Wshadow -Wcast-qual -Wwrite-strings -Wno-sign-compare 
-fno-zero-initialized-in-bss -Dmacppc=macppc -I. -I../../../../arch 
-I../../../.. -nostdinc -DDIAGNOSTIC -DZS_CONSOLE_ABORT 
-DOFB_ENABLE_CACHE -DMAXUSERS=10 -D_KERNEL -D_KERNEL_OPT 
-I../../../../dist/ipf -c ../../../../arch/macppc/dev/adt7467.c
../../../../arch/macppc/dev/adt7467.c: In function `sysctl_adt7467_temp':
../../../../arch/macppc/dev/adt7467.c:202: warning: cast discards 
qualifiers from pointer target type
../../../../arch/macppc/dev/adt7467.c: In function `adt7467c_setup':
../../../../arch/macppc/dev/adt7467.c:255: warning: passing arg 4 of 
`sysctl_createv' from incompatible pointer type
../../../../arch/macppc/dev/adt7467.c:290: warning: passing arg 4 of 
`sysctl_createv' from incompatible pointer type
*** Error code 1

Stop.
make: stopped in /usr/src/sys/arch/macppc/compile/HORUS



unfortunately I'm not so in touch with pure C and kernel internals to 
correct the problem by myself :)
What could be?
It always compiled fine with src <= 3.99.5
Also the userland is built from 3.99.5 sources, gcc is version 3.3.3.
I attach the .c files I added to dev/ and the patch-file.

Best regards

d.

--------------040300030605080708010009
Content-Type: text/plain;
 name="adt7467.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="adt7467.c"

/*	$NetBSD: fan.c,v 1.20 2004/12/09 03:19:56 briggs Exp $	*/

/*-
 * Copyright (C) 1998	Internet Research Institute, Inc.
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by
 *	Internet Research Institute, Inc.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 */

/* a driver fot the ADT7467 environmental controller found in the iBook G4 
   and probably other Apple machines */

/* todo: get the parental interface right, this is an ugly hack. The driver
   should work with ANY i2c bus as parent */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fan.c,v 1.20 2004/12/09 03:19:56 briggs Exp $");

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/sysctl.h>

#include <uvm/uvm_extern.h>

#include <dev/ofw/openfirm.h>
#include <dev/i2c/i2cvar.h>

#include <machine/autoconf.h>
#include <dev/sysmon/sysmonvar.h>
#include "sysmon_envsys.h"


static void adt7467c_attach __P((struct device *, struct device *, void *));
static int adt7467c_match __P((struct device *, struct cfdata *, void *));

struct adt7467c_softc {
	struct device sc_dev;
	struct device *parent;
	int sc_node, address;
	int num_sensors;
	struct sysmon_envsys *sc_sysmon_cookie;
	struct i2c_controller *sc_i2c;
	uint8_t regs[32];
};

struct adt7467c_sysmon {
		struct sysmon_envsys sme;
		struct adt7467c_softc *sc;
		struct envsys_tre_data adt7467c_info[];
	};

struct regdesc {
	struct i2c_controller *rd_i2c;
	uint32_t rd_reg;
};

static uint8_t adt7467c_readreg(struct adt7467c_softc *, uint8_t);
static void adt7467c_writereg(struct adt7467c_softc *, uint8_t, uint8_t);
static void adt7467c_setup(struct adt7467c_softc *);
int sensor_type(char *);
int temp2muk(uint8_t);
int reg2rpm(uint16_t);
int adt7467c_gtredata(struct sysmon_envsys *, struct envsys_tre_data *);
int adt7467c_streinfo(struct sysmon_envsys *, struct envsys_basic_info *);

CFATTACH_DECL(adt7467c, sizeof(struct adt7467c_softc),
    adt7467c_match, adt7467c_attach, NULL, NULL);

int
adt7467c_match(parent, cf, aux)
	struct device *parent;
	struct cfdata *cf;
	void *aux;
{
	struct confargs *ca = aux;
	char compat[32];
	if (strcmp(ca->ca_name, "fan") != 0)
		return 0;

	memset(compat, 0, sizeof(compat));
	OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
	if (strcmp(compat, "adt7467") != 0)
		return 0;
	
	return 1;
}

void
adt7467c_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct adt7467c_softc *sc = (struct adt7467c_softc *)self;
	struct confargs *ca = aux;
	int node;

	node = ca->ca_node;
	sc->sc_node = node;
	sc->parent=parent;
	sc->address=ca->ca_reg[0]&0xfe;
	printf(" ADT7467 thermal monitor and fan controller\n");
	sc->sc_i2c=(struct i2c_controller *)ca->ca_baseaddr;
#ifdef ADT7467_DEBUG
	printf("\n%s: node %08x\n",sc->sc_dev.dv_xname,node);
#endif
	adt7467c_setup(sc);
#ifdef ADT7467_DEBUG
	printf("%d %d %d\n",adt7467c_readreg(sc,0x68),adt7467c_readreg(sc,0x69),adt7467c_readreg(sc,0x67));
#endif
}

uint8_t adt7467c_readreg(struct adt7467c_softc *sc, uint8_t reg)
{
	uint8_t data=0;;
	iic_acquire_bus(sc->sc_i2c,0);
	iic_exec(sc->sc_i2c, I2C_OP_READ,sc->address,&reg,1,&data,1,0);
	iic_release_bus(sc->sc_i2c,0);
	return data;
}

void adt7467c_writereg(struct adt7467c_softc *sc, uint8_t reg, uint8_t data)
{
	uint8_t mdata[2]={reg,data};
	iic_acquire_bus(sc->sc_i2c,0);
	iic_exec(sc->sc_i2c, I2C_OP_WRITE,sc->address,&mdata,2,NULL,0,0);
	iic_release_bus(sc->sc_i2c,0);
}

#if NSYSMON_ENVSYS > 0

struct envsys_range *adt7467c_ranges;
struct envsys_basic_info *adt7467c_info;

int sensor_type(char *t)
{
	if(strcmp(t,"temperature")==0)
		return ENVSYS_STEMP;
	if(strcmp(t,"voltage")==0)
		return ENVSYS_SVOLTS_DC;
	if(strcmp(t,"fanspeed")==0)
		return ENVSYS_SFANRPM;
	return -1;
}

int temp2muk(uint8_t t)
{
	int temp=(int8_t)t;
	return temp*1000000+273150000U;
}

int reg2rpm(uint16_t r)
{
	if(r==0xffff)
		return 0;
	return (90000*60)/(int)r;
}

SYSCTL_SETUP(sysctl_adt7467_setup, "sysctl ADT7467 subtree setup")
{
#ifdef ADT7467_DEBUG
	printf("node setup\n");
#endif
	sysctl_createv(NULL, 0, NULL, NULL,
		       CTLFLAG_PERMANENT,
		       CTLTYPE_NODE, "machdep", NULL,
		       NULL, 0, NULL, 0,
		       CTL_MACHDEP, CTL_EOL);
}

static int
sysctl_adt7467_temp(SYSCTLFN_ARGS)
{
	struct sysctlnode node = *rnode;
	struct adt7467c_softc *sc=(struct adt7467c_softc *)node.sysctl_data;
	int reg=12345, nd=0;
	int *np=(int *)newp;
	uint8_t chipreg=(uint8_t)(node.sysctl_idata&0xff);
	reg=(uint32_t)adt7467c_readreg(sc,chipreg);
	node.sysctl_idata=reg;
	if(np) {
		/* we're asked to write */	
		nd=*np;
		node.sysctl_data=&reg;
		if(sysctl_lookup(SYSCTLFN_CALL(&node))==0) {
			int8_t new_reg;
			new_reg=(int8_t)(max(30,min(85,node.sysctl_idata)));
			adt7467c_writereg(sc,chipreg,new_reg);
			return 0;
		}
		return EINVAL;
	} else {
		node.sysctl_size=4;
		return(sysctl_lookup(SYSCTLFN_CALL(&node)));
	}
}

void
adt7467c_setup(struct adt7467c_softc *sc)
{
	struct adt7467c_sysmon *datap;
	int error, num, cnt, tcnt,wcnt, c_tmp, c_rpm;
	char types[1024], where[1024];
	uint8_t temp[]={0x26,0x27,0x25}, stuff;
	struct envsys_range *cur_r;
	struct envsys_basic_info *cur_i;
	struct envsys_tre_data *cur_t;
	int sensor_id[32], i,ret;
	char type[32];
	struct sysctlnode *me=NULL, *node=NULL;
	
	/* look for sensors */
	cnt=OF_getprop(sc->sc_node,"hwsensor-id",sensor_id,sizeof(sensor_id));
	num=cnt>>2;
	sc->num_sensors=num;
	datap = malloc(sizeof(struct sysmon_envsys)+num*sizeof(struct envsys_tre_data)+sizeof(void *), M_DEVBUF, M_WAITOK | M_ZERO);
	adt7467c_ranges = malloc (sizeof(struct envsys_range)*num, M_DEVBUF, M_WAITOK | M_ZERO);
	adt7467c_info = malloc (sizeof(struct envsys_basic_info)*num, M_DEVBUF, M_WAITOK | M_ZERO);
	
	printf("%s: found %d sensors\n",sc->sc_dev.dv_xname,num);
	cnt=OF_getprop(sc->sc_node,"hwsensor-type",types,1024);
	cnt=OF_getprop(sc->sc_node,"hwsensor-location",where,1024);
	tcnt=wcnt=0;
	c_tmp=0;
	c_rpm=0x28;
	ret=sysctl_createv(NULL, 0, NULL, &me,
	       CTLFLAG_READWRITE,
	       CTLTYPE_NODE, sc->sc_dev.dv_xname, NULL,
	       NULL, 0, NULL, 0,
	       CTL_MACHDEP, CTL_CREATE, CTL_EOL);
#ifdef ADT7467_DEBUG
	if(me!=NULL)
		printf("create node %s: %d -> %d\n",sc->sc_dev.dv_xname,ret,me->sysctl_num);
	printf("i2c: %08x\n",(uint32_t)sc->sc_i2c);
#endif
	for (i=0;i<num;i++)
	{
		cur_r=&adt7467c_ranges[i];
		cur_i=&adt7467c_info[i];
		cur_t=&datap->adt7467c_info[i];
		strncpy(cur_i->desc,&where[wcnt],32);
		wcnt+=strlen(cur_i->desc)+1;
		strncpy(type,&types[tcnt],32);
		tcnt+=strlen(type)+1;
		cur_i->units=sensor_type(type);
		cur_i->sensor=i;
		printf("%2d: %s %s\n",i+1, type, cur_i->desc);
		switch(cur_i->units)
		{
			case ENVSYS_STEMP:
				{
					char name[16];
					struct regdesc rd;
					sc->regs[i]=temp[c_tmp];
					cur_r->low=temp2muk(-127);
					cur_r->high=temp2muk(127);
					cur_r->units=ENVSYS_STEMP;
					rd.rd_i2c=sc->sc_i2c;
					rd.rd_reg=sc->regs[i]+0x42;
					snprintf(name,16,"temp%d",c_tmp);
					ret=sysctl_createv(NULL, 0, NULL, &node,
				       CTLFLAG_READWRITE|CTLFLAG_OWNDESC|CTLFLAG_IMMEDIATE,
				       CTLTYPE_INT, name, cur_i->desc,
		   			    sysctl_adt7467_temp,sc->regs[i]+0x42 , NULL, 0,
		   			    CTL_MACHDEP, me->sysctl_num, CTL_CREATE, CTL_EOL);
					if(node!=NULL) {
						node->sysctl_data=sc;
					}
					#ifdef ADT7467_DEBUG
					printf("create node %s: %d\n",name,ret);
					#endif
					c_tmp++;
				}
				break;
			case ENVSYS_SVOLTS_DC:
				{
					sc->regs[i]=0x21;	/* there's only one voltage sensor */
					cur_r->low=0;
					cur_r->high=2250;	/* 2.25v */
					cur_r->units=ENVSYS_SVOLTS_DC;
					cur_i->rfact=1;
				}
				break;
			case ENVSYS_SFANRPM:
				{
					sc->regs[i]=c_rpm;
					cur_r->low=0;
					cur_r->high=reg2rpm(0xfffe);
					cur_r->units=ENVSYS_SFANRPM;
					c_rpm+=2;	/* fan output is 16bit */
				}
				break;
		}
		cur_i->validflags=ENVSYS_FVALID|ENVSYS_FCURVALID;
		cur_t->sensor = i;
		cur_t->warnflags = ENVSYS_WARN_OK;
		cur_t->validflags = ENVSYS_FVALID|ENVSYS_FCURVALID;
		cur_t->units=cur_i->units;
	}
	stuff=adt7467c_readreg(sc,0x40);
	adt7467c_writereg(sc,0x40,stuff);

	sc->sc_sysmon_cookie = &datap->sme;
	datap->sme.sme_nsensors = num;
	datap->sme.sme_envsys_version = 1000;
	datap->sme.sme_ranges = adt7467c_ranges;
	datap->sme.sme_sensor_info = adt7467c_info;
	datap->sme.sme_sensor_data = datap->adt7467c_info;
	
	datap->sme.sme_cookie = sc;
	datap->sme.sme_gtredata = adt7467c_gtredata;
	datap->sme.sme_streinfo = adt7467c_streinfo;
	datap->sme.sme_flags = 0;

	if ((error = sysmon_envsys_register(&datap->sme)) != 0)
		aprint_error("%s: unable to register with sysmon (%d)\n",
		    sc->sc_dev.dv_xname, error);
}


int
adt7467c_gtredata(struct sysmon_envsys *sme, struct envsys_tre_data *tred)
{
//	struct adt7467c_sysmon *sm=(struct adt7467c_sysmon *)sme;
	struct adt7467c_softc *sc=sme->sme_cookie;
	struct envsys_tre_data *cur_tre;
	struct envsys_basic_info *cur_i;
	uint8_t reg;
	int i;
	
/*	for(i=0;i<sme->sme_nsensors;i++) {*/
	i=tred->sensor;
		cur_tre=&sme->sme_sensor_data[i];
		//cur_tre=tred;
		cur_i=&sme->sme_sensor_info[i];
		reg=sc->regs[i];
		switch(cur_tre->units)
		{
			case ENVSYS_STEMP:
				cur_tre->cur.data_s=temp2muk(adt7467c_readreg(sc,reg));
				break;
			case ENVSYS_SVOLTS_DC:
				{
					uint32_t vr=adt7467c_readreg(sc,reg);
					cur_tre->cur.data_us=(int)((vr*2500000)/0xc0);
				}
				break;
			case ENVSYS_SFANRPM:
				{
					uint16_t blah=(((uint16_t)adt7467c_readreg(sc,reg))|((uint16_t)adt7467c_readreg(sc,reg+1)<<8));
					cur_tre->cur.data_us=reg2rpm(blah);
				}
				break;
		}
		cur_tre->validflags|=ENVSYS_FCURVALID|ENVSYS_FVALID;
	//}
	//sme->sme_sensor_data->cur.data_us = (threshold * 1000000) + 273150000;
	*tred = sme->sme_sensor_data[i];
	return 0;
}

int
adt7467c_streinfo(struct sysmon_envsys *sme, struct envsys_basic_info *binfo)
{

	/* There is nothing to set here. */
	return (EINVAL);
}
#endif /* NSYSMON_ENVSYS > 0 */

--------------040300030605080708010009
Content-Type: text/plain;
 name="deq.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="deq.c"

/*	$NetBSD: fan.c,v 1.20 2004/12/09 03:19:56 briggs Exp $	*/

/*-
 * Copyright (C) 1998	Internet Research Institute, Inc.
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by
 *	Internet Research Institute, Inc.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 */

/* a driver fot the ADT7467 environmental controller found in the iBook G4 
   and probably other Apple machines */

/* todo: get the parental interface right, this is an ugly hack. The driver
   should work with ANY i2c bus as parent */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: fan.c,v 1.20 2004/12/09 03:19:56 briggs Exp $");

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/malloc.h>

#include <uvm/uvm_extern.h>

#include <dev/ofw/openfirm.h>
#include <dev/i2c/i2cvar.h>

#include <machine/autoconf.h>

static void deq_attach __P((struct device *, struct device *, void *));
static int deq_match __P((struct device *, struct cfdata *, void *));

struct deq_softc {
	struct device sc_dev;
	struct device *parent;
	int sc_node, address;
	struct i2c_controller *sc_i2c;
};

CFATTACH_DECL(deq, sizeof(struct deq_softc),
    deq_match, deq_attach, NULL, NULL);

int
deq_match(parent, cf, aux)
	struct device *parent;
	struct cfdata *cf;
	void *aux;
{
	struct confargs *ca = aux;
	char compat[32];
	if (strcmp(ca->ca_name, "deq") != 0)
		return 0;

	memset(compat, 0, sizeof(compat));
	if(OF_getprop(ca->ca_node, "i2c-address", compat, sizeof(compat)))
		return 1;
	return 0;
}

void
deq_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct deq_softc *sc = (struct deq_softc *)self;
	struct confargs *ca = aux;
	int node;

	node = ca->ca_node;
	sc->sc_node = node;
	sc->parent=parent;
	sc->address=ca->ca_reg[0]&0xfe;
	sc->sc_i2c=(struct i2c_controller *)ca->ca_baseaddr;
	printf(" Apple Digital Equalizer\n");
	//printf("%s: node %08x\n",sc->sc_dev.dv_xname,node);
}

--------------040300030605080708010009
Content-Type: text/plain;
 name="uni-n.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="uni-n.c"

/*	$NetBSD: uni_-.c,v 1.20 2004/12/09 03:19:56 briggs Exp $	*/

/*-
 * Copyright (C) 1998	Internet Research Institute, Inc.
 * 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.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by
 *	Internet Research Institute, Inc.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * 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.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: uni-n.c,v 1.20 2004/12/09 03:19:56 briggs Exp $");

#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/device.h>

#include <dev/ofw/openfirm.h>

#include <machine/autoconf.h>

static void uni_n_attach __P((struct device *, struct device *, void *));
static int uni_n_match __P((struct device *, struct cfdata *, void *));
static int uni_n_print __P((void *, const char *));

struct uni_n_softc {
	struct device sc_dev;
	int sc_node;
};


CFATTACH_DECL(uni_n, sizeof(struct uni_n_softc),
    uni_n_match, uni_n_attach, NULL, NULL);

int
uni_n_match(parent, cf, aux)
	struct device *parent;
	struct cfdata *cf;
	void *aux;
{
	struct confargs *ca = aux;
	char compat[32];
	if (strcmp(ca->ca_name, "uni-n") != 0)
		return 0;

	memset(compat, 0, sizeof(compat));
	OF_getprop(ca->ca_node, "compatible", compat, sizeof(compat));
	if (strcmp(compat, "uni-north") != 0)
		return 0;

	return 1;
}

/*
 * Attach all the sub-devices we can find
 */
void
uni_n_attach(parent, self, aux)
	struct device *parent, *self;
	void *aux;
{
	struct uni_n_softc *sc = (struct uni_n_softc *)self;
	struct confargs *our_ca = aux;
	struct confargs ca;
	int node, child, namelen;
	u_int reg[20];
	int intr[6];
	char name[32];

	node = OF_finddevice("/uni-n");
	sc->sc_node = node;
	printf(" address 0x%08x\n",our_ca->ca_reg[0]);
	//printf("%s: node %08x\n",sc->sc_dev.dv_xname,node);
	
	for (child = OF_child(node); child; child = OF_peer(child)) {
		namelen = OF_getprop(child, "name", name, sizeof(name));
		if (namelen < 0)
			continue;
		if (namelen >= sizeof(name))
			continue;

		name[namelen] = 0;
		ca.ca_name = name;
		ca.ca_node = child;

		ca.ca_nreg  = OF_getprop(child, "reg", reg, sizeof(reg));
		ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
				sizeof(intr));
		if (ca.ca_nintr == -1)
			ca.ca_nintr = OF_getprop(child, "interrupts", intr,
					sizeof(intr));

		ca.ca_reg = reg;
		ca.ca_intr = intr;

		config_found(self, &ca, uni_n_print);
	}
}

int
uni_n_print(aux, uni_n)
	void *aux;
	const char *uni_n;
{
	struct confargs *ca = aux;
	if (uni_n)
		aprint_normal("%s at %s", ca->ca_name, uni_n);

	if (ca->ca_nreg > 0)
		aprint_normal(" address 0x%x", ca->ca_reg[0]);

	return UNCONF;
}

--------------040300030605080708010009
Content-Type: text/plain;
 name="ki2c.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ki2c.patch"

Index: conf/files.macppc
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/conf/files.macppc,v
retrieving revision 1.63
diff -u -w -r1.63 files.macppc
--- conf/files.macppc	25 Mar 2004 18:52:25 -0000	1.63
+++ conf/files.macppc	15 Dec 2004 17:29:45 -0000
@@ -72,6 +72,12 @@
 attach uninorth at mainbus
 file arch/macppc/pci/uninorth.c			uninorth
 
+# pseudodev for the UniNorth host controller
+define uni_n {}
+device uni_n: uni_n
+attach uni_n at mainbus
+file arch/macppc/dev/uni-n.c			uni_n
+
 # PCI bus support
 include "dev/pci/files.pci"
 
@@ -195,8 +201,9 @@
 file arch/macppc/macppc/rbus_machdep.c		cardbus
 
 # Keywest I2C
-device ki2c {}
-attach ki2c at obio
+define ki2c {}
+device ki2c: i2cbus, ki2c
+attach ki2c at obio, uni_n
 file arch/macppc/dev/ki2c.c			ki2c
 
 # snapper audio
@@ -205,3 +212,14 @@
 file arch/macppc/dev/snapper.c			snapper
 
 include "arch/macppc/conf/majors.macppc"
+
+define adt7467c {}
+device adt7467c: sysmon_envsys
+attach adt7467c at ki2c
+file arch/macppc/dev/adt7467.c			adt7467c
+
+define deq {}
+device deq
+attach deq at ki2c
+file arch/macppc/dev/deq.c				deq
+
Index: dev/ki2c.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/ki2c.c,v
retrieving revision 1.1
diff -u -w -r1.1 ki2c.c
--- dev/ki2c.c	27 Dec 2003 02:19:34 -0000	1.1
+++ dev/ki2c.c	15 Dec 2004 17:29:46 -0000
@@ -35,6 +35,8 @@
 #include <uvm/uvm_extern.h>
 #include <machine/autoconf.h>
 
+#include <dev/i2c/i2cvar.h>
+
 /* Keywest I2C Register offsets */
 #define MODE	0
 #define CONTROL	1
@@ -86,6 +88,9 @@
 	u_char *sc_reg;
 	int sc_regstep;
 
+	struct i2c_controller sc_i2c;
+	struct lock sc_buslock;
+
 	int sc_flags;
 	u_char *sc_data;
 	int sc_resid;
@@ -104,6 +109,14 @@
 int ki2c_start(struct ki2c_softc *, int, int, void *, int);
 int ki2c_read(struct ki2c_softc *, int, int, void *, int);
 int ki2c_write(struct ki2c_softc *, int, int, const void *, int);
+int ki2c_print __P((void *, const char *));
+
+/* I2C glue */
+static int ki2c_i2c_acquire_bus(void *, int);
+static void ki2c_i2c_release_bus(void *, int);
+static int	ki2c_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t,
+		    void *, size_t, int);
+
 
 struct cfattach ki2c_ca = {
 	"ki2c", {}, sizeof(struct ki2c_softc), ki2c_match, ki2c_attach
@@ -132,7 +145,12 @@
 	struct ki2c_softc *sc = (struct ki2c_softc *)self;
 	struct confargs *ca = aux;
 	int node = ca->ca_node;
-	int rate;
+	int rate, child, namelen;
+	struct confargs c_ca;
+	struct i2cbus_attach_args iba;
+
+	char name[32];
+	u_int reg[20];
 
 	ca->ca_reg[0] += ca->ca_baseaddr;
 
@@ -157,6 +175,56 @@
 
 	ki2c_setmode(sc, I2C_STDSUBMODE);
 	ki2c_setspeed(sc, I2C_100kHz);		/* XXX rate */
+	
+	lockinit(&sc->sc_buslock, PRIBIO|PCATCH, sc->sc_dev.dv_xname, 0, 0);
+
+	/* fill in the i2c tag */
+	sc->sc_i2c.ic_cookie = sc;
+	sc->sc_i2c.ic_acquire_bus = ki2c_i2c_acquire_bus;
+	sc->sc_i2c.ic_release_bus = ki2c_i2c_release_bus;
+	sc->sc_i2c.ic_send_start = NULL;
+	sc->sc_i2c.ic_send_stop = NULL;
+	sc->sc_i2c.ic_initiate_xfer = NULL;
+	sc->sc_i2c.ic_read_byte = NULL;
+	sc->sc_i2c.ic_write_byte = NULL;
+	sc->sc_i2c.ic_exec=ki2c_i2c_exec;
+
+	iba.iba_name = "iic";
+	iba.iba_tag = &sc->sc_i2c;
+	(void) config_found(&sc->sc_dev, &iba, iicbus_print);
+
+
+	for (child = OF_child(node); child; child = OF_peer(child)) {
+		namelen = OF_getprop(child, "name", name, sizeof(name));
+		if (namelen < 0)
+			continue;
+		if (namelen >= sizeof(name))
+			continue;
+
+		name[namelen] = 0;
+		c_ca.ca_name = name;
+		c_ca.ca_node = child;
+		c_ca.ca_nreg  = OF_getprop(child, "reg", reg, sizeof(reg));
+		c_ca.ca_reg = reg;
+		c_ca.ca_baseaddr=(u_int)&sc->sc_i2c;	/* ugly, but we must pass the i2c somehow */
+		config_found(self, &c_ca, ki2c_print);
+	}
+}
+
+int
+ki2c_print(aux, ki2c)
+	void *aux;
+	const char *ki2c;
+{
+	struct confargs *ca = aux;
+
+	if (ki2c)
+		aprint_normal("%s at %s", ca->ca_name, ki2c);
+
+	if (ca->ca_nreg > 0)
+		aprint_normal(" address 0x%x", ca->ca_reg[0]);
+
+	return UNCONF;
 }
 
 u_int
@@ -231,7 +299,6 @@
 	u_int isr, x;
 
 	isr = ki2c_readreg(sc, ISR);
-
 	if (isr & I2C_INT_ADDR) {
 #if 0
 		if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
@@ -353,6 +420,9 @@
 	void *data;
 {
 	sc->sc_flags = I2C_READING;
+	#ifdef KI2C_DEBUG
+		printf("ki2c_read: %02x %d\n",addr,len);
+	#endif
 	return ki2c_start(sc, addr, subaddr, data, len);
 }
 
@@ -363,5 +433,41 @@
 	const void *data;
 {
 	sc->sc_flags = 0;
+	#ifdef KI2C_DEBUG
+		printf("ki2c_write: %02x %d\n",addr,len);
+	#endif
 	return ki2c_start(sc, addr, subaddr, (void *)data, len);
 }
+
+static int
+ki2c_i2c_acquire_bus(void *cookie, int flags)
+{
+	struct ki2c_softc *sc = cookie;
+
+	return (lockmgr(&sc->sc_buslock, LK_EXCLUSIVE, NULL));
+}
+
+static void
+ki2c_i2c_release_bus(void *cookie, int flags)
+{
+	struct ki2c_softc *sc = cookie;
+
+	(void) lockmgr(&sc->sc_buslock, LK_RELEASE, NULL);
+}
+
+int
+ki2c_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *vcmd,
+    size_t cmdlen, void *vbuf, size_t buflen, int flags)
+{
+	struct ki2c_softc *sc = cookie;
+	
+	ki2c_setmode(sc, I2C_STDMODE);	/* we handle the subaddress stuff ourselves */
+	if(ki2c_write(sc,addr,0,vcmd,cmdlen)!=0)
+		return -1;
+	if (I2C_OP_READ_P(op))
+	{
+		if(ki2c_read(sc,addr,0,vbuf,buflen)!=0)
+			return -1;
+	}
+	return 0;
+}
Index: dev/snapper.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/dev/snapper.c,v
retrieving revision 1.2
diff -u -w -r1.2 snapper.c
--- dev/snapper.c	29 Oct 2004 12:57:16 -0000	1.2
+++ dev/snapper.c	15 Dec 2004 17:29:47 -0000
@@ -36,6 +36,7 @@
 #include <sys/audioio.h>
 #include <sys/device.h>
 #include <sys/systm.h>
+#include <sys/malloc.h>
 
 #include <dev/auconv.h>
 #include <dev/audio_if.h>
@@ -54,6 +55,8 @@
 # define DPRINTF while (0) printf
 #endif
 
+#define USE_MALLOC
+
 struct snapper_softc {
 	struct device sc_dev;
 	int sc_flags;
@@ -70,15 +73,20 @@
 	u_int sc_output_mask;		/* output source mask */
 
 	u_char *sc_reg;
-	struct device *sc_i2c;
 
 	u_int sc_vol_l;
 	u_int sc_vol_r;
 
 	dbdma_regmap_t *sc_odma;
 	dbdma_regmap_t *sc_idma;
+	#ifdef USE_MALLOC
+	struct dbdma_command *sc_odmacmd;
+	struct dbdma_command *sc_idmacmd;
+	#else
 	struct dbdma_command sc_odmacmd[20];
 	struct dbdma_command sc_idmacmd[20];
+	#endif
+	struct device *sc_i2c;
 };
 
 int snapper_match(struct device *, struct cfdata *, void *);
@@ -321,9 +329,19 @@
 	int cirq, oirq, iirq, cirq_type, oirq_type, iirq_type;
 	int soundbus, intr[6];
 
+#ifdef USE_MALLOC
+	if((sc->sc_odmacmd=malloc(40*sizeof(struct dbdma_command),M_DEVBUF, M_NOWAIT | M_ZERO))==NULL) {
+		printf("%s: cannot allocate memory for DBDMA\n",self->dv_xname);
+		return;
+	}
+	printf("dbdma: %08x\n",(uint32_t)sc->sc_odmacmd);
+	
+	sc->sc_idmacmd=&sc->sc_odmacmd[20];
+#endif
+
 #ifdef DIAGNOSTIC
 	if ((vaddr_t)sc->sc_odmacmd & 0x0f) {
-		printf(": bad dbdma alignment\n");
+		printf(": bad dbdma alignment (%08x)\n",(uint32_t)sc->sc_odmacmd);
 		return;
 	}
 #endif
@@ -333,9 +351,14 @@
 	ca->ca_reg[4] += ca->ca_baseaddr;
 
 	sc->sc_node = ca->ca_node;
-	sc->sc_reg = (void *)ca->ca_reg[0];
+	sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1]);
+
+	sc->sc_odma = mapiodev(ca->ca_reg[2], ca->ca_reg[3]); /* out */
+	sc->sc_idma = mapiodev(ca->ca_reg[4], ca->ca_reg[5]); /* in */
+
+/*	sc->sc_reg = (void *)ca->ca_reg[0];
 	sc->sc_odma = (void *)ca->ca_reg[2];
-	sc->sc_idma = (void *)ca->ca_reg[4];
+	sc->sc_idma = (void *)ca->ca_reg[4];*/
 
 	soundbus = OF_child(ca->ca_node);
 	OF_getprop(soundbus, "interrupts", intr, sizeof intr);
@@ -346,7 +369,7 @@
 	oirq_type = intr[3] ? IST_LEVEL : IST_EDGE;
 	iirq_type = intr[5] ? IST_LEVEL : IST_EDGE;
 
-	/* intr_establish(cirq, cirq_type, IPL_AUDIO, snapper_intr, sc); */
+	intr_establish(cirq, cirq_type, IPL_AUDIO, snapper_intr, sc);
 	intr_establish(oirq, oirq_type, IPL_AUDIO, snapper_intr, sc);
 	/* intr_establish(iirq, iirq_type, IPL_AUDIO, snapper_intr, sc); */
 
@@ -361,10 +384,15 @@
 	struct snapper_softc *sc = (struct snapper_softc *)dev;
 	struct device *dv;
 
-	for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next)
+	/*for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next)
 		if (strncmp(dv->dv_xname, "ki2c", 4) == 0 &&
 		    strncmp(dv->dv_parent->dv_xname, "obio", 4) == 0)
-			sc->sc_i2c = dv;
+			sc->sc_i2c = dv;*/
+	for (dv = alldevs.tqh_first; dv; dv=dv->dv_list.tqe_next)
+		if (strncmp(dv->dv_xname, "deq", 3) == 0 &&
+		    strncmp(dv->dv_parent->dv_xname, "ki2c", 4) == 0)
+			sc->sc_i2c = dv->dv_parent;
+
 	if (sc->sc_i2c == NULL) {
 		printf("%s: unable to find i2c\n", sc->sc_dev.dv_xname);
 		return;
@@ -373,7 +401,7 @@
 	/* XXX If i2c was failed to attach, what should we do? */
 
 	audio_attach_mi(&snapper_hw_if, sc, &sc->sc_dev);
-
+	printf("%s: using %s\n",sc->sc_dev.dv_xname,sc->sc_i2c->dv_xname);
 	/* ki2c_setmode(sc->sc_i2c, I2C_STDSUBMODE); */
 	snapper_init(sc, sc->sc_node);
 }

--------------040300030605080708010009--