Subject: Re: Hanging problems
To: None <duncan@comp.vuw.ac.nz>
From: Charles M. Hannum <mycroft@ai.mit.edu>
List: current-users
Date: 05/10/1995 10:54:56
   A slightly better fix seemed to be to change the config file to explicity name
   the fd device, rather than use wildcards. Ie:

	   fd0 at fdc0 drive 0

   Again this kernel booted fine.  As an experiment, I added explicitly configured
   additional floppy drives one at a time, and found the machine hung when booting
   a kernel with four floppy drives configured.  It also hung with less than 4
   drives when I didn't explicitly provide drive numbers.  Ie:

	   fd0 at fdc0 drive ?
	   fd1 at fdc0 drive ?

I suspect it will also work if you do:

	fd0 at fdc0 drive 0
	fd1 at fdc0 drive 1

The floppy disk protocol allows for up to 4 devices to be connected.
If you use a `?', then the fd driver will try to probe for all 4 until
it finds one.  It would appear that your machine doesn't like
something in the probe routine when it tries to access devices 2 or 3.


Assuming you're using -current, could you try replacing fdprobe() with
the following, configuring your kernel with:

fd* at fdc? drive ?

and tell me what it displays when you boot?


int
fdprobe(parent, match, aux)
	struct device *parent;
	void *match, *aux;
{
	struct fdc_softc *fdc = (void *)parent;
	struct cfdata *cf = match;
	struct fdc_attach_args *fa = aux;
	int drive = fa->fa_drive;
	int iobase = fdc->sc_iobase;
	int n;

	if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != drive)
		return 0;

	printf("probing for drive %d\n", drive");
	/* select drive and turn on motor */
	outb(iobase + fdout, drive | FDO_FRST | FDO_MOEN(drive));
	/* wait for motor to spin up */
	delay(250000);
	printf("enabled motor\n");
	out_fdc(iobase, NE7CMD_RECAL);
	out_fdc(iobase, drive);
	/* wait for recalibrate */
	delay(2000000);
	printf("sent recalibrate command\n");
	out_fdc(iobase, NE7CMD_SENSEI);
	printf("sent sense command\n");
	n = fdcresult(fdc);
	{
		int i;
		printf("fdprobe: status");
		for (i = 0; i < n; i++)
			printf(" %x", fdc->sc_status[i]);
		printf("\n");
	}
	if (n != 2 || (fdc->sc_status[0] & 0xf8) != 0x20)
		return 0;
	/* turn off motor */
	outb(iobase + fdout, FDO_FRST);
	printf("disabled motor");

	return 1;
}