Subject: autoconfig changes
To: None <current-users@sun-lamp.cs.berkeley.edu, port-i386@sun-lamp.cs.berkeley.edu>
From: Charles Hannum <mycroft@duality.gnu.ai.mit.edu>
List: current-users
Date: 03/29/1994 00:39:37
I just made a major change to the way autoconfig is done on the i386.
This will require building a new copy of config(8) before building a
new kernel with tonight's sources.


This is one of the major steps in converting the code to use
config.new.  Ultimately, this will allow more flexible configuration
(thinks like `sd* at scsibus? slave ?', which will attach all found
SCSI disks on all configured SCSI busses with sequential unit
numbers).

What I've done for now is to hack it to work with the old config(8),
but use (mostly) the same interface that will be present after
switching to config.new.  Right now, the above example doesn't work,
due to limitations in the old config.  (The old config(8) is still
needed because of the silly way interrupts are configure.  This will
change.)

More immediately, this has enabled me to import some much better SCSI
code and a much more robust floppy driver that I worked on in the
infamous `magnum' branch.  If you notice any anomalies, especially
with this code, please let me know ASAP.


The details of the new config are complex, and I won't go into them
here.  Look in the current wd.c and isa.c for examples of how it's
used.  Most well-written drivers will require very few changes to
convert.  I enclose an annotated example below.


===================================================================
RCS file: /b/source/CVS/src/sys/arch/i386/isa/lms.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -c -2 -r1.9 -r1.10
*** 1.9	1994/03/06 17:19:10
--- 1.10	1994/03/29 04:36:06


We don't need NLMS any more, since softc's are dynamically allocated.

***************
*** 21,29 ****
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
!  *	$Id: lms.c,v 1.9 1994/03/06 17:19:10 mycroft Exp $
   */
  
- #include "lms.h"
- 
  #include <sys/param.h>
  #include <sys/kernel.h>
--- 21,27 ----
   * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
!  *	$Id: lms.c,v 1.10 1994/03/29 04:36:06 mycroft Exp $
   */
  
  #include <sys/param.h>
  #include <sys/kernel.h>


We use isa_attach_args rather than isa_device now.  It's in a
different file, with a more conventional name.

***************
*** 43,47 ****
  #include <machine/mouse.h>
  
! #include <i386/isa/isa_device.h>
  
  #define	LMS_DATA	0       /* offset for data port, read-only */
--- 41,45 ----
  #include <machine/mouse.h>
  
! #include <i386/isa/isavar.h>
  
  #define	LMS_DATA	0       /* offset for data port, read-only */


We don't need to statically allocate any softc's; autoconfig allocates
them for us.  Also, we use a different structure for the driver
information that is portable across architectures.

***************
*** 66,76 ****
  	u_char sc_status;	/* mouse button status */
  	int sc_x, sc_y;		/* accumulated motion in the X,Y axis */
! } lms_softc[NLMS];
  
! int lmsprobe __P((struct isa_device *));
! int lmsattach __P((struct isa_device *));
  int lmsintr __P((int));
  
! struct isa_driver lmsdriver = { lmsprobe, lmsattach, "lms" };
  
  #define	LMSUNIT(dev)	(minor(dev))
--- 64,76 ----
  	u_char sc_status;	/* mouse button status */
  	int sc_x, sc_y;		/* accumulated motion in the X,Y axis */
! };
  
! int lmsprobe();
! void lmsattach();
  int lmsintr __P((int));
  
! struct cfdriver lmscd = {
! 	NULL, "lms", lmsprobe, lmsattach, DV_TTY, sizeof(struct lms_softc)
! };
  
  #define	LMSUNIT(dev)	(minor(dev))


The probe routine gets a different set of arguments.  `parent' is a
pointer to the parent's softc; `self' is a pointer to the device's
softc (which was dynamically allocated).  `aux' is a pointer to some
auxiliary information as passed to config_search(), in this case an
isa_attach_args structure.

***************
*** 77,84 ****
  
  int
! lmsprobe(isa_dev)
! 	struct isa_device *isa_dev;
  {
! 	u_short iobase = isa_dev->id_iobase;
  
  	/* Configure and check for port present. */
--- 77,86 ----
  
  int
! lmsprobe(parent, self, aux)
! 	struct device *parent, *self;
! 	void *aux;
  {
! 	struct isa_attach_args *ia = aux;
! 	u_short iobase = ia->ia_iobase;
  
  	/* Configure and check for port present. */


The return value from the probe routine is currently a boolean value,
though in config.new it is a `priority' (which we probably won't use).
So rather than returning the number of ports used, we poke it into the
isa_attach_args.

***************
*** 97,101 ****
  	outb(iobase + LMS_CNTRL, 0x10);
  
! 	return LMS_NPORTS;
  }
  
--- 99,105 ----
  	outb(iobase + LMS_CNTRL, 0x10);
  
! 	ia->ia_iosize = LMS_NPORTS;
! 	ia->ia_msize = 0;
! 	return 1;
  }
  


Again, we get a new set of arguments, just like the probe routine's.
And remove a hack I did to fill in some fields of the `device'
structure so that I could use them.  (This was part of some careful
preparation for these changes.)

***************
*** 100,117 ****
  }
  
! int
! lmsattach(isa_dev)
! 	struct isa_device *isa_dev;
  {
! 	struct lms_softc *sc = &lms_softc[isa_dev->id_unit];
! 	u_short iobase = isa_dev->id_iobase;
  
  	/* Other initialization was done by lmsprobe. */
  	sc->sc_iobase = iobase;
  	sc->sc_state = 0;
- 
- 	/* XXX HACK */
- 	sprintf(sc->sc_dev.dv_xname, "%s%d", lmsdriver.name, isa_dev->id_unit);
- 	sc->sc_dev.dv_unit = isa_dev->id_unit;
  }
  
--- 104,119 ----
  }
  
! void
! lmsattach(parent, self, aux)
! 	struct device *parent, *self;
! 	void *aux;
  {
! 	struct lms_softc *sc = (void *)self;
! 	struct isa_attach_args *ia = aux;
! 	u_short iobase = ia->ia_iobase;
  
  	/* Other initialization was done by lmsprobe. */
  	sc->sc_iobase = iobase;
  	sc->sc_state = 0;
  }
  


The softc's are not static any more.  The maximum unit number and
pointers to softc's are stored in the `cfdriver' structure.  If a
device was not configured, it won't have a softc pointer.

***************
*** 124,131 ****
  	struct lms_softc *sc;
  
! 	if (unit >= NLMS)
  		return ENXIO;
! 	sc = &lms_softc[unit];
! 	if (!sc->sc_iobase)
  		return ENXIO;
  
--- 126,133 ----
  	struct lms_softc *sc;
  
! 	if (unit >= lmscd.cd_ndevs)
  		return ENXIO;
! 	sc = lmscd.cd_devs[unit];
! 	if (!sc)
  		return ENXIO;
  
***************
*** 151,155 ****
  	int flag;
  {
! 	struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
  
  	/* Disable interrupts. */
--- 153,157 ----
  	int flag;
  {
! 	struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
  
  	/* Disable interrupts. */
***************
*** 169,173 ****
  	int flag;
  {
! 	struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
  	int s;
  	int error;
--- 171,175 ----
  	int flag;
  {
! 	struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
  	int s;
  	int error;
***************
*** 217,221 ****
  	int flag;
  {
! 	struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
  	struct mouseinfo info;
  	int s;
--- 219,223 ----
  	int flag;
  {
! 	struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
  	struct mouseinfo info;
  	int s;
***************
*** 266,270 ****
  	int unit;
  {
! 	struct lms_softc *sc = &lms_softc[unit];
  	u_short iobase = sc->sc_iobase;
  	u_char hi, lo, buttons, changed;
--- 268,272 ----
  	int unit;
  {
! 	struct lms_softc *sc = lmscd.cd_devs[unit];
  	u_short iobase = sc->sc_iobase;
  	u_char hi, lo, buttons, changed;
***************
*** 325,329 ****
  	struct proc *p;
  {
! 	struct lms_softc *sc = &lms_softc[LMSUNIT(dev)];
  	int s;
  	int ret;
--- 327,331 ----
  	struct proc *p;
  {
! 	struct lms_softc *sc = lmscd.cd_devs[LMSUNIT(dev)];
  	int s;
  	int ret;



--
The end.

------------------------------------------------------------------------------